@rangertechnologies/ngnxt 2.1.76 → 2.1.78
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/README.md +29 -29
- package/esm2022/lib/ar.i18n.mjs +29 -29
- package/esm2022/lib/components/custom-button/custom-button.component.mjs +39 -39
- package/esm2022/lib/components/custom-calendar/custom-calendar.component.mjs +366 -366
- package/esm2022/lib/components/custom-date/custom-date.component.mjs +47 -47
- package/esm2022/lib/components/custom-date-picker/custom-date-picker.component.mjs +48 -48
- package/esm2022/lib/components/custom-dropdown/custom-dropdown.component.mjs +219 -212
- package/esm2022/lib/components/custom-image/custom-image.component.mjs +34 -34
- package/esm2022/lib/components/custom-input/custom-input.component.mjs +93 -93
- package/esm2022/lib/components/custom-label/custom-label.component.mjs +21 -21
- package/esm2022/lib/components/custom-model/custom-model.component.mjs +48 -48
- package/esm2022/lib/components/custom-radio/custom-radio.component.mjs +115 -115
- package/esm2022/lib/components/custom-table/custom-table.component.mjs +169 -169
- package/esm2022/lib/components/custom-text-area/custom-text-area.component.mjs +65 -65
- package/esm2022/lib/components/custom-time/custom-time.component.mjs +61 -61
- package/esm2022/lib/components/dependent-table/dependent-table.component.mjs +42 -42
- package/esm2022/lib/components/dropdown-with-flag/dropdown-with-flag.component.mjs +39 -39
- package/esm2022/lib/components/file-upload/file-upload.component.mjs +233 -233
- package/esm2022/lib/components/file-view/file-view.component.mjs +46 -46
- package/esm2022/lib/components/loader/loader.component.mjs +23 -23
- package/esm2022/lib/components/pick-location/pick-location.component.mjs +188 -188
- package/esm2022/lib/components/search-box/search-box.component.mjs +130 -130
- package/esm2022/lib/components/table-appendix/table-appendix.component.mjs +123 -123
- package/esm2022/lib/directives/componenthost/componenthost.directive.mjs +19 -19
- package/esm2022/lib/en.i18n.mjs +29 -29
- package/esm2022/lib/i18n-config.service.mjs +4 -4
- package/esm2022/lib/i18n.component.mjs +47 -47
- package/esm2022/lib/i18n.module.mjs +38 -38
- package/esm2022/lib/i18n.pipe.mjs +25 -25
- package/esm2022/lib/i18n.service.mjs +56 -56
- package/esm2022/lib/interfaces/actionMeta.mjs +2 -2
- package/esm2022/lib/interfaces/apimeta.mjs +2 -2
- package/esm2022/lib/interfaces/dependencyMeta.mjs +2 -2
- package/esm2022/lib/model/bookletWrapper.mjs +9 -9
- package/esm2022/lib/model/changeWrapper.mjs +11 -11
- package/esm2022/lib/model/errorWrapper.mjs +6 -6
- package/esm2022/lib/model/tableWrapper.mjs +20 -20
- package/esm2022/lib/nxt-app.component.mjs +22 -22
- package/esm2022/lib/nxt-app.module.mjs +352 -352
- package/esm2022/lib/nxt-app.service.mjs +14 -14
- package/esm2022/lib/pages/booklet/booklet.component.mjs +541 -541
- package/esm2022/lib/pages/questionbook/questionbook.component.mjs +407 -407
- package/esm2022/lib/pages/questionnaire/questionnaire.component.mjs +2373 -2373
- package/esm2022/lib/pages/summary-page/summary-page.component.mjs +76 -76
- package/esm2022/lib/pipe/get-value.pipe.mjs +50 -50
- package/esm2022/lib/sample.mjs +3430 -3430
- package/esm2022/lib/services/change.service.mjs +53 -53
- package/esm2022/lib/services/data.service.mjs +80 -80
- package/esm2022/lib/services/salesforce.service.mjs +46 -46
- package/esm2022/lib/services/shared.service.mjs +100 -100
- package/esm2022/lib/services/storage.service.mjs +44 -44
- package/esm2022/lib/tam.i18n.mjs +29 -29
- package/esm2022/lib/wrapper.mjs +175 -175
- package/esm2022/public-api.mjs +15 -15
- package/esm2022/rangertechnologies-ngnxt.mjs +4 -4
- package/fesm2022/rangertechnologies-ngnxt.mjs +9812 -9805
- package/fesm2022/rangertechnologies-ngnxt.mjs.map +1 -1
- package/index.d.ts +5 -5
- package/lib/ar.i18n.d.ts +24 -24
- package/lib/components/custom-button/custom-button.component.d.ts +16 -16
- package/lib/components/custom-calendar/custom-calendar.component.d.ts +65 -65
- package/lib/components/custom-date/custom-date.component.d.ts +18 -18
- package/lib/components/custom-date-picker/custom-date-picker.component.d.ts +19 -19
- package/lib/components/custom-dropdown/custom-dropdown.component.d.ts +39 -39
- package/lib/components/custom-image/custom-image.component.d.ts +13 -13
- package/lib/components/custom-input/custom-input.component.d.ts +31 -31
- package/lib/components/custom-label/custom-label.component.d.ts +10 -10
- package/lib/components/custom-model/custom-model.component.d.ts +19 -19
- package/lib/components/custom-radio/custom-radio.component.d.ts +33 -33
- package/lib/components/custom-table/custom-table.component.d.ts +43 -43
- package/lib/components/custom-text-area/custom-text-area.component.d.ts +22 -22
- package/lib/components/custom-time/custom-time.component.d.ts +18 -18
- package/lib/components/dependent-table/dependent-table.component.d.ts +15 -15
- package/lib/components/dropdown-with-flag/dropdown-with-flag.component.d.ts +16 -16
- package/lib/components/file-upload/file-upload.component.d.ts +42 -42
- package/lib/components/file-view/file-view.component.d.ts +16 -16
- package/lib/components/loader/loader.component.d.ts +11 -11
- package/lib/components/pick-location/pick-location.component.d.ts +42 -42
- package/lib/components/search-box/search-box.component.d.ts +40 -40
- package/lib/components/table-appendix/table-appendix.component.d.ts +30 -30
- package/lib/directives/componenthost/componenthost.directive.d.ts +8 -8
- package/lib/en.i18n.d.ts +24 -24
- package/lib/i18n-config.service.d.ts +2 -2
- package/lib/i18n.component.d.ts +11 -11
- package/lib/i18n.module.d.ts +9 -9
- package/lib/i18n.pipe.d.ts +10 -10
- package/lib/i18n.service.d.ts +14 -14
- package/lib/interfaces/actionMeta.d.ts +5 -5
- package/lib/interfaces/apimeta.d.ts +14 -13
- package/lib/interfaces/dependencyMeta.d.ts +8 -8
- package/lib/model/bookletWrapper.d.ts +5 -5
- package/lib/model/changeWrapper.d.ts +10 -10
- package/lib/model/errorWrapper.d.ts +5 -5
- package/lib/model/tableWrapper.d.ts +18 -18
- package/lib/nxt-app.component.d.ts +8 -8
- package/lib/nxt-app.module.d.ts +46 -46
- package/lib/nxt-app.service.d.ts +6 -6
- package/lib/pages/booklet/booklet.component.d.ts +68 -68
- package/lib/pages/questionbook/questionbook.component.d.ts +66 -66
- package/lib/pages/questionnaire/questionnaire.component.d.ts +218 -218
- package/lib/pages/summary-page/summary-page.component.d.ts +20 -20
- package/lib/pipe/get-value.pipe.d.ts +7 -7
- package/lib/sample.d.ts +10 -10
- package/lib/services/change.service.d.ts +22 -22
- package/lib/services/data.service.d.ts +13 -13
- package/lib/services/salesforce.service.d.ts +11 -11
- package/lib/services/shared.service.d.ts +15 -15
- package/lib/services/storage.service.d.ts +13 -13
- package/lib/tam.i18n.d.ts +24 -24
- package/lib/wrapper.d.ts +203 -203
- package/package.json +1 -1
- package/public-api.d.ts +10 -10
- package/rangertechnologies-ngnxt-2.1.78.tgz +0 -0
- package/rangertechnologies-ngnxt-2.1.76.tgz +0 -0
|
@@ -1,366 +1,366 @@
|
|
|
1
|
-
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
2
|
-
import * as i0 from "@angular/core";
|
|
3
|
-
import * as i1 from "../../services/change.service";
|
|
4
|
-
import * as i2 from "@angular/common";
|
|
5
|
-
export class CustomCalendarComponent {
|
|
6
|
-
changeService;
|
|
7
|
-
eventSelected = new EventEmitter();
|
|
8
|
-
// VD 06Sep24 calendar changes
|
|
9
|
-
dateSelected = new EventEmitter();
|
|
10
|
-
openModal = new EventEmitter();
|
|
11
|
-
closeModal = new EventEmitter();
|
|
12
|
-
allEvents = [];
|
|
13
|
-
question;
|
|
14
|
-
nxtId;
|
|
15
|
-
//@ViewChild(ComponenthostDirective, { static: true }) dynamicHost: ComponenthostDirective;
|
|
16
|
-
entries = [];
|
|
17
|
-
referenceQuestions = [];
|
|
18
|
-
qbRefrenceBook;
|
|
19
|
-
calendarQuestion = [];
|
|
20
|
-
calendar = {};
|
|
21
|
-
currentDate = new Date();
|
|
22
|
-
calendarDays = [];
|
|
23
|
-
daysOfWeek = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
|
24
|
-
newEventTitle = '';
|
|
25
|
-
newEventTime = '';
|
|
26
|
-
newDescription = '';
|
|
27
|
-
newLink = '';
|
|
28
|
-
selectedDay = null;
|
|
29
|
-
isModalOpen = false;
|
|
30
|
-
modalTitle = 'Custom Modal';
|
|
31
|
-
modalSize = 'large';
|
|
32
|
-
saveButtonValue = 'Save';
|
|
33
|
-
modalFooter = true;
|
|
34
|
-
editingEventId;
|
|
35
|
-
editingEntryGroup;
|
|
36
|
-
showAppoinmentSection = true;
|
|
37
|
-
subscription;
|
|
38
|
-
constructor(changeService) {
|
|
39
|
-
this.changeService = changeService;
|
|
40
|
-
}
|
|
41
|
-
ngOnInit() {
|
|
42
|
-
if (this.question?.input) {
|
|
43
|
-
this.allEvents = this.question.input;
|
|
44
|
-
}
|
|
45
|
-
this.processQuestion();
|
|
46
|
-
this.generateCalendar();
|
|
47
|
-
this.subscription = this.changeService.customChange$.subscribe((changeValue) => {
|
|
48
|
-
if (changeValue == 'calendar-modal-save') {
|
|
49
|
-
this.onSave();
|
|
50
|
-
}
|
|
51
|
-
if (changeValue == 'dataBind') {
|
|
52
|
-
if (this.question?.input) {
|
|
53
|
-
this.allEvents = this.question.input;
|
|
54
|
-
}
|
|
55
|
-
this.processQuestion();
|
|
56
|
-
this.generateCalendar();
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
// this.dateSelected.emit(this.calendar);
|
|
60
|
-
//this.eventSelected.emit(this.allEvents);
|
|
61
|
-
}
|
|
62
|
-
// RS 09DEC24 Changed keys
|
|
63
|
-
processQuestion() {
|
|
64
|
-
this.entries = JSON.parse(this.question['fieldsMeta']);
|
|
65
|
-
this.qbRefrenceBook = JSON.parse(this.question['qbReferenceQuestions']);
|
|
66
|
-
let title = this.qbRefrenceBook?.questionbook?.title;
|
|
67
|
-
this.modalTitle = title;
|
|
68
|
-
this.referenceQuestions = [];
|
|
69
|
-
if (this.entries.length > 0) {
|
|
70
|
-
this.entries.forEach(element => {
|
|
71
|
-
if (element.questionReference) {
|
|
72
|
-
let qReference = JSON.parse(element.questionReference);
|
|
73
|
-
this.referenceQuestions.push(qReference?.question);
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
console.log('entries-->');
|
|
78
|
-
console.log('question-->');
|
|
79
|
-
console.log(this.entries);
|
|
80
|
-
console.log(this.referenceQuestions);
|
|
81
|
-
}
|
|
82
|
-
// sunday comment
|
|
83
|
-
// openQuestionBookModal() {
|
|
84
|
-
// const viewContainerRef = this.dynamicHost.viewContainerRef;
|
|
85
|
-
// viewContainerRef.clear();
|
|
86
|
-
// const componentRef = viewContainerRef.createComponent(QuestionbookComponent);
|
|
87
|
-
// componentRef.instance.qbItem = this.qbRefrenceBook;
|
|
88
|
-
// componentRef.instance.questions = this.referenceQuestions;
|
|
89
|
-
// componentRef.instance.handleQuestion.subscribe((event: any) => this.handleQuestionEvent(event));
|
|
90
|
-
// }
|
|
91
|
-
generateCalendar() {
|
|
92
|
-
const year = this.currentDate.getFullYear();
|
|
93
|
-
const month = this.currentDate.getMonth();
|
|
94
|
-
const startOfMonth = new Date(year, month, 1);
|
|
95
|
-
const endOfMonth = new Date(year, month + 1, 0);
|
|
96
|
-
const startDayOfWeek = startOfMonth.getDay();
|
|
97
|
-
const endDayOfWeek = endOfMonth.getDay();
|
|
98
|
-
const startDate = new Date(startOfMonth);
|
|
99
|
-
startDate.setDate(startDate.getDate() - startDayOfWeek);
|
|
100
|
-
const endDate = new Date(endOfMonth);
|
|
101
|
-
endDate.setDate(endDate.getDate() + (6 - endDayOfWeek));
|
|
102
|
-
const today = new Date(new Date().setHours(0, 0, 0, 0));
|
|
103
|
-
this.calendarDays = [];
|
|
104
|
-
for (let d = new Date(startDate); d <= endDate; d.setDate(d.getDate() + 1)) {
|
|
105
|
-
const date = new Date(d);
|
|
106
|
-
this.calendarDays.push({
|
|
107
|
-
date: date,
|
|
108
|
-
events: [],
|
|
109
|
-
isCurrentMonth: d.getMonth() === month,
|
|
110
|
-
isPast: date < today,
|
|
111
|
-
isToday: date.getTime() === today.getTime(),
|
|
112
|
-
isFuture: date > today,
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
// Populate calendar with events from allEvents array
|
|
116
|
-
this.calendarDays.forEach(day => {
|
|
117
|
-
day.events = this.allEvents?.filter(event => event?.date?.toDateString() === day.date.toDateString());
|
|
118
|
-
});
|
|
119
|
-
// VD 06Sep24 calendar changes
|
|
120
|
-
let cal = {};
|
|
121
|
-
cal['year'] = year;
|
|
122
|
-
cal['month'] = month + 1;
|
|
123
|
-
this.calendar = cal;
|
|
124
|
-
}
|
|
125
|
-
selectDay(day) {
|
|
126
|
-
console.log(day);
|
|
127
|
-
// VD 06Sep24 calendar changes
|
|
128
|
-
this.showAppoinmentSection = true;
|
|
129
|
-
this.selectedDay = day;
|
|
130
|
-
// this.eventSelected.emit(day?.events);
|
|
131
|
-
const previouslySelectedDay = this.calendarDays.find(d => d.isSelected);
|
|
132
|
-
if (previouslySelectedDay) {
|
|
133
|
-
previouslySelectedDay.isSelected = false;
|
|
134
|
-
}
|
|
135
|
-
// Select the clicked day
|
|
136
|
-
day.isSelected = true;
|
|
137
|
-
// VD 09Sep24- setup the query param data for api call
|
|
138
|
-
let referenceData = [];
|
|
139
|
-
this.referenceQuestions.forEach(ques => {
|
|
140
|
-
// VD 09-09-24 get the selected date
|
|
141
|
-
// need to add in the document
|
|
142
|
-
// RS 09DEC24 Changed keys
|
|
143
|
-
if (ques.referenceField == 'selectedDate') {
|
|
144
|
-
ques.input = day.date.toISOString();
|
|
145
|
-
console.log(ques.input);
|
|
146
|
-
}
|
|
147
|
-
// VD 09-09-24 get the query refrence field data to pass the queryParam for api
|
|
148
|
-
if (ques.subText) {
|
|
149
|
-
let subText = JSON.parse(ques.subText);
|
|
150
|
-
if (subText.queryField && subText.queryValueReference) {
|
|
151
|
-
let currentQues = ques;
|
|
152
|
-
let queryReferences = subText.queryValueReference.split(',');
|
|
153
|
-
queryReferences.forEach(refField => {
|
|
154
|
-
let refQues = this.referenceQuestions.find(q => q.referenceField === refField);
|
|
155
|
-
if (refQues) {
|
|
156
|
-
referenceData.push(refQues);
|
|
157
|
-
}
|
|
158
|
-
});
|
|
159
|
-
// Add the referenceData array to the current question
|
|
160
|
-
currentQues.referenceQueryData = referenceData;
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
previousMonth() {
|
|
166
|
-
this.showAppoinmentSection = false;
|
|
167
|
-
this.currentDate.setMonth(this.currentDate.getMonth() - 1);
|
|
168
|
-
this.currentDate = new Date(this.currentDate); // Ensure the date object is updated
|
|
169
|
-
this.generateCalendar();
|
|
170
|
-
this.dateSelected.emit(this.calendar);
|
|
171
|
-
this.eventSelected.emit(this.allEvents);
|
|
172
|
-
}
|
|
173
|
-
nextMonth() {
|
|
174
|
-
// VD 06Sep24 calendar changes
|
|
175
|
-
this.showAppoinmentSection = false;
|
|
176
|
-
this.currentDate.setMonth(this.currentDate.getMonth() + 1);
|
|
177
|
-
this.currentDate = new Date(this.currentDate); // Ensure the date object is updated
|
|
178
|
-
this.generateCalendar();
|
|
179
|
-
this.dateSelected.emit(this.calendar);
|
|
180
|
-
this.eventSelected.emit(this.allEvents);
|
|
181
|
-
}
|
|
182
|
-
addAppointment() {
|
|
183
|
-
this.isModalOpen = true;
|
|
184
|
-
this.calendarQuestion = this.referenceQuestions.map(q => ({ ...q, input: '' }));
|
|
185
|
-
this.referenceQuestions.forEach(ques => {
|
|
186
|
-
// clear the input
|
|
187
|
-
if (ques.referenceField != 'selectedDate') {
|
|
188
|
-
if (ques.type == 'Dropdown') {
|
|
189
|
-
delete ques.input;
|
|
190
|
-
delete ques.selectedValue;
|
|
191
|
-
// VD 06Sep24 calendar changes
|
|
192
|
-
}
|
|
193
|
-
else {
|
|
194
|
-
delete ques.input;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
});
|
|
198
|
-
console.log(this.referenceQuestions);
|
|
199
|
-
this.editingEventId = null;
|
|
200
|
-
this.calendarQuestion = this.referenceQuestions;
|
|
201
|
-
this.openBookModel();
|
|
202
|
-
// sunday comment
|
|
203
|
-
//this.openQuestionBookModal();
|
|
204
|
-
}
|
|
205
|
-
openBookModel() {
|
|
206
|
-
this.openModal.emit({
|
|
207
|
-
qbRefrenceBook: this.qbRefrenceBook,
|
|
208
|
-
referenceQuestions: this.referenceQuestions,
|
|
209
|
-
modalTitle: this.modalTitle,
|
|
210
|
-
modalSize: this.modalSize,
|
|
211
|
-
saveButtonValue: this.saveButtonValue,
|
|
212
|
-
modalFooter: this.modalFooter,
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
closeCalendarModal() {
|
|
216
|
-
this.isModalOpen = false;
|
|
217
|
-
this.closeModal.emit(true);
|
|
218
|
-
}
|
|
219
|
-
// VD 06Sep24 calendar changes
|
|
220
|
-
editEvent(event, entryGroup) {
|
|
221
|
-
this.isModalOpen = true;
|
|
222
|
-
this.referenceQuestions = Object.values(entryGroup);
|
|
223
|
-
this.calendarQuestion = [...this.referenceQuestions]; // Make a copy of the current entries to edit
|
|
224
|
-
this.editingEventId = event.id;
|
|
225
|
-
this.editingEntryGroup = entryGroup; // Store the entry group being edited
|
|
226
|
-
this.generateCalendar(); // Regenerate the calendar to reflect changes
|
|
227
|
-
this.openBookModel();
|
|
228
|
-
// suday comment
|
|
229
|
-
// this.openQuestionBookModal();
|
|
230
|
-
}
|
|
231
|
-
deleteEvent(eventId, entryGroup) {
|
|
232
|
-
let event = this.allEvents?.find(e => e?.id === eventId);
|
|
233
|
-
if (event) {
|
|
234
|
-
// Find the index of the entryGroup to delete
|
|
235
|
-
const entryIndex = event.entries.indexOf(entryGroup);
|
|
236
|
-
if (entryIndex > -1) {
|
|
237
|
-
event.entries.splice(entryIndex, 1); // Remove the specific entry
|
|
238
|
-
}
|
|
239
|
-
// If the event has no more entries, remove the event entirely
|
|
240
|
-
if (event.entries.length === 0) {
|
|
241
|
-
const eventIndex = this.allEvents?.indexOf(event);
|
|
242
|
-
if (eventIndex > -1) {
|
|
243
|
-
this.allEvents?.splice(eventIndex, 1); // Remove the entire event
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
let eventData = {};
|
|
248
|
-
eventData['action'] = "delete";
|
|
249
|
-
eventData['data'] = event;
|
|
250
|
-
this.eventSelected.emit(eventData);
|
|
251
|
-
this.generateCalendar(); // Regenerate the calendar to reflect the changes
|
|
252
|
-
}
|
|
253
|
-
// VD 06Sep24 calendar changes
|
|
254
|
-
addEvent(day, entryQues) {
|
|
255
|
-
// Transform new entries into the desired format
|
|
256
|
-
const newEntries = entryQues.reduce((acc, q) => {
|
|
257
|
-
acc[q.id] = { ...q };
|
|
258
|
-
return acc;
|
|
259
|
-
}, {});
|
|
260
|
-
// Find an existing event for the given date
|
|
261
|
-
const existingEvent = day.events?.find(event => event.date === day.date);
|
|
262
|
-
if (existingEvent) {
|
|
263
|
-
// Merge new entries into the existing event's entries array
|
|
264
|
-
// Check if the entries array already contains an object with the same id
|
|
265
|
-
const existingEntries = existingEvent.entries.map(entry => ({ ...entry }));
|
|
266
|
-
// Append new entries to the existing entries
|
|
267
|
-
existingEntries.push(newEntries);
|
|
268
|
-
existingEvent.entries = existingEntries;
|
|
269
|
-
}
|
|
270
|
-
else {
|
|
271
|
-
// Create a new event if it doesn't exist for the given date
|
|
272
|
-
const newEvent = {
|
|
273
|
-
id: this.generateId(),
|
|
274
|
-
date: day.date,
|
|
275
|
-
entries: [newEntries] // Wrap the new entries in an array
|
|
276
|
-
};
|
|
277
|
-
day.events = day?.events || [];
|
|
278
|
-
day.events.push(newEvent);
|
|
279
|
-
this.allEvents?.push(newEvent);
|
|
280
|
-
//this.eventSelected.emit(this.allEvents);
|
|
281
|
-
let eventData = {};
|
|
282
|
-
eventData['action'] = "add";
|
|
283
|
-
eventData['data'] = newEvent;
|
|
284
|
-
this.eventSelected.emit(eventData);
|
|
285
|
-
}
|
|
286
|
-
this.generateCalendar();
|
|
287
|
-
console.log('allEvents', this.allEvents);
|
|
288
|
-
}
|
|
289
|
-
// VD 06Sep24 calendar changes
|
|
290
|
-
onSave() {
|
|
291
|
-
if (this.editingEventId !== null) {
|
|
292
|
-
const event = this.allEvents?.find(e => e?.id === this.editingEventId);
|
|
293
|
-
if (event && this.editingEntryGroup) {
|
|
294
|
-
// Update the specific entry group within the event
|
|
295
|
-
const entryIndex = event.entries.findIndex(entryGroup => entryGroup === this.editingEntryGroup);
|
|
296
|
-
if (entryIndex > -1) {
|
|
297
|
-
event.entries[entryIndex] = this.calendarQuestion.reduce((acc, q) => {
|
|
298
|
-
acc[q.id] = { ...q };
|
|
299
|
-
return acc;
|
|
300
|
-
}, {});
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
// this.eventSelected.emit(this.allEvents);
|
|
304
|
-
let eventData = {};
|
|
305
|
-
eventData['action'] = "edit";
|
|
306
|
-
eventData['data'] = event;
|
|
307
|
-
this.eventSelected.emit(eventData);
|
|
308
|
-
}
|
|
309
|
-
else {
|
|
310
|
-
if (this.selectedDay) {
|
|
311
|
-
this.addEvent(this.selectedDay, this.calendarQuestion);
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
this.closeCalendarModal();
|
|
315
|
-
this.generateCalendar();
|
|
316
|
-
}
|
|
317
|
-
// onCancel() {
|
|
318
|
-
// console.log('Cancel button clicked');
|
|
319
|
-
// this.closeCalendarModal();
|
|
320
|
-
// }
|
|
321
|
-
//this funtion need to be used
|
|
322
|
-
// handleQuestionEvent(ques){
|
|
323
|
-
// // Update the questions array with the new question
|
|
324
|
-
// const index = this.calendarQuestion.findIndex(q => q.id === ques.id);
|
|
325
|
-
// if (index > -1) {
|
|
326
|
-
// // If question already exists, update it
|
|
327
|
-
// this.calendarQuestion[index] = ques;
|
|
328
|
-
// } else {
|
|
329
|
-
// // If question doesn't exist, add it to the array
|
|
330
|
-
// this.calendarQuestion.push(ques);
|
|
331
|
-
// }
|
|
332
|
-
// console.log(this.calendarQuestion);
|
|
333
|
-
// }
|
|
334
|
-
// VD 06Sep24 calendar changes
|
|
335
|
-
generateId() {
|
|
336
|
-
return '_' + Math.random().toString(36).substr(2, 9);
|
|
337
|
-
}
|
|
338
|
-
getEntryKeys(entryGroup) {
|
|
339
|
-
return Object.keys(entryGroup);
|
|
340
|
-
}
|
|
341
|
-
removeCharacters(questionText) {
|
|
342
|
-
let updatedText = questionText?.replace(/<[^>]*>/g, '');
|
|
343
|
-
return updatedText;
|
|
344
|
-
}
|
|
345
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CustomCalendarComponent, deps: [{ token: i1.ChangeService }], target: i0.ɵɵFactoryTarget.Component });
|
|
346
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: CustomCalendarComponent, selector: "app-custom-calendar", inputs: { allEvents: "allEvents", question: "question", nxtId: "nxtId" }, outputs: { eventSelected: "eventSelected", dateSelected: "dateSelected", openModal: "openModal", closeModal: "closeModal" }, ngImport: i0, template: "<div class=\"align-calendar\">\n <div class=\"calendar-container\">\n <div class=\"calendar-header\">\n <button (click)=\"previousMonth()\"><< Previous >></button>\n <h3>{{ currentDate | date: 'MMMM yyyy' }}</h3>\n <button (click)=\"nextMonth()\"><< Next >></button>\n </div>\n <div class=\"calendar-grid\">\n <div class=\"day-of-week\" *ngFor=\"let day of daysOfWeek\">{{ day }}</div>\n <div\n class=\"calendar-day\"\n *ngFor=\"let day of calendarDays\"\n [class.not-current-month]=\"!day.isCurrentMonth\"\n [class.past]=\"day.isPast\"\n [class.today]=\"day.isToday\"\n [class.future]=\"day.isFuture\"\n [class.selected]=\"day.isSelected\"\n (click)=\"selectDay(day)\"\n >\n <div class=\"day-number\">{{ day.date.getDate() }}\n <span *ngIf=\"day?.events?.length > 0\" class=\"entry-indicator\" [class.select]=\"day?.isSelected\"></span>\n </div>\n <!-- <div *ngFor=\"let event of day.events\" >\n <div *ngFor=\"let entryGroup of event.entries\" class=\"event\">\n <div *ngFor=\"let key of getEntryKeys(entryGroup)\">\n <div *ngIf=\"entryGroup[key].type == 'Time'\">\n {{ entryGroup[key].input?.value | date: 'shortTime' }}\n </div>\n <div *ngIf=\"entryGroup[key].type != 'Time'\">\n {{ entryGroup[key].input }}\n </div>\n </div>\n </div>\n </div> -->\n </div>\n </div>\n </div>\n <div class=\"appoinappointment\">\n <div class=\"appointments-container\">\n <h4>Add Appointment</h4>\n <button *ngIf=\"selectedDay\" (click)=\"addAppointment()\">Add</button>\n </div>\n <!--VD 06Sep24 calendar updates--> \n <!-- RS 09DEC24 Changed keys--> \n <div *ngIf=\"showAppoinmentSection && selectedDay?.events?.length > 0\" class=\"appointments-container\">\n <h4>Appointments</h4>\n <div *ngFor=\"let event of selectedDay?.events\">\n <div class=\"event\" *ngFor=\"let entryGroup of event.entries\">\n <div class=\"event-info\">\n <div *ngFor=\"let key of getEntryKeys(entryGroup)\" class=\"entry-row\">\n <div *ngIf=\"entryGroup[key].questionText\" class=\"entry-text\">\n {{removeCharacters(entryGroup[key].questionText)}}:\n </div>\n <div class=\"entry-value\">\n <!-- VD 09Sep24- date type and link type updates -->\n <span *ngIf=\"entryGroup[key].type != 'Time' && entryGroup[key].type != 'Link'&& entryGroup[key].type != 'Date'\">{{ entryGroup[key].input }}</span>\n <span *ngIf=\"entryGroup[key].type == 'Time'\">{{ entryGroup[key].input | date: 'shortTime' }}</span>\n <span *ngIf=\"entryGroup[key].type == 'Date'\">{{ entryGroup[key].input | date: 'mediumDate' }}</span>\n <span *ngIf=\"entryGroup[key].type == 'Link'\">\n <a [href]=\"'//'+ entryGroup[key].input\" target=\"_blank\">{{removeCharacters(entryGroup[key].questionText)}}</a>\n </span>\n </div>\n </div>\n <div class=\"event-actions\">\n <button (click)=\"editEvent(event,entryGroup)\">Edit</button>\n <button (click)=\"deleteEvent(event.id,entryGroup)\">Delete</button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n\n<!-- <app-custom-model\n [modalTitle]=\"modalTitle\"\n [isModalOpen]=\"isModalOpen\"\n [modalSize]=\"modalSize\"\n [saveButtonValue]=\"saveButtonValue\"\n [modalFooter]=\"modalFooter\"\n (saveButtonEmit)=\"onSave()\"\n (cancelButtonEmit)=\"onCancel()\"\n>\n<lib-questionbook [qbItem]=\"qbRefrenceBook\" [questions]=\"referenceQuestions\" (handleQuestion)=\"handleQuestionEvent($event)\"></lib-questionbook>\n<ng-template dynamicComponentHost ></ng-template>\n</app-custom-model> -->", styles: [".calendar-container{flex:1}.appoinappointment{flex:1;margin-left:10px}.calendar-header{display:flex;justify-content:space-between;align-items:center}.selected{box-shadow:0 0 5px #00000080;background-color:green!important;color:#fff!important}.calendar-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:5px}.day-of-week{text-align:center;font-weight:700;padding:5px;background-color:#f0f0f0;border:1px solid #ccc}.calendar-day{border:1px solid #ccc;padding:5px;display:flex;flex-direction:column;align-items:flex-start;background-color:#fff;position:relative;cursor:pointer}.calendar-day.not-current-month{background-color:#f0f0f0}.calendar-day.past{color:#aaa}.calendar-day.today{background-color:#e6ffe6;font-weight:700}.calendar-day.future{color:#000}.day-number{font-size:1.2em;margin-bottom:5px}.event{background-color:#d1e7dd;border-left:4px solid #0f5132;margin:5px 0;padding:2px 5px;border-radius:3px}.event-title{font-weight:700}.event-time{font-size:.8em}input[type=text],input[type=time]{width:100%;margin-top:5px;box-sizing:border-box}button{margin-top:5px;align-self:stretch;margin-left:0!important}.calendar-header button{margin-top:5px;align-self:stretch;margin-left:0!important;border:none;background:none}.align-calendar{display:flex;width:100%}.form-group.content-box{padding-bottom:0!important}.entry-indicator{position:absolute;top:5px;right:5px;width:10px;height:10px;background-color:#0f5132;border-radius:50%}.select{background-color:#fff}.entry-row{display:flex;align-items:center;margin-bottom:5px}.entry-text{font-weight:700;margin-right:10px;white-space:nowrap}.entry-value{flex:1;word-break:break-word}.entry-value a{color:#4caf50}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i2.DatePipe, name: "date" }] });
|
|
347
|
-
}
|
|
348
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CustomCalendarComponent, decorators: [{
|
|
349
|
-
type: Component,
|
|
350
|
-
args: [{ selector: 'app-custom-calendar', template: "<div class=\"align-calendar\">\n <div class=\"calendar-container\">\n <div class=\"calendar-header\">\n <button (click)=\"previousMonth()\"><< Previous >></button>\n <h3>{{ currentDate | date: 'MMMM yyyy' }}</h3>\n <button (click)=\"nextMonth()\"><< Next >></button>\n </div>\n <div class=\"calendar-grid\">\n <div class=\"day-of-week\" *ngFor=\"let day of daysOfWeek\">{{ day }}</div>\n <div\n class=\"calendar-day\"\n *ngFor=\"let day of calendarDays\"\n [class.not-current-month]=\"!day.isCurrentMonth\"\n [class.past]=\"day.isPast\"\n [class.today]=\"day.isToday\"\n [class.future]=\"day.isFuture\"\n [class.selected]=\"day.isSelected\"\n (click)=\"selectDay(day)\"\n >\n <div class=\"day-number\">{{ day.date.getDate() }}\n <span *ngIf=\"day?.events?.length > 0\" class=\"entry-indicator\" [class.select]=\"day?.isSelected\"></span>\n </div>\n <!-- <div *ngFor=\"let event of day.events\" >\n <div *ngFor=\"let entryGroup of event.entries\" class=\"event\">\n <div *ngFor=\"let key of getEntryKeys(entryGroup)\">\n <div *ngIf=\"entryGroup[key].type == 'Time'\">\n {{ entryGroup[key].input?.value | date: 'shortTime' }}\n </div>\n <div *ngIf=\"entryGroup[key].type != 'Time'\">\n {{ entryGroup[key].input }}\n </div>\n </div>\n </div>\n </div> -->\n </div>\n </div>\n </div>\n <div class=\"appoinappointment\">\n <div class=\"appointments-container\">\n <h4>Add Appointment</h4>\n <button *ngIf=\"selectedDay\" (click)=\"addAppointment()\">Add</button>\n </div>\n <!--VD 06Sep24 calendar updates--> \n <!-- RS 09DEC24 Changed keys--> \n <div *ngIf=\"showAppoinmentSection && selectedDay?.events?.length > 0\" class=\"appointments-container\">\n <h4>Appointments</h4>\n <div *ngFor=\"let event of selectedDay?.events\">\n <div class=\"event\" *ngFor=\"let entryGroup of event.entries\">\n <div class=\"event-info\">\n <div *ngFor=\"let key of getEntryKeys(entryGroup)\" class=\"entry-row\">\n <div *ngIf=\"entryGroup[key].questionText\" class=\"entry-text\">\n {{removeCharacters(entryGroup[key].questionText)}}:\n </div>\n <div class=\"entry-value\">\n <!-- VD 09Sep24- date type and link type updates -->\n <span *ngIf=\"entryGroup[key].type != 'Time' && entryGroup[key].type != 'Link'&& entryGroup[key].type != 'Date'\">{{ entryGroup[key].input }}</span>\n <span *ngIf=\"entryGroup[key].type == 'Time'\">{{ entryGroup[key].input | date: 'shortTime' }}</span>\n <span *ngIf=\"entryGroup[key].type == 'Date'\">{{ entryGroup[key].input | date: 'mediumDate' }}</span>\n <span *ngIf=\"entryGroup[key].type == 'Link'\">\n <a [href]=\"'//'+ entryGroup[key].input\" target=\"_blank\">{{removeCharacters(entryGroup[key].questionText)}}</a>\n </span>\n </div>\n </div>\n <div class=\"event-actions\">\n <button (click)=\"editEvent(event,entryGroup)\">Edit</button>\n <button (click)=\"deleteEvent(event.id,entryGroup)\">Delete</button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n</div>\n\n<!-- <app-custom-model\n [modalTitle]=\"modalTitle\"\n [isModalOpen]=\"isModalOpen\"\n [modalSize]=\"modalSize\"\n [saveButtonValue]=\"saveButtonValue\"\n [modalFooter]=\"modalFooter\"\n (saveButtonEmit)=\"onSave()\"\n (cancelButtonEmit)=\"onCancel()\"\n>\n<lib-questionbook [qbItem]=\"qbRefrenceBook\" [questions]=\"referenceQuestions\" (handleQuestion)=\"handleQuestionEvent($event)\"></lib-questionbook>\n<ng-template dynamicComponentHost ></ng-template>\n</app-custom-model> -->", styles: [".calendar-container{flex:1}.appoinappointment{flex:1;margin-left:10px}.calendar-header{display:flex;justify-content:space-between;align-items:center}.selected{box-shadow:0 0 5px #00000080;background-color:green!important;color:#fff!important}.calendar-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:5px}.day-of-week{text-align:center;font-weight:700;padding:5px;background-color:#f0f0f0;border:1px solid #ccc}.calendar-day{border:1px solid #ccc;padding:5px;display:flex;flex-direction:column;align-items:flex-start;background-color:#fff;position:relative;cursor:pointer}.calendar-day.not-current-month{background-color:#f0f0f0}.calendar-day.past{color:#aaa}.calendar-day.today{background-color:#e6ffe6;font-weight:700}.calendar-day.future{color:#000}.day-number{font-size:1.2em;margin-bottom:5px}.event{background-color:#d1e7dd;border-left:4px solid #0f5132;margin:5px 0;padding:2px 5px;border-radius:3px}.event-title{font-weight:700}.event-time{font-size:.8em}input[type=text],input[type=time]{width:100%;margin-top:5px;box-sizing:border-box}button{margin-top:5px;align-self:stretch;margin-left:0!important}.calendar-header button{margin-top:5px;align-self:stretch;margin-left:0!important;border:none;background:none}.align-calendar{display:flex;width:100%}.form-group.content-box{padding-bottom:0!important}.entry-indicator{position:absolute;top:5px;right:5px;width:10px;height:10px;background-color:#0f5132;border-radius:50%}.select{background-color:#fff}.entry-row{display:flex;align-items:center;margin-bottom:5px}.entry-text{font-weight:700;margin-right:10px;white-space:nowrap}.entry-value{flex:1;word-break:break-word}.entry-value a{color:#4caf50}\n"] }]
|
|
351
|
-
}], ctorParameters: function () { return [{ type: i1.ChangeService }]; }, propDecorators: { eventSelected: [{
|
|
352
|
-
type: Output
|
|
353
|
-
}], dateSelected: [{
|
|
354
|
-
type: Output
|
|
355
|
-
}], openModal: [{
|
|
356
|
-
type: Output
|
|
357
|
-
}], closeModal: [{
|
|
358
|
-
type: Output
|
|
359
|
-
}], allEvents: [{
|
|
360
|
-
type: Input
|
|
361
|
-
}], question: [{
|
|
362
|
-
type: Input
|
|
363
|
-
}], nxtId: [{
|
|
364
|
-
type: Input
|
|
365
|
-
}] } });
|
|
366
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tLWNhbGVuZGFyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL254dC1hcHAvc3JjL2xpYi9jb21wb25lbnRzL2N1c3RvbS1jYWxlbmRhci9jdXN0b20tY2FsZW5kYXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbnh0LWFwcC9zcmMvbGliL2NvbXBvbmVudHMvY3VzdG9tLWNhbGVuZGFyL2N1c3RvbS1jYWxlbmRhci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFjLFlBQVksRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUE0QixNQUFNLGVBQWUsQ0FBQzs7OztBQW1CckgsTUFBTSxPQUFPLHVCQUF1QjtJQWdDYjtJQS9CWCxhQUFhLEdBQUcsSUFBSSxZQUFZLEVBQU8sQ0FBQztJQUNsRCw4QkFBOEI7SUFDcEIsWUFBWSxHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7SUFDdkMsU0FBUyxHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7SUFDcEMsVUFBVSxHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7SUFDdEMsU0FBUyxHQUFVLEVBQUUsQ0FBQztJQUN0QixRQUFRLENBQVU7SUFDbEIsS0FBSyxDQUFTO0lBQ3ZCLDJGQUEyRjtJQUMzRixPQUFPLEdBQUcsRUFBRSxDQUFDO0lBQ2Isa0JBQWtCLEdBQUcsRUFBRSxDQUFDO0lBQ3hCLGNBQWMsQ0FBSztJQUNuQixnQkFBZ0IsR0FBRyxFQUFFLENBQUM7SUFDdEIsUUFBUSxHQUFHLEVBQUUsQ0FBQztJQUNkLFdBQVcsR0FBUyxJQUFJLElBQUksRUFBRSxDQUFDO0lBQy9CLFlBQVksR0FBa0IsRUFBRSxDQUFDO0lBQ2pDLFVBQVUsR0FBYSxDQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQ3RHLGFBQWEsR0FBVyxFQUFFLENBQUM7SUFDM0IsWUFBWSxHQUFXLEVBQUUsQ0FBQztJQUMxQixjQUFjLEdBQVcsRUFBRSxDQUFDO0lBQzVCLE9BQU8sR0FBVyxFQUFFLENBQUM7SUFDckIsV0FBVyxHQUF1QixJQUFJLENBQUM7SUFDdkMsV0FBVyxHQUFHLEtBQUssQ0FBQztJQUNwQixVQUFVLEdBQUcsY0FBYyxDQUFDO0lBQzVCLFNBQVMsR0FBRyxPQUFPLENBQUM7SUFDcEIsZUFBZSxHQUFHLE1BQU0sQ0FBQztJQUN6QixXQUFXLEdBQUcsSUFBSSxDQUFDO0lBQ25CLGNBQWMsQ0FBUztJQUN2QixpQkFBaUIsQ0FBTTtJQUN2QixxQkFBcUIsR0FBWSxJQUFJLENBQUM7SUFDdEMsWUFBWSxDQUFNO0lBQ2xCLFlBQXFCLGFBQTRCO1FBQTVCLGtCQUFhLEdBQWIsYUFBYSxDQUFlO0lBQUksQ0FBQztJQUN0RCxRQUFRO1FBQ0wsSUFBRyxJQUFJLENBQUMsUUFBUSxFQUFFLEtBQUssRUFBQztZQUN2QixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDO1NBQ3JDO1FBQ0YsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUM1RCxDQUFDLFdBQVcsRUFBRSxFQUFFO1lBQ1osSUFBRyxXQUFXLElBQUkscUJBQXFCLEVBQUU7Z0JBQ3ZDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQzthQUNmO1lBQ0QsSUFBRyxXQUFXLElBQUksVUFBVSxFQUFFO2dCQUM1QixJQUFHLElBQUksQ0FBQyxRQUFRLEVBQUUsS0FBSyxFQUFDO29CQUN0QixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDO2lCQUNyQztnQkFDRixJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7Z0JBQ3ZCLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO2FBQ3pCO1FBQ0wsQ0FBQyxDQUNGLENBQUM7UUFDSCx5Q0FBeUM7UUFDeEMsMENBQTBDO0lBQzVDLENBQUM7SUFDRCwwQkFBMEI7SUFDMUIsZUFBZTtRQUNiLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7UUFDdkQsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDO1FBQ3hFLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxjQUFjLEVBQUUsWUFBWSxFQUFFLEtBQUssQ0FBQztRQUNyRCxJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztRQUN4QixJQUFJLENBQUMsa0JBQWtCLEdBQUcsRUFBRSxDQUFDO1FBQzdCLElBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFDO1lBQ3hCLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFO2dCQUMzQixJQUFHLE9BQU8sQ0FBQyxpQkFBaUIsRUFBQztvQkFDM0IsSUFBSSxVQUFVLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsaUJBQWlCLENBQUMsQ0FBQztvQkFDdkQsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsUUFBUSxDQUFDLENBQUM7aUJBQ3BEO1lBQ0wsQ0FBQyxDQUFDLENBQUM7U0FDTDtRQUNELE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDMUIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUMzQixPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMxQixPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFDQSxpQkFBaUI7SUFDbEIsNEJBQTRCO0lBQzVCLGdFQUFnRTtJQUNoRSw4QkFBOEI7SUFDOUIsa0ZBQWtGO0lBQ2xGLHdEQUF3RDtJQUN4RCwrREFBK0Q7SUFDL0QscUdBQXFHO0lBQ3JHLElBQUk7SUFFSixnQkFBZ0I7UUFDZCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQzVDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxFQUFFLENBQUM7UUFFMUMsTUFBTSxZQUFZLEdBQUcsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM5QyxNQUFNLFVBQVUsR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsS0FBSyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUVoRCxNQUFNLGNBQWMsR0FBRyxZQUFZLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDN0MsTUFBTSxZQUFZLEdBQUcsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBRXpDLE1BQU0sU0FBUyxHQUFHLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ3pDLFNBQVMsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxHQUFHLGNBQWMsQ0FBQyxDQUFDO1FBRXhELE1BQU0sT0FBTyxHQUFHLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3JDLE9BQU8sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsQ0FBQyxHQUFHLFlBQVksQ0FBQyxDQUFDLENBQUM7UUFFeEQsTUFBTSxLQUFLLEdBQUcsSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUV2RCxJQUFJLENBQUMsWUFBWSxHQUFHLEVBQUUsQ0FBQztRQUN0QixLQUFLLElBQUksQ0FBQyxHQUFHLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsSUFBSSxPQUFPLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEVBQUU7WUFDMUUsTUFBTSxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDekIsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUM7Z0JBQ3JCLElBQUksRUFBRSxJQUFJO2dCQUNWLE1BQU0sRUFBRSxFQUFFO2dCQUNWLGNBQWMsRUFBRSxDQUFDLENBQUMsUUFBUSxFQUFFLEtBQUssS0FBSztnQkFDdEMsTUFBTSxFQUFFLElBQUksR0FBRyxLQUFLO2dCQUNwQixPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxLQUFLLEtBQUssQ0FBQyxPQUFPLEVBQUU7Z0JBQzNDLFFBQVEsRUFBRSxJQUFJLEdBQUcsS0FBSzthQUN2QixDQUFDLENBQUM7U0FDSjtRQUVILHFEQUFxRDtRQUNyRCxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRTtZQUM5QixHQUFHLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsS0FBSyxHQUFHLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUM7UUFDeEcsQ0FBQyxDQUFDLENBQUM7UUFDRiw4QkFBOEI7UUFDL0IsSUFBSSxHQUFHLEdBQUcsRUFBRSxDQUFBO1FBQ1osR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQztRQUNuQixHQUFHLENBQUMsT0FBTyxDQUFDLEdBQUcsS0FBSyxHQUFHLENBQUMsQ0FBQztRQUN6QixJQUFJLENBQUMsUUFBUSxHQUFHLEdBQUcsQ0FBQztJQUN0QixDQUFDO0lBRUQsU0FBUyxDQUFDLEdBQWdCO1FBQ3hCLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDaEIsOEJBQThCO1FBQy9CLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLENBQUM7UUFDbEMsSUFBSSxDQUFDLFdBQVcsR0FBRyxHQUFHLENBQUM7UUFDeEIsd0NBQXdDO1FBQ3ZDLE1BQU0scUJBQXFCLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDeEUsSUFBSSxxQkFBcUIsRUFBRTtZQUN6QixxQkFBcUIsQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO1NBQzFDO1FBQ0QseUJBQXlCO1FBQ3pCLEdBQUcsQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO1FBQ3ZCLHNEQUFzRDtRQUNyRCxJQUFJLGFBQWEsR0FBRyxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUNyQyxvQ0FBb0M7WUFDcEMsOEJBQThCO1lBQzlCLDBCQUEwQjtZQUN6QixJQUFHLElBQUksQ0FBQyxjQUFjLElBQUksY0FBYyxFQUFDO2dCQUN0QyxJQUFJLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBQ3BDLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO2FBQzFCO1lBQ0QsaUZBQWlGO1lBQ2pGLElBQUcsSUFBSSxDQUFDLE9BQU8sRUFBQztnQkFDZixJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDdkMsSUFBSSxPQUFPLENBQUMsVUFBVSxJQUFJLE9BQU8sQ0FBQyxtQkFBbUIsRUFBRTtvQkFDbkQsSUFBSSxXQUFXLEdBQUcsSUFBSSxDQUFDO29CQUN2QixJQUFJLGVBQWUsR0FBRyxPQUFPLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUM3RCxlQUFlLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFO3dCQUMvQixJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLGNBQWMsS0FBSyxRQUFRLENBQUMsQ0FBQzt3QkFDL0UsSUFBSSxPQUFPLEVBQUU7NEJBQ1QsYUFBYSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQzt5QkFDL0I7b0JBQ0wsQ0FBQyxDQUFDLENBQUM7b0JBQ0gsc0RBQXNEO29CQUN0RCxXQUFXLENBQUMsa0JBQWtCLEdBQUcsYUFBYSxDQUFDO2lCQUNsRDthQUNEO1FBQ0osQ0FBQyxDQUFDLENBQUE7SUFDSixDQUFDO0lBRUQsYUFBYTtRQUNYLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxLQUFLLENBQUM7UUFDbkMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUMzRCxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLG9DQUFvQztRQUNuRixJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDdEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFRCxTQUFTO1FBQ04sOEJBQThCO1FBQy9CLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxLQUFLLENBQUM7UUFDbkMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUMzRCxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLG9DQUFvQztRQUNuRixJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDdEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFRCxjQUFjO1FBQ1osSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7UUFDdkIsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNqRixJQUFJLENBQUMsa0JBQWtCLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQ3JDLGtCQUFrQjtZQUNsQixJQUFHLElBQUksQ0FBQyxjQUFjLElBQUksY0FBYyxFQUFDO2dCQUN2QyxJQUFHLElBQUksQ0FBQyxJQUFJLElBQUksVUFBVSxFQUFDO29CQUN6QixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7b0JBQ2xCLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQztvQkFDekIsOEJBQThCO2lCQUNoQztxQkFBSztvQkFDSixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7aUJBQ25CO2FBQ0Y7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUNILE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFDckMsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7UUFDM0IsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQztRQUNoRCxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDckIsaUJBQWlCO1FBQ2pCLCtCQUErQjtJQUNqQyxDQUFDO0lBRUQsYUFBYTtRQUNYLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDO1lBQ2xCLGNBQWMsRUFBRSxJQUFJLENBQUMsY0FBYztZQUNuQyxrQkFBa0IsRUFBRSxJQUFJLENBQUMsa0JBQWtCO1lBQzNDLFVBQVUsRUFBRyxJQUFJLENBQUMsVUFBVTtZQUM1QixTQUFTLEVBQUcsSUFBSSxDQUFDLFNBQVM7WUFDMUIsZUFBZSxFQUFHLElBQUksQ0FBQyxlQUFlO1lBQ3RDLFdBQVcsRUFBRyxJQUFJLENBQUMsV0FBVztTQUUvQixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsa0JBQWtCO1FBQ2hCLElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDO1FBQ3pCLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzdCLENBQUM7SUFDRiw4QkFBOEI7SUFFL0IsU0FBUyxDQUFDLEtBQVUsRUFBRSxVQUFlO1FBQ25DLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3BELElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyw2Q0FBNkM7UUFDbkcsSUFBSSxDQUFDLGNBQWMsR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQy9CLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxVQUFVLENBQUMsQ0FBQyxxQ0FBcUM7UUFDMUUsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUMsQ0FBQyw2Q0FBNkM7UUFDdEUsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3JCLGdCQUFnQjtRQUNqQixnQ0FBZ0M7SUFFakMsQ0FBQztJQUVELFdBQVcsQ0FBRSxPQUFlLEVBQUUsVUFBZTtRQUMzQyxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLEtBQUssT0FBTyxDQUFDLENBQUM7UUFDekQsSUFBSSxLQUFLLEVBQUU7WUFDUCw2Q0FBNkM7WUFDN0MsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDckQsSUFBSSxVQUFVLEdBQUcsQ0FBQyxDQUFDLEVBQUU7Z0JBQ2pCLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLDRCQUE0QjthQUNwRTtZQUVELDhEQUE4RDtZQUM5RCxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtnQkFDNUIsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ2xELElBQUksVUFBVSxHQUFHLENBQUMsQ0FBQyxFQUFFO29CQUNqQixJQUFJLENBQUMsU0FBUyxFQUFFLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQywwQkFBMEI7aUJBQ3BFO2FBQ0o7U0FDSjtRQUNELElBQUksU0FBUyxHQUFHLEVBQUUsQ0FBQztRQUNsQixTQUFTLENBQUMsUUFBUSxDQUFDLEdBQUcsUUFBUSxDQUFDO1FBQy9CLFNBQVMsQ0FBQyxNQUFNLENBQUMsR0FBRyxLQUFLLENBQUM7UUFDM0IsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDbkMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUMsQ0FBQyxpREFBaUQ7SUFDNUUsQ0FBQztJQUVBLDhCQUE4QjtJQUM3QixRQUFRLENBQUMsR0FBZ0IsRUFBRSxTQUFTO1FBQ2xDLGdEQUFnRDtRQUNoRCxNQUFNLFVBQVUsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQzNDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3JCLE9BQU8sR0FBRyxDQUFDO1FBQ2YsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRVAsNENBQTRDO1FBQzVDLE1BQU0sYUFBYSxHQUFHLEdBQUcsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFekUsSUFBSSxhQUFhLEVBQUU7WUFDZiw0REFBNEQ7WUFDNUQseUVBQXlFO1lBQ3pFLE1BQU0sZUFBZSxHQUFHLGFBQWEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEdBQUcsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzNFLDZDQUE2QztZQUM3QyxlQUFlLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ2pDLGFBQWEsQ0FBQyxPQUFPLEdBQUcsZUFBZSxDQUFDO1NBQzNDO2FBQU07WUFDSCw0REFBNEQ7WUFDNUQsTUFBTSxRQUFRLEdBQUc7Z0JBQ2IsRUFBRSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUU7Z0JBQ3JCLElBQUksRUFBRSxHQUFHLENBQUMsSUFBSTtnQkFDZCxPQUFPLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxtQ0FBbUM7YUFDNUQsQ0FBQztZQUNGLEdBQUcsQ0FBQyxNQUFNLEdBQUcsR0FBRyxFQUFFLE1BQU0sSUFBSSxFQUFFLENBQUE7WUFDOUIsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDMUIsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDL0IsMENBQTBDO1lBQzFDLElBQUksU0FBUyxHQUFHLEVBQUUsQ0FBQztZQUNuQixTQUFTLENBQUMsUUFBUSxDQUFDLEdBQUcsS0FBSyxDQUFDO1lBQzVCLFNBQVMsQ0FBQyxNQUFNLENBQUMsR0FBRyxRQUFRLENBQUM7WUFDN0IsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7U0FDdEM7UUFDRCxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUN4QixPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUNBLDhCQUE4QjtJQUM5QixNQUFNO1FBQ0gsSUFBSSxJQUFJLENBQUMsY0FBYyxLQUFLLElBQUksRUFBRTtZQUM5QixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLEtBQUssSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBQ3ZFLElBQUksS0FBSyxJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtnQkFDakMsbURBQW1EO2dCQUNuRCxNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLFVBQVUsS0FBSyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztnQkFDaEcsSUFBSSxVQUFVLEdBQUcsQ0FBQyxDQUFDLEVBQUU7b0JBQ2pCLEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsRUFBRTt3QkFDaEUsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUM7d0JBQ3JCLE9BQU8sR0FBRyxDQUFDO29CQUNmLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztpQkFDVjthQUNKO1lBQ0osMkNBQTJDO1lBQzFDLElBQUksU0FBUyxHQUFHLEVBQUUsQ0FBQztZQUNuQixTQUFTLENBQUMsUUFBUSxDQUFDLEdBQUcsTUFBTSxDQUFDO1lBQzdCLFNBQVMsQ0FBQyxNQUFNLENBQUMsR0FBRyxLQUFLLENBQUM7WUFDMUIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7U0FDcEM7YUFBTTtZQUNILElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRTtnQkFDbEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO2FBQzFEO1NBQ0o7UUFDRCxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUMxQixJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztJQUM1QixDQUFDO0lBRUMsZUFBZTtJQUNmLDBDQUEwQztJQUMxQywrQkFBK0I7SUFDL0IsSUFBSTtJQUNKLDhCQUE4QjtJQUM5Qiw2QkFBNkI7SUFDN0IsMERBQTBEO0lBQzFELDRFQUE0RTtJQUM1RSx3QkFBd0I7SUFDeEIsaURBQWlEO0lBQ2pELDZDQUE2QztJQUM3QyxlQUFlO0lBQ2YsMERBQTBEO0lBQzFELDBDQUEwQztJQUMxQyxRQUFRO0lBQ1IsMENBQTBDO0lBQzFDLE1BQU07SUFFUCw4QkFBOEI7SUFDN0IsVUFBVTtRQUNSLE9BQU8sR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUN2RCxDQUFDO0lBRUQsWUFBWSxDQUFDLFVBQWU7UUFDMUIsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ25DLENBQUM7SUFFRCxnQkFBZ0IsQ0FBQyxZQUFtQjtRQUNsQyxJQUFJLFdBQVcsR0FBRyxZQUFZLEVBQUUsT0FBTyxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUN4RCxPQUFPLFdBQVcsQ0FBQztJQUNyQixDQUFDO3VHQXpXWSx1QkFBdUI7MkZBQXZCLHVCQUF1QixrUUNuQnBDLDgySUFxRnVCOzsyRkRsRVYsdUJBQXVCO2tCQUxuQyxTQUFTOytCQUNFLHFCQUFxQjtvR0FLckIsYUFBYTtzQkFBdEIsTUFBTTtnQkFFRyxZQUFZO3NCQUFyQixNQUFNO2dCQUNHLFNBQVM7c0JBQWxCLE1BQU07Z0JBQ0csVUFBVTtzQkFBbkIsTUFBTTtnQkFDRSxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkluaXQsIE91dHB1dCwgU2ltcGxlQ2hhbmdlcywgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBRdWVzdGlvbiB9IGZyb20gJy4uLy4uL3dyYXBwZXInO1xuLy9pbXBvcnQgeyBRdWVzdGlvbmJvb2tDb21wb25lbnQgfSBmcm9tICcuLi8uLi9wYWdlcy9xdWVzdGlvbmJvb2svcXVlc3Rpb25ib29rLmNvbXBvbmVudCc7XG4vL2ltcG9ydCB7IENvbXBvbmVudGhvc3REaXJlY3RpdmUgfSBmcm9tICcuLi8uLi9kaXJlY3RpdmVzL2NvbXBvbmVudGhvc3QvY29tcG9uZW50aG9zdC5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgQ2hhbmdlU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2NoYW5nZS5zZXJ2aWNlJztcbmludGVyZmFjZSBDYWxlbmRhckRheSB7XG4gIGRhdGU6IERhdGU7XG4gIGV2ZW50czogYW55W107XG4gIGlzQ3VycmVudE1vbnRoOiBib29sZWFuO1xuICBpc1Bhc3Q6IGJvb2xlYW47XG4gIGlzVG9kYXk6IGJvb2xlYW47XG4gIGlzRnV0dXJlOiBib29sZWFuO1xuICBpc1NlbGVjdGVkPzogYm9vbGVhbjtcbn1cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FwcC1jdXN0b20tY2FsZW5kYXInLFxuICB0ZW1wbGF0ZVVybDogJy4vY3VzdG9tLWNhbGVuZGFyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vY3VzdG9tLWNhbGVuZGFyLmNvbXBvbmVudC5jc3MnXSxcbn0pXG5leHBvcnQgY2xhc3MgQ3VzdG9tQ2FsZW5kYXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBAT3V0cHV0KCkgZXZlbnRTZWxlY3RlZCA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICAvLyBWRCAwNlNlcDI0IGNhbGVuZGFyIGNoYW5nZXNcbiAgQE91dHB1dCgpIGRhdGVTZWxlY3RlZCA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICBAT3V0cHV0KCkgb3Blbk1vZGFsID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gIEBPdXRwdXQoKSBjbG9zZU1vZGFsID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gIEBJbnB1dCgpIGFsbEV2ZW50czogYW55W10gPSBbXTsgXG4gIEBJbnB1dCgpIHF1ZXN0aW9uOiBRdWVzdGlvblxuICBASW5wdXQoKSBueHRJZDogc3RyaW5nO1xuICAvL0BWaWV3Q2hpbGQoQ29tcG9uZW50aG9zdERpcmVjdGl2ZSwgeyBzdGF0aWM6IHRydWUgfSkgZHluYW1pY0hvc3Q6IENvbXBvbmVudGhvc3REaXJlY3RpdmU7XG4gIGVudHJpZXMgPSBbXTtcbiAgcmVmZXJlbmNlUXVlc3Rpb25zID0gW107XG4gIHFiUmVmcmVuY2VCb29rOmFueTtcbiAgY2FsZW5kYXJRdWVzdGlvbiA9IFtdO1xuICBjYWxlbmRhciA9IHt9O1xuICBjdXJyZW50RGF0ZTogRGF0ZSA9IG5ldyBEYXRlKCk7XG4gIGNhbGVuZGFyRGF5czogQ2FsZW5kYXJEYXlbXSA9IFtdO1xuICBkYXlzT2ZXZWVrOiBzdHJpbmdbXSA9IFsnU3VuZGF5JywgJ01vbmRheScsICdUdWVzZGF5JywgJ1dlZG5lc2RheScsICdUaHVyc2RheScsICdGcmlkYXknLCAnU2F0dXJkYXknXTtcbiAgbmV3RXZlbnRUaXRsZTogc3RyaW5nID0gJyc7XG4gIG5ld0V2ZW50VGltZTogc3RyaW5nID0gJyc7XG4gIG5ld0Rlc2NyaXB0aW9uOiBzdHJpbmcgPSAnJztcbiAgbmV3TGluazogc3RyaW5nID0gJyc7XG4gIHNlbGVjdGVkRGF5OiBDYWxlbmRhckRheSB8IG51bGwgPSBudWxsO1xuICBpc01vZGFsT3BlbiA9IGZhbHNlO1xuICBtb2RhbFRpdGxlID0gJ0N1c3RvbSBNb2RhbCc7XG4gIG1vZGFsU2l6ZSA9ICdsYXJnZSc7XG4gIHNhdmVCdXR0b25WYWx1ZSA9ICdTYXZlJztcbiAgbW9kYWxGb290ZXIgPSB0cnVlO1xuICBlZGl0aW5nRXZlbnRJZDogbnVtYmVyO1xuICBlZGl0aW5nRW50cnlHcm91cDogYW55O1xuICBzaG93QXBwb2lubWVudFNlY3Rpb246IGJvb2xlYW4gPSB0cnVlO1xuICBzdWJzY3JpcHRpb246IGFueTtcbiAgY29uc3RydWN0b3IoIHByaXZhdGUgY2hhbmdlU2VydmljZTogQ2hhbmdlU2VydmljZSkgeyB9XG4gIG5nT25Jbml0KCkge1xuICAgICBpZih0aGlzLnF1ZXN0aW9uPy5pbnB1dCl7XG4gICAgICB0aGlzLmFsbEV2ZW50cyA9IHRoaXMucXVlc3Rpb24uaW5wdXQ7XG4gICAgIH1cbiAgICB0aGlzLnByb2Nlc3NRdWVzdGlvbigpO1xuICAgIHRoaXMuZ2VuZXJhdGVDYWxlbmRhcigpO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9uID0gdGhpcy5jaGFuZ2VTZXJ2aWNlLmN1c3RvbUNoYW5nZSQuc3Vic2NyaWJlKFxuICAgICAgKGNoYW5nZVZhbHVlKSA9PiB7XG4gICAgICAgICAgaWYoY2hhbmdlVmFsdWUgPT0gJ2NhbGVuZGFyLW1vZGFsLXNhdmUnKSB7XG4gICAgICAgICAgICB0aGlzLm9uU2F2ZSgpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZihjaGFuZ2VWYWx1ZSA9PSAnZGF0YUJpbmQnKSB7XG4gICAgICAgICAgICBpZih0aGlzLnF1ZXN0aW9uPy5pbnB1dCl7XG4gICAgICAgICAgICAgIHRoaXMuYWxsRXZlbnRzID0gdGhpcy5xdWVzdGlvbi5pbnB1dDtcbiAgICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnByb2Nlc3NRdWVzdGlvbigpO1xuICAgICAgICAgICAgdGhpcy5nZW5lcmF0ZUNhbGVuZGFyKCk7XG4gICAgICAgICAgfVxuICAgICAgfVxuICAgICk7XG4gICAvLyB0aGlzLmRhdGVTZWxlY3RlZC5lbWl0KHRoaXMuY2FsZW5kYXIpO1xuICAgIC8vdGhpcy5ldmVudFNlbGVjdGVkLmVtaXQodGhpcy5hbGxFdmVudHMpO1xuICB9XG4gIC8vIFJTIDA5REVDMjQgQ2hhbmdlZCBrZXlzXG4gIHByb2Nlc3NRdWVzdGlvbigpe1xuICAgIHRoaXMuZW50cmllcyA9IEpTT04ucGFyc2UodGhpcy5xdWVzdGlvblsnZmllbGRzTWV0YSddKTtcbiAgICB0aGlzLnFiUmVmcmVuY2VCb29rID0gSlNPTi5wYXJzZSh0aGlzLnF1ZXN0aW9uWydxYlJlZmVyZW5jZVF1ZXN0aW9ucyddKTtcbiAgICBsZXQgdGl0bGUgPSB0aGlzLnFiUmVmcmVuY2VCb29rPy5xdWVzdGlvbmJvb2s/LnRpdGxlO1xuICAgIHRoaXMubW9kYWxUaXRsZSA9IHRpdGxlO1xuICAgIHRoaXMucmVmZXJlbmNlUXVlc3Rpb25zID0gW107XG4gICAgaWYodGhpcy5lbnRyaWVzLmxlbmd0aCA+IDApe1xuICAgICAgIHRoaXMuZW50cmllcy5mb3JFYWNoKGVsZW1lbnQgPT4ge1xuICAgICAgICAgICBpZihlbGVtZW50LnF1ZXN0aW9uUmVmZXJlbmNlKXtcbiAgICAgICAgICAgICBsZXQgcVJlZmVyZW5jZSA9IEpTT04ucGFyc2UoZWxlbWVudC5xdWVzdGlvblJlZmVyZW5jZSk7XG4gICAgICAgICAgICAgdGhpcy5yZWZlcmVuY2VRdWVzdGlvbnMucHVzaChxUmVmZXJlbmNlPy5xdWVzdGlvbik7XG4gICAgICAgICAgIH1cbiAgICAgICB9KTtcbiAgICB9XG4gICAgY29uc29sZS5sb2coJ2VudHJpZXMtLT4nKTtcbiAgICBjb25zb2xlLmxvZygncXVlc3Rpb24tLT4nKTtcbiAgICBjb25zb2xlLmxvZyh0aGlzLmVudHJpZXMpO1xuICAgIGNvbnNvbGUubG9nKHRoaXMucmVmZXJlbmNlUXVlc3Rpb25zKTtcbiAgfVxuICAgLy8gc3VuZGF5IGNvbW1lbnRcbiAgLy8gb3BlblF1ZXN0aW9uQm9va01vZGFsKCkge1xuICAvLyAgIGNvbnN0IHZpZXdDb250YWluZXJSZWYgPSB0aGlzLmR5bmFtaWNIb3N0LnZpZXdDb250YWluZXJSZWY7XG4gIC8vICAgdmlld0NvbnRhaW5lclJlZi5jbGVhcigpO1xuICAvLyAgIGNvbnN0IGNvbXBvbmVudFJlZiA9IHZpZXdDb250YWluZXJSZWYuY3JlYXRlQ29tcG9uZW50KFF1ZXN0aW9uYm9va0NvbXBvbmVudCk7XG4gIC8vICAgY29tcG9uZW50UmVmLmluc3RhbmNlLnFiSXRlbSA9IHRoaXMucWJSZWZyZW5jZUJvb2s7XG4gIC8vICAgY29tcG9uZW50UmVmLmluc3RhbmNlLnF1ZXN0aW9ucyA9IHRoaXMucmVmZXJlbmNlUXVlc3Rpb25zO1xuICAvLyAgIGNvbXBvbmVudFJlZi5pbnN0YW5jZS5oYW5kbGVRdWVzdGlvbi5zdWJzY3JpYmUoKGV2ZW50OiBhbnkpID0+IHRoaXMuaGFuZGxlUXVlc3Rpb25FdmVudChldmVudCkpO1xuICAvLyB9XG5cbiAgZ2VuZXJhdGVDYWxlbmRhcigpIHtcbiAgICBjb25zdCB5ZWFyID0gdGhpcy5jdXJyZW50RGF0ZS5nZXRGdWxsWWVhcigpO1xuICAgIGNvbnN0IG1vbnRoID0gdGhpcy5jdXJyZW50RGF0ZS5nZXRNb250aCgpO1xuXG4gICAgY29uc3Qgc3RhcnRPZk1vbnRoID0gbmV3IERhdGUoeWVhciwgbW9udGgsIDEpO1xuICAgIGNvbnN0IGVuZE9mTW9udGggPSBuZXcgRGF0ZSh5ZWFyLCBtb250aCArIDEsIDApO1xuXG4gICAgY29uc3Qgc3RhcnREYXlPZldlZWsgPSBzdGFydE9mTW9udGguZ2V0RGF5KCk7XG4gICAgY29uc3QgZW5kRGF5T2ZXZWVrID0gZW5kT2ZNb250aC5nZXREYXkoKTtcblxuICAgIGNvbnN0IHN0YXJ0RGF0ZSA9IG5ldyBEYXRlKHN0YXJ0T2ZNb250aCk7XG4gICAgc3RhcnREYXRlLnNldERhdGUoc3RhcnREYXRlLmdldERhdGUoKSAtIHN0YXJ0RGF5T2ZXZWVrKTtcblxuICAgIGNvbnN0IGVuZERhdGUgPSBuZXcgRGF0ZShlbmRPZk1vbnRoKTtcbiAgICBlbmREYXRlLnNldERhdGUoZW5kRGF0ZS5nZXREYXRlKCkgKyAoNiAtIGVuZERheU9mV2VlaykpO1xuXG4gICAgY29uc3QgdG9kYXkgPSBuZXcgRGF0ZShuZXcgRGF0ZSgpLnNldEhvdXJzKDAsIDAsIDAsIDApKTtcbiAgICBcbiAgICAgdGhpcy5jYWxlbmRhckRheXMgPSBbXTtcbiAgICAgIGZvciAobGV0IGQgPSBuZXcgRGF0ZShzdGFydERhdGUpOyBkIDw9IGVuZERhdGU7IGQuc2V0RGF0ZShkLmdldERhdGUoKSArIDEpKSB7XG4gICAgICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZShkKTtcbiAgICAgICAgdGhpcy5jYWxlbmRhckRheXMucHVzaCh7XG4gICAgICAgICAgZGF0ZTogZGF0ZSxcbiAgICAgICAgICBldmVudHM6IFtdLFxuICAgICAgICAgIGlzQ3VycmVudE1vbnRoOiBkLmdldE1vbnRoKCkgPT09IG1vbnRoLFxuICAgICAgICAgIGlzUGFzdDogZGF0ZSA8IHRvZGF5LFxuICAgICAgICAgIGlzVG9kYXk6IGRhdGUuZ2V0VGltZSgpID09PSB0b2RheS5nZXRUaW1lKCksXG4gICAgICAgICAgaXNGdXR1cmU6IGRhdGUgPiB0b2RheSxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAvLyBQb3B1bGF0ZSBjYWxlbmRhciB3aXRoIGV2ZW50cyBmcm9tIGFsbEV2ZW50cyBhcnJheVxuICAgIHRoaXMuY2FsZW5kYXJEYXlzLmZvckVhY2goZGF5ID0+IHtcbiAgICAgIGRheS5ldmVudHMgPSB0aGlzLmFsbEV2ZW50cz8uZmlsdGVyKGV2ZW50ID0+IGV2ZW50Py5kYXRlPy50b0RhdGVTdHJpbmcoKSA9PT0gZGF5LmRhdGUudG9EYXRlU3RyaW5nKCkpO1xuICAgIH0pO1xuICAgICAvLyBWRCAwNlNlcDI0IGNhbGVuZGFyIGNoYW5nZXNcbiAgICBsZXQgY2FsID0ge31cbiAgICBjYWxbJ3llYXInXSA9IHllYXI7XG4gICAgY2FsWydtb250aCddID0gbW9udGggKyAxO1xuICAgIHRoaXMuY2FsZW5kYXIgPSBjYWw7XG4gIH1cblxuICBzZWxlY3REYXkoZGF5OiBDYWxlbmRhckRheSkge1xuICAgIGNvbnNvbGUubG9nKGRheSk7XG4gICAgIC8vIFZEIDA2U2VwMjQgY2FsZW5kYXIgY2hhbmdlc1xuICAgIHRoaXMuc2hvd0FwcG9pbm1lbnRTZWN0aW9uID0gdHJ1ZTtcbiAgICB0aGlzLnNlbGVjdGVkRGF5ID0gZGF5O1xuICAgLy8gdGhpcy5ldmVudFNlbGVjdGVkLmVtaXQoZGF5Py5ldmVudHMpO1xuICAgIGNvbnN0IHByZXZpb3VzbHlTZWxlY3RlZERheSA9IHRoaXMuY2FsZW5kYXJEYXlzLmZpbmQoZCA9PiBkLmlzU2VsZWN0ZWQpO1xuICAgIGlmIChwcmV2aW91c2x5U2VsZWN0ZWREYXkpIHtcbiAgICAgIHByZXZpb3VzbHlTZWxlY3RlZERheS5pc1NlbGVjdGVkID0gZmFsc2U7XG4gICAgfVxuICAgIC8vIFNlbGVjdCB0aGUgY2xpY2tlZCBkYXlcbiAgICBkYXkuaXNTZWxlY3RlZCA9IHRydWU7XG4gICAvLyBWRCAwOVNlcDI0LSBzZXR1cCB0aGUgcXVlcnkgcGFyYW0gZGF0YSBmb3IgYXBpIGNhbGxcbiAgICBsZXQgcmVmZXJlbmNlRGF0YSA9IFtdO1xuICAgIHRoaXMucmVmZXJlbmNlUXVlc3Rpb25zLmZvckVhY2gocXVlcyA9PiB7XG4gICAgICAvLyBWRCAwOS0wOS0yNCBnZXQgdGhlIHNlbGVjdGVkIGRhdGVcbiAgICAgIC8vIG5lZWQgdG8gYWRkIGluIHRoZSBkb2N1bWVudFxuICAgICAgLy8gUlMgMDlERUMyNCBDaGFuZ2VkIGtleXNcbiAgICAgICBpZihxdWVzLnJlZmVyZW5jZUZpZWxkID09ICdzZWxlY3RlZERhdGUnKXtcbiAgICAgICAgICBxdWVzLmlucHV0ID0gZGF5LmRhdGUudG9JU09TdHJpbmcoKTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhxdWVzLmlucHV0KTtcbiAgICAgICB9XG4gICAgICAgLy8gVkQgMDktMDktMjQgZ2V0IHRoZSBxdWVyeSByZWZyZW5jZSAgZmllbGQgZGF0YSB0byBwYXNzIHRoZSBxdWVyeVBhcmFtICBmb3IgYXBpXG4gICAgICAgaWYocXVlcy5zdWJUZXh0KXtcbiAgICAgICAgbGV0IHN1YlRleHQgPSBKU09OLnBhcnNlKHF1ZXMuc3ViVGV4dCk7XG4gICAgICAgIGlmIChzdWJUZXh0LnF1ZXJ5RmllbGQgJiYgc3ViVGV4dC5xdWVyeVZhbHVlUmVmZXJlbmNlKSB7XG4gICAgICAgICAgICBsZXQgY3VycmVudFF1ZXMgPSBxdWVzO1xuICAgICAgICAgICAgbGV0IHF1ZXJ5UmVmZXJlbmNlcyA9IHN1YlRleHQucXVlcnlWYWx1ZVJlZmVyZW5jZS5zcGxpdCgnLCcpOyAgIFxuICAgICAgICAgICAgcXVlcnlSZWZlcmVuY2VzLmZvckVhY2gocmVmRmllbGQgPT4ge1xuICAgICAgICAgICAgICAgIGxldCByZWZRdWVzID0gdGhpcy5yZWZlcmVuY2VRdWVzdGlvbnMuZmluZChxID0+IHEucmVmZXJlbmNlRmllbGQgPT09IHJlZkZpZWxkKTtcbiAgICAgICAgICAgICAgICBpZiAocmVmUXVlcykge1xuICAgICAgICAgICAgICAgICAgICByZWZlcmVuY2VEYXRhLnB1c2gocmVmUXVlcyk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAvLyBBZGQgdGhlIHJlZmVyZW5jZURhdGEgYXJyYXkgdG8gdGhlIGN1cnJlbnQgcXVlc3Rpb25cbiAgICAgICAgICAgIGN1cnJlbnRRdWVzLnJlZmVyZW5jZVF1ZXJ5RGF0YSA9IHJlZmVyZW5jZURhdGE7XG4gICAgICAgIH1cbiAgICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIHByZXZpb3VzTW9udGgoKSB7XG4gICAgdGhpcy5zaG93QXBwb2lubWVudFNlY3Rpb24gPSBmYWxzZTtcbiAgICB0aGlzLmN1cnJlbnREYXRlLnNldE1vbnRoKHRoaXMuY3VycmVudERhdGUuZ2V0TW9udGgoKSAtIDEpO1xuICAgIHRoaXMuY3VycmVudERhdGUgPSBuZXcgRGF0ZSh0aGlzLmN1cnJlbnREYXRlKTsgLy8gRW5zdXJlIHRoZSBkYXRlIG9iamVjdCBpcyB1cGRhdGVkXG4gICAgdGhpcy5nZW5lcmF0ZUNhbGVuZGFyKCk7XG4gICAgdGhpcy5kYXRlU2VsZWN0ZWQuZW1pdCh0aGlzLmNhbGVuZGFyKTtcbiAgICB0aGlzLmV2ZW50U2VsZWN0ZWQuZW1pdCh0aGlzLmFsbEV2ZW50cyk7XG4gIH1cblxuICBuZXh0TW9udGgoKSB7XG4gICAgIC8vIFZEIDA2U2VwMjQgY2FsZW5kYXIgY2hhbmdlc1xuICAgIHRoaXMuc2hvd0FwcG9pbm1lbnRTZWN0aW9uID0gZmFsc2U7XG4gICAgdGhpcy5jdXJyZW50RGF0ZS5zZXRNb250aCh0aGlzLmN1cnJlbnREYXRlLmdldE1vbnRoKCkgKyAxKTtcbiAgICB0aGlzLmN1cnJlbnREYXRlID0gbmV3IERhdGUodGhpcy5jdXJyZW50RGF0ZSk7IC8vIEVuc3VyZSB0aGUgZGF0ZSBvYmplY3QgaXMgdXBkYXRlZFxuICAgIHRoaXMuZ2VuZXJhdGVDYWxlbmRhcigpO1xuICAgIHRoaXMuZGF0ZVNlbGVjdGVkLmVtaXQodGhpcy5jYWxlbmRhcik7XG4gICAgdGhpcy5ldmVudFNlbGVjdGVkLmVtaXQodGhpcy5hbGxFdmVudHMpO1xuICB9XG5cbiAgYWRkQXBwb2ludG1lbnQoKSB7XG4gICAgdGhpcy5pc01vZGFsT3BlbiA9IHRydWU7XG4gICAgIHRoaXMuY2FsZW5kYXJRdWVzdGlvbiA9IHRoaXMucmVmZXJlbmNlUXVlc3Rpb25zLm1hcChxID0+ICh7IC4uLnEsIGlucHV0OiAnJyB9KSk7XG4gICAgdGhpcy5yZWZlcmVuY2VRdWVzdGlvbnMuZm9yRWFjaChxdWVzID0+IHtcbiAgICAgIC8vIGNsZWFyIHRoZSBpbnB1dFxuICAgICAgaWYocXVlcy5yZWZlcmVuY2VGaWVsZCAhPSAnc2VsZWN0ZWREYXRlJyl7XG4gICAgICAgIGlmKHF1ZXMudHlwZSA9PSAnRHJvcGRvd24nKXtcbiAgICAgICAgICBkZWxldGUgcXVlcy5pbnB1dDtcbiAgICAgICAgICBkZWxldGUgcXVlcy5zZWxlY3RlZFZhbHVlO1xuICAgICAgICAgICAvLyBWRCAwNlNlcDI0IGNhbGVuZGFyIGNoYW5nZXNcbiAgICAgICAgfWVsc2Uge1xuICAgICAgICAgIGRlbGV0ZSBxdWVzLmlucHV0O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gICAgY29uc29sZS5sb2codGhpcy5yZWZlcmVuY2VRdWVzdGlvbnMpO1xuICAgIHRoaXMuZWRpdGluZ0V2ZW50SWQgPSBudWxsO1xuICAgIHRoaXMuY2FsZW5kYXJRdWVzdGlvbiA9IHRoaXMucmVmZXJlbmNlUXVlc3Rpb25zO1xuICAgIHRoaXMub3BlbkJvb2tNb2RlbCgpO1xuICAgIC8vIHN1bmRheSBjb21tZW50XG4gICAgLy90aGlzLm9wZW5RdWVzdGlvbkJvb2tNb2RhbCgpO1xuICB9XG5cbiAgb3BlbkJvb2tNb2RlbCgpe1xuICAgIHRoaXMub3Blbk1vZGFsLmVtaXQoe1xuICAgICAgcWJSZWZyZW5jZUJvb2s6IHRoaXMucWJSZWZyZW5jZUJvb2ssXG4gICAgICByZWZlcmVuY2VRdWVzdGlvbnM6IHRoaXMucmVmZXJlbmNlUXVlc3Rpb25zLFxuICAgICAgbW9kYWxUaXRsZSA6IHRoaXMubW9kYWxUaXRsZSxcbiAgICAgIG1vZGFsU2l6ZSA6IHRoaXMubW9kYWxTaXplLFxuICAgICAgc2F2ZUJ1dHRvblZhbHVlIDogdGhpcy5zYXZlQnV0dG9uVmFsdWUsXG4gICAgICBtb2RhbEZvb3RlciA6IHRoaXMubW9kYWxGb290ZXIsXG5cbiAgICB9KTtcbiAgfVxuXG4gIGNsb3NlQ2FsZW5kYXJNb2RhbCgpIHtcbiAgICB0aGlzLmlzTW9kYWxPcGVuID0gZmFsc2U7XG4gICAgdGhpcy5jbG9zZU1vZGFsLmVtaXQodHJ1ZSk7XG4gIH1cbiAvLyBWRCAwNlNlcDI0IGNhbGVuZGFyIGNoYW5nZXNcblxuZWRpdEV2ZW50KGV2ZW50OiBhbnksIGVudHJ5R3JvdXA6IGFueSkge1xuICB0aGlzLmlzTW9kYWxPcGVuID0gdHJ1ZTtcbiAgdGhpcy5yZWZlcmVuY2VRdWVzdGlvbnMgPSBPYmplY3QudmFsdWVzKGVudHJ5R3JvdXApO1xuICB0aGlzLmNhbGVuZGFyUXVlc3Rpb24gPSBbLi4udGhpcy5yZWZlcmVuY2VRdWVzdGlvbnNdOyAvLyBNYWtlIGEgY29weSBvZiB0aGUgY3VycmVudCBlbnRyaWVzIHRvIGVkaXRcbiAgdGhpcy5lZGl0aW5nRXZlbnRJZCA9IGV2ZW50LmlkO1xuICB0aGlzLmVkaXRpbmdFbnRyeUdyb3VwID0gZW50cnlHcm91cDsgLy8gU3RvcmUgdGhlIGVudHJ5IGdyb3VwIGJlaW5nIGVkaXRlZFxuICB0aGlzLmdlbmVyYXRlQ2FsZW5kYXIoKTsgLy8gUmVnZW5lcmF0ZSB0aGUgY2FsZW5kYXIgdG8gcmVmbGVjdCBjaGFuZ2VzXG4gIHRoaXMub3BlbkJvb2tNb2RlbCgpO1xuICAvLyBzdWRheSBjb21tZW50XG4gLy8gdGhpcy5vcGVuUXVlc3Rpb25Cb29rTW9kYWwoKTtcblxufVxuXG5kZWxldGVFdmVudCggZXZlbnRJZDogbnVtYmVyLCBlbnRyeUdyb3VwOiBhbnkpIHtcbiAgbGV0IGV2ZW50ID0gdGhpcy5hbGxFdmVudHM/LmZpbmQoZSA9PiBlPy5pZCA9PT0gZXZlbnRJZCk7XG4gIGlmIChldmVudCkge1xuICAgICAgLy8gRmluZCB0aGUgaW5kZXggb2YgdGhlIGVudHJ5R3JvdXAgdG8gZGVsZXRlXG4gICAgICBjb25zdCBlbnRyeUluZGV4ID0gZXZlbnQuZW50cmllcy5pbmRleE9mKGVudHJ5R3JvdXApO1xuICAgICAgaWYgKGVudHJ5SW5kZXggPiAtMSkge1xuICAgICAgICAgIGV2ZW50LmVudHJpZXMuc3BsaWNlKGVudHJ5SW5kZXgsIDEpOyAvLyBSZW1vdmUgdGhlIHNwZWNpZmljIGVudHJ5XG4gICAgICB9XG5cbiAgICAgIC8vIElmIHRoZSBldmVudCBoYXMgbm8gbW9yZSBlbnRyaWVzLCByZW1vdmUgdGhlIGV2ZW50IGVudGlyZWx5XG4gICAgICBpZiAoZXZlbnQuZW50cmllcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICBjb25zdCBldmVudEluZGV4ID0gdGhpcy5hbGxFdmVudHM/LmluZGV4T2YoZXZlbnQpO1xuICAgICAgICAgIGlmIChldmVudEluZGV4ID4gLTEpIHtcbiAgICAgICAgICAgICAgdGhpcy5hbGxFdmVudHM/LnNwbGljZShldmVudEluZGV4LCAxKTsgLy8gUmVtb3ZlIHRoZSBlbnRpcmUgZXZlbnRcbiAgICAgICAgICB9XG4gICAgICB9XG4gIH1cbiAgbGV0IGV2ZW50RGF0YSA9IHt9O1xuICAgZXZlbnREYXRhWydhY3Rpb24nXSA9IFwiZGVsZXRlXCI7XG4gICBldmVudERhdGFbJ2RhdGEnXSA9IGV2ZW50O1xuICB0aGlzLmV2ZW50U2VsZWN0ZWQuZW1pdChldmVudERhdGEpO1xuICB0aGlzLmdlbmVyYXRlQ2FsZW5kYXIoKTsgLy8gUmVnZW5lcmF0ZSB0aGUgY2FsZW5kYXIgdG8gcmVmbGVjdCB0aGUgY2hhbmdlc1xufVxuXG4gLy8gVkQgMDZTZXAyNCBjYWxlbmRhciBjaGFuZ2VzXG4gIGFkZEV2ZW50KGRheTogQ2FsZW5kYXJEYXksIGVudHJ5UXVlcykge1xuICAgIC8vIFRyYW5zZm9ybSBuZXcgZW50cmllcyBpbnRvIHRoZSBkZXNpcmVkIGZvcm1hdFxuICAgIGNvbnN0IG5ld0VudHJpZXMgPSBlbnRyeVF1ZXMucmVkdWNlKChhY2MsIHEpID0+IHtcbiAgICAgICAgYWNjW3EuaWRdID0geyAuLi5xIH07XG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgfSwge30pO1xuXG4gICAgLy8gRmluZCBhbiBleGlzdGluZyBldmVudCBmb3IgdGhlIGdpdmVuIGRhdGVcbiAgICBjb25zdCBleGlzdGluZ0V2ZW50ID0gZGF5LmV2ZW50cz8uZmluZChldmVudCA9PiBldmVudC5kYXRlID09PSBkYXkuZGF0ZSk7XG5cbiAgICBpZiAoZXhpc3RpbmdFdmVudCkge1xuICAgICAgICAvLyBNZXJnZSBuZXcgZW50cmllcyBpbnRvIHRoZSBleGlzdGluZyBldmVudCdzIGVudHJpZXMgYXJyYXlcbiAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIGVudHJpZXMgYXJyYXkgYWxyZWFkeSBjb250YWlucyBhbiBvYmplY3Qgd2l0aCB0aGUgc2FtZSBpZFxuICAgICAgICBjb25zdCBleGlzdGluZ0VudHJpZXMgPSBleGlzdGluZ0V2ZW50LmVudHJpZXMubWFwKGVudHJ5ID0+ICh7IC4uLmVudHJ5IH0pKTtcbiAgICAgICAgLy8gQXBwZW5kIG5ldyBlbnRyaWVzIHRvIHRoZSBleGlzdGluZyBlbnRyaWVzXG4gICAgICAgIGV4aXN0aW5nRW50cmllcy5wdXNoKG5ld0VudHJpZXMpO1xuICAgICAgICBleGlzdGluZ0V2ZW50LmVudHJpZXMgPSBleGlzdGluZ0VudHJpZXM7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQ3JlYXRlIGEgbmV3IGV2ZW50IGlmIGl0IGRvZXNuJ3QgZXhpc3QgZm9yIHRoZSBnaXZlbiBkYXRlXG4gICAgICAgIGNvbnN0IG5ld0V2ZW50ID0ge1xuICAgICAgICAgICAgaWQ6IHRoaXMuZ2VuZXJhdGVJZCgpLFxuICAgICAgICAgICAgZGF0ZTogZGF5LmRhdGUsXG4gICAgICAgICAgICBlbnRyaWVzOiBbbmV3RW50cmllc10gLy8gV3JhcCB0aGUgbmV3IGVudHJpZXMgaW4gYW4gYXJyYXlcbiAgICAgICAgfTtcbiAgICAgICAgZGF5LmV2ZW50cyA9IGRheT8uZXZlbnRzIHx8IFtdXG4gICAgICAgIGRheS5ldmVudHMucHVzaChuZXdFdmVudCk7XG4gICAgICAgIHRoaXMuYWxsRXZlbnRzPy5wdXNoKG5ld0V2ZW50KTtcbiAgICAgICAgLy90aGlzLmV2ZW50U2VsZWN0ZWQuZW1pdCh0aGlzLmFsbEV2ZW50cyk7XG4gICAgICAgIGxldCBldmVudERhdGEgPSB7fTtcbiAgICAgICAgZXZlbnREYXRhWydhY3Rpb24nXSA9IFwiYWRkXCI7XG4gICAgICAgIGV2ZW50RGF0YVsnZGF0YSddID0gbmV3RXZlbnQ7XG4gICAgICAgIHRoaXMuZXZlbnRTZWxlY3RlZC5lbWl0KGV2ZW50RGF0YSk7XG4gICAgfVxuICAgIHRoaXMuZ2VuZXJhdGVDYWxlbmRhcigpO1xuICAgIGNvbnNvbGUubG9nKCdhbGxFdmVudHMnLCB0aGlzLmFsbEV2ZW50cyk7XG59XG4gLy8gVkQgMDZTZXAyNCBjYWxlbmRhciBjaGFuZ2VzXG4gb25TYXZlKCkge1xuICAgIGlmICh0aGlzLmVkaXRpbmdFdmVudElkICE9PSBudWxsKSB7XG4gICAgICAgIGNvbnN0IGV2ZW50ID0gdGhpcy5hbGxFdmVudHM/LmZpbmQoZSA9PiBlPy5pZCA9PT0gdGhpcy5lZGl0aW5nRXZlbnRJZCk7XG4gICAgICAgIGlmIChldmVudCAmJiB0aGlzLmVkaXRpbmdFbnRyeUdyb3VwKSB7XG4gICAgICAgICAgICAvLyBVcGRhdGUgdGhlIHNwZWNpZmljIGVudHJ5IGdyb3VwIHdpdGhpbiB0aGUgZXZlbnRcbiAgICAgICAgICAgIGNvbnN0IGVudHJ5SW5kZXggPSBldmVudC5lbnRyaWVzLmZpbmRJbmRleChlbnRyeUdyb3VwID0+IGVudHJ5R3JvdXAgPT09IHRoaXMuZWRpdGluZ0VudHJ5R3JvdXApO1xuICAgICAgICAgICAgaWYgKGVudHJ5SW5kZXggPiAtMSkge1xuICAgICAgICAgICAgICAgIGV2ZW50LmVudHJpZXNbZW50cnlJbmRleF0gPSB0aGlzLmNhbGVuZGFyUXVlc3Rpb24ucmVkdWNlKChhY2MsIHEpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgYWNjW3EuaWRdID0geyAuLi5xIH07XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBhY2M7XG4gICAgICAgICAgICAgICAgfSwge30pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgIC8vIHRoaXMuZXZlbnRTZWxlY3RlZC5lbWl0KHRoaXMuYWxsRXZlbnRzKTtcbiAgICAgIGxldCBldmVudERhdGEgPSB7fTtcbiAgICAgIGV2ZW50RGF0YVsnYWN0aW9uJ10gPSBcImVkaXRcIjtcbiAgICAgIGV2ZW50RGF0YVsnZGF0YSddID0gZXZlbnQ7XG4gICAgICB0aGlzLmV2ZW50U2VsZWN0ZWQuZW1pdChldmVudERhdGEpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh0aGlzLnNlbGVjdGVkRGF5KSB7XG4gICAgICAgICAgICB0aGlzLmFkZEV2ZW50KHRoaXMuc2VsZWN0ZWREYXksIHRoaXMuY2FsZW5kYXJRdWVzdGlvbik7XG4gICAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5jbG9zZUNhbGVuZGFyTW9kYWwoKTtcbiAgICB0aGlzLmdlbmVyYXRlQ2FsZW5kYXIoKTtcbn1cblxuICAvLyBvbkNhbmNlbCgpIHtcbiAgLy8gICBjb25zb2xlLmxvZygnQ2FuY2VsIGJ1dHRvbiBjbGlja2VkJyk7XG4gIC8vICAgdGhpcy5jbG9zZUNhbGVuZGFyTW9kYWwoKTtcbiAgLy8gfVxuICAvL3RoaXMgZnVudGlvbiBuZWVkIHRvIGJlIHVzZWRcbiAgLy8gaGFuZGxlUXVlc3Rpb25FdmVudChxdWVzKXtcbiAgLy8gICAgIC8vIFVwZGF0ZSB0aGUgcXVlc3Rpb25zIGFycmF5IHdpdGggdGhlIG5ldyBxdWVzdGlvblxuICAvLyAgICAgY29uc3QgaW5kZXggPSB0aGlzLmNhbGVuZGFyUXVlc3Rpb24uZmluZEluZGV4KHEgPT4gcS5pZCA9PT0gcXVlcy5pZCk7XG4gIC8vICAgICBpZiAoaW5kZXggPiAtMSkge1xuICAvLyAgICAgICAvLyBJZiBxdWVzdGlvbiBhbHJlYWR5IGV4aXN0cywgdXBkYXRlIGl0XG4gIC8vICAgICAgIHRoaXMuY2FsZW5kYXJRdWVzdGlvbltpbmRleF0gPSBxdWVzO1xuICAvLyAgICAgfSBlbHNlIHtcbiAgLy8gICAgICAgLy8gSWYgcXVlc3Rpb24gZG9lc24ndCBleGlzdCwgYWRkIGl0IHRvIHRoZSBhcnJheVxuICAvLyAgICAgICB0aGlzLmNhbGVuZGFyUXVlc3Rpb24ucHVzaChxdWVzKTtcbiAgLy8gICAgIH1cbiAgLy8gICAgIGNvbnNvbGUubG9nKHRoaXMuY2FsZW5kYXJRdWVzdGlvbik7XG4gIC8vICAgfVxuXG4gLy8gVkQgMDZTZXAyNCBjYWxlbmRhciBjaGFuZ2VzXG4gIGdlbmVyYXRlSWQoKSB7XG4gICAgcmV0dXJuICdfJyArIE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnN1YnN0cigyLCA5KTtcbiAgfVxuXG4gIGdldEVudHJ5S2V5cyhlbnRyeUdyb3VwOiBhbnkpOiBzdHJpbmdbXSB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKGVudHJ5R3JvdXApO1xufVxuXG5yZW1vdmVDaGFyYWN0ZXJzKHF1ZXN0aW9uVGV4dDpzdHJpbmcpe1xuICBsZXQgdXBkYXRlZFRleHQgPSBxdWVzdGlvblRleHQ/LnJlcGxhY2UoLzxbXj5dKj4vZywgJycpO1xuICByZXR1cm4gdXBkYXRlZFRleHQ7XG59XG5cbn1cbiIsIjxkaXYgY2xhc3M9XCJhbGlnbi1jYWxlbmRhclwiPlxuICAgIDxkaXYgY2xhc3M9XCJjYWxlbmRhci1jb250YWluZXJcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJjYWxlbmRhci1oZWFkZXJcIj5cbiAgICAgICAgICA8YnV0dG9uIChjbGljayk9XCJwcmV2aW91c01vbnRoKClcIj48PCBQcmV2aW91cyA+PjwvYnV0dG9uPlxuICAgICAgICAgIDxoMz57eyBjdXJyZW50RGF0ZSB8IGRhdGU6ICdNTU1NIHl5eXknIH19PC9oMz5cbiAgICAgICAgICA8YnV0dG9uIChjbGljayk9XCJuZXh0TW9udGgoKVwiPjw8IE5leHQgPj48L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImNhbGVuZGFyLWdyaWRcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGF5LW9mLXdlZWtcIiAqbmdGb3I9XCJsZXQgZGF5IG9mIGRheXNPZldlZWtcIj57eyBkYXkgfX08L2Rpdj5cbiAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgIGNsYXNzPVwiY2FsZW5kYXItZGF5XCJcbiAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IGRheSBvZiBjYWxlbmRhckRheXNcIlxuICAgICAgICAgICAgICBbY2xhc3Mubm90LWN1cnJlbnQtbW9udGhdPVwiIWRheS5pc0N1cnJlbnRNb250aFwiXG4gICAgICAgICAgICAgIFtjbGFzcy5wYXN0XT1cImRheS5pc1Bhc3RcIlxuICAgICAgICAgICAgICBbY2xhc3MudG9kYXldPVwiZGF5LmlzVG9kYXlcIlxuICAgICAgICAgICAgICBbY2xhc3MuZnV0dXJlXT1cImRheS5pc0Z1dHVyZVwiXG4gICAgICAgICAgICAgIFtjbGFzcy5zZWxlY3RlZF09XCJkYXkuaXNTZWxlY3RlZFwiXG4gICAgICAgICAgICAgIChjbGljayk9XCJzZWxlY3REYXkoZGF5KVwiXG4gICAgICAgID5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRheS1udW1iZXJcIj57eyBkYXkuZGF0ZS5nZXREYXRlKCkgfX1cbiAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cImRheT8uZXZlbnRzPy5sZW5ndGggPiAwXCIgY2xhc3M9XCJlbnRyeS1pbmRpY2F0b3JcIiBbY2xhc3Muc2VsZWN0XT1cImRheT8uaXNTZWxlY3RlZFwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwhLS0gPGRpdiAqbmdGb3I9XCJsZXQgZXZlbnQgb2YgZGF5LmV2ZW50c1wiID5cbiAgICAgICAgICAgICAgICAgIDxkaXYgKm5nRm9yPVwibGV0IGVudHJ5R3JvdXAgb2YgZXZlbnQuZW50cmllc1wiIGNsYXNzPVwiZXZlbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBrZXkgb2YgZ2V0RW50cnlLZXlzKGVudHJ5R3JvdXApXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJlbnRyeUdyb3VwW2tleV0udHlwZSA9PSAnVGltZSdcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGVudHJ5R3JvdXBba2V5XS5pbnB1dD8udmFsdWUgfCBkYXRlOiAnc2hvcnRUaW1lJyB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImVudHJ5R3JvdXBba2V5XS50eXBlICE9ICdUaW1lJ1wiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgZW50cnlHcm91cFtrZXldLmlucHV0IH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvZGl2PiAtLT5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwiYXBwb2luYXBwb2ludG1lbnRcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJhcHBvaW50bWVudHMtY29udGFpbmVyXCI+XG4gICAgICAgICAgPGg0PkFkZCBBcHBvaW50bWVudDwvaDQ+XG4gICAgICAgICAgPGJ1dHRvbiAqbmdJZj1cInNlbGVjdGVkRGF5XCIgKGNsaWNrKT1cImFkZEFwcG9pbnRtZW50KClcIj5BZGQ8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuICAgICAgPCEtLVZEIDA2U2VwMjQgY2FsZW5kYXIgdXBkYXRlcy0tPiBcbiAgICAgIDwhLS0gUlMgMDlERUMyNCBDaGFuZ2VkIGtleXMtLT4gXG4gICAgICA8ZGl2ICpuZ0lmPVwic2hvd0FwcG9pbm1lbnRTZWN0aW9uICYmIHNlbGVjdGVkRGF5Py5ldmVudHM/Lmxlbmd0aCA+IDBcIiBjbGFzcz1cImFwcG9pbnRtZW50cy1jb250YWluZXJcIj5cbiAgICAgICAgICA8aDQ+QXBwb2ludG1lbnRzPC9oND5cbiAgICAgICAgICA8ZGl2ICAqbmdGb3I9XCJsZXQgZXZlbnQgb2Ygc2VsZWN0ZWREYXk/LmV2ZW50c1wiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZXZlbnRcIiAqbmdGb3I9XCJsZXQgZW50cnlHcm91cCBvZiBldmVudC5lbnRyaWVzXCI+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJldmVudC1pbmZvXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQga2V5IG9mIGdldEVudHJ5S2V5cyhlbnRyeUdyb3VwKVwiIGNsYXNzPVwiZW50cnktcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiZW50cnlHcm91cFtrZXldLnF1ZXN0aW9uVGV4dFwiIGNsYXNzPVwiZW50cnktdGV4dFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7cmVtb3ZlQ2hhcmFjdGVycyhlbnRyeUdyb3VwW2tleV0ucXVlc3Rpb25UZXh0KX19OlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZW50cnktdmFsdWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tIFZEIDA5U2VwMjQtIGRhdGUgdHlwZSBhbmQgbGluayB0eXBlIHVwZGF0ZXMgICAgLS0+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJlbnRyeUdyb3VwW2tleV0udHlwZSAhPSAnVGltZScgJiYgZW50cnlHcm91cFtrZXldLnR5cGUgIT0gJ0xpbmsnJiYgZW50cnlHcm91cFtrZXldLnR5cGUgIT0gJ0RhdGUnXCI+e3sgZW50cnlHcm91cFtrZXldLmlucHV0IH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiZW50cnlHcm91cFtrZXldLnR5cGUgPT0gJ1RpbWUnXCI+e3sgZW50cnlHcm91cFtrZXldLmlucHV0IHwgZGF0ZTogJ3Nob3J0VGltZScgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJlbnRyeUdyb3VwW2tleV0udHlwZSA9PSAnRGF0ZSdcIj57eyBlbnRyeUdyb3VwW2tleV0uaW5wdXQgfCBkYXRlOiAnbWVkaXVtRGF0ZScgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJlbnRyeUdyb3VwW2tleV0udHlwZSA9PSAnTGluaydcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGEgW2hyZWZdPVwiJy8vJysgZW50cnlHcm91cFtrZXldLmlucHV0XCIgdGFyZ2V0PVwiX2JsYW5rXCI+e3tyZW1vdmVDaGFyYWN0ZXJzKGVudHJ5R3JvdXBba2V5XS5xdWVzdGlvblRleHQpfX08L2E+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJldmVudC1hY3Rpb25zXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIChjbGljayk9XCJlZGl0RXZlbnQoZXZlbnQsZW50cnlHcm91cClcIj5FZGl0PC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIChjbGljayk9XCJkZWxldGVFdmVudChldmVudC5pZCxlbnRyeUdyb3VwKVwiPkRlbGV0ZTwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2Rpdj5cblxuPCEtLSA8YXBwLWN1c3RvbS1tb2RlbFxuICBbbW9kYWxUaXRsZV09XCJtb2RhbFRpdGxlXCJcbiAgW2lzTW9kYWxPcGVuXT1cImlzTW9kYWxPcGVuXCJcbiAgW21vZGFsU2l6ZV09XCJtb2RhbFNpemVcIlxuICBbc2F2ZUJ1dHRvblZhbHVlXT1cInNhdmVCdXR0b25WYWx1ZVwiXG4gIFttb2RhbEZvb3Rlcl09XCJtb2RhbEZvb3RlclwiXG4gIChzYXZlQnV0dG9uRW1pdCk9XCJvblNhdmUoKVwiXG4gIChjYW5jZWxCdXR0b25FbWl0KT1cIm9uQ2FuY2VsKClcIlxuPlxuPGxpYi1xdWVzdGlvbmJvb2sgW3FiSXRlbV09XCJxYlJlZnJlbmNlQm9va1wiIFtxdWVzdGlvbnNdPVwicmVmZXJlbmNlUXVlc3Rpb25zXCIgKGhhbmRsZVF1ZXN0aW9uKT1cImhhbmRsZVF1ZXN0aW9uRXZlbnQoJGV2ZW50KVwiPjwvbGliLXF1ZXN0aW9uYm9vaz5cbjxuZy10ZW1wbGF0ZSBkeW5hbWljQ29tcG9uZW50SG9zdCA+PC9uZy10ZW1wbGF0ZT5cbjwvYXBwLWN1c3RvbS1tb2RlbD4gLS0+Il19
|
|
1
|
+
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
import * as i1 from "../../services/change.service";
|
|
4
|
+
import * as i2 from "@angular/common";
|
|
5
|
+
export class CustomCalendarComponent {
|
|
6
|
+
changeService;
|
|
7
|
+
eventSelected = new EventEmitter();
|
|
8
|
+
// VD 06Sep24 calendar changes
|
|
9
|
+
dateSelected = new EventEmitter();
|
|
10
|
+
openModal = new EventEmitter();
|
|
11
|
+
closeModal = new EventEmitter();
|
|
12
|
+
allEvents = [];
|
|
13
|
+
question;
|
|
14
|
+
nxtId;
|
|
15
|
+
//@ViewChild(ComponenthostDirective, { static: true }) dynamicHost: ComponenthostDirective;
|
|
16
|
+
entries = [];
|
|
17
|
+
referenceQuestions = [];
|
|
18
|
+
qbRefrenceBook;
|
|
19
|
+
calendarQuestion = [];
|
|
20
|
+
calendar = {};
|
|
21
|
+
currentDate = new Date();
|
|
22
|
+
calendarDays = [];
|
|
23
|
+
daysOfWeek = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
|
24
|
+
newEventTitle = '';
|
|
25
|
+
newEventTime = '';
|
|
26
|
+
newDescription = '';
|
|
27
|
+
newLink = '';
|
|
28
|
+
selectedDay = null;
|
|
29
|
+
isModalOpen = false;
|
|
30
|
+
modalTitle = 'Custom Modal';
|
|
31
|
+
modalSize = 'large';
|
|
32
|
+
saveButtonValue = 'Save';
|
|
33
|
+
modalFooter = true;
|
|
34
|
+
editingEventId;
|
|
35
|
+
editingEntryGroup;
|
|
36
|
+
showAppoinmentSection = true;
|
|
37
|
+
subscription;
|
|
38
|
+
constructor(changeService) {
|
|
39
|
+
this.changeService = changeService;
|
|
40
|
+
}
|
|
41
|
+
ngOnInit() {
|
|
42
|
+
if (this.question?.input) {
|
|
43
|
+
this.allEvents = this.question.input;
|
|
44
|
+
}
|
|
45
|
+
this.processQuestion();
|
|
46
|
+
this.generateCalendar();
|
|
47
|
+
this.subscription = this.changeService.customChange$.subscribe((changeValue) => {
|
|
48
|
+
if (changeValue == 'calendar-modal-save') {
|
|
49
|
+
this.onSave();
|
|
50
|
+
}
|
|
51
|
+
if (changeValue == 'dataBind') {
|
|
52
|
+
if (this.question?.input) {
|
|
53
|
+
this.allEvents = this.question.input;
|
|
54
|
+
}
|
|
55
|
+
this.processQuestion();
|
|
56
|
+
this.generateCalendar();
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
// this.dateSelected.emit(this.calendar);
|
|
60
|
+
//this.eventSelected.emit(this.allEvents);
|
|
61
|
+
}
|
|
62
|
+
// RS 09DEC24 Changed keys
|
|
63
|
+
processQuestion() {
|
|
64
|
+
this.entries = JSON.parse(this.question['fieldsMeta']);
|
|
65
|
+
this.qbRefrenceBook = JSON.parse(this.question['qbReferenceQuestions']);
|
|
66
|
+
let title = this.qbRefrenceBook?.questionbook?.title;
|
|
67
|
+
this.modalTitle = title;
|
|
68
|
+
this.referenceQuestions = [];
|
|
69
|
+
if (this.entries.length > 0) {
|
|
70
|
+
this.entries.forEach(element => {
|
|
71
|
+
if (element.questionReference) {
|
|
72
|
+
let qReference = JSON.parse(element.questionReference);
|
|
73
|
+
this.referenceQuestions.push(qReference?.question);
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
console.log('entries-->');
|
|
78
|
+
console.log('question-->');
|
|
79
|
+
console.log(this.entries);
|
|
80
|
+
console.log(this.referenceQuestions);
|
|
81
|
+
}
|
|
82
|
+
// sunday comment
|
|
83
|
+
// openQuestionBookModal() {
|
|
84
|
+
// const viewContainerRef = this.dynamicHost.viewContainerRef;
|
|
85
|
+
// viewContainerRef.clear();
|
|
86
|
+
// const componentRef = viewContainerRef.createComponent(QuestionbookComponent);
|
|
87
|
+
// componentRef.instance.qbItem = this.qbRefrenceBook;
|
|
88
|
+
// componentRef.instance.questions = this.referenceQuestions;
|
|
89
|
+
// componentRef.instance.handleQuestion.subscribe((event: any) => this.handleQuestionEvent(event));
|
|
90
|
+
// }
|
|
91
|
+
generateCalendar() {
|
|
92
|
+
const year = this.currentDate.getFullYear();
|
|
93
|
+
const month = this.currentDate.getMonth();
|
|
94
|
+
const startOfMonth = new Date(year, month, 1);
|
|
95
|
+
const endOfMonth = new Date(year, month + 1, 0);
|
|
96
|
+
const startDayOfWeek = startOfMonth.getDay();
|
|
97
|
+
const endDayOfWeek = endOfMonth.getDay();
|
|
98
|
+
const startDate = new Date(startOfMonth);
|
|
99
|
+
startDate.setDate(startDate.getDate() - startDayOfWeek);
|
|
100
|
+
const endDate = new Date(endOfMonth);
|
|
101
|
+
endDate.setDate(endDate.getDate() + (6 - endDayOfWeek));
|
|
102
|
+
const today = new Date(new Date().setHours(0, 0, 0, 0));
|
|
103
|
+
this.calendarDays = [];
|
|
104
|
+
for (let d = new Date(startDate); d <= endDate; d.setDate(d.getDate() + 1)) {
|
|
105
|
+
const date = new Date(d);
|
|
106
|
+
this.calendarDays.push({
|
|
107
|
+
date: date,
|
|
108
|
+
events: [],
|
|
109
|
+
isCurrentMonth: d.getMonth() === month,
|
|
110
|
+
isPast: date < today,
|
|
111
|
+
isToday: date.getTime() === today.getTime(),
|
|
112
|
+
isFuture: date > today,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
// Populate calendar with events from allEvents array
|
|
116
|
+
this.calendarDays.forEach(day => {
|
|
117
|
+
day.events = this.allEvents?.filter(event => event?.date?.toDateString() === day.date.toDateString());
|
|
118
|
+
});
|
|
119
|
+
// VD 06Sep24 calendar changes
|
|
120
|
+
let cal = {};
|
|
121
|
+
cal['year'] = year;
|
|
122
|
+
cal['month'] = month + 1;
|
|
123
|
+
this.calendar = cal;
|
|
124
|
+
}
|
|
125
|
+
selectDay(day) {
|
|
126
|
+
console.log(day);
|
|
127
|
+
// VD 06Sep24 calendar changes
|
|
128
|
+
this.showAppoinmentSection = true;
|
|
129
|
+
this.selectedDay = day;
|
|
130
|
+
// this.eventSelected.emit(day?.events);
|
|
131
|
+
const previouslySelectedDay = this.calendarDays.find(d => d.isSelected);
|
|
132
|
+
if (previouslySelectedDay) {
|
|
133
|
+
previouslySelectedDay.isSelected = false;
|
|
134
|
+
}
|
|
135
|
+
// Select the clicked day
|
|
136
|
+
day.isSelected = true;
|
|
137
|
+
// VD 09Sep24- setup the query param data for api call
|
|
138
|
+
let referenceData = [];
|
|
139
|
+
this.referenceQuestions.forEach(ques => {
|
|
140
|
+
// VD 09-09-24 get the selected date
|
|
141
|
+
// need to add in the document
|
|
142
|
+
// RS 09DEC24 Changed keys
|
|
143
|
+
if (ques.referenceField == 'selectedDate') {
|
|
144
|
+
ques.input = day.date.toISOString();
|
|
145
|
+
console.log(ques.input);
|
|
146
|
+
}
|
|
147
|
+
// VD 09-09-24 get the query refrence field data to pass the queryParam for api
|
|
148
|
+
if (ques.subText) {
|
|
149
|
+
let subText = JSON.parse(ques.subText);
|
|
150
|
+
if (subText.queryField && subText.queryValueReference) {
|
|
151
|
+
let currentQues = ques;
|
|
152
|
+
let queryReferences = subText.queryValueReference.split(',');
|
|
153
|
+
queryReferences.forEach(refField => {
|
|
154
|
+
let refQues = this.referenceQuestions.find(q => q.referenceField === refField);
|
|
155
|
+
if (refQues) {
|
|
156
|
+
referenceData.push(refQues);
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
// Add the referenceData array to the current question
|
|
160
|
+
currentQues.referenceQueryData = referenceData;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
previousMonth() {
|
|
166
|
+
this.showAppoinmentSection = false;
|
|
167
|
+
this.currentDate.setMonth(this.currentDate.getMonth() - 1);
|
|
168
|
+
this.currentDate = new Date(this.currentDate); // Ensure the date object is updated
|
|
169
|
+
this.generateCalendar();
|
|
170
|
+
this.dateSelected.emit(this.calendar);
|
|
171
|
+
this.eventSelected.emit(this.allEvents);
|
|
172
|
+
}
|
|
173
|
+
nextMonth() {
|
|
174
|
+
// VD 06Sep24 calendar changes
|
|
175
|
+
this.showAppoinmentSection = false;
|
|
176
|
+
this.currentDate.setMonth(this.currentDate.getMonth() + 1);
|
|
177
|
+
this.currentDate = new Date(this.currentDate); // Ensure the date object is updated
|
|
178
|
+
this.generateCalendar();
|
|
179
|
+
this.dateSelected.emit(this.calendar);
|
|
180
|
+
this.eventSelected.emit(this.allEvents);
|
|
181
|
+
}
|
|
182
|
+
addAppointment() {
|
|
183
|
+
this.isModalOpen = true;
|
|
184
|
+
this.calendarQuestion = this.referenceQuestions.map(q => ({ ...q, input: '' }));
|
|
185
|
+
this.referenceQuestions.forEach(ques => {
|
|
186
|
+
// clear the input
|
|
187
|
+
if (ques.referenceField != 'selectedDate') {
|
|
188
|
+
if (ques.type == 'Dropdown') {
|
|
189
|
+
delete ques.input;
|
|
190
|
+
delete ques.selectedValue;
|
|
191
|
+
// VD 06Sep24 calendar changes
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
delete ques.input;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
console.log(this.referenceQuestions);
|
|
199
|
+
this.editingEventId = null;
|
|
200
|
+
this.calendarQuestion = this.referenceQuestions;
|
|
201
|
+
this.openBookModel();
|
|
202
|
+
// sunday comment
|
|
203
|
+
//this.openQuestionBookModal();
|
|
204
|
+
}
|
|
205
|
+
openBookModel() {
|
|
206
|
+
this.openModal.emit({
|
|
207
|
+
qbRefrenceBook: this.qbRefrenceBook,
|
|
208
|
+
referenceQuestions: this.referenceQuestions,
|
|
209
|
+
modalTitle: this.modalTitle,
|
|
210
|
+
modalSize: this.modalSize,
|
|
211
|
+
saveButtonValue: this.saveButtonValue,
|
|
212
|
+
modalFooter: this.modalFooter,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
closeCalendarModal() {
|
|
216
|
+
this.isModalOpen = false;
|
|
217
|
+
this.closeModal.emit(true);
|
|
218
|
+
}
|
|
219
|
+
// VD 06Sep24 calendar changes
|
|
220
|
+
editEvent(event, entryGroup) {
|
|
221
|
+
this.isModalOpen = true;
|
|
222
|
+
this.referenceQuestions = Object.values(entryGroup);
|
|
223
|
+
this.calendarQuestion = [...this.referenceQuestions]; // Make a copy of the current entries to edit
|
|
224
|
+
this.editingEventId = event.id;
|
|
225
|
+
this.editingEntryGroup = entryGroup; // Store the entry group being edited
|
|
226
|
+
this.generateCalendar(); // Regenerate the calendar to reflect changes
|
|
227
|
+
this.openBookModel();
|
|
228
|
+
// suday comment
|
|
229
|
+
// this.openQuestionBookModal();
|
|
230
|
+
}
|
|
231
|
+
deleteEvent(eventId, entryGroup) {
|
|
232
|
+
let event = this.allEvents?.find(e => e?.id === eventId);
|
|
233
|
+
if (event) {
|
|
234
|
+
// Find the index of the entryGroup to delete
|
|
235
|
+
const entryIndex = event.entries.indexOf(entryGroup);
|
|
236
|
+
if (entryIndex > -1) {
|
|
237
|
+
event.entries.splice(entryIndex, 1); // Remove the specific entry
|
|
238
|
+
}
|
|
239
|
+
// If the event has no more entries, remove the event entirely
|
|
240
|
+
if (event.entries.length === 0) {
|
|
241
|
+
const eventIndex = this.allEvents?.indexOf(event);
|
|
242
|
+
if (eventIndex > -1) {
|
|
243
|
+
this.allEvents?.splice(eventIndex, 1); // Remove the entire event
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
let eventData = {};
|
|
248
|
+
eventData['action'] = "delete";
|
|
249
|
+
eventData['data'] = event;
|
|
250
|
+
this.eventSelected.emit(eventData);
|
|
251
|
+
this.generateCalendar(); // Regenerate the calendar to reflect the changes
|
|
252
|
+
}
|
|
253
|
+
// VD 06Sep24 calendar changes
|
|
254
|
+
addEvent(day, entryQues) {
|
|
255
|
+
// Transform new entries into the desired format
|
|
256
|
+
const newEntries = entryQues.reduce((acc, q) => {
|
|
257
|
+
acc[q.id] = { ...q };
|
|
258
|
+
return acc;
|
|
259
|
+
}, {});
|
|
260
|
+
// Find an existing event for the given date
|
|
261
|
+
const existingEvent = day.events?.find(event => event.date === day.date);
|
|
262
|
+
if (existingEvent) {
|
|
263
|
+
// Merge new entries into the existing event's entries array
|
|
264
|
+
// Check if the entries array already contains an object with the same id
|
|
265
|
+
const existingEntries = existingEvent.entries.map(entry => ({ ...entry }));
|
|
266
|
+
// Append new entries to the existing entries
|
|
267
|
+
existingEntries.push(newEntries);
|
|
268
|
+
existingEvent.entries = existingEntries;
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
// Create a new event if it doesn't exist for the given date
|
|
272
|
+
const newEvent = {
|
|
273
|
+
id: this.generateId(),
|
|
274
|
+
date: day.date,
|
|
275
|
+
entries: [newEntries] // Wrap the new entries in an array
|
|
276
|
+
};
|
|
277
|
+
day.events = day?.events || [];
|
|
278
|
+
day.events.push(newEvent);
|
|
279
|
+
this.allEvents?.push(newEvent);
|
|
280
|
+
//this.eventSelected.emit(this.allEvents);
|
|
281
|
+
let eventData = {};
|
|
282
|
+
eventData['action'] = "add";
|
|
283
|
+
eventData['data'] = newEvent;
|
|
284
|
+
this.eventSelected.emit(eventData);
|
|
285
|
+
}
|
|
286
|
+
this.generateCalendar();
|
|
287
|
+
console.log('allEvents', this.allEvents);
|
|
288
|
+
}
|
|
289
|
+
// VD 06Sep24 calendar changes
|
|
290
|
+
onSave() {
|
|
291
|
+
if (this.editingEventId !== null) {
|
|
292
|
+
const event = this.allEvents?.find(e => e?.id === this.editingEventId);
|
|
293
|
+
if (event && this.editingEntryGroup) {
|
|
294
|
+
// Update the specific entry group within the event
|
|
295
|
+
const entryIndex = event.entries.findIndex(entryGroup => entryGroup === this.editingEntryGroup);
|
|
296
|
+
if (entryIndex > -1) {
|
|
297
|
+
event.entries[entryIndex] = this.calendarQuestion.reduce((acc, q) => {
|
|
298
|
+
acc[q.id] = { ...q };
|
|
299
|
+
return acc;
|
|
300
|
+
}, {});
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
// this.eventSelected.emit(this.allEvents);
|
|
304
|
+
let eventData = {};
|
|
305
|
+
eventData['action'] = "edit";
|
|
306
|
+
eventData['data'] = event;
|
|
307
|
+
this.eventSelected.emit(eventData);
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
if (this.selectedDay) {
|
|
311
|
+
this.addEvent(this.selectedDay, this.calendarQuestion);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
this.closeCalendarModal();
|
|
315
|
+
this.generateCalendar();
|
|
316
|
+
}
|
|
317
|
+
// onCancel() {
|
|
318
|
+
// console.log('Cancel button clicked');
|
|
319
|
+
// this.closeCalendarModal();
|
|
320
|
+
// }
|
|
321
|
+
//this funtion need to be used
|
|
322
|
+
// handleQuestionEvent(ques){
|
|
323
|
+
// // Update the questions array with the new question
|
|
324
|
+
// const index = this.calendarQuestion.findIndex(q => q.id === ques.id);
|
|
325
|
+
// if (index > -1) {
|
|
326
|
+
// // If question already exists, update it
|
|
327
|
+
// this.calendarQuestion[index] = ques;
|
|
328
|
+
// } else {
|
|
329
|
+
// // If question doesn't exist, add it to the array
|
|
330
|
+
// this.calendarQuestion.push(ques);
|
|
331
|
+
// }
|
|
332
|
+
// console.log(this.calendarQuestion);
|
|
333
|
+
// }
|
|
334
|
+
// VD 06Sep24 calendar changes
|
|
335
|
+
generateId() {
|
|
336
|
+
return '_' + Math.random().toString(36).substr(2, 9);
|
|
337
|
+
}
|
|
338
|
+
getEntryKeys(entryGroup) {
|
|
339
|
+
return Object.keys(entryGroup);
|
|
340
|
+
}
|
|
341
|
+
removeCharacters(questionText) {
|
|
342
|
+
let updatedText = questionText?.replace(/<[^>]*>/g, '');
|
|
343
|
+
return updatedText;
|
|
344
|
+
}
|
|
345
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CustomCalendarComponent, deps: [{ token: i1.ChangeService }], target: i0.ɵɵFactoryTarget.Component });
|
|
346
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.3.0", type: CustomCalendarComponent, selector: "app-custom-calendar", inputs: { allEvents: "allEvents", question: "question", nxtId: "nxtId" }, outputs: { eventSelected: "eventSelected", dateSelected: "dateSelected", openModal: "openModal", closeModal: "closeModal" }, ngImport: i0, template: "<div class=\"align-calendar\">\r\n <div class=\"calendar-container\">\r\n <div class=\"calendar-header\">\r\n <button (click)=\"previousMonth()\"><< Previous >></button>\r\n <h3>{{ currentDate | date: 'MMMM yyyy' }}</h3>\r\n <button (click)=\"nextMonth()\"><< Next >></button>\r\n </div>\r\n <div class=\"calendar-grid\">\r\n <div class=\"day-of-week\" *ngFor=\"let day of daysOfWeek\">{{ day }}</div>\r\n <div\r\n class=\"calendar-day\"\r\n *ngFor=\"let day of calendarDays\"\r\n [class.not-current-month]=\"!day.isCurrentMonth\"\r\n [class.past]=\"day.isPast\"\r\n [class.today]=\"day.isToday\"\r\n [class.future]=\"day.isFuture\"\r\n [class.selected]=\"day.isSelected\"\r\n (click)=\"selectDay(day)\"\r\n >\r\n <div class=\"day-number\">{{ day.date.getDate() }}\r\n <span *ngIf=\"day?.events?.length > 0\" class=\"entry-indicator\" [class.select]=\"day?.isSelected\"></span>\r\n </div>\r\n <!-- <div *ngFor=\"let event of day.events\" >\r\n <div *ngFor=\"let entryGroup of event.entries\" class=\"event\">\r\n <div *ngFor=\"let key of getEntryKeys(entryGroup)\">\r\n <div *ngIf=\"entryGroup[key].type == 'Time'\">\r\n {{ entryGroup[key].input?.value | date: 'shortTime' }}\r\n </div>\r\n <div *ngIf=\"entryGroup[key].type != 'Time'\">\r\n {{ entryGroup[key].input }}\r\n </div>\r\n </div>\r\n </div>\r\n </div> -->\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"appoinappointment\">\r\n <div class=\"appointments-container\">\r\n <h4>Add Appointment</h4>\r\n <button *ngIf=\"selectedDay\" (click)=\"addAppointment()\">Add</button>\r\n </div>\r\n <!--VD 06Sep24 calendar updates--> \r\n <!-- RS 09DEC24 Changed keys--> \r\n <div *ngIf=\"showAppoinmentSection && selectedDay?.events?.length > 0\" class=\"appointments-container\">\r\n <h4>Appointments</h4>\r\n <div *ngFor=\"let event of selectedDay?.events\">\r\n <div class=\"event\" *ngFor=\"let entryGroup of event.entries\">\r\n <div class=\"event-info\">\r\n <div *ngFor=\"let key of getEntryKeys(entryGroup)\" class=\"entry-row\">\r\n <div *ngIf=\"entryGroup[key].questionText\" class=\"entry-text\">\r\n {{removeCharacters(entryGroup[key].questionText)}}:\r\n </div>\r\n <div class=\"entry-value\">\r\n <!-- VD 09Sep24- date type and link type updates -->\r\n <span *ngIf=\"entryGroup[key].type != 'Time' && entryGroup[key].type != 'Link'&& entryGroup[key].type != 'Date'\">{{ entryGroup[key].input }}</span>\r\n <span *ngIf=\"entryGroup[key].type == 'Time'\">{{ entryGroup[key].input | date: 'shortTime' }}</span>\r\n <span *ngIf=\"entryGroup[key].type == 'Date'\">{{ entryGroup[key].input | date: 'mediumDate' }}</span>\r\n <span *ngIf=\"entryGroup[key].type == 'Link'\">\r\n <a [href]=\"'//'+ entryGroup[key].input\" target=\"_blank\">{{removeCharacters(entryGroup[key].questionText)}}</a>\r\n </span>\r\n </div>\r\n </div>\r\n <div class=\"event-actions\">\r\n <button (click)=\"editEvent(event,entryGroup)\">Edit</button>\r\n <button (click)=\"deleteEvent(event.id,entryGroup)\">Delete</button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- <app-custom-model\r\n [modalTitle]=\"modalTitle\"\r\n [isModalOpen]=\"isModalOpen\"\r\n [modalSize]=\"modalSize\"\r\n [saveButtonValue]=\"saveButtonValue\"\r\n [modalFooter]=\"modalFooter\"\r\n (saveButtonEmit)=\"onSave()\"\r\n (cancelButtonEmit)=\"onCancel()\"\r\n>\r\n<lib-questionbook [qbItem]=\"qbRefrenceBook\" [questions]=\"referenceQuestions\" (handleQuestion)=\"handleQuestionEvent($event)\"></lib-questionbook>\r\n<ng-template dynamicComponentHost ></ng-template>\r\n</app-custom-model> -->", styles: [".calendar-container{flex:1}.appoinappointment{flex:1;margin-left:10px}.calendar-header{display:flex;justify-content:space-between;align-items:center}.selected{box-shadow:0 0 5px #00000080;background-color:green!important;color:#fff!important}.calendar-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:5px}.day-of-week{text-align:center;font-weight:700;padding:5px;background-color:#f0f0f0;border:1px solid #ccc}.calendar-day{border:1px solid #ccc;padding:5px;display:flex;flex-direction:column;align-items:flex-start;background-color:#fff;position:relative;cursor:pointer}.calendar-day.not-current-month{background-color:#f0f0f0}.calendar-day.past{color:#aaa}.calendar-day.today{background-color:#e6ffe6;font-weight:700}.calendar-day.future{color:#000}.day-number{font-size:1.2em;margin-bottom:5px}.event{background-color:#d1e7dd;border-left:4px solid #0f5132;margin:5px 0;padding:2px 5px;border-radius:3px}.event-title{font-weight:700}.event-time{font-size:.8em}input[type=text],input[type=time]{width:100%;margin-top:5px;box-sizing:border-box}button{margin-top:5px;align-self:stretch;margin-left:0!important}.calendar-header button{margin-top:5px;align-self:stretch;margin-left:0!important;border:none;background:none}.align-calendar{display:flex;width:100%}.form-group.content-box{padding-bottom:0!important}.entry-indicator{position:absolute;top:5px;right:5px;width:10px;height:10px;background-color:#0f5132;border-radius:50%}.select{background-color:#fff}.entry-row{display:flex;align-items:center;margin-bottom:5px}.entry-text{font-weight:700;margin-right:10px;white-space:nowrap}.entry-value{flex:1;word-break:break-word}.entry-value a{color:#4caf50}\n"], dependencies: [{ kind: "directive", type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i2.DatePipe, name: "date" }] });
|
|
347
|
+
}
|
|
348
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CustomCalendarComponent, decorators: [{
|
|
349
|
+
type: Component,
|
|
350
|
+
args: [{ selector: 'app-custom-calendar', template: "<div class=\"align-calendar\">\r\n <div class=\"calendar-container\">\r\n <div class=\"calendar-header\">\r\n <button (click)=\"previousMonth()\"><< Previous >></button>\r\n <h3>{{ currentDate | date: 'MMMM yyyy' }}</h3>\r\n <button (click)=\"nextMonth()\"><< Next >></button>\r\n </div>\r\n <div class=\"calendar-grid\">\r\n <div class=\"day-of-week\" *ngFor=\"let day of daysOfWeek\">{{ day }}</div>\r\n <div\r\n class=\"calendar-day\"\r\n *ngFor=\"let day of calendarDays\"\r\n [class.not-current-month]=\"!day.isCurrentMonth\"\r\n [class.past]=\"day.isPast\"\r\n [class.today]=\"day.isToday\"\r\n [class.future]=\"day.isFuture\"\r\n [class.selected]=\"day.isSelected\"\r\n (click)=\"selectDay(day)\"\r\n >\r\n <div class=\"day-number\">{{ day.date.getDate() }}\r\n <span *ngIf=\"day?.events?.length > 0\" class=\"entry-indicator\" [class.select]=\"day?.isSelected\"></span>\r\n </div>\r\n <!-- <div *ngFor=\"let event of day.events\" >\r\n <div *ngFor=\"let entryGroup of event.entries\" class=\"event\">\r\n <div *ngFor=\"let key of getEntryKeys(entryGroup)\">\r\n <div *ngIf=\"entryGroup[key].type == 'Time'\">\r\n {{ entryGroup[key].input?.value | date: 'shortTime' }}\r\n </div>\r\n <div *ngIf=\"entryGroup[key].type != 'Time'\">\r\n {{ entryGroup[key].input }}\r\n </div>\r\n </div>\r\n </div>\r\n </div> -->\r\n </div>\r\n </div>\r\n </div>\r\n <div class=\"appoinappointment\">\r\n <div class=\"appointments-container\">\r\n <h4>Add Appointment</h4>\r\n <button *ngIf=\"selectedDay\" (click)=\"addAppointment()\">Add</button>\r\n </div>\r\n <!--VD 06Sep24 calendar updates--> \r\n <!-- RS 09DEC24 Changed keys--> \r\n <div *ngIf=\"showAppoinmentSection && selectedDay?.events?.length > 0\" class=\"appointments-container\">\r\n <h4>Appointments</h4>\r\n <div *ngFor=\"let event of selectedDay?.events\">\r\n <div class=\"event\" *ngFor=\"let entryGroup of event.entries\">\r\n <div class=\"event-info\">\r\n <div *ngFor=\"let key of getEntryKeys(entryGroup)\" class=\"entry-row\">\r\n <div *ngIf=\"entryGroup[key].questionText\" class=\"entry-text\">\r\n {{removeCharacters(entryGroup[key].questionText)}}:\r\n </div>\r\n <div class=\"entry-value\">\r\n <!-- VD 09Sep24- date type and link type updates -->\r\n <span *ngIf=\"entryGroup[key].type != 'Time' && entryGroup[key].type != 'Link'&& entryGroup[key].type != 'Date'\">{{ entryGroup[key].input }}</span>\r\n <span *ngIf=\"entryGroup[key].type == 'Time'\">{{ entryGroup[key].input | date: 'shortTime' }}</span>\r\n <span *ngIf=\"entryGroup[key].type == 'Date'\">{{ entryGroup[key].input | date: 'mediumDate' }}</span>\r\n <span *ngIf=\"entryGroup[key].type == 'Link'\">\r\n <a [href]=\"'//'+ entryGroup[key].input\" target=\"_blank\">{{removeCharacters(entryGroup[key].questionText)}}</a>\r\n </span>\r\n </div>\r\n </div>\r\n <div class=\"event-actions\">\r\n <button (click)=\"editEvent(event,entryGroup)\">Edit</button>\r\n <button (click)=\"deleteEvent(event.id,entryGroup)\">Delete</button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- <app-custom-model\r\n [modalTitle]=\"modalTitle\"\r\n [isModalOpen]=\"isModalOpen\"\r\n [modalSize]=\"modalSize\"\r\n [saveButtonValue]=\"saveButtonValue\"\r\n [modalFooter]=\"modalFooter\"\r\n (saveButtonEmit)=\"onSave()\"\r\n (cancelButtonEmit)=\"onCancel()\"\r\n>\r\n<lib-questionbook [qbItem]=\"qbRefrenceBook\" [questions]=\"referenceQuestions\" (handleQuestion)=\"handleQuestionEvent($event)\"></lib-questionbook>\r\n<ng-template dynamicComponentHost ></ng-template>\r\n</app-custom-model> -->", styles: [".calendar-container{flex:1}.appoinappointment{flex:1;margin-left:10px}.calendar-header{display:flex;justify-content:space-between;align-items:center}.selected{box-shadow:0 0 5px #00000080;background-color:green!important;color:#fff!important}.calendar-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:5px}.day-of-week{text-align:center;font-weight:700;padding:5px;background-color:#f0f0f0;border:1px solid #ccc}.calendar-day{border:1px solid #ccc;padding:5px;display:flex;flex-direction:column;align-items:flex-start;background-color:#fff;position:relative;cursor:pointer}.calendar-day.not-current-month{background-color:#f0f0f0}.calendar-day.past{color:#aaa}.calendar-day.today{background-color:#e6ffe6;font-weight:700}.calendar-day.future{color:#000}.day-number{font-size:1.2em;margin-bottom:5px}.event{background-color:#d1e7dd;border-left:4px solid #0f5132;margin:5px 0;padding:2px 5px;border-radius:3px}.event-title{font-weight:700}.event-time{font-size:.8em}input[type=text],input[type=time]{width:100%;margin-top:5px;box-sizing:border-box}button{margin-top:5px;align-self:stretch;margin-left:0!important}.calendar-header button{margin-top:5px;align-self:stretch;margin-left:0!important;border:none;background:none}.align-calendar{display:flex;width:100%}.form-group.content-box{padding-bottom:0!important}.entry-indicator{position:absolute;top:5px;right:5px;width:10px;height:10px;background-color:#0f5132;border-radius:50%}.select{background-color:#fff}.entry-row{display:flex;align-items:center;margin-bottom:5px}.entry-text{font-weight:700;margin-right:10px;white-space:nowrap}.entry-value{flex:1;word-break:break-word}.entry-value a{color:#4caf50}\n"] }]
|
|
351
|
+
}], ctorParameters: function () { return [{ type: i1.ChangeService }]; }, propDecorators: { eventSelected: [{
|
|
352
|
+
type: Output
|
|
353
|
+
}], dateSelected: [{
|
|
354
|
+
type: Output
|
|
355
|
+
}], openModal: [{
|
|
356
|
+
type: Output
|
|
357
|
+
}], closeModal: [{
|
|
358
|
+
type: Output
|
|
359
|
+
}], allEvents: [{
|
|
360
|
+
type: Input
|
|
361
|
+
}], question: [{
|
|
362
|
+
type: Input
|
|
363
|
+
}], nxtId: [{
|
|
364
|
+
type: Input
|
|
365
|
+
}] } });
|
|
366
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9tLWNhbGVuZGFyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL254dC1hcHAvc3JjL2xpYi9jb21wb25lbnRzL2N1c3RvbS1jYWxlbmRhci9jdXN0b20tY2FsZW5kYXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbnh0LWFwcC9zcmMvbGliL2NvbXBvbmVudHMvY3VzdG9tLWNhbGVuZGFyL2N1c3RvbS1jYWxlbmRhci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFjLFlBQVksRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUE0QixNQUFNLGVBQWUsQ0FBQzs7OztBQW1CckgsTUFBTSxPQUFPLHVCQUF1QjtJQWdDYjtJQS9CWCxhQUFhLEdBQUcsSUFBSSxZQUFZLEVBQU8sQ0FBQztJQUNsRCw4QkFBOEI7SUFDcEIsWUFBWSxHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7SUFDdkMsU0FBUyxHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7SUFDcEMsVUFBVSxHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7SUFDdEMsU0FBUyxHQUFVLEVBQUUsQ0FBQztJQUN0QixRQUFRLENBQVU7SUFDbEIsS0FBSyxDQUFTO0lBQ3ZCLDJGQUEyRjtJQUMzRixPQUFPLEdBQUcsRUFBRSxDQUFDO0lBQ2Isa0JBQWtCLEdBQUcsRUFBRSxDQUFDO0lBQ3hCLGNBQWMsQ0FBSztJQUNuQixnQkFBZ0IsR0FBRyxFQUFFLENBQUM7SUFDdEIsUUFBUSxHQUFHLEVBQUUsQ0FBQztJQUNkLFdBQVcsR0FBUyxJQUFJLElBQUksRUFBRSxDQUFDO0lBQy9CLFlBQVksR0FBa0IsRUFBRSxDQUFDO0lBQ2pDLFVBQVUsR0FBYSxDQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQ3RHLGFBQWEsR0FBVyxFQUFFLENBQUM7SUFDM0IsWUFBWSxHQUFXLEVBQUUsQ0FBQztJQUMxQixjQUFjLEdBQVcsRUFBRSxDQUFDO0lBQzVCLE9BQU8sR0FBVyxFQUFFLENBQUM7SUFDckIsV0FBVyxHQUF1QixJQUFJLENBQUM7SUFDdkMsV0FBVyxHQUFHLEtBQUssQ0FBQztJQUNwQixVQUFVLEdBQUcsY0FBYyxDQUFDO0lBQzVCLFNBQVMsR0FBRyxPQUFPLENBQUM7SUFDcEIsZUFBZSxHQUFHLE1BQU0sQ0FBQztJQUN6QixXQUFXLEdBQUcsSUFBSSxDQUFDO0lBQ25CLGNBQWMsQ0FBUztJQUN2QixpQkFBaUIsQ0FBTTtJQUN2QixxQkFBcUIsR0FBWSxJQUFJLENBQUM7SUFDdEMsWUFBWSxDQUFNO0lBQ2xCLFlBQXFCLGFBQTRCO1FBQTVCLGtCQUFhLEdBQWIsYUFBYSxDQUFlO0lBQUksQ0FBQztJQUN0RCxRQUFRO1FBQ0wsSUFBRyxJQUFJLENBQUMsUUFBUSxFQUFFLEtBQUssRUFBQztZQUN2QixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDO1NBQ3JDO1FBQ0YsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUM1RCxDQUFDLFdBQVcsRUFBRSxFQUFFO1lBQ1osSUFBRyxXQUFXLElBQUkscUJBQXFCLEVBQUU7Z0JBQ3ZDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQzthQUNmO1lBQ0QsSUFBRyxXQUFXLElBQUksVUFBVSxFQUFFO2dCQUM1QixJQUFHLElBQUksQ0FBQyxRQUFRLEVBQUUsS0FBSyxFQUFDO29CQUN0QixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDO2lCQUNyQztnQkFDRixJQUFJLENBQUMsZUFBZSxFQUFFLENBQUM7Z0JBQ3ZCLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO2FBQ3pCO1FBQ0wsQ0FBQyxDQUNGLENBQUM7UUFDSCx5Q0FBeUM7UUFDeEMsMENBQTBDO0lBQzVDLENBQUM7SUFDRCwwQkFBMEI7SUFDMUIsZUFBZTtRQUNiLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7UUFDdkQsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDO1FBQ3hFLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxjQUFjLEVBQUUsWUFBWSxFQUFFLEtBQUssQ0FBQztRQUNyRCxJQUFJLENBQUMsVUFBVSxHQUFHLEtBQUssQ0FBQztRQUN4QixJQUFJLENBQUMsa0JBQWtCLEdBQUcsRUFBRSxDQUFDO1FBQzdCLElBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFDO1lBQ3hCLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFFO2dCQUMzQixJQUFHLE9BQU8sQ0FBQyxpQkFBaUIsRUFBQztvQkFDM0IsSUFBSSxVQUFVLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsaUJBQWlCLENBQUMsQ0FBQztvQkFDdkQsSUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsUUFBUSxDQUFDLENBQUM7aUJBQ3BEO1lBQ0wsQ0FBQyxDQUFDLENBQUM7U0FDTDtRQUNELE9BQU8sQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDMUIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUMzQixPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMxQixPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFDQSxpQkFBaUI7SUFDbEIsNEJBQTRCO0lBQzVCLGdFQUFnRTtJQUNoRSw4QkFBOEI7SUFDOUIsa0ZBQWtGO0lBQ2xGLHdEQUF3RDtJQUN4RCwrREFBK0Q7SUFDL0QscUdBQXFHO0lBQ3JHLElBQUk7SUFFSixnQkFBZ0I7UUFDZCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQzVDLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxFQUFFLENBQUM7UUFFMUMsTUFBTSxZQUFZLEdBQUcsSUFBSSxJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM5QyxNQUFNLFVBQVUsR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsS0FBSyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUVoRCxNQUFNLGNBQWMsR0FBRyxZQUFZLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDN0MsTUFBTSxZQUFZLEdBQUcsVUFBVSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBRXpDLE1BQU0sU0FBUyxHQUFHLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQ3pDLFNBQVMsQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLE9BQU8sRUFBRSxHQUFHLGNBQWMsQ0FBQyxDQUFDO1FBRXhELE1BQU0sT0FBTyxHQUFHLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3JDLE9BQU8sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsQ0FBQyxHQUFHLFlBQVksQ0FBQyxDQUFDLENBQUM7UUFFeEQsTUFBTSxLQUFLLEdBQUcsSUFBSSxJQUFJLENBQUMsSUFBSSxJQUFJLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUV2RCxJQUFJLENBQUMsWUFBWSxHQUFHLEVBQUUsQ0FBQztRQUN0QixLQUFLLElBQUksQ0FBQyxHQUFHLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsSUFBSSxPQUFPLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEVBQUU7WUFDMUUsTUFBTSxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDekIsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUM7Z0JBQ3JCLElBQUksRUFBRSxJQUFJO2dCQUNWLE1BQU0sRUFBRSxFQUFFO2dCQUNWLGNBQWMsRUFBRSxDQUFDLENBQUMsUUFBUSxFQUFFLEtBQUssS0FBSztnQkFDdEMsTUFBTSxFQUFFLElBQUksR0FBRyxLQUFLO2dCQUNwQixPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxLQUFLLEtBQUssQ0FBQyxPQUFPLEVBQUU7Z0JBQzNDLFFBQVEsRUFBRSxJQUFJLEdBQUcsS0FBSzthQUN2QixDQUFDLENBQUM7U0FDSjtRQUVILHFEQUFxRDtRQUNyRCxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRTtZQUM5QixHQUFHLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxTQUFTLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsS0FBSyxHQUFHLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUM7UUFDeEcsQ0FBQyxDQUFDLENBQUM7UUFDRiw4QkFBOEI7UUFDL0IsSUFBSSxHQUFHLEdBQUcsRUFBRSxDQUFBO1FBQ1osR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQztRQUNuQixHQUFHLENBQUMsT0FBTyxDQUFDLEdBQUcsS0FBSyxHQUFHLENBQUMsQ0FBQztRQUN6QixJQUFJLENBQUMsUUFBUSxHQUFHLEdBQUcsQ0FBQztJQUN0QixDQUFDO0lBRUQsU0FBUyxDQUFDLEdBQWdCO1FBQ3hCLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDaEIsOEJBQThCO1FBQy9CLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLENBQUM7UUFDbEMsSUFBSSxDQUFDLFdBQVcsR0FBRyxHQUFHLENBQUM7UUFDeEIsd0NBQXdDO1FBQ3ZDLE1BQU0scUJBQXFCLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDeEUsSUFBSSxxQkFBcUIsRUFBRTtZQUN6QixxQkFBcUIsQ0FBQyxVQUFVLEdBQUcsS0FBSyxDQUFDO1NBQzFDO1FBQ0QseUJBQXlCO1FBQ3pCLEdBQUcsQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO1FBQ3ZCLHNEQUFzRDtRQUNyRCxJQUFJLGFBQWEsR0FBRyxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUNyQyxvQ0FBb0M7WUFDcEMsOEJBQThCO1lBQzlCLDBCQUEwQjtZQUN6QixJQUFHLElBQUksQ0FBQyxjQUFjLElBQUksY0FBYyxFQUFDO2dCQUN0QyxJQUFJLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7Z0JBQ3BDLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO2FBQzFCO1lBQ0QsaUZBQWlGO1lBQ2pGLElBQUcsSUFBSSxDQUFDLE9BQU8sRUFBQztnQkFDZixJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDdkMsSUFBSSxPQUFPLENBQUMsVUFBVSxJQUFJLE9BQU8sQ0FBQyxtQkFBbUIsRUFBRTtvQkFDbkQsSUFBSSxXQUFXLEdBQUcsSUFBSSxDQUFDO29CQUN2QixJQUFJLGVBQWUsR0FBRyxPQUFPLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUM3RCxlQUFlLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxFQUFFO3dCQUMvQixJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLGNBQWMsS0FBSyxRQUFRLENBQUMsQ0FBQzt3QkFDL0UsSUFBSSxPQUFPLEVBQUU7NEJBQ1QsYUFBYSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQzt5QkFDL0I7b0JBQ0wsQ0FBQyxDQUFDLENBQUM7b0JBQ0gsc0RBQXNEO29CQUN0RCxXQUFXLENBQUMsa0JBQWtCLEdBQUcsYUFBYSxDQUFDO2lCQUNsRDthQUNEO1FBQ0osQ0FBQyxDQUFDLENBQUE7SUFDSixDQUFDO0lBRUQsYUFBYTtRQUNYLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxLQUFLLENBQUM7UUFDbkMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUMzRCxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLG9DQUFvQztRQUNuRixJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDdEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFRCxTQUFTO1FBQ04sOEJBQThCO1FBQy9CLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxLQUFLLENBQUM7UUFDbkMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUMzRCxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLG9DQUFvQztRQUNuRixJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDdEMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQzFDLENBQUM7SUFFRCxjQUFjO1FBQ1osSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUM7UUFDdkIsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNqRixJQUFJLENBQUMsa0JBQWtCLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQ3JDLGtCQUFrQjtZQUNsQixJQUFHLElBQUksQ0FBQyxjQUFjLElBQUksY0FBYyxFQUFDO2dCQUN2QyxJQUFHLElBQUksQ0FBQyxJQUFJLElBQUksVUFBVSxFQUFDO29CQUN6QixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7b0JBQ2xCLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQztvQkFDekIsOEJBQThCO2lCQUNoQztxQkFBSztvQkFDSixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUM7aUJBQ25CO2FBQ0Y7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUNILE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFDckMsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7UUFDM0IsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQztRQUNoRCxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDckIsaUJBQWlCO1FBQ2pCLCtCQUErQjtJQUNqQyxDQUFDO0lBRUQsYUFBYTtRQUNYLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDO1lBQ2xCLGNBQWMsRUFBRSxJQUFJLENBQUMsY0FBYztZQUNuQyxrQkFBa0IsRUFBRSxJQUFJLENBQUMsa0JBQWtCO1lBQzNDLFVBQVUsRUFBRyxJQUFJLENBQUMsVUFBVTtZQUM1QixTQUFTLEVBQUcsSUFBSSxDQUFDLFNBQVM7WUFDMUIsZUFBZSxFQUFHLElBQUksQ0FBQyxlQUFlO1lBQ3RDLFdBQVcsRUFBRyxJQUFJLENBQUMsV0FBVztTQUUvQixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsa0JBQWtCO1FBQ2hCLElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDO1FBQ3pCLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzdCLENBQUM7SUFDRiw4QkFBOEI7SUFFL0IsU0FBUyxDQUFDLEtBQVUsRUFBRSxVQUFlO1FBQ25DLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3BELElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLENBQUMsQ0FBQyw2Q0FBNkM7UUFDbkcsSUFBSSxDQUFDLGNBQWMsR0FBRyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQy9CLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxVQUFVLENBQUMsQ0FBQyxxQ0FBcUM7UUFDMUUsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUMsQ0FBQyw2Q0FBNkM7UUFDdEUsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ3JCLGdCQUFnQjtRQUNqQixnQ0FBZ0M7SUFFakMsQ0FBQztJQUVELFdBQVcsQ0FBRSxPQUFlLEVBQUUsVUFBZTtRQUMzQyxJQUFJLEtBQUssR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLEtBQUssT0FBTyxDQUFDLENBQUM7UUFDekQsSUFBSSxLQUFLLEVBQUU7WUFDUCw2Q0FBNkM7WUFDN0MsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDckQsSUFBSSxVQUFVLEdBQUcsQ0FBQyxDQUFDLEVBQUU7Z0JBQ2pCLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLDRCQUE0QjthQUNwRTtZQUVELDhEQUE4RDtZQUM5RCxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtnQkFDNUIsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ2xELElBQUksVUFBVSxHQUFHLENBQUMsQ0FBQyxFQUFFO29CQUNqQixJQUFJLENBQUMsU0FBUyxFQUFFLE1BQU0sQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQywwQkFBMEI7aUJBQ3BFO2FBQ0o7U0FDSjtRQUNELElBQUksU0FBUyxHQUFHLEVBQUUsQ0FBQztRQUNsQixTQUFTLENBQUMsUUFBUSxDQUFDLEdBQUcsUUFBUSxDQUFDO1FBQy9CLFNBQVMsQ0FBQyxNQUFNLENBQUMsR0FBRyxLQUFLLENBQUM7UUFDM0IsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDbkMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUMsQ0FBQyxpREFBaUQ7SUFDNUUsQ0FBQztJQUVBLDhCQUE4QjtJQUM3QixRQUFRLENBQUMsR0FBZ0IsRUFBRSxTQUFTO1FBQ2xDLGdEQUFnRDtRQUNoRCxNQUFNLFVBQVUsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQzNDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3JCLE9BQU8sR0FBRyxDQUFDO1FBQ2YsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRVAsNENBQTRDO1FBQzVDLE1BQU0sYUFBYSxHQUFHLEdBQUcsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFekUsSUFBSSxhQUFhLEVBQUU7WUFDZiw0REFBNEQ7WUFDNUQseUVBQXlFO1lBQ3pFLE1BQU0sZUFBZSxHQUFHLGFBQWEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLEdBQUcsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzNFLDZDQUE2QztZQUM3QyxlQUFlLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ2pDLGFBQWEsQ0FBQyxPQUFPLEdBQUcsZUFBZSxDQUFDO1NBQzNDO2FBQU07WUFDSCw0REFBNEQ7WUFDNUQsTUFBTSxRQUFRLEdBQUc7Z0JBQ2IsRUFBRSxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUU7Z0JBQ3JCLElBQUksRUFBRSxHQUFHLENBQUMsSUFBSTtnQkFDZCxPQUFPLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxtQ0FBbUM7YUFDNUQsQ0FBQztZQUNGLEdBQUcsQ0FBQyxNQUFNLEdBQUcsR0FBRyxFQUFFLE1BQU0sSUFBSSxFQUFFLENBQUE7WUFDOUIsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDMUIsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDL0IsMENBQTBDO1lBQzFDLElBQUksU0FBUyxHQUFHLEVBQUUsQ0FBQztZQUNuQixTQUFTLENBQUMsUUFBUSxDQUFDLEdBQUcsS0FBSyxDQUFDO1lBQzVCLFNBQVMsQ0FBQyxNQUFNLENBQUMsR0FBRyxRQUFRLENBQUM7WUFDN0IsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7U0FDdEM7UUFDRCxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUN4QixPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDN0MsQ0FBQztJQUNBLDhCQUE4QjtJQUM5QixNQUFNO1FBQ0gsSUFBSSxJQUFJLENBQUMsY0FBYyxLQUFLLElBQUksRUFBRTtZQUM5QixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLEtBQUssSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDO1lBQ3ZFLElBQUksS0FBSyxJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRTtnQkFDakMsbURBQW1EO2dCQUNuRCxNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLFVBQVUsS0FBSyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztnQkFDaEcsSUFBSSxVQUFVLEdBQUcsQ0FBQyxDQUFDLEVBQUU7b0JBQ2pCLEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsRUFBRTt3QkFDaEUsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUM7d0JBQ3JCLE9BQU8sR0FBRyxDQUFDO29CQUNmLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztpQkFDVjthQUNKO1lBQ0osMkNBQTJDO1lBQzFDLElBQUksU0FBUyxHQUFHLEVBQUUsQ0FBQztZQUNuQixTQUFTLENBQUMsUUFBUSxDQUFDLEdBQUcsTUFBTSxDQUFDO1lBQzdCLFNBQVMsQ0FBQyxNQUFNLENBQUMsR0FBRyxLQUFLLENBQUM7WUFDMUIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7U0FDcEM7YUFBTTtZQUNILElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRTtnQkFDbEIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO2FBQzFEO1NBQ0o7UUFDRCxJQUFJLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUMxQixJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztJQUM1QixDQUFDO0lBRUMsZUFBZTtJQUNmLDBDQUEwQztJQUMxQywrQkFBK0I7SUFDL0IsSUFBSTtJQUNKLDhCQUE4QjtJQUM5Qiw2QkFBNkI7SUFDN0IsMERBQTBEO0lBQzFELDRFQUE0RTtJQUM1RSx3QkFBd0I7SUFDeEIsaURBQWlEO0lBQ2pELDZDQUE2QztJQUM3QyxlQUFlO0lBQ2YsMERBQTBEO0lBQzFELDBDQUEwQztJQUMxQyxRQUFRO0lBQ1IsMENBQTBDO0lBQzFDLE1BQU07SUFFUCw4QkFBOEI7SUFDN0IsVUFBVTtRQUNSLE9BQU8sR0FBRyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUN2RCxDQUFDO0lBRUQsWUFBWSxDQUFDLFVBQWU7UUFDMUIsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ25DLENBQUM7SUFFRCxnQkFBZ0IsQ0FBQyxZQUFtQjtRQUNsQyxJQUFJLFdBQVcsR0FBRyxZQUFZLEVBQUUsT0FBTyxDQUFDLFVBQVUsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUN4RCxPQUFPLFdBQVcsQ0FBQztJQUNyQixDQUFDO3VHQXpXWSx1QkFBdUI7MkZBQXZCLHVCQUF1QixrUUNuQnBDLHdoSkFxRnVCOzsyRkRsRVYsdUJBQXVCO2tCQUxuQyxTQUFTOytCQUNFLHFCQUFxQjtvR0FLckIsYUFBYTtzQkFBdEIsTUFBTTtnQkFFRyxZQUFZO3NCQUFyQixNQUFNO2dCQUNHLFNBQVM7c0JBQWxCLE1BQU07Z0JBQ0csVUFBVTtzQkFBbkIsTUFBTTtnQkFDRSxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csS0FBSztzQkFBYixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkluaXQsIE91dHB1dCwgU2ltcGxlQ2hhbmdlcywgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IFF1ZXN0aW9uIH0gZnJvbSAnLi4vLi4vd3JhcHBlcic7XHJcbi8vaW1wb3J0IHsgUXVlc3Rpb25ib29rQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vcGFnZXMvcXVlc3Rpb25ib29rL3F1ZXN0aW9uYm9vay5jb21wb25lbnQnO1xyXG4vL2ltcG9ydCB7IENvbXBvbmVudGhvc3REaXJlY3RpdmUgfSBmcm9tICcuLi8uLi9kaXJlY3RpdmVzL2NvbXBvbmVudGhvc3QvY29tcG9uZW50aG9zdC5kaXJlY3RpdmUnO1xyXG5pbXBvcnQgeyBDaGFuZ2VTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvY2hhbmdlLnNlcnZpY2UnO1xyXG5pbnRlcmZhY2UgQ2FsZW5kYXJEYXkge1xyXG4gIGRhdGU6IERhdGU7XHJcbiAgZXZlbnRzOiBhbnlbXTtcclxuICBpc0N1cnJlbnRNb250aDogYm9vbGVhbjtcclxuICBpc1Bhc3Q6IGJvb2xlYW47XHJcbiAgaXNUb2RheTogYm9vbGVhbjtcclxuICBpc0Z1dHVyZTogYm9vbGVhbjtcclxuICBpc1NlbGVjdGVkPzogYm9vbGVhbjtcclxufVxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2FwcC1jdXN0b20tY2FsZW5kYXInLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9jdXN0b20tY2FsZW5kYXIuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsczogWycuL2N1c3RvbS1jYWxlbmRhci5jb21wb25lbnQuY3NzJ10sXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBDdXN0b21DYWxlbmRhckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcbiAgQE91dHB1dCgpIGV2ZW50U2VsZWN0ZWQgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuICAvLyBWRCAwNlNlcDI0IGNhbGVuZGFyIGNoYW5nZXNcclxuICBAT3V0cHV0KCkgZGF0ZVNlbGVjdGVkID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XHJcbiAgQE91dHB1dCgpIG9wZW5Nb2RhbCA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xyXG4gIEBPdXRwdXQoKSBjbG9zZU1vZGFsID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XHJcbiAgQElucHV0KCkgYWxsRXZlbnRzOiBhbnlbXSA9IFtdOyBcclxuICBASW5wdXQoKSBxdWVzdGlvbjogUXVlc3Rpb25cclxuICBASW5wdXQoKSBueHRJZDogc3RyaW5nO1xyXG4gIC8vQFZpZXdDaGlsZChDb21wb25lbnRob3N0RGlyZWN0aXZlLCB7IHN0YXRpYzogdHJ1ZSB9KSBkeW5hbWljSG9zdDogQ29tcG9uZW50aG9zdERpcmVjdGl2ZTtcclxuICBlbnRyaWVzID0gW107XHJcbiAgcmVmZXJlbmNlUXVlc3Rpb25zID0gW107XHJcbiAgcWJSZWZyZW5jZUJvb2s6YW55O1xyXG4gIGNhbGVuZGFyUXVlc3Rpb24gPSBbXTtcclxuICBjYWxlbmRhciA9IHt9O1xyXG4gIGN1cnJlbnREYXRlOiBEYXRlID0gbmV3IERhdGUoKTtcclxuICBjYWxlbmRhckRheXM6IENhbGVuZGFyRGF5W10gPSBbXTtcclxuICBkYXlzT2ZXZWVrOiBzdHJpbmdbXSA9IFsnU3VuZGF5JywgJ01vbmRheScsICdUdWVzZGF5JywgJ1dlZG5lc2RheScsICdUaHVyc2RheScsICdGcmlkYXknLCAnU2F0dXJkYXknXTtcclxuICBuZXdFdmVudFRpdGxlOiBzdHJpbmcgPSAnJztcclxuICBuZXdFdmVudFRpbWU6IHN0cmluZyA9ICcnO1xyXG4gIG5ld0Rlc2NyaXB0aW9uOiBzdHJpbmcgPSAnJztcclxuICBuZXdMaW5rOiBzdHJpbmcgPSAnJztcclxuICBzZWxlY3RlZERheTogQ2FsZW5kYXJEYXkgfCBudWxsID0gbnVsbDtcclxuICBpc01vZGFsT3BlbiA9IGZhbHNlO1xyXG4gIG1vZGFsVGl0bGUgPSAnQ3VzdG9tIE1vZGFsJztcclxuICBtb2RhbFNpemUgPSAnbGFyZ2UnO1xyXG4gIHNhdmVCdXR0b25WYWx1ZSA9ICdTYXZlJztcclxuICBtb2RhbEZvb3RlciA9IHRydWU7XHJcbiAgZWRpdGluZ0V2ZW50SWQ6IG51bWJlcjtcclxuICBlZGl0aW5nRW50cnlHcm91cDogYW55O1xyXG4gIHNob3dBcHBvaW5tZW50U2VjdGlvbjogYm9vbGVhbiA9IHRydWU7XHJcbiAgc3Vic2NyaXB0aW9uOiBhbnk7XHJcbiAgY29uc3RydWN0b3IoIHByaXZhdGUgY2hhbmdlU2VydmljZTogQ2hhbmdlU2VydmljZSkgeyB9XHJcbiAgbmdPbkluaXQoKSB7XHJcbiAgICAgaWYodGhpcy5xdWVzdGlvbj8uaW5wdXQpe1xyXG4gICAgICB0aGlzLmFsbEV2ZW50cyA9IHRoaXMucXVlc3Rpb24uaW5wdXQ7XHJcbiAgICAgfVxyXG4gICAgdGhpcy5wcm9jZXNzUXVlc3Rpb24oKTtcclxuICAgIHRoaXMuZ2VuZXJhdGVDYWxlbmRhcigpO1xyXG4gICAgdGhpcy5zdWJzY3JpcHRpb24gPSB0aGlzLmNoYW5nZVNlcnZpY2UuY3VzdG9tQ2hhbmdlJC5zdWJzY3JpYmUoXHJcbiAgICAgIChjaGFuZ2VWYWx1ZSkgPT4ge1xyXG4gICAgICAgICAgaWYoY2hhbmdlVmFsdWUgPT0gJ2NhbGVuZGFyLW1vZGFsLXNhdmUnKSB7XHJcbiAgICAgICAgICAgIHRoaXMub25TYXZlKCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBpZihjaGFuZ2VWYWx1ZSA9PSAnZGF0YUJpbmQnKSB7XHJcbiAgICAgICAgICAgIGlmKHRoaXMucXVlc3Rpb24/LmlucHV0KXtcclxuICAgICAgICAgICAgICB0aGlzLmFsbEV2ZW50cyA9IHRoaXMucXVlc3Rpb24uaW5wdXQ7XHJcbiAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMucHJvY2Vzc1F1ZXN0aW9uKCk7XHJcbiAgICAgICAgICAgIHRoaXMuZ2VuZXJhdGVDYWxlbmRhcigpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICApO1xyXG4gICAvLyB0aGlzLmRhdGVTZWxlY3RlZC5lbWl0KHRoaXMuY2FsZW5kYXIpO1xyXG4gICAgLy90aGlzLmV2ZW50U2VsZWN0ZWQuZW1pdCh0aGlzLmFsbEV2ZW50cyk7XHJcbiAgfVxyXG4gIC8vIFJTIDA5REVDMjQgQ2hhbmdlZCBrZXlzXHJcbiAgcHJvY2Vzc1F1ZXN0aW9uKCl7XHJcbiAgICB0aGlzLmVudHJpZXMgPSBKU09OLnBhcnNlKHRoaXMucXVlc3Rpb25bJ2ZpZWxkc01ldGEnXSk7XHJcbiAgICB0aGlzLnFiUmVmcmVuY2VCb29rID0gSlNPTi5wYXJzZSh0aGlzLnF1ZXN0aW9uWydxYlJlZmVyZW5jZVF1ZXN0aW9ucyddKTtcclxuICAgIGxldCB0aXRsZSA9IHRoaXMucWJSZWZyZW5jZUJvb2s/LnF1ZXN0aW9uYm9vaz8udGl0bGU7XHJcbiAgICB0aGlzLm1vZGFsVGl0bGUgPSB0aXRsZTtcclxuICAgIHRoaXMucmVmZXJlbmNlUXVlc3Rpb25zID0gW107XHJcbiAgICBpZih0aGlzLmVudHJpZXMubGVuZ3RoID4gMCl7XHJcbiAgICAgICB0aGlzLmVudHJpZXMuZm9yRWFjaChlbGVtZW50ID0+IHtcclxuICAgICAgICAgICBpZihlbGVtZW50LnF1ZXN0aW9uUmVmZXJlbmNlKXtcclxuICAgICAgICAgICAgIGxldCBxUmVmZXJlbmNlID0gSlNPTi5wYXJzZShlbGVtZW50LnF1ZXN0aW9uUmVmZXJlbmNlKTtcclxuICAgICAgICAgICAgIHRoaXMucmVmZXJlbmNlUXVlc3Rpb25zLnB1c2gocVJlZmVyZW5jZT8ucXVlc3Rpb24pO1xyXG4gICAgICAgICAgIH1cclxuICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgY29uc29sZS5sb2coJ2VudHJpZXMtLT4nKTtcclxuICAgIGNvbnNvbGUubG9nKCdxdWVzdGlvbi0tPicpO1xyXG4gICAgY29uc29sZS5sb2codGhpcy5lbnRyaWVzKTtcclxuICAgIGNvbnNvbGUubG9nKHRoaXMucmVmZXJlbmNlUXVlc3Rpb25zKTtcclxuICB9XHJcbiAgIC8vIHN1bmRheSBjb21tZW50XHJcbiAgLy8gb3BlblF1ZXN0aW9uQm9va01vZGFsKCkge1xyXG4gIC8vICAgY29uc3Qgdmlld0NvbnRhaW5lclJlZiA9IHRoaXMuZHluYW1pY0hvc3Qudmlld0NvbnRhaW5lclJlZjtcclxuICAvLyAgIHZpZXdDb250YWluZXJSZWYuY2xlYXIoKTtcclxuICAvLyAgIGNvbnN0IGNvbXBvbmVudFJlZiA9IHZpZXdDb250YWluZXJSZWYuY3JlYXRlQ29tcG9uZW50KFF1ZXN0aW9uYm9va0NvbXBvbmVudCk7XHJcbiAgLy8gICBjb21wb25lbnRSZWYuaW5zdGFuY2UucWJJdGVtID0gdGhpcy5xYlJlZnJlbmNlQm9vaztcclxuICAvLyAgIGNvbXBvbmVudFJlZi5pbnN0YW5jZS5xdWVzdGlvbnMgPSB0aGlzLnJlZmVyZW5jZVF1ZXN0aW9ucztcclxuICAvLyAgIGNvbXBvbmVudFJlZi5pbnN0YW5jZS5oYW5kbGVRdWVzdGlvbi5zdWJzY3JpYmUoKGV2ZW50OiBhbnkpID0+IHRoaXMuaGFuZGxlUXVlc3Rpb25FdmVudChldmVudCkpO1xyXG4gIC8vIH1cclxuXHJcbiAgZ2VuZXJhdGVDYWxlbmRhcigpIHtcclxuICAgIGNvbnN0IHllYXIgPSB0aGlzLmN1cnJlbnREYXRlLmdldEZ1bGxZZWFyKCk7XHJcbiAgICBjb25zdCBtb250aCA9IHRoaXMuY3VycmVudERhdGUuZ2V0TW9udGgoKTtcclxuXHJcbiAgICBjb25zdCBzdGFydE9mTW9udGggPSBuZXcgRGF0ZSh5ZWFyLCBtb250aCwgMSk7XHJcbiAgICBjb25zdCBlbmRPZk1vbnRoID0gbmV3IERhdGUoeWVhciwgbW9udGggKyAxLCAwKTtcclxuXHJcbiAgICBjb25zdCBzdGFydERheU9mV2VlayA9IHN0YXJ0T2ZNb250aC5nZXREYXkoKTtcclxuICAgIGNvbnN0IGVuZERheU9mV2VlayA9IGVuZE9mTW9udGguZ2V0RGF5KCk7XHJcblxyXG4gICAgY29uc3Qgc3RhcnREYXRlID0gbmV3IERhdGUoc3RhcnRPZk1vbnRoKTtcclxuICAgIHN0YXJ0RGF0ZS5zZXREYXRlKHN0YXJ0RGF0ZS5nZXREYXRlKCkgLSBzdGFydERheU9mV2Vlayk7XHJcblxyXG4gICAgY29uc3QgZW5kRGF0ZSA9IG5ldyBEYXRlKGVuZE9mTW9udGgpO1xyXG4gICAgZW5kRGF0ZS5zZXREYXRlKGVuZERhdGUuZ2V0RGF0ZSgpICsgKDYgLSBlbmREYXlPZldlZWspKTtcclxuXHJcbiAgICBjb25zdCB0b2RheSA9IG5ldyBEYXRlKG5ldyBEYXRlKCkuc2V0SG91cnMoMCwgMCwgMCwgMCkpO1xyXG4gICAgXHJcbiAgICAgdGhpcy5jYWxlbmRhckRheXMgPSBbXTtcclxuICAgICAgZm9yIChsZXQgZCA9IG5ldyBEYXRlKHN0YXJ0RGF0ZSk7IGQgPD0gZW5kRGF0ZTsgZC5zZXREYXRlKGQuZ2V0RGF0ZSgpICsgMSkpIHtcclxuICAgICAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoZCk7XHJcbiAgICAgICAgdGhpcy5jYWxlbmRhckRheXMucHVzaCh7XHJcbiAgICAgICAgICBkYXRlOiBkYXRlLFxyXG4gICAgICAgICAgZXZlbnRzOiBbXSxcclxuICAgICAgICAgIGlzQ3VycmVudE1vbnRoOiBkLmdldE1vbnRoKCkgPT09IG1vbnRoLFxyXG4gICAgICAgICAgaXNQYXN0OiBkYXRlIDwgdG9kYXksXHJcbiAgICAgICAgICBpc1RvZGF5OiBkYXRlLmdldFRpbWUoKSA9PT0gdG9kYXkuZ2V0VGltZSgpLFxyXG4gICAgICAgICAgaXNGdXR1cmU6IGRhdGUgPiB0b2RheSxcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG5cclxuICAgIC8vIFBvcHVsYXRlIGNhbGVuZGFyIHdpdGggZXZlbnRzIGZyb20gYWxsRXZlbnRzIGFycmF5XHJcbiAgICB0aGlzLmNhbGVuZGFyRGF5cy5mb3JFYWNoKGRheSA9PiB7XHJcbiAgICAgIGRheS5ldmVudHMgPSB0aGlzLmFsbEV2ZW50cz8uZmlsdGVyKGV2ZW50ID0+IGV2ZW50Py5kYXRlPy50b0RhdGVTdHJpbmcoKSA9PT0gZGF5LmRhdGUudG9EYXRlU3RyaW5nKCkpO1xyXG4gICAgfSk7XHJcbiAgICAgLy8gVkQgMDZTZXAyNCBjYWxlbmRhciBjaGFuZ2VzXHJcbiAgICBsZXQgY2FsID0ge31cclxuICAgIGNhbFsneWVhciddID0geWVhcjtcclxuICAgIGNhbFsnbW9udGgnXSA9IG1vbnRoICsgMTtcclxuICAgIHRoaXMuY2FsZW5kYXIgPSBjYWw7XHJcbiAgfVxyXG5cclxuICBzZWxlY3REYXkoZGF5OiBDYWxlbmRhckRheSkge1xyXG4gICAgY29uc29sZS5sb2coZGF5KTtcclxuICAgICAvLyBWRCAwNlNlcDI0IGNhbGVuZGFyIGNoYW5nZXNcclxuICAgIHRoaXMuc2hvd0FwcG9pbm1lbnRTZWN0aW9uID0gdHJ1ZTtcclxuICAgIHRoaXMuc2VsZWN0ZWREYXkgPSBkYXk7XHJcbiAgIC8vIHRoaXMuZXZlbnRTZWxlY3RlZC5lbWl0KGRheT8uZXZlbnRzKTtcclxuICAgIGNvbnN0IHByZXZpb3VzbHlTZWxlY3RlZERheSA9IHRoaXMuY2FsZW5kYXJEYXlzLmZpbmQoZCA9PiBkLmlzU2VsZWN0ZWQpO1xyXG4gICAgaWYgKHByZXZpb3VzbHlTZWxlY3RlZERheSkge1xyXG4gICAgICBwcmV2aW91c2x5U2VsZWN0ZWREYXkuaXNTZWxlY3RlZCA9IGZhbHNlO1xyXG4gICAgfVxyXG4gICAgLy8gU2VsZWN0IHRoZSBjbGlja2VkIGRheVxyXG4gICAgZGF5LmlzU2VsZWN0ZWQgPSB0cnVlO1xyXG4gICAvLyBWRCAwOVNlcDI0LSBzZXR1cCB0aGUgcXVlcnkgcGFyYW0gZGF0YSBmb3IgYXBpIGNhbGxcclxuICAgIGxldCByZWZlcmVuY2VEYXRhID0gW107XHJcbiAgICB0aGlzLnJlZmVyZW5jZVF1ZXN0aW9ucy5mb3JFYWNoKHF1ZXMgPT4ge1xyXG4gICAgICAvLyBWRCAwOS0wOS0yNCBnZXQgdGhlIHNlbGVjdGVkIGRhdGVcclxuICAgICAgLy8gbmVlZCB0byBhZGQgaW4gdGhlIGRvY3VtZW50XHJcbiAgICAgIC8vIFJTIDA5REVDMjQgQ2hhbmdlZCBrZXlzXHJcbiAgICAgICBpZihxdWVzLnJlZmVyZW5jZUZpZWxkID09ICdzZWxlY3RlZERhdGUnKXtcclxuICAgICAgICAgIHF1ZXMuaW5wdXQgPSBkYXkuZGF0ZS50b0lTT1N0cmluZygpO1xyXG4gICAgICAgICAgY29uc29sZS5sb2cocXVlcy5pbnB1dCk7XHJcbiAgICAgICB9XHJcbiAgICAgICAvLyBWRCAwOS0wOS0yNCBnZXQgdGhlIHF1ZXJ5IHJlZnJlbmNlICBmaWVsZCBkYXRhIHRvIHBhc3MgdGhlIHF1ZXJ5UGFyYW0gIGZvciBhcGlcclxuICAgICAgIGlmKHF1ZXMuc3ViVGV4dCl7XHJcbiAgICAgICAgbGV0IHN1YlRleHQgPSBKU09OLnBhcnNlKHF1ZXMuc3ViVGV4dCk7XHJcbiAgICAgICAgaWYgKHN1YlRleHQucXVlcnlGaWVsZCAmJiBzdWJUZXh0LnF1ZXJ5VmFsdWVSZWZlcmVuY2UpIHtcclxuICAgICAgICAgICAgbGV0IGN1cnJlbnRRdWVzID0gcXVlcztcclxuICAgICAgICAgICAgbGV0IHF1ZXJ5UmVmZXJlbmNlcyA9IHN1YlRleHQucXVlcnlWYWx1ZVJlZmVyZW5jZS5zcGxpdCgnLCcpOyAgIFxyXG4gICAgICAgICAgICBxdWVyeVJlZmVyZW5jZXMuZm9yRWFjaChyZWZGaWVsZCA9PiB7XHJcbiAgICAgICAgICAgICAgICBsZXQgcmVmUXVlcyA9IHRoaXMucmVmZXJlbmNlUXVlc3Rpb25zLmZpbmQocSA9PiBxLnJlZmVyZW5jZUZpZWxkID09PSByZWZGaWVsZCk7XHJcbiAgICAgICAgICAgICAgICBpZiAocmVmUXVlcykge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlZmVyZW5jZURhdGEucHVzaChyZWZRdWVzKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIC8vIEFkZCB0aGUgcmVmZXJlbmNlRGF0YSBhcnJheSB0byB0aGUgY3VycmVudCBxdWVzdGlvblxyXG4gICAgICAgICAgICBjdXJyZW50UXVlcy5yZWZlcmVuY2VRdWVyeURhdGEgPSByZWZlcmVuY2VEYXRhO1xyXG4gICAgICAgIH1cclxuICAgICAgIH1cclxuICAgIH0pXHJcbiAgfVxyXG5cclxuICBwcmV2aW91c01vbnRoKCkge1xyXG4gICAgdGhpcy5zaG93QXBwb2lubWVudFNlY3Rpb24gPSBmYWxzZTtcclxuICAgIHRoaXMuY3VycmVudERhdGUuc2V0TW9udGgodGhpcy5jdXJyZW50RGF0ZS5nZXRNb250aCgpIC0gMSk7XHJcbiAgICB0aGlzLmN1cnJlbnREYXRlID0gbmV3IERhdGUodGhpcy5jdXJyZW50RGF0ZSk7IC8vIEVuc3VyZSB0aGUgZGF0ZSBvYmplY3QgaXMgdXBkYXRlZFxyXG4gICAgdGhpcy5nZW5lcmF0ZUNhbGVuZGFyKCk7XHJcbiAgICB0aGlzLmRhdGVTZWxlY3RlZC5lbWl0KHRoaXMuY2FsZW5kYXIpO1xyXG4gICAgdGhpcy5ldmVudFNlbGVjdGVkLmVtaXQodGhpcy5hbGxFdmVudHMpO1xyXG4gIH1cclxuXHJcbiAgbmV4dE1vbnRoKCkge1xyXG4gICAgIC8vIFZEIDA2U2VwMjQgY2FsZW5kYXIgY2hhbmdlc1xyXG4gICAgdGhpcy5zaG93QXBwb2lubWVudFNlY3Rpb24gPSBmYWxzZTtcclxuICAgIHRoaXMuY3VycmVudERhdGUuc2V0TW9udGgodGhpcy5jdXJyZW50RGF0ZS5nZXRNb250aCgpICsgMSk7XHJcbiAgICB0aGlzLmN1cnJlbnREYXRlID0gbmV3IERhdGUodGhpcy5jdXJyZW50RGF0ZSk7IC8vIEVuc3VyZSB0aGUgZGF0ZSBvYmplY3QgaXMgdXBkYXRlZFxyXG4gICAgdGhpcy5nZW5lcmF0ZUNhbGVuZGFyKCk7XHJcbiAgICB0aGlzLmRhdGVTZWxlY3RlZC5lbWl0KHRoaXMuY2FsZW5kYXIpO1xyXG4gICAgdGhpcy5ldmVudFNlbGVjdGVkLmVtaXQodGhpcy5hbGxFdmVudHMpO1xyXG4gIH1cclxuXHJcbiAgYWRkQXBwb2ludG1lbnQoKSB7XHJcbiAgICB0aGlzLmlzTW9kYWxPcGVuID0gdHJ1ZTtcclxuICAgICB0aGlzLmNhbGVuZGFyUXVlc3Rpb24gPSB0aGlzLnJlZmVyZW5jZVF1ZXN0aW9ucy5tYXAocSA9PiAoeyAuLi5xLCBpbnB1dDogJycgfSkpO1xyXG4gICAgdGhpcy5yZWZlcmVuY2VRdWVzdGlvbnMuZm9yRWFjaChxdWVzID0+IHtcclxuICAgICAgLy8gY2xlYXIgdGhlIGlucHV0XHJcbiAgICAgIGlmKHF1ZXMucmVmZXJlbmNlRmllbGQgIT0gJ3NlbGVjdGVkRGF0ZScpe1xyXG4gICAgICAgIGlmKHF1ZXMudHlwZSA9PSAnRHJvcGRvd24nKXtcclxuICAgICAgICAgIGRlbGV0ZSBxdWVzLmlucHV0O1xyXG4gICAgICAgICAgZGVsZXRlIHF1ZXMuc2VsZWN0ZWRWYWx1ZTtcclxuICAgICAgICAgICAvLyBWRCAwNlNlcDI0IGNhbGVuZGFyIGNoYW5nZXNcclxuICAgICAgICB9ZWxzZSB7XHJcbiAgICAgICAgICBkZWxldGUgcXVlcy5pbnB1dDtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgY29uc29sZS5sb2codGhpcy5yZWZlcmVuY2VRdWVzdGlvbnMpO1xyXG4gICAgdGhpcy5lZGl0aW5nRXZlbnRJZCA9IG51bGw7XHJcbiAgICB0aGlzLmNhbGVuZGFyUXVlc3Rpb24gPSB0aGlzLnJlZmVyZW5jZVF1ZXN0aW9ucztcclxuICAgIHRoaXMub3BlbkJvb2tNb2RlbCgpO1xyXG4gICAgLy8gc3VuZGF5IGNvbW1lbnRcclxuICAgIC8vdGhpcy5vcGVuUXVlc3Rpb25Cb29rTW9kYWwoKTtcclxuICB9XHJcblxyXG4gIG9wZW5Cb29rTW9kZWwoKXtcclxuICAgIHRoaXMub3Blbk1vZGFsLmVtaXQoe1xyXG4gICAgICBxYlJlZnJlbmNlQm9vazogdGhpcy5xYlJlZnJlbmNlQm9vayxcclxuICAgICAgcmVmZXJlbmNlUXVlc3Rpb25zOiB0aGlzLnJlZmVyZW5jZVF1ZXN0aW9ucyxcclxuICAgICAgbW9kYWxUaXRsZSA6IHRoaXMubW9kYWxUaXRsZSxcclxuICAgICAgbW9kYWxTaXplIDogdGhpcy5tb2RhbFNpemUsXHJcbiAgICAgIHNhdmVCdXR0b25WYWx1ZSA6IHRoaXMuc2F2ZUJ1dHRvblZhbHVlLFxyXG4gICAgICBtb2RhbEZvb3RlciA6IHRoaXMubW9kYWxGb290ZXIsXHJcblxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBjbG9zZUNhbGVuZGFyTW9kYWwoKSB7XHJcbiAgICB0aGlzLmlzTW9kYWxPcGVuID0gZmFsc2U7XHJcbiAgICB0aGlzLmNsb3NlTW9kYWwuZW1pdCh0cnVlKTtcclxuICB9XHJcbiAvLyBWRCAwNlNlcDI0IGNhbGVuZGFyIGNoYW5nZXNcclxuXHJcbmVkaXRFdmVudChldmVudDogYW55LCBlbnRyeUdyb3VwOiBhbnkpIHtcclxuICB0aGlzLmlzTW9kYWxPcGVuID0gdHJ1ZTtcclxuICB0aGlzLnJlZmVyZW5jZVF1ZXN0aW9ucyA9IE9iamVjdC52YWx1ZXMoZW50cnlHcm91cCk7XHJcbiAgdGhpcy5jYWxlbmRhclF1ZXN0aW9uID0gWy4uLnRoaXMucmVmZXJlbmNlUXVlc3Rpb25zXTsgLy8gTWFrZSBhIGNvcHkgb2YgdGhlIGN1cnJlbnQgZW50cmllcyB0byBlZGl0XHJcbiAgdGhpcy5lZGl0aW5nRXZlbnRJZCA9IGV2ZW50LmlkO1xyXG4gIHRoaXMuZWRpdGluZ0VudHJ5R3JvdXAgPSBlbnRyeUdyb3VwOyAvLyBTdG9yZSB0aGUgZW50cnkgZ3JvdXAgYmVpbmcgZWRpdGVkXHJcbiAgdGhpcy5nZW5lcmF0ZUNhbGVuZGFyKCk7IC8vIFJlZ2VuZXJhdGUgdGhlIGNhbGVuZGFyIHRvIHJlZmxlY3QgY2hhbmdlc1xyXG4gIHRoaXMub3BlbkJvb2tNb2RlbCgpO1xyXG4gIC8vIHN1ZGF5IGNvbW1lbnRcclxuIC8vIHRoaXMub3BlblF1ZXN0aW9uQm9va01vZGFsKCk7XHJcblxyXG59XHJcblxyXG5kZWxldGVFdmVudCggZXZlbnRJZDogbnVtYmVyLCBlbnRyeUdyb3VwOiBhbnkpIHtcclxuICBsZXQgZXZlbnQgPSB0aGlzLmFsbEV2ZW50cz8uZmluZChlID0+IGU/LmlkID09PSBldmVudElkKTtcclxuICBpZiAoZXZlbnQpIHtcclxuICAgICAgLy8gRmluZCB0aGUgaW5kZXggb2YgdGhlIGVudHJ5R3JvdXAgdG8gZGVsZXRlXHJcbiAgICAgIGNvbnN0IGVudHJ5SW5kZXggPSBldmVudC5lbnRyaWVzLmluZGV4T2YoZW50cnlHcm91cCk7XHJcbiAgICAgIGlmIChlbnRyeUluZGV4ID4gLTEpIHtcclxuICAgICAgICAgIGV2ZW50LmVudHJpZXMuc3BsaWNlKGVudHJ5SW5kZXgsIDEpOyAvLyBSZW1vdmUgdGhlIHNwZWNpZmljIGVudHJ5XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIElmIHRoZSBldmVudCBoYXMgbm8gbW9yZSBlbnRyaWVzLCByZW1vdmUgdGhlIGV2ZW50IGVudGlyZWx5XHJcbiAgICAgIGlmIChldmVudC5lbnRyaWVzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgICAgY29uc3QgZXZlbnRJbmRleCA9IHRoaXMuYWxsRXZlbnRzPy5pbmRleE9mKGV2ZW50KTtcclxuICAgICAgICAgIGlmIChldmVudEluZGV4ID4gLTEpIHtcclxuICAgICAgICAgICAgICB0aGlzLmFsbEV2ZW50cz8uc3BsaWNlKGV2ZW50SW5kZXgsIDEpOyAvLyBSZW1vdmUgdGhlIGVudGlyZSBldmVudFxyXG4gICAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgfVxyXG4gIGxldCBldmVudERhdGEgPSB7fTtcclxuICAgZXZlbnREYXRhWydhY3Rpb24nXSA9IFwiZGVsZXRlXCI7XHJcbiAgIGV2ZW50RGF0YVsnZGF0YSddID0gZXZlbnQ7XHJcbiAgdGhpcy5ldmVudFNlbGVjdGVkLmVtaXQoZXZlbnREYXRhKTtcclxuICB0aGlzLmdlbmVyYXRlQ2FsZW5kYXIoKTsgLy8gUmVnZW5lcmF0ZSB0aGUgY2FsZW5kYXIgdG8gcmVmbGVjdCB0aGUgY2hhbmdlc1xyXG59XHJcblxyXG4gLy8gVkQgMDZTZXAyNCBjYWxlbmRhciBjaGFuZ2VzXHJcbiAgYWRkRXZlbnQoZGF5OiBDYWxlbmRhckRheSwgZW50cnlRdWVzKSB7XHJcbiAgICAvLyBUcmFuc2Zvcm0gbmV3IGVudHJpZXMgaW50byB0aGUgZGVzaXJlZCBmb3JtYXRcclxuICAgIGNvbnN0IG5ld0VudHJpZXMgPSBlbnRyeVF1ZXMucmVkdWNlKChhY2MsIHEpID0+IHtcclxuICAgICAgICBhY2NbcS5pZF0gPSB7IC4uLnEgfTtcclxuICAgICAgICByZXR1cm4gYWNjO1xyXG4gICAgfSwge30pO1xyXG5cclxuICAgIC8vIEZpbmQgYW4gZXhpc3RpbmcgZXZlbnQgZm9yIHRoZSBnaXZlbiBkYXRlXHJcbiAgICBjb25zdCBleGlzdGluZ0V2ZW50ID0gZGF5LmV2ZW50cz8uZmluZChldmVudCA9PiBldmVudC5kYXRlID09PSBkYXkuZGF0ZSk7XHJcblxyXG4gICAgaWYgKGV4aXN0aW5nRXZlbnQpIHtcclxuICAgICAgICAvLyBNZXJnZSBuZXcgZW50cmllcyBpbnRvIHRoZSBleGlzdGluZyBldmVudCdzIGVudHJpZXMgYXJyYXlcclxuICAgICAgICAvLyBDaGVjayBpZiB0aGUgZW50cmllcyBhcnJheSBhbHJlYWR5IGNvbnRhaW5zIGFuIG9iamVjdCB3aXRoIHRoZSBzYW1lIGlkXHJcbiAgICAgICAgY29uc3QgZXhpc3RpbmdFbnRyaWVzID0gZXhpc3RpbmdFdmVudC5lbnRyaWVzLm1hcChlbnRyeSA9PiAoeyAuLi5lbnRyeSB9KSk7XHJcbiAgICAgICAgLy8gQXBwZW5kIG5ldyBlbnRyaWVzIHRvIHRoZSBleGlzdGluZyBlbnRyaWVzXHJcbiAgICAgICAgZXhpc3RpbmdFbnRyaWVzLnB1c2gobmV3RW50cmllcyk7XHJcbiAgICAgICAgZXhpc3RpbmdFdmVudC5lbnRyaWVzID0gZXhpc3RpbmdFbnRyaWVzO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICAvLyBDcmVhdGUgYSBuZXcgZXZlbnQgaWYgaXQgZG9lc24ndCBleGlzdCBmb3IgdGhlIGdpdmVuIGRhdGVcclxuICAgICAgICBjb25zdCBuZXdFdmVudCA9IHtcclxuICAgICAgICAgICAgaWQ6IHRoaXMuZ2VuZXJhdGVJZCgpLFxyXG4gICAgICAgICAgICBkYXRlOiBkYXkuZGF0ZSxcclxuICAgICAgICAgICAgZW50cmllczogW25ld0VudHJpZXNdIC8vIFdyYXAgdGhlIG5ldyBlbnRyaWVzIGluIGFuIGFycmF5XHJcbiAgICAgICAgfTtcclxuICAgICAgICBkYXkuZXZlbnRzID0gZGF5Py5ldmVudHMgfHwgW11cclxuICAgICAgICBkYXkuZXZlbnRzLnB1c2gobmV3RXZlbnQpO1xyXG4gICAgICAgIHRoaXMuYWxsRXZlbnRzPy5wdXNoKG5ld0V2ZW50KTtcclxuICAgICAgICAvL3RoaXMuZXZlbnRTZWxlY3RlZC5lbWl0KHRoaXMuYWxsRXZlbnRzKTtcclxuICAgICAgICBsZXQgZXZlbnREYXRhID0ge307XHJcbiAgICAgICAgZXZlbnREYXRhWydhY3Rpb24nXSA9IFwiYWRkXCI7XHJcbiAgICAgICAgZXZlbnREYXRhWydkYXRhJ10gPSBuZXdFdmVudDtcclxuICAgICAgICB0aGlzLmV2ZW50U2VsZWN0ZWQuZW1pdChldmVudERhdGEpO1xyXG4gICAgfVxyXG4gICAgdGhpcy5nZW5lcmF0ZUNhbGVuZGFyKCk7XHJcbiAgICBjb25zb2xlLmxvZygnYWxsRXZlbnRzJywgdGhpcy5hbGxFdmVudHMpO1xyXG59XHJcbiAvLyBWRCAwNlNlcDI0IGNhbGVuZGFyIGNoYW5nZXNcclxuIG9uU2F2ZSgpIHtcclxuICAgIGlmICh0aGlzLmVkaXRpbmdFdmVudElkICE9PSBudWxsKSB7XHJcbiAgICAgICAgY29uc3QgZXZlbnQgPSB0aGlzLmFsbEV2ZW50cz8uZmluZChlID0+IGU/LmlkID09PSB0aGlzLmVkaXRpbmdFdmVudElkKTtcclxuICAgICAgICBpZiAoZXZlbnQgJiYgdGhpcy5lZGl0aW5nRW50cnlHcm91cCkge1xyXG4gICAgICAgICAgICAvLyBVcGRhdGUgdGhlIHNwZWNpZmljIGVudHJ5IGdyb3VwIHdpdGhpbiB0aGUgZXZlbnRcclxuICAgICAgICAgICAgY29uc3QgZW50cnlJbmRleCA9IGV2ZW50LmVudHJpZXMuZmluZEluZGV4KGVudHJ5R3JvdXAgPT4gZW50cnlHcm91cCA9PT0gdGhpcy5lZGl0aW5nRW50cnlHcm91cCk7XHJcbiAgICAgICAgICAgIGlmIChlbnRyeUluZGV4ID4gLTEpIHtcclxuICAgICAgICAgICAgICAgIGV2ZW50LmVudHJpZXNbZW50cnlJbmRleF0gPSB0aGlzLmNhbGVuZGFyUXVlc3Rpb24ucmVkdWNlKChhY2MsIHEpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBhY2NbcS5pZF0gPSB7IC4uLnEgfTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYWNjO1xyXG4gICAgICAgICAgICAgICAgfSwge30pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgIC8vIHRoaXMuZXZlbnRTZWxlY3RlZC5lbWl0KHRoaXMuYWxsRXZlbnRzKTtcclxuICAgICAgbGV0IGV2ZW50RGF0YSA9IHt9O1xyXG4gICAgICBldmVudERhdGFbJ2FjdGlvbiddID0gXCJlZGl0XCI7XHJcbiAgICAgIGV2ZW50RGF0YVsnZGF0YSddID0gZXZlbnQ7XHJcbiAgICAgIHRoaXMuZXZlbnRTZWxlY3RlZC5lbWl0KGV2ZW50RGF0YSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIGlmICh0aGlzLnNlbGVjdGVkRGF5KSB7XHJcbiAgICAgICAgICAgIHRoaXMuYWRkRXZlbnQodGhpcy5zZWxlY3RlZERheSwgdGhpcy5jYWxlbmRhclF1ZXN0aW9uKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICB0aGlzLmNsb3NlQ2FsZW5kYXJNb2RhbCgpO1xyXG4gICAgdGhpcy5nZW5lcmF0ZUNhbGVuZGFyKCk7XHJcbn1cclxuXHJcbiAgLy8gb25DYW5jZWwoKSB7XHJcbiAgLy8gICBjb25zb2xlLmxvZygnQ2FuY2VsIGJ1dHRvbiBjbGlja2VkJyk7XHJcbiAgLy8gICB0aGlzLmNsb3NlQ2FsZW5kYXJNb2RhbCgpO1xyXG4gIC8vIH1cclxuICAvL3RoaXMgZnVudGlvbiBuZWVkIHRvIGJlIHVzZWRcclxuICAvLyBoYW5kbGVRdWVzdGlvbkV2ZW50KHF1ZXMpe1xyXG4gIC8vICAgICAvLyBVcGRhdGUgdGhlIHF1ZXN0aW9ucyBhcnJheSB3aXRoIHRoZSBuZXcgcXVlc3Rpb25cclxuICAvLyAgICAgY29uc3QgaW5kZXggPSB0aGlzLmNhbGVuZGFyUXVlc3Rpb24uZmluZEluZGV4KHEgPT4gcS5pZCA9PT0gcXVlcy5pZCk7XHJcbiAgLy8gICAgIGlmIChpbmRleCA+IC0xKSB7XHJcbiAgLy8gICAgICAgLy8gSWYgcXVlc3Rpb24gYWxyZWFkeSBleGlzdHMsIHVwZGF0ZSBpdFxyXG4gIC8vICAgICAgIHRoaXMuY2FsZW5kYXJRdWVzdGlvbltpbmRleF0gPSBxdWVzO1xyXG4gIC8vICAgICB9IGVsc2Uge1xyXG4gIC8vICAgICAgIC8vIElmIHF1ZXN0aW9uIGRvZXNuJ3QgZXhpc3QsIGFkZCBpdCB0byB0aGUgYXJyYXlcclxuICAvLyAgICAgICB0aGlzLmNhbGVuZGFyUXVlc3Rpb24ucHVzaChxdWVzKTtcclxuICAvLyAgICAgfVxyXG4gIC8vICAgICBjb25zb2xlLmxvZyh0aGlzLmNhbGVuZGFyUXVlc3Rpb24pO1xyXG4gIC8vICAgfVxyXG5cclxuIC8vIFZEIDA2U2VwMjQgY2FsZW5kYXIgY2hhbmdlc1xyXG4gIGdlbmVyYXRlSWQoKSB7XHJcbiAgICByZXR1cm4gJ18nICsgTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc3Vic3RyKDIsIDkpO1xyXG4gIH1cclxuXHJcbiAgZ2V0RW50cnlLZXlzKGVudHJ5R3JvdXA6IGFueSk6IHN0cmluZ1tdIHtcclxuICAgIHJldHVybiBPYmplY3Qua2V5cyhlbnRyeUdyb3VwKTtcclxufVxyXG5cclxucmVtb3ZlQ2hhcmFjdGVycyhxdWVzdGlvblRleHQ6c3RyaW5nKXtcclxuICBsZXQgdXBkYXRlZFRleHQgPSBxdWVzdGlvblRleHQ/LnJlcGxhY2UoLzxbXj5dKj4vZywgJycpO1xyXG4gIHJldHVybiB1cGRhdGVkVGV4dDtcclxufVxyXG5cclxufVxyXG4iLCI8ZGl2IGNsYXNzPVwiYWxpZ24tY2FsZW5kYXJcIj5cclxuICAgIDxkaXYgY2xhc3M9XCJjYWxlbmRhci1jb250YWluZXJcIj5cclxuICAgICAgPGRpdiBjbGFzcz1cImNhbGVuZGFyLWhlYWRlclwiPlxyXG4gICAgICAgICAgPGJ1dHRvbiAoY2xpY2spPVwicHJldmlvdXNNb250aCgpXCI+PDwgUHJldmlvdXMgPj48L2J1dHRvbj5cclxuICAgICAgICAgIDxoMz57eyBjdXJyZW50RGF0ZSB8IGRhdGU6ICdNTU1NIHl5eXknIH19PC9oMz5cclxuICAgICAgICAgIDxidXR0b24gKGNsaWNrKT1cIm5leHRNb250aCgpXCI+PDwgTmV4dCA+PjwvYnV0dG9uPlxyXG4gICAgICA8L2Rpdj5cclxuICAgICAgPGRpdiBjbGFzcz1cImNhbGVuZGFyLWdyaWRcIj5cclxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJkYXktb2Ytd2Vla1wiICpuZ0Zvcj1cImxldCBkYXkgb2YgZGF5c09mV2Vla1wiPnt7IGRheSB9fTwvZGl2PlxyXG4gICAgICAgICAgPGRpdlxyXG4gICAgICAgICAgICAgIGNsYXNzPVwiY2FsZW5kYXItZGF5XCJcclxuICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgZGF5IG9mIGNhbGVuZGFyRGF5c1wiXHJcbiAgICAgICAgICAgICAgW2NsYXNzLm5vdC1jdXJyZW50LW1vbnRoXT1cIiFkYXkuaXNDdXJyZW50TW9udGhcIlxyXG4gICAgICAgICAgICAgIFtjbGFzcy5wYXN0XT1cImRheS5pc1Bhc3RcIlxyXG4gICAgICAgICAgICAgIFtjbGFzcy50b2RheV09XCJkYXkuaXNUb2RheVwiXHJcbiAgICAgICAgICAgICAgW2NsYXNzLmZ1dHVyZV09XCJkYXkuaXNGdXR1cmVcIlxyXG4gICAgICAgICAgICAgIFtjbGFzcy5zZWxlY3RlZF09XCJkYXkuaXNTZWxlY3RlZFwiXHJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cInNlbGVjdERheShkYXkpXCJcclxuICAgICAgICA+XHJcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRheS1udW1iZXJcIj57eyBkYXkuZGF0ZS5nZXREYXRlKCkgfX1cclxuICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiZGF5Py5ldmVudHM/Lmxlbmd0aCA+IDBcIiBjbGFzcz1cImVudHJ5LWluZGljYXRvclwiIFtjbGFzcy5zZWxlY3RdPVwiZGF5Py5pc1NlbGVjdGVkXCI+PC9zcGFuPlxyXG4gICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgIDwhLS0gPGRpdiAqbmdGb3I9XCJsZXQgZXZlbnQgb2YgZGF5LmV2ZW50c1wiID5cclxuICAgICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgZW50cnlHcm91cCBvZiBldmVudC5lbnRyaWVzXCIgY2xhc3M9XCJldmVudFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQga2V5IG9mIGdldEVudHJ5S2V5cyhlbnRyeUdyb3VwKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJlbnRyeUdyb3VwW2tleV0udHlwZSA9PSAnVGltZSdcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgZW50cnlHcm91cFtrZXldLmlucHV0Py52YWx1ZSB8IGRhdGU6ICdzaG9ydFRpbWUnIH19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cImVudHJ5R3JvdXBba2V5XS50eXBlICE9ICdUaW1lJ1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBlbnRyeUdyb3VwW2tleV0uaW5wdXQgfX1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICA8L2Rpdj4gLS0+XHJcbiAgICAgICAgICA8L2Rpdj5cclxuICAgICAgPC9kaXY+XHJcbiAgPC9kaXY+XHJcbiAgICA8ZGl2IGNsYXNzPVwiYXBwb2luYXBwb2ludG1lbnRcIj5cclxuICAgICAgPGRpdiBjbGFzcz1cImFwcG9pbnRtZW50cy1jb250YWluZXJcIj5cclxuICAgICAgICAgIDxoND5BZGQgQXBwb2ludG1lbnQ8L2g0PlxyXG4gICAgICAgICAgPGJ1dHRvbiAqbmdJZj1cInNlbGVjdGVkRGF5XCIgKGNsaWNrKT1cImFkZEFwcG9pbnRtZW50KClcIj5BZGQ8L2J1dHRvbj5cclxuICAgICAgPC9kaXY+XHJcbiAgICAgIDwhLS1WRCAwNlNlcDI0IGNhbGVuZGFyIHVwZGF0ZXMtLT4gXHJcbiAgICAgIDwhLS0gUlMgMDlERUMyNCBDaGFuZ2VkIGtleXMtLT4gXHJcbiAgICAgIDxkaXYgKm5nSWY9XCJzaG93QXBwb2lubWVudFNlY3Rpb24gJiYgc2VsZWN0ZWREYXk/LmV2ZW50cz8ubGVuZ3RoID4gMFwiIGNsYXNzPVwiYXBwb2ludG1lbnRzLWNvbnRhaW5lclwiPlxyXG4gICAgICAgICAgPGg0PkFwcG9pbnRtZW50czwvaDQ+XHJcbiAgICAgICAgICA8ZGl2ICAqbmdGb3I9XCJsZXQgZXZlbnQgb2Ygc2VsZWN0ZWREYXk/LmV2ZW50c1wiPlxyXG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJldmVudFwiICpuZ0Zvcj1cImxldCBlbnRyeUdyb3VwIG9mIGV2ZW50LmVudHJpZXNcIj5cclxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZXZlbnQtaW5mb1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQga2V5IG9mIGdldEVudHJ5S2V5cyhlbnRyeUdyb3VwKVwiIGNsYXNzPVwiZW50cnktcm93XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJlbnRyeUdyb3VwW2tleV0ucXVlc3Rpb25UZXh0XCIgY2xhc3M9XCJlbnRyeS10ZXh0XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7e3JlbW92ZUNoYXJhY3RlcnMoZW50cnlHcm91cFtrZXldLnF1ZXN0aW9uVGV4dCl9fTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJlbnRyeS12YWx1ZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPCEtLSBWRCAwOVNlcDI0LSBkYXRlIHR5cGUgYW5kIGxpbmsgdHlwZSB1cGRhdGVzICAgIC0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJlbnRyeUdyb3VwW2tleV0udHlwZSAhPSAnVGltZScgJiYgZW50cnlHcm91cFtrZXldLnR5cGUgIT0gJ0xpbmsnJiYgZW50cnlHcm91cFtrZXldLnR5cGUgIT0gJ0RhdGUnXCI+e3sgZW50cnlHcm91cFtrZXldLmlucHV0IH19PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJlbnRyeUdyb3VwW2tleV0udHlwZSA9PSAnVGltZSdcIj57eyBlbnRyeUdyb3VwW2tleV0uaW5wdXQgfCBkYXRlOiAnc2hvcnRUaW1lJyB9fTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwiZW50cnlHcm91cFtrZXldLnR5cGUgPT0gJ0RhdGUnXCI+e3sgZW50cnlHcm91cFtrZXldLmlucHV0IHwgZGF0ZTogJ21lZGl1bURhdGUnIH19PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJlbnRyeUdyb3VwW2tleV0udHlwZSA9PSAnTGluaydcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YSBbaHJlZl09XCInLy8nKyBlbnRyeUdyb3VwW2tleV0uaW5wdXRcIiB0YXJnZXQ9XCJfYmxhbmtcIj57e3JlbW92ZUNoYXJhY3RlcnMoZW50cnlHcm91cFtrZXldLnF1ZXN0aW9uVGV4dCl9fTwvYT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZXZlbnQtYWN0aW9uc1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIChjbGljayk9XCJlZGl0RXZlbnQoZXZlbnQsZW50cnlHcm91cClcIj5FZGl0PC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gKGNsaWNrKT1cImRlbGV0ZUV2ZW50KGV2ZW50LmlkLGVudHJ5R3JvdXApXCI+RGVsZXRlPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgIDwvZGl2PlxyXG4gICAgICA8L2Rpdj5cclxuICA8L2Rpdj5cclxuPC9kaXY+XHJcblxyXG48IS0tIDxhcHAtY3VzdG9tLW1vZGVsXHJcbiAgW21vZGFsVGl0bGVdPVwibW9kYWxUaXRsZVwiXHJcbiAgW2lzTW9kYWxPcGVuXT1cImlzTW9kYWxPcGVuXCJcclxuICBbbW9kYWxTaXplXT1cIm1vZGFsU2l6ZVwiXHJcbiAgW3NhdmVCdXR0b25WYWx1ZV09XCJzYXZlQnV0dG9uVmFsdWVcIlxyXG4gIFttb2RhbEZvb3Rlcl09XCJtb2RhbEZvb3RlclwiXHJcbiAgKHNhdmVCdXR0b25FbWl0KT1cIm9uU2F2ZSgpXCJcclxuICAoY2FuY2VsQnV0dG9uRW1pdCk9XCJvbkNhbmNlbCgpXCJcclxuPlxyXG48bGliLXF1ZXN0aW9uYm9vayBbcWJJdGVtXT1cInFiUmVmcmVuY2VCb29rXCIgW3F1ZXN0aW9uc109XCJyZWZlcmVuY2VRdWVzdGlvbnNcIiAoaGFuZGxlUXVlc3Rpb24pPVwiaGFuZGxlUXVlc3Rpb25FdmVudCgkZXZlbnQpXCI+PC9saWItcXVlc3Rpb25ib29rPlxyXG48bmctdGVtcGxhdGUgZHluYW1pY0NvbXBvbmVudEhvc3QgPjwvbmctdGVtcGxhdGU+XHJcbjwvYXBwLWN1c3RvbS1tb2RlbD4gLS0+Il19
|