studiokit-scaffolding-js 7.0.12-next.1.4 → 7.0.12-next.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/ActionList.js +170 -34
- package/lib/components/AlertDialog.js +133 -9
- package/lib/components/AlertWithIcon.js +92 -25
- package/lib/components/ConnectedModal.js +43 -13
- package/lib/components/Dropdowns/GroupsDropdown.js +69 -44
- package/lib/components/Dropdowns/ManagedNavDropdown.js +100 -67
- package/lib/components/Dropdowns/UserDropdown.js +111 -21
- package/lib/components/Dropdowns/index.js +27 -9
- package/lib/components/EntityOwnerList.js +52 -18
- package/lib/components/Error.js +106 -11
- package/lib/components/ErrorBoundary.js +134 -35
- package/lib/components/ErrorMessage.js +44 -9
- package/lib/components/Forms/DateField.js +61 -42
- package/lib/components/Forms/TimeField.js +81 -42
- package/lib/components/Forms/index.js +27 -4
- package/lib/components/Groups/CreateEditCopySaveButtons.js +114 -11
- package/lib/components/Groups/ExternalGroups/Attach.js +212 -148
- package/lib/components/Groups/ExternalGroups/Table.js +181 -45
- package/lib/components/Groups/GroupCreateOrEditCommonProps.js +5 -1
- package/lib/components/Groups/RosterSyncInfo.js +147 -20
- package/lib/components/HOC/AccessibleAppComponent.js +98 -73
- package/lib/components/HOC/ActivityRequiredComponent.js +92 -49
- package/lib/components/HOC/AsyncComponent.js +54 -39
- package/lib/components/HOC/AuthenticatedComponent.js +58 -38
- package/lib/components/HOC/CollectionComponent.js +170 -110
- package/lib/components/HOC/CollectionFirstItemComponent.js +51 -38
- package/lib/components/HOC/CollectionItemComponent.js +168 -106
- package/lib/components/HOC/ConnectedModalComponent.js +109 -80
- package/lib/components/HOC/DataDependentComponent.js +29 -21
- package/lib/components/HOC/EntityComponent.js +71 -57
- package/lib/components/HOC/FullscreenModalComponent.js +163 -123
- package/lib/components/HOC/GroupActivityRequiredComponent.js +45 -31
- package/lib/components/HOC/GuidComponent.js +29 -22
- package/lib/components/HOC/ModelContextDependencyVerifyComponent.js +41 -31
- package/lib/components/HOC/ModelErrorRedirectComponent.js +51 -47
- package/lib/components/HOC/SearchPersistorComponent.js +240 -166
- package/lib/components/HOC/UnauthenticatedComponent.js +37 -25
- package/lib/components/HOC/UserComponent.js +12 -7
- package/lib/components/Icons/IconAlphaList.js +33 -5
- package/lib/components/Icons/IconExternalUser.js +33 -5
- package/lib/components/Icons/IconImpersonation.js +33 -5
- package/lib/components/Icons/IconStopImpersonating.js +33 -5
- package/lib/components/Icons/IconTable.js +35 -7
- package/lib/components/Icons/IconTableDeleteCol.js +33 -5
- package/lib/components/Icons/IconTableDeleteRow.js +33 -5
- package/lib/components/Icons/IconTableInsertCol.js +33 -5
- package/lib/components/Icons/IconTableInsertRow.js +33 -5
- package/lib/components/Impersonation/Button.js +77 -13
- package/lib/components/Impersonation/Link.js +77 -13
- package/lib/components/Impersonation/UserDetail.js +66 -9
- package/lib/components/Loading.js +26 -4
- package/lib/components/LockDownBrowser/Check.js +194 -49
- package/lib/components/LockDownBrowser/ExitButton.js +26 -9
- package/lib/components/LockDownBrowser/Launch.js +70 -62
- package/lib/components/Lti/Confirm.js +152 -11
- package/lib/components/Lti/CreateNonLtiGroupAlertDialog.js +170 -33
- package/lib/components/Lti/Launch.js +105 -24
- package/lib/components/Lti/LaunchGroup.js +85 -13
- package/lib/components/ManageTable.js +309 -87
- package/lib/components/ManageTableNoDataComponent.js +42 -4
- package/lib/components/NewVersionAlert.js +82 -46
- package/lib/components/NotFound.js +86 -10
- package/lib/components/Notifications.js +185 -126
- package/lib/components/PaginationNextButton.js +33 -6
- package/lib/components/PaginationPreviousButton.js +33 -6
- package/lib/components/Quill/CustomToolbar.js +432 -218
- package/lib/components/Quill/Formats/Image.js +73 -63
- package/lib/components/Quill/Formats/List.js +45 -45
- package/lib/components/Quill/Formats/Video.js +28 -24
- package/lib/components/Quill/ImageDropModule.js +147 -117
- package/lib/components/Quill/ImageWarning.js +47 -9
- package/lib/components/Quill/ImageWithAltTextModal.js +425 -86
- package/lib/components/Quill/Specs/CustomImageSpec.js +42 -34
- package/lib/components/Quill/Specs/CustomVideoSpec.js +34 -28
- package/lib/components/Quill/TableModule/Blots/BaseTableBlot.js +98 -98
- package/lib/components/Quill/TableModule/Blots/TableBlot.js +52 -47
- package/lib/components/Quill/TableModule/Blots/TableBodyBlot.js +53 -48
- package/lib/components/Quill/TableModule/Blots/TableCellBlot.js +224 -221
- package/lib/components/Quill/TableModule/Blots/TableContainer.js +80 -83
- package/lib/components/Quill/TableModule/Blots/TableRowBlot.js +75 -70
- package/lib/components/Quill/TableModule/constants.js +45 -41
- package/lib/components/Quill/TableModule/index.js +362 -301
- package/lib/components/Quill/TableModule/utils.js +42 -38
- package/lib/components/Quill/accessibilityFix.js +234 -232
- package/lib/components/Quill/index.js +34 -28
- package/lib/components/RefreshIndicator/Bordered.js +47 -6
- package/lib/components/RefreshIndicator/Inline.js +47 -8
- package/lib/components/RefreshIndicator/index.js +263 -59
- package/lib/components/SearchControls.js +216 -11
- package/lib/components/SentryRoute.js +11 -6
- package/lib/components/Tables/RoleFilter.js +69 -32
- package/lib/components/Tables/TextFilter.js +62 -13
- package/lib/components/UserRoles/Add.js +199 -96
- package/lib/components/UserRoles/Context.js +11 -7
- package/lib/components/UserRoles/RoleCell.js +181 -72
- package/lib/components/UserRoles/Select.js +157 -17
- package/lib/components/UserRoles/Table.js +221 -80
- package/lib/components/UserRoles/index.js +534 -384
- package/lib/config/eslint/index.js +32 -28
- package/lib/config/eslint/lib/order.js +26 -27
- package/lib/config/eslint/lib/prettier.js +20 -18
- package/lib/config/eslint/lib/typescript.js +93 -112
- package/lib/config/eslint/react.js +24 -14
- package/lib/constants/baseActivity.js +30 -26
- package/lib/constants/baseRole.js +14 -10
- package/lib/constants/configuration.js +33 -29
- package/lib/constants/externalProviderType.js +10 -6
- package/lib/constants/fetchErrorData.js +15 -11
- package/lib/constants/index.js +137 -14
- package/lib/constants/lockDownBrowser.js +28 -24
- package/lib/constants/mockData.js +382 -297
- package/lib/constants/modelStatus.js +15 -11
- package/lib/constants/notificationType.js +12 -8
- package/lib/constants/operatingSystem.js +12 -8
- package/lib/constants/shard.js +11 -7
- package/lib/constants/table.js +21 -21
- package/lib/constants/tier.js +12 -8
- package/lib/constants/userRole.js +15 -5
- package/lib/endpointMappings.js +197 -181
- package/lib/hooks/useCollection.js +82 -62
- package/lib/hooks/useCollectionConfiguration.js +228 -83
- package/lib/hooks/useCollectionItem.js +154 -54
- package/lib/hooks/useGuid.js +20 -8
- package/lib/hooks/usePrevious.js +19 -13
- package/lib/index.js +157 -25
- package/lib/redux/actionCreator.js +50 -28
- package/lib/redux/actions/AuthAction.js +44 -31
- package/lib/redux/actions/ModalAction.js +10 -6
- package/lib/redux/actions/ModelAction.js +77 -39
- package/lib/redux/actions/NotificationAction.js +10 -6
- package/lib/redux/actions/SearchAction.js +9 -5
- package/lib/redux/actions/index.js +60 -7
- package/lib/redux/configureReducers.js +60 -49
- package/lib/redux/configureStore.js +83 -87
- package/lib/redux/helpers.js +6 -2
- package/lib/redux/reducers/authReducer.js +50 -43
- package/lib/redux/reducers/index.js +41 -13
- package/lib/redux/reducers/modalsReducer.js +47 -29
- package/lib/redux/reducers/modelsReducer.js +178 -173
- package/lib/redux/reducers/notificationsReducer.js +24 -18
- package/lib/redux/reducers/searchReducer.js +25 -19
- package/lib/redux/sagas/appInsightsSaga.js +22 -18
- package/lib/redux/sagas/authSaga.js +253 -218
- package/lib/redux/sagas/caliperSaga.js +159 -143
- package/lib/redux/sagas/clockOffsetSaga.js +34 -31
- package/lib/redux/sagas/configurationSaga.js +11 -7
- package/lib/redux/sagas/downtimeApiErrorSaga.js +20 -17
- package/lib/redux/sagas/errorSaga.js +27 -21
- package/lib/redux/sagas/googleAnalyticsSaga.js +28 -24
- package/lib/redux/sagas/identityProviderSaga.js +22 -18
- package/lib/redux/sagas/initialDataLoadSaga.js +37 -28
- package/lib/redux/sagas/lockDownBrowserErrorSaga.js +29 -20
- package/lib/redux/sagas/modelFetchSaga.js +355 -322
- package/lib/redux/sagas/noStoreSaga.js +61 -48
- package/lib/redux/sagas/postLoginDataSaga.js +45 -34
- package/lib/redux/sagas/postLoginRedirectSaga.js +27 -27
- package/lib/redux/sagas/rootSaga.js +82 -57
- package/lib/redux/sagas/sentrySaga.js +29 -25
- package/lib/redux/sagas/userIdSaga.js +16 -12
- package/lib/services/codeProviderService.js +25 -19
- package/lib/services/dateService.js +12 -7
- package/lib/services/documentService.js +17 -12
- package/lib/services/fetchService.js +129 -112
- package/lib/services/persistenceService.js +33 -29
- package/lib/services/ticketProviderService.js +29 -23
- package/lib/services/tokenPersistenceService.js +12 -8
- package/lib/services/windowService.js +18 -14
- package/lib/startup.js +132 -114
- package/lib/types/AppConfiguration.js +5 -1
- package/lib/types/Artifact.js +11 -7
- package/lib/types/BaseReduxState.js +5 -1
- package/lib/types/Client.js +5 -1
- package/lib/types/Collection.js +5 -1
- package/lib/types/Configuration.js +5 -1
- package/lib/types/DeepLinkingResponseRequest.js +5 -1
- package/lib/types/DeletableModel.js +5 -1
- package/lib/types/Event.js +5 -1
- package/lib/types/ExternalGroup.js +5 -1
- package/lib/types/ExternalProvider.js +5 -1
- package/lib/types/ExternalTerm.js +5 -1
- package/lib/types/Group.js +5 -1
- package/lib/types/IdentityProvider.js +5 -1
- package/lib/types/LtiLaunch.js +5 -1
- package/lib/types/NameOnlyEntity.js +5 -1
- package/lib/types/Notification.js +5 -1
- package/lib/types/OptionalRecord.js +5 -1
- package/lib/types/OwnerSchedule.js +5 -1
- package/lib/types/PropertyOfType.js +5 -1
- package/lib/types/Quill.js +5 -1
- package/lib/types/RoleDescription.js +5 -1
- package/lib/types/Search.js +5 -1
- package/lib/types/SimpleLocation.js +5 -1
- package/lib/types/UniTime.js +5 -1
- package/lib/types/User.js +5 -1
- package/lib/types/UserRole.js +5 -1
- package/lib/types/auth/AuthState.js +5 -1
- package/lib/types/auth/CasV1LoginRequestBody.js +5 -1
- package/lib/types/auth/ClientCredentials.js +5 -1
- package/lib/types/auth/CodeProviderService.js +5 -1
- package/lib/types/auth/LocalLoginRequestBody.js +5 -1
- package/lib/types/auth/TicketProviderService.js +5 -1
- package/lib/types/auth/TokenPersistenceService.js +5 -1
- package/lib/types/auth/index.js +82 -9
- package/lib/types/externals.d.js +2 -0
- package/lib/types/index.js +313 -30
- package/lib/types/net/EndpointConfig.js +5 -1
- package/lib/types/net/EndpointMapping.js +5 -1
- package/lib/types/net/EndpointMappings.js +5 -1
- package/lib/types/net/ErrorHandler.js +5 -1
- package/lib/types/net/FetchConfig.js +5 -1
- package/lib/types/net/FetchErrorData.js +10 -6
- package/lib/types/net/FetchResult.js +5 -1
- package/lib/types/net/HTTPMethod.js +5 -1
- package/lib/types/net/HTTPStatusCode.js +16 -12
- package/lib/types/net/Metadata.js +5 -1
- package/lib/types/net/Model.js +5 -1
- package/lib/types/net/ModelCollection.js +5 -1
- package/lib/types/net/ModelsState.js +5 -1
- package/lib/types/net/OAuthToken.js +5 -1
- package/lib/types/net/OAuthTokenOrNull.js +5 -1
- package/lib/types/net/TokenAccessFunction.js +5 -1
- package/lib/types/net/index.js +181 -18
- package/lib/utils/baseActivity.js +133 -123
- package/lib/utils/baseRole.js +37 -33
- package/lib/utils/collection.js +425 -298
- package/lib/utils/cookies.js +22 -19
- package/lib/utils/date.js +303 -279
- package/lib/utils/dom.js +176 -165
- package/lib/utils/domainIdentifier.js +9 -5
- package/lib/utils/entityUserRole.js +6 -2
- package/lib/utils/error.js +17 -15
- package/lib/utils/events.js +40 -31
- package/lib/utils/externalGroup.js +22 -18
- package/lib/utils/externalProviders.js +8 -4
- package/lib/utils/externalTerms.js +10 -3
- package/lib/utils/fetch.js +179 -180
- package/lib/utils/group.js +18 -7
- package/lib/utils/groupDates.js +37 -33
- package/lib/utils/groupRoles.js +25 -21
- package/lib/utils/lockDownBrowser.js +15 -11
- package/lib/utils/logger.js +26 -22
- package/lib/utils/lti.js +9 -4
- package/lib/utils/model.js +36 -41
- package/lib/utils/number.js +21 -18
- package/lib/utils/promise.js +28 -21
- package/lib/utils/quill.js +65 -62
- package/lib/utils/route.js +58 -55
- package/lib/utils/search.js +76 -80
- package/lib/utils/shard.js +37 -37
- package/lib/utils/sort.js +50 -42
- package/lib/utils/string.js +13 -8
- package/lib/utils/table.js +38 -33
- package/lib/utils/timezone.js +10 -6
- package/lib/utils/url.js +142 -142
- package/lib/utils/user.js +58 -55
- package/lib/utils/userAgent.js +10 -10
- package/lib/utils/userRole.js +57 -49
- package/package.json +17 -3
package/lib/utils/date.js
CHANGED
|
@@ -1,377 +1,401 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.getDateMinusTime = void 0;
|
|
4
8
|
exports.getEndOfDay = getEndOfDay;
|
|
5
9
|
exports.getEndOfMinute = getEndOfMinute;
|
|
6
|
-
exports.isNowEqualOrAfterDate = isNowEqualOrAfterDate;
|
|
7
|
-
exports.isNowEqualOrBeforeDate = isNowEqualOrBeforeDate;
|
|
8
|
-
exports.isNowAfterDate = isNowAfterDate;
|
|
9
|
-
exports.isNowBeforeDate = isNowBeforeDate;
|
|
10
10
|
exports.getFormattedFullDateAndTime = getFormattedFullDateAndTime;
|
|
11
11
|
exports.getFormattedFullDateWithWeek = getFormattedFullDateWithWeek;
|
|
12
|
+
exports.getFormattedNumberedDate = getFormattedNumberedDate;
|
|
12
13
|
exports.getFormattedNumberedDateAndTime = getFormattedNumberedDateAndTime;
|
|
13
14
|
exports.getFormattedNumberedDateAndTimeWithoutYear = getFormattedNumberedDateAndTimeWithoutYear;
|
|
14
|
-
exports.getFormattedSimplifiedDate = getFormattedSimplifiedDate;
|
|
15
|
-
exports.getFormattedSimplifiedDateWithoutYear = getFormattedSimplifiedDateWithoutYear;
|
|
16
|
-
exports.getFormattedSimplifiedDateWithYearIfNotCurrent = getFormattedSimplifiedDateWithYearIfNotCurrent;
|
|
17
|
-
exports.getFormattedNumberedDate = getFormattedNumberedDate;
|
|
18
|
-
exports.getFormattedNumberedDateWithFullYear = getFormattedNumberedDateWithFullYear;
|
|
19
15
|
exports.getFormattedNumberedDateForInput = getFormattedNumberedDateForInput;
|
|
16
|
+
exports.getFormattedNumberedDateWithFullYear = getFormattedNumberedDateWithFullYear;
|
|
20
17
|
exports.getFormattedNumberedDateWithoutYear = getFormattedNumberedDateWithoutYear;
|
|
21
18
|
exports.getFormattedNumberedTime = getFormattedNumberedTime;
|
|
22
19
|
exports.getFormattedNumberedTimeWithFullZone = getFormattedNumberedTimeWithFullZone;
|
|
23
20
|
exports.getFormattedNumberedTimeWithoutZone = getFormattedNumberedTimeWithoutZone;
|
|
24
21
|
exports.getFormattedNumberedTimeWithoutZoneOrMeridian = getFormattedNumberedTimeWithoutZoneOrMeridian;
|
|
25
|
-
exports.
|
|
22
|
+
exports.getFormattedSimplifiedDate = getFormattedSimplifiedDate;
|
|
23
|
+
exports.getFormattedSimplifiedDateWithYearIfNotCurrent = getFormattedSimplifiedDateWithYearIfNotCurrent;
|
|
24
|
+
exports.getFormattedSimplifiedDateWithoutYear = getFormattedSimplifiedDateWithoutYear;
|
|
26
25
|
exports.getFormattedTimeZone = getFormattedTimeZone;
|
|
26
|
+
exports.getFullFormattedTimeZone = getFullFormattedTimeZone;
|
|
27
|
+
exports.isDateInputSupported = exports.getZonedMomentFromUtcInDefaultZone = exports.getZonedMomentFromUtc = exports.getZonedMomentFromLocalDateTime = exports.getServerNowUtc = exports.getOffsetDate = exports.getLocalMomentFromUtc = exports.getLocalDateTimeFromUtc = void 0;
|
|
27
28
|
exports.isDateTimeValid = isDateTimeValid;
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
exports.isNowAfterDate = isNowAfterDate;
|
|
30
|
+
exports.isNowBeforeDate = isNowBeforeDate;
|
|
31
|
+
exports.isNowEqualOrAfterDate = isNowEqualOrAfterDate;
|
|
32
|
+
exports.isNowEqualOrBeforeDate = isNowEqualOrBeforeDate;
|
|
33
|
+
exports.setClockOffset = exports.isTimeInputSupported = void 0;
|
|
34
|
+
var _momentTimezone = _interopRequireDefault(require("moment-timezone"));
|
|
35
|
+
var _momentTimezoneUtils = _interopRequireDefault(require("moment-timezone/moment-timezone-utils"));
|
|
36
|
+
var _timezone = require("./timezone");
|
|
37
|
+
/**
|
|
38
|
+
* This value is used by time-sensitive functions in this module and other date/time utils. Any time
|
|
39
|
+
* a new Date object is constructed, it will use this value to adjust the time by this offset (to
|
|
40
|
+
* make it consistent with a known time)
|
|
36
41
|
*/
|
|
37
42
|
let clockOffset = 0;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
*
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* When a GroupAssessment comes in the door, it includes the current UTC datetime. This method is
|
|
46
|
+
* used to update the difference between the (accurate) server time and the browser time
|
|
41
47
|
*/
|
|
42
48
|
const setClockOffset = function (offset) {
|
|
43
|
-
|
|
49
|
+
clockOffset = offset;
|
|
44
50
|
};
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Get the current UTC time, calibrated to the API server's clock
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Get the current UTC time, calibrated to the API server's clock
|
|
48
54
|
*/
|
|
55
|
+
exports.setClockOffset = setClockOffset;
|
|
49
56
|
const getServerNowUtc = function () {
|
|
50
|
-
|
|
57
|
+
return new Date(Date.now() + clockOffset);
|
|
51
58
|
};
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* Return the provided date, offset by the clockOffset
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Return the provided date, offset by the clockOffset
|
|
55
62
|
*/
|
|
56
|
-
|
|
57
|
-
|
|
63
|
+
exports.getServerNowUtc = getServerNowUtc;
|
|
64
|
+
const getOffsetDate = date => {
|
|
65
|
+
return new Date(date.getTime() + clockOffset);
|
|
58
66
|
};
|
|
59
67
|
exports.getOffsetDate = getOffsetDate;
|
|
60
|
-
const getZonedMomentFromUtc =
|
|
61
|
-
|
|
68
|
+
const getZonedMomentFromUtc = function () {
|
|
69
|
+
let dateTimeUtc = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getServerNowUtc().toISOString();
|
|
70
|
+
let timeZoneId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : (0, _timezone.guessTimeZoneId)();
|
|
71
|
+
return _momentTimezone.default.utc(dateTimeUtc).tz(timeZoneId);
|
|
62
72
|
};
|
|
63
73
|
exports.getZonedMomentFromUtc = getZonedMomentFromUtc;
|
|
64
|
-
const getZonedMomentFromUtcInDefaultZone =
|
|
65
|
-
|
|
66
|
-
|
|
74
|
+
const getZonedMomentFromUtcInDefaultZone = function () {
|
|
75
|
+
let dateTimeUtc = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getServerNowUtc().toISOString();
|
|
76
|
+
const timeZoneId = (0, _timezone.getDefaultTimeZoneId)();
|
|
77
|
+
return getZonedMomentFromUtc(dateTimeUtc, timeZoneId);
|
|
67
78
|
};
|
|
68
79
|
exports.getZonedMomentFromUtcInDefaultZone = getZonedMomentFromUtcInDefaultZone;
|
|
69
|
-
const getZonedMomentFromLocalDateTime = (localDateTime
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
localMoment.date(),
|
|
75
|
-
localMoment.hour(),
|
|
76
|
-
localMoment.minute(),
|
|
77
|
-
localMoment.second(),
|
|
78
|
-
localMoment.millisecond()
|
|
79
|
-
], timeZoneId);
|
|
80
|
-
return zonedMoment;
|
|
80
|
+
const getZonedMomentFromLocalDateTime = function (localDateTime) {
|
|
81
|
+
let timeZoneId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : (0, _timezone.guessTimeZoneId)();
|
|
82
|
+
const localMoment = (0, _momentTimezone.default)(localDateTime);
|
|
83
|
+
const zonedMoment = _momentTimezone.default.tz([localMoment.year(), localMoment.month(), localMoment.date(), localMoment.hour(), localMoment.minute(), localMoment.second(), localMoment.millisecond()], timeZoneId);
|
|
84
|
+
return zonedMoment;
|
|
81
85
|
};
|
|
82
86
|
exports.getZonedMomentFromLocalDateTime = getZonedMomentFromLocalDateTime;
|
|
83
|
-
const getLocalMomentFromUtc =
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
zonedMoment.hour(),
|
|
90
|
-
zonedMoment.minute(),
|
|
91
|
-
zonedMoment.second(),
|
|
92
|
-
zonedMoment.millisecond()
|
|
93
|
-
]);
|
|
94
|
-
return localMoment;
|
|
87
|
+
const getLocalMomentFromUtc = function () {
|
|
88
|
+
let dateTimeUtc = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getServerNowUtc().toISOString();
|
|
89
|
+
let timeZoneId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : (0, _timezone.guessTimeZoneId)();
|
|
90
|
+
const zonedMoment = getZonedMomentFromUtc(dateTimeUtc, timeZoneId);
|
|
91
|
+
const localMoment = (0, _momentTimezone.default)([zonedMoment.year(), zonedMoment.month(), zonedMoment.date(), zonedMoment.hour(), zonedMoment.minute(), zonedMoment.second(), zonedMoment.millisecond()]);
|
|
92
|
+
return localMoment;
|
|
95
93
|
};
|
|
96
94
|
exports.getLocalMomentFromUtc = getLocalMomentFromUtc;
|
|
97
|
-
const getLocalDateTimeFromUtc =
|
|
98
|
-
|
|
95
|
+
const getLocalDateTimeFromUtc = dateTimeUtc => {
|
|
96
|
+
return getLocalMomentFromUtc(dateTimeUtc).toDate();
|
|
99
97
|
};
|
|
100
98
|
exports.getLocalDateTimeFromUtc = getLocalDateTimeFromUtc;
|
|
101
|
-
const getDateMinusTime =
|
|
102
|
-
|
|
99
|
+
const getDateMinusTime = dateTime => {
|
|
100
|
+
return new Date(dateTime.getFullYear(), dateTime.getMonth(), dateTime.getDate());
|
|
103
101
|
};
|
|
104
102
|
exports.getDateMinusTime = getDateMinusTime;
|
|
105
103
|
function getEndOfDay(dateTimeUtc) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
.add(1, 'days')
|
|
109
|
-
.subtract(3, 'milliseconds') // must be minus 3 for SQL date
|
|
110
|
-
.toDate();
|
|
104
|
+
return (0, _momentTimezone.default)(dateTimeUtc).startOf('day').add(1, 'days').subtract(3, 'milliseconds') // must be minus 3 for SQL date
|
|
105
|
+
.toDate();
|
|
111
106
|
}
|
|
112
107
|
function getEndOfMinute(dateTimeUtc) {
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
.add(1, 'minute')
|
|
116
|
-
.subtract(3, 'milliseconds') // must be minus 3 for SQL date
|
|
117
|
-
.toDate();
|
|
108
|
+
return (0, _momentTimezone.default)(dateTimeUtc).startOf('minute').add(1, 'minute').subtract(3, 'milliseconds') // must be minus 3 for SQL date
|
|
109
|
+
.toDate();
|
|
118
110
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
* @param
|
|
124
|
-
*
|
|
125
|
-
*
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Is the current time, "now", **after or equal to** the given date.
|
|
114
|
+
*
|
|
115
|
+
* @param dateTimeUtc The date to compare the current time, "now", as an ISO date string.
|
|
116
|
+
* @param nowUtc Optional. The current time, "now", as an ISO date string.
|
|
117
|
+
*
|
|
118
|
+
* @returns Whether or not "now" is **after or equal to** `dateTimeUtc`
|
|
126
119
|
*/
|
|
127
|
-
function isNowEqualOrAfterDate(dateTimeUtc
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
120
|
+
function isNowEqualOrAfterDate(dateTimeUtc) {
|
|
121
|
+
let nowUtc = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getServerNowUtc().toISOString();
|
|
122
|
+
if (!dateTimeUtc) {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
const adjustedDateTimeMoment = getLocalMomentFromUtc(dateTimeUtc);
|
|
126
|
+
const currentMoment = getLocalMomentFromUtc(nowUtc);
|
|
127
|
+
return currentMoment.isSameOrAfter(adjustedDateTimeMoment);
|
|
134
128
|
}
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
* @param
|
|
140
|
-
*
|
|
141
|
-
*
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Is the current time, "now", **before or equal to** the given date.
|
|
132
|
+
*
|
|
133
|
+
* @param dateTimeUtc The date to compare the current time, "now", as an ISO date string.
|
|
134
|
+
* @param nowUtc Optional. The current time, "now", as an ISO date string.
|
|
135
|
+
*
|
|
136
|
+
* @returns Whether or not "now" is **before or equal to** `dateTimeUtc`.
|
|
142
137
|
*/
|
|
143
|
-
function isNowEqualOrBeforeDate(dateTimeUtc
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
138
|
+
function isNowEqualOrBeforeDate(dateTimeUtc) {
|
|
139
|
+
let nowUtc = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getServerNowUtc().toISOString();
|
|
140
|
+
if (!dateTimeUtc) {
|
|
141
|
+
return false;
|
|
142
|
+
}
|
|
143
|
+
const adjustedDateTimeMoment = getLocalMomentFromUtc(dateTimeUtc);
|
|
144
|
+
const currentMoment = getLocalMomentFromUtc(nowUtc);
|
|
145
|
+
return currentMoment.isSameOrBefore(adjustedDateTimeMoment);
|
|
150
146
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
*
|
|
154
|
-
*
|
|
155
|
-
* @param
|
|
156
|
-
*
|
|
157
|
-
*
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Is the current time, "now", **after** the given date.
|
|
150
|
+
*
|
|
151
|
+
* @param dateTimeUtc The date to compare the current time, "now", as an ISO date string.
|
|
152
|
+
* @param nowUtc Optional. The current time, "now", as an ISO date string.
|
|
153
|
+
*
|
|
154
|
+
* @returns Whether or not "now" is **after** `dateTimeUtc`.
|
|
158
155
|
*/
|
|
159
|
-
function isNowAfterDate(dateTimeUtc
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
156
|
+
function isNowAfterDate(dateTimeUtc) {
|
|
157
|
+
let nowUtc = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getServerNowUtc().toISOString();
|
|
158
|
+
if (!dateTimeUtc) {
|
|
159
|
+
return false;
|
|
160
|
+
}
|
|
161
|
+
const adjustedDateTimeMoment = getLocalMomentFromUtc(dateTimeUtc);
|
|
162
|
+
const currentMoment = getLocalMomentFromUtc(nowUtc);
|
|
163
|
+
return currentMoment > adjustedDateTimeMoment;
|
|
166
164
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
*
|
|
170
|
-
*
|
|
171
|
-
* @param
|
|
172
|
-
*
|
|
173
|
-
*
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Is the current time, "now", **before** the given date.
|
|
168
|
+
*
|
|
169
|
+
* @param dateTimeUtc The date to compare the current time, "now", as an ISO date string.
|
|
170
|
+
* @param nowUtc Optional. The current time, "now", as an ISO date string.
|
|
171
|
+
*
|
|
172
|
+
* @returns Whether or not "now" is **before** `dateTimeUtc`.
|
|
174
173
|
*/
|
|
175
|
-
function isNowBeforeDate(dateTimeUtc
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
174
|
+
function isNowBeforeDate(dateTimeUtc) {
|
|
175
|
+
let nowUtc = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getServerNowUtc().toISOString();
|
|
176
|
+
if (!dateTimeUtc) {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
const adjustedDateTimeMoment = getLocalMomentFromUtc(dateTimeUtc);
|
|
180
|
+
const currentMoment = getLocalMomentFromUtc(nowUtc);
|
|
181
|
+
return currentMoment < adjustedDateTimeMoment;
|
|
182
182
|
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
*
|
|
186
|
-
* @param
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Returns a date and time string with full date, e.g. `March 5, 2018 @ 4:05 PM EDT`
|
|
186
|
+
* @param dateTimeUtc A UTC date time string
|
|
187
|
+
* @param withTimeZone (optional) Whether to include the time zone abbreviation. Defaults to `true`.
|
|
187
188
|
*/
|
|
188
|
-
function getFormattedFullDateAndTime(dateTimeUtc
|
|
189
|
-
|
|
189
|
+
function getFormattedFullDateAndTime(dateTimeUtc) {
|
|
190
|
+
let withTimeZone = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
191
|
+
return applyFormat(dateTimeUtc, `MMMM D, YYYY @ h:mm\u00a0A${withTimeZone ? ' z' : ''}`);
|
|
190
192
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
*
|
|
194
|
-
* @param
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Returns a date and time string with day of week and American slash dates, e.g. `Mon, 3/5/2018 @ 4:05 PM EDT`
|
|
196
|
+
* @param dateTimeUtc A UTC date time string
|
|
197
|
+
* @param withTimeZone (optional) Whether to include the time zone abbreviation. Defaults to `true`.
|
|
195
198
|
*/
|
|
196
|
-
function getFormattedFullDateWithWeek(dateTimeUtc
|
|
197
|
-
|
|
199
|
+
function getFormattedFullDateWithWeek(dateTimeUtc) {
|
|
200
|
+
let withTimeZone = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
201
|
+
return applyFormat(dateTimeUtc, `ddd, M/D/YYYY @ h:mm\u00a0A${withTimeZone ? ' z' : ''}`);
|
|
198
202
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
*
|
|
202
|
-
* @param
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Returns a date and time string with American slash dates, and no leading zeroes, e.g. `3/5/18 4:05 PM EDT`
|
|
206
|
+
* @param dateTimeUtc A UTC date time string
|
|
207
|
+
* @param withTimeZone (optional) Whether to include the time zone abbreviation. Defaults to `true`.
|
|
203
208
|
*/
|
|
204
|
-
function getFormattedNumberedDateAndTime(dateTimeUtc
|
|
205
|
-
|
|
209
|
+
function getFormattedNumberedDateAndTime(dateTimeUtc) {
|
|
210
|
+
let withTimeZone = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
211
|
+
return applyFormat(dateTimeUtc, `M/D/YY h:mm\u00a0A${withTimeZone ? ' z' : ''}`);
|
|
206
212
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
*
|
|
210
|
-
* @param
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Returns a date and time string with American slash dates, no leading zeroes, and no year, e.g. `3/5 4:05 PM EDT`
|
|
216
|
+
* @param dateTimeUtc A UTC date time string
|
|
217
|
+
* @param withTimeZone (optional) Whether to include the time zone abbreviation. Defaults to `true`.
|
|
211
218
|
*/
|
|
212
|
-
function getFormattedNumberedDateAndTimeWithoutYear(dateTimeUtc
|
|
213
|
-
|
|
219
|
+
function getFormattedNumberedDateAndTimeWithoutYear(dateTimeUtc) {
|
|
220
|
+
let withTimeZone = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
221
|
+
return applyFormat(dateTimeUtc, `M/D h:mm\u00a0A${withTimeZone ? ' z' : ''}`);
|
|
214
222
|
}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
*
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Returns a date string with short month and full year, e.g. `Mar 5, 2018`
|
|
226
|
+
* @param dateTimeUtc A UTC date time string
|
|
218
227
|
*/
|
|
219
228
|
function getFormattedSimplifiedDate(dateTimeUtc) {
|
|
220
|
-
|
|
229
|
+
return applyFormat(dateTimeUtc, 'MMM D, YYYY');
|
|
221
230
|
}
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
*
|
|
231
|
+
|
|
232
|
+
/**
|
|
233
|
+
* Returns a date string with short month and no year, e.g. `Mar 5`
|
|
234
|
+
* @param dateTimeUtc A UTC date time string
|
|
225
235
|
*/
|
|
226
236
|
function getFormattedSimplifiedDateWithoutYear(dateTimeUtc) {
|
|
227
|
-
|
|
237
|
+
return applyFormat(dateTimeUtc, 'MMM D');
|
|
228
238
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
*
|
|
232
|
-
* @param
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Returns a date string as either 'MMM D, YYYY' or 'MMM D' if the date's year is the same as the current year
|
|
242
|
+
* @param dateTimeUtc A UTC date time string
|
|
243
|
+
* @param nowUtc (optional) A UTC date time string of "now". Used for testing.
|
|
233
244
|
*/
|
|
234
|
-
function getFormattedSimplifiedDateWithYearIfNotCurrent(dateTimeUtc
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
: getFormattedSimplifiedDate(dateTimeUtc);
|
|
245
|
+
function getFormattedSimplifiedDateWithYearIfNotCurrent(dateTimeUtc) {
|
|
246
|
+
let nowUtc = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : getServerNowUtc().toISOString();
|
|
247
|
+
const nowUtcMoment = (0, _momentTimezone.default)(nowUtc);
|
|
248
|
+
const dateTimeMoment = (0, _momentTimezone.default)(dateTimeUtc);
|
|
249
|
+
return Math.abs(nowUtcMoment.year() - dateTimeMoment.year()) === 0 ? getFormattedSimplifiedDateWithoutYear(dateTimeUtc) : getFormattedSimplifiedDate(dateTimeUtc);
|
|
240
250
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
*
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Returns a date string with American slash dates, no leading zeroes, and short year, e.g. `3/5/18`
|
|
254
|
+
* @param dateTimeUtc A UTC date time string
|
|
244
255
|
*/
|
|
245
256
|
function getFormattedNumberedDate(dateTimeUtc) {
|
|
246
|
-
|
|
257
|
+
return applyFormat(dateTimeUtc, 'M/D/YY');
|
|
247
258
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
*
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Returns a date string with American slash dates, no leading zeroes, and full year, e.g. `3/5/2018`
|
|
262
|
+
* @param dateTimeUtc A UTC date time string
|
|
251
263
|
*/
|
|
252
264
|
function getFormattedNumberedDateWithFullYear(dateTimeUtc) {
|
|
253
|
-
|
|
265
|
+
return applyFormat(dateTimeUtc, 'M/D/YYYY');
|
|
254
266
|
}
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
*
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Returns a date string for use in HTML inputs, e.g. `2018-03-05`
|
|
270
|
+
* @param dateTimeUtc A UTC date time string
|
|
258
271
|
*/
|
|
259
272
|
function getFormattedNumberedDateForInput(dateTimeUtc) {
|
|
260
|
-
|
|
273
|
+
return applyFormat(dateTimeUtc, 'YYYY-MM-DD');
|
|
261
274
|
}
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
*
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Returns a date string with American slash dates and no year and no leading zeroes, e.g. `3/5`
|
|
278
|
+
* @param dateTimeUtc A UTC date time string
|
|
265
279
|
*/
|
|
266
280
|
function getFormattedNumberedDateWithoutYear(dateTimeUtc) {
|
|
267
|
-
|
|
281
|
+
return applyFormat(dateTimeUtc, 'M/D');
|
|
268
282
|
}
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
*
|
|
272
|
-
* @param
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Returns a time string, e.g. `4:05 PM EDT`
|
|
286
|
+
* @param dateTimeUtc A UTC date time string
|
|
287
|
+
* @param withTimeZone (optional) Whether to include the time zone abbreviation. Defaults to `true`.
|
|
273
288
|
*/
|
|
274
|
-
function getFormattedNumberedTime(dateTimeUtc
|
|
275
|
-
|
|
289
|
+
function getFormattedNumberedTime(dateTimeUtc) {
|
|
290
|
+
let withTimeZone = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
|
|
291
|
+
return applyFormat(dateTimeUtc, `h:mm\u00a0A${withTimeZone ? ' z' : ''}`);
|
|
276
292
|
}
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
*
|
|
280
|
-
* @param
|
|
281
|
-
* @param
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Returns a time string with possibly full time zone name, e.g. `4:05 PM EDT` or `4:05 PM CST (Asia/Taipei)`
|
|
296
|
+
* @param dateTimeUtc A UTC date time string
|
|
297
|
+
* @param showEasternZoneId (optional) Whether or not to include the timeZoneId in the result for EST/EDT. Defaults to `false`.
|
|
298
|
+
* @param timeZoneId (optional) A time zone Id. Defaults to the current time zone id, using `guessTimeZoneId()`.
|
|
282
299
|
*/
|
|
283
|
-
function getFormattedNumberedTimeWithFullZone(dateTimeUtc
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
300
|
+
function getFormattedNumberedTimeWithFullZone(dateTimeUtc) {
|
|
301
|
+
let showEasternZoneId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
302
|
+
let timeZoneId = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : (0, _timezone.guessTimeZoneId)();
|
|
303
|
+
const zonedMoment = getZonedMomentFromUtc(dateTimeUtc, timeZoneId);
|
|
304
|
+
const time = applyFormat(dateTimeUtc, 'h:mm\u00a0A', timeZoneId);
|
|
305
|
+
const timezoneAbbreviation = zonedMoment.zoneAbbr();
|
|
306
|
+
return (timezoneAbbreviation === 'EDT' || timezoneAbbreviation === 'EST') && !showEasternZoneId ?
|
|
307
|
+
// Don't show the full zone name if in EDT or EST, unless told to
|
|
308
|
+
`${time} ${timezoneAbbreviation}` :
|
|
309
|
+
// If not EDT or EST, show the zone name, replacing underscores with spaces
|
|
310
|
+
// Ex: "Asia/Taipei"
|
|
311
|
+
`${time} ${timezoneAbbreviation} (${timeZoneId.replace('_', ' ')})`;
|
|
293
312
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
*
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* Returns a time string without time zone, e.g. `4:05 PM`
|
|
316
|
+
* @param dateTimeUtc A UTC date time string
|
|
297
317
|
*/
|
|
298
318
|
function getFormattedNumberedTimeWithoutZone(dateTimeUtc) {
|
|
299
|
-
|
|
319
|
+
return applyFormat(dateTimeUtc, 'h:mm\u00a0A');
|
|
300
320
|
}
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
*
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Returns a time string without time zone, in 24 hr time, e.g. `16:05`
|
|
324
|
+
* @param dateTimeUtc A UTC date time string
|
|
304
325
|
*/
|
|
305
326
|
function getFormattedNumberedTimeWithoutZoneOrMeridian(dateTimeUtc) {
|
|
306
|
-
|
|
327
|
+
return applyFormat(dateTimeUtc, 'HH:mm');
|
|
307
328
|
}
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
*
|
|
311
|
-
*
|
|
312
|
-
*
|
|
313
|
-
*
|
|
314
|
-
*
|
|
315
|
-
*
|
|
316
|
-
* @param
|
|
317
|
-
* @param
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Returns a full formatted time zone string for the given `timeZoneId`.
|
|
332
|
+
*
|
|
333
|
+
* Combines all possible abbreviations for the zone and the timeZoneId, e.g. `EST/EDT`, `PST/PDT (America/Los Angeles)` or `CST (Asia/Taipei)`
|
|
334
|
+
*
|
|
335
|
+
* If abbreviations are not alpha characters, e.g. `-04`, then only the timeZoneId is returned.
|
|
336
|
+
*
|
|
337
|
+
* @param timeZoneId (optional) A time zone Id. Defaults to the current time zone id, using `guessTimeZoneId()`.
|
|
338
|
+
* @param showEasternZoneId (optional) Whether or not to include the timeZoneId in the result for EST/EDT. Defaults to `false`.
|
|
339
|
+
* @param nowUtc (optional) The current time, "now", as an ISO date string.
|
|
318
340
|
*/
|
|
319
|
-
function getFullFormattedTimeZone(
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
`${abbreviationsString} (${readableZoneId})`;
|
|
341
|
+
function getFullFormattedTimeZone() {
|
|
342
|
+
let timeZoneId = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : (0, _timezone.guessTimeZoneId)();
|
|
343
|
+
let showEasternZoneId = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
344
|
+
let nowUtc = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : getServerNowUtc().toISOString();
|
|
345
|
+
const zone = _momentTimezone.default.tz.zone(timeZoneId);
|
|
346
|
+
if (!zone) return '';
|
|
347
|
+
const zonedMoment = getZonedMomentFromUtc(nowUtc, timeZoneId);
|
|
348
|
+
// filter the zone data down to just recent years, instead of the default of 1900 to 2038
|
|
349
|
+
const filteredZone = _momentTimezoneUtils.default.tz.filterYears(zone, zonedMoment.year() - 1, zonedMoment.year() + 1);
|
|
350
|
+
// find all unique abbreviations for the zone, combined into a string
|
|
351
|
+
const abbreviations = filteredZone.abbrs
|
|
352
|
+
// filter out non-alpha abbreviations
|
|
353
|
+
.filter(abbr => /[a-zA-Z]+/g.test(abbr)).reduce((uniqueAbbrs, abbr) => {
|
|
354
|
+
if (!uniqueAbbrs.includes(abbr)) {
|
|
355
|
+
uniqueAbbrs.push(abbr);
|
|
356
|
+
}
|
|
357
|
+
return uniqueAbbrs;
|
|
358
|
+
}, []);
|
|
359
|
+
const abbreviationsString = abbreviations.length > 0 ? abbreviations.join('/') : null;
|
|
360
|
+
const readableZoneId = timeZoneId.replace('_', ' ');
|
|
361
|
+
return !abbreviationsString ? readableZoneId : abbreviationsString === 'EST/EDT' && !showEasternZoneId ?
|
|
362
|
+
// Don't show the zoneId if in Eastern, unless told to
|
|
363
|
+
abbreviationsString :
|
|
364
|
+
// Show the combined abbreviations plus the friendly zoneId
|
|
365
|
+
`${abbreviationsString} (${readableZoneId})`;
|
|
345
366
|
}
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
*
|
|
349
|
-
*
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Returns the basic time zone abbreviation for the given date, e.g. `EDT`.
|
|
370
|
+
*
|
|
371
|
+
* @param dateTimeUtc The date to format.
|
|
350
372
|
*/
|
|
351
373
|
function getFormattedTimeZone(dateTimeUtc) {
|
|
352
|
-
|
|
374
|
+
return applyFormat(dateTimeUtc, 'z');
|
|
353
375
|
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
*
|
|
357
|
-
* @param {*}
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Formats a date using the given format. Parses the date as UTC, then converts to the current time zone, then formats.
|
|
379
|
+
* @param {*} dateTimeUtc The date to format. Any valid input for `moment.utc(...)`
|
|
380
|
+
* @param {*} format The format to use
|
|
358
381
|
*/
|
|
359
|
-
function applyFormat(dateTimeUtc, format
|
|
360
|
-
|
|
382
|
+
function applyFormat(dateTimeUtc, format) {
|
|
383
|
+
let timeZoneId = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : (0, _timezone.guessTimeZoneId)();
|
|
384
|
+
return getZonedMomentFromUtc(dateTimeUtc, timeZoneId).format(format);
|
|
361
385
|
}
|
|
362
|
-
const isInputTypeSupported =
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
}
|
|
386
|
+
const isInputTypeSupported = type => {
|
|
387
|
+
try {
|
|
388
|
+
const test = document.createElement('input');
|
|
389
|
+
test.type = type;
|
|
390
|
+
const isSupported = test.type === type;
|
|
391
|
+
return isSupported;
|
|
392
|
+
} catch {
|
|
393
|
+
return false;
|
|
394
|
+
}
|
|
372
395
|
};
|
|
373
|
-
exports.isDateInputSupported = isInputTypeSupported('date');
|
|
374
|
-
exports.isTimeInputSupported = isInputTypeSupported('time');
|
|
396
|
+
const isDateInputSupported = exports.isDateInputSupported = isInputTypeSupported('date');
|
|
397
|
+
const isTimeInputSupported = exports.isTimeInputSupported = isInputTypeSupported('time');
|
|
375
398
|
function isDateTimeValid(dateTime) {
|
|
376
|
-
|
|
399
|
+
return !!dateTime && (0, _momentTimezone.default)(dateTime).isValid();
|
|
377
400
|
}
|
|
401
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfbW9tZW50VGltZXpvbmUiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwicmVxdWlyZSIsIl9tb21lbnRUaW1lem9uZVV0aWxzIiwiX3RpbWV6b25lIiwiY2xvY2tPZmZzZXQiLCJzZXRDbG9ja09mZnNldCIsIm9mZnNldCIsImV4cG9ydHMiLCJnZXRTZXJ2ZXJOb3dVdGMiLCJEYXRlIiwibm93IiwiZ2V0T2Zmc2V0RGF0ZSIsImRhdGUiLCJnZXRUaW1lIiwiZ2V0Wm9uZWRNb21lbnRGcm9tVXRjIiwiZGF0ZVRpbWVVdGMiLCJhcmd1bWVudHMiLCJsZW5ndGgiLCJ1bmRlZmluZWQiLCJ0b0lTT1N0cmluZyIsInRpbWVab25lSWQiLCJndWVzc1RpbWVab25lSWQiLCJtb21lbnQiLCJ1dGMiLCJ0eiIsImdldFpvbmVkTW9tZW50RnJvbVV0Y0luRGVmYXVsdFpvbmUiLCJnZXREZWZhdWx0VGltZVpvbmVJZCIsImdldFpvbmVkTW9tZW50RnJvbUxvY2FsRGF0ZVRpbWUiLCJsb2NhbERhdGVUaW1lIiwibG9jYWxNb21lbnQiLCJ6b25lZE1vbWVudCIsInllYXIiLCJtb250aCIsImhvdXIiLCJtaW51dGUiLCJzZWNvbmQiLCJtaWxsaXNlY29uZCIsImdldExvY2FsTW9tZW50RnJvbVV0YyIsImdldExvY2FsRGF0ZVRpbWVGcm9tVXRjIiwidG9EYXRlIiwiZ2V0RGF0ZU1pbnVzVGltZSIsImRhdGVUaW1lIiwiZ2V0RnVsbFllYXIiLCJnZXRNb250aCIsImdldERhdGUiLCJnZXRFbmRPZkRheSIsInN0YXJ0T2YiLCJhZGQiLCJzdWJ0cmFjdCIsImdldEVuZE9mTWludXRlIiwiaXNOb3dFcXVhbE9yQWZ0ZXJEYXRlIiwibm93VXRjIiwiYWRqdXN0ZWREYXRlVGltZU1vbWVudCIsImN1cnJlbnRNb21lbnQiLCJpc1NhbWVPckFmdGVyIiwiaXNOb3dFcXVhbE9yQmVmb3JlRGF0ZSIsImlzU2FtZU9yQmVmb3JlIiwiaXNOb3dBZnRlckRhdGUiLCJpc05vd0JlZm9yZURhdGUiLCJnZXRGb3JtYXR0ZWRGdWxsRGF0ZUFuZFRpbWUiLCJ3aXRoVGltZVpvbmUiLCJhcHBseUZvcm1hdCIsImdldEZvcm1hdHRlZEZ1bGxEYXRlV2l0aFdlZWsiLCJnZXRGb3JtYXR0ZWROdW1iZXJlZERhdGVBbmRUaW1lIiwiZ2V0Rm9ybWF0dGVkTnVtYmVyZWREYXRlQW5kVGltZVdpdGhvdXRZZWFyIiwiZ2V0Rm9ybWF0dGVkU2ltcGxpZmllZERhdGUiLCJnZXRGb3JtYXR0ZWRTaW1wbGlmaWVkRGF0ZVdpdGhvdXRZZWFyIiwiZ2V0Rm9ybWF0dGVkU2ltcGxpZmllZERhdGVXaXRoWWVhcklmTm90Q3VycmVudCIsIm5vd1V0Y01vbWVudCIsImRhdGVUaW1lTW9tZW50IiwiTWF0aCIsImFicyIsImdldEZvcm1hdHRlZE51bWJlcmVkRGF0ZSIsImdldEZvcm1hdHRlZE51bWJlcmVkRGF0ZVdpdGhGdWxsWWVhciIsImdldEZvcm1hdHRlZE51bWJlcmVkRGF0ZUZvcklucHV0IiwiZ2V0Rm9ybWF0dGVkTnVtYmVyZWREYXRlV2l0aG91dFllYXIiLCJnZXRGb3JtYXR0ZWROdW1iZXJlZFRpbWUiLCJnZXRGb3JtYXR0ZWROdW1iZXJlZFRpbWVXaXRoRnVsbFpvbmUiLCJzaG93RWFzdGVyblpvbmVJZCIsInRpbWUiLCJ0aW1lem9uZUFiYnJldmlhdGlvbiIsInpvbmVBYmJyIiwicmVwbGFjZSIsImdldEZvcm1hdHRlZE51bWJlcmVkVGltZVdpdGhvdXRab25lIiwiZ2V0Rm9ybWF0dGVkTnVtYmVyZWRUaW1lV2l0aG91dFpvbmVPck1lcmlkaWFuIiwiZ2V0RnVsbEZvcm1hdHRlZFRpbWVab25lIiwiem9uZSIsImZpbHRlcmVkWm9uZSIsIm1vbWVudFV0aWxzIiwiZmlsdGVyWWVhcnMiLCJhYmJyZXZpYXRpb25zIiwiYWJicnMiLCJmaWx0ZXIiLCJhYmJyIiwidGVzdCIsInJlZHVjZSIsInVuaXF1ZUFiYnJzIiwiaW5jbHVkZXMiLCJwdXNoIiwiYWJicmV2aWF0aW9uc1N0cmluZyIsImpvaW4iLCJyZWFkYWJsZVpvbmVJZCIsImdldEZvcm1hdHRlZFRpbWVab25lIiwiZm9ybWF0IiwiaXNJbnB1dFR5cGVTdXBwb3J0ZWQiLCJ0eXBlIiwiZG9jdW1lbnQiLCJjcmVhdGVFbGVtZW50IiwiaXNTdXBwb3J0ZWQiLCJpc0RhdGVJbnB1dFN1cHBvcnRlZCIsImlzVGltZUlucHV0U3VwcG9ydGVkIiwiaXNEYXRlVGltZVZhbGlkIiwiaXNWYWxpZCJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9kYXRlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBtb21lbnQgZnJvbSAnbW9tZW50LXRpbWV6b25lJ1xyXG5pbXBvcnQgbW9tZW50VXRpbHMgZnJvbSAnbW9tZW50LXRpbWV6b25lL21vbWVudC10aW1lem9uZS11dGlscydcclxuaW1wb3J0IHsgZ2V0RGVmYXVsdFRpbWVab25lSWQsIGd1ZXNzVGltZVpvbmVJZCB9IGZyb20gJy4vdGltZXpvbmUnXHJcblxyXG4vKipcclxuICogVGhpcyB2YWx1ZSBpcyB1c2VkIGJ5IHRpbWUtc2Vuc2l0aXZlIGZ1bmN0aW9ucyBpbiB0aGlzIG1vZHVsZSBhbmQgb3RoZXIgZGF0ZS90aW1lIHV0aWxzLiBBbnkgdGltZVxyXG4gKiBhIG5ldyBEYXRlIG9iamVjdCBpcyBjb25zdHJ1Y3RlZCwgaXQgd2lsbCB1c2UgdGhpcyB2YWx1ZSB0byBhZGp1c3QgdGhlIHRpbWUgYnkgdGhpcyBvZmZzZXQgKHRvXHJcbiAqIG1ha2UgaXQgY29uc2lzdGVudCB3aXRoIGEga25vd24gdGltZSlcclxuICovXHJcbmxldCBjbG9ja09mZnNldCA9IDBcclxuXHJcbi8qKlxyXG4gKiBXaGVuIGEgR3JvdXBBc3Nlc3NtZW50IGNvbWVzIGluIHRoZSBkb29yLCBpdCBpbmNsdWRlcyB0aGUgY3VycmVudCBVVEMgZGF0ZXRpbWUuIFRoaXMgbWV0aG9kIGlzXHJcbiAqIHVzZWQgdG8gdXBkYXRlIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gdGhlIChhY2N1cmF0ZSkgc2VydmVyIHRpbWUgYW5kIHRoZSBicm93c2VyIHRpbWVcclxuICovXHJcbmV4cG9ydCBjb25zdCBzZXRDbG9ja09mZnNldCA9IGZ1bmN0aW9uIChvZmZzZXQ6IG51bWJlcikge1xyXG5cdGNsb2NrT2Zmc2V0ID0gb2Zmc2V0XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZXQgdGhlIGN1cnJlbnQgVVRDIHRpbWUsIGNhbGlicmF0ZWQgdG8gdGhlIEFQSSBzZXJ2ZXIncyBjbG9ja1xyXG4gKi9cclxuZXhwb3J0IGNvbnN0IGdldFNlcnZlck5vd1V0YyA9IGZ1bmN0aW9uICgpIHtcclxuXHRyZXR1cm4gbmV3IERhdGUoRGF0ZS5ub3coKSArIGNsb2NrT2Zmc2V0KVxyXG59XHJcblxyXG4vKipcclxuICogUmV0dXJuIHRoZSBwcm92aWRlZCBkYXRlLCBvZmZzZXQgYnkgdGhlIGNsb2NrT2Zmc2V0XHJcbiAqL1xyXG5leHBvcnQgY29uc3QgZ2V0T2Zmc2V0RGF0ZSA9IChkYXRlOiBEYXRlKSA9PiB7XHJcblx0cmV0dXJuIG5ldyBEYXRlKGRhdGUuZ2V0VGltZSgpICsgY2xvY2tPZmZzZXQpXHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBnZXRab25lZE1vbWVudEZyb21VdGMgPSAoXHJcblx0ZGF0ZVRpbWVVdGMgPSBnZXRTZXJ2ZXJOb3dVdGMoKS50b0lTT1N0cmluZygpLFxyXG5cdHRpbWVab25lSWQgPSBndWVzc1RpbWVab25lSWQoKVxyXG4pID0+IHtcclxuXHRyZXR1cm4gbW9tZW50LnV0YyhkYXRlVGltZVV0YykudHoodGltZVpvbmVJZClcclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IGdldFpvbmVkTW9tZW50RnJvbVV0Y0luRGVmYXVsdFpvbmUgPSAoZGF0ZVRpbWVVdGMgPSBnZXRTZXJ2ZXJOb3dVdGMoKS50b0lTT1N0cmluZygpKSA9PiB7XHJcblx0Y29uc3QgdGltZVpvbmVJZCA9IGdldERlZmF1bHRUaW1lWm9uZUlkKClcclxuXHRyZXR1cm4gZ2V0Wm9uZWRNb21lbnRGcm9tVXRjKGRhdGVUaW1lVXRjLCB0aW1lWm9uZUlkKVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgZ2V0Wm9uZWRNb21lbnRGcm9tTG9jYWxEYXRlVGltZSA9IChsb2NhbERhdGVUaW1lOiBEYXRlIHwgc3RyaW5nLCB0aW1lWm9uZUlkID0gZ3Vlc3NUaW1lWm9uZUlkKCkpID0+IHtcclxuXHRjb25zdCBsb2NhbE1vbWVudCA9IG1vbWVudChsb2NhbERhdGVUaW1lKVxyXG5cdGNvbnN0IHpvbmVkTW9tZW50ID0gbW9tZW50LnR6KFxyXG5cdFx0W1xyXG5cdFx0XHRsb2NhbE1vbWVudC55ZWFyKCksXHJcblx0XHRcdGxvY2FsTW9tZW50Lm1vbnRoKCksXHJcblx0XHRcdGxvY2FsTW9tZW50LmRhdGUoKSxcclxuXHRcdFx0bG9jYWxNb21lbnQuaG91cigpLFxyXG5cdFx0XHRsb2NhbE1vbWVudC5taW51dGUoKSxcclxuXHRcdFx0bG9jYWxNb21lbnQuc2Vjb25kKCksXHJcblx0XHRcdGxvY2FsTW9tZW50Lm1pbGxpc2Vjb25kKClcclxuXHRcdF0sXHJcblx0XHR0aW1lWm9uZUlkXHJcblx0KVxyXG5cdHJldHVybiB6b25lZE1vbWVudFxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgZ2V0TG9jYWxNb21lbnRGcm9tVXRjID0gKFxyXG5cdGRhdGVUaW1lVXRjID0gZ2V0U2VydmVyTm93VXRjKCkudG9JU09TdHJpbmcoKSxcclxuXHR0aW1lWm9uZUlkID0gZ3Vlc3NUaW1lWm9uZUlkKClcclxuKSA9PiB7XHJcblx0Y29uc3Qgem9uZWRNb21lbnQgPSBnZXRab25lZE1vbWVudEZyb21VdGMoZGF0ZVRpbWVVdGMsIHRpbWVab25lSWQpXHJcblx0Y29uc3QgbG9jYWxNb21lbnQgPSBtb21lbnQoW1xyXG5cdFx0em9uZWRNb21lbnQueWVhcigpLFxyXG5cdFx0em9uZWRNb21lbnQubW9udGgoKSxcclxuXHRcdHpvbmVkTW9tZW50LmRhdGUoKSxcclxuXHRcdHpvbmVkTW9tZW50LmhvdXIoKSxcclxuXHRcdHpvbmVkTW9tZW50Lm1pbnV0ZSgpLFxyXG5cdFx0em9uZWRNb21lbnQuc2Vjb25kKCksXHJcblx0XHR6b25lZE1vbWVudC5taWxsaXNlY29uZCgpXHJcblx0XSlcclxuXHRyZXR1cm4gbG9jYWxNb21lbnRcclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IGdldExvY2FsRGF0ZVRpbWVGcm9tVXRjID0gKGRhdGVUaW1lVXRjOiBzdHJpbmcpID0+IHtcclxuXHRyZXR1cm4gZ2V0TG9jYWxNb21lbnRGcm9tVXRjKGRhdGVUaW1lVXRjKS50b0RhdGUoKVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgZ2V0RGF0ZU1pbnVzVGltZSA9IChkYXRlVGltZTogRGF0ZSkgPT4ge1xyXG5cdHJldHVybiBuZXcgRGF0ZShkYXRlVGltZS5nZXRGdWxsWWVhcigpLCBkYXRlVGltZS5nZXRNb250aCgpLCBkYXRlVGltZS5nZXREYXRlKCkpXHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRFbmRPZkRheShkYXRlVGltZVV0Yzogc3RyaW5nKSB7XHJcblx0cmV0dXJuIG1vbWVudChkYXRlVGltZVV0YylcclxuXHRcdC5zdGFydE9mKCdkYXknKVxyXG5cdFx0LmFkZCgxLCAnZGF5cycpXHJcblx0XHQuc3VidHJhY3QoMywgJ21pbGxpc2Vjb25kcycpIC8vIG11c3QgYmUgbWludXMgMyBmb3IgU1FMIGRhdGVcclxuXHRcdC50b0RhdGUoKVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ2V0RW5kT2ZNaW51dGUoZGF0ZVRpbWVVdGM6IHN0cmluZykge1xyXG5cdHJldHVybiBtb21lbnQoZGF0ZVRpbWVVdGMpXHJcblx0XHQuc3RhcnRPZignbWludXRlJylcclxuXHRcdC5hZGQoMSwgJ21pbnV0ZScpXHJcblx0XHQuc3VidHJhY3QoMywgJ21pbGxpc2Vjb25kcycpIC8vIG11c3QgYmUgbWludXMgMyBmb3IgU1FMIGRhdGVcclxuXHRcdC50b0RhdGUoKVxyXG59XHJcblxyXG4vKipcclxuICogSXMgdGhlIGN1cnJlbnQgdGltZSwgXCJub3dcIiwgKiphZnRlciBvciBlcXVhbCB0byoqIHRoZSBnaXZlbiBkYXRlLlxyXG4gKlxyXG4gKiBAcGFyYW0gZGF0ZVRpbWVVdGMgVGhlIGRhdGUgdG8gY29tcGFyZSB0aGUgY3VycmVudCB0aW1lLCBcIm5vd1wiLCBhcyBhbiBJU08gZGF0ZSBzdHJpbmcuXHJcbiAqIEBwYXJhbSBub3dVdGMgT3B0aW9uYWwuIFRoZSBjdXJyZW50IHRpbWUsIFwibm93XCIsIGFzIGFuIElTTyBkYXRlIHN0cmluZy5cclxuICpcclxuICogQHJldHVybnMgV2hldGhlciBvciBub3QgXCJub3dcIiBpcyAqKmFmdGVyIG9yIGVxdWFsIHRvKiogYGRhdGVUaW1lVXRjYFxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGlzTm93RXF1YWxPckFmdGVyRGF0ZShkYXRlVGltZVV0Yz86IHN0cmluZywgbm93VXRjID0gZ2V0U2VydmVyTm93VXRjKCkudG9JU09TdHJpbmcoKSkge1xyXG5cdGlmICghZGF0ZVRpbWVVdGMpIHtcclxuXHRcdHJldHVybiBmYWxzZVxyXG5cdH1cclxuXHRjb25zdCBhZGp1c3RlZERhdGVUaW1lTW9tZW50ID0gZ2V0TG9jYWxNb21lbnRGcm9tVXRjKGRhdGVUaW1lVXRjKVxyXG5cdGNvbnN0IGN1cnJlbnRNb21lbnQgPSBnZXRMb2NhbE1vbWVudEZyb21VdGMobm93VXRjKVxyXG5cdHJldHVybiBjdXJyZW50TW9tZW50LmlzU2FtZU9yQWZ0ZXIoYWRqdXN0ZWREYXRlVGltZU1vbWVudClcclxufVxyXG5cclxuLyoqXHJcbiAqIElzIHRoZSBjdXJyZW50IHRpbWUsIFwibm93XCIsICoqYmVmb3JlIG9yIGVxdWFsIHRvKiogdGhlIGdpdmVuIGRhdGUuXHJcbiAqXHJcbiAqIEBwYXJhbSBkYXRlVGltZVV0YyBUaGUgZGF0ZSB0byBjb21wYXJlIHRoZSBjdXJyZW50IHRpbWUsIFwibm93XCIsIGFzIGFuIElTTyBkYXRlIHN0cmluZy5cclxuICogQHBhcmFtIG5vd1V0YyBPcHRpb25hbC4gVGhlIGN1cnJlbnQgdGltZSwgXCJub3dcIiwgYXMgYW4gSVNPIGRhdGUgc3RyaW5nLlxyXG4gKlxyXG4gKiBAcmV0dXJucyBXaGV0aGVyIG9yIG5vdCBcIm5vd1wiIGlzICoqYmVmb3JlIG9yIGVxdWFsIHRvKiogYGRhdGVUaW1lVXRjYC5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBpc05vd0VxdWFsT3JCZWZvcmVEYXRlKGRhdGVUaW1lVXRjPzogc3RyaW5nLCBub3dVdGMgPSBnZXRTZXJ2ZXJOb3dVdGMoKS50b0lTT1N0cmluZygpKSB7XHJcblx0aWYgKCFkYXRlVGltZVV0Yykge1xyXG5cdFx0cmV0dXJuIGZhbHNlXHJcblx0fVxyXG5cdGNvbnN0IGFkanVzdGVkRGF0ZVRpbWVNb21lbnQgPSBnZXRMb2NhbE1vbWVudEZyb21VdGMoZGF0ZVRpbWVVdGMpXHJcblx0Y29uc3QgY3VycmVudE1vbWVudCA9IGdldExvY2FsTW9tZW50RnJvbVV0Yyhub3dVdGMpXHJcblx0cmV0dXJuIGN1cnJlbnRNb21lbnQuaXNTYW1lT3JCZWZvcmUoYWRqdXN0ZWREYXRlVGltZU1vbWVudClcclxufVxyXG5cclxuLyoqXHJcbiAqIElzIHRoZSBjdXJyZW50IHRpbWUsIFwibm93XCIsICoqYWZ0ZXIqKiB0aGUgZ2l2ZW4gZGF0ZS5cclxuICpcclxuICogQHBhcmFtIGRhdGVUaW1lVXRjIFRoZSBkYXRlIHRvIGNvbXBhcmUgdGhlIGN1cnJlbnQgdGltZSwgXCJub3dcIiwgYXMgYW4gSVNPIGRhdGUgc3RyaW5nLlxyXG4gKiBAcGFyYW0gbm93VXRjIE9wdGlvbmFsLiBUaGUgY3VycmVudCB0aW1lLCBcIm5vd1wiLCBhcyBhbiBJU08gZGF0ZSBzdHJpbmcuXHJcbiAqXHJcbiAqIEByZXR1cm5zIFdoZXRoZXIgb3Igbm90IFwibm93XCIgaXMgKiphZnRlcioqIGBkYXRlVGltZVV0Y2AuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gaXNOb3dBZnRlckRhdGUoZGF0ZVRpbWVVdGM/OiBzdHJpbmcsIG5vd1V0YyA9IGdldFNlcnZlck5vd1V0YygpLnRvSVNPU3RyaW5nKCkpIHtcclxuXHRpZiAoIWRhdGVUaW1lVXRjKSB7XHJcblx0XHRyZXR1cm4gZmFsc2VcclxuXHR9XHJcblx0Y29uc3QgYWRqdXN0ZWREYXRlVGltZU1vbWVudCA9IGdldExvY2FsTW9tZW50RnJvbVV0YyhkYXRlVGltZVV0YylcclxuXHRjb25zdCBjdXJyZW50TW9tZW50ID0gZ2V0TG9jYWxNb21lbnRGcm9tVXRjKG5vd1V0YylcclxuXHRyZXR1cm4gY3VycmVudE1vbWVudCA+IGFkanVzdGVkRGF0ZVRpbWVNb21lbnRcclxufVxyXG5cclxuLyoqXHJcbiAqIElzIHRoZSBjdXJyZW50IHRpbWUsIFwibm93XCIsICoqYmVmb3JlKiogdGhlIGdpdmVuIGRhdGUuXHJcbiAqXHJcbiAqIEBwYXJhbSBkYXRlVGltZVV0YyBUaGUgZGF0ZSB0byBjb21wYXJlIHRoZSBjdXJyZW50IHRpbWUsIFwibm93XCIsIGFzIGFuIElTTyBkYXRlIHN0cmluZy5cclxuICogQHBhcmFtIG5vd1V0YyBPcHRpb25hbC4gVGhlIGN1cnJlbnQgdGltZSwgXCJub3dcIiwgYXMgYW4gSVNPIGRhdGUgc3RyaW5nLlxyXG4gKlxyXG4gKiBAcmV0dXJucyBXaGV0aGVyIG9yIG5vdCBcIm5vd1wiIGlzICoqYmVmb3JlKiogYGRhdGVUaW1lVXRjYC5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBpc05vd0JlZm9yZURhdGUoZGF0ZVRpbWVVdGM/OiBzdHJpbmcsIG5vd1V0YyA9IGdldFNlcnZlck5vd1V0YygpLnRvSVNPU3RyaW5nKCkpIHtcclxuXHRpZiAoIWRhdGVUaW1lVXRjKSB7XHJcblx0XHRyZXR1cm4gZmFsc2VcclxuXHR9XHJcblx0Y29uc3QgYWRqdXN0ZWREYXRlVGltZU1vbWVudCA9IGdldExvY2FsTW9tZW50RnJvbVV0YyhkYXRlVGltZVV0YylcclxuXHRjb25zdCBjdXJyZW50TW9tZW50ID0gZ2V0TG9jYWxNb21lbnRGcm9tVXRjKG5vd1V0YylcclxuXHRyZXR1cm4gY3VycmVudE1vbWVudCA8IGFkanVzdGVkRGF0ZVRpbWVNb21lbnRcclxufVxyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgYSBkYXRlIGFuZCB0aW1lIHN0cmluZyB3aXRoIGZ1bGwgZGF0ZSwgZS5nLiBgTWFyY2ggNSwgMjAxOCBAIDQ6MDUgUE0gRURUYFxyXG4gKiBAcGFyYW0gZGF0ZVRpbWVVdGMgQSBVVEMgZGF0ZSB0aW1lIHN0cmluZ1xyXG4gKiBAcGFyYW0gd2l0aFRpbWVab25lIChvcHRpb25hbCkgV2hldGhlciB0byBpbmNsdWRlIHRoZSB0aW1lIHpvbmUgYWJicmV2aWF0aW9uLiBEZWZhdWx0cyB0byBgdHJ1ZWAuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rm9ybWF0dGVkRnVsbERhdGVBbmRUaW1lKGRhdGVUaW1lVXRjOiBzdHJpbmcsIHdpdGhUaW1lWm9uZSA9IHRydWUpIHtcclxuXHRyZXR1cm4gYXBwbHlGb3JtYXQoZGF0ZVRpbWVVdGMsIGBNTU1NIEQsIFlZWVkgQCBoOm1tXFx1MDBhMEEke3dpdGhUaW1lWm9uZSA/ICcgeicgOiAnJ31gKVxyXG59XHJcblxyXG4vKipcclxuICogUmV0dXJucyBhIGRhdGUgYW5kIHRpbWUgc3RyaW5nIHdpdGggZGF5IG9mIHdlZWsgYW5kIEFtZXJpY2FuIHNsYXNoIGRhdGVzLCBlLmcuIGBNb24sIDMvNS8yMDE4IEAgNDowNSBQTSBFRFRgXHJcbiAqIEBwYXJhbSBkYXRlVGltZVV0YyBBIFVUQyBkYXRlIHRpbWUgc3RyaW5nXHJcbiAqIEBwYXJhbSB3aXRoVGltZVpvbmUgKG9wdGlvbmFsKSBXaGV0aGVyIHRvIGluY2x1ZGUgdGhlIHRpbWUgem9uZSBhYmJyZXZpYXRpb24uIERlZmF1bHRzIHRvIGB0cnVlYC5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRGb3JtYXR0ZWRGdWxsRGF0ZVdpdGhXZWVrKGRhdGVUaW1lVXRjOiBzdHJpbmcsIHdpdGhUaW1lWm9uZSA9IHRydWUpIHtcclxuXHRyZXR1cm4gYXBwbHlGb3JtYXQoZGF0ZVRpbWVVdGMsIGBkZGQsIE0vRC9ZWVlZIEAgaDptbVxcdTAwYTBBJHt3aXRoVGltZVpvbmUgPyAnIHonIDogJyd9YClcclxufVxyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgYSBkYXRlIGFuZCB0aW1lIHN0cmluZyB3aXRoIEFtZXJpY2FuIHNsYXNoIGRhdGVzLCBhbmQgbm8gbGVhZGluZyB6ZXJvZXMsIGUuZy4gYDMvNS8xOCA0OjA1IFBNIEVEVGBcclxuICogQHBhcmFtIGRhdGVUaW1lVXRjIEEgVVRDIGRhdGUgdGltZSBzdHJpbmdcclxuICogQHBhcmFtIHdpdGhUaW1lWm9uZSAob3B0aW9uYWwpIFdoZXRoZXIgdG8gaW5jbHVkZSB0aGUgdGltZSB6b25lIGFiYnJldmlhdGlvbi4gRGVmYXVsdHMgdG8gYHRydWVgLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGdldEZvcm1hdHRlZE51bWJlcmVkRGF0ZUFuZFRpbWUoZGF0ZVRpbWVVdGM6IHN0cmluZywgd2l0aFRpbWVab25lID0gdHJ1ZSkge1xyXG5cdHJldHVybiBhcHBseUZvcm1hdChkYXRlVGltZVV0YywgYE0vRC9ZWSBoOm1tXFx1MDBhMEEke3dpdGhUaW1lWm9uZSA/ICcgeicgOiAnJ31gKVxyXG59XHJcblxyXG4vKipcclxuICogUmV0dXJucyBhIGRhdGUgYW5kIHRpbWUgc3RyaW5nIHdpdGggQW1lcmljYW4gc2xhc2ggZGF0ZXMsIG5vIGxlYWRpbmcgemVyb2VzLCBhbmQgbm8geWVhciwgZS5nLiBgMy81IDQ6MDUgUE0gRURUYFxyXG4gKiBAcGFyYW0gZGF0ZVRpbWVVdGMgQSBVVEMgZGF0ZSB0aW1lIHN0cmluZ1xyXG4gKiBAcGFyYW0gd2l0aFRpbWVab25lIChvcHRpb25hbCkgV2hldGhlciB0byBpbmNsdWRlIHRoZSB0aW1lIHpvbmUgYWJicmV2aWF0aW9uLiBEZWZhdWx0cyB0byBgdHJ1ZWAuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rm9ybWF0dGVkTnVtYmVyZWREYXRlQW5kVGltZVdpdGhvdXRZZWFyKGRhdGVUaW1lVXRjOiBzdHJpbmcsIHdpdGhUaW1lWm9uZSA9IHRydWUpIHtcclxuXHRyZXR1cm4gYXBwbHlGb3JtYXQoZGF0ZVRpbWVVdGMsIGBNL0QgaDptbVxcdTAwYTBBJHt3aXRoVGltZVpvbmUgPyAnIHonIDogJyd9YClcclxufVxyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgYSBkYXRlIHN0cmluZyB3aXRoIHNob3J0IG1vbnRoIGFuZCBmdWxsIHllYXIsIGUuZy4gYE1hciA1LCAyMDE4YFxyXG4gKiBAcGFyYW0gZGF0ZVRpbWVVdGMgQSBVVEMgZGF0ZSB0aW1lIHN0cmluZ1xyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGdldEZvcm1hdHRlZFNpbXBsaWZpZWREYXRlKGRhdGVUaW1lVXRjOiBzdHJpbmcpIHtcclxuXHRyZXR1cm4gYXBwbHlGb3JtYXQoZGF0ZVRpbWVVdGMsICdNTU0gRCwgWVlZWScpXHJcbn1cclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIGEgZGF0ZSBzdHJpbmcgd2l0aCBzaG9ydCBtb250aCBhbmQgbm8geWVhciwgZS5nLiBgTWFyIDVgXHJcbiAqIEBwYXJhbSBkYXRlVGltZVV0YyBBIFVUQyBkYXRlIHRpbWUgc3RyaW5nXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rm9ybWF0dGVkU2ltcGxpZmllZERhdGVXaXRob3V0WWVhcihkYXRlVGltZVV0Yzogc3RyaW5nKSB7XHJcblx0cmV0dXJuIGFwcGx5Rm9ybWF0KGRhdGVUaW1lVXRjLCAnTU1NIEQnKVxyXG59XHJcblxyXG4vKipcclxuICogUmV0dXJucyBhIGRhdGUgc3RyaW5nIGFzIGVpdGhlciAnTU1NIEQsIFlZWVknIG9yICdNTU0gRCcgaWYgdGhlIGRhdGUncyB5ZWFyIGlzIHRoZSBzYW1lIGFzIHRoZSBjdXJyZW50IHllYXJcclxuICogQHBhcmFtIGRhdGVUaW1lVXRjIEEgVVRDIGRhdGUgdGltZSBzdHJpbmdcclxuICogQHBhcmFtIG5vd1V0YyAob3B0aW9uYWwpIEEgVVRDIGRhdGUgdGltZSBzdHJpbmcgb2YgXCJub3dcIi4gVXNlZCBmb3IgdGVzdGluZy5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRGb3JtYXR0ZWRTaW1wbGlmaWVkRGF0ZVdpdGhZZWFySWZOb3RDdXJyZW50KFxyXG5cdGRhdGVUaW1lVXRjOiBzdHJpbmcsXHJcblx0bm93VXRjID0gZ2V0U2VydmVyTm93VXRjKCkudG9JU09TdHJpbmcoKVxyXG4pIHtcclxuXHRjb25zdCBub3dVdGNNb21lbnQgPSBtb21lbnQobm93VXRjKVxyXG5cdGNvbnN0IGRhdGVUaW1lTW9tZW50ID0gbW9tZW50KGRhdGVUaW1lVXRjKVxyXG5cdHJldHVybiBNYXRoLmFicyhub3dVdGNNb21lbnQueWVhcigpIC0gZGF0ZVRpbWVNb21lbnQueWVhcigpKSA9PT0gMFxyXG5cdFx0PyBnZXRGb3JtYXR0ZWRTaW1wbGlmaWVkRGF0ZVdpdGhvdXRZZWFyKGRhdGVUaW1lVXRjKVxyXG5cdFx0OiBnZXRGb3JtYXR0ZWRTaW1wbGlmaWVkRGF0ZShkYXRlVGltZVV0YylcclxufVxyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgYSBkYXRlIHN0cmluZyB3aXRoIEFtZXJpY2FuIHNsYXNoIGRhdGVzLCBubyBsZWFkaW5nIHplcm9lcywgYW5kIHNob3J0IHllYXIsIGUuZy4gYDMvNS8xOGBcclxuICogQHBhcmFtIGRhdGVUaW1lVXRjIEEgVVRDIGRhdGUgdGltZSBzdHJpbmdcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRGb3JtYXR0ZWROdW1iZXJlZERhdGUoZGF0ZVRpbWVVdGM6IHN0cmluZykge1xyXG5cdHJldHVybiBhcHBseUZvcm1hdChkYXRlVGltZVV0YywgJ00vRC9ZWScpXHJcbn1cclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIGEgZGF0ZSBzdHJpbmcgd2l0aCBBbWVyaWNhbiBzbGFzaCBkYXRlcywgbm8gbGVhZGluZyB6ZXJvZXMsIGFuZCBmdWxsIHllYXIsIGUuZy4gYDMvNS8yMDE4YFxyXG4gKiBAcGFyYW0gZGF0ZVRpbWVVdGMgQSBVVEMgZGF0ZSB0aW1lIHN0cmluZ1xyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGdldEZvcm1hdHRlZE51bWJlcmVkRGF0ZVdpdGhGdWxsWWVhcihkYXRlVGltZVV0Yzogc3RyaW5nKSB7XHJcblx0cmV0dXJuIGFwcGx5Rm9ybWF0KGRhdGVUaW1lVXRjLCAnTS9EL1lZWVknKVxyXG59XHJcblxyXG4vKipcclxuICogUmV0dXJucyBhIGRhdGUgc3RyaW5nIGZvciB1c2UgaW4gSFRNTCBpbnB1dHMsIGUuZy4gYDIwMTgtMDMtMDVgXHJcbiAqIEBwYXJhbSBkYXRlVGltZVV0YyBBIFVUQyBkYXRlIHRpbWUgc3RyaW5nXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rm9ybWF0dGVkTnVtYmVyZWREYXRlRm9ySW5wdXQoZGF0ZVRpbWVVdGM6IHN0cmluZykge1xyXG5cdHJldHVybiBhcHBseUZvcm1hdChkYXRlVGltZVV0YywgJ1lZWVktTU0tREQnKVxyXG59XHJcblxyXG4vKipcclxuICogUmV0dXJucyBhIGRhdGUgc3RyaW5nIHdpdGggQW1lcmljYW4gc2xhc2ggZGF0ZXMgYW5kIG5vIHllYXIgYW5kIG5vIGxlYWRpbmcgemVyb2VzLCBlLmcuIGAzLzVgXHJcbiAqIEBwYXJhbSBkYXRlVGltZVV0YyBBIFVUQyBkYXRlIHRpbWUgc3RyaW5nXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rm9ybWF0dGVkTnVtYmVyZWREYXRlV2l0aG91dFllYXIoZGF0ZVRpbWVVdGM6IHN0cmluZykge1xyXG5cdHJldHVybiBhcHBseUZvcm1hdChkYXRlVGltZVV0YywgJ00vRCcpXHJcbn1cclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIGEgdGltZSBzdHJpbmcsIGUuZy4gYDQ6MDUgUE0gRURUYFxyXG4gKiBAcGFyYW0gZGF0ZVRpbWVVdGMgQSBVVEMgZGF0ZSB0aW1lIHN0cmluZ1xyXG4gKiBAcGFyYW0gd2l0aFRpbWVab25lIChvcHRpb25hbCkgV2hldGhlciB0byBpbmNsdWRlIHRoZSB0aW1lIHpvbmUgYWJicmV2aWF0aW9uLiBEZWZhdWx0cyB0byBgdHJ1ZWAuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rm9ybWF0dGVkTnVtYmVyZWRUaW1lKGRhdGVUaW1lVXRjOiBzdHJpbmcsIHdpdGhUaW1lWm9uZSA9IHRydWUpIHtcclxuXHRyZXR1cm4gYXBwbHlGb3JtYXQoZGF0ZVRpbWVVdGMsIGBoOm1tXFx1MDBhMEEke3dpdGhUaW1lWm9uZSA/ICcgeicgOiAnJ31gKVxyXG59XHJcblxyXG4vKipcclxuICogUmV0dXJucyBhIHRpbWUgc3RyaW5nIHdpdGggcG9zc2libHkgZnVsbCB0aW1lIHpvbmUgbmFtZSwgZS5nLiBgNDowNSBQTSBFRFRgIG9yIGA0OjA1IFBNIENTVCAoQXNpYS9UYWlwZWkpYFxyXG4gKiBAcGFyYW0gZGF0ZVRpbWVVdGMgQSBVVEMgZGF0ZSB0aW1lIHN0cmluZ1xyXG4gKiBAcGFyYW0gc2hvd0Vhc3Rlcm5ab25lSWQgKG9wdGlvbmFsKSBXaGV0aGVyIG9yIG5vdCB0byBpbmNsdWRlIHRoZSB0aW1lWm9uZUlkIGluIHRoZSByZXN1bHQgZm9yIEVTVC9FRFQuIERlZmF1bHRzIHRvIGBmYWxzZWAuXHJcbiAqIEBwYXJhbSB0aW1lWm9uZUlkIChvcHRpb25hbCkgQSB0aW1lIHpvbmUgSWQuIERlZmF1bHRzIHRvIHRoZSBjdXJyZW50IHRpbWUgem9uZSBpZCwgdXNpbmcgYGd1ZXNzVGltZVpvbmVJZCgpYC5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRGb3JtYXR0ZWROdW1iZXJlZFRpbWVXaXRoRnVsbFpvbmUoXHJcblx0ZGF0ZVRpbWVVdGM6IHN0cmluZyxcclxuXHRzaG93RWFzdGVyblpvbmVJZCA9IGZhbHNlLFxyXG5cdHRpbWVab25lSWQgPSBndWVzc1RpbWVab25lSWQoKVxyXG4pIHtcclxuXHRjb25zdCB6b25lZE1vbWVudCA9IGdldFpvbmVkTW9tZW50RnJvbVV0YyhkYXRlVGltZVV0YywgdGltZVpvbmVJZClcclxuXHRjb25zdCB0aW1lID0gYXBwbHlGb3JtYXQoZGF0ZVRpbWVVdGMsICdoOm1tXFx1MDBhMEEnLCB0aW1lWm9uZUlkKVxyXG5cdGNvbnN0IHRpbWV6b25lQWJicmV2aWF0aW9uID0gem9uZWRNb21lbnQuem9uZUFiYnIoKVxyXG5cdHJldHVybiAodGltZXpvbmVBYmJyZXZpYXRpb24gPT09ICdFRFQnIHx8IHRpbWV6b25lQWJicmV2aWF0aW9uID09PSAnRVNUJykgJiYgIXNob3dFYXN0ZXJuWm9uZUlkXHJcblx0XHQ/IC8vIERvbid0IHNob3cgdGhlIGZ1bGwgem9uZSBuYW1lIGlmIGluIEVEVCBvciBFU1QsIHVubGVzcyB0b2xkIHRvXHJcblx0XHRcdGAke3RpbWV9ICR7dGltZXpvbmVBYmJyZXZpYXRpb259YFxyXG5cdFx0OiAvLyBJZiBub3QgRURUIG9yIEVTVCwgc2hvdyB0aGUgem9uZSBuYW1lLCByZXBsYWNpbmcgdW5kZXJzY29yZXMgd2l0aCBzcGFjZXNcclxuXHRcdFx0Ly8gRXg6IFwiQXNpYS9UYWlwZWlcIlxyXG5cdFx0XHRgJHt0aW1lfSAke3RpbWV6b25lQWJicmV2aWF0aW9ufSAoJHt0aW1lWm9uZUlkLnJlcGxhY2UoJ18nLCAnICcpfSlgXHJcbn1cclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIGEgdGltZSBzdHJpbmcgd2l0aG91dCB0aW1lIHpvbmUsIGUuZy4gYDQ6MDUgUE1gXHJcbiAqIEBwYXJhbSBkYXRlVGltZVV0YyBBIFVUQyBkYXRlIHRpbWUgc3RyaW5nXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZ2V0Rm9ybWF0dGVkTnVtYmVyZWRUaW1lV2l0aG91dFpvbmUoZGF0ZVRpbWVVdGM6IHN0cmluZykge1xyXG5cdHJldHVybiBhcHBseUZvcm1hdChkYXRlVGltZVV0YywgJ2g6bW1cXHUwMGEwQScpXHJcbn1cclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIGEgdGltZSBzdHJpbmcgd2l0aG91dCB0aW1lIHpvbmUsIGluIDI0IGhyIHRpbWUsIGUuZy4gYDE2OjA1YFxyXG4gKiBAcGFyYW0gZGF0ZVRpbWVVdGMgQSBVVEMgZGF0ZSB0aW1lIHN0cmluZ1xyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGdldEZvcm1hdHRlZE51bWJlcmVkVGltZVdpdGhvdXRab25lT3JNZXJpZGlhbihkYXRlVGltZVV0Yzogc3RyaW5nKSB7XHJcblx0cmV0dXJuIGFwcGx5Rm9ybWF0KGRhdGVUaW1lVXRjLCAnSEg6bW0nKVxyXG59XHJcblxyXG4vKipcclxuICogUmV0dXJucyBhIGZ1bGwgZm9ybWF0dGVkIHRpbWUgem9uZSBzdHJpbmcgZm9yIHRoZSBnaXZlbiBgdGltZVpvbmVJZGAuXHJcbiAqXHJcbiAqIENvbWJpbmVzIGFsbCBwb3NzaWJsZSBhYmJyZXZpYXRpb25zIGZvciB0aGUgem9uZSBhbmQgdGhlIHRpbWVab25lSWQsIGUuZy4gYEVTVC9FRFRgLCBgUFNUL1BEVCAoQW1lcmljYS9Mb3MgQW5nZWxlcylgIG9yIGBDU1QgKEFzaWEvVGFpcGVpKWBcclxuICpcclxuICogSWYgYWJicmV2aWF0aW9ucyBhcmUgbm90IGFscGhhIGNoYXJhY3RlcnMsIGUuZy4gYC0wNGAsIHRoZW4gb25seSB0aGUgdGltZVpvbmVJZCBpcyByZXR1cm5lZC5cclxuICpcclxuICogQHBhcmFtIHRpbWVab25lSWQgKG9wdGlvbmFsKSBBIHRpbWUgem9uZSBJZC4gRGVmYXVsdHMgdG8gdGhlIGN1cnJlbnQgdGltZSB6b25lIGlkLCB1c2luZyBgZ3Vlc3NUaW1lWm9uZUlkKClgLlxyXG4gKiBAcGFyYW0gc2hvd0Vhc3Rlcm5ab25lSWQgKG9wdGlvbmFsKSBXaGV0aGVyIG9yIG5vdCB0byBpbmNsdWRlIHRoZSB0aW1lWm9uZUlkIGluIHRoZSByZXN1bHQgZm9yIEVTVC9FRFQuIERlZmF1bHRzIHRvIGBmYWxzZWAuXHJcbiAqIEBwYXJhbSBub3dVdGMgKG9wdGlvbmFsKSBUaGUgY3VycmVudCB0aW1lLCBcIm5vd1wiLCBhcyBhbiBJU08gZGF0ZSBzdHJpbmcuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZ2V0RnVsbEZvcm1hdHRlZFRpbWVab25lKFxyXG5cdHRpbWVab25lSWQgPSBndWVzc1RpbWVab25lSWQoKSxcclxuXHRzaG93RWFzdGVyblpvbmVJZCA9IGZhbHNlLFxyXG5cdG5vd1V0YyA9IGdldFNlcnZlck5vd1V0YygpLnRvSVNPU3RyaW5nKClcclxuKSB7XHJcblx0Y29uc3Qgem9uZSA9IG1vbWVudC50ei56b25lKHRpbWVab25lSWQpXHJcblx0aWYgKCF6b25lKSByZXR1cm4gJydcclxuXHJcblx0Y29uc3Qgem9uZWRNb21lbnQgPSBnZXRab25lZE1vbWVudEZyb21VdGMobm93VXRjLCB0aW1lWm9uZUlkKVxyXG5cdC8vIGZpbHRlciB0aGUgem9uZSBkYXRhIGRvd24gdG8ganVzdCByZWNlbnQgeWVhcnMsIGluc3RlYWQgb2YgdGhlIGRlZmF1bHQgb2YgMTkwMCB0byAyMDM4XHJcblx0Y29uc3QgZmlsdGVyZWRab25lID0gbW9tZW50VXRpbHMudHouZmlsdGVyWWVhcnMoem9uZSwgem9uZWRNb21lbnQueWVhcigpIC0gMSwgem9uZWRNb21lbnQueWVhcigpICsgMSlcclxuXHQvLyBmaW5kIGFsbCB1bmlxdWUgYWJicmV2aWF0aW9ucyBmb3IgdGhlIHpvbmUsIGNvbWJpbmVkIGludG8gYSBzdHJpbmdcclxuXHRjb25zdCBhYmJyZXZpYXRpb25zID0gZmlsdGVyZWRab25lLmFiYnJzXHJcblx0XHQvLyBmaWx0ZXIgb3V0IG5vbi1hbHBoYSBhYmJyZXZpYXRpb25zXHJcblx0XHQuZmlsdGVyKGFiYnIgPT4gL1thLXpBLVpdKy9nLnRlc3QoYWJicikpXHJcblx0XHQucmVkdWNlKCh1bmlxdWVBYmJyczogc3RyaW5nW10sIGFiYnIpID0+IHtcclxuXHRcdFx0aWYgKCF1bmlxdWVBYmJycy5pbmNsdWRlcyhhYmJyKSkge1xyXG5cdFx0XHRcdHVuaXF1ZUFiYnJzLnB1c2goYWJicilcclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm4gdW5pcXVlQWJicnNcclxuXHRcdH0sIFtdKVxyXG5cdGNvbnN0IGFiYnJldmlhdGlvbnNTdHJpbmcgPSBhYmJyZXZpYXRpb25zLmxlbmd0aCA+IDAgPyBhYmJyZXZpYXRpb25zLmpvaW4oJy8nKSA6IG51bGxcclxuXHRjb25zdCByZWFkYWJsZVpvbmVJZCA9IHRpbWVab25lSWQucmVwbGFjZSgnXycsICcgJylcclxuXHRyZXR1cm4gIWFiYnJldmlhdGlvbnNTdHJpbmdcclxuXHRcdD8gcmVhZGFibGVab25lSWRcclxuXHRcdDogYWJicmV2aWF0aW9uc1N0cmluZyA9PT0gJ0VTVC9FRFQnICYmICFzaG93RWFzdGVyblpvbmVJZFxyXG5cdFx0XHQ/IC8vIERvbid0IHNob3cgdGhlIHpvbmVJZCBpZiBpbiBFYXN0ZXJuLCB1bmxlc3MgdG9sZCB0b1xyXG5cdFx0XHRcdGFiYnJldmlhdGlvbnNTdHJpbmdcclxuXHRcdFx0OiAvLyBTaG93IHRoZSBjb21iaW5lZCBhYmJyZXZpYXRpb25zIHBsdXMgdGhlIGZyaWVuZGx5IHpvbmVJZFxyXG5cdFx0XHRcdGAke2FiYnJldmlhdGlvbnNTdHJpbmd9ICgke3JlYWRhYmxlWm9uZUlkfSlgXHJcbn1cclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIHRoZSBiYXNpYyB0aW1lIHpvbmUgYWJicmV2aWF0aW9uIGZvciB0aGUgZ2l2ZW4gZGF0ZSwgZS5nLiBgRURUYC5cclxuICpcclxuICogQHBhcmFtIGRhdGVUaW1lVXRjIFRoZSBkYXRlIHRvIGZvcm1hdC5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRGb3JtYXR0ZWRUaW1lWm9uZShkYXRlVGltZVV0Yzogc3RyaW5nKSB7XHJcblx0cmV0dXJuIGFwcGx5Rm9ybWF0KGRhdGVUaW1lVXRjLCAneicpXHJcbn1cclxuXHJcbi8qKlxyXG4gKiBGb3JtYXRzIGEgZGF0ZSB1c2luZyB0aGUgZ2l2ZW4gZm9ybWF0LiBQYXJzZXMgdGhlIGRhdGUgYXMgVVRDLCB0aGVuIGNvbnZlcnRzIHRvIHRoZSBjdXJyZW50IHRpbWUgem9uZSwgdGhlbiBmb3JtYXRzLlxyXG4gKiBAcGFyYW0geyp9IGRhdGVUaW1lVXRjIFRoZSBkYXRlIHRvIGZvcm1hdC4gQW55IHZhbGlkIGlucHV0IGZvciBgbW9tZW50LnV0YyguLi4pYFxyXG4gKiBAcGFyYW0geyp9IGZvcm1hdCBUaGUgZm9ybWF0IHRvIHVzZVxyXG4gKi9cclxuZnVuY3Rpb24gYXBwbHlGb3JtYXQoZGF0ZVRpbWVVdGM6IHN0cmluZywgZm9ybWF0OiBzdHJpbmcsIHRpbWVab25lSWQgPSBndWVzc1RpbWVab25lSWQoKSkge1xyXG5cdHJldHVybiBnZXRab25lZE1vbWVudEZyb21VdGMoZGF0ZVRpbWVVdGMsIHRpbWVab25lSWQpLmZvcm1hdChmb3JtYXQpXHJcbn1cclxuXHJcbmNvbnN0IGlzSW5wdXRUeXBlU3VwcG9ydGVkID0gKHR5cGU6IHN0cmluZykgPT4ge1xyXG5cdHRyeSB7XHJcblx0XHRjb25zdCB0ZXN0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaW5wdXQnKVxyXG5cdFx0dGVzdC50eXBlID0gdHlwZVxyXG5cdFx0Y29uc3QgaXNTdXBwb3J0ZWQgPSB0ZXN0LnR5cGUgPT09IHR5cGVcclxuXHRcdHJldHVybiBpc1N1cHBvcnRlZFxyXG5cdH0gY2F0Y2gge1xyXG5cdFx0cmV0dXJuIGZhbHNlXHJcblx0fVxyXG59XHJcblxyXG5leHBvcnQgY29uc3QgaXNEYXRlSW5wdXRTdXBwb3J0ZWQgPSBpc0lucHV0VHlwZVN1cHBvcnRlZCgnZGF0ZScpXHJcblxyXG5leHBvcnQgY29uc3QgaXNUaW1lSW5wdXRTdXBwb3J0ZWQgPSBpc0lucHV0VHlwZVN1cHBvcnRlZCgndGltZScpXHJcblxyXG5leHBvcnQgZnVuY3Rpb24gaXNEYXRlVGltZVZhbGlkKGRhdGVUaW1lOiBzdHJpbmcgfCBEYXRlKSB7XHJcblx0cmV0dXJuICEhZGF0ZVRpbWUgJiYgbW9tZW50KGRhdGVUaW1lKS5pc1ZhbGlkKClcclxufVxyXG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLElBQUFBLGVBQUEsR0FBQUMsc0JBQUEsQ0FBQUMsT0FBQTtBQUNBLElBQUFDLG9CQUFBLEdBQUFGLHNCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBRSxTQUFBLEdBQUFGLE9BQUE7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFB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QUFHLENBQUM7RUFDbkQsT0FBTyxDQUFDaUIsbUJBQW1CLEdBQ3hCRSxjQUFjLEdBQ2RGLG1CQUFtQixLQUFLLFNBQVMsSUFBSSxDQUFDckIsaUJBQWlCO0VBQ3REO0VBQ0RxQixtQkFBbUI7RUFDbEI7RUFDRCxHQUFHQSxtQkFBbUIsS0FBS0UsY0FBYyxHQUFHO0FBQ2hEOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDTyxTQUFTQyxvQkFBb0JBLENBQUN2RixXQUFtQixFQUFFO0VBQ3pELE9BQU84QyxXQUFXLENBQUM5QyxXQUFXLEVBQUUsR0FBRyxDQUFDO0FBQ3JDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTOEMsV0FBV0EsQ0FBQzlDLFdBQW1CLEVBQUV3RixNQUFjLEVBQWtDO0VBQUEsSUFBaENuRixVQUFVLEdBQUFKLFNBQUEsQ0FBQUMsTUFBQSxRQUFBRCxTQUFBLFFBQUFFLFNBQUEsR0FBQUYsU0FBQSxNQUFHLElBQUFLLHlCQUFlLEVBQUMsQ0FBQztFQUN2RixPQUFPUCxxQkFBcUIsQ0FBQ0MsV0FBVyxFQUFFSyxVQUFVLENBQUMsQ0FBQ21GLE1BQU0sQ0FBQ0EsTUFBTSxDQUFDO0FBQ3JFO0FBRUEsTUFBTUMsb0JBQW9CLEdBQUlDLElBQVksSUFBSztFQUM5QyxJQUFJO0lBQ0gsTUFBTVgsSUFBSSxHQUFHWSxRQUFRLENBQUNDLGFBQWEsQ0FBQyxPQUFPLENBQUM7SUFDNUNiLElBQUksQ0FBQ1csSUFBSSxHQUFHQSxJQUFJO0lBQ2hCLE1BQU1HLFdBQVcsR0FBR2QsSUFBSSxDQUFDVyxJQUFJLEtBQUtBLElBQUk7SUFDdEMsT0FBT0csV0FBVztFQUNuQixDQUFDLENBQUMsTUFBTTtJQUNQLE9BQU8sS0FBSztFQUNiO0FBQ0QsQ0FBQztBQUVNLE1BQU1DLG9CQUFvQixHQUFBdEcsT0FBQSxDQUFBc0csb0JBQUEsR0FBR0wsb0JBQW9CLENBQUMsTUFBTSxDQUFDO0FBRXpELE1BQU1NLG9CQUFvQixHQUFBdkcsT0FBQSxDQUFBdUcsb0JBQUEsR0FBR04sb0JBQW9CLENBQUMsTUFBTSxDQUFDO0FBRXpELFNBQVNPLGVBQWVBLENBQUN0RSxRQUF1QixFQUFFO0VBQ3hELE9BQU8sQ0FBQyxDQUFDQSxRQUFRLElBQUksSUFBQW5CLHVCQUFNLEVBQUNtQixRQUFRLENBQUMsQ0FBQ3VFLE9BQU8sQ0FBQyxDQUFDO0FBQ2hEIiwiaWdub3JlTGlzdCI6W119
|