tango-app-ui-shared 3.3.1-beta.74 → 3.3.1-beta.76

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.
@@ -0,0 +1,784 @@
1
+ import { Component, HostListener, } from "@angular/core";
2
+ import dayjs from "dayjs";
3
+ import "dayjs/locale/en";
4
+ import * as i0 from "@angular/core";
5
+ import * as i1 from "../../../../services/auth.service";
6
+ import * as i2 from "@angular/router";
7
+ import * as i3 from "tango-app-ui-global";
8
+ import * as i4 from "@angular/common";
9
+ import * as i5 from "@angular/forms";
10
+ import * as i6 from "ngx-daterangepicker-material";
11
+ export class TrafficNobComponent {
12
+ auth;
13
+ router;
14
+ gs;
15
+ cd;
16
+ dayjs = dayjs;
17
+ isCustomDate = (m) => {
18
+ const isValidDate = m > this.dayjs();
19
+ return isValidDate ? "invalid-date" : false;
20
+ };
21
+ selectedDateRange = { startDate: dayjs().subtract(30, 'days'),
22
+ endDate: dayjs().subtract(1, "days"), };
23
+ selectedFilters = {
24
+ client: null,
25
+ clientName: null,
26
+ clients: [],
27
+ store: null,
28
+ stores: [],
29
+ date: null,
30
+ group: [],
31
+ location: [],
32
+ };
33
+ Opendropdown = false;
34
+ dropdownOpen = null; // 'location' or 'group'
35
+ searchLocationText = "";
36
+ searchGroupText = "";
37
+ locations = [];
38
+ filteredLocations = [];
39
+ groupsData = [];
40
+ filteredGroups = [];
41
+ filteredStores = [];
42
+ stores = [];
43
+ searchStoreText = '';
44
+ clientList = [];
45
+ selectedClient;
46
+ locationLabel = [];
47
+ groupLabel = [];
48
+ users;
49
+ url;
50
+ constructor(auth, router, gs, cd) {
51
+ this.auth = auth;
52
+ this.router = router;
53
+ this.gs = gs;
54
+ this.cd = cd;
55
+ }
56
+ onClick(event) {
57
+ const target = event.target;
58
+ if (!target.closest('.dropdown1')) {
59
+ this.Opendropdown = false;
60
+ }
61
+ }
62
+ closeDropdown1() {
63
+ this.Opendropdown = false;
64
+ }
65
+ ngOnInit() {
66
+ this.url = this.router.url.split("?")[0].split('/');
67
+ const user = JSON.parse(localStorage.getItem('user-info'));
68
+ this.users = user;
69
+ this.gs?.manageRefreshTrigger?.subscribe((e) => {
70
+ if (e) {
71
+ if (user.userType === 'tango') {
72
+ this.getClient();
73
+ }
74
+ else {
75
+ const storedFilters = localStorage.getItem("header-filters");
76
+ if (storedFilters) {
77
+ const headerFilters = JSON.parse(storedFilters);
78
+ this.filteredStores = headerFilters?.stores.map((store) => ({
79
+ ...store,
80
+ checked: store.checked
81
+ }));
82
+ }
83
+ }
84
+ }
85
+ });
86
+ // Fetch client data if the user is of type 'tango'
87
+ if (user.userType === 'tango') {
88
+ this.getClient();
89
+ }
90
+ else {
91
+ this.getLocations();
92
+ this.getGroups();
93
+ this.getStore();
94
+ // this.emitAndStoreFilters();
95
+ // console.log("1")
96
+ }
97
+ // Load filters from localStorage if they exist
98
+ const storedFilters = localStorage.getItem("header-filters");
99
+ if (storedFilters) {
100
+ const headerFilters = JSON.parse(storedFilters);
101
+ // Initialize selectedFilters with defaults or existing values
102
+ this.selectedFilters = {
103
+ client: headerFilters.client || this.users.client,
104
+ clientName: headerFilters.clientName || '',
105
+ clients: headerFilters.clients || [],
106
+ store: headerFilters.store || null,
107
+ date: headerFilters.date || {},
108
+ stores: headerFilters.stores || [],
109
+ group: headerFilters.group || [],
110
+ location: headerFilters.location || []
111
+ };
112
+ // Sync filtered data with stored selections
113
+ this.filteredLocations = this.syncWithLocalStorage(headerFilters.location);
114
+ this.filteredGroups = this.syncWithLocalStorage(headerFilters.group);
115
+ this.filteredStores = this.syncWithLocalStorage(headerFilters.stores);
116
+ // Format date range if it exists
117
+ if (headerFilters.date) {
118
+ this.selectedDateRange = {
119
+ startDate: this.dayjs(headerFilters.date.startDate, "YYYY-MM-DD").format("DD-MM-YYYY"),
120
+ endDate: this.dayjs(headerFilters.date.endDate, "YYYY-MM-DD").format("DD-MM-YYYY"),
121
+ };
122
+ }
123
+ else {
124
+ this.selectedDateRange = {
125
+ startDate: this.dayjs(this.selectedDateRange.startDate, "YYYY-MM-DD").format("DD-MM-YYYY"),
126
+ endDate: this.dayjs(this.selectedDateRange.endDate, "YYYY-MM-DD").format("DD-MM-YYYY"),
127
+ };
128
+ }
129
+ // console.log("3")
130
+ // Emit data via service and update localStorage
131
+ this.emitAndStoreFilters();
132
+ }
133
+ else {
134
+ // Initialize empty states if no header filters are present in localStorage
135
+ this.resetFilters();
136
+ // console.log("2")
137
+ }
138
+ }
139
+ syncWithLocalStorage(items) {
140
+ return items
141
+ ? items.map((item) => ({
142
+ ...item,
143
+ checked: item.checked === true
144
+ }))
145
+ : [];
146
+ }
147
+ emitAndStoreFilters() {
148
+ this.gs.dataRangeValue.next(this.selectedFilters);
149
+ localStorage.setItem("header-filters", JSON.stringify(this.selectedFilters));
150
+ // console.log("1")
151
+ }
152
+ /**
153
+ * Reset selectedFilters and all related arrays to empty states
154
+ */
155
+ resetFilters() {
156
+ this.selectedFilters = {
157
+ client: null,
158
+ clientName: '',
159
+ clients: [],
160
+ store: null,
161
+ date: {},
162
+ stores: [],
163
+ group: [],
164
+ location: []
165
+ };
166
+ this.filteredLocations = [];
167
+ this.filteredGroups = [];
168
+ this.filteredStores = [];
169
+ }
170
+ getClient() {
171
+ this.auth.getClients().subscribe({
172
+ next: (e) => {
173
+ if (e) {
174
+ this.clientList = e.data.result;
175
+ const headerFilters = JSON.parse(localStorage.getItem("header-filters") || "{}");
176
+ if (headerFilters.client) {
177
+ this.clientList.find((obj) => {
178
+ if (obj.clientId === headerFilters.client) {
179
+ this.selectedClient = obj;
180
+ }
181
+ });
182
+ this.selectedFilters.client = headerFilters.client;
183
+ this.selectedFilters.clientName = headerFilters.clientName;
184
+ this.selectedFilters.clients = headerFilters.clients;
185
+ this.selectedFilters.store = headerFilters.store;
186
+ this.selectedFilters.date = headerFilters.date;
187
+ this.selectedFilters.stores = headerFilters.stores;
188
+ this.selectedFilters.group = headerFilters.group;
189
+ this.selectedFilters.location = headerFilters.location;
190
+ this.gs.dataRangeValue.next(this.selectedFilters);
191
+ // console.log("2")
192
+ // Ensure locations and groups are loaded before fetching stores
193
+ this.getLocations();
194
+ this.getGroups();
195
+ // Fetch stores only after locations and groups are set
196
+ this.getStore();
197
+ }
198
+ else {
199
+ this.selectedClient = this.clientList[0];
200
+ this.selectedFilters.client = this.selectedClient.clientId;
201
+ this.selectedFilters.clientName = this.selectedClient.clientName;
202
+ this.selectedFilters.clients = headerFilters.clients;
203
+ this.selectedFilters.store = headerFilters.store;
204
+ this.selectedFilters.date = headerFilters.date;
205
+ this.selectedFilters.stores = headerFilters.stores;
206
+ this.selectedFilters.group = headerFilters.group;
207
+ this.selectedFilters.location = headerFilters.location;
208
+ localStorage.setItem("header-filters", JSON.stringify(this.selectedFilters));
209
+ this.gs.dataRangeValue.next(this.selectedFilters);
210
+ // console.log("3")
211
+ this.cd.detectChanges();
212
+ // Ensure locations and groups are loaded before fetching stores
213
+ this.getLocations();
214
+ this.getGroups();
215
+ // Fetch stores only after locations and groups are set
216
+ this.getStore();
217
+ }
218
+ }
219
+ else {
220
+ this.selectedClient = this.clientList[0];
221
+ this.selectedFilters.client = this.selectedClient.clientId;
222
+ this.selectedFilters.clientName = this.selectedClient.clientName;
223
+ // Ensure locations and groups are loaded before fetching stores
224
+ this.getLocations();
225
+ this.getGroups();
226
+ // Fetch stores only after locations and groups are set
227
+ this.getStore();
228
+ localStorage.setItem("header-filters", JSON.stringify(this.selectedFilters));
229
+ this.gs.dataRangeValue.next(this.selectedFilters);
230
+ // console.log("4")
231
+ this.cd.detectChanges();
232
+ }
233
+ },
234
+ });
235
+ }
236
+ onClientSelect(event) {
237
+ // Update the selected client
238
+ this.selectedClient = event;
239
+ // Clear previous filtered data and selections
240
+ this.filteredGroups = [];
241
+ this.filteredStores = [];
242
+ this.filteredLocations = [];
243
+ this.selectedFilters.stores = [];
244
+ this.selectedFilters.group = [];
245
+ this.selectedFilters.location = [];
246
+ // Fetch header filters from localStorage
247
+ const headerFilters = JSON.parse(localStorage.getItem("header-filters") || "{}");
248
+ // Update the selected filters with the new client
249
+ this.selectedFilters.client = this.selectedClient.clientId;
250
+ this.selectedFilters.clientName = this.selectedClient.clientName;
251
+ // Remove old store, group, and location data from the header filters
252
+ delete headerFilters.stores;
253
+ delete headerFilters.groups;
254
+ delete headerFilters.location;
255
+ // Fetch new data based on the new client
256
+ this.getLocations();
257
+ this.getStore();
258
+ this.getGroups();
259
+ // Update localStorage with the new client selection and empty filter data
260
+ localStorage.setItem('header-filters', JSON.stringify(this.selectedFilters));
261
+ window.location.reload();
262
+ // Emit data to the global service
263
+ // this.gs.dataRangeValue.next(this.selectedFilters);
264
+ // Trigger change detection to reflect UI changes
265
+ this.cd.detectChanges();
266
+ }
267
+ ranges = {
268
+ Today: [dayjs(), dayjs()],
269
+ Yesterday: [dayjs().subtract(1, 'days'), dayjs().subtract(1, 'days')],
270
+ 'This Week': [dayjs().subtract(7, 'days'), dayjs().subtract(1, 'days')],
271
+ 'Last Week': [
272
+ dayjs().subtract(14, 'days').startOf('day'),
273
+ dayjs().subtract(8, 'days').endOf('day'),
274
+ ],
275
+ 'This Month': [dayjs().subtract(30, 'days'), dayjs().subtract(1, 'days')],
276
+ 'Last Month': [
277
+ dayjs().subtract(1, 'month').startOf('month'),
278
+ dayjs().subtract(1, 'month').endOf('month'),
279
+ ],
280
+ };
281
+ onStartDateChange(event) {
282
+ if (this.dayjs(event.startDate).isValid()) {
283
+ this.isCustomDate = (m) => {
284
+ const isValidDate = m > this.dayjs() || m > this.dayjs(event.startDate.add(90, "days"));
285
+ return isValidDate ? "invalid-date" : false;
286
+ };
287
+ }
288
+ }
289
+ datechange(event) {
290
+ if (event && event.startDate && event.endDate) {
291
+ if (this.dayjs(event.startDate).isValid() &&
292
+ this.dayjs(event.endDate).isValid()) {
293
+ this.selectedDateRange.startDate = event.startDate;
294
+ this.selectedDateRange.endDate = event.endDate;
295
+ var datetime = {
296
+ startDate: this.dayjs(event.startDate, "DD-MM-YYYY").format("YYYY-MM-DD"),
297
+ endDate: this.dayjs(event.endDate, "DD-MM-YYYY").format("YYYY-MM-DD"),
298
+ };
299
+ this.selectedFilters.date = datetime;
300
+ localStorage.setItem("header-filters", JSON.stringify(this.selectedFilters));
301
+ window.location.reload();
302
+ // this.gs.dataRangeValue.next(this.selectedFilters);
303
+ }
304
+ }
305
+ }
306
+ opendropdown(e) {
307
+ e.stopPropagation();
308
+ this.Opendropdown = !this.Opendropdown;
309
+ }
310
+ getLocations() {
311
+ // const headerFilters: any = JSON.parse(localStorage.getItem("header-filters") || "{}");
312
+ let obj = {
313
+ clientId: this.selectedFilters.client ? this.selectedFilters.client : this.users.clientId,
314
+ city: [],
315
+ group: [],
316
+ };
317
+ this.auth.getLocation(obj).subscribe({
318
+ next: (res) => {
319
+ let cityList = this.selectedFilters?.location?.filter((location) => location.checked).map((loc) => loc.city);
320
+ // Map the fetched locations with default unchecked state
321
+ this.locations = res?.data?.locationData.map((city) => ({
322
+ city: city.city,
323
+ checked: cityList?.includes(city.city) ? true : false,
324
+ }));
325
+ // Sync the fetched locations with any stored checked values in localStorage
326
+ if (this.selectedFilters.location && Array.isArray(this.selectedFilters.location)) {
327
+ this.filteredLocations = this.locations.map(location => {
328
+ const matchedLocation = this.selectedFilters.location.find((loc) => loc.city === location.city);
329
+ return matchedLocation ? { ...location, checked: matchedLocation.checked } : location;
330
+ });
331
+ }
332
+ else {
333
+ this.filteredLocations = this.locations;
334
+ }
335
+ if (this.searchLocationText) {
336
+ this.filteredLocations = this.locations.filter((location) => location.city.toLowerCase().includes(this.searchLocationText.toLowerCase()));
337
+ }
338
+ },
339
+ error: (err) => {
340
+ console.error("Failed to fetch locations", err);
341
+ },
342
+ });
343
+ }
344
+ isAllLocationsSelected() {
345
+ return this.filteredLocations.every(location => location.checked);
346
+ }
347
+ selectedLocationsLabel() {
348
+ const selectedLocations = this.locationLabel = this.searchLocationText.length ? this.locations
349
+ .filter(location => location.checked).map(location => location.city) : this.filteredLocations
350
+ .filter(location => location.checked).map(location => location.city);
351
+ return selectedLocations.length === 0
352
+ ? ''
353
+ : selectedLocations.length === 1
354
+ ? selectedLocations[0]
355
+ : `${selectedLocations.length} locations`;
356
+ }
357
+ removeLocation() {
358
+ this.Reset();
359
+ }
360
+ getGroups() {
361
+ const city = this.locations
362
+ .filter(location => location.checked)
363
+ .map(location => location.city);
364
+ const obj = { city, clientId: this.selectedFilters.client ? this.selectedFilters.client : this.users.clientId, group: [] };
365
+ this.auth.getGroups(obj).subscribe({
366
+ next: (res) => {
367
+ let checkedGroup = this.selectedFilters?.group?.filter((group) => group.checked).map((group) => group.groupName);
368
+ const combinedGroups = res?.data?.groupData?.map((groupName) => ({
369
+ groupName: groupName.groupName,
370
+ checked: checkedGroup?.includes(groupName.groupName) ? true : false,
371
+ }));
372
+ this.groupsData = combinedGroups;
373
+ if (this.searchGroupText.length) {
374
+ this.filteredGroups = combinedGroups.filter((item) => item.groupName.toLowerCase().includes(this.searchGroupText));
375
+ }
376
+ else {
377
+ this.filteredGroups = combinedGroups;
378
+ }
379
+ // Auto-fetch stores when groups are selected
380
+ const selectedGroups = this.groupsData.filter((group) => group.checked).map((group) => group.groupName);
381
+ if (selectedGroups.length > 0) {
382
+ this.getStore(); // Fetch stores based on selected groups
383
+ }
384
+ },
385
+ error: (err) => {
386
+ console.error("Failed to fetch groups", err);
387
+ },
388
+ });
389
+ }
390
+ toggleDropdown(type) {
391
+ if (this.dropdownOpen === type) {
392
+ // If the dropdown is open, close it and avoid resetting the selected values unnecessarily
393
+ this.dropdownOpen = null;
394
+ }
395
+ else {
396
+ // Open the specific dropdown and handle data fetching only if necessary
397
+ this.dropdownOpen = type;
398
+ if (type === 'group') {
399
+ // Fetch groups only if there are selected cities and no active search text
400
+ const selectedCities = this.locations
401
+ .filter((location) => location.checked)
402
+ .map((location) => location.city);
403
+ // Fetch groups only if locations are selected, no search text exists, and dropdown is opened
404
+ if (this.filteredLocations.length > 0 || (selectedCities.length > 0 && !this.searchGroupText.trim())) {
405
+ this.getGroups();
406
+ }
407
+ else {
408
+ this.filteredGroups = []; // Clear groups if no locations are selected
409
+ }
410
+ }
411
+ if (type === 'store') {
412
+ // Fetch stores only if not already fetched and no search text is active
413
+ if ((!this.filteredStores || this.filteredStores.length === 0) && !this.searchStoreText.trim()) {
414
+ this.getStore();
415
+ }
416
+ }
417
+ }
418
+ }
419
+ handleGroupDropdownClick() {
420
+ if (this.dropdownOpen === 'group') {
421
+ this.resetSelectedGroups();
422
+ }
423
+ this.toggleDropdown('group');
424
+ }
425
+ resetSelectedGroups() {
426
+ this.filteredGroups.forEach((group) => (group.checked = false));
427
+ this.searchGroupText = "";
428
+ }
429
+ selectedGroupsLabel() {
430
+ const selectedGroups = this.groupLabel = this.searchGroupText.length ? this.groupsData.filter((group) => group.checked) : this.filteredGroups.filter((group) => group.checked);
431
+ return selectedGroups.length === 0
432
+ ? ""
433
+ : selectedGroups.length === 1
434
+ ? selectedGroups[0].groupName
435
+ : `${selectedGroups.length} groups`;
436
+ }
437
+ removeGroup() {
438
+ this.Reset();
439
+ }
440
+ isAllGroupsSelected() {
441
+ return this.filteredGroups.length ? this.filteredGroups.every((group) => group.checked) : false;
442
+ }
443
+ getStore() {
444
+ const city = this.locations
445
+ .filter(location => location.checked)
446
+ .map(location => location.city);
447
+ const group = this.groupsData
448
+ .filter(group => group.checked)
449
+ .map(group => group.groupName);
450
+ const data = { city, clusters: group, clientId: this.users.clientId ? this.users.clientId : this.selectedFilters.client };
451
+ this.auth.getHeaderStores(data).subscribe({
452
+ next: (res) => {
453
+ if (res && res.code === 200) {
454
+ this.stores = res.data.storesData;
455
+ // Retrieve checked store IDs from selectedFilters
456
+ const checkedStoreIds = this.selectedFilters?.stores
457
+ ? this.selectedFilters.stores.filter((store) => store.checked).map((store) => store.storeId)
458
+ : [];
459
+ this.stores.forEach(store => {
460
+ if (checkedStoreIds.includes(store.storeId)) {
461
+ store.checked = true; // Sync the checked state with full store list
462
+ }
463
+ });
464
+ // Map the stores and retain the 'checked' status
465
+ if (this.searchStoreText.length) {
466
+ this.filteredStores = this.stores?.filter(store => store.storeName.toLowerCase().includes(this.searchStoreText));
467
+ }
468
+ else {
469
+ this.filteredStores = this.stores;
470
+ }
471
+ // Ensure selectedFilters is in sync with filteredStores
472
+ if (!this.selectedFilters.stores || !this.selectedFilters.stores.length) {
473
+ this.stores.forEach(store => {
474
+ store.checked = true; // Sync the checked state with full store list
475
+ });
476
+ // No previously selected stores, mark all as checked
477
+ this.filteredStores = this.selectedFilters.stores = this.filteredStores.map(store => ({
478
+ ...store,
479
+ checked: true
480
+ }));
481
+ }
482
+ else {
483
+ // Update selectedFilters to reflect current state of stores
484
+ this.selectedFilters.stores = this.filteredStores.map(store => ({
485
+ ...store,
486
+ checked: store.checked
487
+ }));
488
+ }
489
+ // Update localStorage with the latest selectedFilters
490
+ localStorage.setItem('header-filters', JSON.stringify(this.selectedFilters));
491
+ // Emit data via service
492
+ // this.gs.dataRangeValue.next(this.selectedFilters);
493
+ // Trigger change detection to reflect changes in the UI
494
+ this.cd.detectChanges();
495
+ }
496
+ else {
497
+ this.stores = [];
498
+ this.selectedFilters.stores = [];
499
+ this.filteredStores = [];
500
+ this.selectedFilters.stores = this.filteredStores.map(store => ({
501
+ ...store,
502
+ checked: false
503
+ }));
504
+ localStorage.setItem('header-filters', JSON.stringify(this.selectedFilters));
505
+ }
506
+ },
507
+ error: (err) => {
508
+ this.stores = [];
509
+ this.selectedFilters.stores = this.filteredStores.map(store => ({
510
+ ...store,
511
+ checked: false
512
+ }));
513
+ this.filteredStores = [];
514
+ this.selectedFilters.stores = [];
515
+ localStorage.setItem('header-filters', JSON.stringify(this.selectedFilters));
516
+ console.error("Failed to fetch stores", err);
517
+ },
518
+ });
519
+ }
520
+ resetSelectedStores() {
521
+ this.filteredStores.forEach((store) => (store.checked = false));
522
+ this.searchStoreText = "";
523
+ }
524
+ selectedStoresLabel() {
525
+ const selectedStores = this.searchStoreText.length ? this.stores.filter((store) => store.checked) : this.filteredStores.filter((store) => store.checked);
526
+ return selectedStores.length === 0
527
+ ? "0 Stores"
528
+ : selectedStores.length === 1
529
+ ? selectedStores[0].storeName
530
+ : `${selectedStores.length} Stores`;
531
+ }
532
+ isAllStoresSelected() {
533
+ return this.filteredStores.length > 0 && this.filteredStores.every(store => store.checked);
534
+ }
535
+ // Method to handle dropdown item selection
536
+ updateSelectedStores() {
537
+ this.filteredStores.forEach(store => {
538
+ const filteredStore = this.stores.findIndex(fStore => fStore.storeId === store.storeId);
539
+ if (filteredStore != -1) {
540
+ this.stores[filteredStore].checked = store.checked; // Sync the checked state with full store list
541
+ }
542
+ });
543
+ // Update selectedFilters based on the current store selection
544
+ this.selectedFilters.stores = this.stores.filter(store => store.checked);
545
+ // Update localStorage with the latest selection
546
+ localStorage.setItem('header-filters', JSON.stringify(this.selectedFilters));
547
+ // Emit updated filters via service
548
+ // this.gs.dataRangeValue.next(this.selectedFilters);
549
+ // Trigger change detection if necessary
550
+ this.cd.detectChanges();
551
+ }
552
+ toggleSelectAllLocations(event) {
553
+ const isChecked = event.target.checked;
554
+ this.filteredLocations.forEach((location) => (location.checked = isChecked));
555
+ this.updateSelectedLocations();
556
+ }
557
+ toggleSelectAllStores(event) {
558
+ const checked = event.target.checked;
559
+ // Apply the selection to both filtered and full list of stores
560
+ this.filteredStores.forEach(store => store.checked = checked);
561
+ this.stores.forEach(store => {
562
+ const filteredStore = this.filteredStores.find(fStore => fStore.storeId === store.storeId);
563
+ if (filteredStore) {
564
+ store.checked = checked; // Sync the checked state with full store list
565
+ }
566
+ });
567
+ // Update the selected stores and persist the selection
568
+ this.updateSelectedStores();
569
+ }
570
+ updateSelectedLocations() {
571
+ // When locations are selected, fetch the related groups
572
+ const selectedCities = this.filteredLocations
573
+ .filter((location) => location.checked)
574
+ .map((location) => location.city);
575
+ this.filteredLocations.forEach((location) => {
576
+ let findLocationIndex = this.locations.findIndex((loc) => loc.city == location.city);
577
+ if (findLocationIndex != -1) {
578
+ this.locations[findLocationIndex].checked = location.checked;
579
+ }
580
+ });
581
+ if (selectedCities.length > 0 || !selectedCities.length) {
582
+ this.selectedFilters.stores = [];
583
+ this.selectedFilters.location = this.locations;
584
+ this.getGroups(); // Fetch groups based on selected cities
585
+ // If there are selected groups, fetch the stores based on selected groups
586
+ this.getStore();
587
+ }
588
+ else {
589
+ this.filteredGroups = []; // Clear groups if no locations are selected
590
+ this.selectedFilters.location = [];
591
+ }
592
+ this.selectedFilters.group = [];
593
+ this.filteredStores = []; // Reset stores as well
594
+ this.searchGroupText = '';
595
+ this.searchStoreText = '';
596
+ // this.Opendropdown = false;
597
+ }
598
+ toggleSelectAllGroups(event) {
599
+ const isChecked = event.target.checked;
600
+ this.filteredGroups.forEach((group) => (group.checked = isChecked));
601
+ this.updateSelectedGroups();
602
+ // if (!isChecked) {
603
+ // this.selectedFilters.stores =[];
604
+ // // If there are selected groups, fetch the stores based on selected groups
605
+ // this.getStore();
606
+ // }
607
+ }
608
+ updateSelectedGroups() {
609
+ // Fetch the relevant stores after groups are selected
610
+ const selectedGroups = this.filteredGroups
611
+ .filter((group) => group.checked)
612
+ .map((group) => group.groupName);
613
+ this.filteredGroups.forEach((group) => {
614
+ let findGroupIndex = this.groupsData.findIndex((item) => item.groupName == group.groupName);
615
+ if (findGroupIndex != -1) {
616
+ this.groupsData[findGroupIndex].checked = group.checked;
617
+ }
618
+ });
619
+ if (selectedGroups.length > 0 || !selectedGroups.length) {
620
+ this.selectedFilters.stores = [];
621
+ // If there are selected groups, fetch the stores based on selected groups
622
+ this.getStore();
623
+ this.selectedFilters.group = this.groupsData;
624
+ }
625
+ else {
626
+ // If no groups are selected, clear the stores list
627
+ this.filteredStores = [];
628
+ // Also, update localStorage to reflect the cleared store selection
629
+ this.selectedFilters.stores = [];
630
+ localStorage.setItem('header-filters', JSON.stringify(this.selectedFilters));
631
+ // Emit data via service
632
+ // this.gs.dataRangeValue.next(this.selectedFilters);
633
+ }
634
+ // Clear the search store text when groups are updated
635
+ this.searchStoreText = '';
636
+ }
637
+ Reset() {
638
+ // Clear selected groups, stores, and locations
639
+ this.filteredGroups = [];
640
+ this.filteredStores = [];
641
+ this.filteredLocations = []; // Reset locations as well
642
+ // Clear search input fields
643
+ this.searchLocationText = "";
644
+ this.searchGroupText = "";
645
+ this.searchStoreText = "";
646
+ // Fetch locations, groups, and stores again
647
+ this.getLocations();
648
+ this.getStore();
649
+ this.getGroups();
650
+ // Reset the filters in selectedFilters
651
+ this.selectedFilters = {
652
+ ...this.selectedFilters,
653
+ stores: [],
654
+ group: [],
655
+ location: [] // Clear locations selection
656
+ };
657
+ // // Once stores are fetched, mark all as checked
658
+ // setTimeout(() => {
659
+ // this.filteredStores = this.stores.map(store => ({
660
+ // ...store,
661
+ // checked: true // Mark all stores as checked
662
+ // }));
663
+ // // Sync selectedFilters with the updated store state
664
+ // this.selectedFilters.stores = this.filteredStores.map(store => ({
665
+ // ...store,
666
+ // checked: true
667
+ // }));
668
+ // Update localStorage with the latest selectedFilters
669
+ localStorage.setItem('header-filters', JSON.stringify(this.selectedFilters));
670
+ window.location.reload();
671
+ // Emit the reset filters to update other components if needed
672
+ // this.gs.dataRangeValue.next(this.selectedFilters);
673
+ // Trigger change detection
674
+ this.cd.detectChanges();
675
+ // Adding a slight delay to ensure stores are fetched first
676
+ // Close dropdown after reset if necessary
677
+ this.Opendropdown = false;
678
+ }
679
+ Apply() {
680
+ // Close the dropdown
681
+ this.Opendropdown = false;
682
+ // Fetch existing filters from localStorage
683
+ const headerFilters = JSON.parse(localStorage.getItem("header-filters") || "{}");
684
+ this.selectedFilters.store = null;
685
+ // Ensure current selections are reflected
686
+ this.selectedFilters.location = this.locations;
687
+ this.selectedFilters.group = this.groupsData;
688
+ this.selectedFilters.stores = headerFilters.stores ? headerFilters.stores : this.stores;
689
+ // Store updated filters back in localStorage
690
+ localStorage.setItem("header-filters", JSON.stringify(this.selectedFilters));
691
+ window.location.reload();
692
+ // Emit the updated filters via the service
693
+ // this.gs.dataRangeValue.next(this.selectedFilters);
694
+ // Trigger refresh if necessary
695
+ // this.gs.manageRefreshTrigger.next(true);
696
+ this.cd.detectChanges();
697
+ }
698
+ filterLocations() {
699
+ const searchText = this.searchLocationText.toLowerCase();
700
+ if (searchText) {
701
+ // Preserve the checked state during filtering
702
+ this.filteredLocations = this.locations
703
+ .map(location => ({
704
+ ...location,
705
+ checked: this.filteredLocations.find(l => l.city === location.city)?.checked || false
706
+ }))
707
+ .filter(location => location?.city?.toLowerCase().includes(searchText));
708
+ }
709
+ else {
710
+ // Restore the original checked state when search text is cleared
711
+ this.filteredLocations = this.locations.map(location => ({
712
+ ...location,
713
+ checked: this.selectedFilters.location.find((l) => l.city === location.city)?.checked || false
714
+ }));
715
+ }
716
+ }
717
+ filterGroups() {
718
+ const searchText = this.searchGroupText.toLowerCase();
719
+ if (searchText) {
720
+ // Preserve the checked state during filtering
721
+ this.filteredGroups = this.groupsData
722
+ .map(group => ({
723
+ ...group,
724
+ checked: this.filteredGroups.find(g => g.groupName === group.groupName)?.checked || false
725
+ }))
726
+ .filter(group => group?.groupName?.toLowerCase().includes(searchText));
727
+ }
728
+ else {
729
+ // Restore the original checked state when search text is cleared
730
+ this.filteredGroups = this.groupsData.map(group => ({
731
+ ...group,
732
+ checked: this.selectedFilters.group.find((g) => g.groupName === group.groupName)?.checked || false
733
+ }));
734
+ }
735
+ }
736
+ filterStores() {
737
+ const searchText = this.searchStoreText.toLowerCase();
738
+ // Preserve checked states during filtering
739
+ if (searchText) {
740
+ // Filter based on search text while preserving checked state
741
+ this.filteredStores = this.stores
742
+ .map(store => ({
743
+ ...store,
744
+ // Check if the store is already checked in filteredStores, fallback to original stores' checked state
745
+ checked: this.selectedFilters.stores.find((s) => s.storeId === store.storeId)?.checked || store.checked || false
746
+ }))
747
+ .filter(store => store.storeName.toLowerCase().includes(searchText));
748
+ }
749
+ else {
750
+ // When the search text is cleared, restore the original list with preserved checked states
751
+ this.filteredStores = this.stores.map(store => ({
752
+ ...store,
753
+ // Preserve the checked state based on the selected filters
754
+ checked: this.selectedFilters.stores.find((s) => s.storeId === store.storeId)?.checked || store.checked || false
755
+ }));
756
+ }
757
+ }
758
+ closeDropdown() {
759
+ this.dropdownOpen = null;
760
+ }
761
+ clickOutside(event) {
762
+ const clickedInside = event.target.closest(".dropdown-container");
763
+ const clickedoutSide = event.target.closest(".dropdown1");
764
+ if (!clickedInside) {
765
+ this.closeDropdown();
766
+ }
767
+ if (!clickedoutSide) {
768
+ this.closeDropdown1();
769
+ }
770
+ }
771
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TrafficNobComponent, deps: [{ token: i1.AuthService }, { token: i2.Router }, { token: i3.GlobalStateService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
772
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: TrafficNobComponent, selector: "lib-traffic-nob", host: { listeners: { "document:click": "clickOutside($event)" } }, ngImport: i0, template: "<div class=\"me-3\">\r\n <label *ngIf=\"selectedLocationsLabel()\" class=\"badge badge-light-default mx-2\">{{selectedLocationsLabel()}} \r\n <span class=\"cursor-pointer\" (click)=\"removeLocation()\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\">\r\n <path d=\"M9 3L3 9M3 3L9 9\" stroke=\"#667085\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n </svg></span>\r\n </label>\r\n <label *ngIf=\"selectedGroupsLabel()\" class=\"badge badge-light-default mx-2\">{{selectedGroupsLabel()}} \r\n <span class=\"cursor-pointer\" (click)=\"removeGroup()\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\">\r\n <path d=\"M9 3L3 9M3 3L9 9\" stroke=\"#667085\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n </svg></span>\r\n </label>\r\n <label class=\"badge badge-light-default\">{{selectedStoresLabel()}}</label>\r\n</div>\r\n\r\n<div class=\"d-flex align-items-center position-relative my-1\">\r\n <span class=\"svg-icon svg-icon-1 position-absolute ms-3\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path\r\n d=\"M13.3333 1.66663V4.99996M6.66667 1.66663V4.99996M2.5 8.33329H17.5M4.16667 3.33329H15.8333C16.7538 3.33329 17.5 4.07948 17.5 4.99996V16.6666C17.5 17.5871 16.7538 18.3333 15.8333 18.3333H4.16667C3.24619 18.3333 2.5 17.5871 2.5 16.6666V4.99996C2.5 4.07948 3.24619 3.33329 4.16667 3.33329Z\"\r\n stroke=\"#344054\" stroke-width=\"1.67\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </span>\r\n <input class=\"fx-date-range form-control ps-14\" style=\"min-width: 260px !important;\" type=\"text\" matInput\r\n ngxDaterangepickerMd [drops]=\"'down'\" [opens]=\"'right'\" [ranges]=\"ranges\" [showCustomRangeLabel]=\"true\" [autoApply]=\"true\"\r\n [alwaysShowCalendars]=\"false\" [keepCalendarOpeningWithRange]=\"true\" [showCancel]=\"true\" autocomplete=\"off\"\r\n [(ngModel)]=\"selectedDateRange\" (startDateChanged)=\"onStartDateChange($event)\" [isCustomDate]=\"isCustomDate\"\r\n [locale]=\"{ format: 'DD-MM-YYYY', firstDay: 1, monthNames: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] }\"\r\n (datesUpdated)=\"datechange($event)\" name=\"daterange\" [readonly]=\"true\" />\r\n</div>\r\n<div class=\"position-relative\">\r\n <button type=\"button\" (click)=\"opendropdown($event)\" class=\"btn btn-default mx-2 rounded-3 text-nowrap border-val\">\r\n <!-- <span class=\"me-2\">Filter</span> -->\r\n <svg class=\"pl-3\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M5 10H15M2.5 5H17.5M7.5 15H12.5\" stroke=\"#344054\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </button>\r\n\r\n <div *ngIf=\"Opendropdown\" class=\"card p-5 dropdown1 position-absolute z-1 end-0\" style=\"z-index: 1 !important;\" (clickOutside)=\"closeDropdown1()\">\r\n <div class=\"dropdown-title d-flex justify-content-between mb-2\">Filter Options\r\n <button class=\"btn btn-outline w-25 ms-3 btn-resize\" (click)=\"Reset()\"> Reset </button>\r\n <button class=\"btn btn-primary w-25 btn-resize\" (click)=\"Apply()\">Apply</button>\r\n </div>\r\n\r\n <!-- Location Dropdown -->\r\n<div class=\"dropdown-container\" (clickOutside)=\"closeDropdown()\">\r\n <div class=\"dropdown-header\">\r\n <input \r\n type=\"text\" \r\n class=\"form-control dropdown-input cursor-pointer\" \r\n [value]=\"selectedLocationsLabel()\"\r\n (focus)=\"toggleDropdown('location')\" \r\n readonly\r\n placeholder=\"Select locations...\"\r\n />\r\n </div>\r\n <div class=\"dropdown-menu custom-dropdown-menu\" *ngIf=\"dropdownOpen === 'location'\">\r\n <input \r\n type=\"text\" \r\n class=\"form-control mb-2 dropdown-search\" \r\n placeholder=\"Search locations...\" \r\n [(ngModel)]=\"searchLocationText\" \r\n (ngModelChange)=\"filterLocations()\" \r\n />\r\n <div class=\"form-check mb-2 dropdown-item custom-dropdown-item\">\r\n <input \r\n class=\"form-check-input cursor-pointer\" \r\n type=\"checkbox\" \r\n id=\"selectAllLocations\" \r\n [checked]=\"isAllLocationsSelected()\" \r\n (change)=\"toggleSelectAllLocations($event)\" \r\n />\r\n <label class=\"form-check-label\" for=\"selectAllLocations\">\r\n Select All Locations\r\n </label>\r\n </div>\r\n <div \r\n class=\"dropdown-item form-check custom-dropdown-item\" \r\n *ngFor=\"let location of filteredLocations\"\r\n >\r\n <input \r\n class=\"form-check-input cursor-pointer\" \r\n type=\"checkbox\" \r\n [id]=\"location.city\" \r\n [(ngModel)]=\"location.checked\"\r\n (change)=\"updateSelectedLocations()\" \r\n />\r\n <label class=\"form-check-label\" [for]=\"location.city\">\r\n {{ location.city }}\r\n </label>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Group Dropdown -->\r\n<div class=\"dropdown-container mt-3\" (clickOutside)=\"closeDropdown()\">\r\n <div class=\"dropdown-header\" (click)=\"toggleDropdown('group')\">\r\n <input \r\n type=\"text\" \r\n class=\"form-control dropdown-input cursor-pointer\" \r\n [value]=\"selectedGroupsLabel()\" readonly\r\n placeholder=\"Select clusters..\"\r\n />\r\n </div>\r\n <div class=\"dropdown-menu custom-dropdown-menu\" *ngIf=\"dropdownOpen === 'group'\">\r\n <input \r\n type=\"text\" \r\n class=\"form-control mb-2 dropdown-search\" \r\n placeholder=\"Search clusters...\" \r\n [(ngModel)]=\"searchGroupText\" \r\n (ngModelChange)=\"filterGroups()\" \r\n />\r\n <div class=\"form-check mb-2 dropdown-item custom-dropdown-item\">\r\n <input \r\n class=\"form-check-input cursor-pointer\" \r\n type=\"checkbox\" \r\n id=\"selectAllGroups\" \r\n [checked]=\"isAllGroupsSelected()\" \r\n (change)=\"toggleSelectAllGroups($event)\" \r\n />\r\n <label class=\"form-check-label\" for=\"selectAllGroups\">\r\n Select All\r\n </label>\r\n </div>\r\n <div \r\n class=\"dropdown-item form-check custom-dropdown-item\" \r\n *ngFor=\"let group of filteredGroups\"\r\n >\r\n <input \r\n class=\"form-check-input cursor-pointer\" \r\n type=\"checkbox\" \r\n [id]=\"group.groupName\"\r\n [(ngModel)]=\"group.checked\"\r\n (change)=\"updateSelectedGroups()\" \r\n />\r\n <label class=\"form-check-label\" [for]=\"group.groupName\">\r\n {{ group.groupName }}\r\n </label>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n\r\n<!-- Store Dropdown -->\r\n<div class=\"dropdown-container mt-3\" (clickOutside)=\"closeDropdown()\">\r\n <div class=\"dropdown-header\" (click)=\"toggleDropdown('store')\">\r\n <input \r\n type=\"text\" \r\n class=\"form-control dropdown-input cursor-pointer\"\r\n [value]=\"selectedStoresLabel()\"\r\n readonly\r\n placeholder=\"Select stores...\"\r\n />\r\n </div>\r\n <div class=\"dropdown-menu custom-dropdown-menu\" *ngIf=\"dropdownOpen === 'store'\">\r\n <input \r\n type=\"text\" \r\n class=\"form-control mb-2 dropdown-search \" \r\n placeholder=\"Search stores...\" \r\n [(ngModel)]=\"searchStoreText\" \r\n (ngModelChange)=\"filterStores()\" \r\n />\r\n <div class=\"form-check mb-2 dropdown-item custom-dropdown-item\">\r\n <input \r\n class=\"form-check-input cursor-pointer\" \r\n type=\"checkbox\" \r\n id=\"selectAllStores\" \r\n [checked]=\"isAllStoresSelected()\" \r\n (change)=\"toggleSelectAllStores($event)\" \r\n />\r\n <label class=\"form-check-label\" for=\"selectAllStores\">\r\n Select All\r\n </label>\r\n </div>\r\n <div \r\n class=\"dropdown-item form-check custom-dropdown-item\" \r\n *ngFor=\"let store of filteredStores\"\r\n >\r\n <input \r\n class=\"form-check-input\" \r\n type=\"checkbox\" \r\n [id]=\"store.storeId\"\r\n [(ngModel)]=\"store.checked\"\r\n (change)=\"updateSelectedStores()\" \r\n />\r\n <label class=\"form-check-label\" [for]=\"store.storeId\">\r\n {{ store.storeName }}\r\n </label>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n </div>\r\n</div>", styles: [".daterangepicker{display:block!important;top:153.85px!important;left:900px!important;right:0}.form-control{color:var(--Gray-700, #344054)!important;font-size:14px!important;font-weight:600;line-height:20px;text-transform:capitalize}::ng-deep .applyBtn{display:none!important}:host::ng-deep .md-drppicker .btn{line-height:10px!important}:host::ng-deep .daterangepicker-input+.ngx-daterangepicker-material .applyBtn{display:none}:host::ng-deep .md-drppicker.drops-down-right.ltr.double.show-ranges.shown{top:65px!important;left:-470px!important;height:365px!important}:host::ng-deep .md-drppicker .btn{border-radius:8px!important;border:1px solid var(--Primary-600, #00A3FF)!important;background:var(--Primary-600, #00A3FF)!important;box-shadow:0 1px 2px #1018280d!important;color:var(--White, #FFF)!important;font-size:14px!important;font-weight:600!important;line-height:20px;text-transform:capitalize}:host::ng-deep .md-drppicker .ranges ul li button{padding:12px 16px;width:160px;color:var(--Gray-700, #344054);font-size:14px;font-weight:400;line-height:20px;background:none;border:none;text-align:left;cursor:pointer}:host::ng-deep .md-drppicker td.active,:host::ng-deep .md-drppicker td.active:hover{background-color:#029cf4!important;border-radius:20px!important;color:var(--White, #FFF)!important;text-align:center!important;font-size:14px!important;font-weight:500!important;line-height:20px}:host::ng-deep .md-drppicker.ltr .ranges{float:left;margin-top:10px!important}:host::ng-deep .md-drppicker td.in-range{background:var(--Primary-50, #EAF8FF)}:host::ng-deep .md-drppicker .ranges ul li button.active{background:var(--Primary-50, #EAF8FF)!important;border-radius:8px!important;color:var(--Primary-700, #009BF3);font-size:14px!important;font-weight:500!important;line-height:20px!important}:host::ng-deep table th,:host::ng-deep table td{width:40px!important;height:40px!important;padding:10px 8px!important}:host::ng-deep .md-drppicker td.available.prev,:host::ng-deep .md-drppicker th.available.prev{background-image:url(data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgMy43IDYiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDMuNyA2IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxnPg0KCTxwYXRoIGQ9Ik0zLjcsMC43TDEuNCwzbDIuMywyLjNMMyw2TDAsM2wzLTNMMy43LDAuN3oiLz4NCjwvZz4NCjwvc3ZnPg0K)!important;background-repeat:no-repeat!important;background-size:.5em!important;background-position:center!important}:host::ng-deep .md-drppicker td.available.next,:host::ng-deep .md-drppicker th.available.next{background-image:url(data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgMy43IDYiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDMuNyA2IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxnPg0KCTxwYXRoIGQ9Ik0zLjcsMC43TDEuNCwzbDIuMywyLjNMMyw2TDAsM2wzLTNMMy43LDAuN3oiLz4NCjwvZz4NCjwvc3ZnPg0K)!important;background-repeat:no-repeat!important;background-size:.5em!important;background-position:center!important}:host::ng-deep table th{border-bottom:0px solid var(--Gray-200, #EAECF0)!important;background:transparent!important;color:var(--Gray-700, #344054)!important;text-align:center;font-size:16px!important;font-weight:500!important;line-height:24px}:host::ng-deep .md-drppicker .btn.btn-default{border-radius:8px!important;border:1px solid var(--Gray-300, #D0D5DD)!important;background:var(--White, #FFF)!important;box-shadow:0 1px 2px #1018280d!important;color:var(--Gray-700, #344054)!important;font-size:14px!important;font-weight:600!important;line-height:20px;text-transform:capitalize;margin-right:10px!important}:host::ng-deep .md-drppicker td.available.invalid-date{text-decoration:line-through;pointer-events:none;color:#a9a9a9}:host::ng-deep .md-drppicker td.available.today:not(.invalid-date){text-decoration:unset;pointer-events:unset;color:unset}.wrapper{min-width:200px}.btn-primary{line-height:18px!important}.filter-label{color:var(--Gray-500, #667085)!important;font-size:14px;font-style:normal;font-weight:600;line-height:20px;text-transform:capitalize}.position-relative{position:relative}.filter-icon{cursor:pointer}.dropdown-container{position:relative;display:inline-block;width:100%}.dropdown-header{cursor:pointer;width:100%}.form-control{color:var(--Gray-700, #344054)!important;font-size:14px!important;font-weight:600;line-height:20px;text-transform:capitalize;width:100%;box-sizing:border-box}.dropdown-menu{position:absolute;top:100%;left:0;right:0;border:1px solid #ccc;background-color:#fff;z-index:1000;max-height:230px;overflow-y:auto;display:block;box-sizing:border-box;padding:10px 5px}.dropdown-item{padding:6px 0}.dropdown-item:hover{background-color:#f1f1f1}.dropdown-item input[type=checkbox]{margin-right:10px}.custom-dropdown-menu{border-radius:4px;box-shadow:0 1px 2px #1018280d}.custom-dropdown-item{display:flex;align-items:center}.custom-dropdown-item input{margin-left:10px}.btn-resize{font-size:13px!important;height:29px!important;line-height:11px!important;padding:3px!important}.dropdown1{position:absolute;top:70px;min-width:270px!important}.dropdown1 .dropdown-title{color:var(--Gray-900, #101828);font-size:14px;font-weight:600;line-height:24px}.dropdown1 .dropdown{position:relative;display:inline-block}.dropdown1 .dropdown span{color:var(--Gray-700, #344054);font-size:14px;font-weight:600;line-height:20px}::ng-deep .dropdown1{z-index:1!important}.form-check-label{color:var(--Gray-700, #344054)!important;font-size:14px;font-style:normal;font-weight:500;line-height:20px}input[type=checkbox]{width:16px!important;height:16px!important;margin:0 5px;border-radius:4px!important;-webkit-appearance:none;-moz-appearance:none;-o-appearance:none;appearance:none;outline:1px solid var(--gray-300, #D0D5DD);box-shadow:none;font-size:.8em;text-align:center;line-height:1em;background:#fff}input[type=checkbox]:checked{outline:1px solid var(--primary-600, #00A3FF);background-color:var(--primary-50, #EAF8FF)}input[type=checkbox]:checked:after{content:\"\";transform:rotate(45deg);border-bottom:2px solid #00A3FF;border-right:2px solid #00A3FF;display:inline-block;width:.2em;padding-left:0;padding-top:9px;padding-right:4px}\n"], dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i5.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i5.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i5.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i5.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i6.DaterangepickerDirective, selector: "input[ngxDaterangepickerMd]", inputs: ["minDate", "maxDate", "autoApply", "alwaysShowCalendars", "showCustomRangeLabel", "linkedCalendars", "dateLimit", "singleDatePicker", "showWeekNumbers", "showISOWeekNumbers", "showDropdowns", "isInvalidDate", "isCustomDate", "isTooltipDate", "showClearButton", "customRangeDirection", "ranges", "opens", "drops", "firstMonthDayClass", "lastMonthDayClass", "emptyWeekRowClass", "emptyWeekColumnClass", "firstDayOfNextMonthClass", "lastDayOfPreviousMonthClass", "keepCalendarOpeningWithRange", "showRangeLabelOnInput", "showCancel", "lockStartDate", "timePicker", "timePicker24Hour", "timePickerIncrement", "timePickerSeconds", "closeOnAutoApply", "endKeyHolder", "startKey", "locale", "endKey"], outputs: ["change", "rangeClicked", "datesUpdated", "startDateChanged", "endDateChanged", "clearClicked"] }] });
773
+ }
774
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TrafficNobComponent, decorators: [{
775
+ type: Component,
776
+ args: [{ selector: 'lib-traffic-nob', template: "<div class=\"me-3\">\r\n <label *ngIf=\"selectedLocationsLabel()\" class=\"badge badge-light-default mx-2\">{{selectedLocationsLabel()}} \r\n <span class=\"cursor-pointer\" (click)=\"removeLocation()\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\">\r\n <path d=\"M9 3L3 9M3 3L9 9\" stroke=\"#667085\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n </svg></span>\r\n </label>\r\n <label *ngIf=\"selectedGroupsLabel()\" class=\"badge badge-light-default mx-2\">{{selectedGroupsLabel()}} \r\n <span class=\"cursor-pointer\" (click)=\"removeGroup()\"><svg xmlns=\"http://www.w3.org/2000/svg\" width=\"12\" height=\"12\" viewBox=\"0 0 12 12\" fill=\"none\">\r\n <path d=\"M9 3L3 9M3 3L9 9\" stroke=\"#667085\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n </svg></span>\r\n </label>\r\n <label class=\"badge badge-light-default\">{{selectedStoresLabel()}}</label>\r\n</div>\r\n\r\n<div class=\"d-flex align-items-center position-relative my-1\">\r\n <span class=\"svg-icon svg-icon-1 position-absolute ms-3\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\">\r\n <path\r\n d=\"M13.3333 1.66663V4.99996M6.66667 1.66663V4.99996M2.5 8.33329H17.5M4.16667 3.33329H15.8333C16.7538 3.33329 17.5 4.07948 17.5 4.99996V16.6666C17.5 17.5871 16.7538 18.3333 15.8333 18.3333H4.16667C3.24619 18.3333 2.5 17.5871 2.5 16.6666V4.99996C2.5 4.07948 3.24619 3.33329 4.16667 3.33329Z\"\r\n stroke=\"#344054\" stroke-width=\"1.67\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\r\n </svg>\r\n </span>\r\n <input class=\"fx-date-range form-control ps-14\" style=\"min-width: 260px !important;\" type=\"text\" matInput\r\n ngxDaterangepickerMd [drops]=\"'down'\" [opens]=\"'right'\" [ranges]=\"ranges\" [showCustomRangeLabel]=\"true\" [autoApply]=\"true\"\r\n [alwaysShowCalendars]=\"false\" [keepCalendarOpeningWithRange]=\"true\" [showCancel]=\"true\" autocomplete=\"off\"\r\n [(ngModel)]=\"selectedDateRange\" (startDateChanged)=\"onStartDateChange($event)\" [isCustomDate]=\"isCustomDate\"\r\n [locale]=\"{ format: 'DD-MM-YYYY', firstDay: 1, monthNames: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] }\"\r\n (datesUpdated)=\"datechange($event)\" name=\"daterange\" [readonly]=\"true\" />\r\n</div>\r\n<div class=\"position-relative\">\r\n <button type=\"button\" (click)=\"opendropdown($event)\" class=\"btn btn-default mx-2 rounded-3 text-nowrap border-val\">\r\n <!-- <span class=\"me-2\">Filter</span> -->\r\n <svg class=\"pl-3\" width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path d=\"M5 10H15M2.5 5H17.5M7.5 15H12.5\" stroke=\"#344054\" stroke-width=\"2\" stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\" />\r\n </svg>\r\n </button>\r\n\r\n <div *ngIf=\"Opendropdown\" class=\"card p-5 dropdown1 position-absolute z-1 end-0\" style=\"z-index: 1 !important;\" (clickOutside)=\"closeDropdown1()\">\r\n <div class=\"dropdown-title d-flex justify-content-between mb-2\">Filter Options\r\n <button class=\"btn btn-outline w-25 ms-3 btn-resize\" (click)=\"Reset()\"> Reset </button>\r\n <button class=\"btn btn-primary w-25 btn-resize\" (click)=\"Apply()\">Apply</button>\r\n </div>\r\n\r\n <!-- Location Dropdown -->\r\n<div class=\"dropdown-container\" (clickOutside)=\"closeDropdown()\">\r\n <div class=\"dropdown-header\">\r\n <input \r\n type=\"text\" \r\n class=\"form-control dropdown-input cursor-pointer\" \r\n [value]=\"selectedLocationsLabel()\"\r\n (focus)=\"toggleDropdown('location')\" \r\n readonly\r\n placeholder=\"Select locations...\"\r\n />\r\n </div>\r\n <div class=\"dropdown-menu custom-dropdown-menu\" *ngIf=\"dropdownOpen === 'location'\">\r\n <input \r\n type=\"text\" \r\n class=\"form-control mb-2 dropdown-search\" \r\n placeholder=\"Search locations...\" \r\n [(ngModel)]=\"searchLocationText\" \r\n (ngModelChange)=\"filterLocations()\" \r\n />\r\n <div class=\"form-check mb-2 dropdown-item custom-dropdown-item\">\r\n <input \r\n class=\"form-check-input cursor-pointer\" \r\n type=\"checkbox\" \r\n id=\"selectAllLocations\" \r\n [checked]=\"isAllLocationsSelected()\" \r\n (change)=\"toggleSelectAllLocations($event)\" \r\n />\r\n <label class=\"form-check-label\" for=\"selectAllLocations\">\r\n Select All Locations\r\n </label>\r\n </div>\r\n <div \r\n class=\"dropdown-item form-check custom-dropdown-item\" \r\n *ngFor=\"let location of filteredLocations\"\r\n >\r\n <input \r\n class=\"form-check-input cursor-pointer\" \r\n type=\"checkbox\" \r\n [id]=\"location.city\" \r\n [(ngModel)]=\"location.checked\"\r\n (change)=\"updateSelectedLocations()\" \r\n />\r\n <label class=\"form-check-label\" [for]=\"location.city\">\r\n {{ location.city }}\r\n </label>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n<!-- Group Dropdown -->\r\n<div class=\"dropdown-container mt-3\" (clickOutside)=\"closeDropdown()\">\r\n <div class=\"dropdown-header\" (click)=\"toggleDropdown('group')\">\r\n <input \r\n type=\"text\" \r\n class=\"form-control dropdown-input cursor-pointer\" \r\n [value]=\"selectedGroupsLabel()\" readonly\r\n placeholder=\"Select clusters..\"\r\n />\r\n </div>\r\n <div class=\"dropdown-menu custom-dropdown-menu\" *ngIf=\"dropdownOpen === 'group'\">\r\n <input \r\n type=\"text\" \r\n class=\"form-control mb-2 dropdown-search\" \r\n placeholder=\"Search clusters...\" \r\n [(ngModel)]=\"searchGroupText\" \r\n (ngModelChange)=\"filterGroups()\" \r\n />\r\n <div class=\"form-check mb-2 dropdown-item custom-dropdown-item\">\r\n <input \r\n class=\"form-check-input cursor-pointer\" \r\n type=\"checkbox\" \r\n id=\"selectAllGroups\" \r\n [checked]=\"isAllGroupsSelected()\" \r\n (change)=\"toggleSelectAllGroups($event)\" \r\n />\r\n <label class=\"form-check-label\" for=\"selectAllGroups\">\r\n Select All\r\n </label>\r\n </div>\r\n <div \r\n class=\"dropdown-item form-check custom-dropdown-item\" \r\n *ngFor=\"let group of filteredGroups\"\r\n >\r\n <input \r\n class=\"form-check-input cursor-pointer\" \r\n type=\"checkbox\" \r\n [id]=\"group.groupName\"\r\n [(ngModel)]=\"group.checked\"\r\n (change)=\"updateSelectedGroups()\" \r\n />\r\n <label class=\"form-check-label\" [for]=\"group.groupName\">\r\n {{ group.groupName }}\r\n </label>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n\r\n<!-- Store Dropdown -->\r\n<div class=\"dropdown-container mt-3\" (clickOutside)=\"closeDropdown()\">\r\n <div class=\"dropdown-header\" (click)=\"toggleDropdown('store')\">\r\n <input \r\n type=\"text\" \r\n class=\"form-control dropdown-input cursor-pointer\"\r\n [value]=\"selectedStoresLabel()\"\r\n readonly\r\n placeholder=\"Select stores...\"\r\n />\r\n </div>\r\n <div class=\"dropdown-menu custom-dropdown-menu\" *ngIf=\"dropdownOpen === 'store'\">\r\n <input \r\n type=\"text\" \r\n class=\"form-control mb-2 dropdown-search \" \r\n placeholder=\"Search stores...\" \r\n [(ngModel)]=\"searchStoreText\" \r\n (ngModelChange)=\"filterStores()\" \r\n />\r\n <div class=\"form-check mb-2 dropdown-item custom-dropdown-item\">\r\n <input \r\n class=\"form-check-input cursor-pointer\" \r\n type=\"checkbox\" \r\n id=\"selectAllStores\" \r\n [checked]=\"isAllStoresSelected()\" \r\n (change)=\"toggleSelectAllStores($event)\" \r\n />\r\n <label class=\"form-check-label\" for=\"selectAllStores\">\r\n Select All\r\n </label>\r\n </div>\r\n <div \r\n class=\"dropdown-item form-check custom-dropdown-item\" \r\n *ngFor=\"let store of filteredStores\"\r\n >\r\n <input \r\n class=\"form-check-input\" \r\n type=\"checkbox\" \r\n [id]=\"store.storeId\"\r\n [(ngModel)]=\"store.checked\"\r\n (change)=\"updateSelectedStores()\" \r\n />\r\n <label class=\"form-check-label\" [for]=\"store.storeId\">\r\n {{ store.storeName }}\r\n </label>\r\n </div>\r\n </div>\r\n</div>\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n </div>\r\n</div>", styles: [".daterangepicker{display:block!important;top:153.85px!important;left:900px!important;right:0}.form-control{color:var(--Gray-700, #344054)!important;font-size:14px!important;font-weight:600;line-height:20px;text-transform:capitalize}::ng-deep .applyBtn{display:none!important}:host::ng-deep .md-drppicker .btn{line-height:10px!important}:host::ng-deep .daterangepicker-input+.ngx-daterangepicker-material .applyBtn{display:none}:host::ng-deep .md-drppicker.drops-down-right.ltr.double.show-ranges.shown{top:65px!important;left:-470px!important;height:365px!important}:host::ng-deep .md-drppicker .btn{border-radius:8px!important;border:1px solid var(--Primary-600, #00A3FF)!important;background:var(--Primary-600, #00A3FF)!important;box-shadow:0 1px 2px #1018280d!important;color:var(--White, #FFF)!important;font-size:14px!important;font-weight:600!important;line-height:20px;text-transform:capitalize}:host::ng-deep .md-drppicker .ranges ul li button{padding:12px 16px;width:160px;color:var(--Gray-700, #344054);font-size:14px;font-weight:400;line-height:20px;background:none;border:none;text-align:left;cursor:pointer}:host::ng-deep .md-drppicker td.active,:host::ng-deep .md-drppicker td.active:hover{background-color:#029cf4!important;border-radius:20px!important;color:var(--White, #FFF)!important;text-align:center!important;font-size:14px!important;font-weight:500!important;line-height:20px}:host::ng-deep .md-drppicker.ltr .ranges{float:left;margin-top:10px!important}:host::ng-deep .md-drppicker td.in-range{background:var(--Primary-50, #EAF8FF)}:host::ng-deep .md-drppicker .ranges ul li button.active{background:var(--Primary-50, #EAF8FF)!important;border-radius:8px!important;color:var(--Primary-700, #009BF3);font-size:14px!important;font-weight:500!important;line-height:20px!important}:host::ng-deep table th,:host::ng-deep table td{width:40px!important;height:40px!important;padding:10px 8px!important}:host::ng-deep .md-drppicker td.available.prev,:host::ng-deep .md-drppicker th.available.prev{background-image:url(data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgMy43IDYiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDMuNyA2IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxnPg0KCTxwYXRoIGQ9Ik0zLjcsMC43TDEuNCwzbDIuMywyLjNMMyw2TDAsM2wzLTNMMy43LDAuN3oiLz4NCjwvZz4NCjwvc3ZnPg0K)!important;background-repeat:no-repeat!important;background-size:.5em!important;background-position:center!important}:host::ng-deep .md-drppicker td.available.next,:host::ng-deep .md-drppicker th.available.next{background-image:url(data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB2aWV3Qm94PSIwIDAgMy43IDYiIGVuYWJsZS1iYWNrZ3JvdW5kPSJuZXcgMCAwIDMuNyA2IiB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxnPg0KCTxwYXRoIGQ9Ik0zLjcsMC43TDEuNCwzbDIuMywyLjNMMyw2TDAsM2wzLTNMMy43LDAuN3oiLz4NCjwvZz4NCjwvc3ZnPg0K)!important;background-repeat:no-repeat!important;background-size:.5em!important;background-position:center!important}:host::ng-deep table th{border-bottom:0px solid var(--Gray-200, #EAECF0)!important;background:transparent!important;color:var(--Gray-700, #344054)!important;text-align:center;font-size:16px!important;font-weight:500!important;line-height:24px}:host::ng-deep .md-drppicker .btn.btn-default{border-radius:8px!important;border:1px solid var(--Gray-300, #D0D5DD)!important;background:var(--White, #FFF)!important;box-shadow:0 1px 2px #1018280d!important;color:var(--Gray-700, #344054)!important;font-size:14px!important;font-weight:600!important;line-height:20px;text-transform:capitalize;margin-right:10px!important}:host::ng-deep .md-drppicker td.available.invalid-date{text-decoration:line-through;pointer-events:none;color:#a9a9a9}:host::ng-deep .md-drppicker td.available.today:not(.invalid-date){text-decoration:unset;pointer-events:unset;color:unset}.wrapper{min-width:200px}.btn-primary{line-height:18px!important}.filter-label{color:var(--Gray-500, #667085)!important;font-size:14px;font-style:normal;font-weight:600;line-height:20px;text-transform:capitalize}.position-relative{position:relative}.filter-icon{cursor:pointer}.dropdown-container{position:relative;display:inline-block;width:100%}.dropdown-header{cursor:pointer;width:100%}.form-control{color:var(--Gray-700, #344054)!important;font-size:14px!important;font-weight:600;line-height:20px;text-transform:capitalize;width:100%;box-sizing:border-box}.dropdown-menu{position:absolute;top:100%;left:0;right:0;border:1px solid #ccc;background-color:#fff;z-index:1000;max-height:230px;overflow-y:auto;display:block;box-sizing:border-box;padding:10px 5px}.dropdown-item{padding:6px 0}.dropdown-item:hover{background-color:#f1f1f1}.dropdown-item input[type=checkbox]{margin-right:10px}.custom-dropdown-menu{border-radius:4px;box-shadow:0 1px 2px #1018280d}.custom-dropdown-item{display:flex;align-items:center}.custom-dropdown-item input{margin-left:10px}.btn-resize{font-size:13px!important;height:29px!important;line-height:11px!important;padding:3px!important}.dropdown1{position:absolute;top:70px;min-width:270px!important}.dropdown1 .dropdown-title{color:var(--Gray-900, #101828);font-size:14px;font-weight:600;line-height:24px}.dropdown1 .dropdown{position:relative;display:inline-block}.dropdown1 .dropdown span{color:var(--Gray-700, #344054);font-size:14px;font-weight:600;line-height:20px}::ng-deep .dropdown1{z-index:1!important}.form-check-label{color:var(--Gray-700, #344054)!important;font-size:14px;font-style:normal;font-weight:500;line-height:20px}input[type=checkbox]{width:16px!important;height:16px!important;margin:0 5px;border-radius:4px!important;-webkit-appearance:none;-moz-appearance:none;-o-appearance:none;appearance:none;outline:1px solid var(--gray-300, #D0D5DD);box-shadow:none;font-size:.8em;text-align:center;line-height:1em;background:#fff}input[type=checkbox]:checked{outline:1px solid var(--primary-600, #00A3FF);background-color:var(--primary-50, #EAF8FF)}input[type=checkbox]:checked:after{content:\"\";transform:rotate(45deg);border-bottom:2px solid #00A3FF;border-right:2px solid #00A3FF;display:inline-block;width:.2em;padding-left:0;padding-top:9px;padding-right:4px}\n"] }]
777
+ }], ctorParameters: () => [{ type: i1.AuthService }, { type: i2.Router }, { type: i3.GlobalStateService }, { type: i0.ChangeDetectorRef }], propDecorators: { onClick: [{
778
+ type: HostListener,
779
+ args: ['document:click', ['$event']]
780
+ }], clickOutside: [{
781
+ type: HostListener,
782
+ args: ["document:click", ["$event"]]
783
+ }] } });
784
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhZmZpYy1ub2IuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdGFuZ28tYXBwLXNoYXJlZC9zcmMvbGliL21vZHVsZXMvbGF5b3V0L3Rvb2xiYXIvdHJhZmZpYy1ub2IvdHJhZmZpYy1ub2IuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdGFuZ28tYXBwLXNoYXJlZC9zcmMvbGliL21vZHVsZXMvbGF5b3V0L3Rvb2xiYXIvdHJhZmZpYy1ub2IvdHJhZmZpYy1ub2IuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVMLFNBQVMsRUFDVCxZQUFZLEdBR2IsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxLQUFLLE1BQU0sT0FBTyxDQUFDO0FBQzFCLE9BQU8saUJBQWlCLENBQUM7Ozs7Ozs7O0FBU3pCLE1BQU0sT0FBTyxtQkFBbUI7SUFxQ3BCO0lBQThCO0lBQy9CO0lBQ0M7SUF0Q1gsS0FBSyxHQUFHLEtBQUssQ0FBQztJQUNiLFlBQVksR0FBRyxDQUFDLENBQWMsRUFBRSxFQUFFO1FBQ2hDLE1BQU0sV0FBVyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDckMsT0FBTyxXQUFXLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDO0lBQzlDLENBQUMsQ0FBQztJQUVGLGlCQUFpQixHQUFRLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLEVBQUUsTUFBTSxDQUFDO1FBQ2hFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxHQUFFLENBQUM7SUFDekMsZUFBZSxHQUFRO1FBQ3JCLE1BQU0sRUFBRSxJQUFJO1FBQ1osVUFBVSxFQUFFLElBQUk7UUFD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SyxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQUUsT0FBTyxJQUFJLEtBQUssQ0FBQyxPQUFPLElBQUksS0FBSzthQUN0SCxDQUFDLENBQUMsQ0FBQztTQUNMO0lBQ0gsQ0FBQztJQUlELGFBQWE7UUFDWCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQztJQUMzQixDQUFDO0lBR0QsWUFBWSxDQUFDLEtBQWlCO1FBQzVCLE1BQU0sYUFBYSxHQUFJLEtBQUssQ0FBQyxNQUFzQixDQUFDLE9BQU8sQ0FDekQscUJBQXFCLENBQ3RCLENBQUM7UUFDRixNQUFNLGNBQWMsR0FBSSxLQUFLLENBQUMsTUFBc0IsQ0FBQyxPQUFPLENBQzFELFlBQVksQ0FDYixDQUFDO1FBQ0YsSUFBSSxDQUFDLGFBQWEsRUFBRTtZQUNsQixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7U0FDdEI7UUFDRCxJQUFHLENBQUMsY0FBYyxFQUFFO1lBQ2xCLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztTQUN2QjtJQUVILENBQUM7d0dBMzFCVSxtQkFBbUI7NEZBQW5CLG1CQUFtQiwwSENqQmhDLGs3U0F1TU07OzRGRHRMTyxtQkFBbUI7a0JBTC9CLFNBQVM7K0JBQ0UsaUJBQWlCO3NLQStDM0IsT0FBTztzQkFETixZQUFZO3VCQUFDLGdCQUFnQixFQUFFLENBQUMsUUFBUSxDQUFDO2dCQW15QjFDLFlBQVk7c0JBRFgsWUFBWTt1QkFBQyxnQkFBZ0IsRUFBRSxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXHJcbiAgQ29tcG9uZW50LFxyXG4gIEhvc3RMaXN0ZW5lcixcclxuICBPbkRlc3Ryb3ksXHJcbiAgT25Jbml0LFxyXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XHJcbmltcG9ydCBkYXlqcyBmcm9tIFwiZGF5anNcIjtcclxuaW1wb3J0IFwiZGF5anMvbG9jYWxlL2VuXCI7XHJcbmltcG9ydCB7IEdsb2JhbFN0YXRlU2VydmljZSB9IGZyb20gXCJ0YW5nby1hcHAtdWktZ2xvYmFsXCI7XHJcbmltcG9ydCB7IE5hdmlnYXRpb25FbmQsIFJvdXRlciB9IGZyb20gXCJAYW5ndWxhci9yb3V0ZXJcIjtcclxuaW1wb3J0IHsgQXV0aFNlcnZpY2UgfSBmcm9tIFwiLi4vLi4vLi4vLi4vc2VydmljZXMvYXV0aC5zZXJ2aWNlXCI7XHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnbGliLXRyYWZmaWMtbm9iJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vdHJhZmZpYy1ub2IuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsOiAnLi90cmFmZmljLW5vYi5jb21wb25lbnQuc2NzcydcclxufSlcclxuZXhwb3J0IGNsYXNzIFRyYWZmaWNOb2JDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xyXG4gZGF5anMgPSBkYXlqcztcclxuICBpc0N1c3RvbURhdGUgPSAobTogZGF5anMuRGF5anMpID0+IHtcclxuICAgIGNvbnN0IGlzVmFsaWREYXRlID0gbSA+IHRoaXMuZGF5anMoKTtcclxuICAgIHJldHVybiBpc1ZhbGlkRGF0ZSA/IFwiaW52YWxpZC1kYXRlXCIgOiBmYWxzZTtcclxuICB9O1xyXG5cclxuICBzZWxlY3RlZERhdGVSYW5nZTogYW55ID0geyBzdGFydERhdGU6IGRheWpzKCkuc3VidHJhY3QoMzAsICdkYXlzJyksXHJcbiAgICBlbmREYXRlOiBkYXlqcygpLnN1YnRyYWN0KDEsIFwiZGF5c1wiKSx9O1xyXG4gIHNlbGVjdGVkRmlsdGVyczogYW55ID0ge1xyXG4gICAgY2xpZW50OiBudWxsLFxyXG4gICAgY2xpZW50TmFtZTogbnVsbCxcclxuICAgIGNsaWVudHM6IFtdLFxyXG4gICAgc3RvcmU6IG51bGwsXHJcbiAgICBzdG9yZXM6IFtdLFxyXG4gICAgZGF0ZTogbnVsbCxcclxuICAgIGdyb3VwOiBbXSxcclxuICAgIGxvY2F0aW9uOiBbXSxcclxuICB9O1xyXG4gIE9wZW5kcm9wZG93bjogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIGRyb3Bkb3duT3Blbjogc3RyaW5nIHwgbnVsbCA9IG51bGw7IC8vICdsb2NhdGlvbicgb3IgJ2dyb3VwJ1xyXG4gIHNlYXJjaExvY2F0aW9uVGV4dDogc3RyaW5nID0gXCJcIjtcclxuICBzZWFyY2hHcm91cFRleHQ6IHN0cmluZyA9IFwiXCI7XHJcbiAgbG9jYXRpb25zOiBhbnlbXSA9IFtdO1xyXG4gIGZpbHRlcmVkTG9jYXRpb25zOiBhbnlbXSA9IFtdO1xyXG4gIGdyb3Vwc0RhdGE6IGFueVtdID0gW107XHJcbiAgZmlsdGVyZWRHcm91cHM6IGFueVtdID0gW107XHJcbiAgZmlsdGVyZWRTdG9yZXM6IGFueVtdID0gW107XHJcbiAgc3RvcmVzOmFueVtdID0gW11cclxuICBzZWFyY2hTdG9yZVRleHQ6c3RyaW5nID0gJyc7XHJcbiAgY2xpZW50TGlzdDphbnkgPSBbXVxyXG4gIHNlbGVjdGVkQ2xpZW50OmFueVxyXG4gIGxvY2F0aW9uTGFiZWw6IGFueVtdPVtdO1xyXG4gIGdyb3VwTGFiZWw6IGFueVtdPVtdO1xyXG4gIHVzZXJzOiBhbnk7XHJcbiAgdXJsOiBhbnk7XHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIGF1dGg6IEF1dGhTZXJ2aWNlLCAgICBwcml2YXRlIHJvdXRlcjogUm91dGVyLFxyXG4gICAgcHVibGljIGdzOiBHbG9iYWxTdGF0ZVNlcnZpY2UsXHJcbiAgICBwcml2YXRlIGNkOiBDaGFuZ2VEZXRlY3RvclJlZixcclxuICApIHt9XHJcblxyXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmNsaWNrJywgWyckZXZlbnQnXSlcclxuICBvbkNsaWNrIChldmVudDogTW91c2VFdmVudCkge1xyXG4gICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xyXG4gICAgaWYoIXRhcmdldC5jbG9zZXN0KCcuZHJvcGRvd24xJykpIHtcclxuICAgICAgdGhpcy5PcGVuZHJvcGRvd24gPSBmYWxzZTtcclxuICAgIH1cclxuICB9XHJcbiAgY2xvc2VEcm9wZG93bjEoKXtcclxuICAgIHRoaXMuT3BlbmRyb3Bkb3duID0gZmFsc2U7XHJcbiAgfVxyXG4gIG5nT25Jbml0KCk6IHZvaWQge1xyXG4gICAgdGhpcy51cmwgPSB0aGlzLnJvdXRlci51cmwuc3BsaXQoXCI/XCIpWzBdLnNwbGl0KCcvJyk7XHJcbiAgICBjb25zdCB1c2VyID0gSlNPTi5wYXJzZShsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgndXNlci1pbmZvJykgYXMgc3RyaW5nKTtcclxuICAgIHRoaXMudXNlcnMgPSB1c2VyO1xyXG4gICAgdGhpcy5ncz8ubWFuYWdlUmVmcmVzaFRyaWdnZXI/LnN1YnNjcmliZSgoZSkgPT4geyAgICAgIFxyXG4gICAgICBpZiAoZSkge1xyXG4gICAgICAgIGlmICh1c2VyLnVzZXJUeXBlID09PSAndGFuZ28nKSB7XHJcbiAgICAgICAgdGhpcy5nZXRDbGllbnQoKTtcclxuICAgICAgICB9IGVsc2V7XHJcbiAgICAgICAgICBjb25zdCBzdG9yZWRGaWx0ZXJzID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0oXCJoZWFkZXItZmlsdGVyc1wiKTtcclxuICAgICAgICAgIGlmIChzdG9yZWRGaWx0ZXJzKSB7XHJcbiAgICAgICAgICBjb25zdCBoZWFkZXJGaWx0ZXJzID0gSlNPTi5wYXJzZShzdG9yZWRGaWx0ZXJzKTtcclxuICAgICAgICAgIHRoaXMuZmlsdGVyZWRTdG9yZXMgPSBoZWFkZXJGaWx0ZXJzPy5zdG9yZXMubWFwKChzdG9yZTphbnkpID0+ICh7XHJcbiAgICAgICAgICAgIC4uLnN0b3JlLFxyXG4gICAgICAgICAgICBjaGVja2VkOiBzdG9yZS5jaGVja2VkXHJcbiAgICAgICAgICB9KSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiBcclxuICAgIC8vIEZldGNoIGNsaWVudCBkYXRhIGlmIHRoZSB1c2VyIGlzIG9mIHR5cGUgJ3RhbmdvJ1xyXG4gICAgaWYgKHVzZXIudXNlclR5cGUgPT09ICd0YW5nbycpIHtcclxuICAgICAgdGhpcy5nZXRDbGllbnQoKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuZ2V0TG9jYXRpb25zKCk7XHJcbiAgICAgIHRoaXMuZ2V0R3JvdXBzKCk7XHJcbiAgICAgIHRoaXMuZ2V0U3RvcmUoKTtcclxuLy8gICAgICAgdGhpcy5lbWl0QW5kU3RvcmVGaWx0ZXJzKCk7XHJcbi8vIGNvbnNvbGUubG9nKFwiMVwiKVxyXG4gICAgfVxyXG4gICBcclxuICAgIC8vIExvYWQgZmlsdGVycyBmcm9tIGxvY2FsU3RvcmFnZSBpZiB0aGV5IGV4aXN0XHJcbiAgICBjb25zdCBzdG9yZWRGaWx0ZXJzID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0oXCJoZWFkZXItZmlsdGVyc1wiKTtcclxuICAgIGlmIChzdG9yZWRGaWx0ZXJzKSB7XHJcbiAgICAgIGNvbnN0IGhlYWRlckZpbHRlcnMgPSBKU09OLnBhcnNlKHN0b3JlZEZpbHRlcnMpO1xyXG4gIFxyXG4gICAgICAvLyBJbml0aWFsaXplIHNlbGVjdGVkRmlsdGVycyB3aXRoIGRlZmF1bHRzIG9yIGV4aXN0aW5nIHZhbHVlc1xyXG4gICAgICB0aGlzLnNlbGVjdGVkRmlsdGVycyA9IHtcclxuICAgICAgICBjbGllbnQ6IGhlYWRlckZpbHRlcnMuY2xpZW50IHx8IHRoaXMudXNlcnMuY2xpZW50LFxyXG4gICAgICAgIGNsaWVudE5hbWU6IGhlYWRlckZpbHRlcnMuY2xpZW50TmFtZSB8fCAnJyxcclxuICAgICAgICBjbGllbnRzOiBoZWFkZXJGaWx0ZXJzLmNsaWVudHMgfHwgW10sXHJcbiAgICAgICAgc3RvcmU6IGhlYWRlckZpbHRlcnMuc3RvcmUgfHwgbnVsbCxcclxuICAgICAgICBkYXRlOiBoZWFkZXJGaWx0ZXJzLmRhdGUgfHwge30sXHJcbiAgICAgICAgc3RvcmVzOiBoZWFkZXJGaWx0ZXJzLnN0b3JlcyB8fCBbXSxcclxuICAgICAgICBncm91cDogaGVhZGVyRmlsdGVycy5ncm91cCB8fCBbXSxcclxuICAgICAgICBsb2NhdGlvbjogaGVhZGVyRmlsdGVycy5sb2NhdGlvbiB8fCBbXVxyXG4gICAgICB9O1xyXG4gIFxyXG4gICAgICAvLyBTeW5jIGZpbHRlcmVkIGRhdGEgd2l0aCBzdG9yZWQgc2VsZWN0aW9uc1xyXG4gICAgICB0aGlzLmZpbHRlcmVkTG9jYXRpb25zID0gdGhpcy5zeW5jV2l0aExvY2FsU3RvcmFnZShoZWFkZXJGaWx0ZXJzLmxvY2F0aW9uKTtcclxuICAgICAgdGhpcy5maWx0ZXJlZEdyb3VwcyA9IHRoaXMuc3luY1dpdGhMb2NhbFN0b3JhZ2UoaGVhZGVyRmlsdGVycy5ncm91cCk7XHJcbiAgICAgIHRoaXMuZmlsdGVyZWRTdG9yZXMgPSB0aGlzLnN5bmNXaXRoTG9jYWxTdG9yYWdlKGhlYWRlckZpbHRlcnMuc3RvcmVzKTtcclxuICBcclxuICAgICAgLy8gRm9ybWF0IGRhdGUgcmFuZ2UgaWYgaXQgZXhpc3RzXHJcbiAgICAgIGlmIChoZWFkZXJGaWx0ZXJzLmRhdGUpIHtcclxuICAgICAgICB0aGlzLnNlbGVjdGVkRGF0ZVJhbmdlID0ge1xyXG4gICAgICAgICAgc3RhcnREYXRlOiB0aGlzLmRheWpzKGhlYWRlckZpbHRlcnMuZGF0ZS5zdGFydERhdGUsIFwiWVlZWS1NTS1ERFwiKS5mb3JtYXQoXCJERC1NTS1ZWVlZXCIpLFxyXG4gICAgICAgICAgZW5kRGF0ZTogdGhpcy5kYXlqcyhoZWFkZXJGaWx0ZXJzLmRhdGUuZW5kRGF0ZSwgXCJZWVlZLU1NLUREXCIpLmZvcm1hdChcIkRELU1NLVlZWVlcIiksXHJcbiAgICAgICAgfTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLnNlbGVjdGVkRGF0ZVJhbmdlID0ge1xyXG4gICAgICAgICAgc3RhcnREYXRlOiB0aGlzLmRheWpzKHRoaXMuc2VsZWN0ZWREYXRlUmFuZ2Uuc3RhcnREYXRlLCBcIllZWVktTU0tRERcIikuZm9ybWF0KFwiREQtTU0tWVlZWVwiKSxcclxuICAgICAgICAgIGVuZERhdGU6IHRoaXMuZGF5anModGhpcy5zZWxlY3RlZERhdGVSYW5nZS5lbmREYXRlLCBcIllZWVktTU0tRERcIikuZm9ybWF0KFwiREQtTU0tWVlZWVwiKSxcclxuICAgICAgICB9O1xyXG4gICAgICB9XHJcbiAgICAgIC8vIGNvbnNvbGUubG9nKFwiM1wiKVxyXG4gICAgICAvLyBFbWl0IGRhdGEgdmlhIHNlcnZpY2UgYW5kIHVwZGF0ZSBsb2NhbFN0b3JhZ2VcclxudGhpcy5lbWl0QW5kU3RvcmVGaWx0ZXJzKCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAvLyBJbml0aWFsaXplIGVtcHR5IHN0YXRlcyBpZiBubyBoZWFkZXIgZmlsdGVycyBhcmUgcHJlc2VudCBpbiBsb2NhbFN0b3JhZ2VcclxuICAgICAgdGhpcy5yZXNldEZpbHRlcnMoKTtcclxuICAgICAgLy8gY29uc29sZS5sb2coXCIyXCIpXHJcbiAgICB9XHJcbiAgfVxyXG4gIHByaXZhdGUgc3luY1dpdGhMb2NhbFN0b3JhZ2UoaXRlbXM6IGFueVtdKTogYW55W10ge1xyXG4gICAgcmV0dXJuIGl0ZW1zXHJcbiAgICAgID8gaXRlbXMubWFwKChpdGVtOiBhbnkpID0+ICh7XHJcbiAgICAgICAgICAuLi5pdGVtLFxyXG4gICAgICAgICAgY2hlY2tlZDogaXRlbS5jaGVja2VkID09PSB0cnVlXHJcbiAgICAgICAgfSkpXHJcbiAgICAgIDogW107XHJcbiAgfVxyXG4gIHByaXZhdGUgZW1pdEFuZFN0b3JlRmlsdGVycygpOiB2b2lkIHtcclxuICAgIHRoaXMuZ3MuZGF0YVJhbmdlVmFsdWUubmV4dCh0aGlzLnNlbGVjdGVkRmlsdGVycyk7XHJcbiAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShcImhlYWRlci1maWx0ZXJzXCIsIEpTT04uc3RyaW5naWZ5KHRoaXMuc2VsZWN0ZWRGaWx0ZXJzKSk7XHJcbiAgICAvLyBjb25zb2xlLmxvZyhcIjFcIilcclxuICB9XHJcbiAgXHJcbiAgLyoqXHJcbiAgICogUmVzZXQgc2VsZWN0ZWRGaWx0ZXJzIGFuZCBhbGwgcmVsYXRlZCBhcnJheXMgdG8gZW1wdHkgc3RhdGVzXHJcbiAgICovXHJcbiAgcHJpdmF0ZSByZXNldEZpbHRlcnMoKTogdm9pZCB7XHJcbiAgICB0aGlzLnNlbGVjdGVkRmlsdGVycyA9IHtcclxuICAgICAgY2xpZW50OiBudWxsLFxyXG4gICAgICBjbGllbnROYW1lOiAnJyxcclxuICAgICAgY2xpZW50czogW10sXHJcbiAgICAgIHN0b3JlOiBudWxsLFxyXG4gICAgICBkYXRlOiB7fSxcclxuICAgICAgc3RvcmVzOiBbXSxcclxuICAgICAgZ3JvdXA6IFtdLFxyXG4gICAgICBsb2NhdGlvbjogW11cclxuICAgIH07XHJcbiAgICB0aGlzLmZpbHRlcmVkTG9jYXRpb25zID0gW107XHJcbiAgICB0aGlzLmZpbHRlcmVkR3JvdXBzID0gW107XHJcbiAgICB0aGlzLmZpbHRlcmVkU3RvcmVzID0gW107XHJcbiAgfVxyXG5nZXRDbGllbnQoKXtcclxuICB0aGlzLmF1dGguZ2V0Q2xpZW50cygpLnN1YnNjcmliZSh7XHJcbiAgICBuZXh0OiAoZSkgPT4ge1xyXG4gICAgICBpZiAoZSkge1xyXG4gICAgICAgIHRoaXMuY2xpZW50TGlzdCA9IGUuZGF0YS5yZXN1bHQ7XHJcbiAgICAgICAgY29uc3QgaGVhZGVyRmlsdGVyczogYW55ID0gSlNPTi5wYXJzZShcclxuICAgICAgICAgIGxvY2FsU3RvcmFnZS5nZXRJdGVtKFwiaGVhZGVyLWZpbHRlcnNcIikgfHwgXCJ7fVwiXHJcbiAgICAgICAgKTtcclxuICAgICAgICBpZiAoaGVhZGVyRmlsdGVycy5jbGllbnQpIHtcclxuICAgICAgICAgIHRoaXMuY2xpZW50TGlzdC5maW5kKChvYmo6IGFueSkgPT4ge1xyXG4gICAgICAgICAgICBpZiAob2JqLmNsaWVudElkID09PSBoZWFkZXJGaWx0ZXJzLmNsaWVudCkge1xyXG4gICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRDbGllbnQgPSBvYmo7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgIFxyXG4gICAgICAgICAgdGhpcy5zZWxlY3RlZEZpbHRlcnMuY2xpZW50ID0gaGVhZGVyRmlsdGVycy5jbGllbnQ7XHJcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkRmlsdGVycy5jbGllbnROYW1lID0gaGVhZGVyRmlsdGVycy5jbGllbnROYW1lO1xyXG4gICAgICAgICAgdGhpcy5zZWxlY3RlZEZpbHRlcnMuY2xpZW50cyA9IGhlYWRlckZpbHRlcnMuY2xpZW50cztcclxuICAgICAgICAgIHRoaXMuc2VsZWN0ZWRGaWx0ZXJzLnN0b3JlID0gaGVhZGVyRmlsdGVycy5zdG9yZTtcclxuICAgICAgICAgIHRoaXMuc2VsZWN0ZWRGaWx0ZXJzLmRhdGUgPSBoZWFkZXJGaWx0ZXJzLmRhdGU7XHJcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkRmlsdGVycy5zdG9yZXMgPSBoZWFkZXJGaWx0ZXJzLnN0b3JlcztcclxuICAgICAgICAgIHRoaXMuc2VsZWN0ZWRGaWx0ZXJzLmdyb3VwID0gaGVhZGVyRmlsdGVycy5ncm91cDtcclxuICAgICAgICAgIHRoaXMuc2VsZWN0ZWRGaWx0ZXJzLmxvY2F0aW9uID0gaGVhZGVyRmlsdGVycy5sb2NhdGlvbjtcclxuICAgICAgICAgIHRoaXMuZ3MuZGF0YVJhbmdlVmFsdWUubmV4dCh0aGlzLnNlbGVjdGVkRmlsdGVycyk7XHJcbiAgICAgICAgICAvLyBjb25zb2xlLmxvZyhcIjJcIilcclxuICAgICAgICAgICAgICAgICAvLyBFbnN1cmUgbG9jYXRpb25zIGFuZCBncm91cHMgYXJlIGxvYWRlZCBiZWZvcmUgZmV0Y2hpbmcgc3RvcmVzXHJcbiB0aGlzLmdldExvY2F0aW9ucygpO1xyXG4gdGhpcy5nZXRHcm91cHMoKTtcclxuICAvLyBGZXRjaCBzdG9yZXMgb25seSBhZnRlciBsb2NhdGlvbnMgYW5kIGdyb3VwcyBhcmUgc2V0XHJcbiAgdGhpcy5nZXRTdG9yZSgpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRDbGllbnQgPSB0aGlzLmNsaWVudExpc3RbMF07XHJcbiAgICAgICAgdGhpcy5zZWxlY3RlZEZpbHRlcnMuY2xpZW50ID0gIHRoaXMuc2VsZWN0ZWRDbGllbnQuY2xpZW50SWQ7XHJcbiAgICAgICAgdGhpcy5zZWxlY3RlZEZpbHRlcnMuY2xpZW50TmFtZSA9IHRoaXMuc2VsZWN0ZWRDbGllbnQuY2xpZW50TmFtZVxyXG4gICAgICB0aGlzLnNlbGVjdGVkRmlsdGVycy5jbGllbnRzID0gaGVhZGVyRmlsdGVycy5jbGllbnRzO1xyXG4gICAgICB0aGlzLnNlbGVjdGVkRmlsdGVycy5zdG9yZSA9IGhlYWRlckZpbHRlcnMuc3RvcmU7XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWRGaWx0ZXJzLmRhdGUgPSBoZWFkZXJGaWx0ZXJzLmRhdGU7XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWRGaWx0ZXJzLnN0b3JlcyA9IGhlYWRlckZpbHRlcnMuc3RvcmVzO1xyXG4gICAgICB0aGlzLnNlbGVjdGVkRmlsdGVycy5ncm91cCA9IGhlYWRlckZpbHRlcnMuZ3JvdXA7XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWRGaWx0ZXJzLmxvY2F0aW9uID0gaGVhZGVyRmlsdGVycy5sb2NhdGlvbjtcclxuICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShcclxuICAgICAgICAgIFwiaGVhZGVyLWZpbHRlcnNcIixcclxuICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHRoaXMuc2VsZWN0ZWRGaWx0ZXJzKSBcclxuICAgICAgICApO1xyXG4gICAgICAgIHRoaXMuZ3MuZGF0YVJhbmdlVmFsdWUubmV4dCh0aGlzLnNlbGVjdGVkRmlsdGVycyk7XHJcbiAgICAgICAgLy8gY29uc29sZS5sb2coXCIzXCIpXHJcbiAgICAgICAgdGhpcy5jZC5kZXRlY3RDaGFuZ2VzKCk7XHJcbiAgICAgICAgICAgICAgIC8vIEVuc3VyZSBsb2NhdGlvbnMgYW5kIGdyb3VwcyBhcmUgbG9hZGVkIGJlZm9yZSBmZXRjaGluZyBzdG9yZXNcclxuIHRoaXMuZ2V0TG9jYXRpb25zKCk7XHJcbiB0aGlzLmdldEdyb3VwcygpO1xyXG4gIC8vIEZldGNoIHN0b3JlcyBvbmx5IGFmdGVyIGxvY2F0aW9ucyBhbmQgZ3JvdXBzIGFyZSBzZXRcclxuICB0aGlzLmdldFN0b3JlKCk7XHJcbiAgICAgIH1cclxuXHJcblxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5zZWxlY3RlZENsaWVudCA9IHRoaXMuY2xpZW50TGlzdFswXTtcclxuICAgICAgdGhpcy5zZWxlY3RlZEZpbHRlcnMuY2xpZW50ID0gIHRoaXMuc2VsZWN0ZWRDbGllbnQuY2xpZW50SWQ7XHJcbiAgICAgIHRoaXMuc2VsZWN0ZWRGaWx0ZXJzLmNsaWVudE5hbWUgPSB0aGlzLnNlbGVjdGVkQ2xpZW50LmNsaWVudE5hbWVcclxuICAgICAgIC8vIEVuc3VyZSBsb2NhdGlvbnMgYW5kIGdyb3VwcyBhcmUgbG9hZGVkIGJlZm9yZSBmZXRjaGluZyBzdG9yZXNcclxuIHRoaXMuZ2V0TG9jYXRpb25zKCk7XHJcbiB0aGlzLmdldEdyb3VwcygpO1xyXG4gLy8gRmV0Y2ggc3RvcmVzIG9ubHkgYWZ0ZXIgbG9jYXRpb25zIGFuZCBncm91cHMgYXJlIHNldFxyXG4gdGhpcy5nZXRTdG9yZSgpO1xyXG4gICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShcclxuICAgICAgICBcImhlYWRlci1maWx0ZXJzXCIsXHJcbiAgICAgICAgSlNPTi5zdHJpbmdpZnkodGhpcy5zZWxlY3RlZEZpbHRlcnMpIFxyXG4gICAgICApO1xyXG4gICAgICB0aGlzLmdzLmRhdGFSYW5nZVZhbHVlLm5leHQodGhpcy5zZWxlY3RlZEZpbHRlcnMpO1xyXG4gICAgICAvLyBjb25zb2xlLmxvZyhcIjRcIilcclxuICAgICAgdGhpcy5jZC5kZXRlY3RDaGFuZ2VzKCk7XHJcbiAgICB9XHJcbiAgICB9LFxyXG4gIH0pO1xyXG59XHJcbm9uQ2xpZW50U2VsZWN0KGV2ZW50OiBhbnkpOiB2b2lkIHtcclxuICAvLyBVcGRhdGUgdGhlIHNlbGVjdGVkIGNsaWVudFxyXG4gIHRoaXMuc2VsZWN0ZWRDbGllbnQgPSBldmVudDtcclxuICAvLyBDbGVhciBwcmV2aW91cyBmaWx0ZXJlZCBkYXRhIGFuZCBzZWxlY3Rpb25zXHJcbiAgdGhpcy5maWx0ZXJlZEdyb3VwcyA9IFtdO1xyXG4gIHRoaXMuZmlsdGVyZWRTdG9yZXMgPSBbXTtcclxuICB0aGlzLmZpbHRlcmVkTG9jYXRpb25zID0gW107XHJcbiAgdGhpcy5zZWxlY3RlZEZpbHRlcnMuc3RvcmVzID0gW107XHJcbiAgdGhpcy5zZWxlY3RlZEZpbHRlcnMuZ3JvdXAgPSBbXTtcclxuICB0aGlzLnNlbGVjdGVkRmlsdGVycy5sb2NhdGlvbiA9IFtdO1xyXG5cclxuICAvLyBGZXRjaCBoZWFkZXIgZmlsdGVycyBmcm9tIGxvY2FsU3RvcmFnZVxyXG4gIGNvbnN0IGhlYWRlckZpbHRlcnM6IGFueSA9IEpTT04ucGFyc2UobG9jYWxTdG9yYWdlLmdldEl0ZW0oXCJoZWFkZXItZmlsdGVyc1wiKSB8fCBcInt9XCIpO1xyXG4gIFxyXG4gIC8vIFVwZGF0ZSB0aGUgc2VsZWN0ZWQgZmlsdGVycyB3aXRoIHRoZSBuZXcgY2xpZW50XHJcbiAgdGhpcy5zZWxlY3RlZEZpbHRlcnMuY2xpZW50ID0gdGhpcy5zZWxlY3RlZENsaWVudC5jbGllbnRJZDtcclxuICB0aGlzLnNlbGVjdGVkRmlsdGVycy5jbGllbnROYW1lID0gdGhpcy5zZWxlY3RlZENsaWVudC5jbGllbnROYW1lO1xyXG4gIFxyXG4gIC8vIFJlbW92ZSBvbGQgc3RvcmUsIGdyb3VwLCBhbmQgbG9jYXRpb24gZGF0YSBmcm9tIHRoZSBoZWFkZXIgZmlsdGVyc1xyXG4gIGRlbGV0ZSBoZWFkZXJGaWx0ZXJzLnN0b3JlcztcclxuICBkZWxldGUgaGVhZGVyRmlsdGVycy5ncm91cHM7XHJcbiAgZGVsZXRlIGhlYWRlckZpbHRlcnMubG9jYXRpb247XHJcbiAgXHJcbiAgLy8gRmV0Y2ggbmV3IGRhdGEgYmFzZWQgb24gdGhlIG5ldyBjbGllbnRcclxuICB0aGlzLmdldExvY2F0aW9ucygpO1xyXG4gIHRoaXMuZ2V0U3RvcmUoKTtcclxuICB0aGlzLmdldEdyb3VwcygpO1xyXG5cclxuICAvLyBVcGRhdGUgbG9jYWxTdG9yYWdlIHdpdGggdGhlIG5ldyBjbGllbnQgc2VsZWN0aW9uIGFuZCBlbXB0eSBmaWx0ZXIgZGF0YVxyXG4gIGxvY2FsU3RvcmFnZS5zZXRJdGVtKCdoZWFkZXItZmlsdGVycycsIEpTT04uc3RyaW5naWZ5KHRoaXMuc2VsZWN0ZWRGaWx0ZXJzKSk7XHJcbiAgd2luZG93LmxvY2F0aW9uLnJlbG9hZCgpXHJcbiAgLy8gRW1pdCBkYXRhIHRvIHRoZSBnbG9iYWwgc2VydmljZVxyXG4gIC8vIHRoaXMuZ3MuZGF0YVJhbmdlVmFsdWUubmV4dCh0aGlzLnNlbGVjdGVkRmlsdGVycyk7XHJcbiAgLy8gVHJpZ2dlciBjaGFuZ2UgZGV0ZWN0aW9uIHRvIHJlZmxlY3QgVUkgY2hhbmdlc1xyXG4gIHRoaXMuY2QuZGV0ZWN0Q2hhbmdlcygpO1xyXG59XHJcblxyXG5cclxuXHJcbnJhbmdlczphbnkgPSB7XHJcbiAgVG9kYXk6IFtkYXlqcygpLCBkYXlqcygpXSxcclxuICBZZXN0ZXJkYXk6IFtkYXlqcygpLnN1YnRyYWN0KDEsICdkYXlzJyksIGRheWpzKCkuc3VidHJhY3QoMSwgJ2RheXMnKV0sXHJcbiAgJ1RoaXMgV2Vlayc6IFtkYXlqcygpLnN1YnRyYWN0KDcsICdkYXlzJyksIGRheWpzKCkuc3VidHJhY3QoMSwgJ2RheXMnKV0sXHJcbiAgJ0xhc3QgV2Vlayc6IFtcclxuICAgIGRheWpzKCkuc3VidHJhY3QoMTQsICdkYXlzJykuc3RhcnRPZignZGF5JyksXHJcbiAgICBkYXlqcygpLnN1YnRyYWN0KDgsICdkYXlzJykuZW5kT2YoJ2RheScpLFxyXG4gIF0sXHJcbiAgJ1RoaXMgTW9udGgnOiBbZGF5anMoKS5zdWJ0cmFjdCgzMCwgJ2RheXMnKSwgZGF5anMoKS5zdWJ0cmFjdCgxLCAnZGF5cycpXSxcclxuICAnTGFzdCBNb250aCc6IFtcclxuICAgIGRheWpzKCkuc3VidHJhY3QoMSwgJ21vbnRoJykuc3RhcnRPZignbW9udGgnKSxcclxuICAgIGRheWpzKCkuc3VidHJhY3QoMSwgJ21vbnRoJykuZW5kT2YoJ21vbnRoJyksXHJcbiAgXSxcclxufTtcclxuXHJcbiAgb25TdGFydERhdGVDaGFuZ2UoZXZlbnQ6IGFueSkge1xyXG4gICAgaWYgKHRoaXMuZGF5anMoZXZlbnQuc3RhcnREYXRlKS5pc1ZhbGlkKCkpIHtcclxuICAgICBcclxuICAgICAgdGhpcy5pc0N1c3RvbURhdGUgPSAobTogZGF5anMuRGF5anMpID0+IHtcclxuICAgICAgICBjb25zdCBpc1ZhbGlkRGF0ZSA9XHJcbiAgICAgICAgICBtID4gdGhpcy5kYXlqcygpIHx8IG0gPiB0aGlzLmRheWpzKGV2ZW50LnN0YXJ0RGF0ZS5hZGQoOTAsIFwiZGF5c1wiKSk7XHJcbiAgICAgICAgcmV0dXJuIGlzVmFsaWREYXRlID8gXCJpbnZhbGlkLWRhdGVcIiA6IGZhbHNlO1xyXG4gICAgICB9O1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZGF0ZWNoYW5nZShldmVudDogYW55KSB7XHJcbiAgICBpZiAoZXZlbnQgJiYgZXZlbnQuc3RhcnREYXRlICYmIGV2ZW50LmVuZERhdGUpIHtcclxuICAgICAgaWYgKFxyXG4gICAgICAgIHRoaXMuZGF5anMoZXZlbnQuc3RhcnREYXRlKS5pc1ZhbGlkKCkgJiZcclxuICAgICAgICB0aGlzLmRheWpzKGV2ZW50LmVuZERhdGUpLmlzVmFsaWQoKVxyXG4gICAgICApIHtcclxuICAgICAgICB0aGlzLnNlbGVjdGVkRGF0ZVJhbmdlLnN0YXJ0RGF0ZSA9IGV2ZW50LnN0YXJ0RGF0ZTtcclxuICAgICAgICB0aGlzLnNlbGVjdGVkRGF0ZVJhbmdlLmVuZERhdGUgPSBldmVudC5lbmREYXRlO1xyXG4gICAgICAgIHZhciBkYXRldGltZSA9IHtcclxuICAgICAgICAgIHN0YXJ0RGF0ZTogdGhpcy5kYXlqcyhldmVudC5zdGFydERhdGUsIFwiREQtTU0tWVlZWVwiKS5mb3JtYXQoXHJcbiAgICAgICAgICAgIFwiWVlZWS1NTS1ERFwiXHJcbiAgICAgICAgICApLFxyXG4gICAgICAgICAgZW5kRGF0ZTogdGhpcy5kYXlqcyhldmVudC5lbmREYXRlLCBcIkRELU1NLVlZWVlcIikuZm9ybWF0KFwiWVlZWS1NTS1ERFwiKSxcclxuICAgICAgICB9O1xyXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRGaWx0ZXJzLmRhdGUgPSBkYXRldGltZTtcclxuICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbShcclxuICAgICAgICAgIFwiaGVhZGVyLWZpbHRlcnNcIixcclxuICAgICAgICAgIEpTT04uc3RyaW5naWZ5KHRoaXMuc2VsZWN0ZWRGaWx0ZXJzKVxyXG4gICAgICAgICk7XHJcbiAgICAgICAgd2luZG93LmxvY2F0aW9uLnJlbG9hZCgpXHJcbiAgICAgIC8vIHRoaXMuZ3MuZGF0YVJhbmdlVmFsdWUubmV4dCh0aGlzLnNlbGVjdGVkRmlsdGVycyk7XHJcbiAgICAgIH1cclxuICAgIH0gXHJcbiAgfVxyXG4gIG9wZW5kcm9wZG93bihlOk1vdXNlRXZlbnQpIHtcclxuICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICB0aGlzLk9wZW5kcm9wZG93biA9ICF0aGlzLk9wZW5kcm9wZG93bjtcclxuICB9XHJcbiAgZ2V0TG9jYXRpb25zKCk6IHZvaWQge1xyXG4gICAgLy8gY29uc3QgaGVhZGVyRmlsdGVyczogYW55ID0gSlNPTi5wYXJzZShsb2NhbFN0b3JhZ2UuZ2V0SXRlbShcImhlYWRlci1maWx0ZXJzXCIpIHx8IFwie31cIik7XHJcbiAgICBsZXQgb2JqID17XHJcbiAgICAgY2xpZW50SWQ6IHRoaXMuc2VsZWN0ZWRGaWx0ZXJzLmNsaWVudCA/IHRoaXMuc2VsZWN0ZWRGaWx0ZXJzLmNsaWVudCA6dGhpcy51c2Vycy5jbGllbnRJZCxcclxuICAgICBjaXR5OiBbXSxcclxuICAgICBncm91cDogW10sXHJcbiAgICB9XHJcbiAgICB0aGlzLmF1dGguZ2V0TG9jYXRpb24ob2JqKS5zdWJzY3JpYmUoe1xyXG4gICAgICBuZXh0OiAocmVzOiBhbnkpID0+IHtcclxuICAgICAgICBsZXQgY2l0eUxpc3QgPSB0aGlzLnNlbGVjdGVkRmlsdGVycz8ubG9jYXRpb24/LmZpbHRlcigobG9jYXRpb246YW55KSA9PiBsb2NhdGlvbi5jaGVja2VkKS5tYXAoKGxvYzphbnkpID0+IGxvYy5jaXR5KTtcclxuICAgICAgICAvLyBNYXAgdGhlIGZldGNoZWQgbG9jYXRpb25zIHdpdGggZGVmYXVsdCB1bmNoZWNrZWQgc3RhdGVcclxuICAgICAgICB0aGlzLmxvY2F0aW9ucyA9IHJlcz8uZGF0YT8ubG9jYXRpb25EYXRhLm1hcCgoY2l0eTogYW55KSA9PiAoe1xyXG4gICAgICAgICAgY2l0eTogY2l0eS5jaXR5LFxyXG4gICAgICAgICAgY2hlY2tlZDogY2l0eUxpc3Q/LmluY2x1ZGVzKGNpdHkuY2l0eSkgPyB0cnVlIDogZmFsc2UgLFxyXG4gICAgICAgIH0pKTtcclxuICBcclxuICAgICAgICAvLyBTeW5jIHRoZSBmZXRjaGVkIGxvY2F0aW9ucyB3aXRoIGFueSBzdG9yZWQgY2hlY2tlZCB2YWx1ZXMgaW4gbG9jYWxTdG9yYWdlXHJcbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRGaWx0ZXJzLmxvY2F0aW9uICYmIEFycmF5LmlzQXJyYXkodGhpcy5zZWxlY3RlZEZpbHRlcnMubG9jYXRpb24pKSB7XHJcbiAgICAgICAgICB0aGlzLmZpbHRlcmVkTG9jYXRpb25zID0gdGhpcy5sb2NhdGlvbnMubWFwKGxvY2F0aW9uID0+IHtcclxuICAgICAgICAgICAgY29uc3QgbWF0Y2hlZExvY2F0aW9uID0gdGhpcy5zZWxlY3RlZEZpbHRlcnMubG9jYXRpb24uZmluZCgobG9jOiBhbnkpID0+IGxvYy5jaXR5ID09PSBsb2NhdGlvbi5jaXR5KTtcclxuICAgICAgICAgICAgcmV0dXJuIG1hdGNoZWRMb2NhdGlvbiA/IHsgLi4ubG9jYXRpb24sIGNoZWNrZWQ6IG1hdGNoZWRMb2NhdGlvbi5jaGVja2VkIH0gOiBsb2NhdGlvbjtcclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICB0aGlzLmZpbHRlcmVkTG9jYXRpb25zID0gdGhpcy5sb2NhdGlvbnM7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZih0aGlzLnNlYXJjaExvY2F0aW9uVGV4dCkge1xyXG4gICAgICAgICAgdGhpcy5maWx0ZXJlZExvY2F0aW9ucyA9IHRoaXMubG9jYXRpb25zLmZpbHRlcigobG9jYXRpb246YW55KSA9PiBsb2NhdGlvbi5jaXR5LnRvTG93ZXJDYXNlKCkuaW5jbHVkZXModGhpcy5zZWFyY2hMb2NhdGlvblRleHQudG9Mb3dlckNhc2UoKSkpXHJcbiAgICAgICAgfVxyXG4gICAgICB9LFxyXG4gICAgICBlcnJvcjogKGVycikgPT4ge1xyXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXCJGYWlsZWQgdG8gZmV0Y2ggbG9jYXRpb25zXCIsIGVycik7XHJcbiAgICAgIH0sXHJcbiAgICB9KTtcclxuICB9XHJcbiAgXHJcbiAgaXNBbGxMb2NhdGlvbnNTZWxlY3RlZCgpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLmZpbHRlcmVkTG9jYXRpb25zLmV2ZXJ5KGxvY2F0aW9uID0+IGxvY2F0aW9uLmNoZWNrZWQpO1xyXG5cclxuICB9XHJcbiAgXHJcbiAgc2VsZWN0ZWRMb2NhdGlvbnNMYWJlbCgpOiBzdHJpbmcge1xyXG4gICAgY29uc3Qgc2VsZWN0ZWRMb2NhdGlvbnMgPSB0aGlzLmxvY2F0aW9uTGFiZWwgPSB0aGlzLnNlYXJjaExvY2F0aW9uVGV4dC5sZW5ndGggPyB0aGlzLmxvY2F0aW9uc1xyXG4gICAgICAuZmlsdGVyKGxvY2F0aW9uID0+IGxvY2F0aW9uLmNoZWNrZWQpLm1hcChsb2NhdGlvbiA9PiBsb2NhdGlvbi5jaXR5KSA6ICB0aGlzLmZpbHRlcmVkTG9jYXRpb25zXHJcbiAgICAgIC5maWx0ZXIobG9jYXRpb24gPT4gbG9jYXRpb24uY2hlY2tlZCkubWFwKGxvY2F0aW9uID0+IGxvY2F0aW9uLmNpdHkpO1xyXG4gICAgcmV0dXJuIHNlbGVjdGVkTG9jYXRpb25zLmxlbmd0aCA9PT0gMFxyXG4gICAgICA/ICcnXHJcbiAgICAgIDogc2VsZWN0ZWRMb2NhdGlvbnMubGVuZ3RoID09PSAxXHJcbiAgICAgID8gc2VsZWN0ZWRMb2NhdGlvbnNbMF1cclxuICAgICAgOiBgJHtzZWxlY3RlZExvY2F0aW9ucy5sZW5ndGh9IGxvY2F0aW9uc2A7XHJcbiAgfVxyXG5cclxuICByZW1vdmVMb2NhdGlvbigpOiB2b2lkIHtcclxuICAgIHRoaXMuUmVzZXQoKTtcclxuICB9XHJcbiAgXHJcbiAgZ2V0R3JvdXBzKCk6IHZvaWQgeyAgICBcclxuICAgIGNvbnN0IGNpdHkgPSB0aGlzLmxvY2F0aW9uc1xyXG4gICAgICAuZmlsdGVyKGxvY2F0aW9uID0+IGxvY2F0aW9uLmNoZWNrZWQpXHJcbiAgICAgIC5tYXAobG9jYXRpb24gPT4gbG9jYXRpb24uY2l0eSk7XHJcbiAgICBjb25zdCBvYmogPSB7IGNpdHksY2xpZW50SWQ6dGhpcy5zZWxlY3RlZEZpbHRlcnMuY2xpZW50ID8gdGhpcy5zZWxlY3RlZEZpbHRlcnMuY2xpZW50IDp0aGlzLnVzZXJzLmNsaWVudElkLGdyb3VwOltdIH07XHJcbiAgICB0aGlzLmF1dGguZ2V0R3JvdXBzKG9iaikuc3Vic2NyaWJlKHtcclxuICAgICAgbmV4dDogKHJlczogYW55KSA9PiB7XHJcbiAgICAgICAgbGV0IGNoZWNrZWRHcm91cCA9IHRoaXMuc2VsZWN0ZWRGaWx0ZXJzPy5ncm91cD8uZmlsdGVyKChncm91cDphbnkpID0+IGdyb3VwLmNoZWNrZWQpLm1hcCgoZ3JvdXA6YW55KSA9PiBncm91cC5ncm91cE5hbWUpO1xyXG4gICAgICAgIGNvbnN0IGNvbWJpbmVkR3JvdXBzID0gcmVzPy5kYXRhPy5ncm91cERhdGE/Lm1hcCgoZ3JvdXBOYW1lOiBhbnkpID0+ICh7XHJcbiAgICAgICAgICBncm91cE5hbWU6IGdyb3VwTmFtZS5ncm91cE5hbWUsXHJcbiAgICAgICAgICBjaGVja2VkOiBjaGVja2VkR3JvdXA/LmluY2x1ZGVzKGdyb3VwTmFtZS5ncm91cE5hbWUpID8gdHJ1ZSA6IGZhbHNlLFxyXG4gICAgICAgIH0pKTtcclxuICAgICAgICB0aGlzLmdyb3Vwc0RhdGEgPSBjb21iaW5lZEdyb3VwcztcclxuICAgICAgICBpZih0aGlzLnNlYXJjaEdyb3VwVGV4dC5sZW5ndGgpIHtcclxuICAgICAgICAgIHRoaXMuZmlsdGVyZWRHcm91cHMgPSBjb21iaW5lZEdyb3Vwcy5maWx0ZXIoKGl0ZW06YW55KSA9PiBpdGVtLmdyb3VwTmFtZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHRoaXMuc2VhcmNoR3JvdXBUZXh0KSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgdGhpcy5maWx0ZXJlZEdyb3VwcyA9IGNvbWJpbmVkR3JvdXBzO1xyXG4gICAgICAgIH1cclxuICBcclxuICAgICAgICAvLyBBdXRvLWZldGNoIHN0b3JlcyB3aGVuIGdyb3VwcyBhcmUgc2VsZWN0ZWRcclxuICAgICAgICBjb25zdCBzZWxlY3RlZEdyb3VwcyA9IHRoaXMuZ3JvdXBzRGF0YS5maWx0ZXIoKGdyb3VwKSA9PiBncm91cC5jaGVja2VkKS5tYXAoKGdyb3VwKSA9PiBncm91cC5ncm91cE5hbWUpO1xyXG4gICAgICAgIGlmIChzZWxlY3RlZEdyb3Vwcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICB0aGlzLmdldFN0b3JlKCk7IC8vIEZldGNoIHN0b3JlcyBiYXNlZCBvbiBzZWxlY3RlZCBncm91cHNcclxuICAgICAgICB9XHJcbiAgICAgIH0sXHJcbiAgICAgIGVycm9yOiAoZXJyKSA9PiB7XHJcbiAgICAgICAgY29uc29sZS5lcnJvcihcIkZhaWxlZCB0byBmZXRjaCBncm91cHNcIiwgZXJyKTtcclxuICAgICAgfSxcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgdG9nZ2xlRHJvcGRvd24odHlwZTogJ2xvY2F0aW9uJyB8ICdncm91cCcgfCAnc3RvcmUnKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5kcm9wZG93bk9wZW4gPT09IHR5cGUpIHtcclxuICAgICAgLy8gSWYgdGhlIGRyb3Bkb3duIGlzIG9wZW4sIGNsb3NlIGl0IGFuZCBhdm9pZCByZXNldHRpbmcgdGhlIHNlbGVjdGVkIHZhbHVlcyB1bm5lY2Vzc2FyaWx5XHJcbiAgICAgIHRoaXMuZHJvcGRvd25PcGVuID0gbnVsbDtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIC8vIE9wZW4gdGhlIHNwZWNpZmljIGRyb3Bkb3duIGFuZCBoYW5kbGUgZGF0YSBmZXRjaGluZyBvbmx5IGlmIG5lY2Vzc2FyeVxyXG4gICAgICB0aGlzLmRyb3Bkb3duT3BlbiA9IHR5cGU7XHJcbiAgXHJcbiAgICAgIGlmICh0eXBlID09PSAnZ3JvdXAnKSB7XHJcbiAgICAgICAgLy8gRmV0Y2ggZ3JvdXBzIG9ubHkgaWYgdGhlcmUgYXJlIHNlbGVjdGVkIGNpdGllcyBhbmQgbm8gYWN0aXZlIHNlYXJjaCB0ZXh0XHJcbiAgICAgICAgY29uc3Qgc2VsZWN0ZWRDaXRpZXMgPSB0aGlzLmxvY2F0aW9uc1xyXG4gICAgICAgICAgLmZpbHRlcigobG9jYXRpb24pID0+IGxvY2F0aW9uLmNoZWNrZWQpXHJcbiAgICAgICAgICAubWFwKChsb2NhdGlvbikgPT4gbG9jYXRpb24uY2l0eSk7XHJcbiAgXHJcbiAgICAgICAgLy8gRmV0Y2ggZ3JvdXBzIG9ubHkgaWYgbG9jYXRpb25zIGFyZSBzZWxlY3RlZCwgbm8gc2VhcmNoIHRleHQgZXhpc3RzLCBhbmQgZHJvcGRvd24gaXMgb3BlbmVkXHJcbiAgICAgIGlmICh0aGlzLmZpbHRlcmVkTG9jYXRpb25zLmxlbmd0aCA+IDAgfHwgKHNlbGVjdGVkQ2l0aWVzLmxlbmd0aCA+IDAgJiYgIXRoaXMuc2VhcmNoR3JvdXBUZXh0LnRyaW0oKSkpIHtcclxuICAgICAgICB0aGlzLmdldEdyb3VwcygpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuZmlsdGVyZWRHcm91cHMgPSBbXTsgLy8gQ2xlYXIgZ3JvdXBzIGlmIG5vIGxvY2F0aW9ucyBhcmUgc2VsZWN0ZWRcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlID09PSAnc3RvcmUnKSB7XHJcbiAgICAgIC8vIEZldGNoIHN0b3JlcyBvbmx5IGlmIG5vdCBhbHJlYWR5IGZldGNoZWQgYW5kIG5vIHNlYXJjaCB0ZXh0IGlzIGFjdGl2ZVxyXG4gICAgICBpZiAoKCF0aGlzLmZpbHRlcmVkU3RvcmVzIHx8IHRoaXMuZmlsdGVyZWRTdG9yZXMubGVuZ3RoID09PSAwKSAmJiAhdGhpcy5zZWFyY2hTdG9yZVRleHQudHJpbSgpKSB7XHJcbiAgICAgICAgdGhpcy5nZXRTdG9yZSgpO1xyXG4gICAgICB9IFxyXG4gICAgfVxyXG4gICAgfVxyXG4gIH1cclxuICBcclxuICBcclxuICBoYW5kbGVHcm91cERyb3Bkb3duQ2xpY2soKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5kcm9wZG93bk9wZW4gPT09ICdncm91cCcpIHtcclxuICAgICAgdGhpcy5yZXNldFNlbGVjdGVkR3JvdXBzKCk7XHJcbiAgICB9XHJcbiAgICB0aGlzLnRvZ2dsZURyb3Bkb3duKCdncm91cCcpO1xyXG4gIH1cclxuXHJcbiAgcmVzZXRTZWxlY3RlZEdyb3VwcygpOiB2b2lkIHtcclxuICAgIHRoaXMuZmlsdGVyZWRHcm91cHMuZm9yRWFjaCgoZ3JvdXApID0+IChncm91cC5jaGVja2VkID0gZmFsc2UpKTtcclxuICAgIHRoaXMuc2VhcmNoR3JvdXBUZXh0ID0gXCJcIjtcclxuICB9XHJcbiAgc2VsZWN0ZWRHcm91cHNMYWJlbCgpOiBzdHJpbmcge1xyXG4gICAgY29uc3Qgc2VsZWN0ZWRHcm91cHMgPSB0aGlzLmdyb3VwTGFiZWwgPSB0aGlzLnNlYXJjaEdyb3VwVGV4dC5sZW5ndGggPyB0aGlzLmdyb3Vwc0RhdGEuZmlsdGVyKChncm91cCkgPT4gZ3JvdXAuY2hlY2tlZCkgOiB0aGlzLmZpbHRlcmVkR3JvdXBzLmZpbHRlcigoZ3JvdXApID0+IGdyb3VwLmNoZWNrZWQpO1xyXG4gICAgcmV0dXJuIHNlbGVjdGVkR3JvdXBzLmxlbmd0aCA9PT0gMFxyXG4gICAgICA/IFwiXCJcclxuICAgICAgOiBzZWxlY3RlZEdyb3Vwcy5sZW5ndGggPT09IDFcclxuICAgICAgPyBzZWxlY3RlZEdyb3Vwc1swXS5ncm91cE5hbWVcclxuICAgICAgOiBgJHtzZWxlY3RlZEdyb3Vwcy5sZW5ndGh9IGdyb3Vwc2A7XHJcbiAgfVxyXG4gIHJlbW92ZUdyb3VwKCk6IHZvaWQge1xyXG4gICAgdGhpcy5SZXNldCgpO1xyXG4gICBcclxuICB9XHJcbiAgXHJcblxyXG4gIGlzQWxsR3JvdXBzU2VsZWN0ZWQoKTogYm9vbGVhbiB7XHJcbiAgICBcclxuICAgIHJldHVybiB0aGlzLmZpbHRlcmVkR3JvdXBzLmxlbmd0aCA/IHRoaXMuZmlsdGVyZWRHcm91cHMuZXZlcnkoKGdyb3VwKSA9PiBncm91cC5jaGVja2VkKSA6IGZhbHNlO1xyXG4gIH1cclxuICAgICAgICBcclxuICBnZXRTdG9yZSgpOiB2b2lkIHtcclxuICAgIGNvbnN0IGNpdHkgPSB0aGlzLmxvY2F0aW9uc1xyXG4gICAgICAuZmlsdGVyKGxvY2F0aW9uID0+IGxvY2F0aW9uLmNoZWNrZWQpXHJcbiAgICAgIC5tYXAobG9jYXRpb24gPT4gbG9jYXRpb24uY2l0eSk7XHJcbiAgXHJcbiAgICBjb25zdCBncm91cCA9IHRoaXMuZ3JvdXBzRGF0YVxyXG4gICAgICAuZmlsdGVyKGdyb3VwID0+IGdyb3VwLmNoZWNrZWQpXHJcbiAgICAgIC5tYXAoZ3JvdXAgPT4gZ3JvdXAuZ3JvdXBOYW1lKTtcclxuICBcclxuICAgIGNvbnN0IGRhdGEgPSB7IGNpdHksIGNsdXN0ZXJzOmdyb3VwLCBjbGllbnRJZDogdGhpcy51c2Vycy5jbGllbnRJZCA/IHRoaXMudXNlcnMuY2xpZW50SWQgOiB0aGlzLnNlbGVjdGVkRmlsdGVycy5jbGllbnQgfTtcclxuICBcclxuICAgIHRoaXMuYXV0aC5nZXRIZWFkZXJTdG9yZXMoZGF0YSkuc3Vic2NyaWJlKHtcclxuICAgICAgbmV4dDogKHJlczogYW55KSA9PiB7XHJcbiAgICAgICAgaWYocmVzICYmcmVzLmNvZGUgPT09MjAwKXtcclxuICAgICAgICB0aGlzLnN0b3JlcyA9IHJlcy5kYXRhLnN0b3Jlc0RhdGE7ICAgICAgXHJcbiAgICAgICAgLy8gUmV0cmlldmUgY2hlY2tlZCBzdG9yZSBJRHMgZnJvbSBzZWxlY3RlZEZpbHRlcnNcclxuICAgICAgICBjb25zdCBjaGVja2VkU3RvcmVJZHMgPSB0aGlzLnNlbGVjdGVkRmlsdGVycz8uc3RvcmVzXHJcbiAgICAgICAgICA/IHRoaXMuc2VsZWN0ZWRGaWx0ZXJzLnN0b3Jlcy5maWx0ZXIoKHN0b3JlOiBhbnkpID0+IHN0b3JlLmNoZWNrZWQpLm1hcCgoc3RvcmU6IGFueSkgPT4gc3RvcmUuc3RvcmVJZClcclxuICAgICAgICAgIDogW107XHJcblxyXG4gICAgICAgIHRoaXMuc3RvcmVzLmZvckVhY2goc3RvcmUgPT4ge1xyXG4gICAgICAgICAgaWYgKGNoZWNrZWRTdG9yZUlkcy5pbmNsdWRlcyhzdG9yZS5zdG9yZUlkKSkge1xyXG4gICAgICAgICAgICBzdG9yZS5jaGVja2VkID0gdHJ1ZTsgLy8gU3luYyB0aGUgY2hlY2tlZCBzdGF0ZSB3aXRoIGZ1bGwgc3RvcmUgbGlzdFxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIFxyXG4gIFxyXG4gICAgICAgIC8vIE1hcCB0aGUgc3RvcmVzIGFuZCByZXRhaW4gdGhlICdjaGVja2VkJyBzdGF0dXNcclxuICAgICAgICBpZih0aGlzLnNlYXJjaFN0b3JlVGV4dC5sZW5ndGgpIHtcclxuICAgICAgICAgIHRoaXMuZmlsdGVyZWRTdG9yZXMgPSB0aGlzLnN0b3Jlcz8uZmlsdGVyKHN0b3JlID0+IHN0b3JlLnN0b3JlTmFtZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHRoaXMuc2VhcmNoU3RvcmVUZXh0KSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgdGhpcy5maWx0ZXJlZFN0b3JlcyA9IHRoaXMuc3RvcmVzO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBFbnN1cmUgc2VsZWN0ZWRGaWx0ZXJzIGlzIGluIHN5bmMgd2l0aCBmaWx0ZXJlZFN0b3Jlc1xyXG4gICAgICAgIGlmICghdGhpcy5zZWxlY3RlZEZpbHRlcnMuc3RvcmVzIHx8ICF0aGlzLnNlbGVjdGVkRmlsdGVycy5zdG9yZXMubGVuZ3RoKSB7XHJcbiAgICAgICAgICB0aGlzLnN0b3Jlcy5mb3JFYWNoKHN0b3JlID0+IHtcclxuICAgICAgICAgICAgc3RvcmUuY2hlY2tlZCA9IHRydWU7IC8vIFN5bmMgdGhlIGNoZWNrZWQgc3RhdGUgd2l0aCBmdWxsIHN0b3JlIGxpc3RcclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgXHJcbiAgICAgICAgICAvLyBObyBwcmV2aW91c2x5IHNlbGVjdGVkIHN0b3JlcywgbWFyayBhbGwgYXMgY2hlY2tlZFxyXG4gICAgICAgdGhpcy5maWx0ZXJlZFN0b3JlcyA9IHRoaXMuc2VsZWN0ZWRGaWx0ZXJzLnN0b3JlcyA9IHRoaXMuZmlsdGVyZWRTdG9yZXMubWFwKHN0b3JlID0+ICh7XHJcbiAgICAgICAgICAgIC4uLnN0b3JlLFxyXG4gICAgICAgICAgICBjaGVja2VkOiB0cnVlXHJcbiAgICAgICAgICB9KSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIC8vIFVwZGF0ZSBzZWxlY3RlZEZpbHRlcnMgdG8gcmVmbGVjdCBjdXJyZW50IHN0YXRlIG9mIHN0b3Jlc1xyXG4gICAgICAgICAgdGhpcy5zZWxlY3RlZEZpbHRlcnMuc3RvcmVzID0gdGhpcy5maWx0ZXJlZFN0b3Jlcy5tYXAoc3RvcmUgPT4gKHtcclxuICAgICAgICAgICAgLi4uc3RvcmUsXHJcbiAgICAgICAgICAgIGNoZWNrZWQ6IHN0b3JlLmNoZWNrZWRcclxuICAgICAgICAgIH0pKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gVXBkYXRlIGxvY2FsU3RvcmFnZSB3aXRoIHRoZSBsYXRlc3Qgc2VsZWN0ZWRGaWx0ZXJzXHJcbiAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ2hlYWRlci1maWx0ZXJzJywgSlNPTi5zdHJpbmdpZnkodGhpcy5zZWxlY3RlZEZpbHRlcnMpKTtcclxuICBcclxuICAgICAgICAvLyBFbWl0IGRhdGEgdmlhIHNlcnZpY2VcclxuICAgICAgICAvLyB0aGlzLmdzLmRhdGFSYW5nZVZhbHVlLm5leHQodGhpcy5zZWxlY3RlZEZpbHRlcnMpO1xyXG4gICAgICAgIC8vIFRyaWdnZXIgY2hhbmdlIGRldGVjdGlvbiB0byByZWZsZWN0IGNoYW5nZXMgaW4gdGhlIFVJXHJcbiAgICAgICAgdGhpcy5jZC5kZXRlY3RDaGFuZ2VzKCk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5zdG9yZXMgPVtdO1xyXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRGaWx0ZXJzLnN0b3Jlcz1bXTtcclxuICAgICAgICB0aGlzLmZpbHRlcmVkU3RvcmVzID1bXTtcclxuICAgICAgICB0aGlzLnNlbGVjdGVkRmlsdGVycy5zdG9yZXMgPSB0aGlzLmZpbHRlcmVkU3RvcmVzLm1hcChzdG9yZSA9PiAoe1xyXG4gICAgICAgICAgLi4uc3RvcmUsXHJcbiAgICAgICAgICBjaGVja2VkOiBmYWxzZVxyXG4gICAgICAgIH0pKTtcclxuICAgICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnaGVhZGVyLWZpbHRlcnMnLCBKU09OLnN0cmluZ2lmeSh0aGlzLnNlbGVjdGVkRmlsdGVycykpO1xyXG4gICAgICB9XHJcbiAgICB9LFxyXG4gICAgICBlcnJvcjogKGVycikgPT4ge1xyXG4gICAgICAgIHRoaXMuc3RvcmVzID1bXTsgICBcclxuICAgICAgICB0aGlzLnNlbGVjdGVkRmlsdGVycy5zdG9yZXMgPSB0aGlzLmZpbHRlcmVkU3RvcmVzLm1hcChzdG9yZSA9PiAoe1xyXG4gICAgICAgICAgLi4uc3RvcmUsXHJcbiAgICAgICAgICBjaGVja2VkOiBmYWxzZVxyXG4gICAgICAgIH0pKTtcclxuICAgICAgICB0aGlzLmZpbHRlcmVkU3RvcmVzID1bXTtcclxuICAgICAgICB0aGlzLnNlbGVjdGVkRmlsdGVycy5zdG9yZXM9W107XHJcbiAgICAgICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ2hlYWRlci1maWx0ZXJzJywgSlNPTi5zdHJpbmdpZnkodGhpcy5zZWxlY3RlZEZpbHRlcnMpKTtcclxuICAgICAgICBjb25zb2xlLmVycm9yKFwiRmFpbGVkIHRvIGZldGNoIHN0b3Jlc1wiLCBlcnIpO1xyXG4gICAgICB9LFxyXG4gICAgfSk7XHJcbiAgfVxyXG4gIFxyXG5cclxuICByZXNldFNlbGVjdGVkU3RvcmVzKCk6IHZvaWQge1xyXG4gICAgdGhpcy5maWx0ZXJlZFN0b3Jlcy5mb3JFYWNoKChzdG9yZSkgPT4gKHN0b3JlLmNoZWNrZWQgPSBmYWxzZSkpO1xyXG4gICAgdGhpcy5zZWFyY2hTdG9yZVRleHQgPSBcIlwiO1xyXG4gIH1cclxuXHJcbiAgc2VsZWN0ZWRTdG9yZXNMYWJlbCgpOiBzdHJpbmcge1xyXG4gICAgY29uc3Qgc2VsZWN0ZWRTdG9yZXMgPSB0aGlzLnNlYXJjaFN0b3JlVGV4dC5sZW5ndGggPyB0aGlzLnN0b3Jlcy5maWx0ZXIoKHN0b3JlKSA9PiBzdG9yZS5jaGVja2VkKSA6IHRoaXMuZmlsdGVyZWRTdG9yZXMuZmlsdGVyKChzdG9yZSkgPT4gc3RvcmUuY2hlY2tlZCk7XHJcbiAgICByZXR1cm4gc2VsZWN0ZWRTdG9yZXMubGVuZ3RoID09PSAwXHJcbiAgICAgID8gXCIwIFN0b3Jlc1wiXHJcbiAgICAgIDogc2VsZWN0ZWRTdG9yZXMubGVuZ3RoID09PSAxXHJcbiAgICAgID8gc2VsZWN0ZWRTdG9yZXNbMF0uc3RvcmVOYW1lXHJcbiAgICAgIDogYCR7c2VsZWN0ZWRTdG9yZXMubGVuZ3RofSBTdG9yZXNgO1xyXG4gIH1cclxuXHJcbiAgaXNBbGxTdG9yZXNTZWxlY3RlZCgpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLmZpbHRlcmVkU3RvcmVzLmxlbmd0aCA+IDAgJiYgdGhpcy5maWx0ZXJlZFN0b3Jlcy5ldmVyeShzdG9yZSA9PiBzdG9yZS5jaGVja2VkKTtcclxuICB9XHJcbi8vIE1ldGhvZCB0byBoYW5kbGUgZHJvcGRvd24gaXRlbSBzZWxlY3Rpb25cclxudXBkYXRlU2VsZWN0ZWRTdG9yZXMoKTogdm9pZCB7XHJcbiAgdGhpcy5maWx0ZXJlZFN0b3Jlcy5mb3JFYWNoKHN0b3JlID0+IHtcclxuICAgIGNvbnN0IGZpbHRlcmVkU3RvcmUgPSB0aGlzLnN0b3Jlcy5maW5kSW5kZXgoZlN0b3JlID0+IGZTdG9yZS5zdG9yZUlkID09PSBzdG9yZS5zdG9yZUlkKTtcclxuICAgIGlmIChmaWx0ZXJlZFN0b3JlICE9IC0xKSB7XHJcbiAgICAgIHRoaXMuc3RvcmVzW2ZpbHRlcmVkU3RvcmVdLmNoZWNrZWQgPSBzdG9yZS5jaGVja2VkOyAvLyBTeW5jIHRoZSBjaGVja2VkIHN0YXRlIHdpdGggZnVsbCBzdG9yZSBsaXN0XHJcbiAgICB9XHJcbiAgfSk7ICBcclxuICAvLyBVcGRhdGUgc2VsZWN0ZWRGaWx0ZXJzIGJhc2VkIG9uIHRoZSBjdXJyZW50IHN0b3JlIHNlbGVjdGlvblxyXG4gIHRoaXMuc2VsZWN0ZWRGaWx0ZXJzLnN0b3JlcyA9IHRoaXMuc3RvcmVzLmZpbHRlcihzdG9yZSA9PiBzdG9yZS5jaGVja2VkKTtcclxuXHJcbiAgLy8gVXBkYXRlIGxvY2FsU3RvcmFnZSB3aXRoIHRoZSBsYXRlc3Qgc2VsZWN0aW9uXHJcbiAgbG9jYWxTdG9yYWdlLnNldEl0ZW0oJ2hlYWRlci1maWx0ZXJzJywgSlNPTi5zdHJpbmdpZnkodGhpcy5zZWxlY3RlZEZpbHRlcnMpKTtcclxuXHJcbiAgLy8gRW1pdCB1cGRhdGVkIGZpbHRlcnMgdmlhIHNlcnZpY2VcclxuICAvLyB0aGlzLmdzLmRhdGFSYW5nZVZhbHVlLm5leHQodGhpcy5zZWxlY3RlZEZpbHRlcnMpO1xyXG5cclxuICAvLyBUcmlnZ2VyIGNoYW5nZSBkZXRlY3Rpb24gaWYgbmVjZXNzYXJ5XHJcbiAgdGhpcy5jZC5kZXRlY3RDaGFuZ2VzKCk7XHJcbn1cclxuICB0b2dnbGVTZWxlY3RBbGxMb2NhdGlvbnMoZXZlbnQ6IGFueSk6IHZvaWQge1xyXG4gICAgY29uc3QgaXNDaGVja2VkID0gZXZlbnQudGFyZ2V0LmNoZWNrZWQ7XHJcbiAgICB0aGlzLmZpbHRlcmVkTG9jYXRpb25zLmZvckVhY2goKGxvY2F0aW9uKSA9PiAobG9jYXRpb24uY2hlY2tlZCA9IGlzQ2hlY2tlZCkpO1xyXG4gICAgdGhpcy51cGRhdGVTZWxlY3RlZExvY2F0aW9ucygpO1xyXG4gIH1cclxuXHJcbiAgdG9nZ2xlU2VsZWN0QWxsU3RvcmVzKGV2ZW50OiBFdmVudCk6IHZvaWQge1xyXG4gICAgY29uc3QgY2hlY2tlZCA9IChldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudCkuY2hlY2tlZDtcclxuICBcclxuICAgIC8vIEFwcGx5IHRoZSBzZWxlY3Rpb24gdG8gYm90aCBmaWx0ZXJlZCBhbmQgZnVsbCBsaXN0IG9mIHN0b3Jlc1xyXG4gICAgdGhpcy5maWx0ZXJlZFN0b3Jlcy5mb3JFYWNoKHN0b3JlID0+IHN0b3JlLmNoZWNrZWQgPSBjaGVja2VkKTtcclxuICAgIHRoaXMuc3RvcmVzLmZvckVhY2goc3RvcmUgPT4ge1xyXG4gICAgICBjb25zdCBmaWx0ZXJlZFN0b3JlID0gdGhpcy5maWx0ZXJlZFN0b3Jlcy5maW5kKGZTdG9yZSA9PiBmU3RvcmUuc3RvcmVJZCA9PT0gc3RvcmUuc3RvcmVJZCk7XHJcbiAgICAgIGlmIChmaWx0ZXJlZFN0b3JlKSB7XHJcbiAgICAgICAgc3RvcmUuY2hlY2tlZCA9IGNoZWNrZWQ7IC8vIFN5bmMgdGhlIGNoZWNrZWQgc3RhdGUgd2l0aCBmdWxsIHN0b3JlIGxpc3RcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgXHJcbiAgICAvLyBVcGRhdGUgdGhlIHNlbGVjdGVkIHN0b3JlcyBhbmQgcGVyc2lzdCB0aGUgc2VsZWN0aW9uXHJcbiAgICB0aGlzLnVwZGF0ZVNlbGVjdGVkU3RvcmVzKCk7XHJcbiAgfVxyXG5cclxuICB1cGRhdGVTZWxlY3RlZExvY2F0aW9ucygpOiB2b2lkIHtcclxuICAgIC8vIFdoZW4gbG9jYXRpb25zIGFyZSBzZWxlY3RlZCwgZmV0Y2ggdGhlIHJlbGF0ZWQgZ3JvdXBzXHJcbiAgICBjb25zdCBzZWxlY3RlZENpdGllcyA9IHRoaXMuZmlsdGVyZWRMb2NhdGlvbnNcclxuICAgICAgLmZpbHRlcigobG9jYXRpb24pID0+IGxvY2F0aW9uLmNoZWNrZWQpXHJcbiAgICAgIC5tYXAoKGxvY2F0aW9uKSA9PiBsb2NhdGlvbi5jaXR5KTtcclxuICAgIHRoaXMuZmlsdGVyZWRMb2NhdGlvbnMuZm9yRWFjaCgobG9jYXRpb246YW55KSA9PiB7XHJcbiAgICAgIGxldCBmaW5kTG9jYXRpb25JbmRleCA9IHRoaXMubG9jYXRpb25zLmZpbmRJbmRleCgobG9jOmFueSkgPT4gbG9jLmNpdHkgPT0gbG9jYXRpb24uY2l0eSk7XHJcbiAgICAgIGlmKGZpbmRMb2NhdGlvbkluZGV4ICE9IC0xKSB7XHJcbiAgICAgICAgdGhpcy5sb2NhdGlvbnNbZmluZExvY2F0aW9uSW5kZXhdLmNoZWNrZWQgPSBsb2NhdGlvbi5jaGVja2VkO1xyXG4gICAgICB9XHJcbiAgICB9KVxyXG4gICAgaWYgKHNlbGVjdGVkQ2l0aWVzLmxlbmd0aCA+IDAgfHwgIXNlbGVjdGVkQ2l0aWVzLmxlbmd0aCkge1xyXG4gICAgICB0aGlzLnNlbGVjdGVkRmlsdGVycy5zdG9yZXMgPVtdO1xyXG4gICAgICB0aGlzLnNlbGVjdGVkRmlsdGVycy5sb2NhdGlvbiA9IHRoaXMubG9jYXRpb25zO1xyXG4gICAgICB0aGlzLmdldEdyb3VwcygpOyAvLyBGZXRjaCBncm91cHMgYmFzZWQgb24gc2VsZWN0ZWQgY2l0aWVzXHJcbiAgICAgIC8vIElmIHRoZXJlIGFyZSBzZWxlY3RlZCBncm91cHMsIGZldGNoIHRoZSBzdG9yZXMgYmFzZWQgb24gc2VsZWN0ZWQgZ3JvdXBzXHJcbiAgICAgIHRoaXMuZ2V0U3RvcmUoKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuZmlsdGVyZWRHcm91cHMgPSBbXTsgLy8gQ2xlYXIgZ3JvdXBzIGlmIG5vIGxvY2F0aW9ucyBhcmUgc2VsZWN0ZWRcclxuICAgICAgdGhpcy5zZWxlY3RlZEZpbHRlcnMubG9jYXRpb24gPSBbXVxyXG4gICAgfVxyXG4gICAgdGhpcy5zZWxlY3RlZEZpbHRlcnMuZ3JvdXAgPSBbXTtcclxuICBcclxuICAgIHRoaXMuZmlsdGVyZWRTdG9yZXMgPSBbXTsgLy8gUmVzZXQgc3RvcmVzIGFzIHdlbGxcclxuICAgIHRoaXMuc2VhcmNoR3JvdXBUZXh0ID0gJyc7XHJcbiAgICB0aGlzLnNlYXJjaFN0b3JlVGV4dCA9ICcnO1xyXG4gICAgLy8gdGhpcy5PcGVuZHJvcGRvd24gPSBmYWxzZTtcclxuICB9XHJcblxyXG4gIHRvZ2dsZVNlbGVjdEFsbEdyb3VwcyhldmVudDogYW55KTogdm9pZCB7XHJcbiAgICBjb25zdCBpc0NoZWNrZWQgPSBldmVudC50YXJnZXQuY2hlY2tlZDtcclxuICAgIHRoaXMuZmlsdGVyZWRHcm91cHMuZm9yRWFjaCgoZ3JvdXApID0+IChncm91cC5jaGVja2VkID0gaXNDaGVja2VkKSk7XHJcbiAgICB0aGlzLnVwZGF0ZVNlbGVjdGVkR3JvdXBzKCk7XHJcbiAgICAvLyBpZiAoIWlzQ2hlY2tlZCkge1xyXG4gICAgLy8gICB0aGlzLnNlbGVjdGVkRmlsdGVycy5zdG9yZXMgPVtdO1xyXG4gICAgLy8gICAgLy8gSWYgdGhlcmUgYXJlIHNlbGVjdGVkIGdyb3VwcywgZmV0Y2ggdGhlIHN0b3JlcyBiYXNlZCBvbiBzZWxlY3RlZCBncm91cHNcclxuICAgIC8vICAgIHRoaXMuZ2V0U3RvcmUoKTtcclxuICAgIC8vICB9XHJcbiAgfVxyXG5cclxuICB1cGRhdGVTZWxlY3RlZEdyb3VwcygpOiB2b2lkIHtcclxuICAgIC8vIEZldGNoIHRoZSByZWxldmFudCBzdG9yZXMgYWZ0ZXIgZ3JvdXBzIGFyZSBzZWxlY3RlZFxyXG4gICAgY29uc3Qgc2VsZWN0ZWRHcm91cHMgPSB0aGlzLmZpbHRlcmVkR3JvdXBzXHJcbiAgICAgIC5maWx0ZXIoKGdyb3VwKSA9PiBncm91cC5jaGVja2VkKVxyXG4gICAgICAubWFwKChncm91cCkgPT4gZ3JvdXAuZ3JvdXBOYW1lKTtcclxuXHJcbiAgICB0aGlzLmZpbHRlcmVkR3JvdXBzLmZvckVhY2goKGdyb3VwOmFueSkgPT4ge1xyXG4gICAgICBsZXQgZmluZEdyb3VwSW5kZXggPSB0aGlzLmdyb3Vwc0RhdGEuZmluZEluZGV4KChpdGVtOmFueSkgPT4gaXRlbS5ncm91cE5hbWUgPT0gZ3JvdXAuZ3JvdXBOYW1lKTtcclxuICAgICAgaWYoZmluZEdyb3VwSW5kZXggIT0gLTEpIHtcclxuICAgICAgICB0aGlzLmdyb3Vwc0RhdGFbZmluZEdyb3VwSW5kZXhdLmNoZWNrZWQgPSBncm91cC5jaGVja2VkO1xyXG4gICAgICB9XHJcbiAgICB9KSBcclxuICAgIGlmIChzZWxlY3RlZEdyb3Vwcy5sZW5ndGggPiAwIHx8ICFzZWxlY3RlZEdyb3Vwcy5sZW5ndGgpIHtcclxuICAgICAgdGhpcy5zZWxlY3RlZEZpbHRlcnMuc3RvcmVzID1bXTtcclxuICAgICAgLy8gSWYgdGhlcmUgYXJlIHNlbGVjdGVkIGdyb3VwcywgZmV0Y2ggdGhlIHN0b3JlcyBiYXNlZCBvbiBzZWxlY3RlZCBncm91cHNcclxuICAgICAgdGhpcy5nZXRTdG9yZSgpO1xyXG4gICAgICB0aGlzLnNlbGVjdGVkRmlsdGVycy5ncm91cCA9IHRoaXMuZ3JvdXBzRGF0YTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIC8vIElmIG5vIGdyb3VwcyBhcmUgc2VsZWN0ZWQsIGNsZWFyIHRoZSBzdG9yZXMgbGlzdFxyXG4gICAgICB0aGlzLmZpbHRlcmVkU3RvcmVzID0gW107XHJcbiAgICAgIFxyXG4gICAgICAvLyBBbHNvLCB1cGRhdGUgbG9jYWxTdG9yYWdlIHRvIHJlZmxlY3QgdGhlIGNsZWFyZWQgc3RvcmUgc2VsZWN0aW9uXHJcbiAgICAgIHRoaXMuc2VsZWN0ZWRGaWx0ZXJzLnN0b3JlcyA9IFtdO1xyXG4gICAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSgnaGVhZGVyLWZpbHRlcnMnLCBKU09OLnN0cmluZ2lmeSh0aGlzLnNlbGVjdGVkRmlsdGVycykpO1xyXG4gIFxyXG4gICAgICAvLyBFbWl0IGRhdGEgdmlhIHNlcnZpY2VcclxuICAgICAgLy8gdGhpcy5ncy5kYXRhUmFuZ2VWYWx1ZS5uZXh0KHRoaXMuc2VsZWN0ZWRGaWx0ZXJzKTtcclxuICAgIH1cclxuICBcclxuICAgIC8vIENsZWFyIHRoZSBzZWFyY2ggc3RvcmUgdGV4dCB3aGVuIGdyb3VwcyBhcmUgdXBkYXRlZFxyXG4gICAgdGhpcy5zZWFyY2hTdG9yZVRleHQgPSAnJztcclxuICB9XHJcbiAgXHJcblxyXG4gIFJlc2V0KCk6IHZvaWQge1xyXG4gICAgIC8vIENsZWFyIHNlbGVjdGVkIGdyb3Vwcywgc3RvcmVzLCBhbmQgbG9jYXRpb25zXHJcbiAgdGhpcy5maWx0ZXJlZEdyb3VwcyA9IFtdO1xyXG4gIHRoaXMuZmlsdGVyZWRTdG9yZXMgPSBbXTtcclxuICB0aGlzLmZpbHRlcmVkTG9jYXRpb25zID0gW107IC8vIFJlc2V0IGxvY2F0aW9ucyBhcyB3ZWxsXHJcblxyXG4gIC8vIENsZWFyIHNlYXJjaCBpbnB1dCBmaWVsZHNcclxuICB0aGlzLnNlYXJjaExvY2F0aW9uVGV4dCA9IFwiXCI7XHJcbiAgdGhpcy5zZWFyY2hHcm91cFRleHQgPSBcIlwiO1xyXG4gIHRoaXMuc2VhcmNoU3RvcmVUZXh0ID0gXCJcIjtcclxuXHJcbiAgLy8gRmV0Y2ggbG9jYXRpb25zLCBncm91cHMsIGFuZCBzdG9yZXMgYWdhaW5cclxuICB0aGlzLmdldExvY2F0aW9ucygpO1xyXG4gIHRoaXMuZ2V0U3RvcmUoKTtcclxuICB0aGlzLmdldEdyb3VwcygpO1xyXG4gIC8vIFJlc2V0IHRoZSBmaWx0ZXJzIGluIHNlbGVjdGVkRmlsdGVyc1xyXG4gIHRoaXMuc2VsZWN0ZWRGaWx0ZXJzID0ge1xyXG4gICAgLi4udGhpcy5zZWxlY3RlZEZpbHRlcnMsXHJcbiAgICBzdG9yZXM6IFtdLCAgLy8gQ2xlYXIgc3RvcmVzIHNlbGVjdGlvblxyXG4gICAgZ3JvdXA6IFtdLCAgIC8vIENsZWFyIGdyb3VwcyBzZWxlY3Rpb25cclxuICAgIGxvY2F0aW9uOiBbXSAvLyBDbGVhciBsb2NhdGlvbnMgc2VsZWN0aW9uXHJcbiAgfTtcclxuXHJcbiAgLy8gLy8gT25jZSBzdG9yZXMgYXJlIGZldGNoZWQsIG1hcmsgYWxsIGFzIGNoZWNrZWRcclxuICAvLyBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAvLyAgIHRoaXMuZmlsdGVyZWRTdG9yZXMgPSB0aGlzLnN0b3Jlcy5tYXAoc3RvcmUgPT4gKHtcclxuICAvLyAgICAgLi4uc3RvcmUsXHJcbiAgLy8gICAgIGNoZWNrZWQ6IHRydWUgIC8vIE1hcmsgYWxsIHN0b3JlcyBhcyBjaGVja2VkXHJcbiAgLy8gICB9KSk7XHJcblxyXG4gIC8vICAgLy8gU3luYyBzZWxlY3RlZEZpbHRlcnMgd2l0aCB0aGUgdXBkYXRlZCBzdG9yZSBzdGF0ZVxyXG4gIC8vICAgdGhpcy5zZWxlY3RlZEZpbHRlcnMuc3RvcmVzID0gdGhpcy5maWx0ZXJlZFN0b3Jlcy5tYXAoc3RvcmUgPT4gKHtcclxuICAvLyAgICAgLi4uc3RvcmUsXHJcbiAgLy8gICAgIGNoZWNrZWQ6IHRydWVcclxuICAvLyAgIH0pKTtcclxuXHJcbiAgICAvLyBVcGRhdGUgbG9jYWxTdG9yYWdlIHdpdGggdGhlIGxhdGVzdCBzZWxlY3RlZEZpbHRlcnNcclxuICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKCdoZWFkZXItZmlsdGVycycsIEpTT04uc3RyaW5naWZ5KHRoaXMuc2VsZWN0ZWRGaWx0ZXJzKSk7XHJcbiB3aW5kb3cubG9jYXRpb24ucmVsb2FkKClcclxuICAgIC8vIEVtaXQgdGhlIHJlc2V0IGZpbHRlcnMgdG8gdXBkYXRlIG90aGVyIGNvbXBvbmVudHMgaWYgbmVlZGVkXHJcbiAgICAvLyB0aGlzLmdzLmRhdGFSYW5nZVZhbHVlLm5leHQodGhpcy5zZWxlY3RlZEZpbHRlcnMpO1xyXG4gICAgLy8gVHJpZ2dlciBjaGFuZ2UgZGV0ZWN0aW9uXHJcbiAgICB0aGlzLmNkLmRldGVjdENoYW5nZXMoKTtcclxuICAgLy8gQWRkaW5nIGEgc2xpZ2h0IGRlbGF5IHRvIGVuc3VyZSBzdG9yZXMgYXJlIGZldGNoZWQgZmlyc3RcclxuIFxyXG4gIFxyXG4gICAgLy8gQ2xvc2UgZHJvcGRvd24gYWZ0ZXIgcmVzZXQgaWYgbmVjZXNzYXJ5XHJcbiAgICB0aGlzLk9wZW5kcm9wZG93biA9IGZhbHNlO1xyXG4gIH1cclxuICBcclxuICBcclxuICBcclxuICBBcHBseSgpOiB2b2lkIHtcclxuICAgIC8vIENsb3NlIHRoZSBkcm9wZG93blxyXG4gICAgdGhpcy5PcGVuZHJvcGRvd24gPSBmYWxzZTtcclxuICBcclxuICAgIC8vIEZldGNoIGV4aXN0aW5nIGZpbHRlcnMgZnJvbSBsb2NhbFN0b3JhZ2VcclxuICAgIGNvbnN0IGhlYWRlckZpbHRlcnM6IGFueSA9IEpTT04ucGFyc2UobG9jYWxTdG9yYWdlLmdldEl0ZW0oXCJoZWFkZXItZmlsdGVyc1wiKSB8fCBcInt9XCIpO1xyXG4gICAgdGhpcy5zZWxlY3RlZEZpbHRlcnMuc3RvcmUgPSAgbnVsbFxyXG4gICAgLy8gRW5zdXJlIGN1cnJlbnQgc2VsZWN0aW9ucyBhcmUgcmVmbGVjdGVkXHJcbiAgICB0aGlzLnNlbGVjdGVkRmlsdGVycy5sb2NhdGlvbiA9IHRoaXMubG9jYXRpb25zO1xyXG4gICAgdGhpcy5zZWxlY3RlZEZpbHRlcnMuZ3JvdXAgPSB0aGlzLmdyb3Vwc0RhdGE7XHJcbiAgICB0aGlzLnNlbGVjdGVkRmlsdGVycy5zdG9yZXMgPSBoZWFkZXJGaWx0ZXJzLnN0b3JlcyA/IGhlYWRlckZpbHRlcnMuc3RvcmVzIDogdGhpcy5zdG9yZXM7XHJcbiAgXHJcbiAgXHJcbiAgICAvLyBTdG9yZSB1cGRhdGVkIGZpbHRlcnMgYmFjayBpbiBsb2NhbFN0b3JhZ2VcclxuICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKFwiaGVhZGVyLWZpbHRlcnNcIiwgSlNPTi5zdHJpbmdpZnkodGhpcy5zZWxlY3RlZEZpbHRlcnMpKTtcclxuICAgIHdpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKVxyXG4gICAgLy8gRW1pdCB0aGUgdXBkYXRlZCBmaWx0ZXJzIHZpYSB0aGUgc2VydmljZVxyXG4gICAgLy8gdGhpcy5ncy5kYXRhUmFuZ2VWYWx1ZS5uZXh0KHRoaXMuc2VsZWN0ZWRGaWx0ZXJzKTtcclxuICAgIC8vIFRyaWdnZXIgcmVmcmVzaCBpZiBuZWNlc3NhcnlcclxuICAgIC8vIHRoaXMuZ3MubWFuYWdlUmVmcmVzaFRyaWdnZXIubmV4dCh0cnVlKTtcclxuICAgIHRoaXMuY2QuZGV0ZWN0Q2hhbmdlcygpO1xyXG4gIH1cclxuICBcclxuICBmaWx0ZXJMb2NhdGlvbnMoKTogdm9pZCB7ICAgIFxyXG4gICAgY29uc3Qgc2VhcmNoVGV4dCA9IHRoaXMuc2VhcmNoTG9jYXRpb25UZXh0LnRvTG93ZXJDYXNlKCk7XHJcbiAgICBcclxuICAgIGlmIChzZWFyY2hUZXh0KSB7XHJcbiAgICAgIC8vIFByZXNlcnZlIHRoZSBjaGVja2VkIHN0YXRlIGR1cmluZyBmaWx0ZXJpbmdcclxuICAgICAgdGhpcy5maWx0ZXJlZExvY2F0aW9ucyA9IHRoaXMubG9jYXRpb25zXHJcbiAgICAgICAgLm1hcChsb2NhdGlvbiA9PiAoe1xyXG4gICAgICAgICAgLi4ubG9jYXRpb24sXHJcbiAgICAgICAgICBjaGVja2VkOiB0aGlzLmZpbHRlcmVkTG9jYXRpb25zLmZpbmQobCA9PiBsLmNpdHkgPT09IGxvY2F0aW9uLmNpdHkpPy5jaGVja2VkIHx8IGZhbHNlXHJcbiAgICAgICAgfSkpXHJcbiAgICAgICAgLmZpbHRlcihsb2NhdGlvbiA9PlxyXG4gICAgICAgICAgbG9jYXRpb24/LmNpdHk/LnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoc2VhcmNoVGV4dClcclxuICAgICAgICApO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgLy8gUmVzdG9yZSB0aGUgb3JpZ2luYWwgY2hlY2tlZCBzdGF0ZSB3aGVuIHNlYXJjaCB0ZXh0IGlzIGNsZWFyZWRcclxuICAgICAgdGhpcy5maWx0ZXJlZExvY2F0aW9ucyA9IHRoaXMubG9jYXRpb25zLm1hcChsb2NhdGlvbiA9PiAoe1xyXG4gICAgICAgIC4uLmxvY2F0aW9uLFxyXG4gICAgICAgIGNoZWNrZWQ6IHRoaXMuc2VsZWN0ZWRGaWx0ZXJzLmxvY2F0aW9uLmZpbmQoKGw6YW55KSA9PiBsLmNpdHkgPT09IGxvY2F0aW9uLmNpdHkpPy5jaGVja2VkIHx8IGZhbHNlXHJcbiAgICAgIH0pKTtcclxuICAgIH1cclxuICB9XHJcbiAgXHJcblxyXG4gIGZpbHRlckdyb3VwcygpOiB2b2lkIHsgIFxyXG4gICAgY29uc3Qgc2VhcmNoVGV4dCA9IHRoaXMuc2VhcmNoR3JvdXBUZXh0LnRvTG93ZXJDYXNlKCk7XHJcbiAgICBcclxuICAgIGlmIChzZWFyY2hUZXh0KSB7XHJcbiAgICAgIC8vIFByZXNlcnZlIHRoZSBjaGVja2VkIHN0YXRlIGR1cmluZyBmaWx0ZXJpbmdcclxuICAgICAgdGhpcy5maWx0ZXJlZEdyb3VwcyA9IHRoaXMuZ3JvdXBzRGF0YVxyXG4gICAgICAgIC5tYXAoZ3JvdXAgPT4gKHtcclxuICAgICAgICAgIC4uLmdyb3VwLFxyXG4gICAgICAgICAgY2hlY2tlZDogdGhpcy5maWx0ZXJlZEdyb3Vwcy5maW5kKGcgPT4gZy5ncm91cE5hbWUgPT09IGdyb3VwLmdyb3VwTmFtZSk/LmNoZWNrZWQgfHwgZmFsc2VcclxuICAgICAgICB9KSlcclxuICAgICAgICAuZmlsdGVyKGdyb3VwID0+XHJcbiAgICAgICAgICBncm91cD8uZ3JvdXBOYW1lPy50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHNlYXJjaFRleHQpXHJcbiAgICAgICAgKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIC8vIFJlc3RvcmUgdGhlIG9yaWdpbmFsIGNoZWNrZWQgc3RhdGUgd2hlbiBzZWFyY2ggdGV4dCBpcyBjbGVhcmVkXHJcbiAgICAgIHRoaXMuZmlsdGVyZWRHcm91cHMgPSB0aGlzLmdyb3Vwc0RhdGEubWFwKGdyb3VwID0+ICh7XHJcbiAgICAgICAgLi4uZ3JvdXAsXHJcbiAgICAgICAgY2hlY2tlZDogdGhpcy5zZWxlY3RlZEZpbHRlcnMuZ3JvdXAuZmluZCgoZzphbnkpID0+IGcuZ3JvdXBOYW1lID09PSBncm91cC5ncm91cE5hbWUpPy5jaGVja2VkIHx8IGZhbHNlXHJcbiAgICAgIH0pKTtcclxuICAgIH1cclxuICB9XHJcbiAgXHJcbiAgXHJcbiAgZmlsdGVyU3RvcmVzKCk6IHZvaWQge1xyXG4gICAgY29uc3Qgc2VhcmNoVGV4dCA9IHRoaXMuc2VhcmNoU3RvcmVUZXh0LnRvTG93ZXJDYXNlKCk7XHJcbiAgICAvLyBQcmVzZXJ2ZSBjaGVja2VkIHN0YXRlcyBkdXJpbmcgZmlsdGVyaW5nXHJcbiAgICBpZiAoc2VhcmNoVGV4dCkge1xyXG4gICAgICAvLyBGaWx0ZXIgYmFzZWQgb24gc2VhcmNoIHRleHQgd2hpbGUgcHJlc2VydmluZyBjaGVja2VkIHN0YXRlXHJcbiAgICAgIHRoaXMuZmlsdGVyZWRTdG9yZXMgPSB0aGlzLnN0b3Jlc1xyXG4gICAgICAgIC5tYXAoc3RvcmUgPT4gKHtcclxuICAgICAgICAgIC4uLnN0b3JlLFxyXG4gICAgICAgICAgLy8gQ2hlY2sgaWYgdGhlIHN0b3JlIGlzIGFscmVhZHkgY2hlY2tlZCBpbiBmaWx0ZXJlZFN0b3JlcywgZmFsbGJhY2sgdG8gb3JpZ2luYWwgc3RvcmVzJyBjaGVja2VkIHN0YXRlXHJcbiAgICAgICAgICBjaGVja2VkOiB0aGlzLnNlbGVjdGVkRmlsdGVycy5zdG9yZXMuZmluZCgoczogYW55KSA9PiBzLnN0b3JlSWQgPT09IHN0b3JlLnN0b3JlSWQpPy5jaGVja2VkIHx8IHN0b3JlLmNoZWNrZWQgfHwgZmFsc2VcclxuICAgICAgICB9KSlcclxuICAgICAgICAuZmlsdGVyKHN0b3JlID0+IHN0b3JlLnN0b3JlTmFtZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHNlYXJjaFRleHQpKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIC8vIFdoZW4gdGhlIHNlYXJjaCB0ZXh0IGlzIGNsZWFyZWQsIHJlc3RvcmUgdGhlIG9yaWdpbmFsIGxpc3Qgd2l0aCBwcmVzZXJ2ZWQgY2hlY2tlZCBzdGF0ZXNcclxuICAgICAgdGhpcy5maWx0ZXJlZFN0b3JlcyA9IHRoaXMuc3RvcmVzLm1hcChzdG9yZSA9PiAoe1xyXG4gICAgICAgIC4uLnN0b3JlLFxyXG4gICAgICAgIC8vIFByZXNlcnZlIHRoZSBjaGVja2VkIHN0YXRlIGJhc2VkIG9uIHRoZSBzZWxlY3RlZCBmaWx0ZXJzXHJcbiAgICAgICAgY2hlY2tlZDogdGhpcy5zZWxlY3RlZEZpbHRlcnMuc3RvcmVzLmZpbmQoKHM6IGFueSkgPT4gcy5zdG9yZUlkID09PSBzdG9yZS5zdG9yZUlkKT8uY2hlY2tlZCB8fCBzdG9yZS5jaGVja2VkIHx8IGZhbHNlXHJcbiAgICAgIH0pKTtcclxuICAgIH1cclxuICB9XHJcbiAgXHJcbiAgXHJcbiAgIFxyXG4gIGNsb3NlRHJvcGRvd24oKTogdm9pZCB7XHJcbiAgICB0aGlzLmRyb3Bkb3duT3BlbiA9IG51bGw7XHJcbiAgfVxyXG5cclxuICBASG9zdExpc3RlbmVyKFwiZG9jdW1lbnQ6Y2xpY2tcIiwgW1wiJGV2ZW50XCJdKVxyXG4gIGNsaWNrT3V0c2lkZShldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xyXG4gICAgY29uc3QgY2xpY2tlZEluc2lkZSA9IChldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQpLmNsb3Nlc3QoXHJcbiAgICAgIFwiLmRyb3Bkb3duLWNvbnRhaW5lclwiXHJcbiAgICApO1xyXG4gICAgY29uc3QgY2xpY2tlZG91dFNpZGUgPSAoZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50KS5jbG9zZXN0KFxyXG4gICAgICBcIi5kcm9wZG93bjFcIlxyXG4gICAgKTtcclxuICAgIGlmICghY2xpY2tlZEluc2lkZSkge1xyXG4gICAgICB0aGlzLmNsb3NlRHJvcGRvd24oKTtcclxuICAgIH1cclxuICAgIGlmKCFjbGlja2Vkb3V0U2lkZSkge1xyXG4gICAgICB0aGlzLmNsb3NlRHJvcGRvd24xKCk7XHJcbiAgICB9XHJcblxyXG4gIH1cclxufVxyXG5pbnRlcmZhY2UgQ2l0eSB7XHJcbiAgY2l0eTogc3RyaW5nO1xyXG59XHJcblxyXG5pbnRlcmZhY2UgTG9jYXRpb24ge1xyXG4gIGNpdHk6IENpdHk7XHJcbiAgY2hlY2tlZDogYm9vbGVhbjtcclxufVxyXG5cclxuXHJcbiIsIjxkaXYgY2xhc3M9XCJtZS0zXCI+XHJcbiAgICA8bGFiZWwgKm5nSWY9XCJzZWxlY3RlZExvY2F0aW9uc0xhYmVsKClcIiBjbGFzcz1cImJhZGdlIGJhZGdlLWxpZ2h0LWRlZmF1bHQgbXgtMlwiPnt7c2VsZWN0ZWRMb2NhdGlvbnNMYWJlbCgpfX0gXHJcbiAgICAgICAgPHNwYW4gY2xhc3M9XCJjdXJzb3ItcG9pbnRlclwiIChjbGljayk9XCJyZW1vdmVMb2NhdGlvbigpXCI+PHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIxMlwiIGhlaWdodD1cIjEyXCIgdmlld0JveD1cIjAgMCAxMiAxMlwiIGZpbGw9XCJub25lXCI+XHJcbiAgICAgICAgPHBhdGggZD1cIk05IDNMMyA5TTMgM0w5IDlcIiBzdHJva2U9XCIjNjY3MDg1XCIgc3Ryb2tlLXdpZHRoPVwiMS41XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIvPlxyXG4gICAgICAgIDwvc3ZnPjwvc3Bhbj5cclxuICAgIDwvbGFiZWw+XHJcbiAgICA8bGFiZWwgKm5nSWY9XCJzZWxlY3RlZEdyb3Vwc0xhYmVsKClcIiAgY2xhc3M9XCJiYWRnZSBiYWRnZS1saWdodC1kZWZhdWx0IG14LTJcIj57e3NlbGVjdGVkR3JvdXBzTGFiZWwoKX19IFxyXG4gICAgICAgIDxzcGFuIGNsYXNzPVwiY3Vyc29yLXBvaW50ZXJcIiAoY2xpY2spPVwicmVtb3ZlR3JvdXAoKVwiPjxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMTJcIiBoZWlnaHQ9XCIxMlwiIHZpZXdCb3g9XCIwIDAgMTIgMTJcIiBmaWxsPVwibm9uZVwiPlxyXG4gICAgICAgIDxwYXRoIGQ9XCJNOSAzTDMgOU0zIDNMOSA5XCIgc3Ryb2tlPVwiIzY2NzA4NVwiIHN0cm9rZS13aWR0aD1cIjEuNVwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiLz5cclxuICAgICAgICA8L3N2Zz48L3NwYW4+XHJcbiAgICA8L2xhYmVsPlxyXG4gICAgPGxhYmVsICBjbGFzcz1cImJhZGdlIGJhZGdlLWxpZ2h0LWRlZmF1bHRcIj57e3NlbGVjdGVkU3RvcmVzTGFiZWwoKX19PC9sYWJlbD5cclxuPC9kaXY+XHJcblxyXG48ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBwb3NpdGlvbi1yZWxhdGl2ZSBteS0xXCI+XHJcbiAgICA8c3BhbiBjbGFzcz1cInN2Zy1pY29uIHN2Zy1pY29uLTEgcG9zaXRpb24tYWJzb2x1dGUgbXMtM1wiPlxyXG4gICAgICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHdpZHRoPVwiMjBcIiBoZWlnaHQ9XCIyMFwiIHZpZXdCb3g9XCIwIDAgMjAgMjBcIiBmaWxsPVwibm9uZVwiPlxyXG4gICAgICAgICAgICA8cGF0aFxyXG4gICAgICAgICAgICAgICAgZD1cIk0xMy4zMzMzIDEuNjY2NjNWNC45OTk5Nk02LjY2NjY3IDEuNjY2NjNWNC45OTk5Nk0yLjUgOC4zMzMyOUgxNy41TTQuMTY2NjcgMy4zMzMyOUgxNS44MzMzQzE2Ljc1MzggMy4zMzMyOSAxNy41IDQuMDc5NDggMTcuNSA0Ljk5OTk2VjE2LjY2NjZDMTcuNSAxNy41ODcxIDE2Ljc1MzggMTguMzMzMyAxNS44MzMzIDE4LjMzMzNINC4xNjY2N0MzLjI0NjE5IDE4LjMzMzMgMi41IDE3LjU4NzEgMi41IDE2LjY2NjZWNC45OTk5NkMyLjUgNC4wNzk0OCAzLjI0NjE5IDMuMzMzMjkgNC4xNjY2NyAzLjMzMzI5WlwiXHJcbiAgICAgICAgICAgICAgICBzdHJva2U9XCIjMzQ0MDU0XCIgc3Ryb2tlLXdpZHRoPVwiMS42N1wiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XHJcbiAgICAgICAgPC9zdmc+XHJcbiAgICA8L3NwYW4+XHJcbiAgICA8aW5wdXQgY2xhc3M9XCJmeC1kYXRlLXJhbmdlIGZvcm0tY29udHJvbCBwcy0xNFwiIHN0eWxlPVwibWluLXdpZHRoOiAyNjBweCAhaW1wb3J0YW50O1wiIHR5cGU9XCJ0ZXh0XCIgbWF0SW5wdXRcclxuICAgICAgICBuZ3hEYXRlcmFuZ2VwaWNrZXJNZCBbZHJvcHNdPVwiJ2Rvd24nXCIgW29wZW5zXT1cIidyaWdodCdcIiBbcmFuZ2VzXT1cInJhbmdlc1wiIFtzaG93Q3VzdG9tUmFuZ2VMYWJlbF09XCJ0cnVlXCIgW2F1dG9BcHBseV09XCJ0cnVlXCJcclxuICAgICAgICBbYWx3YXlzU2hvd0NhbGVuZGFyc109XCJmYWxzZVwiIFtrZWVwQ2FsZW5kYXJPcGVuaW5nV2l0aFJhbmdlXT1cInRydWVcIiBbc2hvd0NhbmNlbF09XCJ0cnVlXCIgYXV0b2NvbXBsZXRlPVwib2ZmXCJcclxuICAgICAgICBbKG5nTW9kZWwpXT1cInNlbGVjdGVkRGF0ZVJhbmdlXCIgKHN0YXJ0RGF0ZUNoYW5nZWQpPVwib25TdGFydERhdGVDaGFuZ2UoJGV2ZW50KVwiIFtpc0N1c3RvbURhdGVdPVwiaXNDdXN0b21EYXRlXCJcclxuICAgICAgICBbbG9jYWxlXT1cInsgZm9ybWF0OiAnREQtTU0tWVlZWScsIGZpcnN0RGF5OiAxLCBtb250aE5hbWVzOiBbJ0phbnVhcnknLCAnRmVicnVhcnknLCAnTWFyY2gnLCAnQXByaWwnLCAnTWF5JywgJ0p1bmUnLCAnSnVseScsICdBdWd1c3QnLCAnU2VwdGVtYmVyJywgJ09jdG9iZXInLCAnTm92ZW1iZXInLCAnRGVjZW1iZXInXSB9XCJcclxuICAgICAgICAoZGF0ZXNVcGRhdGVkKT1cImRhdGVjaGFuZ2UoJGV2ZW50KVwiIG5hbWU9XCJkYXRlcmFuZ2VcIiBbcmVhZG9ubHldPVwidHJ1ZVwiIC8+XHJcbjwvZGl2PlxyXG48ZGl2IGNsYXNzPVwicG9zaXRpb24tcmVsYXRpdmVcIj5cclxuICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIChjbGljayk9XCJvcGVuZHJvcGRvd24oJGV2ZW50KVwiICBjbGFzcz1cImJ0biBidG4tZGVmYXVsdCBteC0yIHJvdW5kZWQtMyB0ZXh0LW5vd3JhcCBib3JkZXItdmFsXCI+XHJcbiAgICAgICAgPCEtLSA8c3BhbiBjbGFzcz1cIm1lLTJcIj5GaWx0ZXI8L3NwYW4+IC0tPlxyXG4gICAgICAgIDxzdmcgY2xhc3M9XCJwbC0zXCIgd2lkdGg9XCIyMFwiIGhlaWdodD1cIjIwXCIgdmlld0JveD1cIjAgMCAyMCAyMFwiIGZpbGw9XCJub25lXCIgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiPlxyXG4gICAgICAgICAgICA8cGF0aCBkPVwiTTUgMTBIMTVNMi41IDVIMTcuNU03LjUgMTVIMTIuNVwiIHN0cm9rZT1cIiMzNDQwNTRcIiBzdHJva2Utd2lkdGg9XCIyXCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiXHJcbiAgICAgICAgICAgICAgICBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiIC8+XHJcbiAgICAgICAgPC9zdmc+XHJcbiAgICA8L2J1dHRvbj5cclxuXHJcbiAgICA8ZGl2ICpuZ0lmPVwiT3BlbmRyb3Bkb3duXCIgY2xhc3M9XCJjYXJkIHAtNSBkcm9wZG93bjEgcG9zaXRpb24tYWJzb2x1dGUgei0xIGVuZC0wXCIgc3R5bGU9XCJ6LWluZGV4OiAxICFpbXBvcnRhbnQ7XCIgKGNsaWNrT3V0c2lkZSk9XCJjbG9zZURyb3Bkb3duMSgpXCI+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cImRyb3Bkb3duLXRpdGxlIGQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBtYi0yXCI+RmlsdGVyIE9wdGlvbnNcclxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tb3V0bGluZSB3LTI1IG1zLTMgYnRuLXJlc2l6ZVwiIChjbGljayk9XCJSZXNldCgpXCI+IFJlc2V0IDwvYnV0dG9uPlxyXG4gICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5IHctMjUgIGJ0bi1yZXNpemVcIiAoY2xpY2spPVwiQXBwbHkoKVwiPkFwcGx5PC9idXR0b24+XHJcbiAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgIDwhLS0gTG9jYXRpb24gRHJvcGRvd24gLS0+XHJcbjxkaXYgY2xhc3M9XCJkcm9wZG93bi1jb250YWluZXJcIiAoY2xpY2tPdXRzaWRlKT1cImNsb3NlRHJvcGRvd24oKVwiPlxyXG4gICAgPGRpdiBjbGFzcz1cImRyb3Bkb3duLWhlYWRlclwiPlxyXG4gICAgICAgIDxpbnB1dCBcclxuICAgICAgICAgICAgdHlwZT1cInRleHRcIiBcclxuICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZHJvcGRvd24taW5wdXQgY3Vyc29yLXBvaW50ZXJcIiBcclxuICAgICAgICAgICAgW3ZhbHVlXT1cInNlbGVjdGVkTG9jYXRpb25zTGFiZWwoKVwiXHJcbiAgICAgICAgICAgIChmb2N1cyk9XCJ0b2dnbGVEcm9wZG93bignbG9jYXRpb24nKVwiIFxyXG4gICAgICAgICAgICByZWFkb25seVxyXG4gICAgICAgICAgICBwbGFjZWhvbGRlcj1cIlNlbGVjdCBsb2NhdGlvbnMuLi5cIlxyXG4gICAgICAgIC8+XHJcbiAgICA8L2Rpdj5cclxuICAgIDxkaXYgY2xhc3M9XCJkcm9wZG93bi1tZW51IGN1c3RvbS1kcm9wZG93bi1tZW51XCIgKm5nSWY9XCJkcm9wZG93bk9wZW4gPT09ICdsb2NhdGlvbidcIj5cclxuICAgICAgICA8aW5wdXQgXHJcbiAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCIgXHJcbiAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sIG1iLTIgZHJvcGRvd24tc2VhcmNoXCIgXHJcbiAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiU2VhcmNoIGxvY2F0aW9ucy4uLlwiIFxyXG4gICAgICAgICAgICBbKG5nTW9kZWwpXT1cInNlYXJjaExvY2F0aW9uVGV4dFwiIFxyXG4gICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJmaWx0ZXJMb2NhdGlvbnMoKVwiIFxyXG4gICAgICAgIC8+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tY2hlY2sgbWItMiBkcm9wZG93bi1pdGVtIGN1c3RvbS1kcm9wZG93bi1pdGVtXCI+XHJcbiAgICAgICAgICAgIDxpbnB1dCBcclxuICAgICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dCBjdXJzb3ItcG9pbnRlclwiIFxyXG4gICAgICAgICAgICAgICAgdHlwZT1cImNoZWNrYm94XCIgXHJcbiAgICAgICAgICAgICAgICBpZD1cInNlbGVjdEFsbExvY2F0aW9uc1wiIFxyXG4gICAgICAgICAgICAgICAgW2NoZWNrZWRdPVwiaXNBbGxMb2NhdGlvbnNTZWxlY3RlZCgpXCIgXHJcbiAgICAgICAgICAgICAgICAoY2hhbmdlKT1cInRvZ2dsZVNlbGVjdEFsbExvY2F0aW9ucygkZXZlbnQpXCIgXHJcbiAgICAgICAgICAgIC8+XHJcbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tY2hlY2stbGFiZWxcIiBmb3I9XCJzZWxlY3RBbGxMb2NhdGlvbnNcIj5cclxuICAgICAgICAgICAgICAgIFNlbGVjdCBBbGwgTG9jYXRpb25zXHJcbiAgICAgICAgICAgIDwvbGFiZWw+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPGRpdiBcclxuICAgICAgICAgICAgY2xhc3M9XCJkcm9wZG93bi1pdGVtIGZvcm0tY2hlY2sgY3VzdG9tLWRyb3Bkb3duLWl0ZW1cIiBcclxuICAgICAgICAgICAgKm5nRm9yPVwibGV0IGxvY2F0aW9uIG9mIGZpbHRlcmVkTG9jYXRpb25zXCJcclxuICAgICAgICA+XHJcbiAgICAgICAgICAgIDxpbnB1dCBcclxuICAgICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dCBjdXJzb3ItcG9pbnRlclwiIFxyXG4gICAgICAgICAgICAgICAgdHlwZT1cImNoZWNrYm94XCIgXHJcbiAgICAgICAgICAgICAgICBbaWRdPVwibG9jYXRpb24uY2l0eVwiIFxyXG4gICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJsb2NhdGlvbi5jaGVja2VkXCJcclxuICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwidXBkYXRlU2VsZWN0ZWRMb2NhdGlvbnMoKVwiIFxyXG4gICAgICAgICAgICAvPlxyXG4gICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmb3JtLWNoZWNrLWxhYmVsXCIgW2Zvcl09XCJsb2NhdGlvbi5jaXR5XCI+XHJcbiAgICAgICAgICAgICAgICB7eyBsb2NhdGlvbi5jaXR5IH19XHJcbiAgICAgICAgICAgIDwvbGFiZWw+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuPC9kaXY+XHJcblxyXG48IS0tIEdyb3VwIERyb3Bkb3duIC0tPlxyXG48ZGl2IGNsYXNzPVwiZHJvcGRvd24tY29udGFpbmVyIG10LTNcIiAoY2xpY2tPdXRzaWRlKT1cImNsb3NlRHJvcGRvd24oKVwiPlxyXG4gICAgPGRpdiBjbGFzcz1cImRyb3Bkb3duLWhlYWRlclwiIChjbGljayk9XCJ0b2dnbGVEcm9wZG93bignZ3JvdXAnKVwiPlxyXG4gICAgICAgIDxpbnB1dCBcclxuICAgICAgICAgICAgdHlwZT1cInRleHRcIiBcclxuICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZHJvcGRvd24taW5wdXQgY3Vyc29yLXBvaW50ZXJcIiBcclxuICAgICAgICAgICAgW3ZhbHVlXT1cInNlbGVjdGVkR3JvdXBzTGFiZWwoKVwiIHJlYWRvbmx5XHJcbiAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiU2VsZWN0IGNsdXN0ZXJzLi5cIlxyXG4gICAgICAgIC8+XHJcbiAgICA8L2Rpdj5cclxuICAgIDxkaXYgY2xhc3M9XCJkcm9wZG93bi1tZW51IGN1c3RvbS1kcm9wZG93bi1tZW51XCIgKm5nSWY9XCJkcm9wZG93bk9wZW4gPT09ICdncm91cCdcIj5cclxuICAgICAgICA8aW5wdXQgXHJcbiAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCIgXHJcbiAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sIG1iLTIgZHJvcGRvd24tc2VhcmNoXCIgXHJcbiAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiU2VhcmNoIGNsdXN0ZXJzLi4uXCIgXHJcbiAgICAgICAgICAgIFsobmdNb2RlbCldPVwic2VhcmNoR3JvdXBUZXh0XCIgXHJcbiAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cImZpbHRlckdyb3VwcygpXCIgXHJcbiAgICAgICAgLz5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1jaGVjayBtYi0yIGRyb3Bkb3duLWl0ZW0gY3VzdG9tLWRyb3Bkb3duLWl0ZW1cIj5cclxuICAgICAgICAgICAgPGlucHV0IFxyXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0IGN1cnNvci1wb2ludGVyXCIgXHJcbiAgICAgICAgICAgICAgICB0eXBlPVwiY2hlY2tib3hcIiBcclxuICAgICAgICAgICAgICAgIGlkPVwic2VsZWN0QWxsR3JvdXBzXCIgXHJcbiAgICAgICAgICAgICAgICBbY2hlY2tlZF09XCJpc0FsbEdyb3Vwc1NlbGVjdGVkKClcIiBcclxuICAgICAgICAgICAgICAgIChjaGFuZ2UpPVwidG9nZ2xlU2VsZWN0QWxsR3JvdXBzKCRldmVudClcIiBcclxuICAgICAgICAgICAgLz5cclxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1jaGVjay1sYWJlbFwiIGZvcj1cInNlbGVjdEFsbEdyb3Vwc1wiPlxyXG4gICAgICAgICAgICAgICAgU2VsZWN0IEFsbFxyXG4gICAgICAgICAgICA8L2xhYmVsPlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDxkaXYgXHJcbiAgICAgICAgICAgIGNsYXNzPVwiZHJvcGRvd24taXRlbSBmb3JtLWNoZWNrIGN1c3RvbS1kcm9wZG93bi1pdGVtXCIgXHJcbiAgICAgICAgICAgICpuZ0Zvcj1cImxldCBncm91cCBvZiBmaWx0ZXJlZEdyb3Vwc1wiXHJcbiAgICAgICAgPlxyXG4gICAgICAgICAgICA8aW5wdXQgXHJcbiAgICAgICAgICAgICAgICBjbGFzcz1cImZvcm0tY2hlY2staW5wdXQgY3Vyc29yLXBvaW50ZXJcIiBcclxuICAgICAgICAgICAgICAgIHR5cGU9XCJjaGVja2JveFwiIFxyXG4gICAgICAgICAgICAgICAgW2lkXT1cImdyb3VwLmdyb3VwTmFtZVwiXHJcbiAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cImdyb3VwLmNoZWNrZWRcIlxyXG4gICAgICAgICAgICAgICAgKGNoYW5nZSk9XCJ1cGRhdGVTZWxlY3RlZEdyb3VwcygpXCIgXHJcbiAgICAgICAgICAgIC8+XHJcbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tY2hlY2stbGFiZWxcIiBbZm9yXT1cImdyb3VwLmdyb3VwTmFtZVwiPlxyXG4gICAgICAgICAgICAgICAge3sgZ3JvdXAuZ3JvdXBOYW1lIH19XHJcbiAgICAgICAgICAgIDwvbGFiZWw+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuPC9kaXY+XHJcblxyXG5cclxuPCEtLSBTdG9yZSBEcm9wZG93biAtLT5cclxuPGRpdiBjbGFzcz1cImRyb3Bkb3duLWNvbnRhaW5lciBtdC0zXCIgKGNsaWNrT3V0c2lkZSk9XCJjbG9zZURyb3Bkb3duKClcIj5cclxuICAgIDxkaXYgY2xhc3M9XCJkcm9wZG93bi1oZWFkZXJcIiAoY2xpY2spPVwidG9nZ2xlRHJvcGRvd24oJ3N0b3JlJylcIj5cclxuICAgICAgICA8aW5wdXQgXHJcbiAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCIgXHJcbiAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1jb250cm9sIGRyb3Bkb3duLWlucHV0IGN1cnNvci1wb2ludGVyXCJcclxuICAgICAgICAgICAgW3ZhbHVlXT1cInNlbGVjdGVkU3RvcmVzTGFiZWwoKVwiXHJcbiAgICAgICAgICAgIHJlYWRvbmx5XHJcbiAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiU2VsZWN0IHN0b3Jlcy4uLlwiXHJcbiAgICAgICAgLz5cclxuICAgIDwvZGl2PlxyXG4gICAgPGRpdiBjbGFzcz1cImRyb3Bkb3duLW1lbnUgY3VzdG9tLWRyb3Bkb3duLW1lbnVcIiAqbmdJZj1cImRyb3Bkb3duT3BlbiA9PT0gJ3N0b3JlJ1wiPlxyXG4gICAgICAgIDxpbnB1dCBcclxuICAgICAgICAgICAgdHlwZT1cInRleHRcIiBcclxuICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWNvbnRyb2wgbWItMiBkcm9wZG93bi1zZWFyY2ggXCIgXHJcbiAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiU2VhcmNoIHN0b3Jlcy4uLlwiIFxyXG4gICAgICAgICAgICBbKG5nTW9kZWwpXT1cInNlYXJjaFN0b3JlVGV4dFwiIFxyXG4gICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJmaWx0ZXJTdG9yZXMoKVwiIFxyXG4gICAgICAgIC8+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cImZvcm0tY2hlY2sgbWItMiBkcm9wZG93bi1pdGVtIGN1c3RvbS1kcm9wZG93bi1pdGVtXCI+XHJcbiAgICAgICAgICAgIDxpbnB1dCBcclxuICAgICAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dCBjdXJzb3ItcG9pbnRlclwiIFxyXG4gICAgICAgICAgICAgICAgdHlwZT1cImNoZWNrYm94XCIgXHJcbiAgICAgICAgICAgICAgICBpZD1cInNlbGVjdEFsbFN0b3Jlc1wiIFxyXG4gICAgICAgICAgICAgICAgW2NoZWNrZWRdPVwiaXNBbGxTdG9yZXNTZWxlY3RlZCgpXCIgXHJcbiAgICAgICAgICAgICAgICAoY2hhbmdlKT1cInRvZ2dsZVNlbGVjdEFsbFN0b3JlcygkZXZlbnQpXCIgXHJcbiAgICAgICAgICAgIC8+XHJcbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tY2hlY2stbGFiZWxcIiBmb3I9XCJzZWxlY3RBbGxTdG9yZXNcIj5cclxuICAgICAgICAgICAgICAgIFNlbGVjdCBBbGxcclxuICAgICAgICAgICAgPC9sYWJlbD5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8ZGl2IFxyXG4gICAgICAgICAgICBjbGFzcz1cImRyb3Bkb3duLWl0ZW0gZm9ybS1jaGVjayBjdXN0b20tZHJvcGRvd24taXRlbVwiIFxyXG4gICAgICAgICAgICAqbmdGb3I9XCJsZXQgc3RvcmUgb2YgZmlsdGVyZWRTdG9yZXNcIlxyXG4gICAgICAgID5cclxuICAgICAgICAgICAgPGlucHV0IFxyXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0XCIgXHJcbiAgICAgICAgICAgICAgICB0eXBlPVwiY2hlY2tib3hcIiBcclxuICAgICAgICAgICAgICAgIFtpZF09XCJzdG9yZS5zdG9yZUlkXCJcclxuICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwic3RvcmUuY2hlY2tlZFwiXHJcbiAgICAgICAgICAgICAgICAoY2hhbmdlKT1cInVwZGF0ZVNlbGVjdGVkU3RvcmVzKClcIiBcclxuICAgICAgICAgICAgLz5cclxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1jaGVjay1sYWJlbFwiIFtmb3JdPVwic3RvcmUuc3RvcmVJZFwiPlxyXG4gICAgICAgICAgICAgICAge3sgc3RvcmUuc3RvcmVOYW1lIH19XHJcbiAgICAgICAgICAgIDwvbGFiZWw+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuPC9kaXY+XHJcblxyXG5cclxuXHJcblxyXG5cclxuXHJcblxyXG4gICAgPC9kaXY+XHJcbjwvZGl2PiJdfQ==