@orbit/record-cache
Version:
Orbit base classes used to access and maintain a set of records.
282 lines • 51.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AsyncRecordCache = void 0;
const core_1 = require("@orbit/core");
const data_1 = require("@orbit/data");
const records_1 = require("@orbit/records");
const utils_1 = require("@orbit/utils");
const async_operation_processor_1 = require("./async-operation-processor");
const async_live_query_1 = require("./live-query/async-live-query");
const async_cache_integrity_processor_1 = require("./operation-processors/async-cache-integrity-processor");
const async_schema_consistency_processor_1 = require("./operation-processors/async-schema-consistency-processor");
const async_schema_validation_processor_1 = require("./operation-processors/async-schema-validation-processor");
const async_inverse_transform_operators_1 = require("./operators/async-inverse-transform-operators");
const async_query_operators_1 = require("./operators/async-query-operators");
const async_transform_operators_1 = require("./operators/async-transform-operators");
const record_cache_1 = require("./record-cache");
const { assert, deprecate } = core_1.Orbit;
class AsyncRecordCache extends record_cache_1.RecordCache {
constructor(settings) {
var _a, _b, _c;
super(settings);
this._queryOperators = (_a = settings.queryOperators) !== null && _a !== void 0 ? _a : async_query_operators_1.AsyncQueryOperators;
this._transformOperators =
(_b = settings.transformOperators) !== null && _b !== void 0 ? _b : async_transform_operators_1.AsyncTransformOperators;
this._inverseTransformOperators =
(_c = settings.inverseTransformOperators) !== null && _c !== void 0 ? _c : async_inverse_transform_operators_1.AsyncInverseTransformOperators;
this._debounceLiveQueries = settings.debounceLiveQueries !== false;
this._transformBuffer = settings.transformBuffer;
const processors = settings.processors
? settings.processors
: [async_schema_consistency_processor_1.AsyncSchemaConsistencyProcessor, async_cache_integrity_processor_1.AsyncCacheIntegrityProcessor];
if (settings.autoValidate !== false && settings.processors === undefined) {
processors.push(async_schema_validation_processor_1.AsyncSchemaValidationProcessor);
}
this._processors = processors.map((Processor) => {
let processor = new Processor(this);
assert('Each processor must extend AsyncOperationProcessor', processor instanceof async_operation_processor_1.AsyncOperationProcessor);
return processor;
});
}
get processors() {
return this._processors;
}
getQueryOperator(op) {
return this._queryOperators[op];
}
getTransformOperator(op) {
return this._transformOperators[op];
}
getInverseTransformOperator(op) {
return this._inverseTransformOperators[op];
}
async applyRecordChangesetAsync(changeset) {
const { setRecords, removeRecords, addInverseRelationships, removeInverseRelationships } = changeset;
const promises = [];
if (setRecords && setRecords.length > 0) {
promises.push(await this.setRecordsAsync(setRecords));
}
if (removeRecords && removeRecords.length > 0) {
promises.push(await this.removeRecordsAsync(removeRecords));
}
if (addInverseRelationships && addInverseRelationships.length > 0) {
promises.push(await this.addInverseRelationshipsAsync(addInverseRelationships));
}
if (removeInverseRelationships && removeInverseRelationships.length > 0) {
promises.push(await this.removeInverseRelationshipsAsync(removeInverseRelationships));
}
await Promise.all(promises);
}
async getRelatedRecordAsync(identity, relationship) {
const record = await this.getRecordAsync(identity);
if (record) {
return (0, utils_1.deepGet)(record, ['relationships', relationship, 'data']);
}
return undefined;
}
async getRelatedRecordsAsync(identity, relationship) {
const record = await this.getRecordAsync(identity);
if (record) {
return (0, utils_1.deepGet)(record, ['relationships', relationship, 'data']);
}
return undefined;
}
async query(queryOrExpressions, options, id) {
const query = (0, data_1.buildQuery)(queryOrExpressions, options, id, this._queryBuilder);
const response = await this._query(query, options);
if (options === null || options === void 0 ? void 0 : options.fullResponse) {
return response;
}
else {
return response.data;
}
}
async update(transformOrOperations, options, id) {
const transform = (0, data_1.buildTransform)(transformOrOperations, options, id, this._transformBuilder);
const response = await this._update(transform, options);
if (options === null || options === void 0 ? void 0 : options.fullResponse) {
return response;
}
else {
return response.data;
}
}
/**
* Patches the cache with an operation or operations.
*
* @deprecated since v0.17
*/
async patch(operationOrOperations) {
deprecate('AsyncRecordCache#patch has been deprecated. Use AsyncRecordCache#update instead.');
// TODO - Why is this `this` cast necessary for TS to understand the correct
// method overload?
const { data, details } = await this.update(operationOrOperations, {
fullResponse: true
});
return {
inverse: (details === null || details === void 0 ? void 0 : details.inverseOperations) || [],
data: Array.isArray(data) ? data : [data]
};
}
liveQuery(queryOrExpressions, options, id) {
const query = (0, data_1.buildQuery)(queryOrExpressions, options, id, this.queryBuilder);
let debounce = options && options.debounce;
if (typeof debounce !== 'boolean') {
debounce = this._debounceLiveQueries;
}
return new async_live_query_1.AsyncLiveQuery({
debounce,
cache: this,
query
});
}
/////////////////////////////////////////////////////////////////////////////
// Protected methods
/////////////////////////////////////////////////////////////////////////////
async _query(query,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
options) {
let data;
if (Array.isArray(query.expressions)) {
data = [];
for (let expression of query.expressions) {
const queryOperator = this.getQueryOperator(expression.op);
if (!queryOperator) {
throw new Error(`Unable to find query operator: ${expression.op}`);
}
data.push(await queryOperator(this, expression, this.getQueryOptions(query, expression)));
}
}
else {
const expression = query.expressions;
const queryOperator = this.getQueryOperator(expression.op);
if (!queryOperator) {
throw new Error(`Unable to find query operator: ${expression.op}`);
}
data = await queryOperator(this, expression, this.getQueryOptions(query, expression));
}
return { data: data };
}
async _update(transform, options) {
var _a, _b;
if ((_a = this.getTransformOptions(transform)) === null || _a === void 0 ? void 0 : _a.useBuffer) {
const buffer = await this._initTransformBuffer(transform);
buffer.startTrackingChanges();
const response = buffer.update(transform, {
fullResponse: true
});
const changes = buffer.stopTrackingChanges();
await this.applyRecordChangesetAsync(changes);
const { appliedOperations, appliedOperationResults } = response.details;
for (let i = 0, len = appliedOperations.length; i < len; i++) {
this.emit('patch', appliedOperations[i], appliedOperationResults[i]);
}
return response;
}
else {
const response = {
data: []
};
if (options === null || options === void 0 ? void 0 : options.fullResponse) {
response.details = {
appliedOperations: [],
appliedOperationResults: [],
inverseOperations: []
};
}
let data;
if (Array.isArray(transform.operations)) {
await this._applyTransformOperations(transform, transform.operations, response, true);
data = response.data;
}
else {
await this._applyTransformOperation(transform, transform.operations, response, true);
if (Array.isArray(response.data)) {
data = response.data[0];
}
}
if (options === null || options === void 0 ? void 0 : options.fullResponse) {
(_b = response.details) === null || _b === void 0 ? void 0 : _b.inverseOperations.reverse();
}
return {
...response,
data
};
}
}
_getTransformBuffer() {
if (this._transformBuffer === undefined) {
throw new core_1.Assertion('transformBuffer must be provided to cache via constructor settings');
}
return this._transformBuffer;
}
async _initTransformBuffer(transform) {
const buffer = this._getTransformBuffer();
const records = (0, records_1.recordsReferencedByOperations)((0, utils_1.toArray)(transform.operations));
const inverseRelationships = await this.getInverseRelationshipsAsync(records);
const relatedRecords = inverseRelationships.map((ir) => ir.record);
Array.prototype.push.apply(records, relatedRecords);
buffer.resetState();
buffer.setRecordsSync(await this.getRecordsAsync(records));
buffer.addInverseRelationshipsSync(inverseRelationships);
return buffer;
}
async _applyTransformOperations(transform, ops, response, primary = false) {
for (let op of ops) {
await this._applyTransformOperation(transform, op, response, primary);
}
}
async _applyTransformOperation(transform, operation, response, primary = false) {
var _a, _b, _c, _d;
if (operation instanceof data_1.OperationTerm) {
operation = operation.toOperation();
}
for (let processor of this._processors) {
await processor.validate(operation);
}
const inverseTransformOperator = this.getInverseTransformOperator(operation.op);
const inverseOp = await inverseTransformOperator(this, operation, this.getTransformOptions(transform, operation));
if (inverseOp) {
(_b = (_a = response.details) === null || _a === void 0 ? void 0 : _a.inverseOperations) === null || _b === void 0 ? void 0 : _b.push(inverseOp);
// Query and perform related `before` operations
for (let processor of this._processors) {
await this._applyTransformOperations(transform, await processor.before(operation), response);
}
// Query related `after` operations before performing
// the requested operation. These will be applied on success.
let preparedOps = [];
for (let processor of this._processors) {
preparedOps.push(await processor.after(operation));
}
// Perform the requested operation
let transformOperator = this.getTransformOperator(operation.op);
let data = await transformOperator(this, operation, this.getTransformOptions(transform, operation));
if (primary) {
(_c = response.data) === null || _c === void 0 ? void 0 : _c.push(data);
}
if (response.details) {
response.details.appliedOperationResults.push(data);
response.details.appliedOperations.push(operation);
}
// Query and perform related `immediate` operations
for (let processor of this._processors) {
await processor.immediate(operation);
}
// Emit event
this.emit('patch', operation, data);
// Perform prepared operations after performing the requested operation
for (let ops of preparedOps) {
await this._applyTransformOperations(transform, ops, response);
}
// Query and perform related `finally` operations
for (let processor of this._processors) {
await this._applyTransformOperations(transform, await processor.finally(operation), response);
}
}
else if (primary) {
(_d = response.data) === null || _d === void 0 ? void 0 : _d.push(undefined);
}
}
}
exports.AsyncRecordCache = AsyncRecordCache;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXN5bmMtcmVjb3JkLWNhY2hlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FzeW5jLXJlY29yZC1jYWNoZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxzQ0FBK0M7QUFDL0Msc0NBVXFCO0FBQ3JCLDRDQWlCd0I7QUFDeEIsd0NBQXNEO0FBQ3RELDJFQUdxQztBQUNyQyxvRUFBK0Q7QUFDL0QsNEdBQXNHO0FBQ3RHLGtIQUE0RztBQUM1RyxnSEFBMEc7QUFDMUcscUdBR3VEO0FBQ3ZELDZFQUcyQztBQUMzQyxxRkFHK0M7QUFNL0MsaURBS3dCO0FBSXhCLE1BQU0sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLEdBQUcsWUFBSyxDQUFDO0FBZ0JwQyxNQUFzQixnQkFRcEIsU0FBUSwwQkFBMkI7SUFZbkMsWUFBWSxRQUFrRDs7UUFDNUQsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRWhCLElBQUksQ0FBQyxlQUFlLEdBQUcsTUFBQSxRQUFRLENBQUMsY0FBYyxtQ0FBSSwyQ0FBbUIsQ0FBQztRQUN0RSxJQUFJLENBQUMsbUJBQW1CO1lBQ3RCLE1BQUEsUUFBUSxDQUFDLGtCQUFrQixtQ0FBSSxtREFBdUIsQ0FBQztRQUN6RCxJQUFJLENBQUMsMEJBQTBCO1lBQzdCLE1BQUEsUUFBUSxDQUFDLHlCQUF5QixtQ0FBSSxrRUFBOEIsQ0FBQztRQUN2RSxJQUFJLENBQUMsb0JBQW9CLEdBQUcsUUFBUSxDQUFDLG1CQUFtQixLQUFLLEtBQUssQ0FBQztRQUNuRSxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsUUFBUSxDQUFDLGVBQWUsQ0FBQztRQUVqRCxNQUFNLFVBQVUsR0FBbUMsUUFBUSxDQUFDLFVBQVU7WUFDcEUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxVQUFVO1lBQ3JCLENBQUMsQ0FBQyxDQUFDLG9FQUErQixFQUFFLDhEQUE0QixDQUFDLENBQUM7UUFFcEUsSUFBSSxRQUFRLENBQUMsWUFBWSxLQUFLLEtBQUssSUFB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QUksQ0FBQyxPQUFPLEVBQUUsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBRXBDLHVFQUF1RTtZQUN2RSxLQUFLLElBQUksR0FBRyxJQUFJLFdBQVcsRUFBRTtnQkFDM0IsTUFBTSxJQUFJLENBQUMseUJBQXlCLENBQUMsU0FBUyxFQUFFLEdBQUcsRUFBRSxRQUFRLENBQUMsQ0FBQzthQUNoRTtZQUVELGlEQUFpRDtZQUNqRCxLQUFLLElBQUksU0FBUyxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUU7Z0JBQ3RDLE1BQU0sSUFBSSxDQUFDLHlCQUF5QixDQUNsQyxTQUFTLEVBQ1QsTUFBTSxTQUFTLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUNsQyxRQUFRLENBQ1QsQ0FBQzthQUNIO1NBQ0Y7YUFBTSxJQUFJLE9BQU8sRUFBRTtZQUNsQixNQUFBLFFBQVEsQ0FBQyxJQUFJLDBDQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztTQUNoQztJQUNILENBQUM7Q0FDRjtBQTNoQkQsNENBMmhCQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFzc2VydGlvbiwgT3JiaXQgfSBmcm9tICdAb3JiaXQvY29yZSc7XG5pbXBvcnQge1xuICBidWlsZFF1ZXJ5LFxuICBidWlsZFRyYW5zZm9ybSxcbiAgRGVmYXVsdFJlcXVlc3RPcHRpb25zLFxuICBGdWxsUmVxdWVzdE9wdGlvbnMsXG4gIEZ1bGxSZXNwb25zZSxcbiAgT3BlcmF0aW9uVGVybSxcbiAgUXVlcnlPckV4cHJlc3Npb25zLFxuICBSZXF1ZXN0T3B0aW9ucyxcbiAgVHJhbnNmb3JtT3JPcGVyYXRpb25zXG59IGZyb20gJ0BvcmJpdC9kYXRhJztcbmltcG9ydCB7XG4gIEFzeW5jUmVjb3JkUXVlcnlhYmxlLFxuICBBc3luY1JlY29yZFVwZGF0YWJsZSxcbiAgSW5pdGlhbGl6ZWRSZWNvcmQsXG4gIFJlY29yZElkZW50aXR5LFxuICBSZWNvcmRPcGVyYXRpb24sXG4gIFJlY29yZE9wZXJhdGlvblJlc3VsdCxcbiAgUmVjb3JkT3BlcmF0aW9uVGVybSxcbiAgUmVjb3JkUXVlcnksXG4gIFJlY29yZFF1ZXJ5QnVpbGRlcixcbiAgUmVjb3JkUXVlcnlFeHByZXNzaW9uLFxuICBSZWNvcmRRdWVyeVJlc3VsdCxcbiAgcmVjb3Jkc1JlZmVyZW5jZWRCeU9wZXJhdGlvbnMsXG4gIFJlY29yZFRyYW5zZm9ybSxcbiAgUmVjb3JkVHJhbnNmb3JtQnVpbGRlcixcbiAgUmVjb3JkVHJhbnNmb3JtQnVpbGRlckZ1bmMsXG4gIFJlY29yZFRyYW5zZm9ybVJlc3VsdFxufSBmcm9tICdAb3JiaXQvcmVjb3Jkcyc7XG5pbXBvcnQgeyBkZWVwR2V0LCBEaWN0LCB0b0FycmF5IH0gZnJvbSAnQG9yYml0L3V0aWxzJztcbmltcG9ydCB7XG4gIEFzeW5jT3BlcmF0aW9uUHJvY2Vzc29yLFxuICBBc3luY09wZXJhdGlvblByb2Nlc3NvckNsYXNzXG59IGZyb20gJy4vYXN5bmMtb3BlcmF0aW9uLXByb2Nlc3Nvcic7XG5pbXBvcnQgeyBBc3luY0xpdmVRdWVyeSB9IGZyb20gJy4vbGl2ZS1xdWVyeS9hc3luYy1saXZlLXF1ZXJ5JztcbmltcG9ydCB7IEFzeW5jQ2FjaGVJbnRlZ3JpdHlQcm9jZXNzb3IgfSBmcm9tICcuL29wZXJhdGlvbi1wcm9jZXNzb3JzL2FzeW5jLWNhY2hlLWludGVncml0eS1wcm9jZXNzb3InO1xuaW1wb3J0IHsgQXN5bmNTY2hlbWFDb25zaXN0ZW5jeVByb2Nlc3NvciB9IGZyb20gJy4vb3BlcmF0aW9uLXByb2Nlc3NvcnMvYXN5bmMtc2NoZW1hLWNvbnNpc3RlbmN5LXByb2Nlc3Nvcic7XG5pbXBvcnQgeyBBc3luY1NjaGVtYVZhbGlkYXRpb25Qcm9jZXNzb3IgfSBmcm9tICcuL29wZXJhdGlvbi1wcm9jZXNzb3JzL2FzeW5jLXNjaGVtYS12YWxpZGF0aW9uLXByb2Nlc3Nvcic7XG5pbXBvcnQge1xuICBBc3luY0ludmVyc2VUcmFuc2Zvcm1PcGVyYXRvcixcbiAgQXN5bmNJbnZlcnNlVHJhbnNmb3JtT3BlcmF0b3JzXG59IGZyb20gJy4vb3BlcmF0b3JzL2FzeW5jLWludmVyc2UtdHJhbnNmb3JtLW9wZXJhdG9ycyc7XG5pbXBvcnQge1xuICBBc3luY1F1ZXJ5T3BlcmF0b3IsXG4gIEFzeW5jUXVlcnlPcGVyYXRvcnNcbn0gZnJvbSAnLi9vcGVyYXRvcnMvYXN5bmMtcXVlcnktb3BlcmF0b3JzJztcbmltcG9ydCB7XG4gIEFzeW5jVHJhbnNmb3JtT3BlcmF0b3IsXG4gIEFzeW5jVHJhbnNmb3JtT3BlcmF0b3JzXG59IGZyb20gJy4vb3BlcmF0b3JzL2FzeW5jLXRyYW5zZm9ybS1vcGVyYXRvcnMnO1xuaW1wb3J0IHtcbiAgQXN5bmNSZWNvcmRBY2Nlc3NvcixcbiAgUmVjb3JkQ2hhbmdlc2V0LFxuICBSZWNvcmRSZWxhdGlvbnNoaXBJZGVudGl0eVxufSBmcm9tICcuL3JlY29yZC1hY2Nlc3Nvcic7XG5pbXBvcnQge1xuICBSZWNvcmRDYWNoZSxcbiAgUmVjb3JkQ2FjaGVRdWVyeU9wdGlvbnMsXG4gIFJlY29yZENhY2hlU2V0dGluZ3MsXG4gIFJlY29yZENhY2hlVHJhbnNmb3JtT3B0aW9uc1xufSBmcm9tICcuL3JlY29yZC1jYWNoZSc7XG5pbXBvcnQgeyBSZWNvcmRUcmFuc2Zvcm1CdWZmZXIgfSBmcm9tICcuL3JlY29yZC10cmFuc2Zvcm0tYnVmZmVyJztcbmltcG9ydCB7IFBhdGNoUmVzdWx0LCBSZWNvcmRDYWNoZVVwZGF0ZURldGFpbHMgfSBmcm9tICcuL3Jlc3BvbnNlJztcblxuY29uc3QgeyBhc3NlcnQsIGRlcHJlY2F0ZSB9ID0gT3JiaXQ7XG5cbmV4cG9ydCBpbnRlcmZhY2UgQXN5bmNSZWNvcmRDYWNoZVNldHRpbmdzPFxuICBRTyBleHRlbmRzIFJlcXVlc3RPcHRpb25zID0gUmVjb3JkQ2FjaGVRdWVyeU9wdGlvbnMsXG4gIFRPIGV4dGVuZHMgUmVxdWVzdE9wdGlvbnMgPSBSZWNvcmRDYWNoZVRyYW5zZm9ybU9wdGlvbnMsXG4gIFFCID0gUmVjb3JkUXVlcnlCdWlsZGVyLFxuICBUQiA9IFJlY29yZFRyYW5zZm9ybUJ1aWxkZXJcbj4gZXh0ZW5kcyBSZWNvcmRDYWNoZVNldHRpbmdzPFFPLCBUTywgUUIsIFRCPiB7XG4gIHByb2Nlc3NvcnM/OiBBc3luY09wZXJhdGlvblByb2Nlc3NvckNsYXNzW107XG4gIHF1ZXJ5T3BlcmF0b3JzPzogRGljdDxBc3luY1F1ZXJ5T3BlcmF0b3I+O1xuICB0cmFuc2Zvcm1PcGVyYXRvcnM/OiBEaWN0PEFzeW5jVHJhbnNmb3JtT3BlcmF0b3I+O1xuICBpbnZlcnNlVHJhbnNmb3JtT3BlcmF0b3JzPzogRGljdDxBc3luY0ludmVyc2VUcmFuc2Zvcm1PcGVyYXRvcj47XG4gIGRlYm91bmNlTGl2ZVF1ZXJpZXM/OiBib29sZWFuO1xuICB0cmFuc2Zvcm1CdWZmZXI/OiBSZWNvcmRUcmFuc2Zvcm1CdWZmZXI7XG59XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBBc3luY1JlY29yZENhY2hlPFxuICAgIFFPIGV4dGVuZHMgUmVxdWVzdE9wdGlvbnMgPSBSZWNvcmRDYWNoZVF1ZXJ5T3B0aW9ucyxcbiAgICBUTyBleHRlbmRzIFJlcXVlc3RPcHRpb25zID0gUmVjb3JkQ2FjaGVUcmFuc2Zvcm1PcHRpb25zLFxuICAgIFFCID0gUmVjb3JkUXVlcnlCdWlsZGVyLFxuICAgIFRCID0gUmVjb3JkVHJhbnNmb3JtQnVpbGRlcixcbiAgICBRdWVyeVJlc3BvbnNlRGV0YWlscyA9IHVua25vd24sXG4gICAgVHJhbnNmb3JtUmVzcG9uc2VEZXRhaWxzIGV4dGVuZHMgUmVjb3JkQ2FjaGVVcGRhdGVEZXRhaWxzID0gUmVjb3JkQ2FjaGVVcGRhdGVEZXRhaWxzXG4gID5cbiAgZXh0ZW5kcyBSZWNvcmRDYWNoZTxRTywgVE8sIFFCLCBUQj5cbiAgaW1wbGVtZW50c1xuICAgIEFzeW5jUmVjb3JkQWNjZXNzb3IsXG4gICAgQXN5bmNSZWNvcmRRdWVyeWFibGU8UXVlcnlSZXNwb25zZURldGFpbHMsIFFCLCBRTz4sXG4gICAgQXN5bmNSZWNvcmRVcGRhdGFibGU8VHJhbnNmb3JtUmVzcG9uc2VEZXRhaWxzLCBUQiwgVE8+IHtcbiAgcHJvdGVjdGVkIF9wcm9jZXNzb3JzOiBBc3luY09wZXJhdGlvblByb2Nlc3NvcltdO1xuICBwcm90ZWN0ZWQgX3F1ZXJ5T3BlcmF0b3JzOiBEaWN0PEFzeW5jUXVlcnlPcGVyYXRvcj47XG4gIHByb3RlY3RlZCBfdHJhbnNmb3JtT3BlcmF0b3JzOiBEaWN0PEFzeW5jVHJhbnNmb3JtT3BlcmF0b3I+O1xuICBwcm90ZWN0ZWQgX2ludmVyc2VUcmFuc2Zvcm1PcGVyYXRvcnM6IERpY3Q8QXN5bmNJbnZlcnNlVHJhbnNmb3JtT3BlcmF0b3I+O1xuICBwcm90ZWN0ZWQgX2RlYm91bmNlTGl2ZVF1ZXJpZXM6IGJvb2xlYW47XG4gIHByb3RlY3RlZCBfdHJhbnNmb3JtQnVmZmVyPzogUmVjb3JkVHJhbnNmb3JtQnVmZmVyO1xuXG4gIGNvbnN0cnVjdG9yKHNldHRpbmdzOiBBc3luY1JlY29yZENhY2hlU2V0dGluZ3M8UU8sIFRPLCBRQiwgVEI+KSB7XG4gICAgc3VwZXIoc2V0dGluZ3MpO1xuXG4gICAgdGhpcy5fcXVlcnlPcGVyYXRvcnMgPSBzZXR0aW5ncy5xdWVyeU9wZXJhdG9ycyA/PyBBc3luY1F1ZXJ5T3BlcmF0b3JzO1xuICAgIHRoaXMuX3RyYW5zZm9ybU9wZXJhdG9ycyA9XG4gICAgICBzZXR0aW5ncy50cmFuc2Zvcm1PcGVyYXRvcnMgPz8gQXN5bmNUcmFuc2Zvcm1PcGVyYXRvcnM7XG4gICAgdGhpcy5faW52ZXJzZVRyYW5zZm9ybU9wZXJhdG9ycyA9XG4gICAgICBzZXR0aW5ncy5pbnZlcnNlVHJhbnNmb3JtT3BlcmF0b3JzID8/IEFzeW5jSW52ZXJzZVRyYW5zZm9ybU9wZXJhdG9ycztcbiAgICB0aGlzLl9kZWJvdW5jZUxpdmVRdWVyaWVzID0gc2V0dGluZ3MuZGVib3VuY2VMaXZlUXVlcmllcyAhPT0gZmFsc2U7XG4gICAgdGhpcy5fdHJhbnNmb3JtQnVmZmVyID0gc2V0dGluZ3MudHJhbnNmb3JtQnVmZmVyO1xuXG4gICAgY29uc3QgcHJvY2Vzc29yczogQXN5bmNPcGVyYXRpb25Qcm9jZXNzb3JDbGFzc1tdID0gc2V0dGluZ3MucHJvY2Vzc29yc1xuICAgICAgPyBzZXR0aW5ncy5wcm9jZXNzb3JzXG4gICAgICA6IFtBc3luY1NjaGVtYUNvbnNpc3RlbmN5UHJvY2Vzc29yLCBBc3luY0NhY2hlSW50ZWdyaXR5UHJvY2Vzc29yXTtcblxuICAgIGlmIChzZXR0aW5ncy5hdXRvVmFsaWRhdGUgIT09IGZhbHNlICYmIHNldHRpbmdzLnByb2Nlc3NvcnMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgcHJvY2Vzc29ycy5wdXNoKEFzeW5jU2NoZW1hVmFsaWRhdGlvblByb2Nlc3Nvcik7XG4gICAgfVxuXG4gICAgdGhpcy5fcHJvY2Vzc29ycyA9IHByb2Nlc3NvcnMubWFwKChQcm9jZXNzb3IpID0+IHtcbiAgICAgIGxldCBwcm9jZXNzb3IgPSBuZXcgUHJvY2Vzc29yKHRoaXMpO1xuICAgICAgYXNzZXJ0KFxuICAgICAgICAnRWFjaCBwcm9jZXNzb3IgbXVzdCBleHRlbmQgQXN5bmNPcGVyYXRpb25Qcm9jZXNzb3InLFxuICAgICAgICBwcm9jZXNzb3IgaW5zdGFuY2VvZiBBc3luY09wZXJhdGlvblByb2Nlc3NvclxuICAgICAgKTtcbiAgICAgIHJldHVybiBwcm9jZXNzb3I7XG4gICAgfSk7XG4gIH1cblxuICBnZXQgcHJvY2Vzc29ycygpOiBBc3luY09wZXJhdGlvblByb2Nlc3NvcltdIHtcbiAgICByZXR1cm4gdGhpcy5fcHJvY2Vzc29ycztcbiAgfVxuXG4gIGdldFF1ZXJ5T3BlcmF0b3Iob3A6IHN0cmluZyk6IEFzeW5jUXVlcnlPcGVyYXRvciB7XG4gICAgcmV0dXJuIHRoaXMuX3F1ZXJ5T3BlcmF0b3JzW29wXTtcbiAgfVxuXG4gIGdldFRyYW5zZm9ybU9wZXJhdG9yKG9wOiBzdHJpbmcpOiBBc3luY1RyYW5zZm9ybU9wZXJhdG9yIHtcbiAgICByZXR1cm4gdGhpcy5fdHJhbnNmb3JtT3BlcmF0b3JzW29wXTtcbiAgfVxuXG4gIGdldEludmVyc2VUcmFuc2Zvcm1PcGVyYXRvcihvcDogc3RyaW5nKTogQXN5bmNJbnZlcnNlVHJhbnNmb3JtT3BlcmF0b3Ige1xuICAgIHJldHVybiB0aGlzLl9pbnZlcnNlVHJhbnNmb3JtT3BlcmF0b3JzW29wXTtcbiAgfVxuXG4gIC8vIEFic3RyYWN0IG1ldGhvZHMgZm9yIGdldHRpbmcgcmVjb3JkcyBhbmQgcmVsYXRpb25zaGlwc1xuICBhYnN0cmFjdCBnZXRSZWNvcmRBc3luYyhcbiAgICByZWNvcmRJZGVudGl0eTogUmVjb3JkSWRlbnRpdHlcbiAgKTogUHJvbWlzZTxJbml0aWFsaXplZFJlY29yZCB8IHVuZGVmaW5lZD47XG4gIGFic3RyYWN0IGdldFJlY29yZHNBc3luYyhcbiAgICB0eXBlT3JJZGVudGl0aWVzPzogc3RyaW5nIHwgUmVjb3JkSWRlbnRpdHlbXVxuICApOiBQcm9taXNlPEluaXRpYWxpemVkUmVjb3JkW10+O1xuICBhYnN0cmFjdCBnZXRJbnZlcnNlUmVsYXRpb25zaGlwc0FzeW5jKFxuICAgIHJlY29yZElkZW50aXR5T3JJZGVudGl0aWVzOiBSZWNvcmRJZGVudGl0eSB8IFJlY29yZElkZW50aXR5W11cbiAgKTogUHJvbWlzZTxSZWNvcmRSZWxhdGlvbnNoaXBJZGVudGl0eVtdPjtcblxuICAvLyBBYnN0cmFjdCBtZXRob2RzIGZvciBzZXR0aW5nIHJlY29yZHMgYW5kIHJlbGF0aW9uc2hpcHNcbiAgYWJzdHJhY3Qgc2V0UmVjb3JkQXN5bmMocmVjb3JkOiBJbml0aWFsaXplZFJlY29yZCk6IFByb21pc2U8dm9pZD47XG4gIGFic3RyYWN0IHNldFJlY29yZHNBc3luYyhyZWNvcmRzOiBJbml0aWFsaXplZFJlY29yZFtdKTogUHJvbWlzZTx2b2lkPjtcbiAgYWJzdHJhY3QgcmVtb3ZlUmVjb3JkQXN5bmMoXG4gICAgcmVjb3JkSWRlbnRpdHk6IFJlY29yZElkZW50aXR5XG4gICk6IFByb21pc2U8SW5pdGlhbGl6ZWRSZWNvcmQgfCB1bmRlZmluZWQ+O1xuICBhYnN0cmFjdCByZW1vdmVSZWNvcmRzQXN5bmMoXG4gICAgcmVjb3JkSWRlbnRpdGllczogUmVjb3JkSWRlbnRpdHlbXVxuICApOiBQcm9taXNlPEluaXRpYWxpemVkUmVjb3JkW10+O1xuICBhYnN0cmFjdCBhZGRJbnZlcnNlUmVsYXRpb25zaGlwc0FzeW5jKFxuICAgIHJlbGF0aW9uc2hpcHM6IFJlY29yZFJlbGF0aW9uc2hpcElkZW50aXR5W11cbiAgKTogUHJvbWlzZTx2b2lkPjtcbiAgYWJzdHJhY3QgcmVtb3ZlSW52ZXJzZVJlbGF0aW9uc2hpcHNBc3luYyhcbiAgICByZWxhdGlvbnNoaXBzOiBSZWNvcmRSZWxhdGlvbnNoaXBJZGVudGl0eVtdXG4gICk6IFByb21pc2U8dm9pZD47XG5cbiAgYXN5bmMgYXBwbHlSZWNvcmRDaGFuZ2VzZXRBc3luYyhjaGFuZ2VzZXQ6IFJlY29yZENoYW5nZXNldCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHtcbiAgICAgIHNldFJlY29yZHMsXG4gICAgICByZW1vdmVSZWNvcmRzLFxuICAgICAgYWRkSW52ZXJzZVJlbGF0aW9uc2hpcHMsXG4gICAgICByZW1vdmVJbnZlcnNlUmVsYXRpb25zaGlwc1xuICAgIH0gPSBjaGFuZ2VzZXQ7XG5cbiAgICBjb25zdCBwcm9taXNlcyA9IFtdO1xuXG4gICAgaWYgKHNldFJlY29yZHMgJiYgc2V0UmVjb3Jkcy5sZW5ndGggPiAwKSB7XG4gICAgICBwcm9taXNlcy5wdXNoKGF3YWl0IHRoaXMuc2V0UmVjb3Jkc0FzeW5jKHNldFJlY29yZHMpKTtcbiAgICB9XG4gICAgaWYgKHJlbW92ZVJlY29yZHMgJiYgcmVtb3ZlUmVjb3Jkcy5sZW5ndGggPiAwKSB7XG4gICAgICBwcm9taXNlcy5wdXNoKGF3YWl0IHRoaXMucmVtb3ZlUmVjb3Jkc0FzeW5jKHJlbW92ZVJlY29yZHMpKTtcbiAgICB9XG4gICAgaWYgKGFkZEludmVyc2VSZWxhdGlvbnNoaXBzICYmIGFkZEludmVyc2VSZWxhdGlvbnNoaXBzLmxlbmd0aCA+IDApIHtcbiAgICAgIHByb21pc2VzLnB1c2goXG4gICAgICAgIGF3YWl0IHRoaXMuYWRkSW52ZXJzZVJlbGF0aW9uc2hpcHNBc3luYyhhZGRJbnZlcnNlUmVsYXRpb25zaGlwcylcbiAgICAgICk7XG4gICAgfVxuICAgIGlmIChyZW1vdmVJbnZlcnNlUmVsYXRpb25zaGlwcyAmJiByZW1vdmVJbnZlcnNlUmVsYXRpb25zaGlwcy5sZW5ndGggPiAwKSB7XG4gICAgICBwcm9taXNlcy5wdXNoKFxuICAgICAgICBhd2FpdCB0aGlzLnJlbW92ZUludmVyc2VSZWxhdGlvbnNoaXBzQXN5bmMocmVtb3ZlSW52ZXJzZVJlbGF0aW9uc2hpcHMpXG4gICAgICApO1xuICAgIH1cblxuICAgIGF3YWl0IFByb21pc2UuYWxsKHByb21pc2VzKTtcbiAgfVxuXG4gIGFzeW5jIGdldFJlbGF0ZWRSZWNvcmRBc3luYyhcbiAgICBpZGVudGl0eTogUmVjb3JkSWRlbnRpdHksXG4gICAgcmVsYXRpb25zaGlwOiBzdHJpbmdcbiAgKTogUHJvbWlzZTxSZWNvcmRJZGVudGl0eSB8IG51bGwgfCB1bmRlZmluZWQ+IHtcbiAgICBjb25zdCByZWNvcmQgPSBhd2FpdCB0aGlzLmdldFJlY29yZEFzeW5jKGlkZW50aXR5KTtcbiAgICBpZiAocmVjb3JkKSB7XG4gICAgICByZXR1cm4gZGVlcEdldChyZWNvcmQsIFsncmVsYXRpb25zaGlwcycsIHJlbGF0aW9uc2hpcCwgJ2RhdGEnXSk7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBhc3luYyBnZXRSZWxhdGVkUmVjb3Jkc0FzeW5jKFxuICAgIGlkZW50aXR5OiBSZWNvcmRJZGVudGl0eSxcbiAgICByZWxhdGlvbnNoaXA6IHN0cmluZ1xuICApOiBQcm9taXNlPFJlY29yZElkZW50aXR5W10gfCB1bmRlZmluZWQ+IHtcbiAgICBjb25zdCByZWNvcmQgPSBhd2FpdCB0aGlzLmdldFJlY29yZEFzeW5jKGlkZW50aXR5KTtcbiAgICBpZiAocmVjb3JkKSB7XG4gICAgICByZXR1cm4gZGVlcEdldChyZWNvcmQsIFsncmVsYXRpb25zaGlwcycsIHJlbGF0aW9uc2hpcCwgJ2RhdGEnXSk7XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogUXVlcmllcyB0aGUgY2FjaGUuXG4gICAqL1xuICBxdWVyeTxSZXF1ZXN0RGF0YSBleHRlbmRzIFJlY29yZFF1ZXJ5UmVzdWx0ID0gUmVjb3JkUXVlcnlSZXN1bHQ+KFxuICAgIHF1ZXJ5T3JFeHByZXNzaW9uczogUXVlcnlPckV4cHJlc3Npb25zPFJlY29yZFF1ZXJ5RXhwcmVzc2lvbiwgUUI+LFxuICAgIG9wdGlvbnM/OiBEZWZhdWx0UmVxdWVzdE9wdGlvbnM8UU8+LFxuICAgIGlkPzogc3RyaW5nXG4gICk6IFByb21pc2U8UmVxdWVzdERhdGE+O1xuICBxdWVyeTxSZXF1ZXN0RGF0YSBleHRlbmRzIFJlY29yZFF1ZXJ5UmVzdWx0ID0gUmVjb3JkUXVlcnlSZXN1bHQ+KFxuICAgIHF1ZXJ5T3JFeHByZXNzaW9uczogUXVlcnlPckV4cHJlc3Npb25zPFJlY29yZFF1ZXJ5RXhwcmVzc2lvbiwgUUI+LFxuICAgIG9wdGlvbnM6IEZ1bGxSZXF1ZXN0T3B0aW9uczxRTz4sXG4gICAgaWQ/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTxGdWxsUmVzcG9uc2U8UmVxdWVzdERhdGEsIFF1ZXJ5UmVzcG9uc2VEZXRhaWxzLCBSZWNvcmRPcGVyYXRpb24+PjtcbiAgYXN5bmMgcXVlcnk8UmVxdWVzdERhdGEgZXh0ZW5kcyBSZWNvcmRRdWVyeVJlc3VsdCA9IFJlY29yZFF1ZXJ5UmVzdWx0PihcbiAgICBxdWVyeU9yRXhwcmVzc2lvbnM6IFF1ZXJ5T3JFeHByZXNzaW9uczxSZWNvcmRRdWVyeUV4cHJlc3Npb24sIFFCPixcbiAgICBvcHRpb25zPzogUU8sXG4gICAgaWQ/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTxcbiAgICB8IFJlcXVlc3REYXRhXG4gICAgfCBGdWxsUmVzcG9uc2U8UmVxdWVzdERhdGEsIFF1ZXJ5UmVzcG9uc2VEZXRhaWxzLCBSZWNvcmRPcGVyYXRpb24+XG4gID4ge1xuICAgIGNvbnN0IHF1ZXJ5ID0gYnVpbGRRdWVyeShcbiAgICAgIHF1ZXJ5T3JFeHByZXNzaW9ucyxcbiAgICAgIG9wdGlvbnMsXG4gICAgICBpZCxcbiAgICAgIHRoaXMuX3F1ZXJ5QnVpbGRlclxuICAgICk7XG5cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuX3F1ZXJ5PFJlcXVlc3REYXRhPihxdWVyeSwgb3B0aW9ucyk7XG5cbiAgICBpZiAob3B0aW9ucz8uZnVsbFJlc3BvbnNlKSB7XG4gICAgICByZXR1cm4gcmVzcG9uc2U7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiByZXNwb25zZS5kYXRhIGFzIFJlcXVlc3REYXRhO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGVzIHRoZSBjYWNoZS5cbiAgICovXG4gIHVwZGF0ZTxSZXF1ZXN0RGF0YSBleHRlbmRzIFJlY29yZFRyYW5zZm9ybVJlc3VsdCA9IFJlY29yZFRyYW5zZm9ybVJlc3VsdD4oXG4gICAgdHJhbnNmb3JtT3JPcGVyYXRpb25zOiBUcmFuc2Zvcm1Pck9wZXJhdGlvbnM8UmVjb3JkT3BlcmF0aW9uLCBUQj4sXG4gICAgb3B0aW9ucz86IERlZmF1bHRSZXF1ZXN0T3B0aW9uczxUTz4sXG4gICAgaWQ/OiBzdHJpbmdcbiAgKTogUHJvbWlzZTxSZXF1ZXN0RGF0YT47XG4gIHVwZGF0ZTxSZXF1ZXN0RGF0YSBleHRlbmRzIFJlY29yZFRyYW5zZm9ybVJlc3VsdCA9IFJlY29yZFRyYW5zZm9ybVJlc3VsdD4oXG4gICAgdHJhbnNmb3JtT3JPcGVyYXRpb25zOiBUcmFuc2Zvcm1Pck9wZXJhdGlvbnM8UmVjb3JkT3BlcmF0aW9uLCBUQj4sXG4gICAgb3B0aW9uczogRnVsbFJlcXVlc3RPcHRpb25zPFRPPixcbiAgICBpZD86IHN0cmluZ1xuICApOiBQcm9taXNlPFxuICAgIEZ1bGxSZXNwb25zZTxSZXF1ZXN0RGF0YSwgVHJhbnNmb3JtUmVzcG9uc2VEZXRhaWxzLCBSZWNvcmRPcGVyYXRpb24+XG4gID47XG4gIGFzeW5jIHVwZGF0ZTxcbiAgICBSZXF1ZXN0RGF0YSBleHRlbmRzIFJlY29yZFRyYW5zZm9ybVJlc3VsdCA9IFJlY29yZFRyYW5zZm9ybVJlc3VsdFxuICA+KFxuICAgIHRyYW5zZm9ybU9yT3BlcmF0aW9uczogVHJhbnNmb3JtT3JPcGVyYXRpb25zPFJlY29yZE9wZXJhdGlvbiwgVEI+LFxuICAgIG9wdGlvbnM/OiBUTyxcbiAgICBpZD86IHN0cmluZ1xuICApOiBQcm9taXNlPFxuICAgIHwgUmVxdWVzdERhdGFcbiAgICB8IEZ1bGxSZXNwb25zZTxSZXF1ZXN0RGF0YSwgVHJhbnNmb3JtUmVzcG9uc2VEZXRhaWxzLCBSZWNvcmRPcGVyYXRpb24+XG4gID4ge1xuICAgIGNvbnN0IHRyYW5zZm9ybSA9IGJ1aWxkVHJhbnNmb3JtKFxuICAgICAgdHJhbnNmb3JtT3JPcGVyYXRpb25zLFxuICAgICAgb3B0aW9ucyxcbiAgICAgIGlkLFxuICAgICAgdGhpcy5fdHJhbnNmb3JtQnVpbGRlclxuICAgICk7XG5cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuX3VwZGF0ZTxSZXF1ZXN0RGF0YT4odHJhbnNmb3JtLCBvcHRpb25zKTtcblxuICAgIGlmIChvcHRpb25zPy5mdWxsUmVzcG9uc2UpIHtcbiAgICAgIHJldHVybiByZXNwb25zZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHJlc3BvbnNlLmRhdGEgYXMgUmVxdWVzdERhdGE7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFBhdGNoZXMgdGhlIGNhY2hlIHdpdGggYW4gb3BlcmF0aW9uIG9yIG9wZXJhdGlvbnMuXG4gICAqXG4gICAqIEBkZXByZWNhdGVkIHNpbmNlIHYwLjE3XG4gICAqL1xuICBhc3luYyBwYXRjaChcbiAgICBvcGVyYXRpb25Pck9wZXJhdGlvbnM6XG4gICAgICB8IFJlY29yZE9wZXJhdGlvblxuICAgICAgfCBSZWNvcmRPcGVyYXRpb25bXVxuICAgICAgfCBSZWNvcmRPcGVyYXRpb25UZXJtXG4gICAgICB8IFJlY29yZE9wZXJhdGlvblRlcm1bXVxuICAgICAgfCBSZWNvcmRUcmFuc2Zvcm1CdWlsZGVyRnVuY1xuICApOiBQcm9taXNlPFBhdGNoUmVzdWx0PiB7XG4gICAgZGVwcmVjYXRlKFxuICAgICAgJ0FzeW5jUmVjb3JkQ2FjaGUjcGF0Y2ggaGFzIGJlZW4gZGVwcmVjYXRlZC4gVXNlIEFzeW5jUmVjb3JkQ2FjaGUjdXBkYXRlIGluc3RlYWQuJ1xuICAgICk7XG5cbiAgICAvLyBUT0RPIC0gV2h5IGlzIHRoaXMgYHRoaXNgIGNhc3QgbmVjZXNzYXJ5IGZvciBUUyB0byB1bmRlcnN0YW5kIHRoZSBjb3JyZWN0XG4gICAgLy8gbWV0aG9kIG92ZXJsb2FkP1xuICAgIGNvbnN0IHsgZGF0YSwgZGV0YWlscyB9ID0gYXdhaXQgKHRoaXMgYXMgYW55KS51cGRhdGUoXG4gICAgICBvcGVyYXRpb25Pck9wZXJhdGlvbnMsXG4gICAgICB7XG4gICAgICAgIGZ1bGxSZXNwb25zZTogdHJ1ZVxuICAgICAgfVxuICAgICk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgaW52ZXJzZTogZGV0YWlscz8uaW52ZXJzZU9wZXJhdGlvbnMgfHwgW10sXG4gICAgICBkYXRhOiBBcnJheS5pc0FycmF5KGRhdGEpID8gZGF0YSA6IFtkYXRhXVxuICAgIH07XG4gIH1cblxuICBsaXZlUXVlcnkoXG4gICAgcXVlcnlPckV4cHJlc3Npb25zOiBRdWVyeU9yRXhwcmVzc2lvbnM8UmVjb3JkUXVlcnlFeHByZXNzaW9uLCBRQj4sXG4gICAgb3B0aW9ucz86IERlZmF1bHRSZXF1ZXN0T3B0aW9uczxRTz4sXG4gICAgaWQ/OiBzdHJpbmdcbiAgKTogQXN5bmNMaXZlUXVlcnk8UU8sIFRPLCBRQiwgVEI+IHtcbiAgICBjb25zdCBxdWVyeSA9IGJ1aWxkUXVlcnkoXG4gICAgICBxdWVyeU9yRXhwcmVzc2lvbnMsXG4gICAgICBvcHRpb25zLFxuICAgICAgaWQsXG4gICAgICB0aGlzLnF1ZXJ5QnVpbGRlclxuICAgICk7XG5cbiAgICBsZXQgZGVib3VuY2UgPSBvcHRpb25zICYmIChvcHRpb25zIGFzIGFueSkuZGVib3VuY2U7XG4gICAgaWYgKHR5cGVvZiBkZWJvdW5jZSAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICBkZWJvdW5jZSA9IHRoaXMuX2RlYm91bmNlTGl2ZVF1ZXJpZXM7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBBc3luY0xpdmVRdWVyeTxRTywgVE8sIFFCLCBUQj4oe1xuICAgICAgZGVib3VuY2UsXG4gICAgICBjYWNoZTogdGhpcyxcbiAgICAgIHF1ZXJ5XG4gICAgfSk7XG4gIH1cblxuICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAvLyBQcm90ZWN0ZWQgbWV0aG9kc1xuICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4gIHByb3RlY3RlZCBhc3luYyBfcXVlcnk8XG4gICAgUmVxdWVzdERhdGEgZXh0ZW5kcyBSZWNvcmRRdWVyeVJlc3VsdCA9IFJlY29yZFF1ZXJ5UmVzdWx0XG4gID4oXG4gICAgcXVlcnk6IFJlY29yZFF1ZXJ5LFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICBvcHRpb25zPzogUU9cbiAgKTogUHJvbWlzZTxGdWxsUmVzcG9uc2U8UmVxdWVzdERhdGEsIFF1ZXJ5UmVzcG9uc2VEZXRhaWxzLCBSZWNvcmRPcGVyYXRpb24+PiB7XG4gICAgbGV0IGRhdGE7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShxdWVyeS5leHByZXNzaW9ucykpIHtcbiAgICAgIGRhdGEgPSBbXTtcbiAgICAgIGZvciAobGV0IGV4cHJlc3Npb24gb2YgcXVlcnkuZXhwcmVzc2lvbnMpIHtcbiAgICAgICAgY29uc3QgcXVlcnlPcGVyYXRvciA9IHRoaXMuZ2V0UXVlcnlPcGVyYXRvcihleHByZXNzaW9uLm9wKTtcbiAgICAgICAgaWYgKCFxdWVyeU9wZXJhdG9yKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmFibGUgdG8gZmluZCBxdWVyeSBvcGVyYXRvcjogJHtleHByZXNzaW9uLm9wfWApO1xuICAgICAgICB9XG4gICAgICAgIGRhdGEucHVzaChcbiAgICAgICAgICBhd2FpdCBxdWVyeU9wZXJhdG9yKFxuICAgICAgICAgICAgdGhpcyxcbiAgICAgICAgICAgIGV4cHJlc3Npb24sXG4gICAgICAgICAgICB0aGlzLmdldFF1ZXJ5T3B0aW9ucyhxdWVyeSwgZXhwcmVzc2lvbilcbiAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSBxdWVyeS5leHByZXNzaW9ucyBhcyBSZWNvcmRRdWVyeUV4cHJlc3Npb247XG4gICAgICBjb25zdCBxdWVyeU9wZXJhdG9yID0gdGhpcy5nZXRRdWVyeU9wZXJhdG9yKGV4cHJlc3Npb24ub3ApO1xuICAgICAgaWYgKCFxdWVyeU9wZXJhdG9yKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5hYmxlIHRvIGZpbmQgcXVlcnkgb3BlcmF0b3I6ICR7ZXhwcmVzc2lvbi5vcH1gKTtcbiAgICAgIH1cbiAgICAgIGRhdGEgPSBhd2FpdCBxdWVyeU9wZXJhdG9yKFxuICAgICAgICB0aGlzLFxuICAgICAgICBleHByZXNzaW9uLFxuICAgICAgICB0aGlzLmdldFF1ZXJ5T3B0aW9ucyhxdWVyeSwgZXhwcmVzc2lvbilcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgZGF0YTogZGF0YSBhcyBSZXF1ZXN0RGF0YSB9O1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIF91cGRhdGU8XG4gICAgUmVxdWVzdERhdGEgZXh0ZW5kcyBSZWNvcmRUcmFuc2Zvcm1SZXN1bHQgPSBSZWNvcmRUcmFuc2Zvcm1SZXN1bHRcbiAgPihcbiAgICB0cmFuc2Zvcm06IFJlY29yZFRyYW5zZm9ybSxcbiAgICBvcHRpb25zPzogVE9cbiAgKTogUHJvbWlzZTxcbiAgICBGdWxsUmVzcG9uc2U8UmVxdWVzdERhdGEsIFRyYW5zZm9ybVJlc3BvbnNlRGV0YWlscywgUmVjb3JkT3BlcmF0aW9uPlxuICA+IHtcbiAgICBpZiAodGhpcy5nZXRUcmFuc2Zvcm1PcHRpb25zKHRyYW5zZm9ybSk/LnVzZUJ1ZmZlcikge1xuICAgICAgY29uc3QgYnVmZmVyID0gYXdhaXQgdGhpcy5faW5pdFRyYW5zZm9ybUJ1ZmZlcih0cmFuc2Zvcm0pO1xuXG4gICAgICBidWZmZXIuc3RhcnRUcmFja2luZ0NoYW5nZXMoKTtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBidWZmZXIudXBkYXRlKHRyYW5zZm9ybSwge1xuICAgICAgICBmdWxsUmVzcG9uc2U6IHRydWVcbiAgICAgIH0pO1xuXG4gICAgICBjb25zdCBjaGFuZ2VzID0gYnVmZmVyLnN0b3BUcmFja2luZ0NoYW5nZXMoKTtcblxuICAgICAgYXdhaXQgdGhpcy5hcHBseVJlY29yZENoYW5nZXNldEFzeW5jKGNoYW5nZXMpO1xuXG4gICAgICBjb25zdCB7XG4gICAgICAgIGFwcGxpZWRPcGVyYXRpb25zLFxuICAgICAgICBhcHBsaWVkT3BlcmF0aW9uUmVzdWx0c1xuICAgICAgfSA9IHJlc3BvbnNlLmRldGFpbHMgYXMgVHJhbnNmb3JtUmVzcG9uc2VEZXRhaWxzO1xuXG4gICAgICBmb3IgKGxldCBpID0gMCwgbGVuID0gYXBwbGllZE9wZXJhdGlvbnMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgdGhpcy5lbWl0KCdwYXRjaCcsIGFwcGxpZWRPcGVyYXRpb25zW2ldLCBhcHBsaWVkT3BlcmF0aW9uUmVzdWx0c1tpXSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXNwb25zZSBhcyBGdWxsUmVzcG9uc2U8XG4gICAgICAgIFJlcXVlc3REYXRhLFxuICAgICAgICBUcmFuc2Zvcm1SZXNwb25zZURldGFpbHMsXG4gICAgICAgIFJlY29yZE9wZXJhdGlvblxuICAgICAgPjtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSB7XG4gICAgICAgIGRhdGE6IFtdXG4gICAgICB9IGFzIEZ1bGxSZXNwb25zZTxcbiAgICAgICAgUmVjb3JkT3BlcmF0aW9uUmVzdWx0W10sXG4gICAgICAgIFJlY29yZENhY2hlVXBkYXRlRGV0YWlscyxcbiAgICAgICAgUmVjb3JkT3BlcmF0aW9uXG4gICAgICA+O1xuXG4gICAgICBpZiAob3B0aW9ucz8uZnVsbFJlc3BvbnNlKSB7XG4gICAgICAgIHJlc3BvbnNlLmRldGFpbHMgPSB7XG4gICAgICAgICAgYXBwbGllZE9wZXJhdGlvbnM6IFtdLFxuICAgICAgICAgIGFwcGxpZWRPcGVyYXRpb25SZXN1bHRzOiBbXSxcbiAgICAgICAgICBpbnZlcnNlT3BlcmF0aW9uczogW11cbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgbGV0IGRhdGE6IFJlY29yZFRyYW5zZm9ybVJlc3VsdDtcblxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkodHJhbnNmb3JtLm9wZXJhdGlvbnMpKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuX2FwcGx5VHJhbnNmb3JtT3BlcmF0aW9ucyhcbiAgICAgICAgICB0cmFuc2Zvcm0sXG4gICAgICAgICAgdHJhbnNmb3JtLm9wZXJhdGlvbnMsXG4gICAgICAgICAgcmVzcG9uc2UsXG4gICAgICAgICAgdHJ1ZVxuICAgICAgICApO1xuICAgICAgICBkYXRhID0gcmVzcG9uc2UuZGF0YTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGF3YWl0IHRoaXMuX2FwcGx5VHJhbnNmb3JtT3BlcmF0aW9uKFxuICAgICAgICAgIHRyYW5zZm9ybSxcbiAgICAgICAgICB0cmFuc2Zvcm0ub3BlcmF0aW9ucyxcbiAgICAgICAgICByZXNwb25zZSxcbiAgICAgICAgICB0cnVlXG4gICAgICAgICk7XG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHJlc3BvbnNlLmRhdGEpKSB7XG4gICAgICAgICAgZGF0YSA9IHJlc3BvbnNlLmRhdGFbMF07XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKG9wdGlvbnM/LmZ1bGxSZXNwb25zZSkge1xuICAgICAgICByZXNwb25zZS5kZXRhaWxzPy5pbnZlcnNlT3BlcmF0aW9ucy5yZXZlcnNlKCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLnJlc3BvbnNlLFxuICAgICAgICBkYXRhXG4gICAgICB9IGFzIEZ1bGxSZXNwb25zZTxSZXF1ZXN0RGF0YSwgVHJhbnNmb3JtUmVzcG9uc2VEZXRhaWxzLCBSZWNvcmRPcGVyYXRpb24+O1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBfZ2V0VHJhbnNmb3JtQnVmZmVyKCk6IFJlY29yZFRyYW5zZm9ybUJ1ZmZlciB7XG4gICAgaWYgKHRoaXMuX3RyYW5zZm9ybUJ1ZmZlciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uKFxuICAgICAgICAndHJhbnNmb3JtQnVmZmVyIG11c3QgYmUgcHJvdmlkZWQgdG8gY2FjaGUgdmlhIGNvbnN0cnVjdG9yIHNldHRpbmdzJ1xuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3RyYW5zZm9ybUJ1ZmZlcjtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBfaW5pdFRyYW5zZm9ybUJ1ZmZlcihcbiAgICB0cmFuc2Zvcm06IFJlY29yZFRyYW5zZm9ybVxuICApOiBQcm9taXNlPFJlY29yZFRyYW5zZm9ybUJ1ZmZlcj4ge1xuICAgIGNvbnN0IGJ1ZmZlciA9IHRoaXMuX2dldFRyYW5zZm9ybUJ1ZmZlcigpO1xuXG4gICAgY29uc3QgcmVjb3JkcyA9IHJlY29yZHNSZWZlcmVuY2VkQnlPcGVyYXRpb25zKFxuICAgICAgdG9BcnJheSh0cmFuc2Zvcm0ub3BlcmF0aW9ucylcbiAgICApO1xuICAgIGNvbnN0IGludmVyc2VSZWxhdGlvbnNoaXBzID0gYXdhaXQgdGhpcy5nZXRJbnZlcnNlUmVsYXRpb25zaGlwc0FzeW5jKFxuICAgICAgcmVjb3Jkc1xuICAgICk7XG4gICAgY29uc3QgcmVsYXRlZFJlY29yZHMgPSBpbnZlcnNlUmVsYXRpb25zaGlwcy5tYXAoKGlyKSA9PiBpci5yZWNvcmQpO1xuICAgIEFycmF5LnByb3RvdHlwZS5wdXNoLmFwcGx5KHJlY29yZHMsIHJlbGF0ZWRSZWNvcmRzKTtcblxuICAgIGJ1ZmZlci5yZXNldFN0YXRlKCk7XG4gICAgYnVmZmVyLnNldFJlY29yZHNTeW5jKGF3YWl0IHRoaXMuZ2V0UmVjb3Jkc0FzeW5jKHJlY29yZHMpKTtcbiAgICBidWZmZXIuYWRkSW52ZXJzZVJlbGF0aW9uc2hpcHNTeW5jKGludmVyc2VSZWxhdGlvbnNoaXBzKTtcblxuICAgIHJldHVybiBidWZmZXI7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgX2FwcGx5VHJhbnNmb3JtT3BlcmF0aW9ucyhcbiAgICB0cmFuc2Zvcm06IFJlY29yZFRyYW5zZm9ybSxcbiAgICBvcHM6IFJlY29yZE9wZXJhdGlvbltdIHwgUmVjb3JkT3BlcmF0aW9uVGVybVtdLFxuICAgIHJlc3BvbnNlOiBGdWxsUmVzcG9uc2U8XG4gICAgICBSZWNvcmRPcGVyYXRpb25SZXN1bHRbXSxcbiAgICAgIFJlY29yZENhY2hlVXBkYXRlRGV0YWlscyxcbiAgICAgIFJlY29yZE9wZXJhdGlvblxuICAgID4sXG4gICAgcHJpbWFyeSA9IGZhbHNlXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGZvciAobGV0IG9wIG9mIG9wcykge1xuICAgICAgYXdhaXQgdGhpcy5fYXBwbHlUcmFuc2Zvcm1PcGVyYXRpb24odHJhbnNmb3JtLCBvcCwgcmVzcG9uc2UsIHByaW1hcnkpO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBfYXBwbHlUcmFuc2Zvcm1PcGVyYXRpb24oXG4gICAgdHJhbnNmb3JtOiBSZWNvcmRUcmFuc2Zvcm0sXG4gICAgb3BlcmF0aW9uOiBSZWNvcmRPcGVyYXRpb24gfCBSZWNvcmRPcGVyYXRpb25UZXJtLFxuICAgIHJlc3BvbnNlOiBGdWxsUmVzcG9uc2U8XG4gICAgICBSZWNvcmRPcGVyYXRpb25SZXN1bHRbXSxcbiAgICAgIFJlY29yZENhY2hlVXBkYXRlRGV0YWlscyxcbiAgICAgIFJlY29yZE9wZXJhdGlvblxuICAgID4sXG4gICAgcHJpbWFyeSA9IGZhbHNlXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmIChvcGVyYXRpb24gaW5zdGFuY2VvZiBPcGVyYXRpb25UZXJtKSB7XG4gICAgICBvcGVyYXRpb24gPSBvcGVyYXRpb24udG9PcGVyYXRpb24oKSBhcyBSZWNvcmRPcGVyYXRpb247XG4gICAgfVxuXG4gICAgZm9yIChsZXQgcHJvY2Vzc29yIG9mIHRoaXMuX3Byb2Nlc3NvcnMpIHtcbiAgICAgIGF3YWl0IHByb2Nlc3Nvci52YWxpZGF0ZShvcGVyYXRpb24pO1xuICAgIH1cblxuICAgIGNvbnN0IGludmVyc2VUcmFuc2Zvcm1PcGVyYXRvciA9IHRoaXMuZ2V0SW52ZXJzZVRyYW5zZm9ybU9wZXJhdG9yKFxuICAgICAgb3BlcmF0aW9uLm9wXG4gICAgKTtcbiAgICBjb25zdCBpbnZlcnNlT3A6XG4gICAgICB8IFJlY29yZE9wZXJhdGlvblxuICAgICAgfCB1bmRlZmluZWQgPSBhd2FpdCBpbnZlcnNlVHJhbnNmb3JtT3BlcmF0b3IoXG4gICAgICB0aGlzLFxuICAgICAgb3BlcmF0aW9uLFxuICAgICAgdGhpcy5nZXRUcmFuc2Zvcm1PcHRpb25zKHRyYW5zZm9ybSwgb3BlcmF0aW9uKVxuICAgICk7XG4gICAgaWYgKGludmVyc2VPcCkge1xuICAgICAgcmVzcG9uc2UuZGV0YWlscz8uaW52ZXJzZU9wZXJhdGlvbnM/LnB1c2goaW52ZXJzZU9wKTtcblxuICAgICAgLy8gUXVlcnkgYW5kIHBlcmZvcm0gcmVsYXRlZCBgYmVmb3JlYCBvcGVyYXRpb25zXG4gICAgICBmb3IgKGxldCBwcm9jZXNzb3Igb2YgdGhpcy5fcHJvY2Vzc29ycykge1xuICAgICAgICBhd2FpdCB0aGlzLl9hcHBseVRyYW5zZm9ybU9wZXJhdGlvbnMoXG4gICAgICAgICAgdHJhbnNmb3JtLFxuICAgICAgICAgIGF3YWl0IHByb2Nlc3Nvci5iZWZvcmUob3BlcmF0aW9uKSxcbiAgICAgICAgICByZXNwb25zZVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICAvLyBRdWVyeSByZWxhdGVkIGBhZnRlcmAgb3BlcmF0aW9ucyBiZWZvcmUgcGVyZm9ybWluZ1xuICAgICAgLy8gdGhlIHJlcXVlc3RlZCBvcGVyYXRpb24uIFRoZXNlIHdpbGwgYmUgYXBwbGllZCBvbiBzdWNjZXNzLlxuICAgICAgbGV0IHByZXBhcmVkT3BzID0gW107XG4gICAgICBmb3IgKGxldCBwcm9jZXNzb3Igb2YgdGhpcy5fcHJvY2Vzc29ycykge1xuICAgICAgICBwcmVwYXJlZE9wcy5wdXNoKGF3YWl0IHByb2Nlc3Nvci5hZnRlcihvcGVyYXRpb24pKTtcbiAgICAgIH1cblxuICAgICAgLy8gUGVyZm9ybSB0aGUgcmVxdWVzdGVkI