UNPKG

@orbit/jsonapi

Version:

JSON:API support for Orbit.

441 lines 61 kB
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