@orbit/jsonapi
Version:
JSON:API support for Orbit.
441 lines • 61 kB
JavaScript
import { deepSet } from '@orbit/utils';
import { Orbit, Assertion } from '@orbit/core';
import { buildSerializerSettingsFor } from '@orbit/serializers';
import { buildJSONAPISerializerFor } from './serializers/jsonapi-serializer-builder';
import { JSONAPISerializers } from './serializers/jsonapi-serializers';
const { deprecate } = Orbit;
/**
* @deprecated since v0.17, remove in v0.18
*/
export class JSONAPISerializer {
constructor(settings) {
deprecate("The 'JSONAPISerializer' class has deprecated. Use 'serializerFor' instead.");
const { schema, keyMap, serializers } = settings;
let serializerFor;
if (serializers) {
serializerFor = (type) => serializers[type];
}
const serializerSettingsFor = buildSerializerSettingsFor({
settingsByType: {
[JSONAPISerializers.ResourceField]: {
serializationOptions: { inflectors: ['dasherize'] }
},
[JSONAPISerializers.ResourceType]: {
serializationOptions: { inflectors: ['pluralize', 'dasherize'] }
}
}
});
this._schema = schema;
this._keyMap = keyMap;
this._serializerFor = buildJSONAPISerializerFor({
schema,
keyMap,
serializerFor,
serializerSettingsFor
});
}
get schema() {
return this._schema;
}
get keyMap() {
return this._keyMap;
}
get serializerFor() {
return this._serializerFor;
}
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
resourceKey(type) {
return 'id';
}
resourceType(type) {
return this.typeSerializer.serialize(type);
}
resourceRelationship(type, relationship) {
return this.fieldSerializer.serialize(relationship, { type });
}
resourceAttribute(type, attr) {
return this.fieldSerializer.serialize(attr, { type });
}
resourceIdentity(identity) {
return {
type: this.resourceType(identity.type),
id: this.resourceId(identity.type, identity.id)
};
}
resourceIds(type, ids) {
return ids.map((id) => this.resourceId(type, id));
}
resourceId(type, id) {
let resourceKey = this.resourceKey(type);
if (resourceKey === 'id') {
return id;
}
else if (this.keyMap) {
return this.keyMap.idToKey(type, resourceKey, id);
}
else {
throw new Assertion(`A keyMap is required to determine an id from the key '${resourceKey}'`);
}
}
recordId(type, resourceId) {
let resourceKey = this.resourceKey(type);
if (resourceKey === 'id') {
return resourceId;
}
let existingId;
if (this.keyMap) {
existingId = this.keyMap.keyToId(type, resourceKey, resourceId);
if (existingId) {
return existingId;
}
}
else {
throw new Assertion(`A keyMap is required to determine an id from the key '${resourceKey}'`);
}
return this._generateNewId(type, resourceKey, resourceId);
}
recordType(resourceType) {
return this.typeSerializer.deserialize(resourceType);
}
recordIdentity(resourceIdentity) {
let type = this.recordType(resourceIdentity.type);
let id = this.recordId(type, resourceIdentity.id);
return { type, id };
}
recordAttribute(type, resourceAttribute) {
return this.fieldSerializer.deserialize(resourceAttribute);
}
recordRelationship(type, resourceRelationship) {
return this.fieldSerializer.deserialize(resourceRelationship);
}
serialize(document) {
let data = document.data;
return {
data: Array.isArray(data)
? this.serializeRecords(data)
: this.serializeRecord(data)
};
}
serializeAtomicOperationsDocument(document) {
return {
'atomic:operations': this.serializeAtomicOperations(document.operations)
};
}
serializeAtomicOperations(operations) {
return operations.map((operation) => this.serializeAtomicOperation(operation));
}
serializeAtomicOperation(operation) {
return this.atomicOperationSerializer.serialize(operation);
}
serializeRecords(records) {
return records.map((record) => this.serializeRecord(record));
}
serializeRecord(record) {
const resource = {
type: this.resourceType(record.type)
};
const model = this._schema.getModel(record.type);
this.serializeId(resource, record, model);
this.serializeAttributes(resource, record, model);
this.serializeRelationships(resource, record, model);
return resource;
}
serializeIdentity(record) {
return {
type: this.resourceType(record.type),
id: this.resourceId(record.type, record.id)
};
}
serializeId(resource, record,
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
model) {
let value = this.resourceId(record.type, record.id);
if (value !== undefined) {
resource.id = value;
}
}
serializeAttributes(resource, record, model) {
if (record.attributes) {
Object.keys(record.attributes).forEach((attr) => {
this.serializeAttribute(resource, record, attr, model);
});
}
}
serializeAttribute(resource, record, attr, model) {
var _a, _b, _c;
let value = (_a = record.attributes) === null || _a === void 0 ? void 0 : _a[attr];
if (value === undefined) {
return;
}
const attrOptions = (_b = model.attributes) === null || _b === void 0 ? void 0 : _b[attr];
if (attrOptions === undefined) {
return;
}
const serializer = this.serializerFor(attrOptions.type || 'unknown');
if (serializer) {
const serializationOptions = (_c = attrOptions.serialization) !== null && _c !== void 0 ? _c : attrOptions.serializationOptions;
if (attrOptions.serializationOptions !== undefined) {
deprecate(`The attribute '${attr}' for '${record.type}' has been assigned \`serializationOptions\` in the schema. Use \`serialization\` instead.`);
}
value =
value === null
? null
: serializer.serialize(value, serializationOptions);
}
deepSet(resource, ['attributes', this.resourceAttribute(record.type, attr)], value);
}
serializeRelationships(resource, record, model) {
if (record.relationships) {
Object.keys(record.relationships).forEach((relationship) => {
this.serializeRelationship(resource, record, relationship, model);
});
}
}
serializeRelationship(resource, record, relationship, model) {
var _a, _b;
const value = (_a = record.relationships) === null || _a === void 0 ? void 0 : _a[relationship].data;
if (value === undefined) {
return;
}
if (((_b = model.relationships) === null || _b === void 0 ? void 0 : _b[relationship]) === undefined) {
return;
}
let data;
if (Array.isArray(value)) {
data = value.map((id) => this.resourceIdentity(id));
}
else if (value !== null) {
data = this.resourceIdentity(value);
}
else {
data = null;
}
const resourceRelationship = this.resourceRelationship(record.type, relationship);
deepSet(resource, ['relationships', resourceRelationship, 'data'], data);
}
deserialize(document, options) {
let result;
let data;
if (Array.isArray(document.data)) {
let primaryRecords = options === null || options === void 0 ? void 0 : options.primaryRecords;
if (primaryRecords) {
data = document.data.map((entry, i) => {
return this.deserializeResource(entry, primaryRecords === null || primaryRecords === void 0 ? void 0 : primaryRecords[i]);
});
}
else {
data = document.data.map((entry) => this.deserializeResource(entry));
}
}
else if (document.data !== null) {
let primaryRecord = options && options.primaryRecord;
if (primaryRecord) {
data = this.deserializeResource(document.data, primaryRecord);
}
else {
data = this.deserializeResource(document.data);
}
}
else {
data = null;
}
result = { data };
if (document.included) {
result.included = document.included.map((e) => this.deserializeResource(e));
}
if (document.links) {
result.links = document.links;
}
if (document.meta) {
result.meta = document.meta;
}
return result;
}
deserializeAtomicOperationsDocument(document) {
const result = {
operations: this.deserializeAtomicOperations(document['atomic:operations'])
};
if (document.links) {
result.links = document.links;
}
if (document.meta) {
result.meta = document.meta;
}
return result;
}
deserializeAtomicOperations(operations) {
return operations.map((operation) => this.deserializeAtomicOperation(operation));
}
deserializeAtomicOperation(operation) {
return this.atomicOperationSerializer.deserialize(operation);
}
deserializeResourceIdentity(resource, primaryRecord) {
let record;
const type = this.recordType(resource.type);
const resourceKey = this.resourceKey(type);
if (resourceKey === 'id') {
if (resource.id) {
record = { type, id: resource.id };
}
else {
throw new Assertion(`A resource has been enountered without an id`);
}
}
else if (this.keyMap) {
let id;
let keys;
if (resource.id) {
keys = {
[resourceKey]: resource.id
};
id =
(primaryRecord && primaryRecord.id) ||
this.keyMap.idFromKeys(type, keys) ||
this.schema.generateId(type);
}
else {
id =
(primaryRecord && primaryRecord.id) || this.schema.generateId(type);
}
record = { type, id };
if (keys) {
record.keys = keys;
}
}
else {
throw new Assertion(`A keyMap is required to determine an id from the key '${resourceKey}'`);
}
if (this.keyMap) {
this.keyMap.pushRecord(record);
}
return record;
}
deserializeResource(resource, primaryRecord) {
const record = this.deserializeResourceIdentity(resource, primaryRecord);
const model = this._schema.getModel(record.type);
this.deserializeAttributes(record, resource, model);
this.deserializeRelationships(record, resource, model);
this.deserializeLinks(record, resource, model);
this.deserializeMeta(record, resource, model);
return record;
}
deserializeAttributes(record, resource, model) {
if (resource.attributes) {
Object.keys(resource.attributes).forEach((resourceAttribute) => {
var _a;
let attribute = this.recordAttribute(record.type, resourceAttribute);
if (this.schema.hasAttribute(record.type, attribute)) {
let value = (_a = resource.attributes) === null || _a === void 0 ? void 0 : _a[resourceAttribute];
if (value !== undefined) {
this.deserializeAttribute(record, attribute, value, model);
}
}
});
}
}
deserializeAttribute(record, attr, value, model) {
var _a, _b;
record.attributes = record.attributes || {};
if (value !== undefined && value !== null) {
const attrOptions = (_a = model.attributes) === null || _a === void 0 ? void 0 : _a[attr];
if (attrOptions === undefined) {
return;
}
const serializer = this.serializerFor((attrOptions === null || attrOptions === void 0 ? void 0 : attrOptions.type) || 'unknown');
if (serializer) {
const deserializationOptions = (_b = attrOptions.deserialization) !== null && _b !== void 0 ? _b : attrOptions.deserializationOptions;
if (attrOptions.deserializationOptions !== undefined) {
deprecate(`The attribute '${attr}' for '${record.type}' has been assigned \`deserializationOptions\` in the schema. Use \`deserialization\` instead.`);
}
value = serializer.deserialize(value, deserializationOptions);
}
}
record.attributes[attr] = value;
}
deserializeRelationships(record, resource, model) {
if (resource.relationships) {
Object.keys(resource.relationships).forEach((resourceRel) => {
var _a;
let relationship = this.recordRelationship(record.type, resourceRel);
if (this.schema.hasRelationship(record.type, relationship)) {
let value = (_a = resource.relationships) === null || _a === void 0 ? void 0 : _a[resourceRel];
if (value !== undefined) {
this.deserializeRelationship(record, relationship, value, model);
}
}
});
}
}
deserializeRelationship(record, relationship, value,
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
model) {
let resourceData = value.data;
if (resourceData !== undefined) {
let data;
if (resourceData === null) {
data = null;
}
else if (Array.isArray(resourceData)) {
data = resourceData.map((resourceIdentity) => this.recordIdentity(resourceIdentity));
}
else {
data = this.recordIdentity(resourceData);
}
deepSet(record, ['relationships', relationship, 'data'], data);
}
let { links, meta } = value;
if (links !== undefined) {
deepSet(record, ['relationships', relationship, 'links'], links);
}
if (meta !== undefined) {
deepSet(record, ['relationships', relationship, 'meta'], meta);
}
}
deserializeLinks(record, resource,
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
model) {
if (resource.links) {
record.links = resource.links;
}
}
deserializeMeta(record, resource,
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
model) {
if (resource.meta) {
record.meta = resource.meta;
}
}
// Protected / Private
get resourceSerializer() {
return this.serializerFor(JSONAPISerializers.Resource);
}
get identitySerializer() {
return this.serializerFor(JSONAPISerializers.ResourceIdentity);
}
get typeSerializer() {
return this.serializerFor(JSONAPISerializers.ResourceType);
}
get fieldSerializer() {
return this.serializerFor(JSONAPISerializers.ResourceField);
}
get atomicOperationSerializer() {
return this.serializerFor(JSONAPISerializers.ResourceAtomicOperation);
}
_generateNewId(type, keyName, keyValue) {
let id = this.schema.generateId(type);
if (this.keyMap) {
this.keyMap.pushRecord({
type,
id,
keys: {
[keyName]: keyValue
}
});
}
else {
throw new Assertion(`A keyMap is required to generate ids for resource type '${type}'`);
}
return id;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianNvbmFwaS1zZXJpYWxpemVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2pzb25hcGktc2VyaWFsaXplci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsT0FBTyxFQUFRLE1BQU0sY0FBYyxDQUFDO0FBQzdDLE9BQU8sRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBUy9DLE9BQU8sRUFJTCwwQkFBMEIsRUFDM0IsTUFBTSxvQkFBb0IsQ0FBQztBQWU1QixPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSwwQ0FBMEMsQ0FBQztBQUNyRixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUl2RSxNQUFNLEVBQUUsU0FBUyxFQUFFLEdBQUcsS0FBSyxDQUFDO0FBYTVCOztHQUVHO0FBQ0gsTUFBTSxPQUFPLGlCQUFpQjtJQVk1QixZQUFZLFFBQW1DO1FBQzdDLFNBQVMsQ0FDUCw0RUFBNEUsQ0FDN0UsQ0FBQztRQUVGLE1BQU0sRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxHQUFHLFFBQVEsQ0FBQztRQUVqRCxJQUFJLGFBQTBDLENBQUM7UUFDL0MsSUFBSSxXQUFXLEVBQUU7WUFDZixhQUFhLEdBQUcsQ0FBQyxJQUFZLEVBQUUsRUFBRSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztTQUNyRDtRQUNELE1BQU0scUJBQXFCLEdBQUcsMEJBQTBCLENBQUM7WUFDdkQsY0FBYyxFQUFFO2dCQUNkLENBQUMsa0JBQWtCLENBQUMsYUFBYSxDQUFDLEVBQUU7b0JBQ2xDLG9CQUFvQixFQUFFLEVBQUUsVUFBVSxFQUFFLENBQUMsV0FBVyxDQUFDLEVBQUU7aUJBQ3BEO2dCQUNELENBQUMsa0JBQWtCLENBQUMsWUFBWSxDQUFDLEVBQUU7b0JBQ2pDLG9CQUFvQixFQUFFLEVBQUUsVUFBVSxFQUFFLENBQUMsV0FBVyxFQUFFLFdBQVcsQ0FB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O0lBRUQsSUFBYyxlQUFlO1FBQzNCLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FDdkIsa0JBQWtCLENBQUMsYUFBYSxDQUNDLENBQUM7SUFDdEMsQ0FBQztJQUVELElBQWMseUJBQXlCO1FBQ3JDLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FDdkIsa0JBQWtCLENBQUMsdUJBQXVCLENBQ1AsQ0FBQztJQUN4QyxDQUFDO0lBRVMsY0FBYyxDQUN0QixJQUFZLEVBQ1osT0FBZSxFQUNmLFFBQWdCO1FBRWhCLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRXRDLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUNmLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDO2dCQUNyQixJQUFJO2dCQUNKLEVBQUU7Z0JBQ0YsSUFBSSxFQUFFO29CQUNKLENBQUMsT0FBTyxDQUFDLEVBQUUsUUFBUTtpQkFDcEI7YUFDRixDQUFDLENBQUM7U0FDSjthQUFNO1lBQ0wsTUFBTSxJQUFJLFNBQVMsQ0FDakIsMkRBQTJELElBQUksR0FBRyxDQUNuRSxDQUFDO1NBQ0g7UUFFRCxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGRlZXBTZXQsIERpY3QgfSBmcm9tICdAb3JiaXQvdXRpbHMnO1xuaW1wb3J0IHsgT3JiaXQsIEFzc2VydGlvbiB9IGZyb20gJ0BvcmJpdC9jb3JlJztcbmltcG9ydCB7XG4gIFJlY29yZFNjaGVtYSxcbiAgUmVjb3JkS2V5TWFwLFxuICBJbml0aWFsaXplZFJlY29yZCxcbiAgUmVjb3JkSWRlbnRpdHksXG4gIFJlY29yZE9wZXJhdGlvbixcbiAgTW9kZWxEZWZpbml0aW9uXG59IGZyb20gJ0BvcmJpdC9yZWNvcmRzJztcbmltcG9ydCB7XG4gIFNlcmlhbGl6ZXIsXG4gIFNlcmlhbGl6ZXJGb3JGbixcbiAgU3RyaW5nU2VyaWFsaXplcixcbiAgYnVpbGRTZXJpYWxpemVyU2V0dGluZ3NGb3Jcbn0gZnJvbSAnQG9yYml0L3NlcmlhbGl6ZXJzJztcbmltcG9ydCB7XG4gIFJlc291cmNlLFxuICBSZXNvdXJjZURvY3VtZW50LFxuICBSZXNvdXJjZUlkZW50aXR5LFxuICBSZXNvdXJjZVJlbGF0aW9uc2hpcFxufSBmcm9tICcuL3Jlc291cmNlLWRvY3VtZW50JztcbmltcG9ydCB7XG4gIFJlc291cmNlQXRvbWljT3BlcmF0aW9uLFxuICBSZWNvcmRPcGVyYXRpb25zRG9jdW1lbnRcbn0gZnJvbSAnLi9yZXNvdXJjZS1vcGVyYXRpb25zJztcbmltcG9ydCB7IFJlc291cmNlQXRvbWljT3BlcmF0aW9uc0RvY3VtZW50IH0gZnJvbSAnLi9yZXNvdXJjZS1vcGVyYXRpb25zJztcbmltcG9ydCB7IFJlY29yZERvY3VtZW50IH0gZnJvbSAnLi9yZWNvcmQtZG9jdW1lbnQnO1xuaW1wb3J0IHsgSlNPTkFQSVJlc291cmNlU2VyaWFsaXplciB9IGZyb20gJy4vc2VyaWFsaXplcnMvanNvbmFwaS1yZXNvdXJjZS1zZXJpYWxpemVyJztcbmltcG9ydCB7IEpTT05BUElSZXNvdXJjZUlkZW50aXR5U2VyaWFsaXplciB9IGZyb20gJy4vc2VyaWFsaXplcnMvanNvbmFwaS1yZXNvdXJjZS1pZGVudGl0eS1zZXJpYWxpemVyJztcbmltcG9ydCB7IGJ1aWxkSlNPTkFQSVNlcmlhbGl6ZXJGb3IgfSBmcm9tICcuL3NlcmlhbGl6ZXJzL2pzb25hcGktc2VyaWFsaXplci1idWlsZGVyJztcbmltcG9ydCB7IEpTT05BUElTZXJpYWxpemVycyB9IGZyb20gJy4vc2VyaWFsaXplcnMvanNvbmFwaS1zZXJpYWxpemVycyc7XG5pbXBvcnQgeyBKU09OQVBJQXRvbWljT3BlcmF0aW9uU2VyaWFsaXplciB9IGZyb20gJy4vc2VyaWFsaXplcnMvanNvbmFwaS1hdG9taWMtb3BlcmF0aW9uLXNlcmlhbGl6ZXInO1xuaW1wb3J0IHsgSlNPTkFQSVJlc291cmNlRmllbGRTZXJpYWxpemVyIH0gZnJvbSAnLi9zZXJpYWxpemVycy9qc29uYXBpLXJlc291cmNlLWZpZWxkLXNlcmlhbGl6ZXInO1xuXG5jb25zdCB7IGRlcHJlY2F0ZSB9ID0gT3JiaXQ7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSlNPTkFQSVNlcmlhbGl6YXRpb25PcHRpb25zIHtcbiAgcHJpbWFyeVJlY29yZD86IEluaXRpYWxpemVkUmVjb3JkO1xuICBwcmltYXJ5UmVjb3Jkcz86IEluaXRpYWxpemVkUmVjb3JkW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSlNPTkFQSVNlcmlhbGl6ZXJTZXR0aW5ncyB7XG4gIHNjaGVtYTogUmVjb3JkU2NoZW1hO1xuICBrZXlNYXA/OiBSZWNvcmRLZXlNYXA7XG4gIHNlcmlhbGl6ZXJzPzogRGljdDxTZXJpYWxpemVyPjtcbn1cblxuLyoqXG4gKiBAZGVwcmVjYXRlZCBzaW5jZSB2MC4xNywgcmVtb3ZlIGluIHYwLjE4XG4gKi9cbmV4cG9ydCBjbGFzcyBKU09OQVBJU2VyaWFsaXplclxuICBpbXBsZW1lbnRzXG4gICAgU2VyaWFsaXplcjxcbiAgICAgIFJlY29yZERvY3VtZW50LFxuICAgICAgUmVzb3VyY2VEb2N1bWVudCxcbiAgICAgIEpTT05BUElTZXJpYWxpemF0aW9uT3B0aW9ucyxcbiAgICAgIEpTT05BUElTZXJpYWxpemF0aW9uT3B0aW9uc1xuICAgID4ge1xuICBwcm90ZWN0ZWQgX3NjaGVtYTogUmVjb3JkU2NoZW1hO1xuICBwcm90ZWN0ZWQgX2tleU1hcD86IFJlY29yZEtleU1hcDtcbiAgcHJvdGVjdGVkIF9zZXJpYWxpemVyRm9yOiBTZXJpYWxpemVyRm9yRm47XG5cbiAgY29uc3RydWN0b3Ioc2V0dGluZ3M6IEpTT05BUElTZXJpYWxpemVyU2V0dGluZ3MpIHtcbiAgICBkZXByZWNhdGUoXG4gICAgICBcIlRoZSAnSlNPTkFQSVNlcmlhbGl6ZXInIGNsYXNzIGhhcyBkZXByZWNhdGVkLiBVc2UgJ3NlcmlhbGl6ZXJGb3InIGluc3RlYWQuXCJcbiAgICApO1xuXG4gICAgY29uc3QgeyBzY2hlbWEsIGtleU1hcCwgc2VyaWFsaXplcnMgfSA9IHNldHRpbmdzO1xuXG4gICAgbGV0IHNlcmlhbGl6ZXJGb3I6IFNlcmlhbGl6ZXJGb3JGbiB8IHVuZGVmaW5lZDtcbiAgICBpZiAoc2VyaWFsaXplcnMpIHtcbiAgICAgIHNlcmlhbGl6ZXJGb3IgPSAodHlwZTogc3RyaW5nKSA9PiBzZXJpYWxpemVyc1t0eXBlXTtcbiAgICB9XG4gICAgY29uc3Qgc2VyaWFsaXplclNldHRpbmdzRm9yID0gYnVpbGRTZXJpYWxpemVyU2V0dGluZ3NGb3Ioe1xuICAgICAgc2V0dGluZ3NCeVR5cGU6IHtcbiAgICAgICAgW0pTT05BUElTZXJpYWxpemVycy5SZXNvdXJjZUZpZWxkXToge1xuICAgICAgICAgIHNlcmlhbGl6YXRpb25PcHRpb25zOiB7IGluZmxlY3RvcnM6IFsnZGFzaGVyaXplJ10gfVxuICAgICAgICB9LFxuICAgICAgICBbSlNPTkFQSVNlcmlhbGl6ZXJzLlJlc291cmNlVHlwZV06IHtcbiAgICAgICAgICBzZXJpYWxpemF0aW9uT3B0aW9uczogeyBpbmZsZWN0b3JzOiBbJ3BsdXJhbGl6ZScsICdkYXNoZXJpemUnXSB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHRoaXMuX3NjaGVtYSA9IHNjaGVtYTtcbiAgICB0aGlzLl9rZXlNYXAgPSBrZXlNYXA7XG4gICAgdGhpcy5fc2VyaWFsaXplckZvciA9IGJ1aWxkSlNPTkFQSVNlcmlhbGl6ZXJGb3Ioe1xuICAgICAgc2NoZW1hLFxuICAgICAga2V5TWFwLFxuICAgICAgc2VyaWFsaXplckZvcixcbiAgICAgIHNlcmlhbGl6ZXJTZXR0aW5nc0ZvclxuICAgIH0pO1xuICB9XG5cbiAgZ2V0IHNjaGVtYSgpOiBSZWNvcmRTY2hlbWEge1xuICAgIHJldHVybiB0aGlzLl9zY2hlbWE7XG4gIH1cblxuICBnZXQga2V5TWFwKCk6IFJlY29yZEtleU1hcCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuX2tleU1hcDtcbiAgfVxuXG4gIGdldCBzZXJpYWxpemVyRm9yKCk6IFNlcmlhbGl6ZXJGb3JGbiB7XG4gICAgcmV0dXJuIHRoaXMuX3NlcmlhbGl6ZXJGb3I7XG4gIH1cblxuICAvKiBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzICovXG4gIHJlc291cmNlS2V5KHR5cGU6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuICdpZCc7XG4gIH1cblxuICByZXNvdXJjZVR5cGUodHlwZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy50eXBlU2VyaWFsaXplci5zZXJpYWxpemUodHlwZSkgYXMgc3RyaW5nO1xuICB9XG5cbiAgcmVzb3VyY2VSZWxhdGlvbnNoaXAodHlwZTogc3RyaW5nIHwgdW5kZWZpbmVkLCByZWxhdGlvbnNoaXA6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuZmllbGRTZXJpYWxpemVyLnNlcmlhbGl6ZShyZWxhdGlvbnNoaXAsIHsgdHlwZSB9KSBhcyBzdHJpbmc7XG4gIH1cblxuICByZXNvdXJjZUF0dHJpYnV0ZSh0eXBlOiBzdHJpbmcgfCB1bmRlZmluZWQsIGF0dHI6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuZmllbGRTZXJpYWxpemVyLnNlcmlhbGl6ZShhdHRyLCB7IHR5cGUgfSkgYXMgc3RyaW5nO1xuICB9XG5cbiAgcmVzb3VyY2VJZGVudGl0eShpZGVudGl0eTogUmVjb3JkSWRlbnRpdHkpOiBSZXNvdXJjZSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IHRoaXMucmVzb3VyY2VUeXBlKGlkZW50aXR5LnR5cGUpLFxuICAgICAgaWQ6IHRoaXMucmVzb3VyY2VJZChpZGVudGl0eS50eXBlLCBpZGVudGl0eS5pZClcbiAgICB9O1xuICB9XG5cbiAgcmVzb3VyY2VJZHModHlwZTogc3RyaW5nLCBpZHM6IHN0cmluZ1tdKTogKHN0cmluZyB8IHVuZGVmaW5lZClbXSB7XG4gICAgcmV0dXJuIGlkcy5tYXAoKGlkKSA9PiB0aGlzLnJlc291cmNlSWQodHlwZSwgaWQpKTtcbiAgfVxuXG4gIHJlc291cmNlSWQodHlwZTogc3RyaW5nLCBpZDogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBsZXQgcmVzb3VyY2VLZXkgPSB0aGlzLnJlc291cmNlS2V5KHR5cGUpO1xuXG4gICAgaWYgKHJlc291cmNlS2V5ID09PSAnaWQnKSB7XG4gICAgICByZXR1cm4gaWQ7XG4gICAgfSBlbHNlIGlmICh0aGlzLmtleU1hcCkge1xuICAgICAgcmV0dXJuIHRoaXMua2V5TWFwLmlkVG9LZXkodHlwZSwgcmVzb3VyY2VLZXksIGlkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbihcbiAgICAgICAgYEEga2V5TWFwIGlzIHJlcXVpcmVkIHRvIGRldGVybWluZSBhbiBpZCBmcm9tIHRoZSBrZXkgJyR7cmVzb3VyY2VLZXl9J2BcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgcmVjb3JkSWQodHlwZTogc3RyaW5nLCByZXNvdXJjZUlkOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGxldCByZXNvdXJjZUtleSA9IHRoaXMucmVzb3VyY2VLZXkodHlwZSk7XG5cbiAgICBpZiAocmVzb3VyY2VLZXkgPT09ICdpZCcpIHtcbiAgICAgIHJldHVybiByZXNvdXJjZUlkO1xuICAgIH1cblxuICAgIGxldCBleGlzdGluZ0lkO1xuICAgIGlmICh0aGlzLmtleU1hcCkge1xuICAgICAgZXhpc3RpbmdJZCA9IHRoaXMua2V5TWFwLmtleVRvSWQodHlwZSwgcmVzb3VyY2VLZXksIHJlc291cmNlSWQpO1xuICAgICAgaWYgKGV4aXN0aW5nSWQpIHtcbiAgICAgICAgcmV0dXJuIGV4aXN0aW5nSWQ7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93IG5ldyBBc3NlcnRpb24oXG4gICAgICAgIGBBIGtleU1hcCBpcyByZXF1aXJlZCB0byBkZXRlcm1pbmUgYW4gaWQgZnJvbSB0aGUga2V5ICcke3Jlc291cmNlS2V5fSdgXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9nZW5lcmF0ZU5ld0lkKHR5cGUsIHJlc291cmNlS2V5LCByZXNvdXJjZUlkKTtcbiAgfVxuXG4gIHJlY29yZFR5cGUocmVzb3VyY2VUeXBlOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnR5cGVTZXJpYWxpemVyLmRlc2VyaWFsaXplKHJlc291cmNlVHlwZSkgYXMgc3RyaW5nO1xuICB9XG5cbiAgcmVjb3JkSWRlbnRpdHkocmVzb3VyY2VJZGVudGl0eTogUmVzb3VyY2VJZGVudGl0eSk6IFJlY29yZElkZW50aXR5IHtcbiAgICBsZXQgdHlwZSA9IHRoaXMucmVjb3JkVHlwZShyZXNvdXJjZUlkZW50aXR5LnR5cGUpO1xuICAgIGxldCBpZCA9IHRoaXMucmVjb3JkSWQodHlwZSwgcmVzb3VyY2VJZGVudGl0eS5pZCk7XG4gICAgcmV0dXJuIHsgdHlwZSwgaWQgfTtcbiAgfVxuXG4gIHJlY29yZEF0dHJpYnV0ZSh0eXBlOiBzdHJpbmcsIHJlc291cmNlQXR0cmlidXRlOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLmZpZWxkU2VyaWFsaXplci5kZXNlcmlhbGl6ZShyZXNvdXJjZUF0dHJpYnV0ZSkgYXMgc3RyaW5nO1xuICB9XG5cbiAgcmVjb3JkUmVsYXRpb25zaGlwKHR5cGU6IHN0cmluZywgcmVzb3VyY2VSZWxhdGlvbnNoaXA6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuZmllbGRTZXJpYWxpemVyLmRlc2VyaWFsaXplKHJlc291cmNlUmVsYXRpb25zaGlwKSBhcyBzdHJpbmc7XG4gIH1cblxuICBzZXJpYWxpemUoZG9jdW1lbnQ6IFJlY29yZERvY3VtZW50KTogUmVzb3VyY2VEb2N1bWVudCB7XG4gICAgbGV0IGRhdGEgPSBkb2N1bWVudC5kYXRhO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGRhdGE6IEFycmF5LmlzQXJyYXkoZGF0YSlcbiAgICAgICAgPyB0aGlzLnNlcmlhbGl6ZVJlY29yZHMoZGF0YSBhcyBJbml0aWFsaXplZFJlY29yZFtdKVxuICAgICAgICA6IHRoaXMuc2VyaWFsaXplUmVjb3JkKGRhdGEgYXMgSW5pdGlhbGl6ZWRSZWNvcmQpXG4gICAgfTtcbiAgfVxuXG4gIHNlcmlhbGl6ZUF0b21pY09wZXJhdGlvbnNEb2N1bWVudChcbiAgICBkb2N1bWVudDogUmVjb3JkT3BlcmF0aW9uc0RvY3VtZW50XG4gICk6IFJlc291cmNlQXRvbWljT3BlcmF0aW9uc0RvY3VtZW50IHtcbiAgICByZXR1cm4ge1xuICAgICAgJ2F0b21pYzpvcGVyYXRpb25zJzogdGhpcy5zZXJpYWxpemVBdG9taWNPcGVyYXRpb25zKGRvY3VtZW50Lm9wZXJhdGlvbnMpXG4gICAgfTtcbiAgfVxuXG4gIHNlcmlhbGl6ZUF0b21pY09wZXJhdGlvbnMoXG4gICAgb3BlcmF0aW9uczogUmVjb3JkT3BlcmF0aW9uW11cbiAgKTogUmVzb3VyY2VBdG9taWNPcGVyYXRpb25bXSB7XG4gICAgcmV0dXJuIG9wZXJhdGlvbnMubWFwKChvcGVyYXRpb24pID0+XG4gICAgICB0aGlzLnNlcmlhbGl6ZUF0b21pY09wZXJhdGlvbihvcGVyYXRpb24pXG4gICAgKTtcbiAgfVxuXG4gIHNlcmlhbGl6ZUF0b21pY09wZXJhdGlvbihcbiAgICBvcGVyYXRpb246IFJlY29yZE9wZXJhdGlvblxuICApOiBSZXNvdXJjZUF0b21pY09wZXJhdGlvbiB7XG4gICAgcmV0dXJuIHRoaXMuYXRvbWljT3BlcmF0aW9uU2VyaWFsaXplci5zZXJpYWxpemUob3BlcmF0aW9uKTtcbiAgfVxuXG4gIHNlcmlhbGl6ZVJlY29yZHMocmVjb3JkczogSW5pdGlhbGl6ZWRSZWNvcmRbXSk6IFJlc291cmNlW10ge1xuICAgIHJldHVybiByZWNvcmRzLm1hcCgocmVjb3JkKSA9PiB0aGlzLnNlcmlhbGl6ZVJlY29yZChyZWNvcmQpKTtcbiAgfVxuXG4gIHNlcmlhbGl6ZVJlY29yZChyZWNvcmQ6IEluaXRpYWxpemVkUmVjb3JkKTogUmVzb3VyY2Uge1xuICAgIGNvbnN0IHJlc291cmNlOiBSZXNvdXJjZSA9IHtcbiAgICAgIHR5cGU6IHRoaXMucmVzb3VyY2VUeXBlKHJlY29yZC50eXBlKVxuICAgIH07XG4gICAgY29uc3QgbW9kZWw6IE1vZGVsRGVmaW5pdGlvbiA9IHRoaXMuX3NjaGVtYS5nZXRNb2RlbChyZWNvcmQudHlwZSk7XG5cbiAgICB0aGlzLnNlcmlhbGl6ZUlkKHJlc291cmNlLCByZWNvcmQsIG1vZGVsKTtcbiAgICB0aGlzLnNlcmlhbGl6ZUF0dHJpYnV0ZXMocmVzb3VyY2UsIHJlY29yZCwgbW9kZWwpO1xuICAgIHRoaXMuc2VyaWFsaXplUmVsYXRpb25zaGlwcyhyZXNvdXJjZSwgcmVjb3JkLCBtb2RlbCk7XG5cbiAgICByZXR1cm4gcmVzb3VyY2U7XG4gIH1cblxuICBzZXJpYWxpemVJZGVudGl0eShyZWNvcmQ6IEluaXRpYWxpemVkUmVjb3JkKTogUmVzb3VyY2Uge1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiB0aGlzLnJlc291cmNlVHlwZShyZWNvcmQudHlwZSksXG4gICAgICBpZDogdGhpcy5yZXNvdXJjZUlkKHJlY29yZC50eXBlLCByZWNvcmQuaWQpXG4gICAgfTtcbiAgfVxuXG4gIHNlcmlhbGl6ZUlkKFxuICAgIHJlc291cmNlOiBSZXNvdXJjZSxcbiAgICByZWNvcmQ6IFJlY29yZElkZW50aXR5LFxuICAgIC8qIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnMgKi9cbiAgICBtb2RlbDogTW9kZWxEZWZpbml0aW9uXG4gICk6IHZvaWQge1xuICAgIGxldCB2YWx1ZSA9IHRoaXMucmVzb3VyY2VJZChyZWNvcmQudHlwZSwgcmVjb3JkLmlkKTtcbiAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmVzb3VyY2UuaWQgPSB2YWx1ZTtcbiAgICB9XG4gIH1cblxuICBzZXJpYWxpemVBdHRyaWJ1dGVzKFxuICAgIHJlc291cmNlOiBSZXNvdXJjZSxcbiAgICByZWNvcmQ6IEluaXRpYWxpemVkUmVjb3JkLFxuICAgIG1vZGVsOiBNb2RlbERlZmluaXRpb25cbiAgKTogdm9pZCB7XG4gICAgaWYgKHJlY29yZC5hdHRyaWJ1dGVzKSB7XG4gICAgICBPYmplY3Qua2V5cyhyZWNvcmQuYXR0cmlidXRlcykuZm9yRWFjaCgoYXR0cikgPT4ge1xuICAgICAgICB0aGlzLnNlcmlhbGl6ZUF0dHJpYnV0ZShyZXNvdXJjZSwgcmVjb3JkLCBhdHRyLCBtb2RlbCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBzZXJpYWxpemVBdHRyaWJ1dGUoXG4gICAgcmVzb3VyY2U6IFJlc291cmNlLFxuICAgIHJlY29yZDogSW5pdGlhbGl6ZWRSZWNvcmQsXG4gICAgYXR0cjogc3RyaW5nLFxuICAgIG1vZGVsOiBNb2RlbERlZmluaXRpb25cbiAgKTogdm9pZCB7XG4gICAgbGV0IHZhbHVlOiBhbnkgPSByZWNvcmQuYXR0cmlidXRlcz8uW2F0dHJdO1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGF0dHJPcHRpb25zID0gbW9kZWwuYXR0cmlidXRlcz8uW2F0dHJdO1xuICAgIGlmIChhdHRyT3B0aW9ucyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHNlcmlhbGl6ZXIgPSB0aGlzLnNlcmlhbGl6ZXJGb3IoYXR0ck9wdGlvbnMudHlwZSB8fCAndW5rbm93bicpO1xuICAgIGlmIChzZXJpYWxpemVyKSB7XG4gICAgICBjb25zdCBzZXJpYWxpemF0aW9uT3B0aW9ucyA9XG4gICAgICAgIGF0dHJPcHRpb25zLnNlcmlhbGl6YXRpb24gPz8gKGF0dHJPcHRpb25zIGFzIGFueSkuc2VyaWFsaXphdGlvbk9wdGlvbnM7XG5cbiAgICAgIGlmICgoYXR0ck9wdGlvbnMgYXMgYW55KS5zZXJpYWxpemF0aW9uT3B0aW9ucyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGRlcHJlY2F0ZShcbiAgICAgICAgICBgVGhlIGF0dHJpYnV0ZSAnJHthdHRyfScgZm9yICcke3JlY29yZC50eXBlfScgaGFzIGJlZW4gYXNzaWduZWQgXFxgc2VyaWFsaXphdGlvbk9wdGlvbnNcXGAgaW4gdGhlIHNjaGVtYS4gVXNlIFxcYHNlcmlhbGl6YXRpb25cXGAgaW5zdGVhZC5gXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIHZhbHVlID1cbiAgICAgICAgdmFsdWUgPT09IG51bGxcbiAgICAgICAgICA/IG51bGxcbiAgICAgICAgICA6IHNlcmlhbGl6ZXIuc2VyaWFsaXplKHZhbHVlLCBzZXJpYWxpemF0aW9uT3B0aW9ucyk7XG4gICAgfVxuICAgIGRlZXBTZXQoXG4gICAgICByZXNvdXJjZSxcbiAgICAgIFsnYXR0cmlidXRlcycsIHRoaXMucmVzb3VyY2VBdHRyaWJ1dGUocmVjb3JkLnR5cGUsIGF0dHIpXSxcbiAgICAgIHZhbHVlXG4gICAgKTtcbiAgfVxuXG4gIHNlcmlhbGl6ZVJlbGF0aW9uc2hpcHMoXG4gICAgcmVzb3VyY2U6IFJlc291cmNlLFxuICAgIHJlY29yZDogSW5pdGlhbGl6ZWRSZWNvcmQsXG4gICAgbW9kZWw6IE1vZGVsRGVmaW5pdGlvblxuICApOiB2b2lkIHtcbiAgICBpZiAocmVjb3JkLnJlbGF0aW9uc2hpcHMpIHtcbiAgICAgIE9iamVjdC5rZXlzKHJlY29yZC5yZWxhdGlvbnNoaXBzKS5mb3JFYWNoKChyZWxhdGlvbnNoaXApID0+IHtcbiAgICAgICAgdGhpcy5zZXJpYWxpemVSZWxhdGlvbnNoaXAocmVzb3VyY2UsIHJlY29yZCwgcmVsYXRpb25zaGlwLCBtb2RlbCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBzZXJpYWxpemVSZWxhdGlvbnNoaXAoXG4gICAgcmVzb3VyY2U6IFJlc291cmNlLFxuICAgIHJlY29yZDogSW5pdGlhbGl6ZWRSZWNvcmQsXG4gICAgcmVsYXRpb25zaGlwOiBzdHJpbmcsXG4gICAgbW9kZWw6IE1vZGVsRGVmaW5pdGlvblxuICApOiB2b2lkIHtcbiAgICBjb25zdCB2YWx1ZSA9IHJlY29yZC5yZWxhdGlvbnNoaXBzPy5bcmVsYXRpb25zaGlwXS5kYXRhO1xuXG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKG1vZGVsLnJlbGF0aW9uc2hpcHM/LltyZWxhdGlvbnNoaXBdID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsZXQgZGF0YTtcblxuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgZGF0YSA9ICh2YWx1ZSBhcyBSZWNvcmRJZGVudGl0eVtdKS5tYXAoKGlkKSA9PiB0aGlzLnJlc291cmNlSWRlbnRpdHkoaWQpKTtcbiAgICB9IGVsc2UgaWYgKHZhbHVlICE9PSBudWxsKSB7XG4gICAgICBkYXRhID0gdGhpcy5yZXNvdXJjZUlkZW50aXR5KHZhbHVlIGFzIFJlY29yZElkZW50aXR5KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGF0YSA9IG51bGw7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzb3VyY2VSZWxhdGlvbnNoaXAgPSB0aGlzLnJlc291cmNlUmVsYXRpb25zaGlwKFxuICAgICAgcmVjb3JkLnR5cGUsXG4gICAgICByZWxhdGlvbnNoaXBcbiAgICApO1xuXG4gICAgZGVlcFNldChyZXNvdXJjZSwgWydyZWxhdGlvbnNoaXBzJywgcmVzb3VyY2VSZWxhdGlvbnNoaXAsICdkYXRhJ10sIGRhdGEpO1xuICB9XG5cbiAgZGVzZXJpYWxpemUoXG4gICAgZG9jdW1lbnQ6IFJlc291cmNlRG9jdW1lbnQsXG4gICAgb3B0aW9ucz86IEpTT05BUElTZXJpYWxpemF0aW9uT3B0aW9uc1xuICApOiBSZWNvcmREb2N1bWVudCB7XG4gICAgbGV0IHJlc3VsdDogUmVjb3JkRG9jdW1lbnQ7XG4gICAgbGV0IGRhdGE7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShkb2N1bWVudC5kYXRhKSkge1xuICAgICAgbGV0IHByaW1hcnlSZWNvcmRzID0gb3B0aW9ucz8ucHJpbWFyeVJlY29yZHM7XG4gICAgICBpZiAocHJpbWFyeVJlY29yZHMpIHtcbiAgICAgICAgZGF0YSA9IChkb2N1bWVudC5kYXRhIGFzIFJlc291cmNlW10pLm1hcCgoZW50cnksIGkpID0+IHtcbiAgICAgICAgICByZXR1cm4gdGhpcy5kZXNlcmlhbGl6ZVJlc291cmNlKGVudHJ5LCBwcmltYXJ5UmVjb3Jkcz8uW2ldKTtcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkYXRhID0gKGRvY3VtZW50LmRhdGEgYXMgUmVzb3VyY2VbXSkubWFwKChlbnRyeSkgPT5cbiAgICAgICAgICB0aGlzLmRlc2VyaWFsaXplUmVzb3VyY2UoZW50cnkpXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChkb2N1bWVudC5kYXRhICE9PSBudWxsKSB7XG4gICAgICBsZXQgcHJpbWFyeVJlY29yZCA9IG9wdGlvbnMgJiYgb3B0aW9ucy5wcmltYXJ5UmVjb3JkO1xuICAgICAgaWYgKHByaW1hcnlSZWNvcmQpIHtcbiAgICAgICAgZGF0YSA9IHRoaXMuZGVzZXJpYWxpemVSZXNvdXJjZShcbiAgICAgICAgICBkb2N1bWVudC5kYXRhIGFzIFJlc291cmNlLFxuICAgICAgICAgIHByaW1hcnlSZWNvcmRcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRhdGEgPSB0aGlzLmRlc2VyaWFsaXplUmVzb3VyY2UoZG9jdW1lbnQuZGF0YSBhcyBSZXNvdXJjZSk7XG4gICAgICB9XG4gICAgfS