matrix-react-sdk
Version:
SDK for matrix.org using React
133 lines (123 loc) • 19.1 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.useUnreadThreadRooms = useUnreadThreadRooms;
var _react = require("react");
var _matrix = require("matrix-js-sdk/src/matrix");
var _lodash = require("lodash");
var _Unread = require("../../../../Unread");
var _NotificationLevel = require("../../../../stores/notifications/NotificationLevel");
var _notifications = require("../../../../utils/notifications");
var _useSettings = require("../../../../hooks/useSettings");
var _MatrixClientContext = require("../../../../contexts/MatrixClientContext");
var _useEventEmitter = require("../../../../hooks/useEventEmitter");
var _VisibilityProvider = require("../../../../stores/room-list/filters/VisibilityProvider");
/*
* Copyright 2024 New Vector Ltd.
* Copyright 2024 The Matrix.org Foundation C.I.C.
*
* SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
* Please see LICENSE files in the repository root for full details.
*/
const MIN_UPDATE_INTERVAL_MS = 500;
/**
* Return the greatest notification level of all thread, the list of rooms with unread threads, and their notification level.
* The result is computed when the client syncs, or when forceComputation is true
* @param forceComputation
* @returns {Result}
*/
function useUnreadThreadRooms(forceComputation) {
const msc3946ProcessDynamicPredecessor = (0, _useSettings.useSettingValue)("feature_dynamic_room_predecessors");
const settingTACOnlyNotifs = (0, _useSettings.useSettingValue)("Notifications.tac_only_notifications");
const mxClient = (0, _MatrixClientContext.useMatrixClientContext)();
const [result, setResult] = (0, _react.useState)({
greatestNotificationLevel: _NotificationLevel.NotificationLevel.None,
rooms: []
});
const doUpdate = (0, _react.useCallback)(() => {
setResult(computeUnreadThreadRooms(mxClient, msc3946ProcessDynamicPredecessor, settingTACOnlyNotifs));
}, [mxClient, msc3946ProcessDynamicPredecessor, settingTACOnlyNotifs]);
// The exhautive deps lint rule can't compute dependencies here since it's not a plain inline func.
// We make this as simple as possible so its only dep is doUpdate itself.
// eslint-disable-next-line react-hooks/exhaustive-deps
const scheduleUpdate = (0, _react.useCallback)((0, _lodash.throttle)(doUpdate, MIN_UPDATE_INTERVAL_MS, {
leading: false,
trailing: true
}), [doUpdate]);
// Listen to sync events to update the result
(0, _useEventEmitter.useEventEmitter)(mxClient, _matrix.ClientEvent.Sync, scheduleUpdate);
// and also when events get decrypted, since this will often happen after the sync
// event and may change notifications.
(0, _useEventEmitter.useEventEmitter)(mxClient, _matrix.MatrixEventEvent.Decrypted, scheduleUpdate);
// Force the list computation
(0, _react.useEffect)(() => {
if (forceComputation) {
doUpdate();
}
}, [doUpdate, forceComputation]);
return result;
}
/**
* Compute the greatest notification level of all thread, the list of rooms with unread threads, and their notification level.
* @param mxClient - MatrixClient
* @param msc3946ProcessDynamicPredecessor
*/
function computeUnreadThreadRooms(mxClient, msc3946ProcessDynamicPredecessor, settingTACOnlyNotifs) {
// Only count visible rooms to not torment the user with notification counts in rooms they can't see.
// This will include highlights from the previous version of the room internally
const visibleRooms = mxClient.getVisibleRooms(msc3946ProcessDynamicPredecessor);
let greatestNotificationLevel = _NotificationLevel.NotificationLevel.None;
const rooms = [];
for (const room of visibleRooms) {
// We only care about rooms with unread threads
if (_VisibilityProvider.VisibilityProvider.instance.isRoomVisible(room) && (0, _Unread.doesRoomHaveUnreadThreads)(room)) {
// Get the greatest notification level of all threads
const notificationLevel = (0, _notifications.getThreadNotificationLevel)(room);
// If the room has an activity notification or less, we ignore it
if (settingTACOnlyNotifs && notificationLevel <= _NotificationLevel.NotificationLevel.Activity) {
continue;
}
if (notificationLevel > greatestNotificationLevel) {
greatestNotificationLevel = notificationLevel;
}
rooms.push({
room,
notificationLevel
});
}
}
const sortedRooms = rooms.sort((a, b) => sortRoom(a, b));
return {
greatestNotificationLevel,
rooms: sortedRooms
};
}
/**
* Store the room and its thread notification level
*/
/**
* Sort notification level by the most important notification level to the least important
* Highlight > Notification > Activity
* If the notification level is the same, we sort by the most recent thread
* @param roomDataA - room and notification level of room A
* @param roomDataB - room and notification level of room B
* @returns {number}
*/
function sortRoom(roomDataA, roomDataB) {
const {
notificationLevel: notificationLevelA,
room: roomA
} = roomDataA;
const {
notificationLevel: notificationLevelB,
room: roomB
} = roomDataB;
const timestampA = roomA.getLastThread()?.events.at(-1)?.getTs();
const timestampB = roomB.getLastThread()?.events.at(-1)?.getTs();
// NotificationLevel is a numeric enum, so we can compare them directly
if (notificationLevelA > notificationLevelB) return -1;else if (notificationLevelB > notificationLevelA) return 1;
// Display most recent first
else if (!timestampA) return 1;else if (!timestampB) return -1;else return timestampB - timestampA;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJyZXF1aXJlIiwiX21hdHJpeCIsIl9sb2Rhc2giLCJfVW5yZWFkIiwiX05vdGlmaWNhdGlvbkxldmVsIiwiX25vdGlmaWNhdGlvbnMiLCJfdXNlU2V0dGluZ3MiLCJfTWF0cml4Q2xpZW50Q29udGV4dCIsIl91c2VFdmVudEVtaXR0ZXIiLCJfVmlzaWJpbGl0eVByb3ZpZGVyIiwiTUlOX1VQREFURV9JTlRFUlZBTF9NUyIsInVzZVVucmVhZFRocmVhZFJvb21zIiwiZm9yY2VDb21wdXRhdGlvbiIsIm1zYzM5NDZQcm9jZXNzRHluYW1pY1ByZWRlY2Vzc29yIiwidXNlU2V0dGluZ1ZhbHVlIiwic2V0dGluZ1RBQ09ubHlOb3RpZnMiLCJteENsaWVudCIsInVzZU1hdHJpeENsaWVudENvbnRleHQiLCJyZXN1bHQiLCJzZXRSZXN1bHQiLCJ1c2VTdGF0ZSIsImdyZWF0ZXN0Tm90aWZpY2F0aW9uTGV2ZWwiLCJOb3RpZmljYXRpb25MZXZlbCIsIk5vbmUiLCJyb29tcyIsImRvVXBkYXRlIiwidXNlQ2FsbGJhY2siLCJjb21wdXRlVW5yZWFkVGhyZWFkUm9vbXMiLCJzY2hlZHVsZVVwZGF0ZSIsInRocm90dGxlIiwibGVhZGluZyIsInRyYWlsaW5nIiwidXNlRXZlbnRFbWl0dGVyIiwiQ2xpZW50RXZlbnQiLCJTeW5jIiwiTWF0cml4RXZlbnRFdmVudCIsIkRlY3J5cHRlZCIsInVzZUVmZmVjdCIsInZpc2libGVSb29tcyIsImdldFZpc2libGVSb29tcyIsInJvb20iLCJWaXNpYmlsaXR5UHJvdmlkZXIiLCJpbnN0YW5jZSIsImlzUm9vbVZpc2libGUiLCJkb2VzUm9vbUhhdmVVbnJlYWRUaHJlYWRzIiwibm90aWZpY2F0aW9uTGV2ZWwiLCJnZXRUaHJlYWROb3RpZmljYXRpb25MZXZlbCIsIkFjdGl2aXR5IiwicHVzaCIsInNvcnRlZFJvb21zIiwic29ydCIsImEiLCJiIiwic29ydFJvb20iLCJyb29tRGF0YUEiLCJyb29tRGF0YUIiLCJub3RpZmljYXRpb25MZXZlbEEiLCJyb29tQSIsIm5vdGlmaWNhdGlvbkxldmVsQiIsInJvb21CIiwidGltZXN0YW1wQSIsImdldExhc3RUaHJlYWQiLCJldmVudHMiLCJhdCIsImdldFRzIiwidGltZXN0YW1wQiJdLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9jb21wb25lbnRzL3ZpZXdzL3NwYWNlcy90aHJlYWRzLWFjdGl2aXR5LWNlbnRyZS91c2VVbnJlYWRUaHJlYWRSb29tcy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IDIwMjQgTmV3IFZlY3RvciBMdGQuXG4gKiBDb3B5cmlnaHQgMjAyNCBUaGUgTWF0cml4Lm9yZyBGb3VuZGF0aW9uIEMuSS5DLlxuICpcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBR1BMLTMuMC1vbmx5IE9SIEdQTC0zLjAtb25seVxuICogUGxlYXNlIHNlZSBMSUNFTlNFIGZpbGVzIGluIHRoZSByZXBvc2l0b3J5IHJvb3QgZm9yIGZ1bGwgZGV0YWlscy5cbiAqL1xuXG5pbXBvcnQgeyB1c2VDYWxsYmFjaywgdXNlRWZmZWN0LCB1c2VTdGF0ZSB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgQ2xpZW50RXZlbnQsIE1hdHJpeENsaWVudCwgTWF0cml4RXZlbnRFdmVudCwgUm9vbSB9IGZyb20gXCJtYXRyaXgtanMtc2RrL3NyYy9tYXRyaXhcIjtcbmltcG9ydCB7IHRocm90dGxlIH0gZnJvbSBcImxvZGFzaFwiO1xuXG5pbXBvcnQgeyBkb2VzUm9vbUhhdmVVbnJlYWRUaHJlYWRzIH0gZnJvbSBcIi4uLy4uLy4uLy4uL1VucmVhZFwiO1xuaW1wb3J0IHsgTm90aWZpY2F0aW9uTGV2ZWwgfSBmcm9tIFwiLi4vLi4vLi4vLi4vc3RvcmVzL25vdGlmaWNhdGlvbnMvTm90aWZpY2F0aW9uTGV2ZWxcIjtcbmltcG9ydCB7IGdldFRocmVhZE5vdGlmaWNhdGlvbkxldmVsIH0gZnJvbSBcIi4uLy4uLy4uLy4uL3V0aWxzL25vdGlmaWNhdGlvbnNcIjtcbmltcG9ydCB7IHVzZVNldHRpbmdWYWx1ZSB9IGZyb20gXCIuLi8uLi8uLi8uLi9ob29rcy91c2VTZXR0aW5nc1wiO1xuaW1wb3J0IHsgdXNlTWF0cml4Q2xpZW50Q29udGV4dCB9IGZyb20gXCIuLi8uLi8uLi8uLi9jb250ZXh0cy9NYXRyaXhDbGllbnRDb250ZXh0XCI7XG5pbXBvcnQgeyB1c2VFdmVudEVtaXR0ZXIgfSBmcm9tIFwiLi4vLi4vLi4vLi4vaG9va3MvdXNlRXZlbnRFbWl0dGVyXCI7XG5pbXBvcnQgeyBWaXNpYmlsaXR5UHJvdmlkZXIgfSBmcm9tIFwiLi4vLi4vLi4vLi4vc3RvcmVzL3Jvb20tbGlzdC9maWx0ZXJzL1Zpc2liaWxpdHlQcm92aWRlclwiO1xuXG5jb25zdCBNSU5fVVBEQVRFX0lOVEVSVkFMX01TID0gNTAwO1xuXG50eXBlIFJlc3VsdCA9IHtcbiAgICBncmVhdGVzdE5vdGlmaWNhdGlvbkxldmVsOiBOb3RpZmljYXRpb25MZXZlbDtcbiAgICByb29tczogQXJyYXk8eyByb29tOiBSb29tOyBub3RpZmljYXRpb25MZXZlbDogTm90aWZpY2F0aW9uTGV2ZWwgfT47XG59O1xuXG4vKipcbiAqIFJldHVybiB0aGUgZ3JlYXRlc3Qgbm90aWZpY2F0aW9uIGxldmVsIG9mIGFsbCB0aHJlYWQsIHRoZSBsaXN0IG9mIHJvb21zIHdpdGggdW5yZWFkIHRocmVhZHMsIGFuZCB0aGVpciBub3RpZmljYXRpb24gbGV2ZWwuXG4gKiBUaGUgcmVzdWx0IGlzIGNvbXB1dGVkIHdoZW4gdGhlIGNsaWVudCBzeW5jcywgb3Igd2hlbiBmb3JjZUNvbXB1dGF0aW9uIGlzIHRydWVcbiAqIEBwYXJhbSBmb3JjZUNvbXB1dGF0aW9uXG4gKiBAcmV0dXJucyB7UmVzdWx0fVxuICovXG5leHBvcnQgZnVuY3Rpb24gdXNlVW5yZWFkVGhyZWFkUm9vbXMoZm9yY2VDb21wdXRhdGlvbjogYm9vbGVhbik6IFJlc3VsdCB7XG4gICAgY29uc3QgbXNjMzk0NlByb2Nlc3NEeW5hbWljUHJlZGVjZXNzb3IgPSB1c2VTZXR0aW5nVmFsdWU8Ym9vbGVhbj4oXCJmZWF0dXJlX2R5bmFtaWNfcm9vbV9wcmVkZWNlc3NvcnNcIik7XG4gICAgY29uc3Qgc2V0dGluZ1RBQ09ubHlOb3RpZnMgPSB1c2VTZXR0aW5nVmFsdWU8Ym9vbGVhbj4oXCJOb3RpZmljYXRpb25zLnRhY19vbmx5X25vdGlmaWNhdGlvbnNcIik7XG4gICAgY29uc3QgbXhDbGllbnQgPSB1c2VNYXRyaXhDbGllbnRDb250ZXh0KCk7XG5cbiAgICBjb25zdCBbcmVzdWx0LCBzZXRSZXN1bHRdID0gdXNlU3RhdGU8UmVzdWx0Pih7IGdyZWF0ZXN0Tm90aWZpY2F0aW9uTGV2ZWw6IE5vdGlmaWNhdGlvbkxldmVsLk5vbmUsIHJvb21zOiBbXSB9KTtcblxuICAgIGNvbnN0IGRvVXBkYXRlID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgICAgICBzZXRSZXN1bHQoY29tcHV0ZVVucmVhZFRocmVhZFJvb21zKG14Q2xpZW50LCBtc2MzOTQ2UHJvY2Vzc0R5bmFtaWNQcmVkZWNlc3Nvciwgc2V0dGluZ1RBQ09ubHlOb3RpZnMpKTtcbiAgICB9LCBbbXhDbGllbnQsIG1zYzM5NDZQcm9jZXNzRHluYW1pY1ByZWRlY2Vzc29yLCBzZXR0aW5nVEFDT25seU5vdGlmc10pO1xuXG4gICAgLy8gVGhlIGV4aGF1dGl2ZSBkZXBzIGxpbnQgcnVsZSBjYW4ndCBjb21wdXRlIGRlcGVuZGVuY2llcyBoZXJlIHNpbmNlIGl0J3Mgbm90IGEgcGxhaW4gaW5saW5lIGZ1bmMuXG4gICAgLy8gV2UgbWFrZSB0aGlzIGFzIHNpbXBsZSBhcyBwb3NzaWJsZSBzbyBpdHMgb25seSBkZXAgaXMgZG9VcGRhdGUgaXRzZWxmLlxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1ob29rcy9leGhhdXN0aXZlLWRlcHNcbiAgICBjb25zdCBzY2hlZHVsZVVwZGF0ZSA9IHVzZUNhbGxiYWNrKFxuICAgICAgICB0aHJvdHRsZShkb1VwZGF0ZSwgTUlOX1VQREFURV9JTlRFUlZBTF9NUywge1xuICAgICAgICAgICAgbGVhZGluZzogZmFsc2UsXG4gICAgICAgICAgICB0cmFpbGluZzogdHJ1ZSxcbiAgICAgICAgfSksXG4gICAgICAgIFtkb1VwZGF0ZV0sXG4gICAgKTtcblxuICAgIC8vIExpc3RlbiB0byBzeW5jIGV2ZW50cyB0byB1cGRhdGUgdGhlIHJlc3VsdFxuICAgIHVzZUV2ZW50RW1pdHRlcihteENsaWVudCwgQ2xpZW50RXZlbnQuU3luYywgc2NoZWR1bGVVcGRhdGUpO1xuICAgIC8vIGFuZCBhbHNvIHdoZW4gZXZlbnRzIGdldCBkZWNyeXB0ZWQsIHNpbmNlIHRoaXMgd2lsbCBvZnRlbiBoYXBwZW4gYWZ0ZXIgdGhlIHN5bmNcbiAgICAvLyBldmVudCBhbmQgbWF5IGNoYW5nZSBub3RpZmljYXRpb25zLlxuICAgIHVzZUV2ZW50RW1pdHRlcihteENsaWVudCwgTWF0cml4RXZlbnRFdmVudC5EZWNyeXB0ZWQsIHNjaGVkdWxlVXBkYXRlKTtcblxuICAgIC8vIEZvcmNlIHRoZSBsaXN0IGNvbXB1dGF0aW9uXG4gICAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICAgICAgaWYgKGZvcmNlQ29tcHV0YXRpb24pIHtcbiAgICAgICAgICAgIGRvVXBkYXRlKCk7XG4gICAgICAgIH1cbiAgICB9LCBbZG9VcGRhdGUsIGZvcmNlQ29tcHV0YXRpb25dKTtcblxuICAgIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogQ29tcHV0ZSB0aGUgZ3JlYXRlc3Qgbm90aWZpY2F0aW9uIGxldmVsIG9mIGFsbCB0aHJlYWQsIHRoZSBsaXN0IG9mIHJvb21zIHdpdGggdW5yZWFkIHRocmVhZHMsIGFuZCB0aGVpciBub3RpZmljYXRpb24gbGV2ZWwuXG4gKiBAcGFyYW0gbXhDbGllbnQgLSBNYXRyaXhDbGllbnRcbiAqIEBwYXJhbSBtc2MzOTQ2UHJvY2Vzc0R5bmFtaWNQcmVkZWNlc3NvclxuICovXG5mdW5jdGlvbiBjb21wdXRlVW5yZWFkVGhyZWFkUm9vbXMoXG4gICAgbXhDbGllbnQ6IE1hdHJpeENsaWVudCxcbiAgICBtc2MzOTQ2UHJvY2Vzc0R5bmFtaWNQcmVkZWNlc3NvcjogYm9vbGVhbixcbiAgICBzZXR0aW5nVEFDT25seU5vdGlmczogYm9vbGVhbixcbik6IFJlc3VsdCB7XG4gICAgLy8gT25seSBjb3VudCB2aXNpYmxlIHJvb21zIHRvIG5vdCB0b3JtZW50IHRoZSB1c2VyIHdpdGggbm90aWZpY2F0aW9uIGNvdW50cyBpbiByb29tcyB0aGV5IGNhbid0IHNlZS5cbiAgICAvLyBUaGlzIHdpbGwgaW5jbHVkZSBoaWdobGlnaHRzIGZyb20gdGhlIHByZXZpb3VzIHZlcnNpb24gb2YgdGhlIHJvb20gaW50ZXJuYWxseVxuICAgIGNvbnN0IHZpc2libGVSb29tcyA9IG14Q2xpZW50LmdldFZpc2libGVSb29tcyhtc2MzOTQ2UHJvY2Vzc0R5bmFtaWNQcmVkZWNlc3Nvcik7XG5cbiAgICBsZXQgZ3JlYXRlc3ROb3RpZmljYXRpb25MZXZlbCA9IE5vdGlmaWNhdGlvbkxldmVsLk5vbmU7XG4gICAgY29uc3Qgcm9vbXM6IFJlc3VsdFtcInJvb21zXCJdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IHJvb20gb2YgdmlzaWJsZVJvb21zKSB7XG4gICAgICAgIC8vIFdlIG9ubHkgY2FyZSBhYm91dCByb29tcyB3aXRoIHVucmVhZCB0aHJlYWRzXG4gICAgICAgIGlmIChWaXNpYmlsaXR5UHJvdmlkZXIuaW5zdGFuY2UuaXNSb29tVmlzaWJsZShyb29tKSAmJiBkb2VzUm9vbUhhdmVVbnJlYWRUaHJlYWRzKHJvb20pKSB7XG4gICAgICAgICAgICAvLyBHZXQgdGhlIGdyZWF0ZXN0IG5vdGlmaWNhdGlvbiBsZXZlbCBvZiBhbGwgdGhyZWFkc1xuICAgICAgICAgICAgY29uc3Qgbm90aWZpY2F0aW9uTGV2ZWwgPSBnZXRUaHJlYWROb3RpZmljYXRpb25MZXZlbChyb29tKTtcblxuICAgICAgICAgICAgLy8gSWYgdGhlIHJvb20gaGFzIGFuIGFjdGl2aXR5IG5vdGlmaWNhdGlvbiBvciBsZXNzLCB3ZSBpZ25vcmUgaXRcbiAgICAgICAgICAgIGlmIChzZXR0aW5nVEFDT25seU5vdGlmcyAmJiBub3RpZmljYXRpb25MZXZlbCA8PSBOb3RpZmljYXRpb25MZXZlbC5BY3Rpdml0eSkge1xuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAobm90aWZpY2F0aW9uTGV2ZWwgPiBncmVhdGVzdE5vdGlmaWNhdGlvbkxldmVsKSB7XG4gICAgICAgICAgICAgICAgZ3JlYXRlc3ROb3RpZmljYXRpb25MZXZlbCA9IG5vdGlmaWNhdGlvbkxldmVsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByb29tcy5wdXNoKHsgcm9vbSwgbm90aWZpY2F0aW9uTGV2ZWwgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBzb3J0ZWRSb29tcyA9IHJvb21zLnNvcnQoKGEsIGIpID0+IHNvcnRSb29tKGEsIGIpKTtcbiAgICByZXR1cm4geyBncmVhdGVzdE5vdGlmaWNhdGlvbkxldmVsLCByb29tczogc29ydGVkUm9vbXMgfTtcbn1cblxuLyoqXG4gKiBTdG9yZSB0aGUgcm9vbSBhbmQgaXRzIHRocmVhZCBub3RpZmljYXRpb24gbGV2ZWxcbiAqL1xudHlwZSBSb29tRGF0YSA9IFJlc3VsdFtcInJvb21zXCJdWzBdO1xuXG4vKipcbiAqIFNvcnQgbm90aWZpY2F0aW9uIGxldmVsIGJ5IHRoZSBtb3N0IGltcG9ydGFudCBub3RpZmljYXRpb24gbGV2ZWwgdG8gdGhlIGxlYXN0IGltcG9ydGFudFxuICogSGlnaGxpZ2h0ID4gTm90aWZpY2F0aW9uID4gQWN0aXZpdHlcbiAqIElmIHRoZSBub3RpZmljYXRpb24gbGV2ZWwgaXMgdGhlIHNhbWUsIHdlIHNvcnQgYnkgdGhlIG1vc3QgcmVjZW50IHRocmVhZFxuICogQHBhcmFtIHJvb21EYXRhQSAtIHJvb20gYW5kIG5vdGlmaWNhdGlvbiBsZXZlbCBvZiByb29tIEFcbiAqIEBwYXJhbSByb29tRGF0YUIgLSByb29tIGFuZCBub3RpZmljYXRpb24gbGV2ZWwgb2Ygcm9vbSBCXG4gKiBAcmV0dXJucyB7bnVtYmVyfVxuICovXG5mdW5jdGlvbiBzb3J0Um9vbShyb29tRGF0YUE6IFJvb21EYXRhLCByb29tRGF0YUI6IFJvb21EYXRhKTogbnVtYmVyIHtcbiAgICBjb25zdCB7IG5vdGlmaWNhdGlvbkxldmVsOiBub3RpZmljYXRpb25MZXZlbEEsIHJvb206IHJvb21BIH0gPSByb29tRGF0YUE7XG4gICAgY29uc3QgeyBub3RpZmljYXRpb25MZXZlbDogbm90aWZpY2F0aW9uTGV2ZWxCLCByb29tOiByb29tQiB9ID0gcm9vbURhdGFCO1xuXG4gICAgY29uc3QgdGltZXN0YW1wQSA9IHJvb21BLmdldExhc3RUaHJlYWQoKT8uZXZlbnRzLmF0KC0xKT8uZ2V0VHMoKTtcbiAgICBjb25zdCB0aW1lc3RhbXBCID0gcm9vbUIuZ2V0TGFzdFRocmVhZCgpPy5ldmVudHMuYXQoLTEpPy5nZXRUcygpO1xuXG4gICAgLy8gTm90aWZpY2F0aW9uTGV2ZWwgaXMgYSBudW1lcmljIGVudW0sIHNvIHdlIGNhbiBjb21wYXJlIHRoZW0gZGlyZWN0bHlcbiAgICBpZiAobm90aWZpY2F0aW9uTGV2ZWxBID4gbm90aWZpY2F0aW9uTGV2ZWxCKSByZXR1cm4gLTE7XG4gICAgZWxzZSBpZiAobm90aWZpY2F0aW9uTGV2ZWxCID4gbm90aWZpY2F0aW9uTGV2ZWxBKSByZXR1cm4gMTtcbiAgICAvLyBEaXNwbGF5IG1vc3QgcmVjZW50IGZpcnN0XG4gICAgZWxzZSBpZiAoIXRpbWVzdGFtcEEpIHJldHVybiAxO1xuICAgIGVsc2UgaWYgKCF0aW1lc3RhbXBCKSByZXR1cm4gLTE7XG4gICAgZWxzZSByZXR1cm4gdGltZXN0YW1wQiAtIHRpbWVzdGFtcEE7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7OztBQVFBLElBQUFBLE1BQUEsR0FBQUMsT0FBQTtBQUNBLElBQUFDLE9BQUEsR0FBQUQsT0FBQTtBQUNBLElBQUFFLE9BQUEs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