UNPKG

@orbit/record-cache

Version:

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

208 lines 28.7 kB
import { QueryExpressionParseError } from '@orbit/data'; import { RecordNotFoundException } from '@orbit/records'; import { deepGet, isNone } from '@orbit/utils'; export const SyncQueryOperators = { findRecord(cache, expression, options) { const { record } = expression; const currentRecord = cache.getRecordSync(record); if (!currentRecord) { if (options === null || options === void 0 ? void 0 : options.raiseNotFoundExceptions) { throw new RecordNotFoundException(record.type, record.id); } } return currentRecord; }, findRecords(cache, expression, // eslint-disable-next-line @typescript-eslint/no-unused-vars options) { let exp = expression; let results = cache.getRecordsSync(exp.records || exp.type); if (exp.filter) { results = filterRecords(results, exp.filter); } if (exp.sort) { results = sortRecords(results, exp.sort); } if (exp.page) { results = paginateRecords(results, exp.page); } return results; }, findRelatedRecords(cache, expression, options) { const exp = expression; const { record, relationship } = exp; const relatedIds = cache.getRelatedRecordsSync(record, relationship); if (!relatedIds || relatedIds.length === 0) { if (!cache.getRecordSync(record)) { if (options === null || options === void 0 ? void 0 : options.raiseNotFoundExceptions) { throw new RecordNotFoundException(record.type, record.id); } else { return undefined; } } return []; } let results = cache.getRecordsSync(relatedIds); if (exp.filter) { results = filterRecords(results, exp.filter); } if (exp.sort) { results = sortRecords(results, exp.sort); } if (exp.page) { results = paginateRecords(results, exp.page); } return results; }, findRelatedRecord(cache, expression, options) { const exp = expression; const { record, relationship } = exp; const relatedId = cache.getRelatedRecordSync(record, relationship); if (relatedId) { return cache.getRecordSync(relatedId) || null; } else { if (!cache.getRecordSync(record)) { if (options === null || options === void 0 ? void 0 : options.raiseNotFoundExceptions) { throw new RecordNotFoundException(record.type, record.id); } else { return undefined; } } return null; } } }; function filterRecords(records, filters) { return records.filter((record) => { for (let i = 0, l = filters.length; i < l; i++) { if (!applyFilter(record, filters[i])) { return false; } } return true; }); } function applyFilter(record, filter) { if (filter.kind === 'attribute') { let actual = deepGet(record, ['attributes', filter.attribute]); if (actual === undefined) { return false; } let expected = filter.value; switch (filter.op) { case 'equal': return actual === expected; case 'gt': return actual > expected; case 'gte': return actual >= expected; case 'lt': return actual < expected; case 'lte': return actual <= expected; default: throw new QueryExpressionParseError('Filter operation ${filter.op} not recognized for Store.'); } } else if (filter.kind === 'relatedRecords') { let actual = deepGet(record, [ 'relationships', filter.relation, 'data' ]); if (actual === undefined) { return false; } let expected = filter.records; switch (filter.op) { case 'equal': return (actual.length === expected.length && expected.every((e) => actual.some((a) => a.id === e.id && a.type === e.type))); case 'all': return expected.every((e) => actual.some((a) => a.id === e.id && a.type === e.type)); case 'some': return expected.some((e) => actual.some((a) => a.id === e.id && a.type === e.type)); case 'none': return !expected.some((e) => actual.some((a) => a.id === e.id && a.type === e.type)); default: throw new QueryExpressionParseError('Filter operation ${filter.op} not recognized for Store.'); } } else if (filter.kind === 'relatedRecord') { let actual = deepGet(record, ['relationships', filter.relation, 'data']); if (actual === undefined) { return false; } let expected = filter.record; switch (filter.op) { case 'equal': if (actual === null) { return expected === null; } else { if (Array.isArray(expected)) { return expected.some((e) => actual.type === e.type && actual.id === e.id); } else if (expected) { return actual.type === expected.type && actual.id === expected.id; } else { return false; } } default: throw new QueryExpressionParseError('Filter operation ${filter.op} not recognized for Store.'); } } return false; } function sortRecords(records, sortSpecifiers) { const comparisonValues = new Map(); records.forEach((record) => { comparisonValues.set(record, sortSpecifiers.map((sortSpecifier) => { if (sortSpecifier.kind === 'attribute') { return deepGet(record, [ 'attributes', sortSpecifier.attribute ]); } else { throw new QueryExpressionParseError('Sort specifier ${sortSpecifier.kind} not recognized for Store.'); } })); }); const comparisonOrders = sortSpecifiers.map((sortExpression) => sortExpression.order === 'descending' ? -1 : 1); return records.sort((record1, record2) => { const values1 = comparisonValues.get(record1); const values2 = comparisonValues.get(record2); for (let i = 0; i < sortSpecifiers.length; i++) { if (values1[i] < values2[i]) { return -comparisonOrders[i]; } else if (values1[i] > values2[i]) { return comparisonOrders[i]; } else if (isNone(values1[i]) && !isNone(values2[i])) { return comparisonOrders[i]; } else if (isNone(values2[i]) && !isNone(values1[i])) { return -comparisonOrders[i]; } } return 0; }); } function paginateRecords(records, paginationOptions) { if (paginationOptions.limit !== undefined) { let offset = paginationOptions.offset === undefined ? 0 : paginationOptions.offset; let limit = paginationOptions.limit; return records.slice(offset, offset + limit); } else { throw new QueryExpressionParseError('Pagination options not recognized for Store. Please specify `offset` and `limit`.'); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1xdWVyeS1vcGVyYXRvcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvb3BlcmF0b3JzL3N5bmMtcXVlcnktb3BlcmF0b3JzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx5QkFBeUIsRUFBa0IsTUFBTSxhQUFhLENBQUM7QUFDeEUsT0FBTyxFQVFMLHVCQUF1QixFQUl4QixNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFBRSxPQUFPLEVBQVEsTUFBTSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBV3JELE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUE0QjtJQUN6RCxVQUFVLENBQ1IsS0FBeUIsRUFDekIsVUFBaUMsRUFDakMsT0FBd0I7UUFFeEIsTUFBTSxFQUFFLE1BQU0sRUFBRSxHQUFHLFVBQXdCLENBQUM7UUFDNUMsTUFBTSxhQUFhLEdBQUcsS0FBSyxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUVsRCxJQUFJLENBQUMsYUFBYSxFQUFFO1lBQ2xCLElBQUksT0FBTyxhQUFQLE9BQU8sdUJBQVAsT0FBTyxDQUFFLHVCQUF1QixFQUFFO2dCQUNwQyxNQUFNLElBQUksdUJBQXVCLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsRUFBRSxDQUFDLENBQUM7YUFDM0Q7U0FDRjtRQUVELE9BQU8sYUFBYSxDQUFDO0lBQ3ZCLENBQUM7SUFFRCxXQUFXLENBQ1QsS0FBeUIsRUFDekIsVUFBaUM7SUFDakMsNkRBQTZEO0lBQzdELE9BQXdCO1FBRXhCLElBQUksR0FBRyxHQUFHLFVBQXlCLENBQUM7UUFDcEMsSUFBSSxPQUFPLEdBQUcsS0FBSyxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsT0FBTyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM1RCxJQUFJLEdBQUcsQ0FBQyxNQUFNLEVBQUU7WUFDZCxPQUFPLEdBQUcsYUFBYSxDQUFDLE9BQU8sRUFB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LENBQUMsTUFBTSxFQUFFLE1BQU0sR0FBRyxLQUFLLENBQUMsQ0FBQztLQUM5QztTQUFNO1FBQ0wsTUFBTSxJQUFJLHlCQUF5QixDQUNqQyxtRkFBbUYsQ0FDcEYsQ0FBQztLQUNIO0FBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFF1ZXJ5RXhwcmVzc2lvblBhcnNlRXJyb3IsIFJlcXVlc3RPcHRpb25zIH0gZnJvbSAnQG9yYml0L2RhdGEnO1xuaW1wb3J0IHtcbiAgQXR0cmlidXRlU29ydFNwZWNpZmllcixcbiAgRmluZFJlY29yZCxcbiAgRmluZFJlY29yZHMsXG4gIEZpbmRSZWxhdGVkUmVjb3JkLFxuICBGaW5kUmVsYXRlZFJlY29yZHMsXG4gIEluaXRpYWxpemVkUmVjb3JkLFxuICBSZWNvcmRJZGVudGl0eSxcbiAgUmVjb3JkTm90Rm91bmRFeGNlcHRpb24sXG4gIFJlY29yZFF1ZXJ5RXhwcmVzc2lvbixcbiAgUmVjb3JkUXVlcnlFeHByZXNzaW9uUmVzdWx0LFxuICBTb3J0U3BlY2lmaWVyXG59IGZyb20gJ0BvcmJpdC9yZWNvcmRzJztcbmltcG9ydCB7IGRlZXBHZXQsIERpY3QsIGlzTm9uZSB9IGZyb20gJ0BvcmJpdC91dGlscyc7XG5pbXBvcnQgeyBTeW5jUmVjb3JkQWNjZXNzb3IgfSBmcm9tICcuLi9yZWNvcmQtYWNjZXNzb3InO1xuXG5leHBvcnQgaW50ZXJmYWNlIFN5bmNRdWVyeU9wZXJhdG9yIHtcbiAgKFxuICAgIGNhY2hlOiBTeW5jUmVjb3JkQWNjZXNzb3IsXG4gICAgZXhwcmVzc2lvbjogUmVjb3JkUXVlcnlFeHByZXNzaW9uLFxuICAgIG9wdGlvbnM/OiBSZXF1ZXN0T3B0aW9uc1xuICApOiBSZWNvcmRRdWVyeUV4cHJlc3Npb25SZXN1bHQ7XG59XG5cbmV4cG9ydCBjb25zdCBTeW5jUXVlcnlPcGVyYXRvcnM6IERpY3Q8U3luY1F1ZXJ5T3BlcmF0b3I+ID0ge1xuICBmaW5kUmVjb3JkKFxuICAgIGNhY2hlOiBTeW5jUmVjb3JkQWNjZXNzb3IsXG4gICAgZXhwcmVzc2lvbjogUmVjb3JkUXVlcnlFeHByZXNzaW9uLFxuICAgIG9wdGlvbnM/OiBSZXF1ZXN0T3B0aW9uc1xuICApOiBJbml0aWFsaXplZFJlY29yZCB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgeyByZWNvcmQgfSA9IGV4cHJlc3Npb24gYXMgRmluZFJlY29yZDtcbiAgICBjb25zdCBjdXJyZW50UmVjb3JkID0gY2FjaGUuZ2V0UmVjb3JkU3luYyhyZWNvcmQpO1xuXG4gICAgaWYgKCFjdXJyZW50UmVjb3JkKSB7XG4gICAgICBpZiAob3B0aW9ucz8ucmFpc2VOb3RGb3VuZEV4Y2VwdGlvbnMpIHtcbiAgICAgICAgdGhyb3cgbmV3IFJlY29yZE5vdEZvdW5kRXhjZXB0aW9uKHJlY29yZC50eXBlLCByZWNvcmQuaWQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBjdXJyZW50UmVjb3JkO1xuICB9LFxuXG4gIGZpbmRSZWNvcmRzKFxuICAgIGNhY2hlOiBTeW5jUmVjb3JkQWNjZXNzb3IsXG4gICAgZXhwcmVzc2lvbjogUmVjb3JkUXVlcnlFeHByZXNzaW9uLFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICBvcHRpb25zPzogUmVxdWVzdE9wdGlvbnNcbiAgKTogSW5pdGlhbGl6ZWRSZWNvcmRbXSB7XG4gICAgbGV0IGV4cCA9IGV4cHJlc3Npb24gYXMgRmluZFJlY29yZHM7XG4gICAgbGV0IHJlc3VsdHMgPSBjYWNoZS5nZXRSZWNvcmRzU3luYyhleHAucmVjb3JkcyB8fCBleHAudHlwZSk7XG4gICAgaWYgKGV4cC5maWx0ZXIpIHtcbiAgICAgIHJlc3VsdHMgPSBmaWx0ZXJSZWNvcmRzKHJlc3VsdHMsIGV4cC5maWx0ZXIpO1xuICAgIH1cbiAgICBpZiAoZXhwLnNvcnQpIHtcbiAgICAgIHJlc3VsdHMgPSBzb3J0UmVjb3JkcyhyZXN1bHRzLCBleHAuc29ydCk7XG4gICAgfVxuICAgIGlmIChleHAucGFnZSkge1xuICAgICAgcmVzdWx0cyA9IHBhZ2luYXRlUmVjb3JkcyhyZXN1bHRzLCBleHAucGFnZSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHRzO1xuICB9LFxuXG4gIGZpbmRSZWxhdGVkUmVjb3JkcyhcbiAgICBjYWNoZTogU3luY1JlY29yZEFjY2Vzc29yLFxuICAgIGV4cHJlc3Npb246IFJlY29yZFF1ZXJ5RXhwcmVzc2lvbixcbiAgICBvcHRpb25zPzogUmVxdWVzdE9wdGlvbnNcbiAgKTogSW5pdGlhbGl6ZWRSZWNvcmRbXSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgZXhwID0gZXhwcmVzc2lvbiBhcyBGaW5kUmVsYXRlZFJlY29yZHM7XG4gICAgY29uc3QgeyByZWNvcmQsIHJlbGF0aW9uc2hpcCB9ID0gZXhwO1xuICAgIGNvbnN0IHJlbGF0ZWRJZHMgPSBjYWNoZS5nZXRSZWxhdGVkUmVjb3Jkc1N5bmMocmVjb3JkLCByZWxhdGlvbnNoaXApO1xuICAgIGlmICghcmVsYXRlZElkcyB8fCByZWxhdGVkSWRzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgaWYgKCFjYWNoZS5nZXRSZWNvcmRTeW5jKHJlY29yZCkpIHtcbiAgICAgICAgaWYgKG9wdGlvbnM/LnJhaXNlTm90Rm91bmRFeGNlcHRpb25zKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFJlY29yZE5vdEZvdW5kRXhjZXB0aW9uKHJlY29yZC50eXBlLCByZWNvcmQuaWQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICBsZXQgcmVzdWx0cyA9IGNhY2hlLmdldFJlY29yZHNTeW5jKHJlbGF0ZWRJZHMpO1xuXG4gICAgaWYgKGV4cC5maWx0ZXIpIHtcbiAgICAgIHJlc3VsdHMgPSBmaWx0ZXJSZWNvcmRzKHJlc3VsdHMsIGV4cC5maWx0ZXIpO1xuICAgIH1cbiAgICBpZiAoZXhwLnNvcnQpIHtcbiAgICAgIHJlc3VsdHMgPSBzb3J0UmVjb3JkcyhyZXN1bHRzLCBleHAuc29ydCk7XG4gICAgfVxuICAgIGlmIChleHAucGFnZSkge1xuICAgICAgcmVzdWx0cyA9IHBhZ2luYXRlUmVjb3JkcyhyZXN1bHRzLCBleHAucGFnZSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHRzO1xuICB9LFxuXG4gIGZpbmRSZWxhdGVkUmVjb3JkKFxuICAgIGNhY2hlOiBTeW5jUmVjb3JkQWNjZXNzb3IsXG4gICAgZXhwcmVzc2lvbjogUmVjb3JkUXVlcnlFeHByZXNzaW9uLFxuICAgIG9wdGlvbnM/OiBSZXF1ZXN0T3B0aW9uc1xuICApOiBJbml0aWFsaXplZFJlY29yZCB8IG51bGwgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGV4cCA9IGV4cHJlc3Npb24gYXMgRmluZFJlbGF0ZWRSZWNvcmQ7XG4gICAgY29uc3QgeyByZWNvcmQsIHJlbGF0aW9uc2hpcCB9ID0gZXhwO1xuICAgIGNvbnN0IHJlbGF0ZWRJZCA9IGNhY2hlLmdldFJlbGF0ZWRSZWNvcmRTeW5jKHJlY29yZCwgcmVsYXRpb25zaGlwKTtcblxuICAgIGlmIChyZWxhdGVkSWQpIHtcbiAgICAgIHJldHVybiBjYWNoZS5nZXRSZWNvcmRTeW5jKHJlbGF0ZWRJZCkgfHwgbnVsbDtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCFjYWNoZS5nZXRSZWNvcmRTeW5jKHJlY29yZCkpIHtcbiAgICAgICAgaWYgKG9wdGlvbnM/LnJhaXNlTm90Rm91bmRFeGNlcHRpb25zKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFJlY29yZE5vdEZvdW5kRXhjZXB0aW9uKHJlY29yZC50eXBlLCByZWNvcmQuaWQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG59O1xuXG5mdW5jdGlvbiBmaWx0ZXJSZWNvcmRzKHJlY29yZHM6IEluaXRpYWxpemVkUmVjb3JkW10sIGZpbHRlcnM6IGFueVtdKSB7XG4gIHJldHVybiByZWNvcmRzLmZpbHRlcigocmVjb3JkKSA9PiB7XG4gICAgZm9yIChsZXQgaSA9IDAsIGwgPSBmaWx0ZXJzLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgaWYgKCFhcHBseUZpbHRlcihyZWNvcmQsIGZpbHRlcnNbaV0pKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBhcHBseUZpbHRlcihyZWNvcmQ6IEluaXRpYWxpemVkUmVjb3JkLCBmaWx0ZXI6IGFueSk6IGJvb2xlYW4ge1xuICBpZiAoZmlsdGVyLmtpbmQgPT09ICdhdHRyaWJ1dGUnKSB7XG4gICAgbGV0IGFjdHVhbCA9IGRlZXBHZXQocmVjb3JkLCBbJ2F0dHJpYnV0ZXMnLCBmaWx0ZXIuYXR0cmlidXRlXSk7XG4gICAgaWYgKGFjdHVhbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGxldCBleHBlY3RlZCA9IGZpbHRlci52YWx1ZTtcbiAgICBzd2l0Y2ggKGZpbHRlci5vcCkge1xuICAgICAgY2FzZSAnZXF1YWwnOlxuICAgICAgICByZXR1cm4gYWN0dWFsID09PSBleHBlY3RlZDtcbiAgICAgIGNhc2UgJ2d0JzpcbiAgICAgICAgcmV0dXJuIGFjdHVhbCA+IGV4cGVjdGVkO1xuICAgICAgY2FzZSAnZ3RlJzpcbiAgICAgICAgcmV0dXJuIGFjdHVhbCA+PSBleHBlY3RlZDtcbiAgICAgIGNhc2UgJ2x0JzpcbiAgICAgICAgcmV0dXJuIGFjdHVhbCA8IGV4cGVjdGVkO1xuICAgICAgY2FzZSAnbHRlJzpcbiAgICAgICAgcmV0dXJuIGFjdHVhbCA8PSBleHBlY3RlZDtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBRdWVyeUV4cHJlc3Npb25QYXJzZUVycm9yKFxuICAgICAgICAgICdGaWx0ZXIgb3BlcmF0aW9uICR7ZmlsdGVyLm9wfSBub3QgcmVjb2duaXplZCBmb3IgU3RvcmUuJ1xuICAgICAgICApO1xuICAgIH1cbiAgfSBlbHNlIGlmIChmaWx0ZXIua2luZCA9PT0gJ3JlbGF0ZWRSZWNvcmRzJykge1xuICAgIGxldCBhY3R1YWw6IFJlY29yZElkZW50aXR5W10gPSBkZWVwR2V0KHJlY29yZCwgW1xuICAgICAgJ3JlbGF0aW9uc2hpcHMnLFxuICAgICAgZmlsdGVyLnJlbGF0aW9uLFxuICAgICAgJ2RhdGEnXG4gICAgXSk7XG4gICAgaWYgKGFjdHVhbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGxldCBleHBlY3RlZDogUmVjb3JkSWRlbnRpdHlbXSA9IGZpbHRlci5yZWNvcmRzO1xuICAgIHN3aXRjaCAoZmlsdGVyLm9wKSB7XG4gICAgICBjYXNlICdlcXVhbCc6XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgYWN0dWFsLmxlbmd0aCA9PT0gZXhwZWN0ZWQubGVuZ3RoICYmXG4gICAgICAgICAgZXhwZWN0ZWQuZXZlcnkoKGUpID0+XG4gICAgICAgICAgICBhY3R1YWwuc29tZSgoYSkgPT4gYS5pZCA9PT0gZS5pZCAmJiBhLnR5cGUgPT09IGUudHlwZSlcbiAgICAgICAgICApXG4gICAgICAgICk7XG4gICAgICBjYXNlICdhbGwnOlxuICAgICAgICByZXR1cm4gZXhwZWN0ZWQuZXZlcnkoKGUpID0+XG4gICAgICAgICAgYWN0dWFsLnNvbWUoKGEpID0+IGEuaWQgPT09IGUuaWQgJiYgYS50eXBlID09PSBlLnR5cGUpXG4gICAgICAgICk7XG4gICAgICBjYXNlICdzb21lJzpcbiAgICAgICAgcmV0dXJuIGV4cGVjdGVkLnNvbWUoKGUpID0+XG4gICAgICAgICAgYWN0dWFsLnNvbWUoKGEpID0+IGEuaWQgPT09IGUuaWQgJiYgYS50eXBlID09PSBlLnR5cGUpXG4gICAgICAgICk7XG4gICAgICBjYXNlICdub25lJzpcbiAgICAgICAgcmV0dXJuICFleHBlY3RlZC5zb21lKChlKSA9PlxuICAgICAgICAgIGFjdHVhbC5zb21lKChhKSA9PiBhLmlkID09PSBlLmlkICYmIGEudHlwZSA9PT0gZS50eXBlKVxuICAgICAgICApO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IFF1ZXJ5RXhwcmVzc2lvblBhcnNlRXJyb3IoXG4gICAgICAgICAgJ0ZpbHRlciBvcGVyYXRpb24gJHtmaWx0ZXIub3B9IG5vdCByZWNvZ25pemVkIGZvciBTdG9yZS4nXG4gICAgICAgICk7XG4gICAgfVxuICB9IGVsc2UgaWYgKGZpbHRlci5raW5kID09PSAncmVsYXRlZFJlY29yZCcpIHtcbiAgICBsZXQgYWN0dWFsID0gZGVlcEdldChyZWNvcmQsIFsncmVsYXRpb25zaGlwcycsIGZpbHRlci5yZWxhdGlvbiwgJ2RhdGEnXSk7XG4gICAgaWYgKGFjdHVhbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGxldCBleHBlY3RlZCA9IGZpbHRlci5yZWNvcmQ7XG4gICAgc3dpdGNoIChmaWx0ZXIub3ApIHtcbiAgICAgIGNhc2UgJ2VxdWFsJzpcbiAgICAgICAgaWYgKGFjdHVhbCA9PT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiBleHBlY3RlZCA9PT0gbnVsbDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShleHBlY3RlZCkpIHtcbiAgICAgICAgICAgIHJldHVybiBleHBlY3RlZC5zb21lKFxuICAgICAgICAgICAgICAoZSkgPT4gYWN0dWFsLnR5cGUgPT09IGUudHlwZSAmJiBhY3R1YWwuaWQgPT09IGUuaWRcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSBlbHNlIGlmIChleHBlY3RlZCkge1xuICAgICAgICAgICAgcmV0dXJuIGFjdHVhbC50eXBlID09PSBleHBlY3RlZC50eXBlICYmIGFjdHVhbC5pZCA9PT0gZXhwZWN0ZWQuaWQ7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBRdWVyeUV4cHJlc3Npb25QYXJzZUVycm9yKFxuICAgICAgICAgICdGaWx0ZXIgb3BlcmF0aW9uICR7ZmlsdGVyLm9wfSBub3QgcmVjb2duaXplZCBmb3IgU3RvcmUuJ1xuICAgICAgICApO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIHNvcnRSZWNvcmRzKFxuICByZWNvcmRzOiBJbml0aWFsaXplZFJlY29yZFtdLFxuICBzb3J0U3BlY2lmaWVyczogU29ydFNwZWNpZmllcltdXG4pOiBJbml0aWFsaXplZFJlY29yZFtdIHtcbiAgY29uc3QgY29tcGFyaXNvblZhbHVlcyA9IG5ldyBNYXAoKTtcblxuICByZWNvcmRzLmZvckVhY2goKHJlY29yZCkgPT4ge1xuICAgIGNvbXBhcmlzb25WYWx1ZXMuc2V0KFxuICAgICAgcmVjb3JkLFxuICAgICAgc29ydFNwZWNpZmllcnMubWFwKChzb3J0U3BlY2lmaWVyKSA9PiB7XG4gICAgICAgIGlmIChzb3J0U3BlY2lmaWVyLmtpbmQgPT09ICdhdHRyaWJ1dGUnKSB7XG4gICAgICAgICAgcmV0dXJuIGRlZXBHZXQocmVjb3JkLCBbXG4gICAgICAgICAgICAnYXR0cmlidXRlcycsXG4gICAgICAgICAgICAoc29ydFNwZWNpZmllciBhcyBBdHRyaWJ1dGVTb3J0U3BlY2lmaWVyKS5hdHRyaWJ1dGVcbiAgICAgICAgICBdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aHJvdyBuZXcgUXVlcnlFeHByZXNzaW9uUGFyc2VFcnJvcihcbiAgICAgICAgICAgICdTb3J0IHNwZWNpZmllciAke3NvcnRTcGVjaWZpZXIua2luZH0gbm90IHJlY29nbml6ZWQgZm9yIFN0b3JlLidcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICk7XG4gIH0pO1xuXG4gIGNvbnN0IGNvbXBhcmlzb25PcmRlcnMgPSBzb3J0U3BlY2lmaWVycy5tYXAoKHNvcnRFeHByZXNzaW9uKSA9PlxuICAgIHNvcnRFeHByZXNzaW9uLm9yZGVyID09PSAnZGVzY2VuZGluZycgPyAtMSA6IDFcbiAgKTtcblxuICByZXR1cm4gcmVjb3Jkcy5zb3J0KChyZWNvcmQxLCByZWNvcmQyKSA9PiB7XG4gICAgY29uc3QgdmFsdWVzMSA9IGNvbXBhcmlzb25WYWx1ZXMuZ2V0KHJlY29yZDEpO1xuICAgIGNvbnN0IHZhbHVlczIgPSBjb21wYXJpc29uVmFsdWVzLmdldChyZWNvcmQyKTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNvcnRTcGVjaWZpZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAodmFsdWVzMVtpXSA8IHZhbHVlczJbaV0pIHtcbiAgICAgICAgcmV0dXJuIC1jb21wYXJpc29uT3JkZXJzW2ldO1xuICAgICAgfSBlbHNlIGlmICh2YWx1ZXMxW2ldID4gdmFsdWVzMltpXSkge1xuICAgICAgICByZXR1cm4gY29tcGFyaXNvbk9yZGVyc1tpXTtcbiAgICAgIH0gZWxzZSBpZiAoaXNOb25lKHZhbHVlczFbaV0pICYmICFpc05vbmUodmFsdWVzMltpXSkpIHtcbiAgICAgICAgcmV0dXJuIGNvbXBhcmlzb25PcmRlcnNbaV07XG4gICAgICB9IGVsc2UgaWYgKGlzTm9uZSh2YWx1ZXMyW2ldKSAmJiAhaXNOb25lKHZhbHVlczFbaV0pKSB7XG4gICAgICAgIHJldHVybiAtY29tcGFyaXNvbk9yZGVyc1tpXTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIDA7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBwYWdpbmF0ZVJlY29yZHMoXG4gIHJlY29yZHM6IEluaXRpYWxpemVkUmVjb3JkW10sXG4gIHBhZ2luYXRpb25PcHRpb25zOiBhbnlcbik6IEluaXRpYWxpemVkUmVjb3JkW10ge1xuICBpZiAocGFnaW5hdGlvbk9wdGlvbnMubGltaXQgIT09IHVuZGVmaW5lZCkge1xuICAgIGxldCBvZmZzZXQgPVxuICAgICAgcGFnaW5hdGlvbk9wdGlvbnMub2Zmc2V0ID09PSB1bmRlZmluZWQgPyAwIDogcGFnaW5hdGlvbk9wdGlvbnMub2Zmc2V0O1xuICAgIGxldCBsaW1pdCA9IHBhZ2luYXRpb25PcHRpb25zLmxpbWl0O1xuXG4gICAgcmV0dXJuIHJlY29yZHMuc2xpY2Uob2Zmc2V0LCBvZmZzZXQgKyBsaW1pdCk7XG4gIH0gZWxzZSB7XG4gICAgdGhyb3cgbmV3IFF1ZXJ5RXhwcmVzc2lvblBhcnNlRXJyb3IoXG4gICAgICAnUGFnaW5hdGlvbiBvcHRpb25zIG5vdCByZWNvZ25pemVkIGZvciBTdG9yZS4gUGxlYXNlIHNwZWNpZnkgYG9mZnNldGAgYW5kIGBsaW1pdGAuJ1xuICAgICk7XG4gIH1cbn1cbiJdfQ==