UNPKG

@orbit/records

Version:

A flexible data access and synchronization layer.

114 lines 18.5 kB
import { isNone, clone } from '@orbit/utils'; export function cloneRecordIdentity(identity) { const { type, id } = identity; return { type, id }; } export function equalRecordIdentities(record1, record2) { return ((isNone(record1) && isNone(record2)) || (!!record1 && !!record2 && record1.type === record2.type && record1.id === record2.id)); } export function equalRecordIdentitySets(set1, set2) { if (set1.length === set2.length) { if (set1.length === 0) { return true; } const serialized1 = serializeRecordIdentities(set1); const serialized2 = serializeRecordIdentities(set2); return (exclusiveIdentities(serialized1, serialized2).length === 0 && exclusiveIdentities(serialized2, serialized1).length === 0); } return false; } export function uniqueRecordIdentities(set1, set2) { return exclusiveIdentities(serializeRecordIdentities(set1), serializeRecordIdentities(set2)).map((id) => deserializeRecordIdentity(id)); } export function dedupeRecordIdentities(recordIdentities) { let dict = {}; let deduped = []; recordIdentities.forEach((ri) => { const sri = serializeRecordIdentity(ri); if (dict[sri] === undefined) { deduped.push(ri); dict[sri] = true; } }); return deduped; } export function recordsInclude(records, match) { for (let r of records) { if (equalRecordIdentities(r, match)) { return true; } } return false; } export function recordsIncludeAll(records, match) { return (exclusiveIdentities(serializeRecordIdentities(match), serializeRecordIdentities(records)).length === 0); } export function mergeRecords(current, updates) { if (current) { let record = cloneRecordIdentity(current); // Merge `meta` and `links`, replacing whole sections rather than merging // individual members mergeRecordSection(record, current, updates, 'meta', 0); mergeRecordSection(record, current, updates, 'links', 0); // Merge attributes and keys, replacing at the individual field level mergeRecordSection(record, current, updates, 'attributes', 1); mergeRecordSection(record, current, updates, 'keys', 1); // Merge relationships, replacing at the `data`, `links`, and `meta` level // for each relationship mergeRecordSection(record, current, updates, 'relationships', 2); return record; } else { return clone(updates); } } function mergeRecordSection(record, current, update, section, replacementDepth) { if (current[section] && update[section]) { if (replacementDepth === 0) { record[section] = clone(update[section]); } else if (replacementDepth === 1) { record[section] = Object.assign({}, current[section], update[section]); } else { record[section] = {}; for (let name of Object.keys(current[section])) { mergeRecordSection(record[section], current[section], update[section], name, replacementDepth - 1); } for (let name of Object.keys(update[section])) { if (!record[section][name]) { record[section][name] = clone(update[section][name]); } } } } else if (current[section]) { record[section] = clone(current[section]); } else if (update[section]) { record[section] = clone(update[section]); } } export function isRecordIdentity(identity) { const { id, type } = identity; return typeof id === 'string' && typeof type === 'string'; } export function serializeRecordIdentity(record) { return `${record.type}:${record.id}`; } export function deserializeRecordIdentity(identity) { const [type, id] = identity.split(':'); return { type, id }; } function serializeRecordIdentities(recordIdentities) { return recordIdentities.map((r) => serializeRecordIdentity(r)); } function exclusiveIdentities(identities1, identities2) { return identities1.filter((i) => !identities2.includes(i)); } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVjb3JkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3JlY29yZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQVEsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLGNBQWMsQ0FBQztBQStEbkQsTUFBTSxVQUFVLG1CQUFtQixDQUFDLFFBQXdCO0lBQzFELE1BQU0sRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLEdBQUcsUUFBUSxDQUFDO0lBQzlCLE9BQU8sRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUM7QUFDdEIsQ0FBQztBQUVELE1BQU0sVUFBVSxxQkFBcUIsQ0FDbkMsT0FBK0IsRUFDL0IsT0FBK0I7SUFFL0IsT0FBTyxDQUNMLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNwQyxDQUFDLENBQUMsQ0FBQyxPQUFPO1lBQ1IsQ0FBQyxDQUFDLE9BQU87WUFDVCxPQUFPLENBQUMsSUFBSSxLQUFLLE9BQU8sQ0FBQyxJQUFJO1lBQzdCLE9BQU8sQ0FBQyxFQUFFLEtBQUssT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUM3QixDQUFDO0FBQ0osQ0FBQztBQUVELE1BQU0sVUFBVSx1QkFBdUIsQ0FDckMsSUFBc0IsRUFDdEIsSUFBc0I7SUFFdEIsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLElBQUksQ0FBQyxNQUFNLEVBQUU7UUFDL0IsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtZQUNyQixPQUFPLElBQUksQ0FBQztTQUNiO1FBRUQsTUFBTSxXQUFXLEdBQUcseUJBQXlCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDcEQsTUFBTSxXQUFXLEdBQUcseUJBQXlCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFcEQsT0FBTyxDQUNMLG1CQUFtQixDQUFDLFdBQVcsRUFBRSxXQUFXLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQztZQUMxRCxtQkFB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TUFBTSxDQUFDLE9BQU8sQ0FBQyxFQUFFO1FBQzFCLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7S0FDMUM7QUFDSCxDQUFDO0FBRUQsTUFBTSxVQUFVLGdCQUFnQixDQUM5QixRQUFrQztJQUVsQyxNQUFNLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxHQUFHLFFBQTBCLENBQUM7SUFDaEQsT0FBTyxPQUFPLEVBQUUsS0FBSyxRQUFRLElBQUksT0FBTyxJQUFJLEtBQUssUUFBUSxDQUFDO0FBQzVELENBQUM7QUFFRCxNQUFNLFVBQVUsdUJBQXVCLENBQUMsTUFBc0I7SUFDNUQsT0FBTyxHQUFHLE1BQU0sQ0FBQyxJQUFJLElBQUksTUFBTSxDQUFDLEVBQUUsRUFBRSxDQUFDO0FBQ3ZDLENBQUM7QUFFRCxNQUFNLFVBQVUseUJBQXlCLENBQUMsUUFBZ0I7SUFDeEQsTUFBTSxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3ZDLE9BQU8sRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLENBQUM7QUFDdEIsQ0FBQztBQUVELFNBQVMseUJBQXlCLENBQ2hDLGdCQUFrQztJQUVsQyxPQUFPLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsdUJBQXVCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUNqRSxDQUFDO0FBRUQsU0FBUyxtQkFBbUIsQ0FDMUIsV0FBcUIsRUFDckIsV0FBcUI7SUFFckIsT0FBTyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUM3RCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRGljdCwgaXNOb25lLCBjbG9uZSB9IGZyb20gJ0BvcmJpdC91dGlscyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTGlua09iamVjdCB7XG4gIGhyZWY6IHN0cmluZztcbiAgbWV0YT86IERpY3Q8dW5rbm93bj47XG59XG5cbmV4cG9ydCB0eXBlIExpbmsgPSBzdHJpbmcgfCBMaW5rT2JqZWN0O1xuXG5leHBvcnQgaW50ZXJmYWNlIFJlY29yZElkZW50aXR5IHtcbiAgdHlwZTogc3RyaW5nO1xuICBpZDogc3RyaW5nO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlY29yZEhhc09uZVJlbGF0aW9uc2hpcCB7XG4gIGRhdGE/OiBSZWNvcmRJZGVudGl0eSB8IG51bGw7XG4gIGxpbmtzPzogRGljdDxMaW5rPjtcbiAgbWV0YT86IERpY3Q8dW5rbm93bj47XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVjb3JkSGFzTWFueVJlbGF0aW9uc2hpcCB7XG4gIGRhdGE/OiBSZWNvcmRJZGVudGl0eVtdO1xuICBsaW5rcz86IERpY3Q8TGluaz47XG4gIG1ldGE/OiBEaWN0PHVua25vd24+O1xufVxuXG5leHBvcnQgdHlwZSBSZWNvcmRSZWxhdGlvbnNoaXAgPVxuICB8IFJlY29yZEhhc09uZVJlbGF0aW9uc2hpcFxuICB8IFJlY29yZEhhc01hbnlSZWxhdGlvbnNoaXA7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVjb3JkRmllbGRzIHtcbiAga2V5cz86IERpY3Q8c3RyaW5nPjtcbiAgYXR0cmlidXRlcz86IERpY3Q8dW5rbm93bj47XG4gIHJlbGF0aW9uc2hpcHM/OiBEaWN0PFJlY29yZFJlbGF0aW9uc2hpcD47XG4gIGxpbmtzPzogRGljdDxMaW5rPjtcbiAgbWV0YT86IERpY3Q8dW5rbm93bj47XG59XG5cbi8qKlxuICogQGRlcHJlY2F0ZWQgc2luY2UgdjAuMTcsIHVzZSBhbGlhcyBgSW5pdGlhbGl6ZWRSZWNvcmRgIGluc3RlYWRcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZWNvcmQgZXh0ZW5kcyBSZWNvcmRGaWVsZHMsIFJlY29yZElkZW50aXR5IHt9XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW5pdGlhbGl6ZWRSZWNvcmQgZXh0ZW5kcyBSZWNvcmRGaWVsZHMsIFJlY29yZElkZW50aXR5IHt9XG5cbmV4cG9ydCBpbnRlcmZhY2UgVW5pbml0aWFsaXplZFJlY29yZCBleHRlbmRzIFJlY29yZEZpZWxkcyB7XG4gIHR5cGU6IHN0cmluZztcbiAgaWQ/OiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVjb3JkS2V5VmFsdWUge1xuICB0eXBlOiBzdHJpbmc7XG4gIGtleTogc3RyaW5nO1xuICB2YWx1ZTogc3RyaW5nO1xufVxuXG4vKipcbiAqIEBkZXByZWNhdGVkIHNpbmNlIHYwLjE3LCByZXBsYWNlZCBieSBgUmVjb3JkTm9ybWFsaXplcmBcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZWNvcmRJbml0aWFsaXplciB7XG4gIGluaXRpYWxpemVSZWNvcmQocmVjb3JkOiBVbmluaXRpYWxpemVkUmVjb3JkKTogSW5pdGlhbGl6ZWRSZWNvcmQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjbG9uZVJlY29yZElkZW50aXR5KGlkZW50aXR5OiBSZWNvcmRJZGVudGl0eSk6IFJlY29yZElkZW50aXR5IHtcbiAgY29uc3QgeyB0eXBlLCBpZCB9ID0gaWRlbnRpdHk7XG4gIHJldHVybiB7IHR5cGUsIGlkIH07XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBlcXVhbFJlY29yZElkZW50aXRpZXMoXG4gIHJlY29yZDE/OiBSZWNvcmRJZGVudGl0eSB8IG51bGwsXG4gIHJlY29yZDI/OiBSZWNvcmRJZGVudGl0eSB8IG51bGxcbik6IGJvb2xlYW4ge1xuICByZXR1cm4gKFxuICAgIChpc05vbmUocmVjb3JkMSkgJiYgaXNOb25lKHJlY29yZDIpKSB8fFxuICAgICghIXJlY29yZDEgJiZcbiAgICAgICEhcmVjb3JkMiAmJlxuICAgICAgcmVjb3JkMS50eXBlID09PSByZWNvcmQyLnR5cGUgJiZcbiAgICAgIHJlY29yZDEuaWQgPT09IHJlY29yZDIuaWQpXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBlcXVhbFJlY29yZElkZW50aXR5U2V0cyhcbiAgc2V0MTogUmVjb3JkSWRlbnRpdHlbXSxcbiAgc2V0MjogUmVjb3JkSWRlbnRpdHlbXVxuKTogYm9vbGVhbiB7XG4gIGlmIChzZXQxLmxlbmd0aCA9PT0gc2V0Mi5sZW5ndGgpIHtcbiAgICBpZiAoc2V0MS5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGNvbnN0IHNlcmlhbGl6ZWQxID0gc2VyaWFsaXplUmVjb3JkSWRlbnRpdGllcyhzZXQxKTtcbiAgICBjb25zdCBzZXJpYWxpemVkMiA9IHNlcmlhbGl6ZVJlY29yZElkZW50aXRpZXMoc2V0Mik7XG5cbiAgICByZXR1cm4gKFxuICAgICAgZXhjbHVzaXZlSWRlbnRpdGllcyhzZXJpYWxpemVkMSwgc2VyaWFsaXplZDIpLmxlbmd0aCA9PT0gMCAmJlxuICAgICAgZXhjbHVzaXZlSWRlbnRpdGllcyhzZXJpYWxpemVkMiwgc2VyaWFsaXplZDEpLmxlbmd0aCA9PT0gMFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdW5pcXVlUmVjb3JkSWRlbnRpdGllcyhcbiAgc2V0MTogUmVjb3JkSWRlbnRpdHlbXSxcbiAgc2V0MjogUmVjb3JkSWRlbnRpdHlbXVxuKTogUmVjb3JkSWRlbnRpdHlbXSB7XG4gIHJldHVybiBleGNsdXNpdmVJZGVudGl0aWVzKFxuICAgIHNlcmlhbGl6ZVJlY29yZElkZW50aXRpZXMoc2V0MSksXG4gICAgc2VyaWFsaXplUmVjb3JkSWRlbnRpdGllcyhzZXQyKVxuICApLm1hcCgoaWQpID0+IGRlc2VyaWFsaXplUmVjb3JkSWRlbnRpdHkoaWQpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRlZHVwZVJlY29yZElkZW50aXRpZXMoXG4gIHJlY29yZElkZW50aXRpZXM6IFJlY29yZElkZW50aXR5W11cbik6IFJlY29yZElkZW50aXR5W10ge1xuICBsZXQgZGljdDogRGljdDx0cnVlPiA9IHt9O1xuICBsZXQgZGVkdXBlZDogUmVjb3JkSWRlbnRpdHlbXSA9IFtdO1xuICByZWNvcmRJZGVudGl0aWVzLmZvckVhY2goKHJpKSA9PiB7XG4gICAgY29uc3Qgc3JpID0gc2VyaWFsaXplUmVjb3JkSWRlbnRpdHkocmkpO1xuICAgIGlmIChkaWN0W3NyaV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgZGVkdXBlZC5wdXNoKHJpKTtcbiAgICAgIGRpY3Rbc3JpXSA9IHRydWU7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIGRlZHVwZWQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZWNvcmRzSW5jbHVkZShcbiAgcmVjb3JkczogUmVjb3JkSWRlbnRpdHlbXSxcbiAgbWF0Y2g6IFJlY29yZElkZW50aXR5XG4pOiBib29sZWFuIHtcbiAgZm9yIChsZXQgciBvZiByZWNvcmRzKSB7XG4gICAgaWYgKGVxdWFsUmVjb3JkSWRlbnRpdGllcyhyLCBtYXRjaCkpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiByZWNvcmRzSW5jbHVkZUFsbChcbiAgcmVjb3JkczogUmVjb3JkSWRlbnRpdHlbXSxcbiAgbWF0Y2g6IFJlY29yZElkZW50aXR5W11cbik6IGJvb2xlYW4ge1xuICByZXR1cm4gKFxuICAgIGV4Y2x1c2l2ZUlkZW50aXRpZXMoXG4gICAgICBzZXJpYWxpemVSZWNvcmRJZGVudGl0aWVzKG1hdGNoKSxcbiAgICAgIHNlcmlhbGl6ZVJlY29yZElkZW50aXRpZXMocmVjb3JkcylcbiAgICApLmxlbmd0aCA9PT0gMFxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VSZWNvcmRzKFxuICBjdXJyZW50OiBJbml0aWFsaXplZFJlY29yZCB8IG51bGwsXG4gIHVwZGF0ZXM6IEluaXRpYWxpemVkUmVjb3JkXG4pOiBJbml0aWFsaXplZFJlY29yZCB7XG4gIGlmIChjdXJyZW50KSB7XG4gICAgbGV0IHJlY29yZDogSW5pdGlhbGl6ZWRSZWNvcmQgPSBjbG9uZVJlY29yZElkZW50aXR5KGN1cnJlbnQpO1xuXG4gICAgLy8gTWVyZ2UgYG1ldGFgIGFuZCBgbGlua3NgLCByZXBsYWNpbmcgd2hvbGUgc2VjdGlvbnMgcmF0aGVyIHRoYW4gbWVyZ2luZ1xuICAgIC8vIGluZGl2aWR1YWwgbWVtYmVyc1xuICAgIG1lcmdlUmVjb3JkU2VjdGlvbihyZWNvcmQsIGN1cnJlbnQsIHVwZGF0ZXMsICdtZXRhJywgMCk7XG4gICAgbWVyZ2VSZWNvcmRTZWN0aW9uKHJlY29yZCwgY3VycmVudCwgdXBkYXRlcywgJ2xpbmtzJywgMCk7XG5cbiAgICAvLyBNZXJnZSBhdHRyaWJ1dGVzIGFuZCBrZXlzLCByZXBsYWNpbmcgYXQgdGhlIGluZGl2aWR1YWwgZmllbGQgbGV2ZWxcbiAgICBtZXJnZVJlY29yZFNlY3Rpb24ocmVjb3JkLCBjdXJyZW50LCB1cGRhdGVzLCAnYXR0cmlidXRlcycsIDEpO1xuICAgIG1lcmdlUmVjb3JkU2VjdGlvbihyZWNvcmQsIGN1cnJlbnQsIHVwZGF0ZXMsICdrZXlzJywgMSk7XG5cbiAgICAvLyBNZXJnZSByZWxhdGlvbnNoaXBzLCByZXBsYWNpbmcgYXQgdGhlIGBkYXRhYCwgYGxpbmtzYCwgYW5kIGBtZXRhYCBsZXZlbFxuICAgIC8vIGZvciBlYWNoIHJlbGF0aW9uc2hpcFxuICAgIG1lcmdlUmVjb3JkU2VjdGlvbihyZWNvcmQsIGN1cnJlbnQsIHVwZGF0ZXMsICdyZWxhdGlvbnNoaXBzJywgMik7XG5cbiAgICByZXR1cm4gcmVjb3JkO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBjbG9uZSh1cGRhdGVzKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBtZXJnZVJlY29yZFNlY3Rpb24oXG4gIHJlY29yZDogYW55LFxuICBjdXJyZW50OiBhbnksXG4gIHVwZGF0ZTogYW55LFxuICBzZWN0aW9uOiBzdHJpbmcsXG4gIHJlcGxhY2VtZW50RGVwdGg6IG51bWJlclxuKTogdm9pZCB7XG4gIGlmIChjdXJyZW50W3NlY3Rpb25dICYmIHVwZGF0ZVtzZWN0aW9uXSkge1xuICAgIGlmIChyZXBsYWNlbWVudERlcHRoID09PSAwKSB7XG4gICAgICByZWNvcmRbc2VjdGlvbl0gPSBjbG9uZSh1cGRhdGVbc2VjdGlvbl0pO1xuICAgIH0gZWxzZSBpZiAocmVwbGFjZW1lbnREZXB0aCA9PT0gMSkge1xuICAgICAgcmVjb3JkW3NlY3Rpb25dID0gT2JqZWN0LmFzc2lnbih7fSwgY3VycmVudFtzZWN0aW9uXSwgdXBkYXRlW3NlY3Rpb25dKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVjb3JkW3NlY3Rpb25dID0ge307XG4gICAgICBmb3IgKGxldCBuYW1lIG9mIE9iamVjdC5rZXlzKGN1cnJlbnRbc2VjdGlvbl0pKSB7XG4gICAgICAgIG1lcmdlUmVjb3JkU2VjdGlvbihcbiAgICAgICAgICByZWNvcmRbc2VjdGlvbl0sXG4gICAgICAgICAgY3VycmVudFtzZWN0aW9uXSxcbiAgICAgICAgICB1cGRhdGVbc2VjdGlvbl0sXG4gICAgICAgICAgbmFtZSxcbiAgICAgICAgICByZXBsYWNlbWVudERlcHRoIC0gMVxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgZm9yIChsZXQgbmFtZSBvZiBPYmplY3Qua2V5cyh1cGRhdGVbc2VjdGlvbl0pKSB7XG4gICAgICAgIGlmICghcmVjb3JkW3NlY3Rpb25dW25hbWVdKSB7XG4gICAgICAgICAgcmVjb3JkW3NlY3Rpb25dW25hbWVdID0gY2xvbmUodXBkYXRlW3NlY3Rpb25dW25hbWVdKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmIChjdXJyZW50W3NlY3Rpb25dKSB7XG4gICAgcmVjb3JkW3NlY3Rpb25dID0gY2xvbmUoY3VycmVudFtzZWN0aW9uXSk7XG4gIH0gZWxzZSBpZiAodXBkYXRlW3NlY3Rpb25dKSB7XG4gICAgcmVjb3JkW3NlY3Rpb25dID0gY2xvbmUodXBkYXRlW3NlY3Rpb25dKTtcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNSZWNvcmRJZGVudGl0eShcbiAgaWRlbnRpdHk6IFJlY29yZElkZW50aXR5IHwgdW5rbm93blxuKTogaWRlbnRpdHkgaXMgUmVjb3JkSWRlbnRpdHkge1xuICBjb25zdCB7IGlkLCB0eXBlIH0gPSBpZGVudGl0eSBhcyBSZWNvcmRJZGVudGl0eTtcbiAgcmV0dXJuIHR5cGVvZiBpZCA9PT0gJ3N0cmluZycgJiYgdHlwZW9mIHR5cGUgPT09ICdzdHJpbmcnO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc2VyaWFsaXplUmVjb3JkSWRlbnRpdHkocmVjb3JkOiBSZWNvcmRJZGVudGl0eSk6IHN0cmluZyB7XG4gIHJldHVybiBgJHtyZWNvcmQudHlwZX06JHtyZWNvcmQuaWR9YDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGRlc2VyaWFsaXplUmVjb3JkSWRlbnRpdHkoaWRlbnRpdHk6IHN0cmluZyk6IFJlY29yZElkZW50aXR5IHtcbiAgY29uc3QgW3R5cGUsIGlkXSA9IGlkZW50aXR5LnNwbGl0KCc6Jyk7XG4gIHJldHVybiB7IHR5cGUsIGlkIH07XG59XG5cbmZ1bmN0aW9uIHNlcmlhbGl6ZVJlY29yZElkZW50aXRpZXMoXG4gIHJlY29yZElkZW50aXRpZXM6IFJlY29yZElkZW50aXR5W11cbik6IHN0cmluZ1tdIHtcbiAgcmV0dXJuIHJlY29yZElkZW50aXRpZXMubWFwKChyKSA9PiBzZXJpYWxpemVSZWNvcmRJZGVudGl0eShyKSk7XG59XG5cbmZ1bmN0aW9uIGV4Y2x1c2l2ZUlkZW50aXRpZXMoXG4gIGlkZW50aXRpZXMxOiBzdHJpbmdbXSxcbiAgaWRlbnRpdGllczI6IHN0cmluZ1tdXG4pOiBzdHJpbmdbXSB7XG4gIHJldHVybiBpZGVudGl0aWVzMS5maWx0ZXIoKGkpID0+ICFpZGVudGl0aWVzMi5pbmNsdWRlcyhpKSk7XG59XG4iXX0=