generated from obsidianmd/obsidian-sample-plugin
-
Notifications
You must be signed in to change notification settings - Fork 0
/
time.js
236 lines (236 loc) · 27.5 KB
/
time.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
import moment from "moment";
import { ConstantReference } from "model/ref";
export class DateTime {
constructor(time, _hasTimePart) {
this.time = time;
this._hasTimePart = _hasTimePart;
}
static now() {
return new DateTime(moment(), true);
}
static parse(time) {
if (time.length > 10) {
return new DateTime(moment(time, "YYYY-MM-DD HH:mm"), true);
}
else {
return new DateTime(moment(time, "YYYY-MM-DD"), false);
}
}
static duration(from, to, unit, defaultTime) {
return to.fixedTime(defaultTime).diff(from.fixedTime(defaultTime), unit);
}
getTimeInMillis(defaultTime) {
return this.fixedTime(defaultTime).valueOf();
}
format(format, defaultTime) {
return this.fixedTime(defaultTime).format(format);
}
toYYYYMMMM(defaultTime) {
return this.fixedTime(defaultTime).format("YYYY, MMMM");
}
toYYYYMMDD(defaultTime) {
return this.fixedTime(defaultTime).format("YYYY-MM-DD");
}
add(amount, unit, defaultTime) {
return new DateTime(this.fixedTime(defaultTime).clone().add(amount, unit), this._hasTimePart);
}
fixedTime(defaultTime) {
if (this._hasTimePart) {
return this.time;
}
if (defaultTime === undefined) {
return this.time;
}
return this.time.clone().add(defaultTime.minutes, "minutes");
}
get hasTimePart() {
return this._hasTimePart;
}
toString() {
if (this._hasTimePart) {
return this.format("YYYY-MM-DD HH:mm");
}
else {
return this.format("YYYY-MM-DD");
}
}
}
export class Time {
constructor(hour, minute) {
this.hour = hour;
this.minute = minute;
}
static parse(text) {
const s = text.split(":");
if (s.length !== 2) {
throw `unexpected format time: ${text}`;
}
const hour = parseInt(s[0]);
const minute = parseInt(s[1]);
if (hour > 23 || hour < 0) {
throw `hour must be 0~23`;
}
if (minute > 59 || minute < 0) {
throw `minute must be 0~59`;
}
return new Time(hour, minute);
}
get minutes() {
return this.hour * 60 + this.minute;
}
toString() {
const pad = (n) => {
if (n < 10) {
return "0" + n;
}
return "" + n;
};
return `${pad(this.hour)}:${pad(this.minute)}`;
}
}
function add(amount, unit) {
return () => {
return new DateTime(moment(), true).add(amount, unit);
};
}
export function inMinutes(minutes) {
return add(minutes, "minutes");
}
export function inHours(hours) {
return add(hours, "hours");
}
export function nextWeekday(weekday) {
return () => {
const today = moment();
if (today.isoWeekday() <= weekday) {
return new DateTime(today.isoWeekday(weekday), false);
}
else {
return new DateTime(today.add(1, "weeks").isoWeekday(weekday), false);
}
};
}
export function tomorrow() {
return () => {
return new DateTime(moment().add(1, "days"), false);
};
}
export function nextWeek() {
return () => {
return new DateTime(moment().add(1, "weeks"), false);
};
}
export function nextMonth() {
return () => {
return new DateTime(moment().add(1, "months"), false);
};
}
export function nextYear() {
return () => {
return new DateTime(moment().add(1, "years"), false);
};
}
export class Later {
constructor(label, later) {
this.label = label;
this.later = later;
}
}
export function parseLaters(laters) {
return laters.split("\n").map(l => parseLater(l.trim()));
}
export function parseLater(later) {
later = later.toLowerCase();
if (later.startsWith("in")) {
const tokens = later.split(" ");
if (tokens.length !== 3) {
throw `Unsupported format. Should be 'In N (minutes|hours)'`;
}
const n = parseInt(tokens[1]);
switch (tokens[2]) {
case "minute":
case "minutes":
{
const unit = n == 1 ? "minute" : "minutes";
return new Later(`In ${n} ${unit}`, inMinutes(n));
}
case "hour":
case "hours":
{
const unit = n == 1 ? "hour" : "hours";
return new Later(`In ${n} ${unit}`, inHours(n));
}
}
}
else if (later.startsWith("next")) {
const weekday = later.substring(5);
switch (weekday) {
case "sunday":
return new Later("Next Sunday", nextWeekday(0));
case "monday":
return new Later("Next Monday", nextWeekday(1));
case "tuesday":
return new Later("Next Tuesday", nextWeekday(2));
case "wednesday":
return new Later("Next Wednesday", nextWeekday(3));
case "thursday":
return new Later("Next Thursday", nextWeekday(4));
case "friday":
return new Later("Next Friday", nextWeekday(5));
case "saturday":
return new Later("Next Saturday", nextWeekday(6));
case "day":
return new Later("Tomorrow", tomorrow());
case "week":
return new Later("Next week", nextWeek());
case "month":
return new Later("Next month", nextMonth());
case "year":
return new Later("Next year", nextYear());
default:
throw `Unsupported weekday: ${weekday}`;
}
}
else if (later === "tomorrow") {
return new Later("Tomorrow", tomorrow());
}
throw `Unsupported format: ${later}`;
}
export const DEFAULT_LATERS = [
new Later("In 30 minutes", inMinutes(30)),
new Later("In 1 hours", inHours(1)),
new Later("In 3 hours", inHours(3)),
new Later("Tomorrow", tomorrow()),
new Later("Next week", nextWeek()),
];
class DateTimeFormatter {
constructor() {
this.dateFormat = new ConstantReference("YYYY-MM-DD");
this.dateTimeFormat = new ConstantReference("YYYY-MM-DD HH:mm");
}
setTimeFormat(dateFormat, dateTimeFormat) {
this.dateFormat = dateFormat;
this.dateTimeFormat = dateTimeFormat;
}
parse(text) {
const dateTime = moment(text, this.dateTimeFormat.value, true);
if (dateTime.isValid()) {
return new DateTime(dateTime, true);
}
const date = moment(text, this.dateFormat.value, true);
if (date.isValid()) {
return new DateTime(date, false);
}
return null;
}
toString(time) {
if (time.hasTimePart) {
return time.format(this.dateTimeFormat.value);
}
else {
return time.format(this.dateFormat.value);
}
}
}
export const DATE_TIME_FORMATTER = new DateTimeFormatter();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRpbWUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxNQUFNLE1BQU0sUUFBUSxDQUFDO0FBQzVCLE9BQU8sRUFBRSxpQkFBaUIsRUFBcUIsTUFBTSxXQUFXLENBQUM7QUFFakUsTUFBTSxPQUFPLFFBQVE7SUFzQm5CLFlBQW9CLElBQW1CLEVBQVUsWUFBcUI7UUFBbEQsU0FBSSxHQUFKLElBQUksQ0FBZTtRQUFVLGlCQUFZLEdBQVosWUFBWSxDQUFTO0lBQUksQ0FBQztJQXJCcEUsTUFBTSxDQUFDLEdBQUc7UUFDZixPQUFPLElBQUksUUFBUSxDQUFDLE1BQU0sRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFFTSxNQUFNLENBQUMsS0FBSyxDQUFDLElBQVk7UUFDOUIsSUFBSSxJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsRUFBRTtZQUNwQixPQUFPLElBQUksUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsa0JBQWtCLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztTQUM3RDthQUFNO1lBQ0wsT0FBTyxJQUFJLFFBQVEsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLFlBQVksQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1NBQ3hEO0lBQ0gsQ0FBQztJQUVNLE1BQU0sQ0FBQyxRQUFRLENBQ3BCLElBQWMsRUFDZCxFQUFZLEVBQ1osSUFBVSxFQUNWLFdBQWtCO1FBRWxCLE9BQU8sRUFBRSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUMzRSxDQUFDO0lBSU0sZUFBZSxDQUFDLFdBQWtCO1FBQ3ZDLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUMvQyxDQUFDO0lBRU0sTUFBTSxD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QUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDdkQsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUU7WUFDbEIsT0FBTyxJQUFJLFFBQVEsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7U0FDbEM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxRQUFRLENBQUMsSUFBYztRQUNyQixJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUU7WUFDcEIsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDL0M7YUFBTTtZQUNMLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO1NBQzNDO0lBQ0gsQ0FBQztDQUVGO0FBRUQsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxpQkFBaUIsRUFBRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IG1vbWVudCBmcm9tIFwibW9tZW50XCI7XHJcbmltcG9ydCB7IENvbnN0YW50UmVmZXJlbmNlLCBSZWFkT25seVJlZmVyZW5jZSB9IGZyb20gXCJtb2RlbC9yZWZcIjtcclxuXHJcbmV4cG9ydCBjbGFzcyBEYXRlVGltZSB7XHJcbiAgcHVibGljIHN0YXRpYyBub3coKTogRGF0ZVRpbWUge1xyXG4gICAgcmV0dXJuIG5ldyBEYXRlVGltZShtb21lbnQoKSwgdHJ1ZSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc3RhdGljIHBhcnNlKHRpbWU6IHN0cmluZyk6IERhdGVUaW1lIHtcclxuICAgIGlmICh0aW1lLmxlbmd0aCA+IDEwKSB7XHJcbiAgICAgIHJldHVybiBuZXcgRGF0ZVRpbWUobW9tZW50KHRpbWUsIFwiWVlZWS1NTS1ERCBISDptbVwiKSwgdHJ1ZSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm4gbmV3IERhdGVUaW1lKG1vbWVudCh0aW1lLCBcIllZWVktTU0tRERcIiksIGZhbHNlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHB1YmxpYyBzdGF0aWMgZHVyYXRpb24oXHJcbiAgICBmcm9tOiBEYXRlVGltZSxcclxuICAgIHRvOiBEYXRlVGltZSxcclxuICAgIHVuaXQ6IFVuaXQsXHJcbiAgICBkZWZhdWx0VGltZT86IFRpbWVcclxuICApOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRvLmZpeGVkVGltZShkZWZhdWx0VGltZSkuZGlmZihmcm9tLmZpeGVkVGltZShkZWZhdWx0VGltZSksIHVuaXQpO1xyXG4gIH1cclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSB0aW1lOiBtb21lbnQuTW9tZW50LCBwcml2YXRlIF9oYXNUaW1lUGFydDogYm9vbGVhbikgeyB9XHJcblxyXG4gIHB1YmxpYyBnZXRUaW1lSW5NaWxsaXMoZGVmYXVsdFRpbWU/OiBUaW1lKTogbnVtYmVyIHtcclxuICAgIHJldHVybiB0aGlzLmZpeGVkVGltZShkZWZhdWx0VGltZSkudmFsdWVPZigpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGZvcm1hdChmb3JtYXQ6IHN0cmluZywgZGVmYXVsdFRpbWU/OiBUaW1lKSB7XHJcbiAgICByZXR1cm4gdGhpcy5maXhlZFRpbWUoZGVmYXVsdFRpbWUpLmZvcm1hdChmb3JtYXQpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHRvWVlZWU1NTU0oZGVmYXVsdFRpbWU/OiBUaW1lKTogc3RyaW5nIHtcclxuICAgIHJldHVybiB0aGlzLmZpeGVkVGltZShkZWZhdWx0VGltZSkuZm9ybWF0KFwiWVlZWSwgTU1NTVwiKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyB0b1lZWVlNTUREKGRlZmF1bHRUaW1lPzogVGltZSk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gdGhpcy5maXhlZFRpbWUoZGVmYXVsdFRpbWUpLmZvcm1hdChcIllZWVktTU0tRERcIik7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgYWRkKGFtb3VudDogbnVtYmVyLCB1bml0OiBVbml0LCBkZWZhdWx0VGltZT86IFRpbWUpOiBEYXRlVGltZSB7XHJcbiAgICByZXR1cm4gbmV3IERhdGVUaW1lKFxyXG4gICAgICB0aGlzLmZpeGVkVGltZShkZWZhdWx0VGltZSkuY2xvbmUoKS5hZGQoYW1vdW50LCB1bml0KSxcclxuICAgICAgdGhpcy5faGFzVGltZVBhcnRcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGZpeGVkVGltZShkZWZhdWx0VGltZT86IFRpbWUpOiBtb21lbnQuTW9tZW50IHtcclxuICAgIGlmICh0aGlzLl9oYXNUaW1lUGFydCkge1xyXG4gICAgICByZXR1cm4gdGhpcy50aW1lO1xyXG4gICAgfVxyXG4gICAgaWYgKGRlZmF1bHRUaW1lID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgcmV0dXJuIHRoaXMudGltZTtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzLnRpbWUuY2xvbmUoKS5hZGQoZGVmYXVsdFRpbWUubWludXRlcywgXCJtaW51dGVzXCIpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldCBoYXNUaW1lUGFydCgpIHtcclxuICAgIHJldHVybiB0aGlzLl9oYXNUaW1lUGFydDtcclxuICB9XHJcblxyXG4gIHB1YmxpYyB0b1N0cmluZygpOiBzdHJpbmcge1xyXG4gICAgaWYgKHRoaXMuX2hhc1RpbWVQYXJ0KSB7XHJcbiAgICAgIHJldHVybiB0aGlzLmZvcm1hdChcIllZWVktTU0tREQgSEg6bW1cIik7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm4gdGhpcy5mb3JtYXQoXCJZWVlZLU1NLUREXCIpO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIFRpbWUge1xyXG4gIHB1YmxpYyBzdGF0aWMgcGFyc2UodGV4dDogc3RyaW5nKTogVGltZSB7XHJcbiAgICBjb25zdCBzID0gdGV4dC5zcGxpdChcIjpcIik7XHJcbiAgICBpZiAocy5sZW5ndGggIT09IDIpIHtcclxuICAgICAgdGhyb3cgYHVuZXhwZWN0ZWQgZm9ybWF0IHRpbWU6ICR7dGV4dH1gO1xyXG4gICAgfVxyXG4gICAgY29uc3QgaG91ciA9IHBhcnNlSW50KHNbMF0pO1xyXG4gICAgY29uc3QgbWludXRlID0gcGFyc2VJbnQoc1sxXSk7XHJcbiAgICBpZiAoaG91ciA+IDIzIHx8IGhvdXIgPCAwKSB7XHJcbiAgICAgIHRocm93IGBob3VyIG11c3QgYmUgMH4yM2A7XHJcbiAgICB9XHJcbiAgICBpZiAobWludXRlID4gNTkgfHwgbWludXRlIDwgMCkge1xyXG4gICAgICB0aHJvdyBgbWludXRlIG11c3QgYmUgMH41OWA7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gbmV3IFRpbWUoaG91ciwgbWludXRlKTtcclxuICB9XHJcbiAgcHJpdmF0ZSBjb25zdHJ1Y3Rvcihwcml2YXRlIGhvdXI6IG51bWJlciwgcHJpdmF0ZSBtaW51dGU6IG51bWJlcikgeyB9XHJcblxyXG4gIGdldCBtaW51dGVzKCk6IG51bWJlciB7XHJcbiAgICByZXR1cm4gdGhpcy5ob3VyICogNjAgKyB0aGlzLm1pbnV0ZTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyB0b1N0cmluZygpOiBzdHJpbmcge1xyXG4gICAgY29uc3QgcGFkID0gKG46IG51bWJlcik6IHN0cmluZyA9PiB7XHJcbiAgICAgIGlmIChuIDwgMTApIHtcclxuICAgICAgICByZXR1cm4gXCIwXCIgKyBuO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiBcIlwiICsgbjtcclxuICAgIH07XHJcbiAgICByZXR1cm4gYCR7cGFkKHRoaXMuaG91cil9OiR7cGFkKHRoaXMubWludXRlKX1gO1xyXG4gIH1cclxufVxyXG5cclxuZXhwb3J0IHR5cGUgbGF0ZXIgPSAoKSA9PiBEYXRlVGltZTtcclxudHlwZSBVbml0ID0gXCJzZWNvbmRzXCIgfCBcIm1pbnV0ZXNcIiB8IFwiaG91cnNcIiB8IFwiZGF5c1wiO1xyXG5cclxuZnVuY3Rpb24gYWRkKGFtb3VudDogbnVtYmVyLCB1bml0OiBVbml0KTogbGF0ZXIge1xyXG4gIHJldHVybiAoKSA9PiB7XHJcbiAgICByZXR1cm4gbmV3IERhdGVUaW1lKG1vbWVudCgpLCB0cnVlKS5hZGQoYW1vdW50LCB1bml0KTtcclxuICB9O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gaW5NaW51dGVzKG1pbnV0ZXM6IG51bWJlcik6IGxhdGVyIHtcclxuICByZXR1cm4gYWRkKG1pbnV0ZXMsIFwibWludXRlc1wiKTtcclxufVxyXG5cclxuZXhwb3J0IGZ1bmN0aW9uIGluSG91cnMoaG91cnM6IG51bWJlcik6IGxhdGVyIHtcclxuICByZXR1cm4gYWRkKGhvdXJzLCBcImhvdXJzXCIpO1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gbmV4dFdlZWtkYXkod2Vla2RheTogbnVtYmVyKTogbGF0ZXIge1xyXG4gIHJldHVybiAoKSA9PiB7XHJcbiAgICBjb25zdCB0b2RheSA9IG1vbWVudCgpO1xyXG5cclxuICAgIGlmICh0b2RheS5pc29XZWVrZGF5KCkgPD0gd2Vla2RheSkge1xyXG4gICAgICByZXR1cm4gbmV3IERhdGVUaW1lKHRvZGF5Lmlzb1dlZWtkYXkod2Vla2RheSksIGZhbHNlKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHJldHVybiBuZXcgRGF0ZVRpbWUodG9kYXkuYWRkKDEsIFwid2Vla3NcIikuaXNvV2Vla2RheSh3ZWVrZGF5KSwgZmFsc2UpO1xyXG4gICAgfVxyXG4gIH07XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiB0b21vcnJvdygpOiBsYXRlciB7XHJcbiAgcmV0dXJuICgpID0+IHtcclxuICAgIHJldHVybiBuZXcgRGF0ZVRpbWUobW9tZW50KCkuYWRkKDEsIFwiZGF5c1wiKSwgZmFsc2UpO1xyXG4gIH07XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBuZXh0V2VlaygpOiBsYXRlciB7XHJcbiAgcmV0dXJuICgpID0+IHtcclxuICAgIHJldHVybiBuZXcgRGF0ZVRpbWUobW9tZW50KCkuYWRkKDEsIFwid2Vla3NcIiksIGZhbHNlKTtcclxuICB9O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gbmV4dE1vbnRoKCk6IGxhdGVyIHtcclxuICByZXR1cm4gKCkgPT4ge1xyXG4gICAgcmV0dXJuIG5ldyBEYXRlVGltZShtb21lbnQoKS5hZGQoMSwgXCJtb250aHNcIiksIGZhbHNlKTtcclxuICB9O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gbmV4dFllYXIoKTogbGF0ZXIge1xyXG4gIHJldHVybiAoKSA9PiB7XHJcbiAgICByZXR1cm4gbmV3IERhdGVUaW1lKG1vbWVudCgpLmFkZCgxLCBcInllYXJzXCIpLCBmYWxzZSk7XHJcbiAgfTtcclxufVxyXG5cclxuZXhwb3J0IGNsYXNzIExhdGVyIHtcclxuICBjb25zdHJ1Y3RvcihwdWJsaWMgbGFiZWw6IHN0cmluZywgcHVibGljIGxhdGVyOiBsYXRlcikgeyB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUxhdGVycyhsYXRlcnM6IHN0cmluZyk6IEFycmF5PExhdGVyPiB7XHJcbiAgcmV0dXJuIGxhdGVycy5zcGxpdChcIlxcblwiKS5tYXAobCA9PiBwYXJzZUxhdGVyKGwudHJpbSgpKSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUxhdGVyKGxhdGVyOiBzdHJpbmcpOiBMYXRlciB7XHJcbiAgbGF0ZXIgPSBsYXRlci50b0xvd2VyQ2FzZSgpO1xyXG4gIGlmIChsYXRlci5zdGFydHNXaXRoKFwiaW5cIikpIHtcclxuICAgIGNvbnN0IHRva2VucyA9IGxhdGVyLnNwbGl0KFwiIFwiKTtcclxuICAgIGlmICh0b2tlbnMubGVuZ3RoICE9PSAzKSB7XHJcbiAgICAgIHRocm93IGBVbnN1cHBvcnRlZCBmb3JtYXQuICBTaG91bGQgYmUgJ0luIE4gKG1pbnV0ZXN8aG91cnMpJ2A7XHJcbiAgICB9XHJcbiAgICBjb25zdCBuID0gcGFyc2VJbnQodG9rZW5zWzFdKTtcclxuICAgIHN3aXRjaCAodG9rZW5zWzJdKSB7XHJcbiAgICAgIGNhc2UgXCJtaW51dGVcIjpcclxuICAgICAgY2FzZSBcIm1pbnV0ZXNcIjpcclxuICAgICAgICB7XHJcbiAgICAgICAgICBjb25zdCB1bml0ID0gbiA9PSAxID8gXCJtaW51dGVcIiA6IFwibWludXRlc1wiO1xyXG4gICAgICAgICAgcmV0dXJuIG5ldyBMYXRlcihgSW4gJHtufSAke3VuaXR9YCwgaW5NaW51dGVzKG4pKTtcclxuICAgICAgICB9XHJcbiAgICAgIGNhc2UgXCJob3VyXCI6XHJcbiAgICAgIGNhc2UgXCJob3Vyc1wiOlxyXG4gICAgICAgIHtcclxuICAgICAgICAgIGNvbnN0IHVuaXQgPSBuID09IDEgPyBcImhvdXJcIiA6IFwiaG91cnNcIjtcclxuICAgICAgICAgIHJldHVybiBuZXcgTGF0ZXIoYEluICR7bn0gJHt1bml0fWAsIGluSG91cnMobikpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICB9IGVsc2UgaWYgKGxhdGVyLnN0YXJ0c1dpdGgoXCJuZXh0XCIpKSB7XHJcbiAgICBjb25zdCB3ZWVrZGF5ID0gbGF0ZXIuc3Vic3RyaW5nKDUpO1xyXG4gICAgc3dpdGNoICh3ZWVrZGF5KSB7XHJcbiAgICAgIGNhc2UgXCJzdW5kYXlcIjpcclxuICAgICAgICByZXR1cm4gbmV3IExhdGVyKFwiTmV4dCBTdW5kYXlcIiwgbmV4dFdlZWtkYXkoMCkpO1xyXG4gICAgICBjYXNlIFwibW9uZGF5XCI6XHJcbiAgICAgICAgcmV0dXJuIG5ldyBMYXRlcihcIk5leHQgTW9uZGF5XCIsIG5leHRXZWVrZGF5KDEpKTtcclxuICAgICAgY2FzZSBcInR1ZXNkYXlcIjpcclxuICAgICAgICByZXR1cm4gbmV3IExhdGVyKFwiTmV4dCBUdWVzZGF5XCIsIG5leHRXZWVrZGF5KDIpKTtcclxuICAgICAgY2FzZSBcIndlZG5lc2RheVwiOlxyXG4gICAgICAgIHJldHVybiBuZXcgTGF0ZXIoXCJOZXh0IFdlZG5lc2RheVwiLCBuZXh0V2Vla2RheSgzKSk7XHJcbiAgICAgIGNhc2UgXCJ0aHVyc2RheVwiOlxyXG4gICAgICAgIHJldHVybiBuZXcgTGF0ZXIoXCJOZXh0IFRodXJzZGF5XCIsIG5leHRXZWVrZGF5KDQpKTtcclxuICAgICAgY2FzZSBcImZyaWRheVwiOlxyXG4gICAgICAgIHJldHVybiBuZXcgTGF0ZXIoXCJOZXh0IEZyaWRheVwiLCBuZXh0V2Vla2RheSg1KSk7XHJcbiAgICAgIGNhc2UgXCJzYXR1cmRheVwiOlxyXG4gICAgICAgIHJldHVybiBuZXcgTGF0ZXIoXCJOZXh0IFNhdHVyZGF5XCIsIG5leHRXZWVrZGF5KDYpKTtcclxuICAgICAgY2FzZSBcImRheVwiOlxyXG4gICAgICAgIHJldHVybiBuZXcgTGF0ZXIoXCJUb21vcnJvd1wiLCB0b21vcnJvdygpKTtcclxuICAgICAgY2FzZSBcIndlZWtcIjpcclxuICAgICAgICByZXR1cm4gbmV3IExhdGVyKFwiTmV4dCB3ZWVrXCIsIG5leHRXZWVrKCkpO1xyXG4gICAgICBjYXNlIFwibW9udGhcIjpcclxuICAgICAgICByZXR1cm4gbmV3IExhdGVyKFwiTmV4dCBtb250aFwiLCBuZXh0TW9udGgoKSk7XHJcbiAgICAgIGNhc2UgXCJ5ZWFyXCI6XHJcbiAgICAgICAgcmV0dXJuIG5ldyBMYXRlcihcIk5leHQgeWVhclwiLCBuZXh0WWVhcigpKTtcclxuICAgICAgZGVmYXVsdDpcclxuICAgICAgICB0aHJvdyBgVW5zdXBwb3J0ZWQgd2Vla2RheTogJHt3ZWVrZGF5fWA7XHJcbiAgICB9XHJcbiAgfSBlbHNlIGlmIChsYXRlciA9PT0gXCJ0b21vcnJvd1wiKSB7XHJcbiAgICByZXR1cm4gbmV3IExhdGVyKFwiVG9tb3Jyb3dcIiwgdG9tb3Jyb3coKSk7XHJcbiAgfVxyXG4gIHRocm93IGBVbnN1cHBvcnRlZCBmb3JtYXQ6ICR7bGF0ZXJ9YDtcclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IERFRkFVTFRfTEFURVJTOiBBcnJheTxMYXRlcj4gPSBbXHJcbiAgbmV3IExhdGVyKFwiSW4gMzAgbWludXRlc1wiLCBpbk1pbnV0ZXMoMzApKSxcclxuICBuZXcgTGF0ZXIoXCJJbiAxIGhvdXJzXCIsIGluSG91cnMoMSkpLFxyXG4gIG5ldyBMYXRlcihcIkluIDMgaG91cnNcIiwgaW5Ib3VycygzKSksXHJcbiAgbmV3IExhdGVyKFwiVG9tb3Jyb3dcIiwgdG9tb3Jyb3coKSksXHJcbiAgbmV3IExhdGVyKFwiTmV4dCB3ZWVrXCIsIG5leHRXZWVrKCkpLFxyXG5dO1xyXG5cclxuY2xhc3MgRGF0ZVRpbWVGb3JtYXR0ZXIge1xyXG5cclxuICBwcml2YXRlIGRhdGVGb3JtYXQ6IFJlYWRPbmx5UmVmZXJlbmNlPHN0cmluZz4gPSBuZXcgQ29uc3RhbnRSZWZlcmVuY2UoXCJZWVlZLU1NLUREXCIpO1xyXG4gIHByaXZhdGUgZGF0ZVRpbWVGb3JtYXQ6IFJlYWRPbmx5UmVmZXJlbmNlPHN0cmluZz4gPSBuZXcgQ29uc3RhbnRSZWZlcmVuY2UoXCJZWVlZLU1NLUREIEhIOm1tXCIpO1xyXG5cclxuICBzZXRUaW1lRm9ybWF0KGRhdGVGb3JtYXQ6IFJlYWRPbmx5UmVmZXJlbmNlPHN0cmluZz4sIGRhdGVUaW1lRm9ybWF0OiBSZWFkT25seVJlZmVyZW5jZTxzdHJpbmc+KSB7XHJcbiAgICB0aGlzLmRhdGVGb3JtYXQgPSBkYXRlRm9ybWF0O1xyXG4gICAgdGhpcy5kYXRlVGltZUZvcm1hdCA9IGRhdGVUaW1lRm9ybWF0O1xyXG4gIH1cclxuXHJcbiAgcGFyc2UodGV4dDogc3RyaW5nKTogRGF0ZVRpbWUgfCBudWxsIHtcclxuICAgIGNvbnN0IGRhdGVUaW1lID0gbW9tZW50KHRleHQsIHRoaXMuZGF0ZVRpbWVGb3JtYXQudmFsdWUsIHRydWUpO1xyXG4gICAgaWYgKGRhdGVUaW1lLmlzVmFsaWQoKSkge1xyXG4gICAgICByZXR1cm4gbmV3IERhdGVUaW1lKGRhdGVUaW1lLCB0cnVlKTtcclxuICAgIH1cclxuICAgIGNvbnN0IGRhdGUgPSBtb21lbnQodGV4dCwgdGhpcy5kYXRlRm9ybWF0LnZhbHVlLCB0cnVlKTtcclxuICAgIGlmIChkYXRlLmlzVmFsaWQoKSkge1xyXG4gICAgICByZXR1cm4gbmV3IERhdGVUaW1lKGRhdGUsIGZhbHNlKTtcclxuICAgIH1cclxuICAgIHJldHVybiBudWxsO1xyXG4gIH1cclxuXHJcbiAgdG9TdHJpbmcodGltZTogRGF0ZVRpbWUpOiBzdHJpbmcge1xyXG4gICAgaWYgKHRpbWUuaGFzVGltZVBhcnQpIHtcclxuICAgICAgcmV0dXJuIHRpbWUuZm9ybWF0KHRoaXMuZGF0ZVRpbWVGb3JtYXQudmFsdWUpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuIHRpbWUuZm9ybWF0KHRoaXMuZGF0ZUZvcm1hdC52YWx1ZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IERBVEVfVElNRV9GT1JNQVRURVIgPSBuZXcgRGF0ZVRpbWVGb3JtYXR0ZXIoKTsiXX0=