UNPKG

webglimpse

Version:

Webglimpse is a data visualization library for the web.

401 lines 60.9 kB
/* * Copyright (c) 2014, Metron, Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its contributors * may be used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ import { OrderedSet } from '../util/ordered_set'; import { TimelineEventStyleUi } from './timeline_event_style'; import { TimelineAnnotationStyleUi } from './timeline_annotation_style'; import { SimpleModel, XyModel } from '../misc'; import { GL, hasval, getObjectId } from '../util/util'; import { Texture2D } from '../texture'; import { Notification, Notification1, Notification2 } from '../util/notification'; import { isLeftMouseDown } from '../core'; export class TimelineUi { constructor(model, options = {}) { this._dispose = new Notification(); this._input = new TimelineInput(); const getPaneId = function (pane) { const paneId = pane['webglimpse_PaneId']; return hasval(paneId) ? paneId : getObjectId(pane); }; this._panes = new OrderedSet([], getPaneId); this._selection = new TimelineSelectionModel(); attachTimelineInputToSelection(this._input, this._selection, options); this._groupUis = new OrderedSet([], (g) => g.groupGuid); const groupUis = this._groupUis; const addGroupUi = function (group) { groupUis.add(new TimelineGroupUi(group.groupGuid)); }; const removeGroupUi = function (group) { groupUis.removeId(group.groupGuid); }; model.groups.forEach(addGroupUi); model.groups.valueAdded.on(addGroupUi); model.groups.valueRemoved.on(removeGroupUi); this._rowUis = new OrderedSet([], (r) => r.rowGuid); const rowUis = this._rowUis; const addRowUi = function (row) { rowUis.add(new TimelineRowUi(row.rowGuid)); }; const removeRowUi = function (row) { rowUis.removeId(row.rowGuid); }; model.rows.forEach(addRowUi); model.rows.valueAdded.on(addRowUi); model.rows.valueRemoved.on(removeRowUi); this._eventStyles = new OrderedSet([], (s) => s.styleGuid); this._annotationStyles = new OrderedSet([], (s) => s.styleGuid); this._millisPerPx = new SimpleModel(1000); this._imageStatus = {}; this._imageCache = {}; this._dispose.on(function () { model.groups.valueAdded.off(addGroupUi); model.groups.valueRemoved.off(removeGroupUi); model.rows.valueAdded.off(addRowUi); model.rows.valueRemoved.off(removeRowUi); }); } get input() { return this._input; } get selection() { return this._selection; } get groupUis() { return this._groupUis; } groupUi(groupGuid) { return this._groupUis.valueFor(groupGuid); } get rowUis() { return this._rowUis; } rowUi(rowGuid) { return this._rowUis.valueFor(rowGuid); } get eventStyles() { return this._eventStyles; } eventStyle(styleGuid) { return ((hasval(styleGuid) && this._eventStyles.valueFor(styleGuid)) || timelineEventStyle_DEFAULT); } get annotationStyles() { return this._annotationStyles; } annotationStyle(styleGuid) { return ((hasval(styleGuid) && this._annotationStyles.valueFor(styleGuid)) || timelineAnnotationStyle_DEFAULT); } get millisPerPx() { return this._millisPerPx; } loadImage(url, onLoaded) { if (!hasval(this._imageStatus[url])) { this._imageStatus[url] = true; const imageCache = this._imageCache; const image = new Image(); image.onload = function () { const w = image.naturalWidth; const h = image.naturalHeight; imageCache[url] = new Texture2D(w, h, GL.LINEAR, GL.LINEAR, function (g) { g.drawImage(image, 0, 0); }); if (onLoaded) { onLoaded(); } }; image.src = url; } return this._imageCache[url]; } get panes() { return this._panes; } addPane(paneId, pane) { pane['webglimpse_PaneId'] = paneId; this._panes.removeId(paneId); this._panes.add(pane); } removePane(paneId) { this._panes.removeId(paneId); } getPane(paneId) { return this._panes.valueFor(paneId); } get dispose() { return this._dispose; } } export class TimelineGroupUi { constructor(groupGuid) { this._groupGuid = groupGuid; } get groupGuid() { return this._groupGuid; } } export class TimelineRowUi { constructor(rowGuid) { this._rowGuid = rowGuid; this._paneFactoryChanged = new Notification(); this._paneFactory = null; const getPaneId = function (pane) { const paneId = pane['webglimpse_PaneId']; return hasval(paneId) ? paneId : getObjectId(pane); }; this._panes = new OrderedSet([], getPaneId); } get rowGuid() { return this._rowGuid; } get paneFactoryChanged() { return this._paneFactoryChanged; } get paneFactory() { return this._paneFactory; } set paneFactory(paneFactory) { if (paneFactory !== this._paneFactory) { this._paneFactory = paneFactory; this._paneFactoryChanged.fire(); } } get panes() { return this._panes; } addPane(paneId, pane) { pane['webglimpse_PaneId'] = paneId; this._panes.removeId(paneId); this._panes.add(pane); } removePane(paneId) { this._panes.removeId(paneId); } getPane(paneId) { return this._panes.valueFor(paneId); } } const timelineAnnotationStyle_DEFAULT = new TimelineAnnotationStyleUi({ styleGuid: 'DEFAULT', color: 'white', icons: [] }); const timelineEventStyle_DEFAULT = new TimelineEventStyleUi({ styleGuid: 'DEFAULT', icons: [] }); export class TimelineInput { constructor() { this._mouseMove = new Notification1(); this._mouseExit = new Notification1(); this._timeHover = new Notification2(); this._rowHover = new Notification2(); this._eventHover = new Notification2(); this._mouseDown = new Notification1(); this._mouseUp = new Notification1(); this._contextMenu = new Notification1(); } get mouseMove() { return this._mouseMove; } get mouseExit() { return this._mouseExit; } get timeHover() { return this._timeHover; } get rowHover() { return this._rowHover; } get eventHover() { return this._eventHover; } get mouseDown() { return this._mouseDown; } get mouseUp() { return this._mouseUp; } get contextMenu() { return this._contextMenu; } } export class TimelineSelectionModel { constructor() { this._mousePos = new XyModel(); this._hoveredY = new SimpleModel(); this._hoveredTime_PMILLIS = new SimpleModel(); this._selectedInterval = new TimeIntervalModel(0, 0); this._hoveredRow = new SimpleModel(); this._hoveredEvent = new SimpleModel(); this._selectedEvents = new OrderedSet([], (e) => e.eventGuid); this._hoveredTimeseries = new TimelineTimeseriesFragmentSelectionModel(); this._hoveredAnnotation = new SimpleModel(); } get mousePos() { return this._mousePos; } get hoveredY() { return this._hoveredY; } get hoveredTime_PMILLIS() { return this._hoveredTime_PMILLIS; } get selectedInterval() { return this._selectedInterval; } get hoveredRow() { return this._hoveredRow; } get hoveredEvent() { return this._hoveredEvent; } get selectedEvents() { return this._selectedEvents; } get hoveredTimeseries() { return this._hoveredTimeseries; } get hoveredAnnotation() { return this._hoveredAnnotation; } } export class TimelineTimeseriesFragmentSelectionModel { constructor(fragment = null, index = -1) { this._fragment = fragment; this._index = index; this._changed = new Notification(); } setValue(fragment, index) { if (fragment !== this._fragment || index !== this._index) { this._fragment = fragment; this._index = index; this._changed.fire(); } } clearValue() { this.setValue(null, -1); } get fragment() { return this._fragment; } get index() { return this._index; } get changed() { return this._changed; } get times_PMILLIS() { if (this._fragment) { return this._fragment.times_PMILLIS[this._index]; } else { return undefined; } } get data() { if (this._fragment) { return this._fragment.data[this._index]; } else { return undefined; } } } export class TimeIntervalModel { constructor(start_PMILLIS, end_PMILLIS, cursor_PMILLIS) { this._start_PMILLIS = start_PMILLIS; this._end_PMILLIS = end_PMILLIS; this._cursor_PMILLIS = cursor_PMILLIS ? cursor_PMILLIS : end_PMILLIS; this._changed = new Notification(); } get start_PMILLIS() { return this._start_PMILLIS; } get end_PMILLIS() { return this._end_PMILLIS; } get cursor_PMILLIS() { return this._cursor_PMILLIS; } get duration_MILLIS() { return this._end_PMILLIS - this._start_PMILLIS; } get changed() { return this._changed; } set start_PMILLIS(start_PMILLIS) { if (start_PMILLIS !== this._start_PMILLIS) { this._start_PMILLIS = start_PMILLIS; this._changed.fire(); } } set end_PMILLIS(end_PMILLIS) { if (end_PMILLIS !== this._end_PMILLIS) { this._end_PMILLIS = end_PMILLIS; this._changed.fire(); } } set cursor_PMILLIS(cursor_PMILLIS) { if (cursor_PMILLIS !== this._cursor_PMILLIS) { this._cursor_PMILLIS = cursor_PMILLIS; this._changed.fire(); } } setInterval(start_PMILLIS, end_PMILLIS, cursor_PMILLIS) { if (start_PMILLIS !== this._start_PMILLIS || end_PMILLIS !== this._end_PMILLIS || (cursor_PMILLIS && cursor_PMILLIS !== this._cursor_PMILLIS)) { this._start_PMILLIS = start_PMILLIS; this._end_PMILLIS = end_PMILLIS; this._cursor_PMILLIS = cursor_PMILLIS ? cursor_PMILLIS : end_PMILLIS; this._changed.fire(); } } overlaps(start_PMILLIS, end_PMILLIS) { return (this._start_PMILLIS <= end_PMILLIS && start_PMILLIS <= this._end_PMILLIS); } contains(time_PMILLIS) { return (this._start_PMILLIS <= time_PMILLIS && time_PMILLIS <= this._end_PMILLIS); } pan(amount_MILLIS) { if (amount_MILLIS !== 0) { this._start_PMILLIS += amount_MILLIS; this._end_PMILLIS += amount_MILLIS; this._cursor_PMILLIS += amount_MILLIS; this._changed.fire(); } } scale(factor, anchor_PMILLIS) { if (anchor_PMILLIS !== 1) { this._start_PMILLIS = anchor_PMILLIS + factor * (this._start_PMILLIS - anchor_PMILLIS); this._end_PMILLIS = anchor_PMILLIS + factor * (this._end_PMILLIS - anchor_PMILLIS); this._cursor_PMILLIS = anchor_PMILLIS + factor * (this._cursor_PMILLIS - anchor_PMILLIS); this._changed.fire(); } } } function attachTimelineInputToSelection(input, selection, options) { const allowEventMultiSelection = (hasval(options) && hasval(options.allowEventMultiSelection) ? options.allowEventMultiSelection : true); // Mouse-pos & Time // input.mouseMove.on(function (ev) { selection.mousePos.setXy(ev.i, ev.j); }); input.mouseExit.on(function (ev) { selection.mousePos.setXy(null, null); }); input.rowHover.on(function (row, ev) { selection.hoveredRow.value = row; }); input.timeHover.on(function (time_PMILLIS, ev) { selection.hoveredTime_PMILLIS.value = time_PMILLIS; }); // Events // input.eventHover.on(function (event) { selection.hoveredEvent.value = event; }); if (options.allowEventMultiSelection) { input.mouseDown.on(function (ev) { if (isLeftMouseDown(ev.mouseEvent)) { const event = selection.hoveredEvent.value; if (hasval(event)) { const multiSelectMode = (ev.mouseEvent && (ev.mouseEvent.ctrlKey || ev.mouseEvent.shiftKey)); const unselectedEventClicked = !selection.selectedEvents.hasValue(event); if (multiSelectMode) { if (selection.selectedEvents.hasValue(event)) { selection.selectedEvents.removeValue(event); } else { selection.selectedEvents.add(event); } } else if (unselectedEventClicked) { selection.selectedEvents.retainValues([event]); selection.selectedEvents.add(event); } else { // if a selected event is clicked, do nothing (the user is probably initiating a drag) // if they wish to deselect the event, they need to ctrl+click the event or click on // a deselected event } } } }); } else { input.mouseDown.on(function (ev) { if (isLeftMouseDown(ev.mouseEvent)) { const event = selection.hoveredEvent.value; if (hasval(event)) { selection.selectedEvents.retainValues([event]); selection.selectedEvents.add(event); } } }); } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZWxpbmVfdWkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvd2ViZ2xpbXBzZS90aW1lbGluZS90aW1lbGluZV91aS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTRCRztBQUNILE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNqRCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUM5RCxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUN4RSxPQUFPLEVBQUUsV0FBVyxFQUFFLE9BQU8sRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUMvQyxPQUFPLEVBQWEsRUFBRSxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDbEUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUN2QyxPQUFPLEVBQUUsWUFBWSxFQUFFLGFBQWEsRUFBRSxhQUFhLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRixPQUFPLEVBQXNCLGVBQWUsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQVE5RCxNQUFNLE9BQU8sVUFBVTtJQWtCbkIsWUFBWSxLQUFvQixFQUFFLFVBQTZCLEVBQUU7UUFDN0QsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ25DLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxhQUFhLEVBQUUsQ0FBQztRQUVsQyxNQUFNLFNBQVMsR0FBRyxVQUFVLElBQVU7WUFDbEMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLENBQUM7WUFDekMsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3ZELENBQUMsQ0FB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KSAyMDE0LCBNZXRyb24sIEluYy5cclxuICogQWxsIHJpZ2h0cyByZXNlcnZlZC5cclxuICpcclxuICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbixcclxuICogYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxyXG4gKlxyXG4gKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcclxuICogICAgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuXHJcbiAqXHJcbiAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcclxuICogICAgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUgZG9jdW1lbnRhdGlvblxyXG4gKiAgICBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi5cclxuICpcclxuICogMy4gTmVpdGhlciB0aGUgbmFtZSBvZiB0aGUgY29weXJpZ2h0IGhvbGRlciBub3IgdGhlIG5hbWVzIG9mIGl0cyBjb250cmlidXRvcnNcclxuICogICAgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXRcclxuICogICAgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxyXG4gKlxyXG4gKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIiBBTkRcclxuICogQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRURcclxuICogV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRVxyXG4gKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQ09QWVJJR0hUIEhPTERFUiBPUiBDT05UUklCVVRPUlMgQkUgTElBQkxFIEZPUlxyXG4gKiBBTlkgRElSRUNULCBJTkRJUkVDVCwgSU5DSURFTlRBTCwgU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVNcclxuICogKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTO1xyXG4gKiBMT1NTIE9GIFVTRSwgREFUQSwgT1IgUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT05cclxuICogQU5ZIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlRcclxuICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVNcclxuICogU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXHJcbiAqL1xyXG5pbXBvcnQgeyBPcmRlcmVkU2V0IH0gZnJvbSAnLi4vdXRpbC9vcmRlcmVkX3NldCc7XHJcbmltcG9ydCB7IFRpbWVsaW5lRXZlbnRTdHlsZVVpIH0gZnJvbSAnLi90aW1lbGluZV9ldmVudF9zdHlsZSc7XHJcbmltcG9ydCB7IFRpbWVsaW5lQW5ub3RhdGlvblN0eWxlVWkgfSBmcm9tICcuL3RpbWVsaW5lX2Fubm90YXRpb25fc3R5bGUnO1xyXG5pbXBvcnQgeyBTaW1wbGVNb2RlbCwgWHlNb2RlbCB9IGZyb20gJy4uL21pc2MnO1xyXG5pbXBvcnQgeyBTdHJpbmdNYXAsIEdMLCBoYXN2YWwsIGdldE9iamVjdElkIH0gZnJvbSAnLi4vdXRpbC91dGlsJztcclxuaW1wb3J0IHsgVGV4dHVyZTJEIH0gZnJvbSAnLi4vdGV4dHVyZSc7XHJcbmltcG9ydCB7IE5vdGlmaWNhdGlvbiwgTm90aWZpY2F0aW9uMSwgTm90aWZpY2F0aW9uMiB9IGZyb20gJy4uL3V0aWwvbm90aWZpY2F0aW9uJztcclxuaW1wb3J0IHsgUGFuZSwgUG9pbnRlckV2ZW50LCBpc0xlZnRNb3VzZURvd24gfSBmcm9tICcuLi9jb3JlJztcclxuaW1wb3J0IHsgVGltZWxpbmVNb2RlbCwgVGltZWxpbmVHcm91cE1vZGVsLCBUaW1lbGluZVJvd01vZGVsLCBUaW1lbGluZUV2ZW50TW9kZWwsIFRpbWVsaW5lQW5ub3RhdGlvbk1vZGVsLCBUaW1lbGluZVRpbWVzZXJpZXNGcmFnbWVudE1vZGVsIH0gZnJvbSAnLi90aW1lbGluZV9tb2RlbCc7XHJcbmltcG9ydCB7IFRpbWVsaW5lUm93UGFuZUZhY3RvcnkgfSBmcm9tICcuL3RpbWVsaW5lX3Jvdyc7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFRpbWVsaW5lVWlPcHRpb25zIHtcclxuICAgIGFsbG93RXZlbnRNdWx0aVNlbGVjdGlvbj86IGJvb2xlYW47XHJcbn1cclxuXHJcbmV4cG9ydCBjbGFzcyBUaW1lbGluZVVpIHtcclxuICAgIHByaXZhdGUgX2lucHV0OiBUaW1lbGluZUlucHV0O1xyXG4gICAgcHJpdmF0ZSBfc2VsZWN0aW9uOiBUaW1lbGluZVNlbGVjdGlvbk1vZGVsO1xyXG5cclxuICAgIHByaXZhdGUgX2dyb3VwVWlzOiBPcmRlcmVkU2V0PFRpbWVsaW5lR3JvdXBVaT47XHJcbiAgICBwcml2YXRlIF9yb3dVaXM6IE9yZGVyZWRTZXQ8VGltZWxpbmVSb3dVaT47XHJcbiAgICBwcml2YXRlIF9ldmVudFN0eWxlczogT3JkZXJlZFNldDxUaW1lbGluZUV2ZW50U3R5bGVVaT47XHJcbiAgICBwcml2YXRlIF9hbm5vdGF0aW9uU3R5bGVzOiBPcmRlcmVkU2V0PFRpbWVsaW5lQW5ub3RhdGlvblN0eWxlVWk+O1xyXG5cclxuICAgIHByaXZhdGUgX21pbGxpc1BlclB4OiBTaW1wbGVNb2RlbDxudW1iZXI+O1xyXG5cclxuICAgIHByaXZhdGUgX2ltYWdlU3RhdHVzOiBTdHJpbmdNYXA8Ym9vbGVhbj47XHJcbiAgICBwcml2YXRlIF9pbWFnZUNhY2hlOiBTdHJpbmdNYXA8VGV4dHVyZTJEPjtcclxuXHJcbiAgICBwcml2YXRlIF9kaXNwb3NlOiBOb3RpZmljYXRpb247XHJcblxyXG4gICAgcHJpdmF0ZSBfcGFuZXM6IE9yZGVyZWRTZXQ8UGFuZT47XHJcblxyXG4gICAgY29uc3RydWN0b3IobW9kZWw6IFRpbWVsaW5lTW9kZWwsIG9wdGlvbnM6IFRpbWVsaW5lVWlPcHRpb25zID0ge30pIHtcclxuICAgICAgICB0aGlzLl9kaXNwb3NlID0gbmV3IE5vdGlmaWNhdGlvbigpO1xyXG4gICAgICAgIHRoaXMuX2lucHV0ID0gbmV3IFRpbWVsaW5lSW5wdXQoKTtcclxuXHJcbiAgICAgICAgY29uc3QgZ2V0UGFuZUlkID0gZnVuY3Rpb24gKHBhbmU6IFBhbmUpOiBzdHJpbmcge1xyXG4gICAgICAgICAgICBjb25zdCBwYW5lSWQgPSBwYW5lWyd3ZWJnbGltcHNlX1BhbmVJZCddO1xyXG4gICAgICAgICAgICByZXR1cm4gaGFzdmFsKHBhbmVJZCkgPyBwYW5lSWQgOiBnZXRPYmplY3RJZChwYW5lKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICB0aGlzLl9wYW5lcyA9IG5ldyBPcmRlcmVkU2V0PFBhbmU+KFtdLCBnZXRQYW5lSWQpO1xyXG5cclxuICAgICAgICB0aGlzLl9zZWxlY3Rpb24gPSBuZXcgVGltZWxpbmVTZWxlY3Rpb25Nb2RlbCgpO1xyXG4gICAgICAgIGF0dGFjaFRpbWVsaW5lSW5wdXRUb1NlbGVjdGlvbih0aGlzLl9pbnB1dCwgdGhpcy5fc2VsZWN0aW9uLCBvcHRpb25zKTtcclxuXHJcbiAgICAgICAgdGhpcy5fZ3JvdXBVaXMgPSBuZXcgT3JkZXJlZFNldDxUaW1lbGluZUdyb3VwVWk+KFtdLCAoZykgPT4gZy5ncm91cEd1aWQpO1xyXG4gICAgICAgIGNvbnN0IGdyb3VwVWlzID0gdGhpcy5fZ3JvdXBVaXM7XHJcbiAgICAgICAgY29uc3QgYWRkR3JvdXBVaSA9IGZ1bmN0aW9uIChncm91cDogVGltZWxpbmVHcm91cE1vZGVsKSB7IGdyb3VwVWlzLmFkZChuZXcgVGltZWxpbmVHcm91cFVpKGdyb3VwLmdyb3VwR3VpZCkpOyB9O1xyXG4gICAgICAgIGNvbnN0IHJlbW92ZUdyb3VwVWkgPSBmdW5jdGlvbiAoZ3JvdXA6IFRpbWVsaW5lR3JvdXBNb2RlbCkgeyBncm91cFVpcy5yZW1vdmVJZChncm91cC5ncm91cEd1aWQpOyB9O1xyXG4gICAgICAgIG1vZGVsLmdyb3Vwcy5mb3JFYWNoKGFkZEdyb3VwVWkpO1xyXG4gICAgICAgIG1vZGVsLmdyb3Vwcy52YWx1ZUFkZGVkLm9uKGFkZEdyb3VwVWkpO1xyXG4gICAgICAgIG1vZGVsLmdyb3Vwcy52YWx1ZVJlbW92ZWQub24ocmVtb3ZlR3JvdXBVaSk7XHJcblxyXG4gICAgICAgIHRoaXMuX3Jvd1VpcyA9IG5ldyBPcmRlcmVkU2V0PFRpbWVsaW5lUm93VWk+KFtdLCAocikgPT4gci5yb3dHdWlkKTtcclxuICAgICAgICBjb25zdCByb3dVaXMgPSB0aGlzLl9yb3dVaXM7XHJcbiAgICAgICAgY29uc3QgYWRkUm93VWkgPSBmdW5jdGlvbiAocm93OiBUaW1lbGluZVJvd01vZGVsKSB7IHJvd1Vpcy5hZGQobmV3IFRpbWVsaW5lUm93VWkocm93LnJvd0d1aWQpKTsgfTtcclxuICAgICAgICBjb25zdCByZW1vdmVSb3dVaSA9IGZ1bmN0aW9uIChyb3c6IFRpbWVsaW5lUm93TW9kZWwpIHsgcm93VWlzLnJlbW92ZUlkKHJvdy5yb3dHdWlkKTsgfTtcclxuICAgICAgICBtb2RlbC5yb3dzLmZvckVhY2goYWRkUm93VWkpO1xyXG4gICAgICAgIG1vZGVsLnJvd3MudmFsdWVBZGRlZC5vbihhZGRSb3dVaSk7XHJcbiAgICAgICAgbW9kZWwucm93cy52YWx1ZVJlbW92ZWQub24ocmVtb3ZlUm93VWkpO1xyXG5cclxuICAgICAgICB0aGlzLl9ldmVudFN0eWxlcyA9IG5ldyBPcmRlcmVkU2V0PFRpbWVsaW5lRXZlbnRTdHlsZVVpPihbXSwgKHMpID0+IHMuc3R5bGVHdWlkKTtcclxuICAgICAgICB0aGlzLl9hbm5vdGF0aW9uU3R5bGVzID0gbmV3IE9yZGVyZWRTZXQ8VGltZWxpbmVBbm5vdGF0aW9uU3R5bGVVaT4oW10sIChzKSA9PiBzLnN0eWxlR3VpZCk7XHJcblxyXG4gICAgICAgIHRoaXMuX21pbGxpc1BlclB4ID0gbmV3IFNpbXBsZU1vZGVsPG51bWJlcj4oMTAwMCk7XHJcblxyXG4gICAgICAgIHRoaXMuX2ltYWdlU3RhdHVzID0ge307XHJcbiAgICAgICAgdGhpcy5faW1hZ2VDYWNoZSA9IHt9O1xyXG5cclxuICAgICAgICB0aGlzLl9kaXNwb3NlLm9uKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgbW9kZWwuZ3JvdXBzLnZhbHVlQWRkZWQub2ZmKGFkZEdyb3VwVWkpO1xyXG4gICAgICAgICAgICBtb2RlbC5ncm91cHMudmFsdWVSZW1vdmVkLm9mZihyZW1vdmVHcm91cFVpKTtcclxuICAgICAgICAgICAgbW9kZWwucm93cy52YWx1ZUFkZGVkLm9mZihhZGRSb3dVaSk7XHJcbiAgICAgICAgICAgIG1vZGVsLnJvd3MudmFsdWVSZW1vdmVkLm9mZihyZW1vdmVSb3dVaSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IGlucHV0KCk6IFRpbWVsaW5lSW5wdXQge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9pbnB1dDtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgc2VsZWN0aW9uKCk6IFRpbWVsaW5lU2VsZWN0aW9uTW9kZWwge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zZWxlY3Rpb247XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IGdyb3VwVWlzKCk6IE9yZGVyZWRTZXQ8VGltZWxpbmVHcm91cFVpPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dyb3VwVWlzO1xyXG4gICAgfVxyXG5cclxuICAgIGdyb3VwVWkoZ3JvdXBHdWlkOiBzdHJpbmcpOiBUaW1lbGluZUdyb3VwVWkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9ncm91cFVpcy52YWx1ZUZvcihncm91cEd1aWQpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCByb3dVaXMoKTogT3JkZXJlZFNldDxUaW1lbGluZVJvd1VpPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Jvd1VpcztcclxuICAgIH1cclxuXHJcbiAgICByb3dVaShyb3dHdWlkOiBzdHJpbmcpOiBUaW1lbGluZVJvd1VpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcm93VWlzLnZhbHVlRm9yKHJvd0d1aWQpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBldmVudFN0eWxlcygpOiBPcmRlcmVkU2V0PFRpbWVsaW5lRXZlbnRTdHlsZVVpPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2V2ZW50U3R5bGVzO1xyXG4gICAgfVxyXG5cclxuICAgIGV2ZW50U3R5bGUoc3R5bGVHdWlkOiBzdHJpbmcpOiBUaW1lbGluZUV2ZW50U3R5bGVVaSB7XHJcbiAgICAgICAgcmV0dXJuICgoaGFzdmFsKHN0eWxlR3VpZCkgJiYgdGhpcy5fZXZlbnRTdHlsZXMudmFsdWVGb3Ioc3R5bGVHdWlkKSkgfHwgdGltZWxpbmVFdmVudFN0eWxlX0RFRkFVTFQpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBhbm5vdGF0aW9uU3R5bGVzKCk6IE9yZGVyZWRTZXQ8VGltZWxpbmVBbm5vdGF0aW9uU3R5bGVVaT4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9hbm5vdGF0aW9uU3R5bGVzO1xyXG4gICAgfVxyXG5cclxuICAgIGFubm90YXRpb25TdHlsZShzdHlsZUd1aWQ6IHN0cmluZyk6IFRpbWVsaW5lQW5ub3RhdGlvblN0eWxlVWkge1xyXG4gICAgICAgIHJldHVybiAoKGhhc3ZhbChzdHlsZUd1aWQpICYmIHRoaXMuX2Fubm90YXRpb25TdHlsZXMudmFsdWVGb3Ioc3R5bGVHdWlkKSkgfHwgdGltZWxpbmVBbm5vdGF0aW9uU3R5bGVfREVGQVVMVCk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IG1pbGxpc1BlclB4KCk6IFNpbXBsZU1vZGVsPG51bWJlcj4ge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9taWxsaXNQZXJQeDtcclxuICAgIH1cclxuXHJcbiAgICBsb2FkSW1hZ2UodXJsOiBzdHJpbmcsIG9uTG9hZGVkOiAoKSA9PiB2b2lkKTogVGV4dHVyZTJEIHtcclxuICAgICAgICBpZiAoIWhhc3ZhbCh0aGlzLl9pbWFnZVN0YXR1c1t1cmxdKSkge1xyXG4gICAgICAgICAgICB0aGlzLl9pbWFnZVN0YXR1c1t1cmxdID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGltYWdlQ2FjaGUgPSB0aGlzLl9pbWFnZUNhY2hlO1xyXG4gICAgICAgICAgICBjb25zdCBpbWFnZSA9IG5ldyBJbWFnZSgpO1xyXG4gICAgICAgICAgICBpbWFnZS5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCB3ID0gaW1hZ2UubmF0dXJhbFdpZHRoO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaCA9IGltYWdlLm5hdHVyYWxIZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICBpbWFnZUNhY2hlW3VybF0gPSBuZXcgVGV4dHVyZTJEKHcsIGgsIEdMLkxJTkVBUiwgR0wuTElORUFSLCBmdW5jdGlvbiAoZykgeyBnLmRyYXdJbWFnZShpbWFnZSwgMCwgMCk7IH0pO1xyXG4gICAgICAgICAgICAgICAgaWYgKG9uTG9hZGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb25Mb2FkZWQoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgaW1hZ2Uuc3JjID0gdXJsO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGhpcy5faW1hZ2VDYWNoZVt1cmxdO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBwYW5lcygpOiBPcmRlcmVkU2V0PFBhbmU+IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcGFuZXM7XHJcbiAgICB9XHJcblxyXG4gICAgYWRkUGFuZShwYW5lSWQ6IHN0cmluZywgcGFuZTogUGFuZSkge1xyXG4gICAgICAgIHBhbmVbJ3dlYmdsaW1wc2VfUGFuZUlkJ10gPSBwYW5lSWQ7XHJcbiAgICAgICAgdGhpcy5fcGFuZXMucmVtb3ZlSWQocGFuZUlkKTtcclxuICAgICAgICB0aGlzLl9wYW5lcy5hZGQocGFuZSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmVtb3ZlUGFuZShwYW5lSWQ6IHN0cmluZykge1xyXG4gICAgICAgIHRoaXMuX3BhbmVzLnJlbW92ZUlkKHBhbmVJZCk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0UGFuZShwYW5lSWQ6IHN0cmluZyk6IFBhbmUge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9wYW5lcy52YWx1ZUZvcihwYW5lSWQpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBkaXNwb3NlKCkgeyByZXR1cm4gdGhpcy5fZGlzcG9zZTsgfVxyXG59XHJcblxyXG5cclxuXHJcbmV4cG9ydCBjbGFzcyBUaW1lbGluZUdyb3VwVWkge1xyXG4gICAgcHJpdmF0ZSBfZ3JvdXBHdWlkOiBzdHJpbmc7XHJcblxyXG4gICAgY29uc3RydWN0b3IoZ3JvdXBHdWlkOiBzdHJpbmcpIHtcclxuICAgICAgICB0aGlzLl9ncm91cEd1aWQgPSBncm91cEd1aWQ7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IGdyb3VwR3VpZCgpOiBzdHJpbmcge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9ncm91cEd1aWQ7XHJcbiAgICB9XHJcbn1cclxuXHJcblxyXG5cclxuZXhwb3J0IGNsYXNzIFRpbWVsaW5lUm93VWkge1xyXG4gICAgcHJpdmF0ZSBfcm93R3VpZDogc3RyaW5nO1xyXG4gICAgcHJpdmF0ZSBfcGFuZUZhY3RvcnlDaGFuZ2VkOiBOb3RpZmljYXRpb247XHJcbiAgICBwcml2YXRlIF9wYW5lRmFjdG9yeTogVGltZWxpbmVSb3dQYW5lRmFjdG9yeTtcclxuICAgIHByaXZhdGUgX3BhbmVzOiBPcmRlcmVkU2V0PFBhbmU+O1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKHJvd0d1aWQ6IHN0cmluZykge1xyXG4gICAgICAgIHRoaXMuX3Jvd0d1aWQgPSByb3dHdWlkO1xyXG4gICAgICAgIHRoaXMuX3BhbmVGYWN0b3J5Q2hhbmdlZCA9IG5ldyBOb3RpZmljYXRpb24oKTtcclxuICAgICAgICB0aGlzLl9wYW5lRmFjdG9yeSA9IG51bGw7XHJcblxyXG4gICAgICAgIGNvbnN0IGdldFBhbmVJZCA9IGZ1bmN0aW9uIChwYW5lOiBQYW5lKTogc3RyaW5nIHtcclxuICAgICAgICAgICAgY29uc3QgcGFuZUlkID0gcGFuZVsnd2ViZ2xpbXBzZV9QYW5lSWQnXTtcclxuICAgICAgICAgICAgcmV0dXJuIGhhc3ZhbChwYW5lSWQpID8gcGFuZUlkIDogZ2V0T2JqZWN0SWQocGFuZSk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgdGhpcy5fcGFuZXMgPSBuZXcgT3JkZXJlZFNldDxQYW5lPihbXSwgZ2V0UGFuZUlkKTtcclxuICAgIH1cclxuXHJcbiAgICBnZXQgcm93R3VpZCgpOiBzdHJpbmcge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9yb3dHdWlkO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBwYW5lRmFjdG9yeUNoYW5nZWQoKTogTm90aWZpY2F0aW9uIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcGFuZUZhY3RvcnlDaGFuZ2VkO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBwYW5lRmFjdG9yeSgpOiBUaW1lbGluZVJvd1BhbmVGYWN0b3J5IHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcGFuZUZhY3Rvcnk7XHJcbiAgICB9XHJcblxyXG4gICAgc2V0IHBhbmVGYWN0b3J5KHBhbmVGYWN0b3J5OiBUaW1lbGluZVJvd1BhbmVGYWN0b3J5KSB7XHJcbiAgICAgICAgaWYgKHBhbmVGYWN0b3J5ICE9PSB0aGlzLl9wYW5lRmFjdG9yeSkge1xyXG4gICAgICAgICAgICB0aGlzLl9wYW5lRmFjdG9yeSA9IHBhbmVGYWN0b3J5O1xyXG4gICAgICAgICAgICB0aGlzLl9wYW5lRmFjdG9yeUNoYW5nZWQuZmlyZSgpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBnZXQgcGFuZXMoKTogT3JkZXJlZFNldDxQYW5lPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX3BhbmVzO1xyXG4gICAgfVxyXG5cclxuICAgIGFkZFBhbmUocGFuZUlkOiBzdHJpbmcsIHBhbmU6IFBhbmUpIHtcclxuICAgICAgICBwYW5lWyd3ZWJnbGltcHNlX1BhbmVJZCddID0gcGFuZUlkO1xyXG4gICAgICAgIHRoaXMuX3BhbmVzLnJlbW92ZUlkKHBhbmVJZCk7XHJcbiAgICAgICAgdGhpcy5fcGFuZXMuYWRkKHBhbmUpO1xyXG4gICAgfVxyXG5cclxuICAgIHJlbW92ZVBhbmUocGFuZUlkOiBzdHJpbmcpIHtcclxuICAgICAgICB0aGlzLl9wYW5lcy5yZW1vdmVJZChwYW5lSWQpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldFBhbmUocGFuZUlkOiBzdHJpbmcpOiBQYW5lIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fcGFuZXMudmFsdWVGb3IocGFuZUlkKTtcclxuICAgIH1cclxufVxyXG5cclxuXHJcbmNvbnN0IHRpbWVsaW5lQW5ub3RhdGlvblN0eWxlX0RFRkFVTFQgPSBuZXcgVGltZWxpbmVBbm5vdGF0aW9uU3R5bGVVaSh7XHJcbiAgICBzdHlsZUd1aWQ6ICdERUZBVUxUJyxcclxuICAgIGNvbG9yOiAnd2hpdGUnLFxyXG4gICAgaWNvbnM6IFtdXHJcbn0pO1xyXG5cclxuXHJcbmNvbnN0IHRpbWVsaW5lRXZlbnRTdHlsZV9ERUZBVUxUID0gbmV3IFRpbWVsaW5lRXZlbnRTdHlsZVVpKHtcclxuICAgIHN0eWxlR3VpZDogJ0RFRkFVTFQnLFxyXG4gICAgaWNvbnM6IFtdXHJcbn0pO1xyXG5cclxuXHJcblxyXG5leHBvcnQgY2xhc3MgVGltZWxpbmVJbnB1dCB7XHJcbiAgICBwcml2YXRlIF9tb3VzZU1vdmUgPSBuZXcgTm90aWZpY2F0aW9uMTxQb2ludGVyRXZlbnQ+KCk7XHJcbiAgICBwcml2YXRlIF9tb3VzZUV4aXQgPSBuZXcgTm90aWZpY2F0aW9uMTxQb2ludGVyRXZlbnQ+KCk7XHJcbiAgICBwcml2YXRlIF90aW1lSG92ZXIgPSBuZXcgTm90aWZpY2F0aW9uMjxudW1iZXIsIFBvaW50ZXJFdmVudD4oKTtcclxuICAgIHByaXZhdGUgX3Jvd0hvdmVyID0gbmV3IE5vdGlmaWNhdGlvbjI8VGltZWxpbmVSb3dNb2RlbCwgUG9pbnRlckV2ZW50PigpO1xyXG4gICAgcHJpdmF0ZSBfZXZlbnRIb3ZlciA9IG5ldyBOb3RpZmljYXRpb24yPFRpbWVsaW5lRXZlbnRNb2RlbCwgUG9pbnRlckV2ZW50PigpO1xyXG4gICAgcHJpdmF0ZSBfbW91c2VEb3duID0gbmV3IE5vdGlmaWNhdGlvbjE8UG9pbnRlckV2ZW50PigpO1xyXG4gICAgcHJpdmF0ZSBfbW91c2VVcCA9IG5ldyBOb3RpZmljYXRpb24xPFBvaW50ZXJFdmVudD4oKTtcclxuICAgIHByaXZhdGUgX2NvbnRleHRNZW51ID0gbmV3IE5vdGlmaWNhdGlvbjE8UG9pbnRlckV2ZW50PigpO1xyXG5cclxuICAgIGdldCBtb3VzZU1vdmUoKTogTm90aWZpY2F0aW9uMTxQb2ludGVyRXZlbnQ+IHsgcmV0dXJuIHRoaXMuX21vdXNlTW92ZTsgfVxyXG4gICAgZ2V0IG1vdXNlRXhpdCgpOiBOb3RpZmljYXRpb24xPFBvaW50ZXJFdmVudD4geyByZXR1cm4gdGhpcy5fbW91c2VFeGl0OyB9XHJcbiAgICBnZXQgdGltZUhvdmVyKCk6IE5vdGlmaWNhdGlvbjI8bnVtYmVyLCBQb2ludGVyRXZlbnQ+IHsgcmV0dXJuIHRoaXMuX3RpbWVIb3ZlcjsgfVxyXG4gICAgZ2V0IHJvd0hvdmVyKCk6IE5vdGlmaWNhdGlvbjI8VGltZWxpbmVSb3dNb2RlbCwgUG9pbnRlckV2ZW50PiB7IHJldHVybiB0aGlzLl9yb3dIb3ZlcjsgfVxyXG4gICAgZ2V0IGV2ZW50SG92ZXIoKTogTm90aWZpY2F0aW9uMjxUaW1lbGluZUV2ZW50TW9kZWwsIFBvaW50ZXJFdmVudD4geyByZXR1cm4gdGhpcy5fZXZlbnRIb3ZlcjsgfVxyXG4gICAgZ2V0IG1vdXNlRG93bigpOiBOb3RpZmljYXRpb24xPFBvaW50ZXJFdmVudD4geyByZXR1cm4gdGhpcy5fbW91c2VEb3duOyB9XHJcbiAgICBnZXQgbW91c2VVcCgpOiBOb3RpZmljYXRpb24xPFBvaW50ZXJFdmVudD4geyByZXR1cm4gdGhpcy5fbW91c2VVcDsgfVxyXG4gICAgZ2V0IGNvbnRleHRNZW51KCk6IE5vdGlmaWNhdGlvbjE8UG9pbnRlckV2ZW50PiB7IHJldHVybiB0aGlzLl9jb250ZXh0TWVudTsgfVxyXG59XHJcblxyXG5cclxuXHJcbmV4cG9ydCBjbGFzcyBUaW1lbGluZVNlbGVjdGlvbk1vZGVsIHtcclxuICAgIHByaXZhdGUgX21vdXNlUG9zID0gbmV3IFh5TW9kZWwoKTtcclxuXHJcbiAgICBwcml2YXRlIF9ob3ZlcmVkWSA9IG5ldyBTaW1wbGVNb2RlbDxudW1iZXI+KCk7XHJcbiAgICBwcml2YXRlIF9ob3ZlcmVkVGltZV9QTUlMTElTID0gbmV3IFNpbXBsZU1vZGVsPG51bWJlcj4oKTtcclxuICAgIHByaXZhdGUgX3NlbGVjdGVkSW50ZXJ2YWwgPSBuZXcgVGltZUludGVydmFsTW9kZWwoMCwgMCk7XHJcblxyXG4gICAgcHJpdmF0ZSBfaG92ZXJlZFJvdyA9IG5ldyBTaW1wbGVNb2RlbDxUaW1lbGluZVJvd01vZGVsPigpO1xyXG5cclxuICAgIHByaXZhdGUgX2hvdmVyZWRFdmVudCA9IG5ldyBTaW1wbGVNb2RlbDxUaW1lbGluZUV2ZW50TW9kZWw+KCk7XHJcbiAgICBwcml2YXRlIF9zZWxlY3RlZEV2ZW50cyA9IG5ldyBPcmRlcmVkU2V0PFRpbWVsaW5lRXZlbnRNb2RlbD4oW10sIChlKSA9PiBlLmV2ZW50R3VpZCk7XHJcblxyXG4gICAgcHJpdmF0ZSBfaG92ZXJlZFRpbWVzZXJpZXMgPSBuZXcgVGltZWxpbmVUaW1lc2VyaWVzRnJhZ21lbnRTZWxlY3Rpb25Nb2RlbCgpO1xyXG5cclxuICAgIHByaXZhdGUgX2hvdmVyZWRBbm5vdGF0aW9uID0gbmV3IFNpbXBsZU1vZGVsPFRpbWVsaW5lQW5ub3RhdGlvbk1vZGVsPigpO1xyXG5cclxuICAgIGdldCBtb3VzZVBvcygpOiBYeU1vZGVsIHsgcmV0dXJuIHRoaXMuX21vdXNlUG9zOyB9XHJcblxyXG4gICAgZ2V0IGhvdmVyZWRZKCk6IFNpbXBsZU1vZGVsPG51