angular-bootstrap-datetimepicker
Version:
Native Angular (8+) datetime picker component styled by Twitter Bootstrap 4.
243 lines • 29.9 kB
JavaScript
/**
* @license
* Copyright 2013-present Dale Lotts All Rights Reserved.
* http://www.dalelotts.com
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/dalelotts/angular-bootstrap-datetimepicker/blob/master/LICENSE
*/
import * as _moment from 'moment';
/**
* Work around for moment namespace conflict when used with webpack and rollup.
* See https://github.com/dherges/ng-packagr/issues/163
*
* Depending on whether rollup is used, moment needs to be imported differently.
* Since Moment.js doesn't have a default export, we normally need to import using
* the `* as`syntax.
*
* rollup creates a synthetic default module and we thus need to import it using
* the `default as` syntax.
*
* @internal
**/
const moment = _moment;
/**
* Default implementation for the `month` view.
*/
export class DlMonthModelProvider {
/**
* Receives input changes detected by Angular.
*
* @param changes
* the input changes detected by Angular.
*/
onChanges(
// @ts-ignore
changes) { }
/**
* Returns the `month` model for the specified moment in `local` time with the
* `active` month set to the first day of the specified month.
*
* The `month` model represents a year (12 months) as three rows with four columns.
*
* The year always starts in January.
*
* Each cell represents midnight on the 1st day of the month.
*
* The `active` month will be the January of year of the specified milliseconds.
*
* @param milliseconds
* the moment in time from which the month model will be created.
* @param selectedMilliseconds
* the current value of the date/time picker.
* @returns
* the model representing the specified moment in time.
*/
getModel(milliseconds, selectedMilliseconds) {
const startDate = moment(milliseconds).startOf('year');
const rowNumbers = [0, 1, 2];
const columnNumbers = [0, 1, 2, 3];
const previousYear = moment(startDate).subtract(1, 'year');
const nextYear = moment(startDate).add(1, 'year');
const activeValue = moment(milliseconds).startOf('month').valueOf();
const selectedValue = selectedMilliseconds === null || selectedMilliseconds === undefined
? selectedMilliseconds
: moment(selectedMilliseconds).startOf('month').valueOf();
return {
viewName: 'month',
viewLabel: startDate.format('YYYY'),
activeDate: activeValue,
leftButton: {
value: previousYear.valueOf(),
ariaLabel: `Go to ${previousYear.format('YYYY')}`,
classes: {},
},
upButton: {
value: startDate.valueOf(),
ariaLabel: `Go to ${startDate.format('YYYY')}`,
classes: {},
},
rightButton: {
value: nextYear.valueOf(),
ariaLabel: `Go to ${nextYear.format('YYYY')}`,
classes: {},
},
rows: rowNumbers.map(rowOfMonths)
};
function rowOfMonths(rowNumber) {
const currentMoment = moment();
const cells = columnNumbers.map((columnNumber) => {
const monthMoment = moment(startDate).add((rowNumber * columnNumbers.length) + columnNumber, 'months');
return {
display: monthMoment.format('MMM'),
ariaLabel: monthMoment.format('MMM YYYY'),
value: monthMoment.valueOf(),
classes: {
'dl-abdtp-active': activeValue === monthMoment.valueOf(),
'dl-abdtp-selected': selectedValue === monthMoment.valueOf(),
'dl-abdtp-now': monthMoment.isSame(currentMoment, 'month'),
}
};
});
return { cells };
}
}
/**
* Move the active `month` one row `down` from the specified moment in time.
*
* Moving `down` can result in the `active` month being part of a different year than
* the specified `fromMilliseconds`, in this case the year represented by the model
* will change to show the correct year.
*
* @param fromMilliseconds
* the moment in time from which the next `month` model `down` will be constructed.
* @param selectedMilliseconds
* the current value of the date/time picker.
* @returns
* model containing an `active` `month` one row `down` from the specified moment in time.
*/
goDown(fromMilliseconds, selectedMilliseconds) {
return this.getModel(moment(fromMilliseconds).add(4, 'month').valueOf(), selectedMilliseconds);
}
/**
* Move the active `month` one row `up` from the specified moment in time.
*
* Moving `up` can result in the `active` month being part of a different year than
* the specified `fromMilliseconds`, in this case the year represented by the model
* will change to show the correct year.
*
* @param fromMilliseconds
* the moment in time from which the previous `month` model `up` will be constructed.
* @param selectedMilliseconds
* the current value of the date/time picker.
* @returns
* model containing an `active` `month` one row `up` from the specified moment in time.
*/
goUp(fromMilliseconds, selectedMilliseconds) {
return this.getModel(moment(fromMilliseconds).subtract(4, 'month').valueOf(), selectedMilliseconds);
}
/**
* Move the `active` `month` one (1) month to the `left` of the specified moment in time.
*
* Moving `left` can result in the `active` month being part of a different year than
* the specified `fromMilliseconds`, in this case the year represented by the model
* will change to show the correct year.
*
* @param fromMilliseconds
* the moment in time from which the `month` model to the `left` will be constructed.
* @param selectedMilliseconds
* the current value of the date/time picker.
* @returns
* model containing an `active` `month` one month to the `left` of the specified moment in time.
*/
goLeft(fromMilliseconds, selectedMilliseconds) {
return this.getModel(moment(fromMilliseconds).subtract(1, 'month').valueOf(), selectedMilliseconds);
}
/**
* Move the `active` `month` one (1) month to the `right` of the specified moment in time.
*
* The `active` month will be `one (1) month after` the specified milliseconds.
* This moves the `active` date one month `right` in the current `month` view.
*
* Moving `right` can result in the `active` month being part of a different year than
* the specified `fromMilliseconds`, in this case the year represented by the model
* will change to show the correct year.
*
* @param fromMilliseconds
* the moment in time from which the `month` model to the `right` will be constructed.
* @param selectedMilliseconds
* the current value of the date/time picker.
* @returns
* model containing an `active` `month` one year to the `right` of the specified moment in time.
*/
goRight(fromMilliseconds, selectedMilliseconds) {
return this.getModel(moment(fromMilliseconds).add(1, 'month').valueOf(), selectedMilliseconds);
}
/**
* Move the active `month` one year `down` from the specified moment in time.
*
* Paging `down` will result in the `active` month being part of a different year than
* the specified `fromMilliseconds`. As a result, the year represented by the model
* will change to show the correct year.
*
* @param fromMilliseconds
* the moment in time from which the next `month` model page `down` will be constructed.
* @param selectedMilliseconds
* the current value of the date/time picker.
* @returns
* model containing an `active` `month` one year `down` from the specified moment in time.
*/
pageDown(fromMilliseconds, selectedMilliseconds) {
return this.getModel(moment(fromMilliseconds).add(12, 'months').valueOf(), selectedMilliseconds);
}
/**
* Move the active `month` one year `down` from the specified moment in time.
*
* Paging `up` will result in the `active` month being part of a different year than
* the specified `fromMilliseconds`. As a result, the year represented by the model
* will change to show the correct year.
*
* @param fromMilliseconds
* the moment in time from which the next `month` model page `up` will be constructed.
* @param selectedMilliseconds
* the current value of the date/time picker.
* @returns
* model containing an `active` `month` one year `up` from the specified moment in time.
*/
pageUp(fromMilliseconds, selectedMilliseconds) {
return this.getModel(moment(fromMilliseconds).subtract(12, 'months').valueOf(), selectedMilliseconds);
}
/**
* Move the `active` `month` to `December` of the current year.
*
* The view or time range will not change unless the `fromMilliseconds` value
* is in a different year than the displayed decade.
*
* @param fromMilliseconds
* the moment in time from which `December 1` will be calculated.
* @param selectedMilliseconds
* the current value of the date/time picker.
* @returns
* a model with the `December` cell in the view as the active `month`.
*/
goEnd(fromMilliseconds, selectedMilliseconds) {
return this.getModel(moment(fromMilliseconds).endOf('year').valueOf(), selectedMilliseconds);
}
/**
* Move the `active` `month` to `January` of the current year.
*
* The view or time range will not change unless the `fromMilliseconds` value
* is in a different year than the displayed decade.
*
* @param fromMilliseconds
* the moment in time from which `January 1` will be calculated.
* @param selectedMilliseconds
* the current value of the date/time picker.
* @returns
* a model with the `January` cell in the view as the active `month`.
*/
goHome(fromMilliseconds, selectedMilliseconds) {
return this.getModel(moment(fromMilliseconds).startOf('year').valueOf(), selectedMilliseconds);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGwtbW9kZWwtcHJvdmlkZXItbW9udGguanMiLCJzb3VyY2VSb290Ijoibmc6Ly9hbmd1bGFyLWJvb3RzdHJhcC1kYXRldGltZXBpY2tlci8iLCJzb3VyY2VzIjpbImRsLWRhdGUtdGltZS1waWNrZXIvZGwtbW9kZWwtcHJvdmlkZXItbW9udGgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7R0FPRztBQUdILE9BQU8sS0FBSyxPQUFPLE1BQU0sUUFBUSxDQUFDO0FBSWxDOzs7Ozs7Ozs7Ozs7SUFZSTtBQUNKLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQztBQUV2Qjs7R0FFRztBQUNILE1BQU0sT0FBTyxvQkFBb0I7SUFFL0I7Ozs7O09BS0c7SUFDSCxTQUFTO0lBQ1AsYUFBYTtJQUNiLE9BQXNCLElBQ2YsQ0FBQztJQUVWOzs7Ozs7Ozs7Ozs7Ozs7Ozs7T0FrQkc7SUFDSCxRQUFRLENBQUMsWUFBb0IsRUFBRSxvQkFBNEI7UUFDekQsTUFBTSxTQUFTLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUV2RCxNQUFNLFVBQVUsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDN0IsTUFBTSxhQUFhLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUVuQyxNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUMzRCxNQUFNLFFBQVEsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNsRCxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3BFLE1BQU0sYUFBYSxHQUFHLG9CQUFvQixLQUFLLElBQUksSUFBSSxvQkFBb0IsS0FBSyxTQUFTO1lBQ3ZGLENBQUMsQ0FBQyxvQkFBb0I7WUFDdEIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUU1RCxPQUFPO1lBQ0wsUUFBUSxFQUFFLE9BQU87WUFDakIsU0FBUyxFQUFFLFNBQVMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDO1lBQ25DLFVBQVUsRUFBRSxXQUFXO1lBQ3ZCLFVBQVUsRUFBRTtnQkFDVixLQUFLLEVBQUUsWUFBWSxDQUFDLE9BQU8sRUFBRTtnQkFDN0IsU0FBUyxFQUFFLFNBQVMsWUFBWSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRTtnQkFDakQsT0FBTyxFQUFFLEVBQUU7YUFDWjtZQUNELFFBQVEsRUFBRTtnQkFDUixLQUFLLEVBQUUsU0FBUyxDQUFDLE9BQU8sRUFBRTtnQkFDMUIsU0FBUyxFQUFFLFNBQVMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRTtnQkFDOUMsT0FBTyxFQUFFLEVBQUU7YUFDWjtZQUNELFdBQVcsRUFBRTtnQkFDWCxLQUFLLEVBQUUsUUFBUSxDQUFDLE9BQU8sRUFBRTtnQkFDekIsU0FBUyxFQUFFLFNBQVMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRTtnQkFDN0MsT0FBTyxFQUFFLEVBQUU7YUFDWjtZQUNELElBQUksRUFBRSxVQUFVLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQztTQUNsQyxDQUFDO1FBRUYsU0FBUyxXQUFXLENBQUMsU0FBUztZQUU1QixNQUFNLGFBQWEsR0FBRyxNQUFNLEVBQUUsQ0FBQztZQUMvQixNQUFNLEtBQUssR0FBRyxhQUFhLENBQUMsR0FBRyxDQUFDLENBQUMsWUFBWSxFQUFFLEVBQUU7Z0JBQy9DLE1BQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxTQUFTLEdBQUcsYUFBYSxDQUFDLE1BQU0sQ0FBQyxHQUFHLFlBQVksRUFBRSxRQUFRLENBQUMsQ0FBQztnQkFDdkcsT0FBTztvQkFDTCxPQUFPLEVBQUUsV0FBVyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7b0JBQ2xDLFNBQVMsRUFBRSxXQUFXLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQztvQkFDekMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxPQUFPLEVBQUU7b0JBQzVCLE9BQU8sRUFBRTt3QkFDUCxpQkFBaUIsRUFBRSxXQUFXLEtBQUssV0FBVyxDQUFDLE9BQU8sRUFBRTt3QkFDeEQsbUJBQW1CLEVBQUUsYUFBYSxLQUFLLFdBQVcsQ0FBQyxPQUFPLEVBQUU7d0JBQzVELGNBQWMsRUFBRSxXQUFXLENBQUMsTUFBTSxDQUFDLGFBQWEsRUFBRSxPQUFPLENBQUM7cUJBQzNEO2lCQUNGLENBQUM7WUFDSixDQUFDLENBQUMsQ0FBQztZQUNILE9BQU8sRUFBQyxLQUFLLEVBQUMsQ0FBQztRQUNqQixDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7O09BYUc7SUFDSCxNQUFNLENBQUMsZ0JBQXdCLEVBQUUsb0JBQTRCO1FBQzNELE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLG9CQUFvQixDQUFDLENBQUM7SUFDakcsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7O09BYUc7SUFDSCxJQUFJLENBQUMsZ0JBQXdCLEVBQUUsb0JBQTRCO1FBQ3pELE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLG9CQUFvQixDQUFDLENBQUM7SUFDdEcsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7O09BYUc7SUFDSCxNQUFNLENBQUMsZ0JBQXdCLEVBQUUsb0JBQTRCO1FBQzNELE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLG9CQUFvQixDQUFDLENBQUM7SUFDdEcsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7Ozs7O09BZ0JHO0lBQ0gsT0FBTyxDQUFDLGdCQUF3QixFQUFFLG9CQUE0QjtRQUM1RCxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxvQkFBb0IsQ0FBQyxDQUFDO0lBQ2pHLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7OztPQWFHO0lBQ0gsUUFBUSxDQUFDLGdCQUF3QixFQUFFLG9CQUE0QjtRQUM3RCxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxRQUFRLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxvQkFBb0IsQ0FBQyxDQUFDO0lBQ25HLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7OztPQWFHO0lBQ0gsTUFBTSxDQUFDLGdCQUF3QixFQUFFLG9CQUE0QjtRQUMzRCxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUMsUUFBUSxDQUFDLEVBQUUsRUFBRSxRQUFRLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxvQkFBb0IsQ0FBQyxDQUFDO0lBQ3hHLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7O09BWUc7SUFDSCxLQUFLLENBQUMsZ0JBQXdCLEVBQUUsb0JBQTRCO1FBQzFELE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsb0JBQW9CLENBQUMsQ0FBQztJQUMvRixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7OztPQVlHO0lBQ0gsTUFBTSxDQUFDLGdCQUF3QixFQUFFLG9CQUE0QjtRQUMzRCxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLG9CQUFvQixDQUFDLENBQUM7SUFDakcsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IDIwMTMtcHJlc2VudCBEYWxlIExvdHRzIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBodHRwOi8vd3d3LmRhbGVsb3R0cy5jb21cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2dpdGh1Yi5jb20vZGFsZWxvdHRzL2FuZ3VsYXItYm9vdHN0cmFwLWRhdGV0aW1lcGlja2VyL2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAqL1xuXG5pbXBvcnQge1NpbXBsZUNoYW5nZXN9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0ICogYXMgX21vbWVudCBmcm9tICdtb21lbnQnO1xuaW1wb3J0IHtEbERhdGVUaW1lUGlja2VyTW9kZWx9IGZyb20gJy4vZGwtZGF0ZS10aW1lLXBpY2tlci1tb2RlbCc7XG5pbXBvcnQge0RsTW9kZWxQcm92aWRlcn0gZnJvbSAnLi9kbC1tb2RlbC1wcm92aWRlcic7XG5cbi8qKlxuICogV29yayBhcm91bmQgZm9yIG1vbWVudCBuYW1lc3BhY2UgY29uZmxpY3Qgd2hlbiB1c2VkIHdpdGggd2VicGFjayBhbmQgcm9sbHVwLlxuICogU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9kaGVyZ2VzL25nLXBhY2thZ3IvaXNzdWVzLzE2M1xuICpcbiAqIERlcGVuZGluZyBvbiB3aGV0aGVyIHJvbGx1cCBpcyB1c2VkLCBtb21lbnQgbmVlZHMgdG8gYmUgaW1wb3J0ZWQgZGlmZmVyZW50bHkuXG4gKiBTaW5jZSBNb21lbnQuanMgZG9lc24ndCBoYXZlIGEgZGVmYXVsdCBleHBvcnQsIHdlIG5vcm1hbGx5IG5lZWQgdG8gaW1wb3J0IHVzaW5nXG4gKiB0aGUgYCogYXNgc3ludGF4LlxuICpcbiAqIHJvbGx1cCBjcmVhdGVzIGEgc3ludGhldGljIGRlZmF1bHQgbW9kdWxlIGFuZCB3ZSB0aHVzIG5lZWQgdG8gaW1wb3J0IGl0IHVzaW5nXG4gKiB0aGUgYGRlZmF1bHQgYXNgIHN5bnRheC5cbiAqXG4gKiBAaW50ZXJuYWxcbiAqKi9cbmNvbnN0IG1vbWVudCA9IF9tb21lbnQ7XG5cbi8qKlxuICogRGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBmb3IgdGhlIGBtb250aGAgdmlldy5cbiAqL1xuZXhwb3J0IGNsYXNzIERsTW9udGhNb2RlbFByb3ZpZGVyIGltcGxlbWVudHMgRGxNb2RlbFByb3ZpZGVyIHtcblxuICAvKipcbiAgICogUmVjZWl2ZXMgaW5wdXQgY2hhbmdlcyBkZXRlY3RlZCBieSBBbmd1bGFyLlxuICAgKlxuICAgKiBAcGFyYW0gY2hhbmdlc1xuICAgKiAgdGhlIGlucHV0IGNoYW5nZXMgZGV0ZWN0ZWQgYnkgQW5ndWxhci5cbiAgICovXG4gIG9uQ2hhbmdlcyhcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgY2hhbmdlczogU2ltcGxlQ2hhbmdlc1xuICApOiB2b2lkIHt9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGBtb250aGAgbW9kZWwgZm9yIHRoZSBzcGVjaWZpZWQgbW9tZW50IGluIGBsb2NhbGAgdGltZSB3aXRoIHRoZVxuICAgKiBgYWN0aXZlYCBtb250aCBzZXQgdG8gdGhlIGZpcnN0IGRheSBvZiB0aGUgc3BlY2lmaWVkIG1vbnRoLlxuICAgKlxuICAgKiBUaGUgYG1vbnRoYCBtb2RlbCByZXByZXNlbnRzIGEgeWVhciAoMTIgbW9udGhzKSBhcyB0aHJlZSByb3dzIHdpdGggZm91ciBjb2x1bW5zLlxuICAgKlxuICAgKiBUaGUgeWVhciBhbHdheXMgc3RhcnRzIGluIEphbnVhcnkuXG4gICAqXG4gICAqIEVhY2ggY2VsbCByZXByZXNlbnRzIG1pZG5pZ2h0IG9uIHRoZSAxc3QgZGF5IG9mIHRoZSBtb250aC5cbiAgICpcbiAgICogVGhlIGBhY3RpdmVgIG1vbnRoIHdpbGwgYmUgdGhlIEphbnVhcnkgb2YgeWVhciBvZiB0aGUgc3BlY2lmaWVkIG1pbGxpc2Vjb25kcy5cbiAgICpcbiAgICogQHBhcmFtIG1pbGxpc2Vjb25kc1xuICAgKiAgdGhlIG1vbWVudCBpbiB0aW1lIGZyb20gd2hpY2ggdGhlIG1vbnRoIG1vZGVsIHdpbGwgYmUgY3JlYXRlZC5cbiAgICogQHBhcmFtIHNlbGVjdGVkTWlsbGlzZWNvbmRzXG4gICAqICB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgZGF0ZS90aW1lIHBpY2tlci5cbiAgICogQHJldHVybnNcbiAgICogIHRoZSBtb2RlbCByZXByZXNlbnRpbmcgdGhlIHNwZWNpZmllZCBtb21lbnQgaW4gdGltZS5cbiAgICovXG4gIGdldE1vZGVsKG1pbGxpc2Vjb25kczogbnVtYmVyLCBzZWxlY3RlZE1pbGxpc2Vjb25kczogbnVtYmVyKTogRGxEYXRlVGltZVBpY2tlck1vZGVsIHtcbiAgICBjb25zdCBzdGFydERhdGUgPSBtb21lbnQobWlsbGlzZWNvbmRzKS5zdGFydE9mKCd5ZWFyJyk7XG5cbiAgICBjb25zdCByb3dOdW1iZXJzID0gWzAsIDEsIDJdO1xuICAgIGNvbnN0IGNvbHVtbk51bWJlcnMgPSBbMCwgMSwgMiwgM107XG5cbiAgICBjb25zdCBwcmV2aW91c1llYXIgPSBtb21lbnQoc3RhcnREYXRlKS5zdWJ0cmFjdCgxLCAneWVhcicpO1xuICAgIGNvbnN0IG5leHRZZWFyID0gbW9tZW50KHN0YXJ0RGF0ZSkuYWRkKDEsICd5ZWFyJyk7XG4gICAgY29uc3QgYWN0aXZlVmFsdWUgPSBtb21lbnQobWlsbGlzZWNvbmRzKS5zdGFydE9mKCdtb250aCcpLnZhbHVlT2YoKTtcbiAgICBjb25zdCBzZWxlY3RlZFZhbHVlID0gc2VsZWN0ZWRNaWxsaXNlY29uZHMgPT09IG51bGwgfHwgc2VsZWN0ZWRNaWxsaXNlY29uZHMgPT09IHVuZGVmaW5lZFxuICAgICAgPyBzZWxlY3RlZE1pbGxpc2Vjb25kc1xuICAgICAgOiBtb21lbnQoc2VsZWN0ZWRNaWxsaXNlY29uZHMpLnN0YXJ0T2YoJ21vbnRoJykudmFsdWVPZigpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHZpZXdOYW1lOiAnbW9udGgnLFxuICAgICAgdmlld0xhYmVsOiBzdGFydERhdGUuZm9ybWF0KCdZWVlZJyksXG4gICAgICBhY3RpdmVEYXRlOiBhY3RpdmVWYWx1ZSxcbiAgICAgIGxlZnRCdXR0b246IHtcbiAgICAgICAgdmFsdWU6IHByZXZpb3VzWWVhci52YWx1ZU9mKCksXG4gICAgICAgIGFyaWFMYWJlbDogYEdvIHRvICR7cHJldmlvdXNZZWFyLmZvcm1hdCgnWVlZWScpfWAsXG4gICAgICAgIGNsYXNzZXM6IHt9LFxuICAgICAgfSxcbiAgICAgIHVwQnV0dG9uOiB7XG4gICAgICAgIHZhbHVlOiBzdGFydERhdGUudmFsdWVPZigpLFxuICAgICAgICBhcmlhTGFiZWw6IGBHbyB0byAke3N0YXJ0RGF0ZS5mb3JtYXQoJ1lZWVknKX1gLFxuICAgICAgICBjbGFzc2VzOiB7fSxcbiAgICAgIH0sXG4gICAgICByaWdodEJ1dHRvbjoge1xuICAgICAgICB2YWx1ZTogbmV4dFllYXIudmFsdWVPZigpLFxuICAgICAgICBhcmlhTGFiZWw6IGBHbyB0byAke25leHRZZWFyLmZvcm1hdCgnWVlZWScpfWAsXG4gICAgICAgIGNsYXNzZXM6IHt9LFxuICAgICAgfSxcbiAgICAgIHJvd3M6IHJvd051bWJlcnMubWFwKHJvd09mTW9udGhzKVxuICAgIH07XG5cbiAgICBmdW5jdGlvbiByb3dPZk1vbnRocyhyb3dOdW1iZXIpIHtcblxuICAgICAgY29uc3QgY3VycmVudE1vbWVudCA9IG1vbWVudCgpO1xuICAgICAgY29uc3QgY2VsbHMgPSBjb2x1bW5OdW1iZXJzLm1hcCgoY29sdW1uTnVtYmVyKSA9PiB7XG4gICAgICAgIGNvbnN0IG1vbnRoTW9tZW50ID0gbW9tZW50KHN0YXJ0RGF0ZSkuYWRkKChyb3dOdW1iZXIgKiBjb2x1bW5OdW1iZXJzLmxlbmd0aCkgKyBjb2x1bW5OdW1iZXIsICdtb250aHMnKTtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBkaXNwbGF5OiBtb250aE1vbWVudC5mb3JtYXQoJ01NTScpLFxuICAgICAgICAgIGFyaWFMYWJlbDogbW9udGhNb21lbnQuZm9ybWF0KCdNTU0gWVlZWScpLFxuICAgICAgICAgIHZhbHVlOiBtb250aE1vbWVudC52YWx1ZU9mKCksXG4gICAgICAgICAgY2xhc3Nlczoge1xuICAgICAgICAgICAgJ2RsLWFiZHRwLWFjdGl2ZSc6IGFjdGl2ZVZhbHVlID09PSBtb250aE1vbWVudC52YWx1ZU9mKCksXG4gICAgICAgICAgICAnZGwtYWJkdHAtc2VsZWN0ZWQnOiBzZWxlY3RlZFZhbHVlID09PSBtb250aE1vbWVudC52YWx1ZU9mKCksXG4gICAgICAgICAgICAnZGwtYWJkdHAtbm93JzogbW9udGhNb21lbnQuaXNTYW1lKGN1cnJlbnRNb21lbnQsICdtb250aCcpLFxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIHtjZWxsc307XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE1vdmUgdGhlIGFjdGl2ZSBgbW9udGhgIG9uZSByb3cgYGRvd25gIGZyb20gdGhlIHNwZWNpZmllZCBtb21lbnQgaW4gdGltZS5cbiAgICpcbiAgICogTW92aW5nIGBkb3duYCBjYW4gcmVzdWx0IGluIHRoZSBgYWN0aXZlYCBtb250aCBiZWluZyBwYXJ0IG9mIGEgZGlmZmVyZW50IHllYXIgdGhhblxuICAgKiB0aGUgc3BlY2lmaWVkIGBmcm9tTWlsbGlzZWNvbmRzYCwgaW4gdGhpcyBjYXNlIHRoZSB5ZWFyIHJlcHJlc2VudGVkIGJ5IHRoZSBtb2RlbFxuICAgKiB3aWxsIGNoYW5nZSB0byBzaG93IHRoZSBjb3JyZWN0IHllYXIuXG4gICAqXG4gICAqIEBwYXJhbSBmcm9tTWlsbGlzZWNvbmRzXG4gICAqICB0aGUgbW9tZW50IGluIHRpbWUgZnJvbSB3aGljaCB0aGUgbmV4dCBgbW9udGhgIG1vZGVsIGBkb3duYCB3aWxsIGJlIGNvbnN0cnVjdGVkLlxuICAgKiBAcGFyYW0gc2VsZWN0ZWRNaWxsaXNlY29uZHNcbiAgICogIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBkYXRlL3RpbWUgcGlja2VyLlxuICAgKiBAcmV0dXJuc1xuICAgKiAgbW9kZWwgY29udGFpbmluZyBhbiBgYWN0aXZlYCBgbW9udGhgIG9uZSByb3cgYGRvd25gIGZyb20gdGhlIHNwZWNpZmllZCBtb21lbnQgaW4gdGltZS5cbiAgICovXG4gIGdvRG93bihmcm9tTWlsbGlzZWNvbmRzOiBudW1iZXIsIHNlbGVjdGVkTWlsbGlzZWNvbmRzOiBudW1iZXIpOiBEbERhdGVUaW1lUGlja2VyTW9kZWwge1xuICAgIHJldHVybiB0aGlzLmdldE1vZGVsKG1vbWVudChmcm9tTWlsbGlzZWNvbmRzKS5hZGQoNCwgJ21vbnRoJykudmFsdWVPZigpLCBzZWxlY3RlZE1pbGxpc2Vjb25kcyk7XG4gIH1cblxuICAvKipcbiAgICogTW92ZSB0aGUgYWN0aXZlIGBtb250aGAgb25lIHJvdyBgdXBgIGZyb20gdGhlIHNwZWNpZmllZCBtb21lbnQgaW4gdGltZS5cbiAgICpcbiAgICogTW92aW5nIGB1cGAgY2FuIHJlc3VsdCBpbiB0aGUgYGFjdGl2ZWAgbW9udGggYmVpbmcgcGFydCBvZiBhIGRpZmZlcmVudCB5ZWFyIHRoYW5cbiAgICogdGhlIHNwZWNpZmllZCBgZnJvbU1pbGxpc2Vjb25kc2AsIGluIHRoaXMgY2FzZSB0aGUgeWVhciByZXByZXNlbnRlZCBieSB0aGUgbW9kZWxcbiAgICogd2lsbCBjaGFuZ2UgdG8gc2hvdyB0aGUgY29ycmVjdCB5ZWFyLlxuICAgKlxuICAgKiBAcGFyYW0gZnJvbU1pbGxpc2Vjb25kc1xuICAgKiAgdGhlIG1vbWVudCBpbiB0aW1lIGZyb20gd2hpY2ggdGhlIHByZXZpb3VzIGBtb250aGAgbW9kZWwgYHVwYCB3aWxsIGJlIGNvbnN0cnVjdGVkLlxuICAgKiBAcGFyYW0gc2VsZWN0ZWRNaWxsaXNlY29uZHNcbiAgICogIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBkYXRlL3RpbWUgcGlja2VyLlxuICAgKiBAcmV0dXJuc1xuICAgKiAgbW9kZWwgY29udGFpbmluZyBhbiBgYWN0aXZlYCBgbW9udGhgIG9uZSByb3cgYHVwYCBmcm9tIHRoZSBzcGVjaWZpZWQgbW9tZW50IGluIHRpbWUuXG4gICAqL1xuICBnb1VwKGZyb21NaWxsaXNlY29uZHM6IG51bWJlciwgc2VsZWN0ZWRNaWxsaXNlY29uZHM6IG51bWJlcik6IERsRGF0ZVRpbWVQaWNrZXJNb2RlbCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0TW9kZWwobW9tZW50KGZyb21NaWxsaXNlY29uZHMpLnN1YnRyYWN0KDQsICdtb250aCcpLnZhbHVlT2YoKSwgc2VsZWN0ZWRNaWxsaXNlY29uZHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1vdmUgdGhlIGBhY3RpdmVgIGBtb250aGAgb25lICgxKSBtb250aCB0byB0aGUgYGxlZnRgIG9mIHRoZSBzcGVjaWZpZWQgbW9tZW50IGluIHRpbWUuXG4gICAqXG4gICAqIE1vdmluZyBgbGVmdGAgY2FuIHJlc3VsdCBpbiB0aGUgYGFjdGl2ZWAgbW9udGggYmVpbmcgcGFydCBvZiBhIGRpZmZlcmVudCB5ZWFyIHRoYW5cbiAgICogdGhlIHNwZWNpZmllZCBgZnJvbU1pbGxpc2Vjb25kc2AsIGluIHRoaXMgY2FzZSB0aGUgeWVhciByZXByZXNlbnRlZCBieSB0aGUgbW9kZWxcbiAgICogd2lsbCBjaGFuZ2UgdG8gc2hvdyB0aGUgY29ycmVjdCB5ZWFyLlxuICAgKlxuICAgKiBAcGFyYW0gZnJvbU1pbGxpc2Vjb25kc1xuICAgKiAgdGhlIG1vbWVudCBpbiB0aW1lIGZyb20gd2hpY2ggdGhlIGBtb250aGAgbW9kZWwgdG8gdGhlIGBsZWZ0YCB3aWxsIGJlIGNvbnN0cnVjdGVkLlxuICAgKiBAcGFyYW0gc2VsZWN0ZWRNaWxsaXNlY29uZHNcbiAgICogIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBkYXRlL3RpbWUgcGlja2VyLlxuICAgKiBAcmV0dXJuc1xuICAgKiAgbW9kZWwgY29udGFpbmluZyBhbiBgYWN0aXZlYCBgbW9udGhgIG9uZSBtb250aCB0byB0aGUgYGxlZnRgIG9mIHRoZSBzcGVjaWZpZWQgbW9tZW50IGluIHRpbWUuXG4gICAqL1xuICBnb0xlZnQoZnJvbU1pbGxpc2Vjb25kczogbnVtYmVyLCBzZWxlY3RlZE1pbGxpc2Vjb25kczogbnVtYmVyKTogRGxEYXRlVGltZVBpY2tlck1vZGVsIHtcbiAgICByZXR1cm4gdGhpcy5nZXRNb2RlbChtb21lbnQoZnJvbU1pbGxpc2Vjb25kcykuc3VidHJhY3QoMSwgJ21vbnRoJykudmFsdWVPZigpLCBzZWxlY3RlZE1pbGxpc2Vjb25kcyk7XG4gIH1cblxuICAvKipcbiAgICogTW92ZSB0aGUgYGFjdGl2ZWAgYG1vbnRoYCBvbmUgKDEpIG1vbnRoIHRvIHRoZSBgcmlnaHRgIG9mIHRoZSBzcGVjaWZpZWQgbW9tZW50IGluIHRpbWUuXG4gICAqXG4gICAqIFRoZSBgYWN0aXZlYCBtb250aCB3aWxsIGJlIGBvbmUgKDEpIG1vbnRoIGFmdGVyYCB0aGUgc3BlY2lmaWVkIG1pbGxpc2Vjb25kcy5cbiAgICogVGhpcyBtb3ZlcyB0aGUgYGFjdGl2ZWAgZGF0ZSBvbmUgbW9udGggYHJpZ2h0YCBpbiB0aGUgY3VycmVudCBgbW9udGhgIHZpZXcuXG4gICAqXG4gICAqIE1vdmluZyBgcmlnaHRgIGNhbiByZXN1bHQgaW4gdGhlIGBhY3RpdmVgIG1vbnRoIGJlaW5nIHBhcnQgb2YgYSBkaWZmZXJlbnQgeWVhciB0aGFuXG4gICAqIHRoZSBzcGVjaWZpZWQgYGZyb21NaWxsaXNlY29uZHNgLCBpbiB0aGlzIGNhc2UgdGhlIHllYXIgcmVwcmVzZW50ZWQgYnkgdGhlIG1vZGVsXG4gICAqIHdpbGwgY2hhbmdlIHRvIHNob3cgdGhlIGNvcnJlY3QgeWVhci5cbiAgICpcbiAgICogQHBhcmFtIGZyb21NaWxsaXNlY29uZHNcbiAgICogIHRoZSBtb21lbnQgaW4gdGltZSBmcm9tIHdoaWNoIHRoZSBgbW9udGhgIG1vZGVsIHRvIHRoZSBgcmlnaHRgIHdpbGwgYmUgY29uc3RydWN0ZWQuXG4gICAqIEBwYXJhbSBzZWxlY3RlZE1pbGxpc2Vjb25kc1xuICAgKiAgdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGRhdGUvdGltZSBwaWNrZXIuXG4gICAqIEByZXR1cm5zXG4gICAqICBtb2RlbCBjb250YWluaW5nIGFuIGBhY3RpdmVgIGBtb250aGAgb25lIHllYXIgdG8gdGhlIGByaWdodGAgb2YgdGhlIHNwZWNpZmllZCBtb21lbnQgaW4gdGltZS5cbiAgICovXG4gIGdvUmlnaHQoZnJvbU1pbGxpc2Vjb25kczogbnVtYmVyLCBzZWxlY3RlZE1pbGxpc2Vjb25kczogbnVtYmVyKTogRGxEYXRlVGltZVBpY2tlck1vZGVsIHtcbiAgICByZXR1cm4gdGhpcy5nZXRNb2RlbChtb21lbnQoZnJvbU1pbGxpc2Vjb25kcykuYWRkKDEsICdtb250aCcpLnZhbHVlT2YoKSwgc2VsZWN0ZWRNaWxsaXNlY29uZHMpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1vdmUgdGhlIGFjdGl2ZSBgbW9udGhgIG9uZSB5ZWFyIGBkb3duYCBmcm9tIHRoZSBzcGVjaWZpZWQgbW9tZW50IGluIHRpbWUuXG4gICAqXG4gICAqIFBhZ2luZyBgZG93bmAgd2lsbCByZXN1bHQgaW4gdGhlIGBhY3RpdmVgIG1vbnRoIGJlaW5nIHBhcnQgb2YgYSBkaWZmZXJlbnQgeWVhciB0aGFuXG4gICAqIHRoZSBzcGVjaWZpZWQgYGZyb21NaWxsaXNlY29uZHNgLiBBcyBhIHJlc3VsdCwgdGhlIHllYXIgcmVwcmVzZW50ZWQgYnkgdGhlIG1vZGVsXG4gICAqIHdpbGwgY2hhbmdlIHRvIHNob3cgdGhlIGNvcnJlY3QgeWVhci5cbiAgICpcbiAgICogQHBhcmFtIGZyb21NaWxsaXNlY29uZHNcbiAgICogIHRoZSBtb21lbnQgaW4gdGltZSBmcm9tIHdoaWNoIHRoZSBuZXh0IGBtb250aGAgbW9kZWwgcGFnZSBgZG93bmAgd2lsbCBiZSBjb25zdHJ1Y3RlZC5cbiAgICogQHBhcmFtIHNlbGVjdGVkTWlsbGlzZWNvbmRzXG4gICAqICB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgZGF0ZS90aW1lIHBpY2tlci5cbiAgICogQHJldHVybnNcbiAgICogIG1vZGVsIGNvbnRhaW5pbmcgYW4gYGFjdGl2ZWAgYG1vbnRoYCBvbmUgeWVhciBgZG93bmAgZnJvbSB0aGUgc3BlY2lmaWVkIG1vbWVudCBpbiB0aW1lLlxuICAgKi9cbiAgcGFnZURvd24oZnJvbU1pbGxpc2Vjb25kczogbnVtYmVyLCBzZWxlY3RlZE1pbGxpc2Vjb25kczogbnVtYmVyKTogRGxEYXRlVGltZVBpY2tlck1vZGVsIHtcbiAgICByZXR1cm4gdGhpcy5nZXRNb2RlbChtb21lbnQoZnJvbU1pbGxpc2Vjb25kcykuYWRkKDEyLCAnbW9udGhzJykudmFsdWVPZigpLCBzZWxlY3RlZE1pbGxpc2Vjb25kcyk7XG4gIH1cblxuICAvKipcbiAgICogTW92ZSB0aGUgYWN0aXZlIGBtb250aGAgb25lIHllYXIgYGRvd25gIGZyb20gdGhlIHNwZWNpZmllZCBtb21lbnQgaW4gdGltZS5cbiAgICpcbiAgICogUGFnaW5nIGB1cGAgd2lsbCByZXN1bHQgaW4gdGhlIGBhY3RpdmVgIG1vbnRoIGJlaW5nIHBhcnQgb2YgYSBkaWZmZXJlbnQgeWVhciB0aGFuXG4gICAqIHRoZSBzcGVjaWZpZWQgYGZyb21NaWxsaXNlY29uZHNgLiBBcyBhIHJlc3VsdCwgdGhlIHllYXIgcmVwcmVzZW50ZWQgYnkgdGhlIG1vZGVsXG4gICAqIHdpbGwgY2hhbmdlIHRvIHNob3cgdGhlIGNvcnJlY3QgeWVhci5cbiAgICpcbiAgICogQHBhcmFtIGZyb21NaWxsaXNlY29uZHNcbiAgICogIHRoZSBtb21lbnQgaW4gdGltZSBmcm9tIHdoaWNoIHRoZSBuZXh0IGBtb250aGAgbW9kZWwgcGFnZSBgdXBgIHdpbGwgYmUgY29uc3RydWN0ZWQuXG4gICAqIEBwYXJhbSBzZWxlY3RlZE1pbGxpc2Vjb25kc1xuICAgKiAgdGhlIGN1cnJlbnQgdmFsdWUgb2YgdGhlIGRhdGUvdGltZSBwaWNrZXIuXG4gICAqIEByZXR1cm5zXG4gICAqICBtb2RlbCBjb250YWluaW5nIGFuIGBhY3RpdmVgIGBtb250aGAgb25lIHllYXIgYHVwYCBmcm9tIHRoZSBzcGVjaWZpZWQgbW9tZW50IGluIHRpbWUuXG4gICAqL1xuICBwYWdlVXAoZnJvbU1pbGxpc2Vjb25kczogbnVtYmVyLCBzZWxlY3RlZE1pbGxpc2Vjb25kczogbnVtYmVyKTogRGxEYXRlVGltZVBpY2tlck1vZGVsIHtcbiAgICByZXR1cm4gdGhpcy5nZXRNb2RlbChtb21lbnQoZnJvbU1pbGxpc2Vjb25kcykuc3VidHJhY3QoMTIsICdtb250aHMnKS52YWx1ZU9mKCksIHNlbGVjdGVkTWlsbGlzZWNvbmRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNb3ZlIHRoZSBgYWN0aXZlYCBgbW9udGhgIHRvIGBEZWNlbWJlcmAgb2YgdGhlIGN1cnJlbnQgeWVhci5cbiAgICpcbiAgICogVGhlIHZpZXcgb3IgdGltZSByYW5nZSB3aWxsIG5vdCBjaGFuZ2UgdW5sZXNzIHRoZSBgZnJvbU1pbGxpc2Vjb25kc2AgdmFsdWVcbiAgICogaXMgaW4gYSBkaWZmZXJlbnQgeWVhciB0aGFuIHRoZSBkaXNwbGF5ZWQgZGVjYWRlLlxuICAgKlxuICAgKiBAcGFyYW0gZnJvbU1pbGxpc2Vjb25kc1xuICAgKiAgdGhlIG1vbWVudCBpbiB0aW1lIGZyb20gd2hpY2ggYERlY2VtYmVyIDFgIHdpbGwgYmUgY2FsY3VsYXRlZC5cbiAgICogQHBhcmFtIHNlbGVjdGVkTWlsbGlzZWNvbmRzXG4gICAqICB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgZGF0ZS90aW1lIHBpY2tlci5cbiAgICogQHJldHVybnNcbiAgICogIGEgbW9kZWwgd2l0aCB0aGUgYERlY2VtYmVyYCBjZWxsIGluIHRoZSB2aWV3IGFzIHRoZSBhY3RpdmUgYG1vbnRoYC5cbiAgICovXG4gIGdvRW5kKGZyb21NaWxsaXNlY29uZHM6IG51bWJlciwgc2VsZWN0ZWRNaWxsaXNlY29uZHM6IG51bWJlcik6IERsRGF0ZVRpbWVQaWNrZXJNb2RlbCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0TW9kZWwobW9tZW50KGZyb21NaWxsaXNlY29uZHMpLmVuZE9mKCd5ZWFyJykudmFsdWVPZigpLCBzZWxlY3RlZE1pbGxpc2Vjb25kcyk7XG4gIH1cblxuICAvKipcbiAgICogTW92ZSB0aGUgYGFjdGl2ZWAgYG1vbnRoYCB0byBgSmFudWFyeWAgb2YgdGhlIGN1cnJlbnQgeWVhci5cbiAgICpcbiAgICogVGhlIHZpZXcgb3IgdGltZSByYW5nZSB3aWxsIG5vdCBjaGFuZ2UgdW5sZXNzIHRoZSBgZnJvbU1pbGxpc2Vjb25kc2AgdmFsdWVcbiAgICogaXMgaW4gYSBkaWZmZXJlbnQgeWVhciB0aGFuIHRoZSBkaXNwbGF5ZWQgZGVjYWRlLlxuICAgKlxuICAgKiBAcGFyYW0gZnJvbU1pbGxpc2Vjb25kc1xuICAgKiAgdGhlIG1vbWVudCBpbiB0aW1lIGZyb20gd2hpY2ggYEphbnVhcnkgMWAgd2lsbCBiZSBjYWxjdWxhdGVkLlxuICAgKiBAcGFyYW0gc2VsZWN0ZWRNaWxsaXNlY29uZHNcbiAgICogIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBkYXRlL3RpbWUgcGlja2VyLlxuICAgKiBAcmV0dXJuc1xuICAgKiAgYSBtb2RlbCB3aXRoIHRoZSBgSmFudWFyeWAgY2VsbCBpbiB0aGUgdmlldyBhcyB0aGUgYWN0aXZlIGBtb250aGAuXG4gICAqL1xuICBnb0hvbWUoZnJvbU1pbGxpc2Vjb25kczogbnVtYmVyLCBzZWxlY3RlZE1pbGxpc2Vjb25kczogbnVtYmVyKTogRGxEYXRlVGltZVBpY2tlck1vZGVsIHtcbiAgICByZXR1cm4gdGhpcy5nZXRNb2RlbChtb21lbnQoZnJvbU1pbGxpc2Vjb25kcykuc3RhcnRPZigneWVhcicpLnZhbHVlT2YoKSwgc2VsZWN0ZWRNaWxsaXNlY29uZHMpO1xuICB9XG59XG4iXX0=