@pebula/metap
Version:
meta-programming tools
325 lines • 27.9 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import * as tslib_1 from "tslib";
import { isFunction } from '@pebula/utils';
import { PropMetadata, ExcludeMetadata, LazyInit, array, } from '@pebula/metap/internal';
import { ExclusivePropertyContainer, InclusivePropertyContainer, transformValueIn } from './serialization-context';
/**
* Returns an array of 2 property names, first is the name of the transformed output
* second is the name of the property name to transform.
* Used for applying NamingStrategyConfig based on the TransformDir
* @param {?} dir
* @param {?} transformNameStrategy
* @return {?}
*/
export function namingStrategyMap(dir, transformNameStrategy) {
return transformNameStrategy && isFunction(transformNameStrategy[dir]);
}
/**
* \@internal
* @template T, Z
* @param {?} meta
* @param {?} dir
* @return {?}
*/
export function getInstructions(meta, dir) {
// all excluded instructions for this type
// this array will be filtered to hold only @Exclude without @Prop
/** @type {?} */
var excluded = meta
.getValues(ExcludeMetadata)
.filter((/**
* @param {?} e
* @return {?}
*/
function (e) { return !e.from || e.from === dir; }));
/** @type {?} */
var model = meta.model();
// in exclusive mode there is no point in have 2 transformation strategies.
// incoming is never there since incoming keys are not calculated, only defined Props.
if (model.transformStrategy === 'exclusive') {
dir = 'outgoing';
}
// only apply naming strategy on outgoing, incoming has no effect here
/** @type {?} */
var naming = namingStrategyMap(dir, model.transformNameStrategy);
/** @type {?} */
var fkMap = new Map();
// TODO: move to for loop
/** @type {?} */
var instructions = meta.getValues(PropMetadata).map((/**
* @param {?} prop
* @return {?}
*/
function (prop) {
/** @type {?} */
var obj = {
cls: prop.name,
obj: prop.alias[dir],
exclude: array.findRemove(excluded, (/**
* @param {?} e
* @return {?}
*/
function (e) { return e.name === prop.name; })),
prop: prop
};
// apply naming strategy when DONT HAVE ALIAS!
if (!obj.exclude && naming && obj.cls === obj.obj) {
obj.obj = model.transformNameStrategy[dir](obj.cls);
}
// store the PoClassPropertyMap of a belongsTo PropMetadata relation
// and the PoClassPropertyMap of all foreign key PropMetadata.
// These arr actually matching pairs of a belongTo relation and it's fk
// (not all belongsTo has fk, only different property name is a fk)
//
// At the end, go through the stored PropMetadata and see if matching pairs found (2 values in array)
// for all of them, swap the prop names so:
// belongsTo PoClassPropertyMap will output (deserialize) to the original fk property name
// foreignKey PoClassPropertyMap wil input (serialize) to the belongsTo property name
// this swap make the deserialize/serialize process transparent to fk mismatch defined on the model.
// De/Serialize implementations are only responsible to return the right object
// (e.g. detect when a key is incoming, return obj instead)
if (prop.relation) {
/** @type {?} */
var arr = fkMap.get(prop) || [];
arr[0] = obj;
fkMap.set(prop, arr);
}
else if (prop.foreignKeyOf) {
/** @type {?} */
var arr = fkMap.get(prop.foreignKeyOf) || [];
arr[1] = obj;
fkMap.set(prop.foreignKeyOf, arr);
}
return obj;
}));
Array.from(fkMap.entries()).forEach((/**
* @param {?} __0
* @return {?}
*/
function (_a) {
var _b = tslib_1.__read(_a, 2), k = _b[0], v = _b[1];
if (v.length === 2) {
// this is a swap
v[0].obj = (/** @type {?} */ (v[1].cls));
v[1].cls = (/** @type {?} */ (k.name)); // v[0].cls === k.name
}
}));
return { excluded: excluded, instructions: instructions };
}
/**
* @param {?} p
* @return {?}
*/
function serializePredicate(p) {
return p.cls === this;
}
/**
* @param {?} p
* @return {?}
*/
function deserializePredicate(p) {
return p.obj === this;
}
var ɵ0 = /**
* @this {?}
* @return {?}
*/
function () {
/** @type {?} */
var idKey = this.meta.getIdentityKey();
if (idKey) {
return (this.hasOwnProperty('incoming')
? this.incoming
: this.outgoing).instructions.find((/**
* @param {?} p
* @return {?}
*/
function (p) { return p.prop.name === idKey; }));
}
}, ɵ1 = /**
* @this {?}
* @return {?}
*/
function () {
return getInstructions(this.meta, 'incoming');
}, ɵ2 = /**
* @this {?}
* @return {?}
*/
function () {
return getInstructions(this.meta, 'outgoing');
}, ɵ3 = /**
* @this {?}
* @return {?}
*/
function () {
/** @type {?} */
var model = this.meta.model();
if (model.transformStrategy === 'exclusive') {
return new ExclusivePropertyContainer(this.meta.target, this.incoming);
}
else {
/** @type {?} */
var rename = namingStrategyMap('incoming', model.transformNameStrategy)
? (/**
* @param {?} prop
* @return {?}
*/
function (prop) { return (prop.cls = model.transformNameStrategy.incoming(prop.obj)); })
: undefined;
return new InclusivePropertyContainer(this.meta.target, this.incoming, deserializePredicate, rename);
}
}, ɵ4 = /**
* @this {?}
* @return {?}
*/
function () {
/** @type {?} */
var model = this.meta.model();
if (model.transformStrategy === 'exclusive') {
return new ExclusivePropertyContainer(this.meta.target, this.outgoing);
}
else {
/** @type {?} */
var rename = namingStrategyMap('outgoing', model.transformNameStrategy)
? (/**
* @param {?} prop
* @return {?}
*/
function (prop) { return (prop.obj = model.transformNameStrategy.outgoing(prop.cls)); })
: undefined;
return new InclusivePropertyContainer(this.meta.target, this.outgoing, serializePredicate, rename);
}
};
// @dynamic
/**
* A TargetSerializationContext is the running context of a mapper for a specific target class that
* can serialize and deserialize instances of the target class.
* It will run the mapper, provide input and parse results
* @template T, Z
*/
var TargetSerializationContext = /** @class */ (function () {
function TargetSerializationContext(meta) {
this.meta = meta;
}
/**
* @param {?} mapper
* @return {?}
*/
TargetSerializationContext.prototype.serialize = /**
* @param {?} mapper
* @return {?}
*/
function (mapper) {
return mapper.serialize(this.outgoingContainer);
};
/**
* Deserialize a single target.
* Does not support collection deserialization, if mapper is a collection will throw.
* @param mapper
* @param target
*/
/**
* Deserialize a single target.
* Does not support collection deserialization, if mapper is a collection will throw.
* @param {?} mapper
* @param {?} target
* @return {?}
*/
TargetSerializationContext.prototype.deserialize = /**
* Deserialize a single target.
* Does not support collection deserialization, if mapper is a collection will throw.
* @param {?} mapper
* @param {?} target
* @return {?}
*/
function (mapper, target) {
/** @type {?} */
var cb = (/**
* @param {?} prop
* @return {?}
*/
function (prop) {
/** @type {?} */
var propMeta = (prop.prop && prop.prop.foreignKeyOf) || prop.prop;
target[prop.cls] = transformValueIn(mapper.getValue(prop.obj, propMeta), propMeta);
});
if (isFunction(mapper.setRef)) {
mapper.setRef(target);
}
if (mapper.raw === true) {
this.incomingContainer.forEachRaw(mapper.getKeys(), cb);
}
else {
this.incomingContainer.forEach(mapper.getKeys(), cb);
}
if (isFunction(mapper.getIdentity)) {
if (this.identity) {
/** @type {?} */
var ident = transformValueIn(mapper.getIdentity(), this.identity.prop);
if (ident) {
target[this.identity.cls] = ident;
}
}
}
};
tslib_1.__decorate([
LazyInit((ɵ0)),
tslib_1.__metadata("design:type", Object)
], TargetSerializationContext.prototype, "identity", void 0);
tslib_1.__decorate([
LazyInit((ɵ1)),
tslib_1.__metadata("design:type", Object)
], TargetSerializationContext.prototype, "incoming", void 0);
tslib_1.__decorate([
LazyInit((ɵ2)),
tslib_1.__metadata("design:type", Object)
], TargetSerializationContext.prototype, "outgoing", void 0);
tslib_1.__decorate([
LazyInit((ɵ3)),
tslib_1.__metadata("design:type", Object)
], TargetSerializationContext.prototype, "incomingContainer", void 0);
tslib_1.__decorate([
LazyInit((ɵ4)),
tslib_1.__metadata("design:type", Object)
], TargetSerializationContext.prototype, "outgoingContainer", void 0);
return TargetSerializationContext;
}());
export { TargetSerializationContext };
if (false) {
/**
* @type {?}
* @protected
*/
TargetSerializationContext.prototype.identity;
/**
* @type {?}
* @protected
*/
TargetSerializationContext.prototype.incoming;
/**
* @type {?}
* @protected
*/
TargetSerializationContext.prototype.outgoing;
/**
* @type {?}
* @protected
*/
TargetSerializationContext.prototype.incomingContainer;
/**
* @type {?}
* @protected
*/
TargetSerializationContext.prototype.outgoingContainer;
/**
* @type {?}
* @protected
*/
TargetSerializationContext.prototype.meta;
}
export { ɵ0, ɵ1, ɵ2, ɵ3, ɵ4 };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFyZ2V0LXNlcmlhbGl6YXRpb24tY29udGV4dC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BwZWJ1bGEvbWV0YXAvIiwic291cmNlcyI6WyJsaWIvc2VyaWFsaXphdGlvbi9tYXBwaW5nL3RhcmdldC1zZXJpYWxpemF0aW9uLWNvbnRleHQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFDTCxZQUFZLEVBQ1osZUFBZSxFQUVmLFFBQVEsRUFPUixLQUFLLEdBQ04sTUFBTSx3QkFBd0IsQ0FBQztBQUVoQyxPQUFPLEVBRUwsMEJBQTBCLEVBQzFCLDBCQUEwQixFQUMxQixnQkFBZ0IsRUFDakIsTUFBTSx5QkFBeUIsQ0FBQzs7Ozs7Ozs7O0FBU2pDLE1BQU0sVUFBVSxpQkFBaUIsQ0FBQyxHQUFpQixFQUFFLHFCQUEyQztJQUM5RixPQUFPLHFCQUFxQixJQUFJLFVBQVUsQ0FBQyxxQkFBcUIsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBQ3pFLENBQUM7Ozs7Ozs7O0FBS0QsTUFBTSxVQUFVLGVBQWUsQ0FBTyxJQUEwQixFQUFFLEdBQWlCOzs7O1FBRzNFLFFBQVEsR0FBRyxJQUFJO1NBQ2xCLFNBQVMsQ0FBQyxlQUFlLENBQUM7U0FDMUIsTUFBTTs7OztJQUFDLFVBQUEsQ0FBQyxJQUFJLE9BQUEsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxJQUFJLEtBQUssR0FBRyxFQUF6QixDQUF5QixFQUFDOztRQUVuQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFBRTtJQUUxQiwyRUFBMkU7SUFDM0Usc0ZBQXNGO0lBQ3RGLElBQUksS0FBSyxDQUFDLGlCQUFpQixLQUFLLFdBQVcsRUFBRTtRQUMzQyxHQUFHLEdBQUcsVUFBVSxDQUFDO0tBQ2xCOzs7UUFHSyxNQUFNLEdBQUcsaUJBQWlCLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxxQkFB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OENBU21EOzs7OztJQUVuRCw4Q0FHMkM7Ozs7O0lBRTNDLDhDQUcyQzs7Ozs7SUFFM0MsdURBZ0IrQzs7Ozs7SUFFL0MsdURBZ0IrQzs7Ozs7SUFFbkMsMENBQW9DIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaXNGdW5jdGlvbiB9IGZyb20gJ0BwZWJ1bGEvdXRpbHMnO1xuaW1wb3J0IHtcbiAgUHJvcE1ldGFkYXRhLFxuICBFeGNsdWRlTWV0YWRhdGEsXG4gIFRhcmdldE1ldGFkYXRhLFxuICBMYXp5SW5pdCxcbiAgVHJhbnNmb3JtRGlyLFxuICBOYW1pbmdTdHJhdGVneUNvbmZpZyxcbiAgQmFzZVNlcmlhbGl6ZXIsXG4gIEJhc2VEZXNlcmlhbGl6ZXIsXG4gIFBvQ2xhc3NQcm9wZXJ0eU1hcCxcbiAgU2VyaWFsaXplckNvbnRleHQsXG4gIGFycmF5LFxufSBmcm9tICdAcGVidWxhL21ldGFwL2ludGVybmFsJztcblxuaW1wb3J0IHtcbiAgQ29tcGlsZWRUcmFuc2Zvcm1hdGlvbixcbiAgRXhjbHVzaXZlUHJvcGVydHlDb250YWluZXIsXG4gIEluY2x1c2l2ZVByb3BlcnR5Q29udGFpbmVyLFxuICB0cmFuc2Zvcm1WYWx1ZUluXG59IGZyb20gJy4vc2VyaWFsaXphdGlvbi1jb250ZXh0JztcblxuLyoqXG4gKiBSZXR1cm5zIGFuIGFycmF5IG9mIDIgcHJvcGVydHkgbmFtZXMsIGZpcnN0IGlzIHRoZSBuYW1lIG9mIHRoZSB0cmFuc2Zvcm1lZCBvdXRwdXRcbiAqIHNlY29uZCBpcyB0aGUgbmFtZSBvZiB0aGUgcHJvcGVydHkgbmFtZSB0byB0cmFuc2Zvcm0uXG4gKiBVc2VkIGZvciBhcHBseWluZyBOYW1pbmdTdHJhdGVneUNvbmZpZyBiYXNlZCBvbiB0aGUgVHJhbnNmb3JtRGlyXG4gKiBAcGFyYW0gZGlyXG4gKiBAcGFyYW0gdHJhbnNmb3JtTmFtZVN0cmF0ZWd5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBuYW1pbmdTdHJhdGVneU1hcChkaXI6IFRyYW5zZm9ybURpciwgdHJhbnNmb3JtTmFtZVN0cmF0ZWd5OiBOYW1pbmdTdHJhdGVneUNvbmZpZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gdHJhbnNmb3JtTmFtZVN0cmF0ZWd5ICYmIGlzRnVuY3Rpb24odHJhbnNmb3JtTmFtZVN0cmF0ZWd5W2Rpcl0pO1xufVxuXG4vKipcbiAqIEBpbnRlcm5hbFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0SW5zdHJ1Y3Rpb25zPFQsIFo+KG1ldGE6IFRhcmdldE1ldGFkYXRhPFQsIFo+LCBkaXI6IFRyYW5zZm9ybURpcik6IENvbXBpbGVkVHJhbnNmb3JtYXRpb24ge1xuICAvLyBhbGwgZXhjbHVkZWQgaW5zdHJ1Y3Rpb25zIGZvciB0aGlzIHR5cGVcbiAgLy8gdGhpcyBhcnJheSB3aWxsIGJlIGZpbHRlcmVkIHRvIGhvbGQgb25seSBARXhjbHVkZSB3aXRob3V0IEBQcm9wXG4gIGNvbnN0IGV4Y2x1ZGVkID0gbWV0YVxuICAgIC5nZXRWYWx1ZXMoRXhjbHVkZU1ldGFkYXRhKVxuICAgIC5maWx0ZXIoZSA9PiAhZS5mcm9tIHx8IGUuZnJvbSA9PT0gZGlyKTtcblxuICBjb25zdCBtb2RlbCA9IG1ldGEubW9kZWwoKTtcblxuICAvLyBpbiBleGNsdXNpdmUgbW9kZSB0aGVyZSBpcyBubyBwb2ludCBpbiBoYXZlIDIgdHJhbnNmb3JtYXRpb24gc3RyYXRlZ2llcy5cbiAgLy8gaW5jb21pbmcgaXMgbmV2ZXIgdGhlcmUgc2luY2UgaW5jb21pbmcga2V5cyBhcmUgbm90IGNhbGN1bGF0ZWQsIG9ubHkgZGVmaW5lZCBQcm9wcy5cbiAgaWYgKG1vZGVsLnRyYW5zZm9ybVN0cmF0ZWd5ID09PSAnZXhjbHVzaXZlJykge1xuICAgIGRpciA9ICdvdXRnb2luZyc7XG4gIH1cblxuICAvLyBvbmx5IGFwcGx5IG5hbWluZyBzdHJhdGVneSBvbiBvdXRnb2luZywgaW5jb21pbmcgaGFzIG5vIGVmZmVjdCBoZXJlXG4gIGNvbnN0IG5hbWluZyA9IG5hbWluZ1N0cmF0ZWd5TWFwKGRpciwgbW9kZWwudHJhbnNmb3JtTmFtZVN0cmF0ZWd5KTtcblxuICBjb25zdCBma01hcCA9IG5ldyBNYXA8UHJvcE1ldGFkYXRhLCBQb0NsYXNzUHJvcGVydHlNYXBbXT4oKTtcblxuICAvLyBUT0RPOiBtb3ZlIHRvIGZvciBsb29wXG4gIGNvbnN0IGluc3RydWN0aW9ucyA9IG1ldGEuZ2V0VmFsdWVzKFByb3BNZXRhZGF0YSkubWFwKHByb3AgPT4ge1xuICAgIGNvbnN0IG9iaiA9IHtcbiAgICAgIGNsczogcHJvcC5uYW1lLFxuICAgICAgb2JqOiBwcm9wLmFsaWFzW2Rpcl0sXG4gICAgICBleGNsdWRlOiBhcnJheS5maW5kUmVtb3ZlKGV4Y2x1ZGVkLCBlID0+IGUubmFtZSA9PT0gcHJvcC5uYW1lKSxcbiAgICAgIHByb3BcbiAgICB9O1xuXG4gICAgLy8gYXBwbHkgbmFtaW5nIHN0cmF0ZWd5IHdoZW4gRE9OVCBIQVZFIEFMSUFTIVxuICAgIGlmICghb2JqLmV4Y2x1ZGUgJiYgbmFtaW5nICYmIG9iai5jbHMgPT09IG9iai5vYmopIHtcbiAgICAgIG9iai5vYmogPSBtb2RlbC50cmFuc2Zvcm1OYW1lU3RyYXRlZ3lbZGlyXShvYmouY2xzKTtcbiAgICB9XG5cbiAgICAvLyBzdG9yZSB0aGUgUG9DbGFzc1Byb3BlcnR5TWFwIG9mIGEgYmVsb25nc1RvIFByb3BNZXRhZGF0YSByZWxhdGlvblxuICAgIC8vIGFuZCB0aGUgUG9DbGFzc1Byb3BlcnR5TWFwIG9mIGFsbCBmb3JlaWduIGtleSBQcm9wTWV0YWRhdGEuXG4gICAgLy8gVGhlc2UgYXJyIGFjdHVhbGx5IG1hdGNoaW5nIHBhaXJzIG9mIGEgYmVsb25nVG8gcmVsYXRpb24gYW5kIGl0J3MgZmtcbiAgICAvLyAobm90IGFsbCBiZWxvbmdzVG8gaGFzIGZrLCBvbmx5IGRpZmZlcmVudCBwcm9wZXJ0eSBuYW1lIGlzIGEgZmspXG4gICAgLy9cbiAgICAvLyBBdCB0aGUgZW5kLCBnbyB0aHJvdWdoIHRoZSBzdG9yZWQgUHJvcE1ldGFkYXRhIGFuZCBzZWUgaWYgbWF0Y2hpbmcgcGFpcnMgZm91bmQgKDIgdmFsdWVzIGluIGFycmF5KVxuICAgIC8vIGZvciBhbGwgb2YgdGhlbSwgc3dhcCB0aGUgcHJvcCBuYW1lcyBzbzpcbiAgICAvLyBiZWxvbmdzVG8gUG9DbGFzc1Byb3BlcnR5TWFwIHdpbGwgb3V0cHV0IChkZXNlcmlhbGl6ZSkgdG8gdGhlIG9yaWdpbmFsIGZrIHByb3BlcnR5IG5hbWVcbiAgICAvLyBmb3JlaWduS2V5IFBvQ2xhc3NQcm9wZXJ0eU1hcCB3aWwgaW5wdXQgKHNlcmlhbGl6ZSkgdG8gdGhlIGJlbG9uZ3NUbyBwcm9wZXJ0eSBuYW1lXG4gICAgLy8gdGhpcyBzd2FwIG1ha2UgdGhlIGRlc2VyaWFsaXplL3NlcmlhbGl6ZSBwcm9jZXNzIHRyYW5zcGFyZW50IHRvIGZrIG1pc21hdGNoIGRlZmluZWQgb24gdGhlIG1vZGVsLlxuICAgIC8vIERlL1NlcmlhbGl6ZSBpbXBsZW1lbnRhdGlvbnMgYXJlIG9ubHkgcmVzcG9uc2libGUgdG8gcmV0dXJuIHRoZSByaWdodCBvYmplY3RcbiAgICAvLyAoZS5nLiBkZXRlY3Qgd2hlbiBhIGtleSBpcyBpbmNvbWluZywgcmV0dXJuIG9iaiBpbnN0ZWFkKVxuICAgIGlmIChwcm9wLnJlbGF0aW9uKSB7XG4gICAgICBjb25zdCBhcnIgPSBma01hcC5nZXQocHJvcCkgfHwgW107XG4gICAgICBhcnJbMF0gPSBvYmo7XG4gICAgICBma01hcC5zZXQocHJvcCwgYXJyKTtcbiAgICB9IGVsc2UgaWYgKHByb3AuZm9yZWlnbktleU9mKSB7XG4gICAgICBjb25zdCBhcnIgPSBma01hcC5nZXQocHJvcC5mb3JlaWduS2V5T2YpIHx8IFtdO1xuICAgICAgYXJyWzFdID0gb2JqO1xuICAgICAgZmtNYXAuc2V0KHByb3AuZm9yZWlnbktleU9mLCBhcnIpO1xuICAgIH1cblxuICAgIHJldHVybiBvYmo7XG4gIH0pO1xuXG4gIEFycmF5LmZyb20oZmtNYXAuZW50cmllcygpKS5mb3JFYWNoKChbaywgdl0pID0+IHtcbiAgICBpZiAodi5sZW5ndGggPT09IDIpIHtcbiAgICAgIC8vIHRoaXMgaXMgYSBzd2FwXG4gICAgICB2WzBdLm9iaiA9IHZbMV0uY2xzIGFzIGFueTtcbiAgICAgIHZbMV0uY2xzID0gay5uYW1lIGFzIGFueTsgLy8gdlswXS5jbHMgPT09IGsubmFtZVxuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIHsgZXhjbHVkZWQsIGluc3RydWN0aW9ucyB9O1xufVxuXG5mdW5jdGlvbiBzZXJpYWxpemVQcmVkaWNhdGUocDogUG9DbGFzc1Byb3BlcnR5TWFwKSB7XG4gIHJldHVybiBwLmNscyA9PT0gdGhpcztcbn1cbmZ1bmN0aW9uIGRlc2VyaWFsaXplUHJlZGljYXRlKHA6IFBvQ2xhc3NQcm9wZXJ0eU1hcCkge1xuICByZXR1cm4gcC5vYmogPT09IHRoaXM7XG59XG5cbi8vIEBkeW5hbWljXG4vKipcbiAqIEEgVGFyZ2V0U2VyaWFsaXphdGlvbkNvbnRleHQgaXMgdGhlIHJ1bm5pbmcgY29udGV4dCBvZiBhIG1hcHBlciBmb3IgYSBzcGVjaWZpYyB0YXJnZXQgY2xhc3MgdGhhdFxuICogY2FuIHNlcmlhbGl6ZSBhbmQgZGVzZXJpYWxpemUgaW5zdGFuY2VzIG9mIHRoZSB0YXJnZXQgY2xhc3MuXG4gKiBJdCB3aWxsIHJ1biB0aGUgbWFwcGVyLCBwcm92aWRlIGlucHV0IGFuZCBwYXJzZSByZXN1bHRzXG4gKi9cbmV4cG9ydCBjbGFzcyBUYXJnZXRTZXJpYWxpemF0aW9uQ29udGV4dDxUID0gYW55LCBaID0gYW55PiB7XG4gIEBMYXp5SW5pdChmdW5jdGlvbih0aGlzOiBUYXJnZXRTZXJpYWxpemF0aW9uQ29udGV4dDxULCBaPik6IFBvQ2xhc3NQcm9wZXJ0eU1hcCB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgaWRLZXkgPSB0aGlzLm1ldGEuZ2V0SWRlbnRpdHlLZXkoKTtcbiAgICBpZiAoaWRLZXkpIHtcbiAgICAgIHJldHVybiAodGhpcy5oYXNPd25Qcm9wZXJ0eSgnaW5jb21pbmcnKVxuICAgICAgICA/IHRoaXMuaW5jb21pbmdcbiAgICAgICAgOiB0aGlzLm91dGdvaW5nXG4gICAgICApLmluc3RydWN0aW9ucy5maW5kKHAgPT4gcC5wcm9wLm5hbWUgPT09IGlkS2V5KTtcbiAgICB9XG4gIH0pXG4gIHByb3RlY3RlZCBpZGVudGl0eTogUG9DbGFzc1Byb3BlcnR5TWFwIHwgdW5kZWZpbmVkO1xuXG4gIEBMYXp5SW5pdChmdW5jdGlvbih0aGlzOiBUYXJnZXRTZXJpYWxpemF0aW9uQ29udGV4dDxULCBaPik6IENvbXBpbGVkVHJhbnNmb3JtYXRpb24ge1xuICAgIHJldHVybiBnZXRJbnN0cnVjdGlvbnModGhpcy5tZXRhLCAnaW5jb21pbmcnKTtcbiAgfSlcbiAgcHJvdGVjdGVkIGluY29taW5nOiBDb21waWxlZFRyYW5zZm9ybWF0aW9uO1xuXG4gIEBMYXp5SW5pdChmdW5jdGlvbih0aGlzOiBUYXJnZXRTZXJpYWxpemF0aW9uQ29udGV4dDxULCBaPik6IENvbXBpbGVkVHJhbnNmb3JtYXRpb24ge1xuICAgIHJldHVybiBnZXRJbnN0cnVjdGlvbnModGhpcy5tZXRhLCAnb3V0Z29pbmcnKTtcbiAgfSlcbiAgcHJvdGVjdGVkIG91dGdvaW5nOiBDb21waWxlZFRyYW5zZm9ybWF0aW9uO1xuXG4gIEBMYXp5SW5pdChmdW5jdGlvbih0aGlzOiBUYXJnZXRTZXJpYWxpemF0aW9uQ29udGV4dDxULCBaPik6IFNlcmlhbGl6ZXJDb250ZXh0IHtcbiAgICBjb25zdCBtb2RlbCA9IHRoaXMubWV0YS5tb2RlbCgpO1xuICAgIGlmIChtb2RlbC50cmFuc2Zvcm1TdHJhdGVneSA9PT0gJ2V4Y2x1c2l2ZScpIHtcbiAgICAgIHJldHVybiBuZXcgRXhjbHVzaXZlUHJvcGVydHlDb250YWluZXIodGhpcy5tZXRhLnRhcmdldCwgdGhpcy5pbmNvbWluZyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IHJlbmFtZSA9IG5hbWluZ1N0cmF0ZWd5TWFwKCdpbmNvbWluZycsIG1vZGVsLnRyYW5zZm9ybU5hbWVTdHJhdGVneSlcbiAgICAgICAgPyBwcm9wID0+IChwcm9wLmNscyA9IG1vZGVsLnRyYW5zZm9ybU5hbWVTdHJhdGVneS5pbmNvbWluZyhwcm9wLm9iaikpXG4gICAgICAgIDogdW5kZWZpbmVkO1xuICAgICAgcmV0dXJuIG5ldyBJbmNsdXNpdmVQcm9wZXJ0eUNvbnRhaW5lcihcbiAgICAgICAgdGhpcy5tZXRhLnRhcmdldCxcbiAgICAgICAgdGhpcy5pbmNvbWluZyxcbiAgICAgICAgZGVzZXJpYWxpemVQcmVkaWNhdGUsXG4gICAgICAgIHJlbmFtZVxuICAgICAgKTtcbiAgICB9XG4gIH0pXG4gIHByb3RlY3RlZCBpbmNvbWluZ0NvbnRhaW5lcjogU2VyaWFsaXplckNvbnRleHQ7XG5cbiAgQExhenlJbml0KGZ1bmN0aW9uKHRoaXM6IFRhcmdldFNlcmlhbGl6YXRpb25Db250ZXh0PFQsIFo+KTogU2VyaWFsaXplckNvbnRleHQge1xuICAgIGNvbnN0IG1vZGVsID0gdGhpcy5tZXRhLm1vZGVsKCk7XG4gICAgaWYgKG1vZGVsLnRyYW5zZm9ybVN0cmF0ZWd5ID09PSAnZXhjbHVzaXZlJykge1xuICAgICAgcmV0dXJuIG5ldyBFeGNsdXNpdmVQcm9wZXJ0eUNvbnRhaW5lcih0aGlzLm1ldGEudGFyZ2V0LCB0aGlzLm91dGdvaW5nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgcmVuYW1lID0gbmFtaW5nU3RyYXRlZ3lNYXAoJ291dGdvaW5nJywgbW9kZWwudHJhbnNmb3JtTmFtZVN0cmF0ZWd5KVxuICAgICAgICA/IHByb3AgPT4gKHByb3Aub2JqID0gbW9kZWwudHJhbnNmb3JtTmFtZVN0cmF0ZWd5Lm91dGdvaW5nKHByb3AuY2xzKSlcbiAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgICByZXR1cm4gbmV3IEluY2x1c2l2ZVByb3BlcnR5Q29udGFpbmVyKFxuICAgICAgICB0aGlzLm1ldGEudGFyZ2V0LFxuICAgICAgICB0aGlzLm91dGdvaW5nLFxuICAgICAgICBzZXJpYWxpemVQcmVkaWNhdGUsXG4gICAgICAgIHJlbmFtZVxuICAgICAgKTtcbiAgICB9XG4gIH0pXG4gIHByb3RlY3RlZCBvdXRnb2luZ0NvbnRhaW5lcjogU2VyaWFsaXplckNvbnRleHQ7XG5cbiAgY29uc3RydWN0b3IocHJvdGVjdGVkIG1ldGE6IFRhcmdldE1ldGFkYXRhPFQsIFo+KSB7fVxuXG4gIHNlcmlhbGl6ZShtYXBwZXI6IEJhc2VTZXJpYWxpemVyKTogYW55IHtcbiAgICByZXR1cm4gbWFwcGVyLnNlcmlhbGl6ZSh0aGlzLm91dGdvaW5nQ29udGFpbmVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXNlcmlhbGl6ZSBhIHNpbmdsZSB0YXJnZXQuXG4gICAqIERvZXMgbm90IHN1cHBvcnQgY29sbGVjdGlvbiBkZXNlcmlhbGl6YXRpb24sIGlmIG1hcHBlciBpcyBhIGNvbGxlY3Rpb24gd2lsbCB0aHJvdy5cbiAgICogQHBhcmFtIG1hcHBlclxuICAgKiBAcGFyYW0gdGFyZ2V0XG4gICAqL1xuICBkZXNlcmlhbGl6ZShtYXBwZXI6IEJhc2VEZXNlcmlhbGl6ZXIsIHRhcmdldDogYW55KTogdm9pZCB7XG4gICAgY29uc3QgY2IgPSAocHJvcDogUG9DbGFzc1Byb3BlcnR5TWFwKSA9PiB7XG4gICAgICBjb25zdCBwcm9wTWV0YSA9IChwcm9wLnByb3AgJiYgcHJvcC5wcm9wLmZvcmVpZ25LZXlPZikgfHwgcHJvcC5wcm9wO1xuICAgICAgdGFyZ2V0W3Byb3AuY2xzXSA9IHRyYW5zZm9ybVZhbHVlSW4oXG4gICAgICAgIG1hcHBlci5nZXRWYWx1ZShwcm9wLm9iaiwgcHJvcE1ldGEpLFxuICAgICAgICBwcm9wTWV0YVxuICAgICAgKTtcbiAgICB9O1xuXG4gICAgaWYgKGlzRnVuY3Rpb24obWFwcGVyLnNldFJlZikpIHtcbiAgICAgIG1hcHBlci5zZXRSZWYodGFyZ2V0KTtcbiAgICB9XG5cbiAgICBpZiAobWFwcGVyLnJhdyA9PT0gdHJ1ZSkge1xuICAgICAgdGhpcy5pbmNvbWluZ0NvbnRhaW5lci5mb3JFYWNoUmF3KG1hcHBlci5nZXRLZXlzKCksIGNiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5pbmNvbWluZ0NvbnRhaW5lci5mb3JFYWNoKG1hcHBlci5nZXRLZXlzKCksIGNiKTtcbiAgICB9XG5cbiAgICBpZiAoaXNGdW5jdGlvbihtYXBwZXIuZ2V0SWRlbnRpdHkpKSB7XG4gICAgICBpZiAodGhpcy5pZGVudGl0eSkge1xuICAgICAgICBjb25zdCBpZGVudCA9IHRyYW5zZm9ybVZhbHVlSW4oXG4gICAgICAgICAgbWFwcGVyLmdldElkZW50aXR5KCksXG4gICAgICAgICAgdGhpcy5pZGVudGl0eS5wcm9wXG4gICAgICAgICk7XG4gICAgICAgIGlmIChpZGVudCkge1xuICAgICAgICAgIHRhcmdldFt0aGlzLmlkZW50aXR5LmNsc10gPSBpZGVudDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuIl19