@smarterplan/ngx-smarterplan-core 0.3.11

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.
Files changed (134) hide show
  1. package/README.md +24 -0
  2. package/esm2020/lib/components/csv-export/csv-export.component.mjs +59 -0
  3. package/esm2020/lib/components/loader/loader.component.mjs +14 -0
  4. package/esm2020/lib/components/menu-bar/avatar/avatar.component.mjs +75 -0
  5. package/esm2020/lib/components/menu-bar/menu-bar.component.mjs +115 -0
  6. package/esm2020/lib/components/menu-bar/navigation-bar/navigation-bar.component.mjs +254 -0
  7. package/esm2020/lib/components/menu-bar/range-date-picker/range-date-picker.component.mjs +81 -0
  8. package/esm2020/lib/components/modal-switch-visit/modal-switch-visit.component.mjs +39 -0
  9. package/esm2020/lib/components/search-bar/search-bar.component.mjs +63 -0
  10. package/esm2020/lib/components/support-modal/support-modal.component.mjs +59 -0
  11. package/esm2020/lib/config.mjs +4 -0
  12. package/esm2020/lib/helpers.service.mjs +468 -0
  13. package/esm2020/lib/mattertagData.mjs +177 -0
  14. package/esm2020/lib/ngx-smarterplan-core.module.mjs +117 -0
  15. package/esm2020/lib/ngx-smarterplan-core.service.mjs +14 -0
  16. package/esm2020/lib/pipes/duration-to-string.pipe.mjs +66 -0
  17. package/esm2020/lib/pipes/hashtag-from-id.pipe.mjs +26 -0
  18. package/esm2020/lib/pipes/safe-url.pipe.mjs +20 -0
  19. package/esm2020/lib/pipes/time-date-to-local-string.pipe.mjs +104 -0
  20. package/esm2020/lib/pipes/username-from-id.pipe.mjs +29 -0
  21. package/esm2020/lib/services/base-tab.service.mjs +24 -0
  22. package/esm2020/lib/services/baseVisibility.service.mjs +17 -0
  23. package/esm2020/lib/services/booking.service.mjs +161 -0
  24. package/esm2020/lib/services/content.service.mjs +135 -0
  25. package/esm2020/lib/services/filter.service.mjs +560 -0
  26. package/esm2020/lib/services/intervention.service.mjs +236 -0
  27. package/esm2020/lib/services/locale.service.mjs +45 -0
  28. package/esm2020/lib/services/matterport-import.service.mjs +339 -0
  29. package/esm2020/lib/services/matterport.service.mjs +876 -0
  30. package/esm2020/lib/services/models/affectation.service.mjs +60 -0
  31. package/esm2020/lib/services/models/base-object.service.mjs +70 -0
  32. package/esm2020/lib/services/models/capture.service.mjs +34 -0
  33. package/esm2020/lib/services/models/comment.service.mjs +98 -0
  34. package/esm2020/lib/services/models/domain.service.mjs +77 -0
  35. package/esm2020/lib/services/models/equipment.service.mjs +629 -0
  36. package/esm2020/lib/services/models/event.service.mjs +128 -0
  37. package/esm2020/lib/services/models/feature.service.mjs +339 -0
  38. package/esm2020/lib/services/models/hashtag.service.mjs +38 -0
  39. package/esm2020/lib/services/models/layer.service.mjs +33 -0
  40. package/esm2020/lib/services/models/measurement.service.mjs +158 -0
  41. package/esm2020/lib/services/models/mission.service.mjs +185 -0
  42. package/esm2020/lib/services/models/navigation.service.mjs +76 -0
  43. package/esm2020/lib/services/models/node.service.mjs +31 -0
  44. package/esm2020/lib/services/models/operation.service.mjs +59 -0
  45. package/esm2020/lib/services/models/organisation.service.mjs +73 -0
  46. package/esm2020/lib/services/models/plan.service.mjs +573 -0
  47. package/esm2020/lib/services/models/poi.service.mjs +48 -0
  48. package/esm2020/lib/services/models/profile.service.mjs +54 -0
  49. package/esm2020/lib/services/models/property.service.mjs +34 -0
  50. package/esm2020/lib/services/models/space.service.mjs +184 -0
  51. package/esm2020/lib/services/models/template.service.mjs +41 -0
  52. package/esm2020/lib/services/models/ticket.service.mjs +454 -0
  53. package/esm2020/lib/services/models/visit.service.mjs +130 -0
  54. package/esm2020/lib/services/models/zone.service.mjs +184 -0
  55. package/esm2020/lib/services/navigator.service.mjs +165 -0
  56. package/esm2020/lib/services/s3.service.mjs +124 -0
  57. package/esm2020/lib/services/search.service.mjs +124 -0
  58. package/esm2020/lib/services/support.service.mjs +42 -0
  59. package/esm2020/lib/services/tag.service.mjs +101 -0
  60. package/esm2020/lib/services/user.service.mjs +444 -0
  61. package/esm2020/lib/services/viewer.service.mjs +395 -0
  62. package/esm2020/lib/services/zone-drawer.service.mjs +76 -0
  63. package/esm2020/lib/types.service.mjs +266 -0
  64. package/esm2020/public-api.mjs +63 -0
  65. package/esm2020/smarterplan-ngx-smarterplan-core.mjs +5 -0
  66. package/fesm2015/smarterplan-ngx-smarterplan-core.mjs +10057 -0
  67. package/fesm2015/smarterplan-ngx-smarterplan-core.mjs.map +1 -0
  68. package/fesm2020/smarterplan-ngx-smarterplan-core.mjs +9371 -0
  69. package/fesm2020/smarterplan-ngx-smarterplan-core.mjs.map +1 -0
  70. package/lib/components/csv-export/csv-export.component.d.ts +18 -0
  71. package/lib/components/loader/loader.component.d.ts +8 -0
  72. package/lib/components/menu-bar/avatar/avatar.component.d.ts +18 -0
  73. package/lib/components/menu-bar/menu-bar.component.d.ts +35 -0
  74. package/lib/components/menu-bar/navigation-bar/navigation-bar.component.d.ts +66 -0
  75. package/lib/components/menu-bar/range-date-picker/range-date-picker.component.d.ts +24 -0
  76. package/lib/components/modal-switch-visit/modal-switch-visit.component.d.ts +22 -0
  77. package/lib/components/search-bar/search-bar.component.d.ts +16 -0
  78. package/lib/components/support-modal/support-modal.component.d.ts +24 -0
  79. package/lib/config.d.ts +17 -0
  80. package/lib/helpers.service.d.ts +79 -0
  81. package/lib/mattertagData.d.ts +65 -0
  82. package/lib/ngx-smarterplan-core.module.d.ts +28 -0
  83. package/lib/ngx-smarterplan-core.service.d.ts +6 -0
  84. package/lib/pipes/duration-to-string.pipe.d.ts +12 -0
  85. package/lib/pipes/hashtag-from-id.pipe.d.ts +10 -0
  86. package/lib/pipes/safe-url.pipe.d.ts +10 -0
  87. package/lib/pipes/time-date-to-local-string.pipe.d.ts +16 -0
  88. package/lib/pipes/username-from-id.pipe.d.ts +11 -0
  89. package/lib/services/base-tab.service.d.ts +10 -0
  90. package/lib/services/baseVisibility.service.d.ts +8 -0
  91. package/lib/services/booking.service.d.ts +21 -0
  92. package/lib/services/content.service.d.ts +28 -0
  93. package/lib/services/filter.service.d.ts +58 -0
  94. package/lib/services/intervention.service.d.ts +25 -0
  95. package/lib/services/locale.service.d.ts +23 -0
  96. package/lib/services/matterport-import.service.d.ts +46 -0
  97. package/lib/services/matterport.service.d.ts +141 -0
  98. package/lib/services/models/affectation.service.d.ts +14 -0
  99. package/lib/services/models/base-object.service.d.ts +20 -0
  100. package/lib/services/models/capture.service.d.ts +13 -0
  101. package/lib/services/models/comment.service.d.ts +26 -0
  102. package/lib/services/models/domain.service.d.ts +19 -0
  103. package/lib/services/models/equipment.service.d.ts +88 -0
  104. package/lib/services/models/event.service.d.ts +43 -0
  105. package/lib/services/models/feature.service.d.ts +71 -0
  106. package/lib/services/models/hashtag.service.d.ts +13 -0
  107. package/lib/services/models/layer.service.d.ts +11 -0
  108. package/lib/services/models/measurement.service.d.ts +43 -0
  109. package/lib/services/models/mission.service.d.ts +32 -0
  110. package/lib/services/models/navigation.service.d.ts +22 -0
  111. package/lib/services/models/node.service.d.ts +12 -0
  112. package/lib/services/models/operation.service.d.ts +15 -0
  113. package/lib/services/models/organisation.service.d.ts +19 -0
  114. package/lib/services/models/plan.service.d.ts +117 -0
  115. package/lib/services/models/poi.service.d.ts +15 -0
  116. package/lib/services/models/profile.service.d.ts +15 -0
  117. package/lib/services/models/property.service.d.ts +13 -0
  118. package/lib/services/models/space.service.d.ts +38 -0
  119. package/lib/services/models/template.service.d.ts +15 -0
  120. package/lib/services/models/ticket.service.d.ts +86 -0
  121. package/lib/services/models/visit.service.d.ts +24 -0
  122. package/lib/services/models/zone.service.d.ts +25 -0
  123. package/lib/services/navigator.service.d.ts +55 -0
  124. package/lib/services/s3.service.d.ts +13 -0
  125. package/lib/services/search.service.d.ts +20 -0
  126. package/lib/services/support.service.d.ts +17 -0
  127. package/lib/services/tag.service.d.ts +45 -0
  128. package/lib/services/user.service.d.ts +104 -0
  129. package/lib/services/viewer.service.d.ts +113 -0
  130. package/lib/services/zone-drawer.service.d.ts +7 -0
  131. package/lib/types.service.d.ts +723 -0
  132. package/package.json +41 -0
  133. package/public-api.d.ts +56 -0
  134. package/smarterplan-ngx-smarterplan-core.d.ts +5 -0
@@ -0,0 +1,560 @@
1
+ /* eslint-disable no-case-declarations */
2
+ /* eslint-disable no-await-in-loop */
3
+ /* eslint-disable guard-for-in */
4
+ /* eslint-disable class-methods-use-this */
5
+ import { Injectable } from "@angular/core";
6
+ import { Subject } from "rxjs";
7
+ import { getLevelsBelow, getHighestLevelForMissions, getHighestRoleForMissions, filterUniqueArrayByID } from "../helpers.service";
8
+ import { PoiType, ProfileEntity, RoleStatus } from "../types.service";
9
+ import levenshtein from 'js-levenshtein';
10
+ import * as i0 from "@angular/core";
11
+ import * as i1 from "./user.service";
12
+ import * as i2 from "./models/zone.service";
13
+ import * as i3 from "./models/poi.service";
14
+ var FilterType;
15
+ (function (FilterType) {
16
+ FilterType["DOMAIN"] = "DOMAIN";
17
+ FilterType["LEVEL"] = "LEVEL";
18
+ FilterType["ROLE"] = "ROLE";
19
+ FilterType["ZONE"] = "ZONE";
20
+ FilterType["SPACE"] = "SPACE";
21
+ FilterType["HASHTAG"] = "HASHTAG";
22
+ })(FilterType || (FilterType = {}));
23
+ export class FilterService {
24
+ constructor(userService, zoneService, poiService) {
25
+ this.userService = userService;
26
+ this.zoneService = zoneService;
27
+ this.poiService = poiService;
28
+ this.updateDateFilter = new Subject();
29
+ }
30
+ filterTicketsByDomain(ticketsToFilter, domain) {
31
+ return ticketsToFilter.filter((tic) => tic.domainID === domain);
32
+ }
33
+ filterObjectsByLevel(objectsToFilter, level) {
34
+ const visibleLevels = getLevelsBelow(level);
35
+ const filtered = objectsToFilter.filter((tic) => visibleLevels.includes(tic.level));
36
+ return filtered;
37
+ }
38
+ filterTicketsForMission(ticketsToFilter, mission) {
39
+ const managerRoles = [
40
+ RoleStatus.MANAGER,
41
+ RoleStatus.ADMIN,
42
+ RoleStatus.OWNER,
43
+ ];
44
+ if (!managerRoles.includes(mission.role)) {
45
+ if (mission.role === RoleStatus.SERVICE) {
46
+ // SERVICE can see tickets to which he is assigned
47
+ const ticketsAssigned = [];
48
+ for (const t of ticketsToFilter) {
49
+ if (t.assignees.items.length > 0) {
50
+ for (const assignment of t.assignees.items) {
51
+ if (assignment.missionID === mission.id) {
52
+ ticketsAssigned.push(t);
53
+ }
54
+ }
55
+ }
56
+ }
57
+ return ticketsAssigned;
58
+ }
59
+ // OCCUPANT and VISITOR can see only tickets that they created
60
+ return ticketsToFilter.filter((ticket) => {
61
+ return ticket.ownerMissionID === mission.id;
62
+ });
63
+ }
64
+ return ticketsToFilter;
65
+ }
66
+ getFiltersForRole(role) {
67
+ switch (role) {
68
+ case RoleStatus.ADMIN:
69
+ return [FilterType.LEVEL];
70
+ case RoleStatus.MANAGER:
71
+ return [FilterType.ZONE, FilterType.LEVEL];
72
+ case RoleStatus.OWNER:
73
+ return [FilterType.ZONE, FilterType.LEVEL];
74
+ case RoleStatus.SERVICE:
75
+ return [
76
+ // FilterType.ZONE,
77
+ // FilterType.LEVEL,
78
+ // FilterType.DOMAIN,
79
+ FilterType.ROLE, // that is the most severe filter
80
+ ];
81
+ case RoleStatus.OCCUPANT:
82
+ return [
83
+ FilterType.ZONE,
84
+ FilterType.DOMAIN,
85
+ FilterType.ROLE,
86
+ FilterType.LEVEL,
87
+ FilterType.HASHTAG,
88
+ ];
89
+ case RoleStatus.VISITOR:
90
+ return [
91
+ FilterType.ZONE,
92
+ FilterType.LEVEL,
93
+ FilterType.DOMAIN,
94
+ FilterType.ROLE,
95
+ FilterType.HASHTAG,
96
+ ];
97
+ case RoleStatus.VISITOR_MUSEUM:
98
+ return [FilterType.ZONE, FilterType.LEVEL, FilterType.HASHTAG];
99
+ case RoleStatus.GUIDE_MUSEUM:
100
+ return [FilterType.LEVEL];
101
+ default:
102
+ return [FilterType.LEVEL];
103
+ }
104
+ }
105
+ async filterTicketsForCurrentUserInSpace(tickets, spaceID) {
106
+ const finalTickets = [];
107
+ let domFiltered = tickets;
108
+ let roleFiltered = tickets;
109
+ let levelFiltered = tickets;
110
+ let zoneFiltered = tickets;
111
+ const missions = this.userService.currentMissions;
112
+ if (missions) {
113
+ const currentSpaceMissions = missions.filter((m) => m.spaceID === spaceID);
114
+ if (currentSpaceMissions.length > 0) {
115
+ const highestLelel = getHighestLevelForMissions(currentSpaceMissions);
116
+ const highestRole = getHighestRoleForMissions(currentSpaceMissions);
117
+ // console.log("Highest level: ", highestLelel, ", Highest Role: ", highestRole)
118
+ const filters = this.getFiltersForRole(highestRole);
119
+ for (const filter of filters) {
120
+ if (filter === FilterType.DOMAIN) {
121
+ let domains = [];
122
+ for (const m of currentSpaceMissions) {
123
+ if (m.domains) {
124
+ domains = [...domains, ...m.domains];
125
+ }
126
+ }
127
+ let allDomainsFiltered = [];
128
+ for (const d of domains) {
129
+ const currentDomFiltered = this.filterTicketsByDomain(tickets, d);
130
+ allDomainsFiltered = [
131
+ ...allDomainsFiltered,
132
+ ...currentDomFiltered,
133
+ ];
134
+ }
135
+ domFiltered = allDomainsFiltered;
136
+ }
137
+ if (filter === FilterType.ROLE) {
138
+ const highestRoleMission = currentSpaceMissions.find((m) => m.role === highestRole);
139
+ roleFiltered = this.filterTicketsForMission(tickets, highestRoleMission);
140
+ }
141
+ if (filter === FilterType.LEVEL) {
142
+ levelFiltered = this.filterObjectsByLevel(tickets, highestLelel);
143
+ }
144
+ if (filter === FilterType.ZONE) {
145
+ zoneFiltered = await this.applyZoneFilterForMissions(currentSpaceMissions, tickets);
146
+ }
147
+ }
148
+ // keep only tickets present in all filtered arrays
149
+ // console.log(domFiltered);
150
+ // console.log(roleFiltered);
151
+ // console.log(levelFiltered);
152
+ // console.log(zoneFiltered);
153
+ for (const tic of levelFiltered) {
154
+ if (domFiltered.includes(tic) &&
155
+ roleFiltered.includes(tic) &&
156
+ zoneFiltered.includes(tic)) {
157
+ finalTickets.push(tic);
158
+ }
159
+ }
160
+ }
161
+ }
162
+ // console.log(finalTickets);
163
+ return finalTickets;
164
+ }
165
+ subscribeToDataFilterUpdate(next, error, complete) {
166
+ const s = this.updateDateFilter.subscribe(next, error, complete);
167
+ return s;
168
+ }
169
+ dateFilterUpdated(dateRange) {
170
+ this.currentDateFilter = dateRange;
171
+ this.updateDateFilter.next(dateRange);
172
+ }
173
+ filterObjectsForDateRange(objects, dateRange) {
174
+ return objects.filter((object) => {
175
+ const createdAtDate = new Date(object.createdAt);
176
+ return (createdAtDate >= dateRange[0] && createdAtDate <= dateRange[1]);
177
+ });
178
+ }
179
+ filterMeasurementsForDateRange(measurements, dateRange) {
180
+ return measurements.filter((measure) => {
181
+ const createdAtDate = new Date(measure.comment.createdAt);
182
+ return (createdAtDate >= dateRange[0] && createdAtDate <= dateRange[1]);
183
+ });
184
+ }
185
+ async filterObjectsForZone(objects, zoneID = null, zone = null) {
186
+ const filteredObjects = [];
187
+ await Promise.all(objects.map(async (object) => {
188
+ const [poi] = object.pois.items;
189
+ if (poi && zone) {
190
+ if (zone.sweepIDs && zone.sweepIDs.includes(poi.matterportSweepID)) {
191
+ if (this.poiService.poiIsVirtual(poi) && zone.layer && zone.layer.name === "FLOOR") {
192
+ // we include in Floor zone only
193
+ filteredObjects.push(object);
194
+ }
195
+ if (!this.poiService.poiIsVirtual(poi)) {
196
+ filteredObjects.push(object);
197
+ }
198
+ }
199
+ }
200
+ if (poi && !zone && zoneID) {
201
+ const zones = await this.zoneService.getZonesForObject(object);
202
+ if (zones &&
203
+ zones.some((zone_) => zone_.id === zoneID ||
204
+ zone_.parentID === zoneID)) {
205
+ filteredObjects.push(object);
206
+ }
207
+ }
208
+ }));
209
+ return filteredObjects;
210
+ }
211
+ filterEquipmentsByDomainList(equipments, domainIDList) {
212
+ let filtered = [];
213
+ const filteredByDomain = equipments.filter((equip) => domainIDList.includes(equip.domainID));
214
+ filtered = [...filtered, ...filteredByDomain];
215
+ const filteredByParentDomain = equipments.filter((equip) => equip.domain &&
216
+ equip.domain.parentID &&
217
+ domainIDList.includes(equip.domain.parentID));
218
+ filtered = [...filtered, ...filteredByParentDomain];
219
+ return filterUniqueArrayByID(filtered);
220
+ }
221
+ filterEquipmentsForTerm(equips, term) {
222
+ // filter domains
223
+ let byDomain = equips.filter((eq) => {
224
+ if (eq.domain && eq.domain.name) {
225
+ const normalizedDomain = eq.domain.name.toLowerCase();
226
+ const lev = levenshtein(normalizedDomain, term);
227
+ return lev <= 2 || normalizedDomain.includes(term);
228
+ }
229
+ return false;
230
+ });
231
+ const byParentDomain = equips.filter((eq) => {
232
+ if (eq.domain && eq.domain.parentID) {
233
+ const normalizedParent = eq.domain.parent.name.toLowerCase();
234
+ const lev = levenshtein(normalizedParent, term);
235
+ return lev <= 2 || normalizedParent.includes(term);
236
+ }
237
+ return false;
238
+ });
239
+ byDomain = [...byDomain, ...byParentDomain];
240
+ // filter name
241
+ let byName = [];
242
+ const terms = term.split(" ").filter((token) => token.length > 2);
243
+ for (const eq of equips) {
244
+ const words = eq.name
245
+ .toLowerCase()
246
+ .split(" ")
247
+ .filter((token) => token.length > 2);
248
+ const matched = [];
249
+ for (const token of terms) {
250
+ for (const word of words) {
251
+ if (levenshtein(token, word) <= 1) {
252
+ matched.push(true);
253
+ break;
254
+ }
255
+ }
256
+ }
257
+ if (matched.length === terms.length) {
258
+ byName.push(eq);
259
+ }
260
+ }
261
+ const byNameSimple = equips.filter((eq) => eq.name.toLowerCase().includes(term));
262
+ byName = [...byName, ...byNameSimple];
263
+ // by serial number
264
+ const bySerialNumber = equips.filter((eq) => eq.serialNumber && eq.serialNumber.toLowerCase() === term);
265
+ const result = [...byDomain, ...byName, ...bySerialNumber];
266
+ return filterUniqueArrayByID(result);
267
+ }
268
+ filterTicketsForTerm(tickets, term) {
269
+ // filter term in title and description
270
+ const byTitle = this.filterObjectsForTerm(tickets, term);
271
+ // by equipment
272
+ const byEquipment = tickets.filter((ticket) => ticket.equipments &&
273
+ this.filterEquipmentsForTerm(ticket.equipments, term).length >
274
+ 0);
275
+ return filterUniqueArrayByID([...byTitle, ...byEquipment]);
276
+ }
277
+ filterLocationsForTerm(locations, term) {
278
+ // by name
279
+ const byName = locations.filter((loc) => loc.name.toLowerCase().includes(term));
280
+ // by address
281
+ const byAddress = locations.filter((loc) => loc.addresses.toLowerCase().includes(term));
282
+ return filterUniqueArrayByID([...byName, ...byAddress]);
283
+ }
284
+ filterOrganisationsForTerm(orgs, term) {
285
+ const byName = orgs.filter((org) => {
286
+ const words = org.name.toLowerCase().split(" ");
287
+ return (words.some((word) => word.length > 2 && levenshtein(word, term) <= 1) || org.name.toLowerCase().includes(term));
288
+ });
289
+ return byName;
290
+ }
291
+ filterUsersForTerm(users, term) {
292
+ const byName = users.filter((user) => {
293
+ const words = user.displayName.toLowerCase().split(" ");
294
+ return (words.some((word) => word.length > 2 && levenshtein(word, term) <= 1) || user.displayName.toLowerCase().includes(term));
295
+ });
296
+ return byName;
297
+ }
298
+ async filterFeaturesForCurrentUserInSpace(features, spaceID) {
299
+ const finalFeatures = [];
300
+ let levelFiltered = features;
301
+ let zoneFiltered = features;
302
+ let hashtagFiltered = features;
303
+ const missions = this.userService.currentMissions;
304
+ if (missions) {
305
+ const currentSpaceMissions = missions.filter((m) => m.spaceID === spaceID);
306
+ if (currentSpaceMissions.length > 0) {
307
+ const highestLelel = getHighestLevelForMissions(currentSpaceMissions);
308
+ const highestRole = getHighestRoleForMissions(currentSpaceMissions);
309
+ const filters = this.getFiltersForRole(highestRole);
310
+ for (const filter of filters) {
311
+ if (filter === FilterType.LEVEL) {
312
+ levelFiltered = this.filterObjectsByLevel(features, highestLelel);
313
+ }
314
+ if (filter === FilterType.ZONE) {
315
+ zoneFiltered = await this.applyZoneFilterForMissions(currentSpaceMissions, features);
316
+ }
317
+ if (filter === FilterType.HASHTAG) {
318
+ hashtagFiltered =
319
+ this.filterFeaturesByHashtagsAndLocale(currentSpaceMissions, features);
320
+ }
321
+ }
322
+ for (const feature of levelFiltered) {
323
+ if (hashtagFiltered.includes(feature) &&
324
+ zoneFiltered.includes(feature)) {
325
+ finalFeatures.push(feature);
326
+ }
327
+ }
328
+ }
329
+ }
330
+ return finalFeatures;
331
+ }
332
+ filterFeaturesForTerm(features, term) {
333
+ // filter term in title
334
+ const byTitle = this.filterObjectsForTerm(features, term);
335
+ // by comments
336
+ const byComment = features.filter((feature) => this.filterObjectsForTerm(feature.comments.items, term).length >
337
+ 0);
338
+ return filterUniqueArrayByID([...byTitle, ...byComment]);
339
+ }
340
+ /**
341
+ *
342
+ * @param objects Array of Comments, Tickets, Features. Obligatory proporties: title, description
343
+ * @param term string
344
+ */
345
+ filterObjectsForTerm(objects, term) {
346
+ // filter term in title
347
+ const byTitle = objects.filter((feature) => {
348
+ const words = feature.title.toLowerCase().split(" ");
349
+ return (words.some((word) => word.length > 2 && levenshtein(word, term) <= 1) || feature.title.toLowerCase().includes(term));
350
+ });
351
+ // term present in description
352
+ const byDescription = objects.filter((feature) => feature.description &&
353
+ feature.description.toLowerCase().includes(term));
354
+ return filterUniqueArrayByID([...byTitle, ...byDescription]);
355
+ }
356
+ filterMissionByStartTimeDateForDateRange(missions, dateRange) {
357
+ return missions.filter((mission) => {
358
+ const startDateTime = new Date(mission.startDateTime);
359
+ return (startDateTime >= dateRange[0] && startDateTime <= dateRange[1]);
360
+ });
361
+ }
362
+ async applyZoneFilterForMissions(currentSpaceMissions, objects) {
363
+ const allowedZones = [];
364
+ for (const mission of currentSpaceMissions) {
365
+ if (mission.zoneID) {
366
+ allowedZones.push(mission.zoneID);
367
+ }
368
+ }
369
+ if (allowedZones.length === currentSpaceMissions.length) {
370
+ let allZoneFiltered = [];
371
+ await Promise.all(allowedZones.map(async (zoneID) => {
372
+ const currentZoneFiltered = await this.filterObjectsForZone(objects, zoneID);
373
+ allZoneFiltered = [
374
+ ...allZoneFiltered,
375
+ ...currentZoneFiltered,
376
+ ];
377
+ }));
378
+ return filterUniqueArrayByID(allZoneFiltered);
379
+ }
380
+ return objects;
381
+ }
382
+ async filterEquipmentsForCurrentUserInSpace(spaceID, equips) {
383
+ const finalEquips = [];
384
+ let domFiltered = equips;
385
+ const roleFiltered = equips;
386
+ const levelFiltered = equips;
387
+ let zoneFiltered = equips;
388
+ const missions = this.userService.currentMissions;
389
+ if (missions) {
390
+ const currentSpaceMissions = missions.filter((m) => m.spaceID === spaceID);
391
+ if (currentSpaceMissions.length > 0) {
392
+ const highestLelel = getHighestLevelForMissions(currentSpaceMissions);
393
+ const highestRole = getHighestRoleForMissions(currentSpaceMissions);
394
+ // console.log("Highest level: ", highestLelel, ", Highest Role: ", highestRole)
395
+ const filters = this.getFiltersForRole(highestRole);
396
+ for (const filter of filters) {
397
+ if (filter === FilterType.DOMAIN) {
398
+ let domains = [];
399
+ for (const m of currentSpaceMissions) {
400
+ if (m.domains) {
401
+ domains = [...domains, ...m.domains];
402
+ }
403
+ }
404
+ let allDomainsFiltered = [];
405
+ const currentDomFiltered = this.filterEquipmentsByDomainList(equips, domains);
406
+ allDomainsFiltered = [
407
+ ...allDomainsFiltered,
408
+ ...currentDomFiltered,
409
+ ];
410
+ domFiltered = allDomainsFiltered;
411
+ }
412
+ if (filter === FilterType.ROLE) {
413
+ // const highestRoleMission = currentSpaceMissions.find(
414
+ // (m) => m.role === highestRole,
415
+ // );
416
+ // TODO
417
+ }
418
+ if (filter === FilterType.LEVEL) {
419
+ // TODO, equipment does not have level
420
+ }
421
+ if (filter === FilterType.ZONE) {
422
+ zoneFiltered = await this.applyZoneFilterForMissions(currentSpaceMissions, equips);
423
+ }
424
+ }
425
+ for (const tic of levelFiltered) {
426
+ if (domFiltered.includes(tic) &&
427
+ roleFiltered.includes(tic) &&
428
+ zoneFiltered.includes(tic)) {
429
+ finalEquips.push(tic);
430
+ }
431
+ }
432
+ }
433
+ }
434
+ return finalEquips;
435
+ }
436
+ async filterMeasurementsForCurrentUserInSpace(spaceID, comments) {
437
+ let finalMeasurements = [];
438
+ let zoneFiltered = comments;
439
+ const missions = this.userService.currentMissions;
440
+ if (missions) {
441
+ const currentSpaceMissions = missions.filter((m) => m.spaceID === spaceID);
442
+ if (currentSpaceMissions.length > 0) {
443
+ const highestRole = getHighestRoleForMissions(currentSpaceMissions);
444
+ const filters = this.getFiltersForRole(highestRole);
445
+ for (const filter of filters) {
446
+ if (filter === FilterType.ZONE) {
447
+ zoneFiltered = await this.applyZoneFilterForMissions(currentSpaceMissions, comments);
448
+ }
449
+ }
450
+ finalMeasurements = zoneFiltered;
451
+ }
452
+ }
453
+ return finalMeasurements;
454
+ }
455
+ async isObjectAllowedForUserInSpace(object, spaceID) {
456
+ const mission = this.userService.currentMission(spaceID);
457
+ const filters = this.getFiltersForRole(mission.role);
458
+ for (const filter of filters) {
459
+ if (filter === FilterType.LEVEL &&
460
+ Object.prototype.hasOwnProperty.call(object, "level")) {
461
+ const levelFiltered = this.filterObjectsByLevel([object], mission.level);
462
+ if (levelFiltered.length === 0) {
463
+ return false;
464
+ }
465
+ }
466
+ if (filter === FilterType.ZONE) {
467
+ const zoneFiltered = await this.applyZoneFilterForMissions([mission], [object]);
468
+ if (zoneFiltered.length === 0) {
469
+ return false;
470
+ }
471
+ }
472
+ }
473
+ return true;
474
+ }
475
+ filterTemplatesForTerm(missions, term) {
476
+ // term present in description
477
+ const byDescription = missions.filter((mis) => mis.description && mis.description.toLowerCase().includes(term));
478
+ // by user lastName which is the name of the visit:
479
+ // metadata: "{\"firstName\":\"\",\"lastName\":\"Visite du 5 Juillet\"}"
480
+ const userProfiles = missions.map((mis) => new ProfileEntity(mis.user));
481
+ const byUserLastname = this.filterUsersForTerm(userProfiles, term);
482
+ const userIds = new Set(byUserLastname.map((user) => user.id));
483
+ const missionsByUser = missions.filter((mis) => userIds.has(mis.userID));
484
+ return filterUniqueArrayByID([...byDescription, ...missionsByUser]);
485
+ }
486
+ async filterObjectsForSweep(objects, objectType, sweep) {
487
+ let filtered = [];
488
+ switch (objectType) {
489
+ case PoiType.EQUIPMENT:
490
+ const pois = await this.poiService.getPoisByMatterportSweepByType(sweep, objectType);
491
+ const equipIDs = new Set(pois.map((poi) => poi.elementID));
492
+ filtered = objects.filter((object) => equipIDs.has(object.id));
493
+ break;
494
+ default:
495
+ break;
496
+ }
497
+ return filtered;
498
+ }
499
+ filterFeaturesByHashtagsAndLocale(currentSpaceMissions, features) {
500
+ const [currentMission] = currentSpaceMissions;
501
+ // filter by locale
502
+ let filteredLocale = [...features];
503
+ if (currentMission.locale) {
504
+ filteredLocale = features.filter((feature) => feature.locale && feature.locale === currentMission.locale);
505
+ }
506
+ // filter by hashtags
507
+ if (currentMission.hashtags && currentMission.hashtags.length > 0) {
508
+ const filteredByHashtags = [];
509
+ for (const feature of filteredLocale) {
510
+ if (!feature.hashtags || feature.hashtags.length === 0) {
511
+ // Feature without hashtag is available for everybody
512
+ filteredByHashtags.push(feature);
513
+ }
514
+ else if (currentMission.hashtags.every((hashtag) => feature.hashtags.includes(hashtag))) {
515
+ filteredByHashtags.push(feature);
516
+ }
517
+ }
518
+ return filteredByHashtags;
519
+ }
520
+ return filteredLocale;
521
+ }
522
+ filterFeaturesForMissionWithoutZone(features, mission) {
523
+ const finalFeatures = [];
524
+ let levelFiltered = features;
525
+ let zoneFiltered = features;
526
+ let hashtagFiltered = features;
527
+ const filters = this.getFiltersForRole(mission.role);
528
+ for (const filter of filters) {
529
+ if (filter === FilterType.LEVEL) {
530
+ levelFiltered = this.filterObjectsByLevel(features, mission.level);
531
+ }
532
+ // if (filter === FilterType.ZONE) {
533
+ // zoneFiltered = await this.applyZoneFilterForMissions(
534
+ // currentSpaceMissions,
535
+ // features,
536
+ // );
537
+ // }
538
+ if (filter === FilterType.HASHTAG) {
539
+ hashtagFiltered =
540
+ this.filterFeaturesByHashtagsAndLocale([mission], features);
541
+ }
542
+ }
543
+ for (const feature of levelFiltered) {
544
+ if (hashtagFiltered.includes(feature) &&
545
+ zoneFiltered.includes(feature)) {
546
+ finalFeatures.push(feature);
547
+ }
548
+ }
549
+ return finalFeatures;
550
+ }
551
+ }
552
+ FilterService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: FilterService, deps: [{ token: i1.BaseUserService }, { token: i2.ZoneService }, { token: i3.PoiService }], target: i0.ɵɵFactoryTarget.Injectable });
553
+ FilterService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: FilterService, providedIn: "root" });
554
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: FilterService, decorators: [{
555
+ type: Injectable,
556
+ args: [{
557
+ providedIn: "root",
558
+ }]
559
+ }], ctorParameters: function () { return [{ type: i1.BaseUserService }, { type: i2.ZoneService }, { type: i3.PoiService }]; } });
560
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsdGVyLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtc21hcnRlcnBsYW4tY29yZS9zcmMvbGliL3NlcnZpY2VzL2ZpbHRlci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHlDQUF5QztBQUN6QyxxQ0FBcUM7QUFDckMsaUNBQWlDO0FBQ2pDLDJDQUEyQztBQUMzQyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxPQUFPLEVBQWdCLE1BQU0sTUFBTSxDQUFDO0FBQzdDLE9BQU8sRUFBRSxjQUFjLEVBQUUsMEJBQTBCLEVBQUUseUJBQXlCLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNsSSxPQUFPLEVBQW9FLE9BQU8sRUFBRSxhQUFhLEVBQUUsVUFBVSxFQUFnRSxNQUFNLGtCQUFrQixDQUFDO0FBWXRNLE9BQU8sV0FBVyxNQUFNLGdCQUFnQixDQUFDOzs7OztBQVJ6QyxJQUFLLFVBT0o7QUFQRCxXQUFLLFVBQVU7SUFDWCwrQkFBaUIsQ0FBQTtJQUNqQiw2QkFBZSxDQUFBO0lBQ2YsMkJBQWEsQ0FBQTtJQUNiLDJCQUFhLENBQUE7SUFDYiw2QkFBZSxDQUFBO0lBQ2YsaUNBQW1CLENBQUE7QUFDdkIsQ0FBQyxFQVBJLFVBQVUsS0FBVixVQUFVLFFBT2Q7QUFLRCxNQUFNLE9BQU8sYUFBYTtJQUt0QixZQUNZLFdBQTRCLEVBQzVCLFdBQXdCLEVBQ3hCLFVBQXNCO1FBRnRCLGdCQUFXLEdBQVgsV0FBVyxDQUFpQjtRQUM1QixnQkFBVyxHQUFYLFdBQVcsQ0FBYTtRQUN4QixlQUFVLEdBQVYsVUFBVSxDQUFZO1FBUDFCLHFCQUFnQixHQUFvQixJQUFJLE9BQU8sRUFBRSxDQUFDO0lBUXZELENBQUM7SUFFSixxQkFBcUIsQ0FBQyxlQUF5QixFQUFFLE1BQWM7UUFDM0QsT0FBTyxlQUFlLENBQUMs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VCxhQUFhO2tCQUh6QixVQUFVO21CQUFDO29CQUNSLFVBQVUsRUFBRSxNQUFNO2lCQUNyQiIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIG5vLWNhc2UtZGVjbGFyYXRpb25zICovXHJcbi8qIGVzbGludC1kaXNhYmxlIG5vLWF3YWl0LWluLWxvb3AgKi9cclxuLyogZXNsaW50LWRpc2FibGUgZ3VhcmQtZm9yLWluICovXHJcbi8qIGVzbGludC1kaXNhYmxlIGNsYXNzLW1ldGhvZHMtdXNlLXRoaXMgKi9cclxuaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XHJcbmltcG9ydCB7IFN1YmplY3QsIFN1YnNjcmlwdGlvbiB9IGZyb20gXCJyeGpzXCI7XHJcbmltcG9ydCB7IGdldExldmVsc0JlbG93LCBnZXRIaWdoZXN0TGV2ZWxGb3JNaXNzaW9ucywgZ2V0SGlnaGVzdFJvbGVGb3JNaXNzaW9ucywgZmlsdGVyVW5pcXVlQXJyYXlCeUlEIH0gZnJvbSBcIi4uL2hlbHBlcnMuc2VydmljZVwiO1xyXG5pbXBvcnQgeyBab25lLCBFcXVpcG1lbnQsIExldmVsU3RhdHVzLCBNZWFzdXJlbWVudCwgTWlzc2lvbiwgT3JnYW5pc2F0aW9uLCBQb2lUeXBlLCBQcm9maWxlRW50aXR5LCBSb2xlU3RhdHVzLCBTcGFjZSwgVGlja2V0LCBEYk9iamVjdFR5cGUsIEZlYXR1cmUsIENvbW1lbnQsIFZpc2l0VGVtcGxhdGUgfSBmcm9tIFwiLi4vdHlwZXMuc2VydmljZVwiO1xyXG5pbXBvcnQgeyBQb2lTZXJ2aWNlIH0gZnJvbSBcIi4vbW9kZWxzL3BvaS5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IFpvbmVTZXJ2aWNlIH0gZnJvbSBcIi4vbW9kZWxzL3pvbmUuc2VydmljZVwiO1xyXG5pbXBvcnQgeyBCYXNlVXNlclNlcnZpY2UgfSBmcm9tIFwiLi91c2VyLnNlcnZpY2VcIjtcclxuZW51bSBGaWx0ZXJUeXBlIHtcclxuICAgIERPTUFJTiA9IFwiRE9NQUlOXCIsXHJcbiAgICBMRVZFTCA9IFwiTEVWRUxcIixcclxuICAgIFJPTEUgPSBcIlJPTEVcIixcclxuICAgIFpPTkUgPSBcIlpPTkVcIixcclxuICAgIFNQQUNFID0gXCJTUEFDRVwiLFxyXG4gICAgSEFTSFRBRyA9IFwiSEFTSFRBR1wiLFxyXG59XHJcbmltcG9ydCBsZXZlbnNodGVpbiBmcm9tICdqcy1sZXZlbnNodGVpbic7XHJcbkBJbmplY3RhYmxlKHtcclxuICAgIHByb3ZpZGVkSW46IFwicm9vdFwiLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgRmlsdGVyU2VydmljZSB7XHJcbiAgICBwcml2YXRlIHVwZGF0ZURhdGVGaWx0ZXI6IFN1YmplY3Q8RGF0ZVtdPiA9IG5ldyBTdWJqZWN0KCk7XHJcblxyXG4gICAgcHVibGljIGN1cnJlbnREYXRlRmlsdGVyOiBEYXRlW107XHJcblxyXG4gICAgY29uc3RydWN0b3IoXHJcbiAgICAgICAgcHJpdmF0ZSB1c2VyU2VydmljZTogQmFzZVVzZXJTZXJ2aWNlLFxyXG4gICAgICAgIHByaXZhdGUgem9uZVNlcnZpY2U6IFpvbmVTZXJ2aWNlLFxyXG4gICAgICAgIHByaXZhdGUgcG9pU2VydmljZTogUG9pU2VydmljZSxcclxuICAgICkge31cclxuXHJcbiAgICBmaWx0ZXJUaWNrZXRzQnlEb21haW4odGlja2V0c1RvRmlsdGVyOiBUaWNrZXRbXSwgZG9tYWluOiBzdHJpbmcpIHtcclxuICAgICAgICByZXR1cm4gdGlja2V0c1RvRmlsdGVyLmZpbHRlcigodGljKSA9PiB0aWMuZG9tYWluSUQgPT09IGRvbWFpbik7XHJcbiAgICB9XHJcblxyXG4gICAgZmlsdGVyT2JqZWN0c0J5TGV2ZWwob2JqZWN0c1RvRmlsdGVyOiBhbnlbXSwgbGV2ZWw6IExldmVsU3RhdHVzKTogYW55W10ge1xyXG4gICAgICAgIGNvbnN0IHZpc2libGVMZXZlbHMgPSBnZXRMZXZlbHNCZWxvdyhsZXZlbCk7XHJcbiAgICAgICAgY29uc3QgZmlsdGVyZWQgPSBvYmplY3RzVG9GaWx0ZXIuZmlsdGVyKCh0aWMpID0+XHJcbiAgICAgICAgICAgIHZpc2libGVMZXZlbHMuaW5jbHVkZXModGljLmxldmVsKSxcclxuICAgICAgICApO1xyXG4gICAgICAgIHJldHVybiBmaWx0ZXJlZDtcclxuICAgIH1cclxuXHJcbiAgICBmaWx0ZXJUaWNrZXRzRm9yTWlzc2lvbihcclxuICAgICAgICB0aWNrZXRzVG9GaWx0ZXI6IFRpY2tldFtdLFxyXG4gICAgICAgIG1pc3Npb246IE1pc3Npb24sXHJcbiAgICApOiBUaWNrZXRbXSB7XHJcbiAgICAgICAgY29uc3QgbWFuYWdlclJvbGVzOiBSb2xlU3RhdHVzW10gPSBbXHJcbiAgICAgICAgICAgIFJvbGVTdGF0dXMuTUFOQUdFUixcclxuICAgICAgICAgICAgUm9sZVN0YXR1cy5BRE1JTixcclxuICAgICAgICAgICAgUm9sZVN0YXR1cy5PV05FUixcclxuICAgICAgICBdO1xyXG4gICAgICAgIGlmICghbWFuYWdlclJvbGVzLmluY2x1ZGVzKG1pc3Npb24ucm9sZSkpIHtcclxuICAgICAgICAgICAgaWYgKG1pc3Npb24ucm9sZSA9PT0gUm9sZVN0YXR1cy5TRVJWSUNFKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBTRVJWSUNFIGNhbiBzZWUgdGlja2V0cyB0byB3aGljaCBoZSBpcyBhc3NpZ25lZFxyXG4gICAgICAgICAgICAgICAgY29uc3QgdGlja2V0c0Fzc2lnbmVkID0gW107XHJcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHQgb2YgdGlja2V0c1RvRmlsdGVyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHQuYXNzaWduZWVzLml0ZW1zLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBhc3NpZ25tZW50IG9mIHQuYXNzaWduZWVzLml0ZW1zKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYXNzaWdubWVudC5taXNzaW9uSUQgPT09IG1pc3Npb24uaWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aWNrZXRzQXNzaWduZWQucHVzaCh0KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiB0aWNrZXRzQXNzaWduZWQ7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gT0NDVVBBTlQgYW5kIFZJU0lUT1IgY2FuIHNlZSBvbmx5IHRpY2tldHMgdGhhdCB0aGV5IGNyZWF0ZWRcclxuICAgICAgICAgICAgcmV0dXJuIHRpY2tldHNUb0ZpbHRlci5maWx0ZXIoKHRpY2tldCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRpY2tldC5vd25lck1pc3Npb25JRCA9PT0gbWlzc2lvbi5pZDtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0aWNrZXRzVG9GaWx0ZXI7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0RmlsdGVyc0ZvclJvbGUocm9sZTogUm9sZVN0YXR1cyk6IEZpbHRlclR5cGVbXSB7XHJcbiAgICAgICAgc3dpdGNoIChyb2xlKSB7XHJcbiAgICAgICAgICAgIGNhc2UgUm9sZVN0YXR1cy5BRE1JTjpcclxuICAgICAgICAgICAgICAgIHJldHVybiBbRmlsdGVyVHlwZS5MRVZFTF07XHJcbiAgICAgICAgICAgIGNhc2UgUm9sZVN0YXR1cy5NQU5BR0VSOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFtGaWx0ZXJUeXBlLlpPTkUsIEZpbHRlclR5cGUuTEVWRUxdO1xyXG4gICAgICAgICAgICBjYXNlIFJvbGVTdGF0dXMuT1dORVI6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gW0ZpbHRlclR5cGUuWk9ORSwgRmlsdGVyVHlwZS5MRVZFTF07XHJcbiAgICAgICAgICAgIGNhc2UgUm9sZVN0YXR1cy5TRVJWSUNFOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFtcclxuICAgICAgICAgICAgICAgICAgICAvLyBGaWx0ZXJUeXBlLlpPTkUsXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gRmlsdGVyVHlwZS5MRVZFTCxcclxuICAgICAgICAgICAgICAgICAgICAvLyBGaWx0ZXJUeXBlLkRPTUFJTixcclxuICAgICAgICAgICAgICAgICAgICBGaWx0ZXJUeXBlLlJPTEUsIC8vIHRoYXQgaXMgdGhlIG1vc3Qgc2V2ZXJlIGZpbHRlclxyXG4gICAgICAgICAgICAgICAgXTtcclxuICAgICAgICAgICAgY2FzZSBSb2xlU3RhdHVzLk9DQ1VQQU5UOlxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIFtcclxuICAgICAgICAgICAgICAgICAgICBGaWx0ZXJUeXBlLlpPTkUsXHJcbiAgICAgICAgICAgICAgICAgICAgRmlsdGVyVHlwZS5ET01BSU4sXHJcbiAgICAgICAgICAgICAgICAgICAgRmlsdGVyVHlwZS5ST0xFLFxyXG4gICAgICAgICAgICAgICAgICAgIEZpbHRlclR5cGUuTEVWRUwsXHJcbiAgICAgICAgICAgICAgICAgICAgRmlsdGVyVHlwZS5IQVNIVEFHLFxyXG4gICAgICAgICAgICAgICAgXTtcclxuICAgICAgICAgICAgY2FzZSBSb2xlU3RhdHVzLlZJU0lUT1I6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gW1xyXG4gICAgICAgICAgICAgICAgICAgIEZpbHRlclR5cGUuWk9ORSxcclxuICAgICAgICAgICAgICAgICAgICBGaWx0ZXJUeXBlLkxFVkVMLFxyXG4gICAgICAgICAgICAgICAgICAgIEZpbHRlclR5cGUuRE9NQUlOLFxyXG4gICAgICAgICAgICAgICAgICAgIEZpbHRlclR5cGUuUk9MRSxcclxuICAgICAgICAgICAgICAgICAgICBGaWx0ZXJUeXBlLkhBU0hUQUcsXHJcbiAgICAgICAgICAgICAgICBdO1xyXG4gICAgICAgICAgICBjYXNlIFJvbGVTdGF0dXMuVklTSVRPUl9NVVNFVU06XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gW0ZpbHRlclR5cGUuWk9ORSwgRmlsdGVyVHlwZS5MRVZFTCwgRmlsdGVyVHlwZS5IQVNIVEFHXTtcclxuICAgICAgICAgICAgY2FzZSBSb2xlU3RhdHVzLkdVSURFX01VU0VVTTpcclxuICAgICAgICAgICAgICAgIHJldHVybiBbRmlsdGVyVHlwZS5MRVZFTF07XHJcbiAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gW0ZpbHRlclR5cGUuTEVWRUxdO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBmaWx0ZXJUaWNrZXRzRm9yQ3VycmVudFVzZXJJblNwYWNlKFxyXG4gICAgICAgIHRpY2tldHM6IFRpY2tldFtdLFxyXG4gICAgICAgIHNwYWNlSUQ6IHN0cmluZyxcclxuICAgICk6IFByb21pc2U8VGlja2V0W10+IHtcclxuICAgICAgICBjb25zdCBmaW5hbFRpY2tldHM6IFRpY2tldFtdID0gW107XHJcbiAgICAgICAgbGV0IGRvbUZpbHRlcmVkOiBUaWNrZXRbXSA9IHRpY2tldHM7XHJcbiAgICAgICAgbGV0IHJvbGVGaWx0ZXJlZDogVGlja2V0W10gPSB0aWNrZXRzO1xyXG4gICAgICAgIGxldCBsZXZlbEZpbHRlcmVkOiBUaWNrZXRbXSA9IHRpY2tldHM7XHJcbiAgICAgICAgbGV0IHpvbmVGaWx0ZXJlZDogVGlja2V0W10gPSB0aWNrZXRzO1xyXG4gICAgICAgIGNvbnN0IG1pc3Npb25zID0gdGhpcy51c2VyU2VydmljZS5jdXJyZW50TWlzc2lvbnM7XHJcbiAgICAgICAgaWYgKG1pc3Npb25zKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRTcGFjZU1pc3Npb25zID0gbWlzc2lvbnMuZmlsdGVyKFxyXG4gICAgICAgICAgICAgICAgKG0pID0+IG0uc3BhY2VJRCA9PT0gc3BhY2VJRCxcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgaWYgKGN1cnJlbnRTcGFjZU1pc3Npb25zLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGhpZ2hlc3RMZWxlbCA9XHJcbiAgICAgICAgICAgICAgICAgICAgZ2V0SGlnaGVzdExldmVsRm9yTWlzc2lvbnMoY3VycmVudFNwYWNlTWlzc2lvbnMpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaGlnaGVzdFJvbGUgPVxyXG4gICAgICAgICAgICAgICAgICAgIGdldEhpZ2hlc3RSb2xlRm9yTWlzc2lvbnMoY3VycmVudFNwYWNlTWlzc2lvbnMpO1xyXG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coXCJIaWdoZXN0IGxldmVsOiBcIiwgaGlnaGVzdExlbGVsLCBcIiwgSGlnaGVzdCBSb2xlOiBcIiwgaGlnaGVzdFJvbGUpXHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgZmlsdGVycyA9IHRoaXMuZ2V0RmlsdGVyc0ZvclJvbGUoaGlnaGVzdFJvbGUpO1xyXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBmaWx0ZXIgb2YgZmlsdGVycykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChmaWx0ZXIgPT09IEZpbHRlclR5cGUuRE9NQUlOKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBkb21haW5zOiBzdHJpbmdbXSA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IG0gb2YgY3VycmVudFNwYWNlTWlzc2lvbnMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtLmRvbWFpbnMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb21haW5zID0gWy4uLmRvbWFpbnMsIC4uLm0uZG9tYWluc107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGFsbERvbWFpbnNGaWx0ZXJlZCA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGQgb2YgZG9tYWlucykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY3VycmVudERvbUZpbHRlcmVkID1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZpbHRlclRpY2tldHNCeURvbWFpbih0aWNrZXRzLCBkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsbERvbWFpbnNGaWx0ZXJlZCA9IFtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5hbGxEb21haW5zRmlsdGVyZWQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4uY3VycmVudERvbUZpbHRlcmVkLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBkb21GaWx0ZXJlZCA9IGFsbERvbWFpbnNGaWx0ZXJlZDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZpbHRlciA9PT0gRmlsdGVyVHlwZS5ST0xFKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGhpZ2hlc3RSb2xlTWlzc2lvbiA9IGN1cnJlbnRTcGFjZU1pc3Npb25zLmZpbmQoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAobSkgPT4gbS5yb2xlID09PSBoaWdoZXN0Um9sZSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcm9sZUZpbHRlcmVkID0gdGhpcy5maWx0ZXJUaWNrZXRzRm9yTWlzc2lvbihcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRpY2tldHMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaWdoZXN0Um9sZU1pc3Npb24sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBpZiAoZmlsdGVyID09PSBGaWx0ZXJUeXBlLkxFVkVMKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldmVsRmlsdGVyZWQgPSB0aGlzLmZpbHRlck9iamVjdHNCeUxldmVsKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGlja2V0cyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpZ2hlc3RMZWxlbCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChmaWx0ZXIgPT09IEZpbHRlclR5cGUuWk9ORSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB6b25lRmlsdGVyZWQgPSBhd2FpdCB0aGlzLmFwcGx5Wm9uZUZpbHRlckZvck1pc3Npb25zKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudFNwYWNlTWlzc2lvbnMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aWNrZXRzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vIGtlZXAgb25seSB0aWNrZXRzIHByZXNlbnQgaW4gYWxsIGZpbHRlcmVkIGFycmF5c1xyXG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coZG9tRmlsdGVyZWQpO1xyXG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2cocm9sZUZpbHRlcmVkKTtcclxuICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGxldmVsRmlsdGVyZWQpO1xyXG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coem9uZUZpbHRlcmVkKTtcclxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgdGljIG9mIGxldmVsRmlsdGVyZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRvbUZpbHRlcmVkLmluY2x1ZGVzKHRpYykgJiZcclxuICAgICAgICAgICAgICAgICAgICAgICAgcm9sZUZpbHRlcmVkLmluY2x1ZGVzKHRpYykgJiZcclxuICAgICAgICAgICAgICAgICAgICAgICAgem9uZUZpbHRlcmVkLmluY2x1ZGVzKHRpYylcclxuICAgICAgICAgICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmluYWxUaWNrZXRzLnB1c2godGljKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gY29uc29sZS5sb2coZmluYWxUaWNrZXRzKTtcclxuICAgICAgICByZXR1cm4gZmluYWxUaWNrZXRzO1xyXG4gICAgfVxyXG5cclxuICAgIHN1YnNjcmliZVRvRGF0YUZpbHRlclVwZGF0ZShcclxuICAgICAgICBuZXh0PzogKHZhbHVlOiBhbnkpID0+IHZvaWQsXHJcbiAgICAgICAgZXJyb3I/OiAoZXJyb3I6IGFueSkgPT4gdm9pZCxcclxuICAgICAgICBjb21wbGV0ZT86ICgpID0+IHZvaWQsXHJcbiAgICApOiBTdWJzY3JpcHRpb24ge1xyXG4gICAgICAgIGNvbnN0IHMgPSB0aGlzLnVwZGF0ZURhdGVGaWx0ZXIuc3Vic2NyaWJlKG5leHQsIGVycm9yLCBjb21wbGV0ZSk7XHJcbiAgICAgICAgcmV0dXJuIHM7XHJcbiAgICB9XHJcblxyXG4gICAgZGF0ZUZpbHRlclVwZGF0ZWQoZGF0ZVJhbmdlOiBEYXRlW10gfCBudWxsKSB7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50RGF0ZUZpbHRlciA9IGRhdGVSYW5nZTtcclxuICAgICAgICB0aGlzLnVwZGF0ZURhdGVGaWx0ZXIubmV4dChkYXRlUmFuZ2UpO1xyXG4gICAgfVxyXG5cclxuICAgIGZpbHRlck9iamVjdHNGb3JEYXRlUmFuZ2Uob2JqZWN0czogYW55W10sIGRhdGVSYW5nZTogRGF0ZVtdKTogYW55W10ge1xyXG4gICAgICAgIHJldHVybiBvYmplY3RzLmZpbHRlcigob2JqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IGNyZWF0ZWRBdERhdGUgPSBuZXcgRGF0ZShvYmplY3QuY3JlYXRlZEF0KTtcclxuICAgICAgICAgICAgcmV0dXJuIChcclxuICAgICAgICAgICAgICAgIGNyZWF0ZWRBdERhdGUgPj0gZGF0ZVJhbmdlWzBdICYmIGNyZWF0ZWRBdERhdGUgPD0gZGF0ZVJhbmdlWzFdXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgZmlsdGVyTWVhc3VyZW1lbnRzRm9yRGF0ZVJhbmdlKFxyXG4gICAgICAgIG1lYXN1cmVtZW50czogTWVhc3VyZW1lbnRbXSxcclxuICAgICAgICBkYXRlUmFuZ2U6IERhdGVbXSxcclxuICAgICk6IE1lYXN1cmVtZW50W10ge1xyXG4gICAgICAgIHJldHVybiBtZWFzdXJlbWVudHMuZmlsdGVyKChtZWFzdXJlKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IGNyZWF0ZWRBdERhdGUgPSBuZXcgRGF0ZShtZWFzdXJlLmNvbW1lbnQuY3JlYXRlZEF0KTtcclxuICAgICAgICAgICAgcmV0dXJuIChcclxuICAgICAgICAgICAgICAgIGNyZWF0ZWRBdERhdGUgPj0gZGF0ZVJhbmdlWzBdICYmIGNyZWF0ZWRBdERhdGUgPD0gZGF0ZVJhbmdlWzFdXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgZmlsdGVyT2JqZWN0c0ZvclpvbmUoXHJcbiAgICAgICAgb2JqZWN0czogYW55W10sXHJcbiAgICAgICAgem9uZUlEOiBzdHJpbmcgPSBudWxsLFxyXG4gICAgICAgIHpvbmU6IFpvbmUgPSBudWxsLFxyXG4gICAgKTogUHJvbWlzZTxhbnlbXT4ge1xyXG4gICAgICAgIGNvbnN0IGZpbHRlcmVkT2JqZWN0cyA9IFtdO1xyXG4gICAgICAgIGF3YWl0IFByb21pc2UuYWxsKFxyXG4gICAgICAgICAgICBvYmplY3RzLm1hcChhc3luYyAob2JqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBbcG9pXSA9IG9iamVjdC5wb2lzLml0ZW1zO1xyXG4gICAgICAgICAgICAgICAgaWYgKHBvaSAmJiB6b25lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHpvbmUuc3dlZXBJRHMgJiYgem9uZS5zd2VlcElEcy5pbmNsdWRlcyhwb2kubWF0dGVycG9ydFN3ZWVwSUQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnBvaVNlcnZpY2UucG9pSXNWaXJ0dWFsKHBvaSkgJiYgem9uZS5sYXllciAmJiB6b25lLmxheWVyLm5hbWUgPT09IFwiRkxPT1JcIiApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdlIGluY2x1ZGUgaW4gRmxvb3Igem9uZSBvbmx5XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXJlZE9iamVjdHMucHVzaChvYmplY3QpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5wb2lTZXJ2aWNlLnBvaUlzVmlydHVhbChwb2kpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXJlZE9iamVjdHMucHVzaChvYmplY3QpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHBvaSAmJiAhem9uZSAmJiB6b25lSUQpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB6b25lcyA9IGF3YWl0IHRoaXMuem9uZVNlcnZpY2UuZ2V0Wm9uZXNGb3JPYmplY3QoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdCxcclxuICAgICAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChcclxuICAgICAgICAgICAgICAgICAgICAgICAgem9uZXMgJiZcclxuICAgICAgICAgICAgICAgICAgICAgICAgem9uZXMuc29tZShcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICh6b25lXykgPT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB6b25lXy5pZCA9PT0gem9uZUlEIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgem9uZV8ucGFyZW50SUQgPT09IHpvbmVJRCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICAgICAgICAgICkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmaWx0ZXJlZE9iamVjdHMucHVzaChvYmplY3QpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSksXHJcbiAgICAgICAgKTtcclxuICAgICAgICByZXR1cm4gZmlsdGVyZWRPYmplY3RzO1xyXG4gICAgfVxyXG5cclxuICAgIGZpbHRlckVxdWlwbWVudHNCeURvbWFpbkxpc3QoXHJcbiAgICAgICAgZXF1aXBtZW50czogRXF1aXBtZW50W10sXHJcbiAgICAgICAgZG9tYWluSURMaXN0OiBzdHJpbmdbXSxcclxuICAgICk6IEVxdWlwbWVudFtdIHtcclxuICAgICAgICBsZXQgZmlsdGVyZWQgPSBbXTtcclxuICAgICAgICBjb25zdCBmaWx0ZXJlZEJ5RG9tYWluID0gZXF1aXBtZW50cy5maWx0ZXIoKGVxdWlwKSA9PlxyXG4gICAgICAgICAgICBkb21haW5JRExpc3QuaW5jbHVkZXMoZXF1aXAuZG9tYWluSUQpLFxyXG4gICAgICAgICk7XHJcbiAgICAgICAgZmlsdGVyZWQgPSBbLi4uZmlsdGVyZWQsIC4uLmZpbHRlcmVkQnlEb21haW5dO1xyXG4gICAgICAgIGNvbnN0IGZpbHRlcmVkQnlQYXJlbnREb21haW4gPSBlcXVpcG1lbnRzLmZpbHRlcihcclxuICAgICAgICAgICAgKGVxdWlwKSA9PlxyXG4gICAgICAgICAgICAgICAgZXF1aXAuZG9tYWluICYmXHJcbiAgICAgICAgICAgICAgICBlcXVpcC5kb21haW4ucGFyZW50SUQgJiZcclxuICAgICAgICAgICAgICAgIGRvbWFpbklETGlzdC5pbmNsdWRlcyhlcXVpcC5kb21haW4ucGFyZW50SUQpLFxyXG4gICAgICAgICk7XHJcbiAgICAgICAgZmlsdGVyZWQgPSBbLi4uZmlsdGVyZWQsIC4uLmZpbHRlcmVkQnlQYXJlbnREb21haW5dO1xyXG4gICAgICAgIHJldHVybiBmaWx0ZXJVbmlxdWVBcnJheUJ5SUQoZmlsdGVyZWQpO1xyXG4gICAgfVxyXG5cclxuICAgIGZpbHRlckVxdWlwbWVudHNGb3JUZXJtKGVxdWlwczogRXF1aXBtZW50W10sIHRlcm06IHN0cmluZyk6IEVxdWlwbWVudFtdIHtcclxuICAgICAgICAvLyBmaWx0ZXIgZG9tYWluc1xyXG4gICAgICAgIGxldCBieURvbWFpbiA9IGVxdWlwcy5maWx0ZXIoKGVxKSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChlcS5kb21haW4gJiYgZXEuZG9tYWluLm5hbWUpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG5vcm1hbGl6ZWREb21haW4gPSBlcS5kb21haW4ubmFtZS50b0xvd2VyQ2FzZSgpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbGV2ID0gbGV2ZW5zaHRlaW4obm9ybWFsaXplZERvbWFpbiwgdGVybSk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbGV2IDw9IDIgfHwgbm9ybWFsaXplZERvbWFpbi5pbmNsdWRlcyh0ZXJtKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgY29uc3QgYnlQYXJlbnREb21haW4gPSBlcXVpcHMuZmlsdGVyKChlcSkgPT4ge1xyXG4gICAgICAgICAgICBpZiAoZXEuZG9tYWluICYmIGVxLmRvbWFpbi5wYXJlbnRJRCkge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgbm9ybWFsaXplZFBhcmVudCA9IGVxLmRvbWFpbi5wYXJlbnQubmFtZS50b0xvd2VyQ2FzZSgpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbGV2ID0gbGV2ZW5zaHRlaW4obm9ybWFsaXplZFBhcmVudCwgdGVybSk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbGV2IDw9IDIgfHwgbm9ybWFsaXplZFBhcmVudC5pbmNsdWRlcyh0ZXJtKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgYnlEb21haW4gPSBbLi4uYnlEb21haW4sIC4uLmJ5UGFyZW50RG9tYWluXTtcclxuICAgICAgICAvLyBmaWx0ZXIgbmFtZVxyXG4gICAgICAgIGxldCBieU5hbWUgPSBbXTtcclxuICAgICAgICBjb25zdCB0ZXJtcyA9IHRlcm0uc3BsaXQoXCIgXCIpLmZpbHRlcigodG9rZW4pID0+IHRva2VuLmxlbmd0aCA+IDIpO1xyXG4gICAgICAgIGZvciAoY29uc3QgZXEgb2YgZXF1aXBzKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHdvcmRzID0gZXEubmFtZVxyXG4gICAgICAgICAgICAgICAgLnRvTG93ZXJDYXNlKClcclxuICAgICAgICAgICAgICAgIC5zcGxpdChcIiBcIilcclxuICAgICAgICAgICAgICAgIC5maWx0ZXIoKHRva2VuKSA9PiB0b2tlbi5sZW5ndGggPiAyKTtcclxuICAgICAgICAgICAgY29uc3QgbWF0Y2hlZCA9IFtdO1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHRva2VuIG9mIHRlcm1zKSB7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IHdvcmQgb2Ygd29yZHMpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAobGV2ZW5zaHRlaW4odG9rZW4sIHdvcmQpIDw9IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbWF0Y2hlZC5wdXNoKHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKG1hdGNoZWQubGVuZ3RoID09PSB0ZXJtcy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgIGJ5TmFtZS5wdXNoKGVxKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgYnlOYW1lU2ltcGxlID0gZXF1aXBzLmZpbHRlcigoZXEpID0+XHJcbiAgICAgICAgICAgIGVxLm5hbWUudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyh0ZXJtKSxcclxuICAgICAgICApO1xyXG4gICAgICAgIGJ5TmFtZSA9IFsuLi5ieU5hbWUsIC4uLmJ5TmFtZVNpbXBsZV07XHJcbiAgICAgICAgLy8gYnkgc2VyaWFsIG51bWJlclxyXG4gICAgICAgIGNvbnN0IGJ5U2VyaWFsTnVtYmVyID0gZXF1aXBzLmZpbHRlcihcclxuICAgICAgICAgICAgKGVxKSA9PiBlcS5zZXJpYWxOdW1iZXIgJiYgZXEuc2VyaWFsTnVtYmVyLnRvTG93ZXJDYXNlKCkgPT09IHRlcm0sXHJcbiAgICAgICAgKTtcclxuICAgICAgICBjb25zdCByZXN1bHQgPSBbLi4uYnlEb21haW4sIC4uLmJ5TmFtZSwgLi4uYnlTZXJpYWxOdW1iZXJdO1xyXG4gICAgICAgIHJldHVybiBmaWx0ZXJVbmlxdWVBcnJheUJ5SUQocmVzdWx0KTtcclxuICAgIH1cclxuXHJcbiAgICBmaWx0ZXJUaWNrZXRzRm9yVGVybSh0aWNrZXRzOiBUaWNrZXRbXSwgdGVybTogc3RyaW5nKTogVGlja2V0W10ge1xyXG4gICAgICAgIC8vIGZpbHRlciB0ZXJtIGluIHRpdGxlIGFuZCBkZXNjcmlwdGlvblxyXG4gICAgICAgIGNvbnN0IGJ5VGl0bGUgPSB0aGlzLmZpbHRlck9iamVjdHNGb3JUZXJtKHRpY2tldHMsIHRlcm0pO1xyXG4gICAgICAgIC8vIGJ5IGVxdWlwbWVudFxyXG4gICAgICAgIGNvbnN0IGJ5RXF1aXBtZW50ID0gdGlja2V0cy5maWx0ZXIoXHJcbiAgICAgICAgICAgICh0aWNrZXQpID0+XHJcbiAgICAgICAgICAgICAgICB0aWNrZXQuZXF1aXBtZW50cyAmJlxyXG4gICAgICAgICAgICAgICAgdGhpcy5maWx0ZXJFcXVpcG1lbnRzRm9yVGVybSh0aWNrZXQuZXF1aXBtZW50cywgdGVybSkubGVuZ3RoID5cclxuICAgICAgICAgICAgICAgICAgICAwLFxyXG4gICAgICAgICk7XHJcbiAgICAgICAgcmV0dXJuIGZpbHRlclVuaXF1ZUFycmF5QnlJRChbLi4uYnlUaXRsZSwgLi4uYnlFcXVpcG1lbnRdKTtcclxuICAgIH1cclxuXHJcbiAgICBmaWx0ZXJMb2NhdGlvbnNGb3JUZXJtKGxvY2F0aW9uczogU3BhY2VbXSwgdGVybTogc3RyaW5nKTogU3BhY2VbXSB7XHJcbiAgICAgICAgLy8gYnkgbmFtZVxyXG4gICAgICAgIGNvbnN0IGJ5TmFtZSA9IGxvY2F0aW9ucy5maWx0ZXIoKGxvYykgPT5cclxuICAgICAgICAgICAgbG9jLm5hbWUudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyh0ZXJtKSxcclxuICAgICAgICApO1xyXG4gICAgICAgIC8vIGJ5IGFkZHJlc3NcclxuICAgICAgICBjb25zdCBieUFkZHJlc3MgPSBsb2NhdGlvbnMuZmlsdGVyKChsb2MpID0+XHJcbiAgICAgICAgICAgIGxvYy5hZGRyZXNzZXMudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyh0ZXJtKSxcclxuICAgICAgICApO1xyXG4gICAgICAgIHJldHVybiBmaWx0ZXJVbmlxdWVBcnJheUJ5SUQoWy4uLmJ5TmFtZSwgLi4uYnlBZGRyZXNzXSk7XHJcbiAgICB9XHJcblxyXG4gICAgZmlsdGVyT3JnYW5pc2F0aW9uc0ZvclRlcm0oXHJcbiAgICAgICAgb3JnczogT3JnYW5pc2F0aW9uW10sXHJcbiAgICAgICAgdGVybTogc3RyaW5nLFxyXG4gICAgKTogT3JnYW5pc2F0aW9uW10ge1xyXG4gICAgICAgIGNvbnN0IGJ5TmFtZSA9IG9yZ3MuZmlsdGVyKChvcmcpID0+IHtcclxuICAgICAgICAgICAgY29uc3Qgd29yZHMgPSBvcmcubmFtZS50b0xvd2VyQ2FzZSgpLnNwbGl0KFwiIFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIChcclxuICAgICAgICAgICAgICAgIHdvcmRzLnNvbWUoXHJcbiAgICAgICAgICAgICAgICAgICAgKHdvcmQpID0+IHdvcmQubGVuZ3RoID4gMiAmJiBsZXZlbnNodGVpbih3b3JkLCB0ZXJtKSA8PSAxLFxyXG4gICAgICAgICAgICAgICAgKSB8fCBvcmcubmFtZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHRlcm0pXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIGJ5TmFtZTtcclxuICAgIH1cclxuXHJcbiAgICBmaWx0ZXJVc2Vyc0ZvclRlcm0odXNlcnM6IFByb2ZpbGVFbnRpdHlbXSwgdGVybTogc3RyaW5nKSB7XHJcbiAgICAgICAgY29uc3QgYnlOYW1lID0gdXNlcnMuZmlsdGVyKCh1c2VyKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHdvcmRzID0gdXNlci5kaXNwbGF5TmFtZS50b0xvd2VyQ2FzZSgpLnNwbGl0KFwiIFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuIChcclxuICAgICAgICAgICAgICAgIHdvcmRzLnNvbWUoXHJcbiAgICAgICAgICAgICAgICAgICAgKHdvcmQpID0+IHdvcmQubGVuZ3RoID4gMiAmJiBsZXZlbnNodGVpbih3b3JkLCB0ZXJtKSA8PSAxLFxyXG4gICAgICAgICAgICAgICAgKSB8fCB1c2VyLmRpc3BsYXlOYW1lLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXModGVybSlcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gYnlOYW1lO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGZpbHRlckZlYXR1cmVzRm9yQ3VycmVudFVzZXJJblNwYWNlKFxyXG4gICAgICAgIGZlYXR1cmVzOiBGZWF0dXJlW10sXHJcbiAgICAgICAgc3BhY2VJRDogc3RyaW5nLFxyXG4gICAgKTogUHJvbWlzZTxGZWF0dXJlW10+IHtcclxuICAgICAgICBjb25zdCBmaW5hbEZlYXR1cmVzOiBGZWF0dXJlW10gPSBbXTtcclxuICAgICAgICBsZXQgbGV2ZWxGaWx0ZXJlZDogRmVhdHVyZVtdID0gZmVhdHVyZXM7XHJcbiAgICAgICAgbGV0IHpvbmVGaWx0ZXJlZDogRmVhdHVyZVtdID0gZmVhdHVyZXM7XHJcbiAgICAgICAgbGV0IGhhc2h0YWdGaWx0ZXJlZDogRmVhdHVyZVtdID0gZmVhdHVyZXM7XHJcbiAgICAgICAgY29uc3QgbWlzc2lvbnMgPSB0aGlzLnVzZXJTZXJ2aWNlLmN1cnJlbnRNaXNzaW9ucztcclxuICAgICAgICBpZiAobWlzc2lvbnMpIHtcclxuICAgICAgICAgICAgY29uc3QgY3VycmVudFNwYWNlTWlzc2lvbnMgPSBtaXNzaW9ucy5maWx0ZXIoXHJcbiAgICAgICAgICAgICAgICAobSkgPT4gbS5zcGFjZUlEID09PSBzcGFjZUlELFxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgICAgICBpZiAoY3VycmVudFNwYWNlTWlzc2lvbnMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaGlnaGVzdExlbGVsID1cclxuICAgICAgICAgICAgICAgICAgICBnZXRIaWdoZXN0TGV2ZWxGb3JNaXNzaW9ucyhjdXJyZW50U3BhY2VNaXNzaW9ucyk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBoaWdoZXN0Um9sZSA9XHJcbiAgICAgICAgICAgICAgICAgICAgZ2V0SGlnaGVzdFJvbGVGb3JNaXNzaW9ucyhjdXJyZW50U3BhY2VNaXNzaW9ucyk7XHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgZmlsdGVycyA9IHRoaXMuZ2V0RmlsdGVyc0ZvclJvbGUoaGlnaGVzdFJvbGUpO1xyXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBmaWx0ZXIgb2YgZmlsdGVycykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChmaWx0ZXIgPT09IEZpbHRlclR5cGUuTEVWRUwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxGaWx0ZXJlZCA9IHRoaXMuZmlsdGVyT2JqZWN0c0J5TGV2ZWwoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmZWF0dXJlcyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpZ2hlc3RMZWxlbCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZpbHRlciA9PT0gRmlsdGVyVHlwZS5aT05FKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHpvbmVGaWx0ZXJlZCA9IGF3YWl0IHRoaXMuYXBwbHlab25lRmlsdGVyRm9yTWlzc2lvbnMoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50U3BhY2VNaXNzaW9ucyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZlYXR1cmVzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoZmlsdGVyID09PSBGaWx0ZXJUeXBlLkhBU0hUQUcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaGFzaHRhZ0ZpbHRlcmVkID1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZmlsdGVyRmVhdHVyZXNCeUhhc2h0YWdzQW5kTG9jYWxlKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRTcGFjZU1pc3Npb25zLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZlYXR1cmVzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGZlYXR1cmUgb2YgbGV2ZWxGaWx0ZXJlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChcclxuICAgICAgICAgICAgICAgICAgICAgICAgaGFzaHRhZ0ZpbHRlcmVkLmluY2x1ZGVzKGZlYXR1cmUpICYmXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHpvbmVGaWx0ZXJlZC5pbmNsdWRlcyhmZWF0dXJlKVxyXG4gICAgICAgICAgICAgICAgICAgICkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmaW5hbEZlYXR1cmVzLnB1c2goZmVhdHVyZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmaW5hbEZlYXR1cmVzO1xyXG4gICAgfVxyXG5cclxuICAgIGZpbHRlckZlYXR1cmVzRm9yVGVybShmZWF0dXJlczogRmVhdHVyZVtdLCB0ZXJtOiBzdHJpbmcpOiBGZWF0dXJlW10ge1xyXG4gICAgICAgIC8vIGZpbHRlciB0ZXJtIGluIHRpdGxlXHJcbiAgICAgICAgY29uc3QgYnlUaXRsZSA9IHRoaXMuZmlsdGVyT2JqZWN0c0ZvclRlcm0oZmVhdHVyZXMsIHRlcm0pO1xyXG4gICAgICAgIC8vIGJ5IGNvbW1lbnRzXHJcbiAgICAgICAgY29uc3QgYnlDb21tZW50ID0gZmVhdHVyZXMuZmlsdGVyKFxyXG4gICAgICAgICAgICAoZmVhdHVyZSkgPT5cclxuICAgICAgICAgICAgICAgIHRoaXMuZmlsdGVyT2JqZWN0c0ZvclRlcm0oZmVhdHVyZS5jb21tZW50cy5pdGVtcywgdGVybSkubGVuZ3RoID5cclxuICAgICAgICAgICAgICAgIDAsXHJcbiAgICAgICAgKTtcclxuICAgICAgICByZXR1cm4gZmlsdGVyVW5pcXVlQXJyYXlCeUlEKFsuLi5ieVRpdGxlLCAuLi5ieUNvbW1lbnRdKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gb2JqZWN0cyBBcnJheSBvZiBDb21tZW50cywgVGlja2V0cywgRmVhdHVyZXMuIE9ibGlnYXRvcnkgcHJvcG9ydGllczogdGl0bGUsIGRlc2NyaXB0aW9uXHJcbiAgICAgKiBAcGFyYW0gdGVybSBzdHJpbmdcclxuICAgICAqL1xyXG4gICAgZmlsdGVyT2JqZWN0c0ZvclRlcm0ob2JqZWN0czogYW55W10sIHRlcm06IHN0cmluZyk6IGFueVtdIHtcclxuICAgICAgICAvLyBmaWx0ZXIgdGVybSBpbiB0aXRsZVxyXG4gICAgICAgIGNvbnN0IGJ5VGl0bGUgPSBvYmplY3RzLmZpbHRlcigoZmVhdHVyZSkgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCB3b3JkcyA9IGZlYXR1cmUudGl0bGUudG9Mb3dlckNhc2UoKS5zcGxpdChcIiBcIik7XHJcbiAgICAgICAgICAgIHJldHVybiAoXHJcbiAgICAgICAgICAgICAgICB3b3Jkcy5zb21lKFxyXG4gICAgICAgICAgICAgICAgICAgICh3b3JkKSA9PiB3b3JkLmxlbmd0aCA+IDIgJiYgbGV2ZW5zaHRlaW4od29yZCwgdGVybSkgPD0gMSxcclxuICAgICAgICAgICAgICAgICkgfHwgZmVhdHVyZS50aXRsZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHRlcm0pXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy8gdGVybSBwcmVzZW50IGluIGRlc2NyaXB0aW9uXHJcbiAgICAgICAgY29uc3QgYnlEZXNjcmlwdGlvbiA9IG9iamVjdHMuZmlsdGVyKFxyXG4gICAgICAgICAgICAoZmVhdHVyZSkgPT5cclxuICAgICAgICAgICAgICAgIGZlYXR1cmUuZGVzY3JpcHRpb24gJiZcclxuICAgICAgICAgICAgICAgIGZlYXR1cmUuZGVzY3JpcHRpb24udG9Mb3dlckNhc2UoKS5pbmNsdWRlcyh0ZXJtKSxcclxuICAgICAgICApO1xyXG4gICAgICAgIHJldHVybiBmaWx0ZXJVbmlxdWVBcnJheUJ5SUQoWy4uLmJ5VGl0bGUsIC4uLmJ5RGVzY3JpcHRpb25dKTtcclxuICAgIH1cclxuXHJcbiAgICBmaWx0ZXJNaXNzaW9uQnlTdGFydFRpbWVEYXRlRm9yRGF0ZVJhbmdlKFxyXG4gICAgICAgIG1pc3Npb25zOiBhbnlbXSxcclxuICAgICAgICBkYXRlUmFuZ2U6IERhdGVbXSxcclxuICAgICk6IGFueVtdIHtcclxuICAgICAgICByZXR1cm4gbWlzc2lvbnMuZmlsdGVyKChtaXNzaW9uKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHN0YXJ0RGF0ZVRpbWUgPSBuZXcgRGF0ZShtaXNzaW9uLnN0YXJ0RGF0ZVRpbWUpO1xyXG4gICAgICAgICAgICByZXR1cm4gKFxyXG4gICAgICAgICAgICAgICAgc3RhcnREYXRlVGltZSA+PSBkYXRlUmFuZ2VbMF0gJiYgc3RhcnREYXRlVGltZSA8PSBkYXRlUmFuZ2VbMV1cclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBhcHBseVpvbmVGaWx0ZXJGb3JNaXNzaW9ucyhcclxuICAgICAgICBjdXJyZW50U3BhY2VNaXNzaW9uczogTWlzc2lvbltdLFxyXG4gICAgICAgIG9iamVjdHM6IGFueVtdLFxyXG4gICAgKTogUHJvbWlzZTxhbnlbXT4ge1xyXG4gICAgICAgIGNvbnN0IGFsbG93ZWRab25lcyA9IFtdO1xyXG4gICAgICAgIGZvciAoY29uc3QgbWlzc2lvbiBvZiBjdXJyZW50U3BhY2VNaXNzaW9ucykge1xyXG4gICAgICAgICAgICBpZiAobWlzc2lvbi56b25lSUQpIHtcclxuICAgICAgICAgICAgICAgIGFsbG93ZWRab25lcy5wdXNoKG1pc3Npb24uem9uZUlEKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYWxsb3dlZFpvbmVzLmxlbmd0aCA9PT0gY3VycmVudFNwYWNlTWlzc2lvbnMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIGxldCBhbGxab25lRmlsdGVyZWQgPSBbXTtcclxuICAgICAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoXHJcbiAgICAgICAgICAgICAgICBhbGxvd2VkWm9uZXMubWFwKGFzeW5jICh6b25lSUQpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50Wm9uZUZpbHRlcmVkID0gYXdhaXQgdGhpcy5maWx0ZXJPYmplY3RzRm9yWm9uZShcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2JqZWN0cyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgem9uZUlELFxyXG4gICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAgICAgYWxsWm9uZUZpbHRlcmVkID0gW1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAuLi5hbGxab25lRmlsdGVyZWQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC4uLmN1cnJlbnRab25lRmlsdGVyZWQsXHJcbiAgICAgICAgICAgICAgICAgICAgXTtcclxuICAgICAgICAgICAgICAgIH0pLFxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgICAgICByZXR1cm4gZmlsdGVyVW5pcXVlQXJyYXlCeUlEKGFsbFpvbmVGaWx0ZXJlZCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBvYmplY3RzO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGZpbHRlckVxdWlwbWVudHNGb3JDdXJyZW50VXNlckluU3BhY2UoXHJcbiAgICAgICAgc3BhY2VJRDogc3RyaW5nLFxyXG4gICAgICAgIGVxdWlwczogRXF1aXBtZW50W10sXHJcbiAgICApOiBQcm9taXNlPEVxdWlwbWVudFtdPiB7XHJcbiAgICAgICAgY29uc3QgZmluYWxFcXVpcHM6IEVxdWlwbWVudFtdID0gW107XHJcbiAgICAgICAgbGV0IGRvbUZpbHRlcmVkOiBFcXVpcG1lbnRbXSA9IGVxdWlwcztcclxuICAgICAgICBjb25zdCByb2xlRmlsdGVyZWQ6IEVxdWlwbWVudFtdID0gZXF1aXBzO1xyXG4gICAgICAgIGNvbnN0IGxldmVsRmlsdGVyZWQ6IEVxdWlwbWVudFtdID0gZXF1aXBzO1xyXG4gICAgICAgIGxldCB6b25lRmlsdGVyZWQ6IEVxdWlwbWVudFtdID0gZXF1aXBzO1xyXG4gICAgICAgIGNvbnN0IG1pc3Npb25zID0gdGhpcy51c2VyU2VydmljZS5jdXJyZW50TWlzc2lvbnM7XHJcbiAgICAgICAgaWYgKG1pc3Npb25zKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGN1cnJlbnRTcGFjZU1pc3Npb25zID0gbWlzc2lvbnMuZmlsdGVyKFxyXG4gICAgICAgICAgICAgICAgKG0pID0+IG0uc3BhY2VJRCA9PT0gc3BhY2VJRCxcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgaWYgKGN1cnJlbnRTcGFjZU1pc3Npb25zLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGhpZ2hlc3RMZWxlbCA9XHJcbiAgICAgICAgICAgICAgICAgICAgZ2V0SGlnaGVzdExldmVsRm9yTWlzc2lvbnMoY3VycmVudFNwYWNlTWlzc2lvbnMpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaGlnaGVzdFJvbGUgPVxyXG4gICAgICAgICAgICAgICAgICAgIGdldEhpZ2hlc3RSb2xlRm9yTWlzc2lvbnMoY3VycmVudFNwYWNlTWlzc2lvbnMpO1xyXG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coXCJIaWdoZXN0IGxldmVsOiBcIiwgaGlnaGVzdExlbGVsLCBcIiwgSGlnaGVzdCBSb2xlOiBcIiwgaGlnaGVzdFJvbGUpXHJcblxyXG4gICAgICAgICAgICAgICAgY29uc3QgZmlsdGVycyA9IHRoaXMuZ2V0RmlsdGVyc0ZvclJvbGUoaGlnaGVzdFJvbGUpO1xyXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCBmaWx0ZXIgb2YgZmlsdGVycykge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChmaWx0ZXIgPT09IEZpbHRlclR5cGUuRE9NQUlOKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBkb21haW5zOiBzdHJpbmdbXSA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IG0gb2YgY3VycmVudFNwYWNlTWlzc2lvbnMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChtLmRvbWFpbnMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb21haW5zID0gWy4uLmRvbWFpbnMsIC4uLm0uZG9tYWluc107XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGFsbERvbWFpbnNGaWx0ZXJlZCA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50RG9tRmlsdGVyZWQgPVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5maWx0ZXJFcXVpcG1lbnRzQnlEb21haW5MaXN0KGVxdWlwcywgZG9tYWlucyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFsbERvbWFpbnNGaWx0ZXJlZCA9IFtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLmFsbERvbWFpbnNGaWx0ZXJlZCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLmN1cnJlbnREb21GaWx0ZXJlZCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZG9tRmlsdGVyZWQgPSBhbGxEb21haW5zRmlsdGVyZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChmaWx0ZXIgPT09IEZpbHRlclR5cGUuUk9MRSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBjb25zdCBoaWdoZXN0Um9sZU1pc3Npb24gPSBjdXJyZW50U3BhY2VNaXNzaW9ucy5maW5kKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgKG0pID0+IG0ucm9sZSA9PT0gaGlnaGVzdFJvbGUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vICk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRPRE9cclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChmaWx0ZXIgPT09IEZpbHRlclR5cGUuTEVWRUwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gVE9ETywgZXF1aXBtZW50IGRvZXMgbm90IGhhdmUgbGV2ZWxcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChmaWx0ZXIgPT09IEZpbHRlclR5cGUuWk9ORSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB6b25lRmlsdGVyZWQgPSBhd2FpdCB0aGlzLmFwcGx5Wm9uZUZpbHRlckZvck1pc3Npb25zKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudFNwYWNlTWlzc2lvbnMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcXVpcHMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZm9yIChjb25zdCB0aWMgb2YgbGV2ZWxGaWx0ZXJlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChcclxuICAgICAgICAgICAgICAgICAgICAgICAgZG9tRmlsdGVyZWQuaW5jbHVkZXModGljKSAmJlxyXG4gICAgICAgICAgICAgICAgICAgICAgICByb2xlRmlsdGVyZWQuaW5jbHVkZXModGljKSAmJlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB6b25lRmlsdGVyZWQuaW5jbHVkZXModGljKVxyXG4gICAgICAgICAgICAgICAgICAgICkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmaW5hbEVxdWlwcy5wdXNoKHRpYyk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmaW5hbEVxdWlwcztcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBmaWx0ZXJNZWFzdXJlbWVudHNGb3JDdXJyZW50VXNlckluU3BhY2UoXHJcbiAgICAgICAgc3BhY2VJRDogc3RyaW5nLFxyXG4gICAgICAgIGNvbW1lbnRzOiBDb21tZW50W10sXHJcbiAgICApOiBQcm9taXNlPENvbW1lbnRbXT4ge1xyXG4gICAgICAgIGxldCBmaW5hbE1lYXN1cmVtZW50czogQ29tbWVudFtdID0gW107XHJcbiAgICAgICAgbGV0IHpvbmVGaWx0ZXJlZDogQ29tbWVudFtdID0gY29tbWVudHM7XHJcbiAgICAgICAgY29uc3QgbWlzc2lvbnMgPSB0aGlzLnVzZXJTZXJ2aWNlLmN1cnJlbnRNaXNzaW9ucztcclxuICAgICAgICBpZiAobWlzc2lvbnMpIHtcclxuICAgICAgICAgICAgY29uc3QgY3VycmVudFNwYWNlTWlzc2lvbnMgPSBtaXNzaW9ucy5maWx0ZXIoXHJcbiAgICAgICAgICAgICAgICAobSkgPT4gbS5zcGFjZUlEID09PSBzcGFjZUlELFxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgICAgICBpZiAoY3VycmVudFNwYWNlTWlzc2lvbnMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaGlnaGVzdFJvbGUgPVxyXG4gICAgICAgICAgICAgICAgICAgIGdldEhpZ2hlc3RSb2xlRm9yTWlzc2lvbnMoY3VycmVudFNwYWNlTWlzc2lvbnMpO1xyXG5cclxuICAgICAgICAgICAgICAgIGNvbnN0IGZpbHRlcnMgPSB0aGlzLmdldEZpbHRlcnNGb3JSb2xlKGhpZ2hlc3RSb2xlKTtcclxuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgZmlsdGVyIG9mIGZpbHRlcnMpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZmlsdGVyID09PSBGaWx0ZXJUeXBlLlpPTkUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgem9uZUZpbHRlcmVkID0gYXdhaXQgdGhpcy5hcHBseVpvbmVGaWx0ZXJGb3JNaXNzaW9ucyhcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRTcGFjZU1pc3Npb25zLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbWVudHMsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZmluYWxNZWFzdXJlbWVudHMgPSB6b25lRmlsdGVyZWQ7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGZpbmFsTWVhc3VyZW1lbnRzO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGlzT2JqZWN0QWxsb3dlZEZvclVzZXJJblNwYWNlKFxyXG4gICAgICAgIG9iamVjdDogT2JqZWN0LFxyXG4gICAgICAgIHNwYWNlSUQ6IHN0cmluZyxcclxuICAgICk6IFByb21pc2U8Ym9vbGVhbj4ge1xyXG4gICAgICAgIGNvbnN0IG1pc3Npb24gPSB0aGlzLnVzZXJTZXJ2aWNlLmN1cnJlbnRNaXNzaW9uKHNwYWNlSUQpO1xyXG4gICAgICAgIGNvbnN0IGZpbHRlcnMgPSB0aGlzLmdldEZpbHRlcnNGb3JSb2xlKG1pc3Npb24ucm9sZSk7XHJcbiAgICAgICAgZm9yIChjb25zdCBmaWx0ZXIgb2YgZmlsdGVycykge1xyXG4gICAgICAgICAgICBpZiAoXHJcbiAgICAgICAgICAgICAgICBmaWx0ZXIgPT09IEZpbHRlclR5cGUuTEVWRUwgJiZcclxuICAgICAgICAgICAgICAgIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIFwibGV2ZWxcIilcclxuICAgICAgICAgICAgKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBsZXZlbEZpbHRlcmVkID0gdGhpcy5maWx0ZXJPYmplY3RzQnlMZXZlbChcclxuICAgICAgICAgICAgICAgICAgICBbb2JqZWN0XSxcclxuICAgICAgICAgICAgICAgICAgICBtaXNzaW9uLmxldmVsLFxyXG4gICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgIGlmIChsZXZlbEZpbHRlcmVkLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoZmlsdGVyID09PSBGaWx0ZXJUeXBlLlpPTkUpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHpvbmVGaWx0ZXJlZCA9IGF3YWl0IHRoaXMuYXBwbHlab25lRmlsdGVyRm9yTWlzc2lvbnMoXHJcbiAgICAgICAgICAgICAgICAgICAgW21pc3Npb25dLFxyXG4gICAgICAgICAgICAgICAgICAgIFtvYmplY3RdLFxyXG4gICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgIGlmICh6b25lRmlsdGVyZWQubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGZpbHRlclRlbXBsYXRlc0ZvclRlcm0obWlzc2lvbnM6IE1pc3Npb25bXSwgdGVybTogc3RyaW5nKTogTWlzc2lvbltdIHtcclxuICAgICAgICAvLyB0ZXJtIHByZXNlbnQgaW4gZGVzY3JpcHRpb25cclxuICAgICAgICBjb25zdCBieURlc2NyaXB0aW9uID0gbWlzc2lvbnMuZmlsdGVyKFxyXG4gICAgICAgICAgICAobWlzKSA9PlxyXG4gICAgICAgICAgICAgICAgbWlzLmRlc2NyaXB0aW9uICYmIG1pcy5kZXNjcmlwdGlvbi50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHRlcm0pLFxyXG4gICAgICAgICk7XHJcbiAgICAgICAgLy8gYnkgdXNlciBsYXN0TmFtZSB3aGljaCBpcyB0aGUgbmFtZSBvZiB0aGUgdmlzaXQ6XHJcbiAgICAgICAgLy8gbWV0YWRhdGE6IFwie1xcXCJmaXJzdE5hbWVcXFwiOlxcXCJcXFwiLFxcXCJsYXN0TmFtZVxcXCI6XFxcIlZpc2l0ZSBkdSA1IEp1aWxsZXRcXFwifVwiXHJcbiAgICAgICAgY29uc3QgdXNlclByb2ZpbGVzID0gbWlzc2lvbnMubWFwKChtaXMpID0+IG5ldyBQcm9maWxlRW50aXR5KG1pcy51c2VyKSk7XHJcbiAgICAgICAgY29uc3QgYnlVc2VyTGFzdG5hbWUgPSB0aGlzLmZpbHRlclVzZXJzRm9yVGVybSh1c2VyUHJvZmlsZXMsIHRlcm0pO1xyXG4gICAgICAgIGNvbnN0IHVzZXJJZHMgPSBuZXcgU2V0KGJ5VXNlckxhc3RuYW1lLm1hcCgodXNlcikgPT4gdXNlci5pZCkpO1xyXG4gICAgICAgIGNvbnN0IG1pc3Npb25zQnlVc2VyID0gbWlzc2lvbnMuZmlsdGVyKChtaXMpID0+XHJcbiAgICAgICAgICAgIHVzZXJJZHMuaGFzKG1pcy51c2VySUQpLFxyXG4gICAgICAgICk7XHJcbiAgICAgICAgcmV0dXJuIGZpbHRlclVuaXF1ZUFycmF5QnlJRChbLi4uYnlEZXNjcmlwdGlvbiwgLi4ubWlzc2lvbnNCeVVzZXJdKTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBmaWx0ZXJPYmplY3RzRm9yU3dlZXAoXHJcbiAgICAgICAgb2JqZWN0czogYW55W10sXHJcbiAgICAgICAgb2JqZWN0VHlwZTogUG9pVHlwZSxcclxuICAgICAgICBzd2VlcDogc3RyaW5nLFxyXG4gICAgKTogUHJvbWlzZTxhbnlbXT4ge1xyXG4gICAgICAgIGxldCBmaWx0ZXJlZCA9IFtdO1xyXG4gICAgICAgIHN3aXRjaCAob2JqZWN0VHlwZSkge1xyXG4gICAgICAgICAgICBjYXNlIFBvaVR5cGUuRVFVSVBNRU5UOlxyXG4gICAgICAgICAgICAgICAgY29uc3QgcG9pcyA9XHJcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5wb2lTZXJ2aWNlLmdldFBvaXNCeU1hdHRlcnBvcnRTd2VlcEJ5VHlwZShcclxuICAgICAgICAgICAgICAgICAgICAgICAgc3dlZXAsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9iamVjdFR5cGUsXHJcbiAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGVxdWlwSURzID0gbmV3IFNldChwb2lzLm1hcCgocG9pKSA9PiBwb2kuZWxlbWVudElEKSk7XHJcbiAgICAgICAgICAgICAgICBmaWx0ZXJlZCA9IG9iamVjdHMuZmlsdGVyKChvYmplY3QpID0+IGVxdWlwSURzLmhhcyhvYmplY3QuaWQpKTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmaWx0ZXJlZDtcclxuICAgIH1cclxuXHJcbiAgICBmaWx0ZXJGZWF0dXJlc0J5SGFzaHRhZ3NBbmRMb2NhbGUoXHJcbiAgICAgICAgY3VycmVudFNwYWNlTWlzc2lvbnM6IE1pc3Npb25bXSxcclxuICAgICAgICBmZWF0dXJlczogRmVhdHVyZVtdLFxyXG4gICAgKTogRmVhdHVyZVtdIHtcclxuICAgICAgICBjb25zdCBbY3VycmVudE1pc3Npb25dID0gY3VycmVudFNwYWNlTWlzc2lvbnM7XHJcbiAgICAgICAgLy8gZmlsdGVyIGJ5IGxvY2FsZVxyXG4gICAgICAgIGxldCBmaWx0ZXJlZExvY2FsZSA9IFsuLi5mZWF0dXJlc107XHJcbiAgICAgICAgaWYgKGN1cnJlbnRNaXNzaW9uLmxvY2FsZSkge1xyXG4gICAgICAgICAgICBmaWx0ZXJlZExvY2FsZSA9IGZlYXR1cmVzLmZpbHRlcihcclxuICAgICAgICAgICAgICAgIChmZWF0dXJlKSA9PlxyXG4gICAgICAgICAgICAgICAgICAgIGZlYXR1cmUubG9jYWxlICYmIGZlYXR1cmUubG9jYWxlID09PSBjdXJyZW50TWlzc2lvbi5sb2NhbGUsXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGZpbHRlciBieSBoYXNodGFnc1xyXG4gICAgICAgIGlmIChjdXJyZW50TWlzc2lvbi5oYXNodGFncyAmJiBjdXJyZW50TWlzc2lvbi5oYXNodGFncy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGZpbHRlcmVkQnlIYXNodGFncyA9IFtdO1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGZlYXR1cmUgb2YgZmlsdGVyZWRMb2NhbGUpIHtcclxuICAgICAgICAgICAgICAgIGlmICghZmVhdHVyZS5oYXNodGFncyB8fCBmZWF0dXJlLmhhc2h0YWdzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIEZlYXR1cmUgd2l0aG91dCBoYXNodGFnIGlzIGF2YWlsYWJsZSBmb3IgZXZlcnlib2R5XHJcbiAgICAgICAgICAgICAgICAgICAgZmlsdGVyZWRCeUhhc2h0YWdzLnB1c2goZmVhdHVyZSk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFxyXG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRNaXNzaW9uLmhhc2h0YWdzLmV2ZXJ5KChoYXNodGFnKSA9PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBmZWF0dXJlLmhhc2h0YWdzLmluY2x1ZGVzKGhhc2h0YWcpLFxyXG4gICAgICAgICAgICAgICAgICAgIClcclxuICAgICAgICAgICAgICAgICkge1xyXG4gICAgICAgICAgICAgICAgICAgIGZpbHRlcmVkQnlIYXNodGFncy5wdXNoKGZlYXR1cmUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBmaWx0ZXJlZEJ5SGFzaHRhZ3M7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmaWx0ZXJlZExvY2FsZTtcclxuICAgIH1cclxuXHJcbiAgICBmaWx0ZXJGZWF0dXJlc0Zvck1pc3Npb25XaXRob3V0Wm9uZShcclxuICAgICAgICBmZWF0dXJlczogRmVhdHVyZVtdLFxyXG4gICAgICAgIG1pc3Npb246IE1pc3Npb24sXHJcbiAgICApOiBGZWF0dXJlW10ge1xyXG4gICAgICAgIGNvbnN0IGZpbmFsRmVhdHVyZXM6IEZlYXR1cmVbXSA9IFtdO1xyXG4gICAgICAgIGxldCBsZXZlbEZpbHRlcmVkOiBGZWF0dXJlW10gPSBmZWF0dXJlcztcclxuICAgICAgICBsZXQgem9uZUZpbHRlcmVkOiBGZWF0dXJlW10gPSBmZWF0dXJlcztcclxuICAgICAgICBsZXQgaGFzaHRhZ0ZpbHRlcmVkOiBGZWF0dXJlW10gPSBmZWF0dXJlcztcclxuXHJcbiAgICAgICAgY29uc3QgZmlsdGVycyA9IHRoaXMuZ2V0RmlsdGVyc0ZvclJvbGUobWlzc2lvbi5yb2xlKTtcclxuICAgICAgICBmb3IgKGNvbnN0IGZpbHRlciBvZiBmaWx0ZXJzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGZpbHRlciA9PT0gRmlsdGVyVHlwZS5MRVZFTCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXZlbEZpbHRlcmVkID0gdGhpcy5maWx0ZXJPYmplY3RzQnlMZXZlbChcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZlYXR1cmVzLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWlzc2lvbi5sZXZlbCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gaWYgKGZpbHRlciA9PT0gRmlsdGVyVHlwZS5aT05FKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gICAgIHpvbmVGaWx0ZXJlZCA9IGF3YWl0IHRoaXMuYXBwbHlab25lRmlsdGVyRm9yTWlzc2lvbnMoXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gICAgICAgICBjdXJyZW50U3BhY2VNaXNzaW9ucyxcclxuICAgICAgICAgICAgICAgICAgICAvLyAgICAgICAgIGZlYXR1cmVzLFxyXG4gICAgICAgICAgICAgICAgICAgIC8vICAgICApO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoZmlsdGVyID09PSBGaWx0ZXJUeXBlLkhBU0hUQUcpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaGFzaHRhZ0ZpbHRlcmVkID1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZmlsdGVyRmVhdHVyZXNCeUhhc2h0YWdzQW5kTG9jYWxlKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttaXNzaW9uXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmZWF0dXJlcyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgIGZvciAoY29uc3QgZmVhdHVyZSBvZiBsZXZlbEZpbHRlcmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBoYXNodGFnRmlsdGVyZWQuaW5jbHVkZXMoZmVhdHVyZSkgJiZcclxuICAgICAgICAgICAgICAgICAgICAgICAgem9uZUZpbHRlcmVkLmluY2x1ZGVzKGZlYXR1cmUpXHJcbiAgICAgICAgICAgICAgICAgICAgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpbmFsRmVhdHVyZXMucHVzaChmZWF0dXJlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmaW5hbEZlYXR1cmVzO1xyXG4gICAgfVxyXG59XHJcbiJdfQ==