UNPKG

@orbit/record-cache

Version:

Orbit base classes used to access and maintain a set of records.

282 lines 51.7 kB
"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