@ieeesa-npm/dashboard 0.0.1 → 0.0.3
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/esm2022/lib/assets/constants.json +23 -6
- package/esm2022/lib/assets/dashboard-mock.mjs +5 -1
- package/esm2022/lib/assets/dashboard-route-paths.mock.mjs +7 -5
- package/esm2022/lib/components/event-group-card/event-group-card.component.mjs +168 -31
- package/esm2022/lib/components/meeting-attendance-row/meeting-attendance-row.component.mjs +25 -24
- package/esm2022/lib/components/upcoming-meetings-events/upcoming-meetings-events.component.mjs +103 -5
- package/esm2022/lib/components/welcome-header/dashboard-welcome-header.component.mjs +3 -3
- package/esm2022/lib/components/your-groups/your-groups.component.mjs +264 -118
- package/esm2022/lib/dashboard.component.mjs +54 -14
- package/esm2022/lib/models/event-meeting-list-item.model.mjs +2 -0
- package/esm2022/lib/models/event-meeting-list-payload.model.mjs +8 -0
- package/esm2022/lib/models/group-row.model.mjs +1 -1
- package/esm2022/lib/models/meeting-row.model.mjs +1 -1
- package/esm2022/lib/models/my-groups-view.model.mjs +2 -0
- package/esm2022/lib/models/upcoming-event.model.mjs +13 -2
- package/esm2022/lib/services/dashboard.service.mjs +229 -35
- package/esm2022/lib/utils/date-format.util.mjs +110 -0
- package/esm2022/lib/utils/event-meeting-mapper.util.mjs +96 -0
- package/esm2022/public-api.mjs +3 -1
- package/fesm2022/ieeesa-npm-dashboard.mjs +1300 -444
- package/fesm2022/ieeesa-npm-dashboard.mjs.map +1 -1
- package/lib/components/event-group-card/event-group-card.component.d.ts +100 -132
- package/lib/components/meeting-attendance-row/meeting-attendance-row.component.d.ts +8 -132
- package/lib/components/member-level-badge/member-level-badge.component.d.ts +19 -3
- package/lib/components/upcoming-meetings-events/upcoming-meetings-events.component.d.ts +63 -126
- package/lib/components/your-groups/your-groups.component.d.ts +158 -51
- package/lib/dashboard.component.d.ts +48 -10
- package/lib/models/event-meeting-list-item.model.d.ts +107 -0
- package/lib/models/event-meeting-list-payload.model.d.ts +40 -0
- package/lib/models/group-row.model.d.ts +25 -0
- package/lib/models/meeting-row.model.d.ts +18 -2
- package/lib/models/my-groups-view.model.d.ts +56 -0
- package/lib/models/upcoming-event.model.d.ts +40 -2
- package/lib/services/dashboard.service.d.ts +97 -14
- package/lib/utils/date-format.util.d.ts +60 -0
- package/lib/utils/event-meeting-mapper.util.d.ts +50 -0
- package/package.json +1 -1
- package/public-api.d.ts +2 -0
|
@@ -2,10 +2,27 @@ import { Injectable } from '@angular/core';
|
|
|
2
2
|
import { BehaviorSubject, catchError, map, of, } from 'rxjs';
|
|
3
3
|
import { AttendanceState } from '../models/attendance-state.model';
|
|
4
4
|
import { DashboardSectionState } from '../models/dashboard-section-state.model';
|
|
5
|
-
import {
|
|
5
|
+
import { UpcomingItemKind, } from '../models/upcoming-event.model';
|
|
6
|
+
import { mapEventMeetingDetails, mapEventMeetingList, } from '../utils/event-meeting-mapper.util';
|
|
6
7
|
import { applyLeaveMeetingSuccess, applyLogAttendanceSuccess, beginAttendanceAction, endAttendanceAction, } from './attendance-reducers';
|
|
7
8
|
import * as i0 from "@angular/core";
|
|
8
9
|
import * as i1 from "@ieeesa-npm/utility";
|
|
10
|
+
/** Fallback label for an empty group type / member level, matching the My Groups tab. */
|
|
11
|
+
const UNASSIGNED_LABEL = 'Unassigned';
|
|
12
|
+
/** Placeholder for an empty cell value. */
|
|
13
|
+
const EMPTY_VALUE = '-';
|
|
14
|
+
/** Statuses included in the upcoming section, matching the view-events-meetings-list screen. */
|
|
15
|
+
const UPCOMING_STATUSES = ['In Progress', 'Upcoming'];
|
|
16
|
+
/** Sort column used for the top-level events & meetings list. */
|
|
17
|
+
const UPCOMING_SORT_COLUMN = 'startDateTime';
|
|
18
|
+
/** Sort column used for an event's expanded child-meeting list (meetingsDetails). */
|
|
19
|
+
const EVENT_MEETINGS_SORT_COLUMN = 'meetingStDate';
|
|
20
|
+
/** Default page size for the top-level upcoming section list. */
|
|
21
|
+
const UPCOMING_PAGE_SIZE = 10;
|
|
22
|
+
/** Default page size for an event's expanded child-meeting list. */
|
|
23
|
+
const EVENT_MEETINGS_PAGE_SIZE = 5;
|
|
24
|
+
/** Large page size used by the eager count prefetch to capture the full set. */
|
|
25
|
+
const EVENT_COUNT_PAGE_SIZE = 200;
|
|
9
26
|
/**
|
|
10
27
|
* DashboardService is the single source of truth for the dashboard landing
|
|
11
28
|
* page's data and attendance state. It mirrors the `events-and-meetings`
|
|
@@ -15,11 +32,12 @@ import * as i1 from "@ieeesa-npm/utility";
|
|
|
15
32
|
* through the shared `HttpService` from `@ieeesa-npm/utility` (never
|
|
16
33
|
* `HttpClient` directly).
|
|
17
34
|
*
|
|
18
|
-
* The upcoming-events
|
|
19
|
-
*
|
|
20
|
-
* the
|
|
21
|
-
*
|
|
22
|
-
*
|
|
35
|
+
* The upcoming-events load calls the real `POST /meetings/eventsAndMeetings`
|
|
36
|
+
* endpoint (child meetings are lazily loaded per-event via
|
|
37
|
+
* `POST /meetings/meetingsDetails`); the groups load calls `GET
|
|
38
|
+
* /groups/my-groups`. The attendance actions compose the pure reducers from
|
|
39
|
+
* `attendance-reducers.ts` so the displayed `AttendanceState` only advances on a
|
|
40
|
+
* successful resolution and the prior state is retained on failure.
|
|
23
41
|
* @export
|
|
24
42
|
* @class DashboardService
|
|
25
43
|
*/
|
|
@@ -62,35 +80,172 @@ export class DashboardService {
|
|
|
62
80
|
this.userPermissions = userPermissions;
|
|
63
81
|
}
|
|
64
82
|
/**
|
|
65
|
-
* Loads the user's upcoming events
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
83
|
+
* Loads the user's upcoming events & meetings from the real backend via
|
|
84
|
+
* `POST {apiBaseUrl}/meetings/eventsAndMeetings`, the same endpoint the
|
|
85
|
+
* `view-events-meetings-list` screen uses. The response is mapped into the
|
|
86
|
+
* dashboard view models (with STANDALONE_MEETING rows ordered last), the
|
|
87
|
+
* per-meeting attendance-state map is seeded, and the section advances through
|
|
88
|
+
* LOADING → LOADED/EMPTY on success, leaving the caller to set ERROR on
|
|
89
|
+
* failure. Follows the shared `pipe(map, catchError(throw))` pattern.
|
|
90
|
+
* @return {Observable<EventMeetingListResponse>} The upcoming events & meetings response envelope.
|
|
72
91
|
* @memberof DashboardService
|
|
73
92
|
*/
|
|
74
93
|
loadUpcomingEvents() {
|
|
75
94
|
this.upcomingState.next(DashboardSectionState.LOADING);
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
95
|
+
const payload = {
|
|
96
|
+
payload: {
|
|
97
|
+
eventId: null,
|
|
98
|
+
sortColumn: UPCOMING_SORT_COLUMN,
|
|
99
|
+
ascendingOrder: true,
|
|
100
|
+
page: 1,
|
|
101
|
+
size: UPCOMING_PAGE_SIZE,
|
|
102
|
+
filter: {
|
|
103
|
+
status: UPCOMING_STATUSES,
|
|
104
|
+
isAllMeetingSelected: false,
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
return this.httpService
|
|
109
|
+
.postData(`${this.apiBaseUrl}/meetings/eventsAndMeetings`, payload)
|
|
110
|
+
.pipe(map((response) => {
|
|
111
|
+
const events = mapEventMeetingList(response?.body?.eventMeetingList ?? []);
|
|
83
112
|
this.upcomingEvents.next(events);
|
|
84
113
|
this.seedAttendanceStates(events);
|
|
85
114
|
this.upcomingState.next(events.length > 0
|
|
86
115
|
? DashboardSectionState.LOADED
|
|
87
116
|
: DashboardSectionState.EMPTY);
|
|
117
|
+
// Eagerly fetch each EVENT's meeting count so the "{n} meetings" and
|
|
118
|
+
// "{n} open for attendance" summaries are correct before expanding.
|
|
119
|
+
this.loadEventCounts(events);
|
|
88
120
|
return response;
|
|
89
121
|
}), catchError((error) => {
|
|
90
122
|
this.upcomingState.next(DashboardSectionState.ERROR);
|
|
91
123
|
throw error;
|
|
92
124
|
}));
|
|
93
125
|
}
|
|
126
|
+
/**
|
|
127
|
+
* Lazily loads (and paginates) the child meetings of an EVENT row via
|
|
128
|
+
* `POST {apiBaseUrl}/meetings/meetingsDetails` — the per-event expand endpoint
|
|
129
|
+
* used by the reference screen. On success the loaded meetings are mapped and
|
|
130
|
+
* merged onto the matching event in the `upcomingEvents` list (with its
|
|
131
|
+
* `meetingCount` / `openForAttendanceCount` refreshed), and the per-meeting
|
|
132
|
+
* attendance-state map is extended. Each event paginates independently.
|
|
133
|
+
* @param {string} eventId - The event whose meetings to load.
|
|
134
|
+
* @param {number} [page=1] - The one-based page to request.
|
|
135
|
+
* @param {number} [size=EVENT_MEETINGS_PAGE_SIZE] - The page size.
|
|
136
|
+
* @return {Observable<EventMeetingDetailResponse>} The child-meetings response envelope.
|
|
137
|
+
* @memberof DashboardService
|
|
138
|
+
*/
|
|
139
|
+
loadEventMeetings(eventId, page = 1, size = EVENT_MEETINGS_PAGE_SIZE) {
|
|
140
|
+
return this.fetchEventMeetingsPage(eventId, page, size).pipe(map((response) => {
|
|
141
|
+
const meetings = mapEventMeetingDetails(response?.body?.meetings ?? []);
|
|
142
|
+
const total = response?.body?.totalRecords ?? meetings.length;
|
|
143
|
+
// Prefer the already-known full open count on the event; fall back to
|
|
144
|
+
// the current page's open count when it hasn't been prefetched.
|
|
145
|
+
const existing = this.upcomingEvents.value.find((event) => event.eventId === eventId);
|
|
146
|
+
const pageOpenCount = meetings.filter((meeting) => meeting.isOpenForAttendance).length;
|
|
147
|
+
const openForAttendanceCount = existing?.openForAttendanceCount || pageOpenCount;
|
|
148
|
+
this.mergeEventMeetings(eventId, meetings, total, openForAttendanceCount);
|
|
149
|
+
this.seedAttendanceStatesFromMeetings(meetings);
|
|
150
|
+
return response;
|
|
151
|
+
}), catchError((error) => {
|
|
152
|
+
throw error;
|
|
153
|
+
}));
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Merges a freshly loaded page of child meetings onto the matching event in
|
|
157
|
+
* the `upcomingEvents` list, refreshing the event's `meetings`,
|
|
158
|
+
* `meetingCount` (from the backend `totalRecords`), and
|
|
159
|
+
* `openForAttendanceCount`. Leaves all other events untouched.
|
|
160
|
+
* @param {string} eventId - The event to merge meetings onto.
|
|
161
|
+
* @param {MeetingRow[]} meetings - The mapped child meetings for the page.
|
|
162
|
+
* @param {number} totalRecords - The event's total meeting count from the backend.
|
|
163
|
+
* @return {void}
|
|
164
|
+
* @memberof DashboardService
|
|
165
|
+
*/
|
|
166
|
+
mergeEventMeetings(eventId, meetings, totalRecords, openForAttendanceCount) {
|
|
167
|
+
const next = this.upcomingEvents.value.map((event) => {
|
|
168
|
+
if (event.eventId !== eventId) {
|
|
169
|
+
return event;
|
|
170
|
+
}
|
|
171
|
+
return {
|
|
172
|
+
...event,
|
|
173
|
+
meetings,
|
|
174
|
+
meetingCount: totalRecords,
|
|
175
|
+
openForAttendanceCount,
|
|
176
|
+
};
|
|
177
|
+
});
|
|
178
|
+
this.upcomingEvents.next(next);
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Eagerly fetches each EVENT's total meeting count and open-for-attendance
|
|
182
|
+
* count by requesting a large first page of its child meetings, then merging
|
|
183
|
+
* only the counts (not the rows) so the collapsed card summaries are accurate
|
|
184
|
+
* before the user expands. Standalone meetings are skipped. Failures per event
|
|
185
|
+
* are swallowed so one failing count never breaks the list.
|
|
186
|
+
* @param {UpcomingEvent[]} events - The loaded events to fetch counts for.
|
|
187
|
+
* @return {void}
|
|
188
|
+
* @memberof DashboardService
|
|
189
|
+
*/
|
|
190
|
+
loadEventCounts(events) {
|
|
191
|
+
events
|
|
192
|
+
.filter((event) => event.kind === UpcomingItemKind.EVENT && event.eventId)
|
|
193
|
+
.forEach((event) => {
|
|
194
|
+
this.fetchEventMeetingsPage(event.eventId, 1, EVENT_COUNT_PAGE_SIZE)
|
|
195
|
+
.pipe(catchError(() => of(null)))
|
|
196
|
+
.subscribe((response) => {
|
|
197
|
+
if (!response) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
const meetings = mapEventMeetingDetails(response?.body?.meetings ?? []);
|
|
201
|
+
const total = response?.body?.totalRecords ?? meetings.length;
|
|
202
|
+
const openCount = meetings.filter((meeting) => meeting.isOpenForAttendance).length;
|
|
203
|
+
this.mergeEventCounts(event.eventId, total, openCount);
|
|
204
|
+
this.seedAttendanceStatesFromMeetings(meetings);
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Merges only the meeting counts onto the matching event, leaving its
|
|
210
|
+
* `meetings` rows untouched (used by the eager count prefetch).
|
|
211
|
+
* @param {string} eventId - The event to update.
|
|
212
|
+
* @param {number} totalRecords - The event's total meeting count.
|
|
213
|
+
* @param {number} openForAttendanceCount - The open-for-attendance count.
|
|
214
|
+
* @return {void}
|
|
215
|
+
* @memberof DashboardService
|
|
216
|
+
*/
|
|
217
|
+
mergeEventCounts(eventId, totalRecords, openForAttendanceCount) {
|
|
218
|
+
const next = this.upcomingEvents.value.map((event) => event.eventId === eventId
|
|
219
|
+
? { ...event, meetingCount: totalRecords, openForAttendanceCount }
|
|
220
|
+
: event);
|
|
221
|
+
this.upcomingEvents.next(next);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Builds and posts the `meetingsDetails` request for a single event page,
|
|
225
|
+
* returning the raw response envelope. Shared by {@link loadEventMeetings} and
|
|
226
|
+
* the eager count prefetch.
|
|
227
|
+
* @param {string} eventId - The event whose meetings to fetch.
|
|
228
|
+
* @param {number} page - The one-based page to request.
|
|
229
|
+
* @param {number} size - The page size.
|
|
230
|
+
* @return {Observable<EventMeetingDetailResponse>} The child-meetings response.
|
|
231
|
+
* @memberof DashboardService
|
|
232
|
+
*/
|
|
233
|
+
fetchEventMeetingsPage(eventId, page, size) {
|
|
234
|
+
const payload = {
|
|
235
|
+
payload: {
|
|
236
|
+
eventId,
|
|
237
|
+
sortColumn: EVENT_MEETINGS_SORT_COLUMN,
|
|
238
|
+
ascendingOrder: true,
|
|
239
|
+
page,
|
|
240
|
+
size,
|
|
241
|
+
filter: {
|
|
242
|
+
status: UPCOMING_STATUSES,
|
|
243
|
+
isAllMeetingSelected: false,
|
|
244
|
+
},
|
|
245
|
+
},
|
|
246
|
+
};
|
|
247
|
+
return this.httpService.postData(`${this.apiBaseUrl}/meetings/meetingsDetails`, payload);
|
|
248
|
+
}
|
|
94
249
|
/**
|
|
95
250
|
* Loads the user's groups, driving the groups section through
|
|
96
251
|
* LOADING → LOADED/EMPTY on success and leaving the caller to set ERROR on
|
|
@@ -102,13 +257,10 @@ export class DashboardService {
|
|
|
102
257
|
*/
|
|
103
258
|
loadGroups() {
|
|
104
259
|
this.groupsState.next(DashboardSectionState.LOADING);
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
body
|
|
109
|
-
});
|
|
110
|
-
return response$.pipe(map((response) => {
|
|
111
|
-
const groups = response?.body ?? [];
|
|
260
|
+
return this.httpService
|
|
261
|
+
.getData(`${this.apiBaseUrl}/groups/my-groups`)
|
|
262
|
+
.pipe(map((response) => {
|
|
263
|
+
const groups = (response?.body?.groups ?? []).map((group) => this.mapGroup(group));
|
|
112
264
|
this.groups.next(groups);
|
|
113
265
|
this.groupsState.next(groups.length > 0
|
|
114
266
|
? DashboardSectionState.LOADED
|
|
@@ -119,6 +271,35 @@ export class DashboardService {
|
|
|
119
271
|
throw error;
|
|
120
272
|
}));
|
|
121
273
|
}
|
|
274
|
+
/**
|
|
275
|
+
* Maps a backend {@link MyGroupView} to the table-facing {@link GroupRow}.
|
|
276
|
+
* Mirrors the My Groups profile tab: the type falls back to "Unassigned" when
|
|
277
|
+
* `groupTypeName` is null, affiliations are comma-joined, empty officer role /
|
|
278
|
+
* affiliation render as a placeholder, and a blank member level becomes
|
|
279
|
+
* "Unassigned" (rendered as the warning pill by the Your Groups component).
|
|
280
|
+
* @param {MyGroupView} group - The backend group view.
|
|
281
|
+
* @return {GroupRow}
|
|
282
|
+
* @memberof DashboardService
|
|
283
|
+
*/
|
|
284
|
+
mapGroup(group) {
|
|
285
|
+
// The backend returns officer roles as an `officer` array of
|
|
286
|
+
// { officerId, officerName }. Join the names for the Officer Role column
|
|
287
|
+
// (e.g. "Chair" or "Chair, Vice Chair"); show the placeholder when empty.
|
|
288
|
+
const officerRole = (group.officer ?? [])
|
|
289
|
+
.map((officer) => officer?.officerName?.trim())
|
|
290
|
+
.filter((name) => !!name)
|
|
291
|
+
.join(', ') || EMPTY_VALUE;
|
|
292
|
+
return {
|
|
293
|
+
groupId: group.groupId,
|
|
294
|
+
group: group.groupName,
|
|
295
|
+
type: group.groupTypeName || group.groupType || UNASSIGNED_LABEL,
|
|
296
|
+
officerRole,
|
|
297
|
+
affiliation: group.affiliations?.join(', ') || EMPTY_VALUE,
|
|
298
|
+
memberLevel: group.memberLevel?.trim() || UNASSIGNED_LABEL,
|
|
299
|
+
// Carry the ancestor hierarchy through for the expandable hierarchy rows.
|
|
300
|
+
hierarchy: group.hierarchy ?? [],
|
|
301
|
+
};
|
|
302
|
+
}
|
|
122
303
|
/**
|
|
123
304
|
* Logs attendance for a meeting. Marks the meeting in-flight (retaining the
|
|
124
305
|
* prior displayed state), posts through `HttpService`, applies the
|
|
@@ -183,16 +364,29 @@ export class DashboardService {
|
|
|
183
364
|
* @memberof DashboardService
|
|
184
365
|
*/
|
|
185
366
|
seedAttendanceStates(events) {
|
|
367
|
+
const meetings = events.flatMap((event) => event.meetings ?? []);
|
|
368
|
+
this.seedAttendanceStatesFromMeetings(meetings);
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Seeds the attendance-state map from a list of meeting rows, using each
|
|
372
|
+
* meeting's `attendanceState` (defaulting to `NOT_ATTENDING`) without
|
|
373
|
+
* overwriting ids absent from the new list. Shared by the list load and the
|
|
374
|
+
* per-event expand so freshly loaded child meetings pick up their state.
|
|
375
|
+
* @param {MeetingRow[]} meetings - The meeting rows to seed from.
|
|
376
|
+
* @return {void}
|
|
377
|
+
* @memberof DashboardService
|
|
378
|
+
*/
|
|
379
|
+
seedAttendanceStatesFromMeetings(meetings) {
|
|
186
380
|
const next = {
|
|
187
381
|
...this.attendanceStates.value,
|
|
188
382
|
};
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
meeting.
|
|
194
|
-
|
|
195
|
-
}
|
|
383
|
+
meetings.forEach((meeting) => {
|
|
384
|
+
if (meeting.meetingId) {
|
|
385
|
+
next[meeting.meetingId] =
|
|
386
|
+
meeting.attendanceState ??
|
|
387
|
+
next[meeting.meetingId] ??
|
|
388
|
+
AttendanceState.NOT_ATTENDING;
|
|
389
|
+
}
|
|
196
390
|
});
|
|
197
391
|
this.attendanceStates.next(next);
|
|
198
392
|
}
|
|
@@ -205,4 +399,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImpo
|
|
|
205
399
|
providedIn: 'root',
|
|
206
400
|
}]
|
|
207
401
|
}], ctorParameters: function () { return [{ type: i1.HttpService }]; } });
|
|
208
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGFzaGJvYXJkLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9kYXNoYm9hcmQvc3JjL2xpYi9zZXJ2aWNlcy9kYXNoYm9hcmQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFDTCxlQUFlLEVBRWYsVUFBVSxFQUNWLEdBQUcsRUFDSCxFQUFFLEdBQ0gsTUFBTSxNQUFNLENBQUM7QUFHZCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFFbkUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFHaEYsT0FBTyxFQUNMLG1CQUFtQixFQUNuQiwyQkFBMkIsR0FDNUIsTUFBTSwwQkFBMEIsQ0FBQztBQUNsQyxPQUFPLEVBQ0wsd0JBQXdCLEVBQ3hCLHlCQUF5QixFQUN6QixxQkFBcUIsRUFDckIsbUJBQW1CLEdBQ3BCLE1BQU0sdUJBQXVCLENBQUM7OztBQUUvQjs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQUlILE1BQU0sT0FBTyxnQkFBZ0I7SUFxQzNCO0lBQ0UsMENBQTBDO0lBQ2xDLFdBQXdCLENBQUMsNkNBQTZDOztRQUF0RSxnQkFBVyxHQUFYLFdBQVcsQ0FBYTtRQW5DakIsbUJBQWMsR0FBRyxJQUFJLGVBQWUsQ0FBa0IsRUFBRSxDQUFDLENBQUM7UUFDMUQsV0FBTSxHQUFHLElBQUksZUFBZSxDQUFhLEVBQUUsQ0FBQyxDQUFDO1FBQzdDLGtCQUFhLEdBQUcsSUFBSSxlQUFlLENBQ2xELHFCQUFxQixDQUFDLE9BQU8sQ0FDOUIsQ0FBQztRQUNlLGdCQUFXLEdBQUcsSUFBSSxlQUFlLENBQ2hELHFCQUFxQixDQUFDLE9BQU8sQ0FDOUIsQ0FBQztRQUNlLHFCQUFnQixHQUFHLElBQUksZUFBZSxDQUVyRCxFQUFFLENBQUMsQ0FBQztRQUNX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LElBQUksR0FBb0M7WUFDNUMsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsS0FBSztTQUMvQixDQUFDO1FBQ0YsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1lBQ3ZCLEtBQUssQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7Z0JBQ2xDLElBQUksT0FBTyxDQUFDLFNBQVMsRUFBRTtvQkFDckIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUM7d0JBQ3JCLE9BQU8sQ0FBQyxlQUFlLElBQUksZUFBZSxDQUFDLGFBQWEsQ0FBQztpQkFDNUQ7WUFDSCxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNuQyxDQUFDOytHQXZPVSxnQkFBZ0I7bUhBQWhCLGdCQUFnQixjQUZmLE1BQU07OzRGQUVQLGdCQUFnQjtrQkFINUIsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7XHJcbiAgQmVoYXZpb3JTdWJqZWN0LFxyXG4gIE9ic2VydmFibGUsXHJcbiAgY2F0Y2hFcnJvcixcclxuICBtYXAsXHJcbiAgb2YsXHJcbn0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IEh0dHBTZXJ2aWNlIH0gZnJvbSAnQGllZWVzYS1ucG0vdXRpbGl0eSc7XHJcbmltcG9ydCB7IFVzZXJQZXJtaXNzaW9uIH0gZnJvbSAnQGllZWVzYS1ucG0vbW9kZWxzJztcclxuaW1wb3J0IHsgQXR0ZW5kYW5jZVN0YXRlIH0gZnJvbSAnLi4vbW9kZWxzL2F0dGVuZGFuY2Utc3RhdGUubW9kZWwnO1xyXG5pbXBvcnQgeyBEYXNoYm9hcmRMaXN0UmVzcG9uc2UgfSBmcm9tICcuLi9tb2RlbHMvZGFzaGJvYXJkLWxpc3QtcmVzcG9uc2UubW9kZWwnO1xyXG5pbXBvcnQgeyBEYXNoYm9hcmRTZWN0aW9uU3RhdGUgfSBmcm9tICcuLi9tb2RlbHMvZGFzaGJvYXJkLXNlY3Rpb24tc3RhdGUubW9kZWwnO1xyXG5pbXBvcnQgeyBHcm91cFJvdyB9IGZyb20gJy4uL21vZGVscy9ncm91cC1yb3cubW9kZWwnO1xyXG5pbXBvcnQgeyBVcGNvbWluZ0V2ZW50IH0gZnJvbSAnLi4vbW9kZWxzL3VwY29taW5nLWV2ZW50Lm1vZGVsJztcclxuaW1wb3J0IHtcclxuICBEYXNoYm9hcmRHcm91cHNNb2NrLFxyXG4gIERhc2hib2FyZFVwY29taW5nRXZlbnRzTW9jayxcclxufSBmcm9tICcuLi9hc3NldHMvZGFzaGJvYXJkLW1vY2snO1xyXG5pbXBvcnQge1xyXG4gIGFwcGx5TGVhdmVNZWV0aW5nU3VjY2VzcyxcclxuICBhcHBseUxvZ0F0dGVuZGFuY2VTdWNjZXNzLFxyXG4gIGJlZ2luQXR0ZW5kYW5jZUFjdGlvbixcclxuICBlbmRBdHRlbmRhbmNlQWN0aW9uLFxyXG59IGZyb20gJy4vYXR0ZW5kYW5jZS1yZWR1Y2Vycyc7XHJcblxyXG4vKipcclxuICogRGFzaGJvYXJkU2VydmljZSBpcyB0aGUgc2luZ2xlIHNvdXJjZSBvZiB0cnV0aCBmb3IgdGhlIGRhc2hib2FyZCBsYW5kaW5nXHJcbiAqIHBhZ2UncyBkYXRhIGFuZCBhdHRlbmRhbmNlIHN0YXRlLiBJdCBtaXJyb3JzIHRoZSBgZXZlbnRzLWFuZC1tZWV0aW5nc2BcclxuICogc2VydmljZSBjb252ZW50aW9uczogaXQgaXMgYSBgcHJvdmlkZWRJbjogJ3Jvb3QnYCBzaW5nbGV0b24sIGhvbGRzIHRoZSBob3N0XHJcbiAqIGBhcGlCYXNlVXJsYCAvIGB1c2VyUGVybWlzc2lvbnNgIHNldCB2aWEge0BsaW5rIHNldEFwcENvbmZpZ30sIG93bnMgaXRzIHN0YXRlXHJcbiAqIHZpYSBgQmVoYXZpb3JTdWJqZWN0YHMgZXhwb3NlZCBhcyBvYnNlcnZhYmxlcywgYW5kIHJlYWNoZXMgdGhlIGJhY2tlbmQgb25seVxyXG4gKiB0aHJvdWdoIHRoZSBzaGFyZWQgYEh0dHBTZXJ2aWNlYCBmcm9tIGBAaWVlZXNhLW5wbS91dGlsaXR5YCAobmV2ZXJcclxuICogYEh0dHBDbGllbnRgIGRpcmVjdGx5KS5cclxuICpcclxuICogVGhlIHVwY29taW5nLWV2ZW50cyBhbmQgZ3JvdXBzIGxvYWRzIGN1cnJlbnRseSByZXR1cm4gYW5ub3RhdGVkIG1vY2sgZGF0YVxyXG4gKiBiZWNhdXNlIHRoZWlyIGVuZHBvaW50cyBhcmUgbm90IHlldCBhdmFpbGFibGU7IHRoZSBhdHRlbmRhbmNlIGFjdGlvbnMgY29tcG9zZVxyXG4gKiB0aGUgcHVyZSByZWR1Y2VycyBmcm9tIGBhdHRlbmRhbmNlLXJlZHVjZXJzLnRzYCBzbyB0aGUgZGlzcGxheWVkXHJcbiAqIGBBdHRlbmRhbmNlU3RhdGVgIG9ubHkgYWR2YW5jZXMgb24gYSBzdWNjZXNzZnVsIHJlc29sdXRpb24gYW5kIHRoZSBwcmlvclxyXG4gKiBzdGF0ZSBpcyByZXRhaW5lZCBvbiBmYWlsdXJlLlxyXG4gKiBAZXhwb3J0XHJcbiAqIEBjbGFzcyBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAqL1xyXG5ASW5qZWN0YWJsZSh7XHJcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgRGFzaGJvYXJkU2VydmljZSB7XHJcbiAgYXBpQmFzZVVybCE6IHN0cmluZztcclxuICB1c2VyUGVybWlzc2lvbnMhOiBVc2VyUGVybWlzc2lvbltdO1xyXG5cclxuICBwcml2YXRlIHJlYWRvbmx5IHVwY29taW5nRXZlbnRzID0gbmV3IEJlaGF2aW9yU3ViamVjdDxVcGNvbWluZ0V2ZW50W10+KFtdKTtcclxuICBwcml2YXRlIHJlYWRvbmx5IGdyb3VwcyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8R3JvdXBSb3dbXT4oW10pO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgdXBjb21pbmdTdGF0ZSA9IG5ldyBCZWhhdmlvclN1YmplY3Q8RGFzaGJvYXJkU2VjdGlvblN0YXRlPihcclxuICAgIERhc2hib2FyZFNlY3Rpb25TdGF0ZS5MT0FESU5HXHJcbiAgKTtcclxuICBwcml2YXRlIHJlYWRvbmx5IGdyb3Vwc1N0YXRlID0gbmV3IEJlaGF2aW9yU3ViamVjdDxEYXNoYm9hcmRTZWN0aW9uU3RhdGU+KFxyXG4gICAgRGFzaGJvYXJkU2VjdGlvblN0YXRlLkxPQURJTkdcclxuICApO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgYXR0ZW5kYW5jZVN0YXRlcyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8XHJcbiAgICBSZWNvcmQ8c3RyaW5nLCBBdHRlbmRhbmNlU3RhdGU+XHJcbiAgPih7fSk7XHJcbiAgcHJpdmF0ZSByZWFkb25seSBpbkZsaWdodE1lZXRpbmdJZHMgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFxyXG4gICAgUmVhZG9ubHlTZXQ8c3RyaW5nPlxyXG4gID4obmV3IFNldDxzdHJpbmc+KCkpO1xyXG5cclxuICAvKiogRW1pdHMgdGhlIGxpc3Qgb2YgdGhlIHVzZXIncyB1cGNvbWluZyBldmVudHMuICovXHJcbiAgdXBjb21pbmdFdmVudHMkOiBPYnNlcnZhYmxlPFVwY29taW5nRXZlbnRbXT4gPVxyXG4gICAgdGhpcy51cGNvbWluZ0V2ZW50cy5hc09ic2VydmFibGUoKTtcclxuICAvKiogRW1pdHMgdGhlIGxpc3Qgb2YgdGhlIHVzZXIncyBncm91cHMuICovXHJcbiAgZ3JvdXBzJDogT2JzZXJ2YWJsZTxHcm91cFJvd1tdPiA9IHRoaXMuZ3JvdXBzLmFzT2JzZXJ2YWJsZSgpO1xyXG4gIC8qKiBFbWl0cyB0aGUgbG9hZC9lbXB0eS9lcnJvciBzdGF0ZSBvZiB0aGUgdXBjb21pbmctZXZlbnRzIHNlY3Rpb24uICovXHJcbiAgdXBjb21pbmdTdGF0ZSQ6IE9ic2VydmFibGU8RGFzaGJvYXJkU2VjdGlvblN0YXRlPiA9XHJcbiAgICB0aGlzLnVwY29taW5nU3RhdGUuYXNPYnNlcnZhYmxlKCk7XHJcbiAgLyoqIEVtaXRzIHRoZSBsb2FkL2VtcHR5L2Vycm9yIHN0YXRlIG9mIHRoZSBncm91cHMgc2VjdGlvbi4gKi9cclxuICBncm91cHNTdGF0ZSQ6IE9ic2VydmFibGU8RGFzaGJvYXJkU2VjdGlvblN0YXRlPiA9XHJcbiAgICB0aGlzLmdyb3Vwc1N0YXRlLmFzT2JzZXJ2YWJsZSgpO1xyXG4gIC8qKiBFbWl0cyB0aGUgcGVyLW1lZXRpbmcgYXR0ZW5kYW5jZS1zdGF0ZSBtYXAuICovXHJcbiAgYXR0ZW5kYW5jZVN0YXRlcyQ6IE9ic2VydmFibGU8UmVjb3JkPHN0cmluZywgQXR0ZW5kYW5jZVN0YXRlPj4gPVxyXG4gICAgdGhpcy5hdHRlbmRhbmNlU3RhdGVzLmFzT2JzZXJ2YWJsZSgpO1xyXG4gIC8qKiBFbWl0cyB0aGUgc2V0IG9mIG1lZXRpbmcgaWRzIHdpdGggYW4gYXR0ZW5kYW5jZSBhY3Rpb24gaW4gZmxpZ2h0LiAqL1xyXG4gIGluRmxpZ2h0TWVldGluZ0lkcyQ6IE9ic2VydmFibGU8UmVhZG9ubHlTZXQ8c3RyaW5nPj4gPVxyXG4gICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXVudXNlZC12YXJzXHJcbiAgICBwcml2YXRlIGh0dHBTZXJ2aWNlOiBIdHRwU2VydmljZSAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tZW1wdHktZnVuY3Rpb25cclxuICApIHt9XHJcblxyXG4gIC8qKlxyXG4gICAqIFN0b3JlcyB0aGUgaG9zdC1zdXBwbGllZCBBUEkgYmFzZSBVUkwgYW5kIHVzZXIgcGVybWlzc2lvbnMgdXNlZCB0byBidWlsZFxyXG4gICAqIHJlcXVlc3QgVVJMcyBhbmQgZ2F0ZSBwZXJtaXNzaW9uLWNvbnRyb2xsZWQgYWN0aW9ucy4gTWlycm9ycyB0aGVcclxuICAgKiBgZXZlbnRzLWFuZC1tZWV0aW5nc2Agc2VydmljZSBgc2V0QXBwQ29uZmlnYC5cclxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXBpQmFzZVVSTCAtIFRoZSBob3N0IGFwcGxpY2F0aW9uJ3MgQVBJIGJhc2UgVVJMLlxyXG4gICAqIEBwYXJhbSB7VXNlclBlcm1pc3Npb25bXX0gdXNlclBlcm1pc3Npb25zIC0gVGhlIHNpZ25lZC1pbiB1c2VyJ3MgcGVybWlzc2lvbnMuXHJcbiAgICogQHJldHVybiB7dm9pZH1cclxuICAgKiBAbWVtYmVyb2YgRGFzaGJvYXJkU2VydmljZVxyXG4gICAqL1xyXG4gIHNldEFwcENvbmZpZyhhcGlCYXNlVVJMOiBzdHJpbmcsIHVzZXJQZXJtaXNzaW9uczogVXNlclBlcm1pc3Npb25bXSk6IHZvaWQge1xyXG4gICAgdGhpcy5hcGlCYXNlVXJsID0gYXBpQmFzZVVSTDtcclxuICAgIHRoaXMudXNlclBlcm1pc3Npb25zID0gdXNlclBlcm1pc3Npb25zO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTG9hZHMgdGhlIHVzZXIncyB1cGNvbWluZyBldmVudHMsIGRyaXZpbmcgdGhlIHVwY29taW5nIHNlY3Rpb24gdGhyb3VnaFxyXG4gICAqIExPQURJTkcg4oaSIExPQURFRC9FTVBUWSBvbiBzdWNjZXNzIGFuZCBsZWF2aW5nIHRoZSBjYWxsZXIgdG8gc2V0IEVSUk9SIG9uXHJcbiAgICogZmFpbHVyZS4gRm9sbG93cyB0aGUgYHBpcGUobWFwLCBjYXRjaEVycm9yKHRocm93KSlgIHBhdHRlcm4gYW5kIHNlZWRzIHRoZVxyXG4gICAqIHBlci1tZWV0aW5nIGF0dGVuZGFuY2Utc3RhdGUgbWFwIGZyb20gdGhlIGxvYWRlZCBtZWV0aW5ncy5cclxuICAgKlxyXG4gICAqIFRPRE86IFJlcGxhY2UgbW9jayB3aXRoIHJlYWwgQVBJIGNhbGwgd2hlbiBCRSBpcyByZWFkeVxyXG4gICAqIEByZXR1cm4ge09ic2VydmFibGU8RGFzaGJvYXJkTGlzdFJlc3BvbnNlPFVwY29taW5nRXZlbnRbXT4+fSBUaGUgdXBjb21pbmctZXZlbnRzIHJlc3BvbnNlIGVudmVsb3BlLlxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgbG9hZFVwY29taW5nRXZlbnRzKCk6IE9ic2VydmFibGU8RGFzaGJvYXJkTGlzdFJlc3BvbnNlPFVwY29taW5nRXZlbnRbXT4+IHtcclxuICAgIHRoaXMudXBjb21pbmdTdGF0ZS5uZXh0KERhc2hib2FyZFNlY3Rpb25TdGF0ZS5MT0FESU5HKTtcclxuICAgIC8vIFRPRE86IFJlcGxhY2UgbW9jayB3aXRoIHJlYWwgQVBJIGNhbGwgd2hlbiBCRSBpcyByZWFkeVxyXG4gICAgY29uc3QgcmVzcG9uc2UkOiBPYnNlcnZhYmxlPERhc2hib2FyZExpc3RSZXNwb25zZTxVcGNvbWluZ0V2ZW50W10+PiA9IG9mKHtcclxuICAgICAgc3RhdHVzOiB0cnVlLFxyXG4gICAgICBib2R5OiBEYXNoYm9hcmRVcGNvbWluZ0V2ZW50c01vY2ssXHJcbiAgICB9KTtcclxuICAgIHJldHVybiByZXNwb25zZSQucGlwZShcclxuICAgICAgbWFwKChyZXNwb25zZSkgPT4ge1xyXG4gICAgICAgIGNvbnN0IGV2ZW50cyA9IHJlc3BvbnNlPy5ib2R5ID8/IFtdO1xyXG4gICAgICAgIHRoaXMudXBjb21pbmdFdmVudHMubmV4dChldmVudHMpO1xyXG4gICAgICAgIHRoaXMuc2VlZEF0dGVuZGFuY2VTdGF0ZXMoZXZlbnRzKTtcclxuICAgICAgICB0aGlzLnVwY29taW5nU3RhdGUubmV4dChcclxuICAgICAgICAgIGV2ZW50cy5sZW5ndGggPiAwXHJcbiAgICAgICAgICAgID8gRGFzaGJvYXJkU2VjdGlvblN0YXRlLkxPQURFRFxyXG4gICAgICAgICAgICA6IERhc2hib2FyZFNlY3Rpb25TdGF0ZS5FTVBUWVxyXG4gICAgICAgICk7XHJcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICB9KSxcclxuICAgICAgY2F0Y2hFcnJvcigoZXJyb3IpID0+IHtcclxuICAgICAgICB0aGlzLnVwY29taW5nU3RhdGUubmV4dChEYXNoYm9hcmRTZWN0aW9uU3RhdGUuRVJST1IpO1xyXG4gICAgICAgIHRocm93IGVycm9yO1xyXG4gICAgICB9KVxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIExvYWRzIHRoZSB1c2VyJ3MgZ3JvdXBzLCBkcml2aW5nIHRoZSBncm91cHMgc2VjdGlvbiB0aHJvdWdoXHJcbiAgICogTE9BRElORyDihpIgTE9BREVEL0VNUFRZIG9uIHN1Y2Nlc3MgYW5kIGxlYXZpbmcgdGhlIGNhbGxlciB0byBzZXQgRVJST1Igb25cclxuICAgKiBmYWlsdXJlLiBGb2xsb3dzIHRoZSBgcGlwZShtYXAsIGNhdGNoRXJyb3IodGhyb3cpKWAgcGF0dGVybi5cclxuICAgKlxyXG4gICAqIFRPRE86IFJlcGxhY2UgbW9jayB3aXRoIHJlYWwgQVBJIGNhbGwgd2hlbiBCRSBpcyByZWFkeVxyXG4gICAqIEByZXR1cm4ge09ic2VydmFibGU8RGFzaGJvYXJkTGlzdFJlc3BvbnNlPEdyb3VwUm93W10+Pn0gVGhlIGdyb3VwcyByZXNwb25zZSBlbnZlbG9wZS5cclxuICAgKiBAbWVtYmVyb2YgRGFzaGJvYXJkU2VydmljZVxyXG4gICAqL1xyXG4gIGxvYWRHcm91cHMoKTogT2JzZXJ2YWJsZTxEYXNoYm9hcmRMaXN0UmVzcG9uc2U8R3JvdXBSb3dbXT4+IHtcclxuICAgIHRoaXMuZ3JvdXBzU3RhdGUubmV4dChEYXNoYm9hcmRTZWN0aW9uU3RhdGUuTE9BRElORyk7XHJcbiAgICAvLyBUT0RPOiBSZXBsYWNlIG1vY2sgd2l0aCByZWFsIEFQSSBjYWxsIHdoZW4gQkUgaXMgcmVhZHlcclxuICAgIGNvbnN0IHJlc3BvbnNlJDogT2JzZXJ2YWJsZTxEYXNoYm9hcmRMaXN0UmVzcG9uc2U8R3JvdXBSb3dbXT4+ID0gb2Yoe1xyXG4gICAgICBzdGF0dXM6IHRydWUsXHJcbiAgICAgIGJvZHk6IERhc2hib2FyZEdyb3Vwc01vY2ssXHJcbiAgICB9KTtcclxuICAgIHJldHVybiByZXNwb25zZSQucGlwZShcclxuICAgICAgbWFwKChyZXNwb25zZSkgPT4ge1xyXG4gICAgICAgIGNvbnN0IGdyb3VwcyA9IHJlc3BvbnNlPy5ib2R5ID8/IFtdO1xyXG4gICAgICAgIHRoaXMuZ3JvdXBzLm5leHQoZ3JvdXBzKTtcclxuICAgICAgICB0aGlzLmdyb3Vwc1N0YXRlLm5leHQoXHJcbiAgICAgICAgICBncm91cHMubGVuZ3RoID4gMFxyXG4gICAgICAgICAgICA/IERhc2hib2FyZFNlY3Rpb25TdGF0ZS5MT0FERURcclxuICAgICAgICAgICAgOiBEYXNoYm9hcmRTZWN0aW9uU3RhdGUuRU1QVFlcclxuICAgICAgICApO1xyXG4gICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgfSksXHJcbiAgICAgIGNhdGNoRXJyb3IoKGVycm9yKSA9PiB7XHJcbiAgICAgICAgdGhpcy5ncm91cHNTdGF0ZS5uZXh0KERhc2hib2FyZFNlY3Rpb25TdGF0ZS5FUlJPUik7XHJcbiAgICAgICAgdGhyb3cgZXJyb3I7XHJcbiAgICAgIH0pXHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTG9ncyBhdHRlbmRhbmNlIGZvciBhIG1lZXRpbmcuIE1hcmtzIHRoZSBtZWV0aW5nIGluLWZsaWdodCAocmV0YWluaW5nIHRoZVxyXG4gICAqIHByaW9yIGRpc3BsYXllZCBzdGF0ZSksIHBvc3RzIHRocm91Z2ggYEh0dHBTZXJ2aWNlYCwgYXBwbGllcyB0aGVcclxuICAgKiBsb2ctYXR0ZW5kYW5jZS1zdWNjZXNzIHJlZHVjZXIgb24gc3VjY2VzcywgY2xlYXJzIHRoZSBpbi1mbGlnaHQgZmxhZyBvblxyXG4gICAqIGNvbXBsZXRpb24sIGFuZCByZXRocm93cyB3aGlsZSByZXRhaW5pbmcgcHJpb3Igc3RhdGUgb24gZmFpbHVyZS5cclxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWVldGluZ0lkIC0gVGhlIG1lZXRpbmcgdG8gbG9nIGF0dGVuZGFuY2UgZm9yLlxyXG4gICAqIEByZXR1cm4ge09ic2VydmFibGU8RGFzaGJvYXJkTGlzdFJlc3BvbnNlPHVua25vd24+Pn0gVGhlIGF0dGVuZGFuY2UgcmVzcG9uc2UgZW52ZWxvcGUuXHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBsb2dBdHRlbmRhbmNlKFxyXG4gICAgbWVldGluZ0lkOiBzdHJpbmdcclxuICApOiBPYnNlcnZhYmxlPERhc2hib2FyZExpc3RSZXNwb25zZTx1bmtub3duPj4ge1xyXG4gICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMubmV4dChcclxuICAgICAgYmVnaW5BdHRlbmRhbmNlQWN0aW9uKHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICApO1xyXG4gICAgcmV0dXJuIHRoaXMuaHR0cFNlcnZpY2VcclxuICAgICAgLnBvc3REYXRhKGAke3RoaXMuYXBpQmFzZVVybH0vbWVldGluZ3MvYXR0ZW5kYW5jZS9sb2dgLCB7IG1lZXRpbmdJZCB9KVxyXG4gICAgICAucGlwZShcclxuICAgICAgICBtYXAoKHJlc3BvbnNlKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLmF0dGVuZGFuY2VTdGF0ZXMubmV4dChcclxuICAgICAgICAgICAgYXBwbHlMb2dBdHRlbmRhbmNlU3VjY2Vzcyh0aGlzLmF0dGVuZGFuY2VTdGF0ZXMudmFsdWUsIG1lZXRpbmdJZClcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICB0aGlzLmluRmxpZ2h0TWVldGluZ0lkcy5uZXh0KFxyXG4gICAgICAgICAgICBlbmRBdHRlbmRhbmNlQWN0aW9uKHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pLFxyXG4gICAgICAgIGNhdGNoRXJyb3IoKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICAvLyBSZXRhaW4gcHJpb3IgYXR0ZW5kYW5jZSBzdGF0ZTsgb25seSBjbGVhciB0aGUgaW4tZmxpZ2h0IGZsYWcuXHJcbiAgICAgICAgICB0aGlzLmluRmxpZ2h0TWVldGluZ0lkcy5uZXh0KFxyXG4gICAgICAgICAgICBlbmRBdHRlbmRhbmNlQWN0aW9uKHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgdGhyb3cgZXJyb3I7XHJcbiAgICAgICAgfSlcclxuICAgICAgKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIExlYXZlcyBhIG1lZXRpbmcuIE1hcmtzIHRoZSBtZWV0aW5nIGluLWZsaWdodCAocmV0YWluaW5nIHRoZSBwcmlvclxyXG4gICAqIGRpc3BsYXllZCBzdGF0ZSksIHBvc3RzIHRocm91Z2ggYEh0dHBTZXJ2aWNlYCwgYXBwbGllcyB0aGVcclxuICAgKiBsZWF2ZS1tZWV0aW5nLXN1Y2Nlc3MgcmVkdWNlciBvbiBzdWNjZXNzLCBjbGVhcnMgdGhlIGluLWZsaWdodCBmbGFnIG9uXHJcbiAgICogY29tcGxldGlvbiwgYW5kIHJldGhyb3dzIHdoaWxlIHJldGFpbmluZyBwcmlvciBzdGF0ZSBvbiBmYWlsdXJlLlxyXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZWV0aW5nSWQgLSBUaGUgbWVldGluZyB0byBsZWF2ZS5cclxuICAgKiBAcmV0dXJuIHtPYnNlcnZhYmxlPERhc2hib2FyZExpc3RSZXNwb25zZTx1bmtub3duPj59IFRoZSBhdHRlbmRhbmNlIHJlc3BvbnNlIGVudmVsb3BlLlxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgbGVhdmVNZWV0aW5nKFxyXG4gICAgbWVldGluZ0lkOiBzdHJpbmdcclxuICApOiBPYnNlcnZhYmxlPERhc2hib2FyZExpc3RSZXNwb25zZTx1bmtub3duPj4ge1xyXG4gICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMubmV4dChcclxuICAgICAgYmVnaW5BdHRlbmRhbmNlQWN0aW9uKHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICApO1xyXG4gICAgcmV0dXJuIHRoaXMuaHR0cFNlcnZpY2VcclxuICAgICAgLnBvc3REYXRhKGAke3RoaXMuYXBpQmFzZVVybH0vbWVldGluZ3MvYXR0ZW5kYW5jZS9sZWF2ZWAsIHsgbWVldGluZ0lkIH0pXHJcbiAgICAgIC5waXBlKFxyXG4gICAgICAgIG1hcCgocmVzcG9uc2UpID0+IHtcclxuICAgICAgICAgIHRoaXMuYXR0ZW5kYW5jZVN0YXRlcy5uZXh0KFxyXG4gICAgICAgICAgICBhcHBseUxlYXZlTWVldGluZ1N1Y2Nlc3ModGhpcy5hdHRlbmRhbmNlU3RhdGVzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMubmV4dChcclxuICAgICAgICAgICAgZW5kQXR0ZW5kYW5jZUFjdGlvbih0aGlzLmluRmxpZ2h0TWVldGluZ0lkcy52YWx1ZSwgbWVldGluZ0lkKVxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICB9KSxcclxuICAgICAgICBjYXRjaEVycm9yKChlcnJvcikgPT4ge1xyXG4gICAgICAgICAgLy8gUmV0YWluIHByaW9yIGF0dGVuZGFuY2Ugc3RhdGU7IG9ubHkgY2xlYXIgdGhlIGluLWZsaWdodCBmbGFnLlxyXG4gICAgICAgICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMubmV4dChcclxuICAgICAgICAgICAgZW5kQXR0ZW5kYW5jZUFjdGlvbih0aGlzLmluRmxpZ2h0TWVldGluZ0lkcy52YWx1ZSwgbWVldGluZ0lkKVxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIHRocm93IGVycm9yO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXR1cm5zIGEgc3luY2hyb25vdXMgc25hcHNob3Qgb2YgdGhlIHBlci1tZWV0aW5nIGF0dGVuZGFuY2Utc3RhdGUgbWFwLlxyXG4gICAqIEByZXR1cm4ge1JlY29yZDxzdHJpbmcsIEF0dGVuZGFuY2VTdGF0ZT59IFRoZSBjdXJyZW50IGF0dGVuZGFuY2Utc3RhdGUgbWFwLlxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgZ2V0QXR0ZW5kYW5jZVN0YXRlc1NuYXBzaG90KCk6IFJlY29yZDxzdHJpbmcsIEF0dGVuZGFuY2VTdGF0ZT4ge1xyXG4gICAgcmV0dXJuIHRoaXMuYXR0ZW5kYW5jZVN0YXRlcy52YWx1ZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFNlZWRzIHRoZSBhdHRlbmRhbmNlLXN0YXRlIG1hcCBmcm9tIGEgZnJlc2hseSBsb2FkZWQgbGlzdCBvZiBldmVudHMsIHVzaW5nXHJcbiAgICogZWFjaCBtZWV0aW5nJ3MgYGF0dGVuZGFuY2VTdGF0ZWAgKGRlZmF1bHRpbmcgdG8gYE5PVF9BVFRFTkRJTkdgKS4gS2VlcHMgdGhlXHJcbiAgICogZGlzcGxheWVkIHN0YXRlIGluIHN5bmMgd2l0aCB0aGUgZGF0YSBsb2FkIHdpdGhvdXQgb3ZlcndyaXRpbmcgaWRzIHRoYXQgYXJlXHJcbiAgICogbm90IHByZXNlbnQgaW4gdGhlIG5ldyBsaXN0LlxyXG4gICAqIEBwYXJhbSB7VXBjb21pbmdFdmVudFtdfSBldmVudHMgLSBUaGUgbG9hZGVkIHVwY29taW5nIGV2ZW50cy5cclxuICAgKiBAcmV0dXJuIHt2b2lkfVxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBzZWVkQXR0ZW5kYW5jZVN0YXRlcyhldmVudHM6IFVwY29taW5nRXZlbnRbXSk6IHZvaWQge1xyXG4gICAgY29uc3QgbmV4dDogUmVjb3JkPHN0cmluZywgQXR0ZW5kYW5jZVN0YXRlPiA9IHtcclxuICAgICAgLi4udGhpcy5hdHRlbmRhbmNlU3RhdGVzLnZhbHVlLFxyXG4gICAgfTtcclxuICAgIGV2ZW50cy5mb3JFYWNoKChldmVudCkgPT4ge1xyXG4gICAgICBldmVudC5tZWV0aW5ncz8uZm9yRWFjaCgobWVldGluZykgPT4ge1xyXG4gICAgICAgIGlmIChtZWV0aW5nLm1lZXRpbmdJZCkge1xyXG4gICAgICAgICAgbmV4dFttZWV0aW5nLm1lZXRpbmdJZF0gPVxyXG4gICAgICAgICAgICBtZWV0aW5nLmF0dGVuZGFuY2VTdGF0ZSA/PyBBdHRlbmRhbmNlU3RhdGUuTk9UX0FUVEVORElORztcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgICB0aGlzLmF0dGVuZGFuY2VTdGF0ZXMubmV4dChuZXh0KTtcclxuICB9XHJcbn1cclxuIl19
|
|
402
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGFzaGJvYXJkLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9kYXNoYm9hcmQvc3JjL2xpYi9zZXJ2aWNlcy9kYXNoYm9hcmQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFDTCxlQUFlLEVBRWYsVUFBVSxFQUNWLEdBQUcsRUFDSCxFQUFFLEdBQ0gsTUFBTSxNQUFNLENBQUM7QUFHZCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFFbkUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFNaEYsT0FBTyxFQUVMLGdCQUFnQixHQUNqQixNQUFNLGdDQUFnQyxDQUFDO0FBU3hDLE9BQU8sRUFDTCxzQkFBc0IsRUFDdEIsbUJBQW1CLEdBQ3BCLE1BQU0sb0NBQW9DLENBQUM7QUFtQjVDLE9BQU8sRUFDTCx3QkFBd0IsRUFDeEIseUJBQXlCLEVBQ3pCLHFCQUFxQixFQUNyQixtQkFBbUIsR0FDcEIsTUFBTSx1QkFBdUIsQ0FBQzs7O0FBckIvQix5RkFBeUY7QUFDekYsTUFBTSxnQkFBZ0IsR0FBRyxZQUFZLENBQUM7QUFDdEMsMkNBQTJDO0FBQzNDLE1BQU0sV0FBVyxHQUFHLEdBQUcsQ0FBQztBQUN4QixnR0FBZ0c7QUFDaEcsTUFBTSxpQkFBaUIsR0FBRyxDQUFDLGFBQWEsRUFBRSxVQUFVLENBQUMsQ0FBQztBQUN0RCxpRUFBaUU7QUFDakUsTUFBTSxvQkFBb0IsR0FBRyxlQUFlLENBQUM7QUFDN0MscUZBQXFGO0FBQ3JGLE1BQU0sMEJBQTBCLEdBQUcsZUFBZSxDQUFDO0FBQ25ELGlFQUFpRTtBQUNqRSxNQUFNLGtCQUFrQixHQUFHLEVBQUUsQ0FBQztBQUM5QixvRUFBb0U7QUFDcEUsTUFBTSx3QkFBd0IsR0FBRyxDQUFDLENBQUM7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LENBQUMsS0FBSztTQUMvQixDQUFDO1FBQ0YsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQzNCLElBQUksT0FBTyxDQUFDLFNBQVMsRUFBRTtnQkFDckIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUM7b0JBQ3JCLE9BQU8sQ0FBQyxlQUFlO3dCQUN2QixJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQzt3QkFDdkIsZUFBZSxDQUFDLGFBQWEsQ0FBQzthQUNqQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNuQyxDQUFDOytHQTFjVSxnQkFBZ0I7bUhBQWhCLGdCQUFnQixjQUZmLE1BQU07OzRGQUVQLGdCQUFnQjtrQkFINUIsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7XHJcbiAgQmVoYXZpb3JTdWJqZWN0LFxyXG4gIE9ic2VydmFibGUsXHJcbiAgY2F0Y2hFcnJvcixcclxuICBtYXAsXHJcbiAgb2YsXHJcbn0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IEh0dHBTZXJ2aWNlIH0gZnJvbSAnQGllZWVzYS1ucG0vdXRpbGl0eSc7XHJcbmltcG9ydCB7IFVzZXJQZXJtaXNzaW9uIH0gZnJvbSAnQGllZWVzYS1ucG0vbW9kZWxzJztcclxuaW1wb3J0IHsgQXR0ZW5kYW5jZVN0YXRlIH0gZnJvbSAnLi4vbW9kZWxzL2F0dGVuZGFuY2Utc3RhdGUubW9kZWwnO1xyXG5pbXBvcnQgeyBEYXNoYm9hcmRMaXN0UmVzcG9uc2UgfSBmcm9tICcuLi9tb2RlbHMvZGFzaGJvYXJkLWxpc3QtcmVzcG9uc2UubW9kZWwnO1xyXG5pbXBvcnQgeyBEYXNoYm9hcmRTZWN0aW9uU3RhdGUgfSBmcm9tICcuLi9tb2RlbHMvZGFzaGJvYXJkLXNlY3Rpb24tc3RhdGUubW9kZWwnO1xyXG5pbXBvcnQgeyBHcm91cFJvdyB9IGZyb20gJy4uL21vZGVscy9ncm91cC1yb3cubW9kZWwnO1xyXG5pbXBvcnQge1xyXG4gIE15R3JvdXBzVmlldyxcclxuICBNeUdyb3VwVmlldyxcclxufSBmcm9tICcuLi9tb2RlbHMvbXktZ3JvdXBzLXZpZXcubW9kZWwnO1xyXG5pbXBvcnQge1xyXG4gIFVwY29taW5nRXZlbnQsXHJcbiAgVXBjb21pbmdJdGVtS2luZCxcclxufSBmcm9tICcuLi9tb2RlbHMvdXBjb21pbmctZXZlbnQubW9kZWwnO1xyXG5pbXBvcnQge1xyXG4gIEV2ZW50TWVldGluZ0RldGFpbFBheWxvYWQsXHJcbiAgRXZlbnRNZWV0aW5nTGlzdFBheWxvYWQsXHJcbn0gZnJvbSAnLi4vbW9kZWxzL2V2ZW50LW1lZXRpbmctbGlzdC1wYXlsb2FkLm1vZGVsJztcclxuaW1wb3J0IHtcclxuICBFdmVudE1lZXRpbmdEZXRhaWxSZXNwb25zZSxcclxuICBFdmVudE1lZXRpbmdMaXN0UmVzcG9uc2UsXHJcbn0gZnJvbSAnLi4vbW9kZWxzL2V2ZW50LW1lZXRpbmctbGlzdC1pdGVtLm1vZGVsJztcclxuaW1wb3J0IHtcclxuICBtYXBFdmVudE1lZXRpbmdEZXRhaWxzLFxyXG4gIG1hcEV2ZW50TWVldGluZ0xpc3QsXHJcbn0gZnJvbSAnLi4vdXRpbHMvZXZlbnQtbWVldGluZy1tYXBwZXIudXRpbCc7XHJcbmltcG9ydCB7IE1lZXRpbmdSb3cgfSBmcm9tICcuLi9tb2RlbHMvbWVldGluZy1yb3cubW9kZWwnO1xyXG5cclxuLyoqIEZhbGxiYWNrIGxhYmVsIGZvciBhbiBlbXB0eSBncm91cCB0eXBlIC8gbWVtYmVyIGxldmVsLCBtYXRjaGluZyB0aGUgTXkgR3JvdXBzIHRhYi4gKi9cclxuY29uc3QgVU5BU1NJR05FRF9MQUJFTCA9ICdVbmFzc2lnbmVkJztcclxuLyoqIFBsYWNlaG9sZGVyIGZvciBhbiBlbXB0eSBjZWxsIHZhbHVlLiAqL1xyXG5jb25zdCBFTVBUWV9WQUxVRSA9ICctJztcclxuLyoqIFN0YXR1c2VzIGluY2x1ZGVkIGluIHRoZSB1cGNvbWluZyBzZWN0aW9uLCBtYXRjaGluZyB0aGUgdmlldy1ldmVudHMtbWVldGluZ3MtbGlzdCBzY3JlZW4uICovXHJcbmNvbnN0IFVQQ09NSU5HX1NUQVRVU0VTID0gWydJbiBQcm9ncmVzcycsICdVcGNvbWluZyddO1xyXG4vKiogU29ydCBjb2x1bW4gdXNlZCBmb3IgdGhlIHRvcC1sZXZlbCBldmVudHMgJiBtZWV0aW5ncyBsaXN0LiAqL1xyXG5jb25zdCBVUENPTUlOR19TT1JUX0NPTFVNTiA9ICdzdGFydERhdGVUaW1lJztcclxuLyoqIFNvcnQgY29sdW1uIHVzZWQgZm9yIGFuIGV2ZW50J3MgZXhwYW5kZWQgY2hpbGQtbWVldGluZyBsaXN0IChtZWV0aW5nc0RldGFpbHMpLiAqL1xyXG5jb25zdCBFVkVOVF9NRUVUSU5HU19TT1JUX0NPTFVNTiA9ICdtZWV0aW5nU3REYXRlJztcclxuLyoqIERlZmF1bHQgcGFnZSBzaXplIGZvciB0aGUgdG9wLWxldmVsIHVwY29taW5nIHNlY3Rpb24gbGlzdC4gKi9cclxuY29uc3QgVVBDT01JTkdfUEFHRV9TSVpFID0gMTA7XHJcbi8qKiBEZWZhdWx0IHBhZ2Ugc2l6ZSBmb3IgYW4gZXZlbnQncyBleHBhbmRlZCBjaGlsZC1tZWV0aW5nIGxpc3QuICovXHJcbmNvbnN0IEVWRU5UX01FRVRJTkdTX1BBR0VfU0laRSA9IDU7XHJcbi8qKiBMYXJnZSBwYWdlIHNpemUgdXNlZCBieSB0aGUgZWFnZXIgY291bnQgcHJlZmV0Y2ggdG8gY2FwdHVyZSB0aGUgZnVsbCBzZXQuICovXHJcbmNvbnN0IEVWRU5UX0NPVU5UX1BBR0VfU0laRSA9IDIwMDtcclxuaW1wb3J0IHtcclxuICBhcHBseUxlYXZlTWVldGluZ1N1Y2Nlc3MsXHJcbiAgYXBwbHlMb2dBdHRlbmRhbmNlU3VjY2VzcyxcclxuICBiZWdpbkF0dGVuZGFuY2VBY3Rpb24sXHJcbiAgZW5kQXR0ZW5kYW5jZUFjdGlvbixcclxufSBmcm9tICcuL2F0dGVuZGFuY2UtcmVkdWNlcnMnO1xyXG5cclxuLyoqXHJcbiAqIERhc2hib2FyZFNlcnZpY2UgaXMgdGhlIHNpbmdsZSBzb3VyY2Ugb2YgdHJ1dGggZm9yIHRoZSBkYXNoYm9hcmQgbGFuZGluZ1xyXG4gKiBwYWdlJ3MgZGF0YSBhbmQgYXR0ZW5kYW5jZSBzdGF0ZS4gSXQgbWlycm9ycyB0aGUgYGV2ZW50cy1hbmQtbWVldGluZ3NgXHJcbiAqIHNlcnZpY2UgY29udmVudGlvbnM6IGl0IGlzIGEgYHByb3ZpZGVkSW46ICdyb290J2Agc2luZ2xldG9uLCBob2xkcyB0aGUgaG9zdFxyXG4gKiBgYXBpQmFzZVVybGAgLyBgdXNlclBlcm1pc3Npb25zYCBzZXQgdmlhIHtAbGluayBzZXRBcHBDb25maWd9LCBvd25zIGl0cyBzdGF0ZVxyXG4gKiB2aWEgYEJlaGF2aW9yU3ViamVjdGBzIGV4cG9zZWQgYXMgb2JzZXJ2YWJsZXMsIGFuZCByZWFjaGVzIHRoZSBiYWNrZW5kIG9ubHlcclxuICogdGhyb3VnaCB0aGUgc2hhcmVkIGBIdHRwU2VydmljZWAgZnJvbSBgQGllZWVzYS1ucG0vdXRpbGl0eWAgKG5ldmVyXHJcbiAqIGBIdHRwQ2xpZW50YCBkaXJlY3RseSkuXHJcbiAqXHJcbiAqIFRoZSB1cGNvbWluZy1ldmVudHMgbG9hZCBjYWxscyB0aGUgcmVhbCBgUE9TVCAvbWVldGluZ3MvZXZlbnRzQW5kTWVldGluZ3NgXHJcbiAqIGVuZHBvaW50IChjaGlsZCBtZWV0aW5ncyBhcmUgbGF6aWx5IGxvYWRlZCBwZXItZXZlbnQgdmlhXHJcbiAqIGBQT1NUIC9tZWV0aW5ncy9tZWV0aW5nc0RldGFpbHNgKTsgdGhlIGdyb3VwcyBsb2FkIGNhbGxzIGBHRVRcclxuICogL2dyb3Vwcy9teS1ncm91cHNgLiBUaGUgYXR0ZW5kYW5jZSBhY3Rpb25zIGNvbXBvc2UgdGhlIHB1cmUgcmVkdWNlcnMgZnJvbVxyXG4gKiBgYXR0ZW5kYW5jZS1yZWR1Y2Vycy50c2Agc28gdGhlIGRpc3BsYXllZCBgQXR0ZW5kYW5jZVN0YXRlYCBvbmx5IGFkdmFuY2VzIG9uIGFcclxuICogc3VjY2Vzc2Z1bCByZXNvbHV0aW9uIGFuZCB0aGUgcHJpb3Igc3RhdGUgaXMgcmV0YWluZWQgb24gZmFpbHVyZS5cclxuICogQGV4cG9ydFxyXG4gKiBAY2xhc3MgRGFzaGJvYXJkU2VydmljZVxyXG4gKi9cclxuQEluamVjdGFibGUoe1xyXG4gIHByb3ZpZGVkSW46ICdyb290JyxcclxufSlcclxuZXhwb3J0IGNsYXNzIERhc2hib2FyZFNlcnZpY2Uge1xyXG4gIGFwaUJhc2VVcmwhOiBzdHJpbmc7XHJcbiAgdXNlclBlcm1pc3Npb25zITogVXNlclBlcm1pc3Npb25bXTtcclxuXHJcbiAgcHJpdmF0ZSByZWFkb25seSB1cGNvbWluZ0V2ZW50cyA9IG5ldyBCZWhhdmlvclN1YmplY3Q8VXBjb21pbmdFdmVudFtdPihbXSk7XHJcbiAgcHJpdmF0ZSByZWFkb25seSBncm91cHMgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PEdyb3VwUm93W10+KFtdKTtcclxuICBwcml2YXRlIHJlYWRvbmx5IHVwY29taW5nU3RhdGUgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PERhc2hib2FyZFNlY3Rpb25TdGF0ZT4oXHJcbiAgICBEYXNoYm9hcmRTZWN0aW9uU3RhdGUuTE9BRElOR1xyXG4gICk7XHJcbiAgcHJpdmF0ZSByZWFkb25seSBncm91cHNTdGF0ZSA9IG5ldyBCZWhhdmlvclN1YmplY3Q8RGFzaGJvYXJkU2VjdGlvblN0YXRlPihcclxuICAgIERhc2hib2FyZFNlY3Rpb25TdGF0ZS5MT0FESU5HXHJcbiAgKTtcclxuICBwcml2YXRlIHJlYWRvbmx5IGF0dGVuZGFuY2VTdGF0ZXMgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFxyXG4gICAgUmVjb3JkPHN0cmluZywgQXR0ZW5kYW5jZVN0YXRlPlxyXG4gID4oe30pO1xyXG4gIHByaXZhdGUgcmVhZG9ubHkgaW5GbGlnaHRNZWV0aW5nSWRzID0gbmV3IEJlaGF2aW9yU3ViamVjdDxcclxuICAgIFJlYWRvbmx5U2V0PHN0cmluZz5cclxuICA+KG5ldyBTZXQ8c3RyaW5nPigpKTtcclxuXHJcbiAgLyoqIEVtaXRzIHRoZSBsaXN0IG9mIHRoZSB1c2VyJ3MgdXBjb21pbmcgZXZlbnRzLiAqL1xyXG4gIHVwY29taW5nRXZlbnRzJDogT2JzZXJ2YWJsZTxVcGNvbWluZ0V2ZW50W10+ID1cclxuICAgIHRoaXMudXBjb21pbmdFdmVudHMuYXNPYnNlcnZhYmxlKCk7XHJcbiAgLyoqIEVtaXRzIHRoZSBsaXN0IG9mIHRoZSB1c2VyJ3MgZ3JvdXBzLiAqL1xyXG4gIGdyb3VwcyQ6IE9ic2VydmFibGU8R3JvdXBSb3dbXT4gPSB0aGlzLmdyb3Vwcy5hc09ic2VydmFibGUoKTtcclxuICAvKiogRW1pdHMgdGhlIGxvYWQvZW1wdHkvZXJyb3Igc3RhdGUgb2YgdGhlIHVwY29taW5nLWV2ZW50cyBzZWN0aW9uLiAqL1xyXG4gIHVwY29taW5nU3RhdGUkOiBPYnNlcnZhYmxlPERhc2hib2FyZFNlY3Rpb25TdGF0ZT4gPVxyXG4gICAgdGhpcy51cGNvbWluZ1N0YXRlLmFzT2JzZXJ2YWJsZSgpO1xyXG4gIC8qKiBFbWl0cyB0aGUgbG9hZC9lbXB0eS9lcnJvciBzdGF0ZSBvZiB0aGUgZ3JvdXBzIHNlY3Rpb24uICovXHJcbiAgZ3JvdXBzU3RhdGUkOiBPYnNlcnZhYmxlPERhc2hib2FyZFNlY3Rpb25TdGF0ZT4gPVxyXG4gICAgdGhpcy5ncm91cHNTdGF0ZS5hc09ic2VydmFibGUoKTtcclxuICAvKiogRW1pdHMgdGhlIHBlci1tZWV0aW5nIGF0dGVuZGFuY2Utc3RhdGUgbWFwLiAqL1xyXG4gIGF0dGVuZGFuY2VTdGF0ZXMkOiBPYnNlcnZhYmxlPFJlY29yZDxzdHJpbmcsIEF0dGVuZGFuY2VTdGF0ZT4+ID1cclxuICAgIHRoaXMuYXR0ZW5kYW5jZVN0YXRlcy5hc09ic2VydmFibGUoKTtcclxuICAvKiogRW1pdHMgdGhlIHNldCBvZiBtZWV0aW5nIGlkcyB3aXRoIGFuIGF0dGVuZGFuY2UgYWN0aW9uIGluIGZsaWdodC4gKi9cclxuICBpbkZsaWdodE1lZXRpbmdJZHMkOiBPYnNlcnZhYmxlPFJlYWRvbmx5U2V0PHN0cmluZz4+ID1cclxuICAgIHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLmFzT2JzZXJ2YWJsZSgpO1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby11bnVzZWQtdmFyc1xyXG4gICAgcHJpdmF0ZSBodHRwU2VydmljZTogSHR0cFNlcnZpY2UgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWVtcHR5LWZ1bmN0aW9uXHJcbiAgKSB7fVxyXG5cclxuICAvKipcclxuICAgKiBTdG9yZXMgdGhlIGhvc3Qtc3VwcGxpZWQgQVBJIGJhc2UgVVJMIGFuZCB1c2VyIHBlcm1pc3Npb25zIHVzZWQgdG8gYnVpbGRcclxuICAgKiByZXF1ZXN0IFVSTHMgYW5kIGdhdGUgcGVybWlzc2lvbi1jb250cm9sbGVkIGFjdGlvbnMuIE1pcnJvcnMgdGhlXHJcbiAgICogYGV2ZW50cy1hbmQtbWVldGluZ3NgIHNlcnZpY2UgYHNldEFwcENvbmZpZ2AuXHJcbiAgICogQHBhcmFtIHtzdHJpbmd9IGFwaUJhc2VVUkwgLSBUaGUgaG9zdCBhcHBsaWNhdGlvbidzIEFQSSBiYXNlIFVSTC5cclxuICAgKiBAcGFyYW0ge1VzZXJQZXJtaXNzaW9uW119IHVzZXJQZXJtaXNzaW9ucyAtIFRoZSBzaWduZWQtaW4gdXNlcidzIHBlcm1pc3Npb25zLlxyXG4gICAqIEByZXR1cm4ge3ZvaWR9XHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBzZXRBcHBDb25maWcoYXBpQmFzZVVSTDogc3RyaW5nLCB1c2VyUGVybWlzc2lvbnM6IFVzZXJQZXJtaXNzaW9uW10pOiB2b2lkIHtcclxuICAgIHRoaXMuYXBpQmFzZVVybCA9IGFwaUJhc2VVUkw7XHJcbiAgICB0aGlzLnVzZXJQZXJtaXNzaW9ucyA9IHVzZXJQZXJtaXNzaW9ucztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIExvYWRzIHRoZSB1c2VyJ3MgdXBjb21pbmcgZXZlbnRzICYgbWVldGluZ3MgZnJvbSB0aGUgcmVhbCBiYWNrZW5kIHZpYVxyXG4gICAqIGBQT1NUIHthcGlCYXNlVXJsfS9tZWV0aW5ncy9ldmVudHNBbmRNZWV0aW5nc2AsIHRoZSBzYW1lIGVuZHBvaW50IHRoZVxyXG4gICAqIGB2aWV3LWV2ZW50cy1tZWV0aW5ncy1saXN0YCBzY3JlZW4gdXNlcy4gVGhlIHJlc3BvbnNlIGlzIG1hcHBlZCBpbnRvIHRoZVxyXG4gICAqIGRhc2hib2FyZCB2aWV3IG1vZGVscyAod2l0aCBTVEFOREFMT05FX01FRVRJTkcgcm93cyBvcmRlcmVkIGxhc3QpLCB0aGVcclxuICAgKiBwZXItbWVldGluZyBhdHRlbmRhbmNlLXN0YXRlIG1hcCBpcyBzZWVkZWQsIGFuZCB0aGUgc2VjdGlvbiBhZHZhbmNlcyB0aHJvdWdoXHJcbiAgICogTE9BRElORyDihpIgTE9BREVEL0VNUFRZIG9uIHN1Y2Nlc3MsIGxlYXZpbmcgdGhlIGNhbGxlciB0byBzZXQgRVJST1Igb25cclxuICAgKiBmYWlsdXJlLiBGb2xsb3dzIHRoZSBzaGFyZWQgYHBpcGUobWFwLCBjYXRjaEVycm9yKHRocm93KSlgIHBhdHRlcm4uXHJcbiAgICogQHJldHVybiB7T2JzZXJ2YWJsZTxFdmVudE1lZXRpbmdMaXN0UmVzcG9uc2U+fSBUaGUgdXBjb21pbmcgZXZlbnRzICYgbWVldGluZ3MgcmVzcG9uc2UgZW52ZWxvcGUuXHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBsb2FkVXBjb21pbmdFdmVudHMoKTogT2JzZXJ2YWJsZTxFdmVudE1lZXRpbmdMaXN0UmVzcG9uc2U+IHtcclxuICAgIHRoaXMudXBjb21pbmdTdGF0ZS5uZXh0KERhc2hib2FyZFNlY3Rpb25TdGF0ZS5MT0FESU5HKTtcclxuICAgIGNvbnN0IHBheWxvYWQ6IEV2ZW50TWVldGluZ0xpc3RQYXlsb2FkID0ge1xyXG4gICAgICBwYXlsb2FkOiB7XHJcbiAgICAgICAgZXZlbnRJZDogbnVsbCxcclxuICAgICAgICBzb3J0Q29sdW1uOiBVUENPTUlOR19TT1JUX0NPTFVNTixcclxuICAgICAgICBhc2NlbmRpbmdPcmRlcjogdHJ1ZSxcclxuICAgICAgICBwYWdlOiAxLFxyXG4gICAgICAgIHNpemU6IFVQQ09NSU5HX1BBR0VfU0laRSxcclxuICAgICAgICBmaWx0ZXI6IHtcclxuICAgICAgICAgIHN0YXR1czogVVBDT01JTkdfU1RBVFVTRVMsXHJcbiAgICAgICAgICBpc0FsbE1lZXRpbmdTZWxlY3RlZDogZmFsc2UsXHJcbiAgICAgICAgfSxcclxuICAgICAgfSxcclxuICAgIH07XHJcbiAgICByZXR1cm4gdGhpcy5odHRwU2VydmljZVxyXG4gICAgICAucG9zdERhdGEoYCR7dGhpcy5hcGlCYXNlVXJsfS9tZWV0aW5ncy9ldmVudHNBbmRNZWV0aW5nc2AsIHBheWxvYWQpXHJcbiAgICAgIC5waXBlKFxyXG4gICAgICAgIG1hcCgocmVzcG9uc2U6IEV2ZW50TWVldGluZ0xpc3RSZXNwb25zZSkgPT4ge1xyXG4gICAgICAgICAgY29uc3QgZXZlbnRzID0gbWFwRXZlbnRNZWV0aW5nTGlzdChcclxuICAgICAgICAgICAgcmVzcG9uc2U/LmJvZHk/LmV2ZW50TWVldGluZ0xpc3QgPz8gW11cclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICB0aGlzLnVwY29taW5nRXZlbnRzLm5leHQoZXZlbnRzKTtcclxuICAgICAgICAgIHRoaXMuc2VlZEF0dGVuZGFuY2VTdGF0ZXMoZXZlbnRzKTtcclxuICAgICAgICAgIHRoaXMudXBjb21pbmdTdGF0ZS5uZXh0KFxyXG4gICAgICAgICAgICBldmVudHMubGVuZ3RoID4gMFxyXG4gICAgICAgICAgICAgID8gRGFzaGJvYXJkU2VjdGlvblN0YXRlLkxPQURFRFxyXG4gICAgICAgICAgICAgIDogRGFzaGJvYXJkU2VjdGlvblN0YXRlLkVNUFRZXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgLy8gRWFnZXJseSBmZXRjaCBlYWNoIEVWRU5UJ3MgbWVldGluZyBjb3VudCBzbyB0aGUgXCJ7bn0gbWVldGluZ3NcIiBhbmRcclxuICAgICAgICAgIC8vIFwie259IG9wZW4gZm9yIGF0dGVuZGFuY2VcIiBzdW1tYXJpZXMgYXJlIGNvcnJlY3QgYmVmb3JlIGV4cGFuZGluZy5cclxuICAgICAgICAgIHRoaXMubG9hZEV2ZW50Q291bnRzKGV2ZW50cyk7XHJcbiAgICAgICAgICByZXR1cm4gcmVzcG9uc2U7XHJcbiAgICAgICAgfSksXHJcbiAgICAgICAgY2F0Y2hFcnJvcigoZXJyb3IpID0+IHtcclxuICAgICAgICAgIHRoaXMudXBjb21pbmdTdGF0ZS5uZXh0KERhc2hib2FyZFNlY3Rpb25TdGF0ZS5FUlJPUik7XHJcbiAgICAgICAgICB0aHJvdyBlcnJvcjtcclxuICAgICAgICB9KVxyXG4gICAgICApO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTGF6aWx5IGxvYWRzIChhbmQgcGFnaW5hdGVzKSB0aGUgY2hpbGQgbWVldGluZ3Mgb2YgYW4gRVZFTlQgcm93IHZpYVxyXG4gICAqIGBQT1NUIHthcGlCYXNlVXJsfS9tZWV0aW5ncy9tZWV0aW5nc0RldGFpbHNgIOKAlCB0aGUgcGVyLWV2ZW50IGV4cGFuZCBlbmRwb2ludFxyXG4gICAqIHVzZWQgYnkgdGhlIHJlZmVyZW5jZSBzY3JlZW4uIE9uIHN1Y2Nlc3MgdGhlIGxvYWRlZCBtZWV0aW5ncyBhcmUgbWFwcGVkIGFuZFxyXG4gICAqIG1lcmdlZCBvbnRvIHRoZSBtYXRjaGluZyBldmVudCBpbiB0aGUgYHVwY29taW5nRXZlbnRzYCBsaXN0ICh3aXRoIGl0c1xyXG4gICAqIGBtZWV0aW5nQ291bnRgIC8gYG9wZW5Gb3JBdHRlbmRhbmNlQ291bnRgIHJlZnJlc2hlZCksIGFuZCB0aGUgcGVyLW1lZXRpbmdcclxuICAgKiBhdHRlbmRhbmNlLXN0YXRlIG1hcCBpcyBleHRlbmRlZC4gRWFjaCBldmVudCBwYWdpbmF0ZXMgaW5kZXBlbmRlbnRseS5cclxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRJZCAtIFRoZSBldmVudCB3aG9zZSBtZWV0aW5ncyB0byBsb2FkLlxyXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbcGFnZT0xXSAtIFRoZSBvbmUtYmFzZWQgcGFnZSB0byByZXF1ZXN0LlxyXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBbc2l6ZT1FVkVOVF9NRUVUSU5HU19QQUdFX1NJWkVdIC0gVGhlIHBhZ2Ugc2l6ZS5cclxuICAgKiBAcmV0dXJuIHtPYnNlcnZhYmxlPEV2ZW50TWVldGluZ0RldGFpbFJlc3BvbnNlPn0gVGhlIGNoaWxkLW1lZXRpbmdzIHJlc3BvbnNlIGVudmVsb3BlLlxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgbG9hZEV2ZW50TWVldGluZ3MoXHJcbiAgICBldmVudElkOiBzdHJpbmcsXHJcbiAgICBwYWdlID0gMSxcclxuICAgIHNpemUgPSBFVkVOVF9NRUVUSU5HU19QQUdFX1NJWkVcclxuICApOiBPYnNlcnZhYmxlPEV2ZW50TWVldGluZ0RldGFpbFJlc3BvbnNlPiB7XHJcbiAgICByZXR1cm4gdGhpcy5mZXRjaEV2ZW50TWVldGluZ3NQYWdlKGV2ZW50SWQsIHBhZ2UsIHNpemUpLnBpcGUoXHJcbiAgICAgIG1hcCgocmVzcG9uc2U6IEV2ZW50TWVldGluZ0RldGFpbFJlc3BvbnNlKSA9PiB7XHJcbiAgICAgICAgY29uc3QgbWVldGluZ3MgPSBtYXBFdmVudE1lZXRpbmdEZXRhaWxzKFxyXG4gICAgICAgICAgcmVzcG9uc2U/LmJvZHk/Lm1lZXRpbmdzID8/IFtdXHJcbiAgICAgICAgKTtcclxuICAgICAgICBjb25zdCB0b3RhbCA9IHJlc3BvbnNlPy5ib2R5Py50b3RhbFJlY29yZHMgPz8gbWVldGluZ3MubGVuZ3RoO1xyXG4gICAgICAgIC8vIFByZWZlciB0aGUgYWxyZWFkeS1rbm93biBmdWxsIG9wZW4gY291bnQgb24gdGhlIGV2ZW50OyBmYWxsIGJhY2sgdG9cclxuICAgICAgICAvLyB0aGUgY3VycmVudCBwYWdlJ3Mgb3BlbiBjb3VudCB3aGVuIGl0IGhhc24ndCBiZWVuIHByZWZldGNoZWQuXHJcbiAgICAgICAgY29uc3QgZXhpc3RpbmcgPSB0aGlzLnVwY29taW5nRXZlbnRzLnZhbHVlLmZpbmQoXHJcbiAgICAgICAgICAoZXZlbnQpID0+IGV2ZW50LmV2ZW50SWQgPT09IGV2ZW50SWRcclxuICAgICAgICApO1xyXG4gICAgICAgIGNvbnN0IHBhZ2VPcGVuQ291bnQgPSBtZWV0aW5ncy5maWx0ZXIoXHJcbiAgICAgICAgICAobWVldGluZykgPT4gbWVldGluZy5pc09wZW5Gb3JBdHRlbmRhbmNlXHJcbiAgICAgICAgKS5sZW5ndGg7XHJcbiAgICAgICAgY29uc3Qgb3BlbkZvckF0dGVuZGFuY2VDb3VudCA9XHJcbiAgICAgICAgICBleGlzdGluZz8ub3BlbkZvckF0dGVuZGFuY2VDb3VudCB8fCBwYWdlT3BlbkNvdW50O1xyXG4gICAgICAgIHRoaXMubWVyZ2VFdmVudE1lZXRpbmdzKGV2ZW50SWQsIG1lZXRpbmdzLCB0b3RhbCwgb3BlbkZvckF0dGVuZGFuY2VDb3VudCk7XHJcbiAgICAgICAgdGhpcy5zZWVkQXR0ZW5kYW5jZVN0YXRlc0Zyb21NZWV0aW5ncyhtZWV0aW5ncyk7XHJcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICB9KSxcclxuICAgICAgY2F0Y2hFcnJvcigoZXJyb3IpID0+IHtcclxuICAgICAgICB0aHJvdyBlcnJvcjtcclxuICAgICAgfSlcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBNZXJnZXMgYSBmcmVzaGx5IGxvYWRlZCBwYWdlIG9mIGNoaWxkIG1lZXRpbmdzIG9udG8gdGhlIG1hdGNoaW5nIGV2ZW50IGluXHJcbiAgICogdGhlIGB1cGNvbWluZ0V2ZW50c2AgbGlzdCwgcmVmcmVzaGluZyB0aGUgZXZlbnQncyBgbWVldGluZ3NgLFxyXG4gICAqIGBtZWV0aW5nQ291bnRgIChmcm9tIHRoZSBiYWNrZW5kIGB0b3RhbFJlY29yZHNgKSwgYW5kXHJcbiAgICogYG9wZW5Gb3JBdHRlbmRhbmNlQ291bnRgLiBMZWF2ZXMgYWxsIG90aGVyIGV2ZW50cyB1bnRvdWNoZWQuXHJcbiAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50SWQgLSBUaGUgZXZlbnQgdG8gbWVyZ2UgbWVldGluZ3Mgb250by5cclxuICAgKiBAcGFyYW0ge01lZXRpbmdSb3dbXX0gbWVldGluZ3MgLSBUaGUgbWFwcGVkIGNoaWxkIG1lZXRpbmdzIGZvciB0aGUgcGFnZS5cclxuICAgKiBAcGFyYW0ge251bWJlcn0gdG90YWxSZWNvcmRzIC0gVGhlIGV2ZW50J3MgdG90YWwgbWVldGluZyBjb3VudCBmcm9tIHRoZSBiYWNrZW5kLlxyXG4gICAqIEByZXR1cm4ge3ZvaWR9XHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBwcml2YXRlIG1lcmdlRXZlbnRNZWV0aW5ncyhcclxuICAgIGV2ZW50SWQ6IHN0cmluZyxcclxuICAgIG1lZXRpbmdzOiBNZWV0aW5nUm93W10sXHJcbiAgICB0b3RhbFJlY29yZHM6IG51bWJlcixcclxuICAgIG9wZW5Gb3JBdHRlbmRhbmNlQ291bnQ6IG51bWJlclxyXG4gICk6IHZvaWQge1xyXG4gICAgY29uc3QgbmV4dCA9IHRoaXMudXBjb21pbmdFdmVudHMudmFsdWUubWFwKChldmVudCkgPT4ge1xyXG4gICAgICBpZiAoZXZlbnQuZXZlbnRJZCAhPT0gZXZlbnRJZCkge1xyXG4gICAgICAgIHJldHVybiBldmVudDtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIC4uLmV2ZW50LFxyXG4gICAgICAgIG1lZXRpbmdzLFxyXG4gICAgICAgIG1lZXRpbmdDb3VudDogdG90YWxSZWNvcmRzLFxyXG4gICAgICAgIG9wZW5Gb3JBdHRlbmRhbmNlQ291bnQsXHJcbiAgICAgIH07XHJcbiAgICB9KTtcclxuICAgIHRoaXMudXBjb21pbmdFdmVudHMubmV4dChuZXh0KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEVhZ2VybHkgZmV0Y2hlcyBlYWNoIEVWRU5UJ3MgdG90YWwgbWVldGluZyBjb3VudCBhbmQgb3Blbi1mb3ItYXR0ZW5kYW5jZVxyXG4gICAqIGNvdW50IGJ5IHJlcXVlc3RpbmcgYSBsYXJnZSBmaXJzdCBwYWdlIG9mIGl0cyBjaGlsZCBtZWV0aW5ncywgdGhlbiBtZXJnaW5nXHJcbiAgICogb25seSB0aGUgY291bnRzIChub3QgdGhlIHJvd3MpIHNvIHRoZSBjb2xsYXBzZWQgY2FyZCBzdW1tYXJpZXMgYXJlIGFjY3VyYXRlXHJcbiAgICogYmVmb3JlIHRoZSB1c2VyIGV4cGFuZHMuIFN0YW5kYWxvbmUgbWVldGluZ3MgYXJlIHNraXBwZWQuIEZhaWx1cmVzIHBlciBldmVudFxyXG4gICAqIGFyZSBzd2FsbG93ZWQgc28gb25lIGZhaWxpbmcgY291bnQgbmV2ZXIgYnJlYWtzIHRoZSBsaXN0LlxyXG4gICAqIEBwYXJhbSB7VXBjb21pbmdFdmVudFtdfSBldmVudHMgLSBUaGUgbG9hZGVkIGV2ZW50cyB0byBmZXRjaCBjb3VudHMgZm9yLlxyXG4gICAqIEByZXR1cm4ge3ZvaWR9XHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBwcml2YXRlIGxvYWRFdmVudENvdW50cyhldmVudHM6IFVwY29taW5nRXZlbnRbXSk6IHZvaWQge1xyXG4gICAgZXZlbnRzXHJcbiAgICAgIC5maWx0ZXIoKGV2ZW50KSA9PiBldmVudC5raW5kID09PSBVcGNvbWluZ0l0ZW1LaW5kLkVWRU5UICYmIGV2ZW50LmV2ZW50SWQpXHJcbiAgICAgIC5mb3JFYWNoKChldmVudCkgPT4ge1xyXG4gICAgICAgIHRoaXMuZmV0Y2hFdmVudE1lZXRpbmdzUGFnZShldmVudC5ldmVudElkLCAxLCBFVkVOVF9DT1VOVF9QQUdFX1NJWkUpXHJcbiAgICAgICAgICAucGlwZShcclxuICAgICAgICAgICAgY2F0Y2hFcnJvcigoKSA9PiBvZihudWxsKSlcclxuICAgICAgICAgIClcclxuICAgICAgICAgIC5zdWJzY3JpYmUoKHJlc3BvbnNlKSA9PiB7XHJcbiAgICAgICAgICAgIGlmICghcmVzcG9uc2UpIHtcclxuICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY29uc3QgbWVldGluZ3MgPSBtYXBFdmVudE1lZXRpbmdEZXRhaWxzKFxyXG4gICAgICAgICAgICAgIHJlc3BvbnNlPy5ib2R5Py5tZWV0aW5ncyA/PyBbXVxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgICAgICBjb25zdCB0b3RhbCA9IHJlc3BvbnNlPy5ib2R5Py50b3RhbFJlY29yZHMgPz8gbWVldGluZ3MubGVuZ3RoO1xyXG4gICAgICAgICAgICBjb25zdCBvcGVuQ291bnQgPSBtZWV0aW5ncy5maWx0ZXIoXHJcbiAgICAgICAgICAgICAgKG1lZXRpbmcpID0+IG1lZXRpbmcuaXNPcGVuRm9yQXR0ZW5kYW5jZVxyXG4gICAgICAgICAgICApLmxlbmd0aDtcclxuICAgICAgICAgICAgdGhpcy5tZXJnZUV2ZW50Q291bnRzKGV2ZW50LmV2ZW50SWQsIHRvdGFsLCBvcGVuQ291bnQpO1xyXG4gICAgICAgICAgICB0aGlzLnNlZWRBdHRlbmRhbmNlU3RhdGVzRnJvbU1lZXRpbmdzKG1lZXRpbmdzKTtcclxuICAgICAgICAgIH0pO1xyXG4gICAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE1lcmdlcyBvbmx5IHRoZSBtZWV0aW5nIGNvdW50cyBvbnRvIHRoZSBtYXRjaGluZyBldmVudCwgbGVhdmluZyBpdHNcclxuICAgKiBgbWVldGluZ3NgIHJvd3MgdW50b3VjaGVkICh1c2VkIGJ5IHRoZSBlYWdlciBjb3VudCBwcmVmZXRjaCkuXHJcbiAgICogQHBhcmFtIHtzdHJpbmd9IGV2ZW50SWQgLSBUaGUgZXZlbnQgdG8gdXBkYXRlLlxyXG4gICAqIEBwYXJhbSB7bnVtYmVyfSB0b3RhbFJlY29yZHMgLSBUaGUgZXZlbnQncyB0b3RhbCBtZWV0aW5nIGNvdW50LlxyXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBvcGVuRm9yQXR0ZW5kYW5jZUNvdW50IC0gVGhlIG9wZW4tZm9yLWF0dGVuZGFuY2UgY291bnQuXHJcbiAgICogQHJldHVybiB7dm9pZH1cclxuICAgKiBAbWVtYmVyb2YgRGFzaGJvYXJkU2VydmljZVxyXG4gICAqL1xyXG4gIHByaXZhdGUgbWVyZ2VFdmVudENvdW50cyhcclxuICAgIGV2ZW50SWQ6IHN0cmluZyxcclxuICAgIHRvdGFsUmVjb3JkczogbnVtYmVyLFxyXG4gICAgb3BlbkZvckF0dGVuZGFuY2VDb3VudDogbnVtYmVyXHJcbiAgKTogdm9pZCB7XHJcbiAgICBjb25zdCBuZXh0ID0gdGhpcy51cGNvbWluZ0V2ZW50cy52YWx1ZS5tYXAoKGV2ZW50KSA9PlxyXG4gICAgICBldmVudC5ldmVudElkID09PSBldmVudElkXHJcbiAgICAgICAgPyB7IC4uLmV2ZW50LCBtZWV0aW5nQ291bnQ6IHRvdGFsUmVjb3Jkcywgb3BlbkZvckF0dGVuZGFuY2VDb3VudCB9XHJcbiAgICAgICAgOiBldmVudFxyXG4gICAgKTtcclxuICAgIHRoaXMudXBjb21pbmdFdmVudHMubmV4dChuZXh0KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEJ1aWxkcyBhbmQgcG9zdHMgdGhlIGBtZWV0aW5nc0RldGFpbHNgIHJlcXVlc3QgZm9yIGEgc2luZ2xlIGV2ZW50IHBhZ2UsXHJcbiAgICogcmV0dXJuaW5nIHRoZSByYXcgcmVzcG9uc2UgZW52ZWxvcGUuIFNoYXJlZCBieSB7QGxpbmsgbG9hZEV2ZW50TWVldGluZ3N9IGFuZFxyXG4gICAqIHRoZSBlYWdlciBjb3VudCBwcmVmZXRjaC5cclxuICAgKiBAcGFyYW0ge3N0cmluZ30gZXZlbnRJZCAtIFRoZSBldmVudCB3aG9zZSBtZWV0aW5ncyB0byBmZXRjaC5cclxuICAgKiBAcGFyYW0ge251bWJlcn0gcGFnZSAtIFRoZSBvbmUtYmFzZWQgcGFnZSB0byByZXF1ZXN0LlxyXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBzaXplIC0gVGhlIHBhZ2Ugc2l6ZS5cclxuICAgKiBAcmV0dXJuIHtPYnNlcnZhYmxlPEV2ZW50TWVldGluZ0RldGFpbFJlc3BvbnNlPn0gVGhlIGNoaWxkLW1lZXRpbmdzIHJlc3BvbnNlLlxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBmZXRjaEV2ZW50TWVldGluZ3NQYWdlKFxyXG4gICAgZXZlbnRJZDogc3RyaW5nLFxyXG4gICAgcGFnZTogbnVtYmVyLFxyXG4gICAgc2l6ZTogbnVtYmVyXHJcbiAgKTogT2JzZXJ2YWJsZTxFdmVudE1lZXRpbmdEZXRhaWxSZXNwb25zZT4ge1xyXG4gICAgY29uc3QgcGF5bG9hZDogRXZlbnRNZWV0aW5nRGV0YWlsUGF5bG9hZCA9IHtcclxuICAgICAgcGF5bG9hZDoge1xyXG4gICAgICAgIGV2ZW50SWQsXHJcbiAgICAgICAgc29ydENvbHVtbjogRVZFTlRfTUVFVElOR1NfU09SVF9DT0xVTU4sXHJcbiAgICAgICAgYXNjZW5kaW5nT3JkZXI6IHRydWUsXHJcbiAgICAgICAgcGFnZSxcclxuICAgICAgICBzaXplLFxyXG4gICAgICAgIGZpbHRlcjoge1xyXG4gICAgICAgICAgc3RhdHVzOiBVUENPTUlOR19TVEFUVVNFUyxcclxuICAgICAgICAgIGlzQWxsTWVldGluZ1NlbGVjdGVkOiBmYWxzZSxcclxuICAgICAgICB9LFxyXG4gICAgICB9LFxyXG4gICAgfTtcclxuICAgIHJldHVybiB0aGlzLmh0dHBTZXJ2aWNlLnBvc3REYXRhKFxyXG4gICAgICBgJHt0aGlzLmFwaUJhc2VVcmx9L21lZXRpbmdzL21lZXRpbmdzRGV0YWlsc2AsXHJcbiAgICAgIHBheWxvYWRcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBMb2FkcyB0aGUgdXNlcidzIGdyb3VwcywgZHJpdmluZyB0aGUgZ3JvdXBzIHNlY3Rpb24gdGhyb3VnaFxyXG4gICAqIExPQURJTkcg4oaSIExPQURFRC9FTVBUWSBvbiBzdWNjZXNzIGFuZCBsZWF2aW5nIHRoZSBjYWxsZXIgdG8gc2V0IEVSUk9SIG9uXHJcbiAgICogZmFpbHVyZS4gRm9sbG93cyB0aGUgYHBpcGUobWFwLCBjYXRjaEVycm9yKHRocm93KSlgIHBhdHRlcm4uXHJcbiAgICpcclxuICAgKiBUT0RPOiBSZXBsYWNlIG1vY2sgd2l0aCByZWFsIEFQSSBjYWxsIHdoZW4gQkUgaXMgcmVhZHlcclxuICAgKiBAcmV0dXJuIHtPYnNlcnZhYmxlPERhc2hib2FyZExpc3RSZXNwb25zZTxHcm91cFJvd1tdPj59IFRoZSBncm91cHMgcmVzcG9uc2UgZW52ZWxvcGUuXHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBsb2FkR3JvdXBzKCk6IE9ic2VydmFibGU8RGFzaGJvYXJkTGlzdFJlc3BvbnNlPE15R3JvdXBzVmlldz4+IHtcclxuICAgIHRoaXMuZ3JvdXBzU3RhdGUubmV4dChEYXNoYm9hcmRTZWN0aW9uU3RhdGUuTE9BRElORyk7XHJcbiAgICByZXR1cm4gdGhpcy5odHRwU2VydmljZVxyXG4gICAgICAuZ2V0RGF0YShgJHt0aGlzLmFwaUJhc2VVcmx9L2dyb3Vwcy9teS1ncm91cHNgKVxyXG4gICAgICAucGlwZShcclxuICAgICAgICBtYXAoKHJlc3BvbnNlOiBEYXNoYm9hcmRMaXN0UmVzcG9uc2U8TXlHcm91cHNWaWV3PikgPT4ge1xyXG4gICAgICAgICAgY29uc3QgZ3JvdXBzID0gKHJlc3BvbnNlPy5ib2R5Py5ncm91cHMgPz8gW10pLm1hcCgoZ3JvdXApID0+XHJcbiAgICAgICAgICAgIHRoaXMubWFwR3JvdXAoZ3JvdXApXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgdGhpcy5ncm91cHMubmV4dChncm91cHMpO1xyXG4gICAgICAgICAgdGhpcy5ncm91cHNTdGF0ZS5uZXh0KFxyXG4gICAgICAgICAgICBncm91cHMubGVuZ3RoID4gMFxyXG4gICAgICAgICAgICAgID8gRGFzaGJvYXJkU2VjdGlvblN0YXRlLkxPQURFRFxyXG4gICAgICAgICAgICAgIDogRGFzaGJvYXJkU2VjdGlvblN0YXRlLkVNUFRZXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pLFxyXG4gICAgICAgIGNhdGNoRXJyb3IoKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLmdyb3Vwc1N0YXRlLm5leHQoRGFzaGJvYXJkU2VjdGlvblN0YXRlLkVSUk9SKTtcclxuICAgICAgICAgIHRocm93IGVycm9yO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBNYXBzIGEgYmFja2VuZCB7QGxpbmsgTXlHcm91cFZpZXd9IHRvIHRoZSB0YWJsZS1mYWNpbmcge0BsaW5rIEdyb3VwUm93fS5cclxuICAgKiBNaXJyb3JzIHRoZSBNeSBHcm91cHMgcHJvZmlsZSB0YWI6IHRoZSB0eXBlIGZhbGxzIGJhY2sgdG8gXCJVbmFzc2lnbmVkXCIgd2hlblxyXG4gICAqIGBncm91cFR5cGVOYW1lYCBpcyBudWxsLCBhZmZpbGlhdGlvbnMgYXJlIGNvbW1hLWpvaW5lZCwgZW1wdHkgb2ZmaWNlciByb2xlIC9cclxuICAgKiBhZmZpbGlhdGlvbiByZW5kZXIgYXMgYSBwbGFjZWhvbGRlciwgYW5kIGEgYmxhbmsgbWVtYmVyIGxldmVsIGJlY29tZXNcclxuICAgKiBcIlVuYXNzaWduZWRcIiAocmVuZGVyZWQgYXMgdGhlIHdhcm5pbmcgcGlsbCBieSB0aGUgWW91ciBHcm91cHMgY29tcG9uZW50KS5cclxuICAgKiBAcGFyYW0ge015R3JvdXBWaWV3fSBncm91cCAtIFRoZSBiYWNrZW5kIGdyb3VwIHZpZXcuXHJcbiAgICogQHJldHVybiB7R3JvdXBSb3d9XHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBwcml2YXRlIG1hcEdyb3VwKGdyb3VwOiBNeUdyb3VwVmlldyk6IEdyb3VwUm93IHtcclxuICAgIC8vIFRoZSBiYWNrZW5kIHJldHVybnMgb2ZmaWNlciByb2xlcyBhcyBhbiBgb2ZmaWNlcmAgYXJyYXkgb2ZcclxuICAgIC8vIHsgb2ZmaWNlcklkLCBvZmZpY2VyTmFtZSB9LiBKb2luIHRoZSBuYW1lcyBmb3IgdGhlIE9mZmljZXIgUm9sZSBjb2x1bW5cclxuICAgIC8vIChlLmcuIFwiQ2hhaXJcIiBvciBcIkNoYWlyLCBWaWNlIENoYWlyXCIpOyBzaG93IHRoZSBwbGFjZWhvbGRlciB3aGVuIGVtcHR5LlxyXG4gICAgY29uc3Qgb2ZmaWNlclJvbGUgPVxyXG4gICAgICAoZ3JvdXAub2ZmaWNlciA/PyBbXSlcclxuICAgICAgICAubWFwKChvZmZpY2VyKSA9PiBvZmZpY2VyPy5vZmZpY2VyTmFtZT8udHJpbSgpKVxyXG4gICAgICAgIC5maWx0ZXIoKG5hbWUpID0+ICEhbmFtZSlcclxuICAgICAgICAuam9pbignLCAnKSB8fCBFTVBUWV9WQUxVRTtcclxuXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBncm91cElkOiBncm91cC5ncm91cElkLFxyXG4gICAgICBncm91cDogZ3JvdXAuZ3JvdXBOYW1lLFxyXG4gICAgICB0eXBlOiBncm91cC5ncm91cFR5cGVOYW1lIHx8IGdyb3VwLmdyb3VwVHlwZSB8fCBVTkFTU0lHTkVEX0xBQkVMLFxyXG4gICAgICBvZmZpY2VyUm9sZSxcclxuICAgICAgYWZmaWxpYXRpb246IGdyb3VwLmFmZmlsaWF0aW9ucz8uam9pbignLCAnKSB8fCBFTVBUWV9WQUxVRSxcclxuICAgICAgbWVtYmVyTGV2ZWw6IGdyb3VwLm1lbWJlckxldmVsPy50cmltKCkgfHwgVU5BU1NJR05FRF9MQUJFTCxcclxuICAgICAgLy8gQ2FycnkgdGhlIGFuY2VzdG9yIGhpZXJhcmNoeSB0aHJvdWdoIGZvciB0aGUgZXhwYW5kYWJsZSBoaWVyYXJjaHkgcm93cy5cclxuICAgICAgaGllcmFyY2h5OiBncm91cC5oaWVyYXJjaHkgPz8gW10sXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTG9ncyBhdHRlbmRhbmNlIGZvciBhIG1lZXRpbmcuIE1hcmtzIHRoZSBtZWV0aW5nIGluLWZsaWdodCAocmV0YWluaW5nIHRoZVxyXG4gICAqIHByaW9yIGRpc3BsYXllZCBzdGF0ZSksIHBvc3RzIHRocm91Z2ggYEh0dHBTZXJ2aWNlYCwgYXBwbGllcyB0aGVcclxuICAgKiBsb2ctYXR0ZW5kYW5jZS1zdWNjZXNzIHJlZHVjZXIgb24gc3VjY2VzcywgY2xlYXJzIHRoZSBpbi1mbGlnaHQgZmxhZyBvblxyXG4gICAqIGNvbXBsZXRpb24sIGFuZCByZXRocm93cyB3aGlsZSByZXRhaW5pbmcgcHJpb3Igc3RhdGUgb24gZmFpbHVyZS5cclxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWVldGluZ0lkIC0gVGhlIG1lZXRpbmcgdG8gbG9nIGF0dGVuZGFuY2UgZm9yLlxyXG4gICAqIEByZXR1cm4ge09ic2VydmFibGU8RGFzaGJvYXJkTGlzdFJlc3BvbnNlPHVua25vd24+Pn0gVGhlIGF0dGVuZGFuY2UgcmVzcG9uc2UgZW52ZWxvcGUuXHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBsb2dBdHRlbmRhbmNlKFxyXG4gICAgbWVldGluZ0lkOiBzdHJpbmdcclxuICApOiBPYnNlcnZhYmxlPERhc2hib2FyZExpc3RSZXNwb25zZTx1bmtub3duPj4ge1xyXG4gICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMubmV4dChcclxuICAgICAgYmVnaW5BdHRlbmRhbmNlQWN0aW9uKHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICApO1xyXG4gICAgcmV0dXJuIHRoaXMuaHR0cFNlcnZpY2VcclxuICAgICAgLnBvc3REYXRhKGAke3RoaXMuYXBpQmFzZVVybH0vbWVldGluZ3MvYXR0ZW5kYW5jZS9sb2dgLCB7IG1lZXRpbmdJZCB9KVxyXG4gICAgICAucGlwZShcclxuICAgICAgICBtYXAoKHJlc3BvbnNlKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLmF0dGVuZGFuY2VTdGF0ZXMubmV4dChcclxuICAgICAgICAgICAgYXBwbHlMb2dBdHRlbmRhbmNlU3VjY2Vzcyh0aGlzLmF0dGVuZGFuY2VTdGF0ZXMudmFsdWUsIG1lZXRpbmdJZClcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICB0aGlzLmluRmxpZ2h0TWVldGluZ0lkcy5uZXh0KFxyXG4gICAgICAgICAgICBlbmRBdHRlbmRhbmNlQWN0aW9uKHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgcmV0dXJuIHJlc3BvbnNlO1xyXG4gICAgICAgIH0pLFxyXG4gICAgICAgIGNhdGNoRXJyb3IoKGVycm9yKSA9PiB7XHJcbiAgICAgICAgICAvLyBSZXRhaW4gcHJpb3IgYXR0ZW5kYW5jZSBzdGF0ZTsgb25seSBjbGVhciB0aGUgaW4tZmxpZ2h0IGZsYWcuXHJcbiAgICAgICAgICB0aGlzLmluRmxpZ2h0TWVldGluZ0lkcy5uZXh0KFxyXG4gICAgICAgICAgICBlbmRBdHRlbmRhbmNlQWN0aW9uKHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgdGhyb3cgZXJyb3I7XHJcbiAgICAgICAgfSlcclxuICAgICAgKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIExlYXZlcyBhIG1lZXRpbmcuIE1hcmtzIHRoZSBtZWV0aW5nIGluLWZsaWdodCAocmV0YWluaW5nIHRoZSBwcmlvclxyXG4gICAqIGRpc3BsYXllZCBzdGF0ZSksIHBvc3RzIHRocm91Z2ggYEh0dHBTZXJ2aWNlYCwgYXBwbGllcyB0aGVcclxuICAgKiBsZWF2ZS1tZWV0aW5nLXN1Y2Nlc3MgcmVkdWNlciBvbiBzdWNjZXNzLCBjbGVhcnMgdGhlIGluLWZsaWdodCBmbGFnIG9uXHJcbiAgICogY29tcGxldGlvbiwgYW5kIHJldGhyb3dzIHdoaWxlIHJldGFpbmluZyBwcmlvciBzdGF0ZSBvbiBmYWlsdXJlLlxyXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBtZWV0aW5nSWQgLSBUaGUgbWVldGluZyB0byBsZWF2ZS5cclxuICAgKiBAcmV0dXJuIHtPYnNlcnZhYmxlPERhc2hib2FyZExpc3RSZXNwb25zZTx1bmtub3duPj59IFRoZSBhdHRlbmRhbmNlIHJlc3BvbnNlIGVudmVsb3BlLlxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgbGVhdmVNZWV0aW5nKFxyXG4gICAgbWVldGluZ0lkOiBzdHJpbmdcclxuICApOiBPYnNlcnZhYmxlPERhc2hib2FyZExpc3RSZXNwb25zZTx1bmtub3duPj4ge1xyXG4gICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMubmV4dChcclxuICAgICAgYmVnaW5BdHRlbmRhbmNlQWN0aW9uKHRoaXMuaW5GbGlnaHRNZWV0aW5nSWRzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICApO1xyXG4gICAgcmV0dXJuIHRoaXMuaHR0cFNlcnZpY2VcclxuICAgICAgLnBvc3REYXRhKGAke3RoaXMuYXBpQmFzZVVybH0vbWVldGluZ3MvYXR0ZW5kYW5jZS9sZWF2ZWAsIHsgbWVldGluZ0lkIH0pXHJcbiAgICAgIC5waXBlKFxyXG4gICAgICAgIG1hcCgocmVzcG9uc2UpID0+IHtcclxuICAgICAgICAgIHRoaXMuYXR0ZW5kYW5jZVN0YXRlcy5uZXh0KFxyXG4gICAgICAgICAgICBhcHBseUxlYXZlTWVldGluZ1N1Y2Nlc3ModGhpcy5hdHRlbmRhbmNlU3RhdGVzLnZhbHVlLCBtZWV0aW5nSWQpXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMubmV4dChcclxuICAgICAgICAgICAgZW5kQXR0ZW5kYW5jZUFjdGlvbih0aGlzLmluRmxpZ2h0TWVldGluZ0lkcy52YWx1ZSwgbWVldGluZ0lkKVxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIHJldHVybiByZXNwb25zZTtcclxuICAgICAgICB9KSxcclxuICAgICAgICBjYXRjaEVycm9yKChlcnJvcikgPT4ge1xyXG4gICAgICAgICAgLy8gUmV0YWluIHByaW9yIGF0dGVuZGFuY2Ugc3RhdGU7IG9ubHkgY2xlYXIgdGhlIGluLWZsaWdodCBmbGFnLlxyXG4gICAgICAgICAgdGhpcy5pbkZsaWdodE1lZXRpbmdJZHMubmV4dChcclxuICAgICAgICAgICAgZW5kQXR0ZW5kYW5jZUFjdGlvbih0aGlzLmluRmxpZ2h0TWVldGluZ0lkcy52YWx1ZSwgbWVldGluZ0lkKVxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIHRocm93IGVycm9yO1xyXG4gICAgICAgIH0pXHJcbiAgICAgICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXR1cm5zIGEgc3luY2hyb25vdXMgc25hcHNob3Qgb2YgdGhlIHBlci1tZWV0aW5nIGF0dGVuZGFuY2Utc3RhdGUgbWFwLlxyXG4gICAqIEByZXR1cm4ge1JlY29yZDxzdHJpbmcsIEF0dGVuZGFuY2VTdGF0ZT59IFRoZSBjdXJyZW50IGF0dGVuZGFuY2Utc3RhdGUgbWFwLlxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgZ2V0QXR0ZW5kYW5jZVN0YXRlc1NuYXBzaG90KCk6IFJlY29yZDxzdHJpbmcsIEF0dGVuZGFuY2VTdGF0ZT4ge1xyXG4gICAgcmV0dXJuIHRoaXMuYXR0ZW5kYW5jZVN0YXRlcy52YWx1ZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFNlZWRzIHRoZSBhdHRlbmRhbmNlLXN0YXRlIG1hcCBmcm9tIGEgZnJlc2hseSBsb2FkZWQgbGlzdCBvZiBldmVudHMsIHVzaW5nXHJcbiAgICogZWFjaCBtZWV0aW5nJ3MgYGF0dGVuZGFuY2VTdGF0ZWAgKGRlZmF1bHRpbmcgdG8gYE5PVF9BVFRFTkRJTkdgKS4gS2VlcHMgdGhlXHJcbiAgICogZGlzcGxheWVkIHN0YXRlIGluIHN5bmMgd2l0aCB0aGUgZGF0YSBsb2FkIHdpdGhvdXQgb3ZlcndyaXRpbmcgaWRzIHRoYXQgYXJlXHJcbiAgICogbm90IHByZXNlbnQgaW4gdGhlIG5ldyBsaXN0LlxyXG4gICAqIEBwYXJhbSB7VXBjb21pbmdFdmVudFtdfSBldmVudHMgLSBUaGUgbG9hZGVkIHVwY29taW5nIGV2ZW50cy5cclxuICAgKiBAcmV0dXJuIHt2b2lkfVxyXG4gICAqIEBtZW1iZXJvZiBEYXNoYm9hcmRTZXJ2aWNlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBzZWVkQXR0ZW5kYW5jZVN0YXRlcyhldmVudHM6IFVwY29taW5nRXZlbnRbXSk6IHZvaWQge1xyXG4gICAgY29uc3QgbWVldGluZ3MgPSBldmVudHMuZmxhdE1hcCgoZXZlbnQpID0+IGV2ZW50Lm1lZXRpbmdzID8/IFtdKTtcclxuICAgIHRoaXMuc2VlZEF0dGVuZGFuY2VTdGF0ZXNGcm9tTWVldGluZ3MobWVldGluZ3MpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU2VlZHMgdGhlIGF0dGVuZGFuY2Utc3RhdGUgbWFwIGZyb20gYSBsaXN0IG9mIG1lZXRpbmcgcm93cywgdXNpbmcgZWFjaFxyXG4gICAqIG1lZXRpbmcncyBgYXR0ZW5kYW5jZVN0YXRlYCAoZGVmYXVsdGluZyB0byBgTk9UX0FUVEVORElOR2ApIHdpdGhvdXRcclxuICAgKiBvdmVyd3JpdGluZyBpZHMgYWJzZW50IGZyb20gdGhlIG5ldyBsaXN0LiBTaGFyZWQgYnkgdGhlIGxpc3QgbG9hZCBhbmQgdGhlXHJcbiAgICogcGVyLWV2ZW50IGV4cGFuZCBzbyBmcmVzaGx5IGxvYWRlZCBjaGlsZCBtZWV0aW5ncyBwaWNrIHVwIHRoZWlyIHN0YXRlLlxyXG4gICAqIEBwYXJhbSB7TWVldGluZ1Jvd1tdfSBtZWV0aW5ncyAtIFRoZSBtZWV0aW5nIHJvd3MgdG8gc2VlZCBmcm9tLlxyXG4gICAqIEByZXR1cm4ge3ZvaWR9XHJcbiAgICogQG1lbWJlcm9mIERhc2hib2FyZFNlcnZpY2VcclxuICAgKi9cclxuICBwcml2YXRlIHNlZWRBdHRlbmRhbmNlU3RhdGVzRnJvbU1lZXRpbmdzKG1lZXRpbmdzOiBNZWV0aW5nUm93W10pOiB2b2lkIHtcclxuICAgIGNvbnN0IG5leHQ6IFJlY29yZDxzdHJpbmcsIEF0dGVuZGFuY2VTdGF0ZT4gPSB7XHJcbiAgICAgIC4uLnRoaXMuYXR0ZW5kYW5jZVN0YXRlcy52YWx1ZSxcclxuICAgIH07XHJcbiAgICBtZWV0aW5ncy5mb3JFYWNoKChtZWV0aW5nKSA9PiB7XHJcbiAgICAgIGlmIChtZWV0aW5nLm1lZXRpbmdJZCkge1xyXG4gICAgICAgIG5leHRbbWVldGluZy5tZWV0aW5nSWRdID1cclxuICAgICAgICAgIG1lZXRpbmcuYXR0ZW5kYW5jZVN0YXRlID8/XHJcbiAgICAgICAgICBuZXh0W21lZXRpbmcubWVldGluZ0lkXSA/P1xyXG4gICAgICAgICAgQXR0ZW5kYW5jZVN0YXRlLk5PVF9BVFRFTkRJTkc7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgdGhpcy5hdHRlbmRhbmNlU3RhdGVzLm5leHQobmV4dCk7XHJcbiAgfVxyXG59XHJcbiJdfQ==
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure luxon date/time formatting helpers for the dashboard library.
|
|
3
|
+
*
|
|
4
|
+
* The real "events & meetings" backend returns date-times as ISO-8601 strings
|
|
5
|
+
* (e.g. "2026-01-01T00:00:00") together with a display timezone string
|
|
6
|
+
* (e.g. "(UTC-04:00) America/New_York"). These helpers parse the ISO value and
|
|
7
|
+
* render it in the item's own zone (never moment). A numeric epoch-milliseconds
|
|
8
|
+
* value is also accepted for backward compatibility with fixtures/tests. All
|
|
9
|
+
* helpers fall back gracefully to an empty string when the value is missing or
|
|
10
|
+
* unparseable.
|
|
11
|
+
*/
|
|
12
|
+
import { DateTime } from 'luxon';
|
|
13
|
+
/**
|
|
14
|
+
* Extracts a luxon-usable IANA zone from a backend timezone string such as
|
|
15
|
+
* "(UTC-04:00) America/New_York" or "America/New_York". Returns `undefined`
|
|
16
|
+
* when no usable zone can be derived so luxon falls back to the local zone.
|
|
17
|
+
* @param {string | undefined} timezone - The backend timezone string.
|
|
18
|
+
* @return {string | undefined} The IANA zone id, or undefined.
|
|
19
|
+
*/
|
|
20
|
+
export function extractIanaZone(timezone) {
|
|
21
|
+
if (!timezone) {
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
// Strip a leading "(UTC±HH:MM) " offset prefix when present.
|
|
25
|
+
const closingParen = timezone.indexOf(') ');
|
|
26
|
+
const zone = closingParen > -1
|
|
27
|
+
? timezone.slice(closingParen + 2).trim()
|
|
28
|
+
: timezone.trim();
|
|
29
|
+
return zone.length > 0 ? zone : undefined;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Parses a backend date-time value — either an ISO-8601 string
|
|
33
|
+
* (e.g. "2026-01-01T00:00:00") or an epoch-milliseconds number — into a luxon
|
|
34
|
+
* {@link DateTime} in the supplied timezone. The ISO value is treated as a wall
|
|
35
|
+
* time in the item's zone so the rendered time matches the backend's intent.
|
|
36
|
+
* Returns an invalid DateTime when the value is missing/unparseable.
|
|
37
|
+
* @param {string | number | undefined | null} value - The ISO string or epoch ms.
|
|
38
|
+
* @param {string | undefined} timezone - The backend timezone string.
|
|
39
|
+
* @return {DateTime} The parsed luxon DateTime (may be invalid).
|
|
40
|
+
*/
|
|
41
|
+
export function parseBackendDateTime(value, timezone) {
|
|
42
|
+
const zone = extractIanaZone(timezone);
|
|
43
|
+
if (value === undefined || value === null || value === '') {
|
|
44
|
+
return DateTime.invalid('empty');
|
|
45
|
+
}
|
|
46
|
+
if (typeof value === 'number') {
|
|
47
|
+
return zone
|
|
48
|
+
? DateTime.fromMillis(value, { zone })
|
|
49
|
+
: DateTime.fromMillis(value);
|
|
50
|
+
}
|
|
51
|
+
// ISO string: parse as a wall time in the item's zone when known.
|
|
52
|
+
const isoOptions = zone ? { zone } : {};
|
|
53
|
+
const parsed = DateTime.fromISO(value, isoOptions);
|
|
54
|
+
return parsed.isValid ? parsed : DateTime.fromISO(value);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Formats a backend date-time value (ISO string or epoch ms) with luxon using
|
|
58
|
+
* the supplied format token, honouring the supplied timezone. Returns an empty
|
|
59
|
+
* string when the value is missing or invalid.
|
|
60
|
+
* @param {string | number | undefined | null} value - The ISO string or epoch ms.
|
|
61
|
+
* @param {string} format - The luxon `toFormat` token.
|
|
62
|
+
* @param {string | undefined} timezone - The backend timezone string.
|
|
63
|
+
* @return {string} The formatted value, or an empty string.
|
|
64
|
+
*/
|
|
65
|
+
export function formatBackendDateTime(value, format, timezone) {
|
|
66
|
+
const parsed = parseBackendDateTime(value, timezone);
|
|
67
|
+
return parsed.isValid ? parsed.toFormat(format) : '';
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Backward-compatible alias kept for existing callers. Accepts ISO strings or
|
|
71
|
+
* epoch ms and formats them in the item's zone.
|
|
72
|
+
* @param {string | number | undefined | null} value - The ISO string or epoch ms.
|
|
73
|
+
* @param {string} format - The luxon `toFormat` token.
|
|
74
|
+
* @param {string | undefined} timezone - The backend timezone string.
|
|
75
|
+
* @return {string} The formatted value, or an empty string.
|
|
76
|
+
*/
|
|
77
|
+
export function formatEpoch(value, format, timezone) {
|
|
78
|
+
return formatBackendDateTime(value, format, timezone);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Computes a human "Day X of Y" indicator for a multi-day event from its start
|
|
82
|
+
* and end date-times, relative to "now". Returns an empty string when the dates
|
|
83
|
+
* are missing/invalid or the event spans a single day.
|
|
84
|
+
* @param {string | number | undefined | null} start - Event start (ISO or epoch ms).
|
|
85
|
+
* @param {string | number | undefined | null} end - Event end (ISO or epoch ms).
|
|
86
|
+
* @param {string | undefined} timezone - The backend timezone string.
|
|
87
|
+
* @return {string} The "Day X of Y" label, or an empty string.
|
|
88
|
+
*/
|
|
89
|
+
export function computeDayIndicator(start, end, timezone) {
|
|
90
|
+
const zone = extractIanaZone(timezone);
|
|
91
|
+
const startDt = parseBackendDateTime(start, timezone);
|
|
92
|
+
const endDt = parseBackendDateTime(end, timezone);
|
|
93
|
+
if (!startDt.isValid || !endDt.isValid) {
|
|
94
|
+
return '';
|
|
95
|
+
}
|
|
96
|
+
const startDay = startDt.startOf('day');
|
|
97
|
+
const endDay = endDt.startOf('day');
|
|
98
|
+
const totalDays = Math.floor(endDay.diff(startDay, 'days').days) + 1;
|
|
99
|
+
// Only meaningful for short, multi-day events (a conference-week style span).
|
|
100
|
+
// Very long spans (e.g. a year-long series) are not shown as "Day X of Y".
|
|
101
|
+
const MAX_DAY_INDICATOR_SPAN = 31;
|
|
102
|
+
if (totalDays <= 1 || totalDays > MAX_DAY_INDICATOR_SPAN) {
|
|
103
|
+
return '';
|
|
104
|
+
}
|
|
105
|
+
const now = (zone ? DateTime.now().setZone(zone) : DateTime.now()).startOf('day');
|
|
106
|
+
const clampedNow = now < startDay ? startDay : now > endDay ? endDay : now;
|
|
107
|
+
const currentDay = Math.floor(clampedNow.diff(startDay, 'days').days) + 1;
|
|
108
|
+
return `Day ${currentDay} of ${totalDays}`;
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS1mb3JtYXQudXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Rhc2hib2FyZC9zcmMvbGliL3V0aWxzL2RhdGUtZm9ybWF0LnV0aWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7R0FVRztBQUNILE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxPQUFPLENBQUM7QUFFakM7Ozs7OztHQU1HO0FBQ0gsTUFBTSxVQUFVLGVBQWUsQ0FDN0IsUUFBNEI7SUFFNUIsSUFBSSxDQUFDLFFBQVEsRUFBRTtRQUNiLE9BQU8sU0FBUyxDQUFDO0tBQ2xCO0lBQ0QsNkRBQTZEO0lBQzdELE1BQU0sWUFBWSxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDNUMsTUFBTSxJQUFJLEdBQ1IsWUFBWSxHQUFHLENBQUMsQ0FBQztRQUNmLENBQUMsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLFlBQVksR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUU7UUFDekMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUN0QixPQUFPLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztBQUM1QyxDQUFDO0FBRUQ7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBTSxVQUFVLG9CQUFvQixDQUNsQyxLQUF5QyxFQUN6QyxRQUFpQjtJQUVqQixNQUFNLElBQUksR0FBRyxlQUFlLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDdkMsSUFBSSxLQUFLLEtBQUssU0FBUyxJQUFJLEtBQUssS0FBSyxJQUFJLElBQUksS0FBSyxLQUFLLEVBQUUsRUFBRTtRQUN6RCxPQUFPLFFBQVEsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7S0FDbEM7SUFDRCxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsRUFB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QUFVLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDMUUsT0FBTyxPQUFPLFVBQVUsT0FBTyxTQUFTLEVBQUUsQ0FBQztBQUM3QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXHJcbiAqIFB1cmUgbHV4b24gZGF0ZS90aW1lIGZvcm1hdHRpbmcgaGVscGVycyBmb3IgdGhlIGRhc2hib2FyZCBsaWJyYXJ5LlxyXG4gKlxyXG4gKiBUaGUgcmVhbCBcImV2ZW50cyAmIG1lZXRpbmdzXCIgYmFja2VuZCByZXR1cm5zIGRhdGUtdGltZXMgYXMgSVNPLTg2MDEgc3RyaW5nc1xyXG4gKiAoZS5nLiBcIjIwMjYtMDEtMDFUMDA6MDA6MDBcIikgdG9nZXRoZXIgd2l0aCBhIGRpc3BsYXkgdGltZXpvbmUgc3RyaW5nXHJcbiAqIChlLmcuIFwiKFVUQy0wNDowMCkgQW1lcmljYS9OZXdfWW9ya1wiKS4gVGhlc2UgaGVscGVycyBwYXJzZSB0aGUgSVNPIHZhbHVlIGFuZFxyXG4gKiByZW5kZXIgaXQgaW4gdGhlIGl0ZW0ncyBvd24gem9uZSAobmV2ZXIgbW9tZW50KS4gQSBudW1lcmljIGVwb2NoLW1pbGxpc2Vjb25kc1xyXG4gKiB2YWx1ZSBpcyBhbHNvIGFjY2VwdGVkIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5IHdpdGggZml4dHVyZXMvdGVzdHMuIEFsbFxyXG4gKiBoZWxwZXJzIGZhbGwgYmFjayBncmFjZWZ1bGx5IHRvIGFuIGVtcHR5IHN0cmluZyB3aGVuIHRoZSB2YWx1ZSBpcyBtaXNzaW5nIG9yXHJcbiAqIHVucGFyc2VhYmxlLlxyXG4gKi9cclxuaW1wb3J0IHsgRGF0ZVRpbWUgfSBmcm9tICdsdXhvbic7XHJcblxyXG4vKipcclxuICogRXh0cmFjdHMgYSBsdXhvbi11c2FibGUgSUFOQSB6b25lIGZyb20gYSBiYWNrZW5kIHRpbWV6b25lIHN0cmluZyBzdWNoIGFzXHJcbiAqIFwiKFVUQy0wNDowMCkgQW1lcmljYS9OZXdfWW9ya1wiIG9yIFwiQW1lcmljYS9OZXdfWW9ya1wiLiBSZXR1cm5zIGB1bmRlZmluZWRgXHJcbiAqIHdoZW4gbm8gdXNhYmxlIHpvbmUgY2FuIGJlIGRlcml2ZWQgc28gbHV4b24gZmFsbHMgYmFjayB0byB0aGUgbG9jYWwgem9uZS5cclxuICogQHBhcmFtIHtzdHJpbmcgfCB1bmRlZmluZWR9IHRpbWV6b25lIC0gVGhlIGJhY2tlbmQgdGltZXpvbmUgc3RyaW5nLlxyXG4gKiBAcmV0dXJuIHtzdHJpbmcgfCB1bmRlZmluZWR9IFRoZSBJQU5BIHpvbmUgaWQsIG9yIHVuZGVmaW5lZC5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBleHRyYWN0SWFuYVpvbmUoXHJcbiAgdGltZXpvbmU6IHN0cmluZyB8IHVuZGVmaW5lZFxyXG4pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xyXG4gIGlmICghdGltZXpvbmUpIHtcclxuICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbiAgfVxyXG4gIC8vIFN0cmlwIGEgbGVhZGluZyBcIihVVEPCsUhIOk1NKSBcIiBvZmZzZXQgcHJlZml4IHdoZW4gcHJlc2VudC5cclxuICBjb25zdCBjbG9zaW5nUGFyZW4gPSB0aW1lem9uZS5pbmRleE9mKCcpICcpO1xyXG4gIGNvbnN0IHpvbmUgPVxyXG4gICAgY2xvc2luZ1BhcmVuID4gLTFcclxuICAgICAgPyB0aW1lem9uZS5zbGljZShjbG9zaW5nUGFyZW4gKyAyKS50cmltKClcclxuICAgICAgOiB0aW1lem9uZS50cmltKCk7XHJcbiAgcmV0dXJuIHpvbmUubGVuZ3RoID4gMCA/IHpvbmUgOiB1bmRlZmluZWQ7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBQYXJzZXMgYSBiYWNrZW5kIGRhdGUtdGltZSB2YWx1ZSDigJQgZWl0aGVyIGFuIElTTy04NjAxIHN0cmluZ1xyXG4gKiAoZS5nLiBcIjIwMjYtMDEtMDFUMDA6MDA6MDBcIikgb3IgYW4gZXBvY2gtbWlsbGlzZWNvbmRzIG51bWJlciDigJQgaW50byBhIGx1eG9uXHJcbiAqIHtAbGluayBEYXRlVGltZX0gaW4gdGhlIHN1cHBsaWVkIHRpbWV6b25lLiBUaGUgSVNPIHZhbHVlIGlzIHRyZWF0ZWQgYXMgYSB3YWxsXHJcbiAqIHRpbWUgaW4gdGhlIGl0ZW0ncyB6b25lIHNvIHRoZSByZW5kZXJlZCB0aW1lIG1hdGNoZXMgdGhlIGJhY2tlbmQncyBpbnRlbnQuXHJcbiAqIFJldHVybnMgYW4gaW52YWxpZCBEYXRlVGltZSB3aGVuIHRoZSB2YWx1ZSBpcyBtaXNzaW5nL3VucGFyc2VhYmxlLlxyXG4gKiBAcGFyYW0ge3N0cmluZyB8IG51bWJlciB8IHVuZGVmaW5lZCB8IG51bGx9IHZhbHVlIC0gVGhlIElTTyBzdHJpbmcgb3IgZXBvY2ggbXMuXHJcbiAqIEBwYXJhbSB7c3RyaW5nIHwgdW5kZWZpbmVkfSB0aW1lem9uZSAtIFRoZSBiYWNrZW5kIHRpbWV6b25lIHN0cmluZy5cclxuICogQHJldHVybiB7RGF0ZVRpbWV9IFRoZSBwYXJzZWQgbHV4b24gRGF0ZVRpbWUgKG1heSBiZSBpbnZhbGlkKS5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUJhY2tlbmREYXRlVGltZShcclxuICB2YWx1ZTogc3RyaW5nIHwgbnVtYmVyIHwgdW5kZWZpbmVkIHwgbnVsbCxcclxuICB0aW1lem9uZT86IHN0cmluZ1xyXG4pOiBEYXRlVGltZSB7XHJcbiAgY29uc3Qgem9uZSA9IGV4dHJhY3RJYW5hWm9uZSh0aW1lem9uZSk7XHJcbiAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQgfHwgdmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09ICcnKSB7XHJcbiAgICByZXR1cm4gRGF0ZVRpbWUuaW52YWxpZCgnZW1wdHknKTtcclxuICB9XHJcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcclxuICAgIHJldHVybiB6b25lXHJcbiAgICAgID8gRGF0ZVRpbWUuZnJvbU1pbGxpcyh2YWx1ZSwgeyB6b25lIH0pXHJcbiAgICAgIDogRGF0ZVRpbWUuZnJvbU1pbGxpcyh2YWx1ZSk7XHJcbiAgfVxyXG4gIC8vIElTTyBzdHJpbmc6IHBhcnNlIGFzIGEgd2FsbCB0aW1lIGluIHRoZSBpdGVtJ3Mgem9uZSB3aGVuIGtub3duLlxyXG4gIGNvbnN0IGlzb09wdGlvbnMgPSB6b25lID8geyB6b25lIH0gOiB7fTtcclxuICBjb25zdCBwYXJzZWQgPSBEYXRlVGltZS5mcm9tSVNPKHZhbHVlLCBpc29PcHRpb25zKTtcclxuICByZXR1cm4gcGFyc2VkLmlzVmFsaWQgPyBwYXJzZWQgOiBEYXRlVGltZS5mcm9tSVNPKHZhbHVlKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEZvcm1hdHMgYSBiYWNrZW5kIGRhdGUtdGltZSB2YWx1ZSAoSVNPIHN0cmluZyBvciBlcG9jaCBtcykgd2l0aCBsdXhvbiB1c2luZ1xyXG4gKiB0aGUgc3VwcGxpZWQgZm9ybWF0IHRva2VuLCBob25vdXJpbmcgdGhlIHN1cHBsaWVkIHRpbWV6b25lLiBSZXR1cm5zIGFuIGVtcHR5XHJcbiAqIHN0cmluZyB3aGVuIHRoZSB2YWx1ZSBpcyBtaXNzaW5nIG9yIGludmFsaWQuXHJcbiAqIEBwYXJhbSB7c3RyaW5nIHwgbnVtYmVyIHwgdW5kZWZpbmVkIHwgbnVsbH0gdmFsdWUgLSBUaGUgSVNPIHN0cmluZyBvciBlcG9jaCBtcy5cclxuICogQHBhcmFtIHtzdHJpbmd9IGZvcm1hdCAtIFRoZSBsdXhvbiBgdG9Gb3JtYXRgIHRva2VuLlxyXG4gKiBAcGFyYW0ge3N0cmluZyB8IHVuZGVmaW5lZH0gdGltZXpvbmUgLSBUaGUgYmFja2VuZCB0aW1lem9uZSBzdHJpbmcuXHJcbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGZvcm1hdHRlZCB2YWx1ZSwgb3IgYW4gZW1wdHkgc3RyaW5nLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdEJhY2tlbmREYXRlVGltZShcclxuICB2YWx1ZTogc3RyaW5nIHwgbnVtYmVyIHwgdW5kZWZpbmVkIHwgbnVsbCxcclxuICBmb3JtYXQ6IHN0cmluZyxcclxuICB0aW1lem9uZT86IHN0cmluZ1xyXG4pOiBzdHJpbmcge1xyXG4gIGNvbnN0IHBhcnNlZCA9IHBhcnNlQmFja2VuZERhdGVUaW1lKHZhbHVlLCB0aW1lem9uZSk7XHJcbiAgcmV0dXJuIHBhcnNlZC5pc1ZhbGlkID8gcGFyc2VkLnRvRm9ybWF0KGZvcm1hdCkgOiAnJztcclxufVxyXG5cclxuLyoqXHJcbiAqIEJhY2t3YXJkLWNvbXBhdGlibGUgYWxpYXMga2VwdCBmb3IgZXhpc3RpbmcgY2FsbGVycy4gQWNjZXB0cyBJU08gc3RyaW5ncyBvclxyXG4gKiBlcG9jaCBtcyBhbmQgZm9ybWF0cyB0aGVtIGluIHRoZSBpdGVtJ3Mgem9uZS5cclxuICogQHBhcmFtIHtzdHJpbmcgfCBudW1iZXIgfCB1bmRlZmluZWQgfCBudWxsfSB2YWx1ZSAtIFRoZSBJU08gc3RyaW5nIG9yIGVwb2NoIG1zLlxyXG4gKiBAcGFyYW0ge3N0cmluZ30gZm9ybWF0IC0gVGhlIGx1eG9uIGB0b0Zvcm1hdGAgdG9rZW4uXHJcbiAqIEBwYXJhbSB7c3RyaW5nIHwgdW5kZWZpbmVkfSB0aW1lem9uZSAtIFRoZSBiYWNrZW5kIHRpbWV6b25lIHN0cmluZy5cclxuICogQHJldHVybiB7c3RyaW5nfSBUaGUgZm9ybWF0dGVkIHZhbHVlLCBvciBhbiBlbXB0eSBzdHJpbmcuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZm9ybWF0RXBvY2goXHJcbiAgdmFsdWU6IHN0cmluZyB8IG51bWJlciB8IHVuZGVmaW5lZCB8IG51bGwsXHJcbiAgZm9ybWF0OiBzdHJpbmcsXHJcbiAgdGltZXpvbmU/OiBzdHJpbmdcclxuKTogc3RyaW5nIHtcclxuICByZXR1cm4gZm9ybWF0QmFja2VuZERhdGVUaW1lKHZhbHVlLCBmb3JtYXQsIHRpbWV6b25lKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIENvbXB1dGVzIGEgaHVtYW4gXCJEYXkgWCBvZiBZXCIgaW5kaWNhdG9yIGZvciBhIG11bHRpLWRheSBldmVudCBmcm9tIGl0cyBzdGFydFxyXG4gKiBhbmQgZW5kIGRhdGUtdGltZXMsIHJlbGF0aXZlIHRvIFwibm93XCIuIFJldHVybnMgYW4gZW1wdHkgc3RyaW5nIHdoZW4gdGhlIGRhdGVzXHJcbiAqIGFyZSBtaXNzaW5nL2ludmFsaWQgb3IgdGhlIGV2ZW50IHNwYW5zIGEgc2luZ2xlIGRheS5cclxuICogQHBhcmFtIHtzdHJpbmcgfCBudW1iZXIgfCB1bmRlZmluZWQgfCBudWxsfSBzdGFydCAtIEV2ZW50IHN0YXJ0IChJU08gb3IgZXBvY2ggbXMpLlxyXG4gKiBAcGFyYW0ge3N0cmluZyB8IG51bWJlciB8IHVuZGVmaW5lZCB8IG51bGx9IGVuZCAtIEV2ZW50IGVuZCAoSVNPIG9yIGVwb2NoIG1zKS5cclxuICogQHBhcmFtIHtzdHJpbmcgfCB1bmRlZmluZWR9IHRpbWV6b25lIC0gVGhlIGJhY2tlbmQgdGltZXpvbmUgc3RyaW5nLlxyXG4gKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBcIkRheSBYIG9mIFlcIiBsYWJlbCwgb3IgYW4gZW1wdHkgc3RyaW5nLlxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGNvbXB1dGVEYXlJbmRpY2F0b3IoXHJcbiAgc3RhcnQ6IHN0cmluZyB8IG51bWJlciB8IHVuZGVmaW5lZCB8IG51bGwsXHJcbiAgZW5kOiBzdHJpbmcgfCBudW1iZXIgfCB1bmRlZmluZWQgfCBudWxsLFxyXG4gIHRpbWV6b25lPzogc3RyaW5nXHJcbik6IHN0cmluZyB7XHJcbiAgY29uc3Qgem9uZSA9IGV4dHJhY3RJYW5hWm9uZSh0aW1lem9uZSk7XHJcbiAgY29uc3Qgc3RhcnREdCA9IHBhcnNlQmFja2VuZERhdGVUaW1lKHN0YXJ0LCB0aW1lem9uZSk7XHJcbiAgY29uc3QgZW5kRHQgPSBwYXJzZUJhY2tlbmREYXRlVGltZShlbmQsIHRpbWV6b25lKTtcclxuICBpZiAoIXN0YXJ0RHQuaXNWYWxpZCB8fCAhZW5kRHQuaXNWYWxpZCkge1xyXG4gICAgcmV0dXJuICcnO1xyXG4gIH1cclxuICBjb25zdCBzdGFydERheSA9IHN0YXJ0RHQuc3RhcnRPZignZGF5Jyk7XHJcbiAgY29uc3QgZW5kRGF5ID0gZW5kRHQuc3RhcnRPZignZGF5Jyk7XHJcbiAgY29uc3QgdG90YWxEYXlzID0gTWF0aC5mbG9vcihlbmREYXkuZGlmZihzdGFydERheSwgJ2RheXMnKS5kYXlzKSArIDE7XHJcbiAgLy8gT25seSBtZWFuaW5nZnVsIGZvciBzaG9ydCwgbXVsdGktZGF5IGV2ZW50cyAoYSBjb25mZXJlbmNlLXdlZWsgc3R5bGUgc3BhbikuXHJcbiAgLy8gVmVyeSBsb25nIHNwYW5zIChlLmcuIGEgeWVhci1sb25nIHNlcmllcykgYXJlIG5vdCBzaG93biBhcyBcIkRheSBYIG9mIFlcIi5cclxuICBjb25zdCBNQVhfREFZX0lORElDQVRPUl9TUEFOID0gMzE7XHJcbiAgaWYgKHRvdGFsRGF5cyA8PSAxIHx8IHRvdGFsRGF5cyA+IE1BWF9EQVlfSU5ESUNBVE9SX1NQQU4pIHtcclxuICAgIHJldHVybiAnJztcclxuICB9XHJcbiAgY29uc3Qgbm93ID0gKHpvbmUgPyBEYXRlVGltZS5ub3coKS5zZXRab25lKHpvbmUpIDogRGF0ZVRpbWUubm93KCkpLnN0YXJ0T2YoXHJcbiAgICAnZGF5J1xyXG4gICk7XHJcbiAgY29uc3QgY2xhbXBlZE5vdyA9IG5vdyA8IHN0YXJ0RGF5ID8gc3RhcnREYXkgOiBub3cgPiBlbmREYXkgPyBlbmREYXkgOiBub3c7XHJcbiAgY29uc3QgY3VycmVudERheSA9IE1hdGguZmxvb3IoY2xhbXBlZE5vdy5kaWZmKHN0YXJ0RGF5LCAnZGF5cycpLmRheXMpICsgMTtcclxuICByZXR1cm4gYERheSAke2N1cnJlbnREYXl9IG9mICR7dG90YWxEYXlzfWA7XHJcbn1cclxuIl19
|