@techextensor/tab-core-utility 2.2.133 → 2.2.134

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 (33) hide show
  1. package/esm2022/lib/tab-core-utility/app/enums/common.enum.mjs +23 -0
  2. package/esm2022/lib/tab-core-utility/app/enums/dsq.enum.mjs +17 -1
  3. package/esm2022/lib/tab-core-utility/app/enums/permission.enum.mjs +8 -1
  4. package/esm2022/lib/tab-core-utility/app/helpers/common/meta-data.helpers.mjs +161 -608
  5. package/esm2022/lib/tab-core-utility/app/interfaces/schema.interface.mjs +1 -2
  6. package/esm2022/lib/tab-core-utility/app/models/app-field.model.mjs +72 -0
  7. package/esm2022/lib/tab-core-utility/app/models/app-object.class.mjs +1 -1
  8. package/esm2022/lib/tab-core-utility/app/models/app-object.model.mjs +186 -0
  9. package/esm2022/lib/tab-core-utility/app/models/app-screen.model.mjs +37 -0
  10. package/esm2022/lib/tab-core-utility/app/models/common.class.mjs +1 -1
  11. package/esm2022/lib/tab-core-utility/app/models/data-source-queries.class.mjs +1 -1
  12. package/esm2022/lib/tab-core-utility/app/models/data-source-query.model.mjs +123 -0
  13. package/esm2022/lib/tab-core-utility/app/models/filter.model.mjs +24 -0
  14. package/esm2022/lib/tab-core-utility/app/models/orgInfo.model.mjs +38 -0
  15. package/esm2022/lib/tab-core-utility/app/models/parameter.model.mjs +18 -0
  16. package/esm2022/lib/tab-core-utility/app/models/sort.model.mjs +18 -0
  17. package/lib/tab-core-utility/app/enums/common.enum.d.ts +18 -0
  18. package/lib/tab-core-utility/app/enums/dsq.enum.d.ts +14 -0
  19. package/lib/tab-core-utility/app/enums/permission.enum.d.ts +6 -0
  20. package/lib/tab-core-utility/app/helpers/common/meta-data.helpers.d.ts +84 -320
  21. package/lib/tab-core-utility/app/interfaces/schema.interface.d.ts +1 -2
  22. package/lib/tab-core-utility/app/models/app-field.model.d.ts +56 -0
  23. package/lib/tab-core-utility/app/models/app-object.class.d.ts +11 -8
  24. package/lib/tab-core-utility/app/models/app-object.model.d.ts +124 -0
  25. package/lib/tab-core-utility/app/models/app-screen.model.d.ts +27 -0
  26. package/lib/tab-core-utility/app/models/common.class.d.ts +3 -0
  27. package/lib/tab-core-utility/app/models/data-source-queries.class.d.ts +8 -4
  28. package/lib/tab-core-utility/app/models/data-source-query.model.d.ts +69 -0
  29. package/lib/tab-core-utility/app/models/filter.model.d.ts +21 -0
  30. package/lib/tab-core-utility/app/models/orgInfo.model.d.ts +23 -0
  31. package/lib/tab-core-utility/app/models/parameter.model.d.ts +14 -0
  32. package/lib/tab-core-utility/app/models/sort.model.d.ts +15 -0
  33. package/package.json +1 -1
@@ -1,655 +1,208 @@
1
- /* eslint-disable @typescript-eslint/no-explicit-any */
2
1
  import { Injectable } from "@angular/core";
3
- import { MetadataEntityType } from "../../interfaces/schema.interface";
4
2
  import { Common } from "../../constants/common";
3
+ import { AppObjectModel } from "../../models/app-object.model";
4
+ import { MetadataEntityType } from "../../interfaces/schema.interface";
5
+ import { AppScreenModel } from "../../models/app-screen.model";
6
+ import { OrgInfoModel } from "../../models/orgInfo.model";
5
7
  import * as i0 from "@angular/core";
6
- /**
7
- * MetadataUtils - Utility service for retrieving and manipulating application metadata
8
- *
9
- * This service provides methods to extract, filter, and format different parts of the
10
- * application metadata, including objects, fields, screens, menus, etc.
11
- */
12
8
  export class MetadataHelper {
13
- // Helper method to consistently format results
14
- formatResults(items, columns) {
15
- if (!columns || columns.length === 0) {
16
- return items;
17
- }
18
- return items.map(item => {
19
- const result = {};
20
- columns.forEach(col => {
21
- result[col] = item[col];
22
- });
23
- return result;
9
+ constructor() {
10
+ this.appObjectMap = new Map();
11
+ this.allAppObjects = null;
12
+ this.appScreenMap = new Map();
13
+ this.allAppScreens = null;
14
+ this.orgInfoMap = new Map();
15
+ this.allOrgInfos = null;
16
+ }
17
+ /**
18
+ * Returns the value associated with the given key from the given map.
19
+ * If the key does not exist in the map, and the source list contains an item that matches
20
+ * the given condition, it creates a new model using the given model factory and adds it to the map.
21
+ * @param map The map to search in.
22
+ * @param key The key to search for.
23
+ * @param sourceList The list of items to search in.
24
+ * @param matchFn The condition to match.
25
+ * @param modelFactory The factory to create a new model if the key does not exist.
26
+ * @returns The value associated with the given key, or null if no match is found.
27
+ */
28
+ getFromMapOrCreate(map, key, sourceList, matchFn, modelFactory) {
29
+ if (!key)
30
+ return null;
31
+ if (map.has(key))
32
+ return map.get(key) || null;
33
+ const item = sourceList.find(matchFn);
34
+ const model = item ? modelFactory(item) : null;
35
+ map.set(key, model);
36
+ return model;
37
+ }
38
+ /**
39
+ * Lazily initializes a list of models from a source list.
40
+ * It creates a new model for each item in the source list and adds it to the given map.
41
+ * It also sets the list of models to the given setter.
42
+ * @param listRef The reference to the list of models.
43
+ * @param setter The setter to set the list of models.
44
+ * @param sourceList The source list of items.
45
+ * @param map The map to store the models.
46
+ * @param getKeys The function to get the keys for the given item.
47
+ * @param modelFactory The factory to create a new model for the given item.
48
+ * @returns The list of models.
49
+ */
50
+ lazyInitList(listRef, setter, sourceList, map, getKeys, modelFactory) {
51
+ // If the list is already initialized, return it.
52
+ if (listRef)
53
+ return listRef;
54
+ // Create a new model for each item in the source list and add it to the map.
55
+ const models = sourceList.map((item) => {
56
+ const model = modelFactory(item);
57
+ getKeys(item).forEach(key => map.set(key, model));
58
+ return model;
24
59
  });
60
+ // Set the list of models to the given setter.
61
+ setter(models);
62
+ // Return the list of models.
63
+ return models;
25
64
  }
26
65
  /**
27
- * Search across all metadata for a term
28
- *
29
- * @param searchTerm Term to search for
30
- * @param entityTypes Optional types of entities to search (if not provided, searches all)
31
- * @returns Search results grouped by entity type
32
- *
33
- * @example
34
- * // Search across all metadata
35
- * const results = metadataUtils.searchAcrossMetadata('Blueprint');
36
- *
37
- * // Search only in app objects and screens
38
- * const results = metadataUtils.searchAcrossMetadata(
39
- * 'Role',
40
- * [MetadataEntityType.APP_OBJECTS, MetadataEntityType.APP_SCREENS]
41
- * );
42
- */
43
- searchAcrossMetadata(searchTerm, entityTypes) {
44
- try {
45
- if (!searchTerm || searchTerm.trim() === '') {
46
- return {};
47
- }
48
- const term = searchTerm.toLowerCase();
49
- const results = {};
50
- // If entityTypes not provided, search all entity types
51
- const typesToSearch = entityTypes || Object.values(MetadataEntityType);
52
- // Execute search for each entity type
53
- if (typesToSearch.includes(MetadataEntityType.APP_OBJECTS)) {
54
- results[MetadataEntityType.APP_OBJECTS] = this.searchAppObjects(term);
55
- }
56
- if (typesToSearch.includes(MetadataEntityType.APP_FIELDS)) {
57
- results[MetadataEntityType.APP_FIELDS] = this.searchAppFields(term);
58
- }
59
- if (typesToSearch.includes(MetadataEntityType.DATA_SOURCE_QUERIES)) {
60
- results[MetadataEntityType.DATA_SOURCE_QUERIES] = this.searchDataSourceQueries(term);
61
- }
62
- if (typesToSearch.includes(MetadataEntityType.APP_SCREENS)) {
63
- results[MetadataEntityType.APP_SCREENS] = this.searchAppScreens(term);
64
- }
65
- if (typesToSearch.includes(MetadataEntityType.APP_MENUS)) {
66
- results[MetadataEntityType.APP_MENUS] = this.searchAppMenus(term);
67
- }
68
- return results;
69
- }
70
- catch (error) {
71
- console.error('Error in searchMetadata:', error);
72
- return {};
73
- }
74
- }
75
- /**
76
- * Search for a term within App Objects
77
- * @private
66
+ * Finds an app object in the map by its name or id.
67
+ * If the app object is not found, it creates a new one and adds it to the map.
68
+ * @param nameOrId The name or id of the app object to find.
69
+ * @returns The app object if found, or null if not found.
78
70
  */
79
- searchAppObjects(term) {
80
- return this.getAppObjects(obj => this.containsTerm(obj.ObjectName, term) ||
81
- this.containsTerm(obj.DisplayName, term) ||
82
- this.containsTerm(obj.Description, term) ||
83
- this.containsTerm(obj.SystemDBTableName, term));
71
+ getAppObjectByIdOrName(nameOrId) {
72
+ return this.getFromMapOrCreate(this.appObjectMap, nameOrId, Common.tabJson.AppObjects, obj => obj.ObjectName === nameOrId || obj.ID === nameOrId, obj => new AppObjectModel(obj));
84
73
  }
85
74
  /**
86
- * Search for a term within App Fields
87
- * @private
75
+ * Returns a list of app objects in the metadata.
76
+ * If a filter function is given, it is applied to each app object.
77
+ * @param filterFn The filter function to apply to the app objects.
78
+ * @returns The list of app objects.
88
79
  */
89
- searchAppFields(term) {
90
- return this.getAppFields(field => this.containsTerm(field.FieldName, term) ||
91
- this.containsTerm(field.DisplayName, term) ||
92
- this.containsTerm(field.Description, term) ||
93
- this.containsTerm(field.SystemDBFieldName, term));
80
+ getAllAppObjects(filterFn) {
81
+ // Initialize the list of app objects lazily.
82
+ const list = this.lazyInitList(this.allAppObjects, val => (this.allAppObjects = val), Common.tabJson.AppObjects, this.appObjectMap, (obj) => [obj.ID, obj.ObjectName], obj => new AppObjectModel(obj));
83
+ // If a filter function is given, apply it to the list of app objects.
84
+ return filterFn ? list.filter(filterFn) : list;
94
85
  }
95
86
  /**
96
- * Search for a term within Data Source Queries
97
- * @private
87
+ * Returns a list of fields in the metadata.
88
+ * If a filter function is given, it is applied to each field.
89
+ * @param filterFn The filter function to apply to the fields.
90
+ * @returns The list of fields.
98
91
  */
99
- searchDataSourceQueries(term) {
100
- return this.getDataSourceQueries(query => this.containsTerm(query.QueryName, term) ||
101
- this.containsTerm(query.DisplayName, term));
92
+ getAllFields(filterFn) {
93
+ // Get a list of all fields from all app objects.
94
+ const allFields = this.getAllAppObjects().flatMap(obj => obj.fields());
95
+ // If a filter function is given, apply it to the list of fields.
96
+ return filterFn ? allFields.filter(filterFn) : allFields;
102
97
  }
103
98
  /**
104
- * Search for a term within App Screens
105
- * @private
99
+ * Returns a list of data source queries in the metadata.
100
+ * If a filter function is given, it is applied to each data source query.
101
+ * @param filterFn The filter function to apply to the data source queries.
102
+ * @returns The list of data source queries.
106
103
  */
107
- searchAppScreens(term) {
108
- return this.getAppScreens(screen => this.containsTerm(screen.Name, term) ||
109
- this.containsTerm(screen.Description, term));
104
+ getAllDataSourceQueries(filterFn) {
105
+ // Get a list of all data source queries from all app objects.
106
+ const allDSQs = this.getAllAppObjects().flatMap(obj => obj.dataSourceQueries());
107
+ // If a filter function is given, apply it to the list of data source queries.
108
+ return filterFn ? allDSQs.filter(filterFn) : allDSQs;
110
109
  }
111
110
  /**
112
- * Search for a term within App Menus
113
- * @private
114
- */
115
- searchAppMenus(term) {
116
- return this.getAppMenus(menu => this.containsTerm(menu.MenuName, term) ||
117
- this.containsTerm(menu.DisplayName, term));
118
- }
119
- /**
120
- * Helper method to check if a string contains a search term
121
- * @private
122
- */
123
- containsTerm(value, term) {
124
- return !!value && value.toLowerCase().includes(term);
125
- }
126
- /**
127
- * Gets App Objects based on filter criteria
128
- *
129
- * @param filterFn Optional filter function to apply to app objects
130
- * @param columns Optional columns to include in the result
131
- * @returns Array of filtered app objects
132
- *
133
- * @example
134
- * // Get all system app objects
135
- * const systemObjects = metadataUtils.getAppObjects(obj => obj.IsSystem === true);
111
+ * Retrieves a data source query by its ID, QueryName, or DisplayName.
112
+ * Searches through all data source queries and returns the first match.
136
113
  *
137
- * // Get specific columns from non-deprecated objects
138
- * const objects = metadataUtils.getAppObjects(
139
- * obj => !obj.IsDeprecated,
140
- * ['ID', 'DisplayName', 'ObjectName']
141
- * );
114
+ * @param {string} nameOrId - The ID, QueryName, or DisplayName of the data source query to retrieve.
115
+ * @returns {DataSourceQueryModel | null} - The data source query model if found, otherwise null.
142
116
  */
143
- getAppObjects(filterFn, columns) {
144
- try {
145
- let appObjects = Common.tabJson.AppObjects || [];
146
- // Apply filter if provided
147
- if (filterFn) {
148
- appObjects = appObjects.filter(filterFn);
149
- }
150
- // Return all object data if no columns specified
151
- return this.formatResults(appObjects, columns);
152
- }
153
- catch (error) {
154
- console.error('Error in getAppObjects:', error);
155
- return [];
156
- }
117
+ getDataSourceQueryByIdOrName(nameOrId) {
118
+ // Search for the data source query by ID, QueryName, or DisplayName
119
+ return this.getAllDataSourceQueries().find(dsq => dsq?.ID === nameOrId || dsq?.QueryName === nameOrId || dsq?.DisplayName === nameOrId) || null;
157
120
  }
158
121
  /**
159
- * Gets a specific App Object by ID or Name
160
- *
161
- * @param appObject ID or Name of the app object to retrieve
162
- * @param columns Optional columns to include in the result
163
- * @returns The app object with specified columns or null if not found
164
- *
165
- * @example
166
- * // Get a specific app object with all properties
167
- * const appObj = metadataUtils.getAppObjectDetails('b4887d4d-bb1e-4d52-a7e8-2f943d69e44c' or 'TABMD_SYSTEM');
122
+ * Retrieves an app screen by its ID, Name, or DisplayName.
123
+ * Searches through all app screens and returns the first match.
168
124
  *
169
- * // Get specific columns from an app object
170
- * const appObj = metadataUtils.getAppObjectDetails(
171
- * 'b4887d4d-bb1e-4d52-a7e8-2f943d69e44c',
172
- * ['ID', 'DisplayName', 'ObjectName']
173
- * );
125
+ * @param {string} nameOrId - The ID, Name, or DisplayName of the app screen to retrieve.
126
+ * @returns {AppScreenModel | null} - The app screen model if found, otherwise null.
174
127
  */
175
- getAppObjectDetails(appObject, columns) {
176
- try {
177
- return this.getAppObjects(obj => obj.ID?.toLowerCase() === appObject?.toLowerCase() || obj.ObjectName === appObject, columns)?.[0] ?? null;
178
- }
179
- catch (error) {
180
- console.error('Error in getAppObjectById:', error);
181
- return null;
182
- }
128
+ getAppScreenByIdOrName(nameOrId) {
129
+ return this.getFromMapOrCreate(this.appScreenMap, nameOrId, Common.tabJson.AppScreens, screen => screen?.ID === nameOrId || screen?.Name === nameOrId, screen => new AppScreenModel(screen));
183
130
  }
184
131
  /**
185
- * Gets all fields across all app objects with filter criteria
186
- *
187
- * @param filterFn Optional filter function to apply to fields
188
- * @param columns Optional columns to include in the result
189
- * @returns Array of filtered fields
132
+ * Retrieves a list of all app screens.
133
+ * If a filter function is given, it is applied to the list of app screens.
190
134
  *
191
- * @example
192
- * // Get all required fields across all objects
193
- * const requiredFields = metadataUtils.getAppFields(field => field.IsRequired === true);
194
- *
195
- * // Get specific columns from searchable fields
196
- * const fields = metadataUtils.getAppFields(
197
- * field => field.IsSearchable === true,
198
- * ['ID', 'DisplayName', 'FieldName']
199
- * );
135
+ * @param {function} filterFn - The filter function to apply to the app screens.
136
+ * @returns {AppScreenModel[]} - The list of app screens.
200
137
  */
201
- getAppFields(filterFn, columns) {
202
- try {
203
- // Get all fields from all app objects
204
- const allFields = [];
205
- Common.tabJson.AppObjects.forEach((obj) => {
206
- allFields.push(...obj.Fields);
207
- });
208
- // Apply filter if provided
209
- let filteredFields = allFields;
210
- if (filterFn) {
211
- filteredFields = allFields.filter(filterFn);
212
- }
213
- // Return all field data if no columns specified
214
- return this.formatResults(filteredFields, columns);
215
- }
216
- catch (error) {
217
- console.error('Error in getAppFields:', error);
218
- return [];
219
- }
138
+ getAllAppScreens(filterFn) {
139
+ // Initialize the list of app screens lazily.
140
+ const list = this.lazyInitList(this.allAppScreens, val => (this.allAppScreens = val), Common.tabJson.AppScreens, this.appScreenMap, (s) => [s?.ID, s?.Name], s => new AppScreenModel(s));
141
+ // If a filter function is given, apply it to the list of app screens.
142
+ return filterFn ? list.filter(filterFn) : list;
220
143
  }
221
144
  /**
222
- * Gets fields for a specific app object
145
+ * Retrieves an organization info by its ID or TenantCode.
146
+ * Searches through all organization info and returns the first match.
223
147
  *
224
- * @param appObject ID or Name of the app object
225
- * @param filterFn Optional filter function for fields
226
- * @returns Array of fields for the specified object
227
- *
228
- * @example
229
- * // Get all fields for an object
230
- * const fields = metadataUtils.getAppFieldsByAppObject('b4887d4d-bb1e-4d52-a7e8-2f943d69e44c' or 'TABMD_SYSTEM');
231
- *
232
- * // Get only required fields
233
- * const requiredFields = metadataUtils.getAppFieldsByAppObject(
234
- * 'b4887d4d-bb1e-4d52-a7e8-2f943d69e44c',
235
- * field => field.IsRequired === true
236
- * );
148
+ * @param {string} nameOrTenantCode - The ID or TenantCode of the organization info to retrieve.
149
+ * @returns {OrgInfoModel | null} - The organization info model if found, otherwise null.
237
150
  */
238
- getAppFieldsByAppObject(appObject, filterFn, columns) {
239
- try {
240
- const filteredAppObject = this.getAppObjectDetails(appObject);
241
- if (!filteredAppObject) {
242
- return [];
243
- }
244
- let fields = filteredAppObject.Fields || [];
245
- // Apply filter if provided
246
- if (filterFn) {
247
- fields = fields.filter(filterFn);
248
- }
249
- return this.formatResults(fields, columns);
250
- }
251
- catch (error) {
252
- console.error('Error in getAppFieldById:', error);
253
- return [];
254
- }
255
- }
256
- /**
257
- * Gets lookup fields for a specific app object
258
- *
259
- * @param appObject ID or Name of the app object
260
- * @param filterFn Optional filter function for lookup fields
261
- * @param columns Optional columns to include in the result
262
- * @returns Array of lookup fields for the specified object
263
- *
264
- * @example
265
- * // Get all lookup fields for an object
266
- * const lookupFields = metadataUtils.getLookupFieldsByAppObject('TABD_Blueprint_SLASchemes');
267
- *
268
- * // Get specific lookup fields
269
- * const fields = metadataUtils.getLookupFieldsByAppObject(
270
- * 'b4887d4d-bb1e-4d52-a7e8-2f943d69e44c',
271
- * field => field.IsRequired === true
272
- * );
273
- */
274
- getLookupFieldsByAppObject(appObject, filterFn, columns) {
275
- try {
276
- // Get fields for the specified object that are lookups
277
- return this.getAppFieldsByAppObject(appObject, field => {
278
- // Check if the field is a lookup type
279
- const isLookup = field.LookUpDetails != null;
280
- // Apply additional user filter if provided
281
- return isLookup && (!filterFn || filterFn(field));
282
- }, columns);
283
- }
284
- catch (error) {
285
- console.error('Error in getAppObjectLookupFields:', error);
286
- return [];
287
- }
288
- }
289
- /**
290
- * Gets data source queries with filter criteria
291
- *
292
- * @param filterFn Optional filter function to apply to queries
293
- * @param columns Optional columns to include in the result
294
- * @returns Array of filtered data source queries
295
- *
296
- * @example
297
- * // Get all queries with a specific naming pattern
298
- * const queries = metadataUtils.getDataSourceQueries(query => query.QueryName.includes('List'));
299
- *
300
- * // Get specific columns from all queries
301
- * const queries = metadataUtils.getDataSourceQueries(
302
- * undefined,
303
- * ['ID', 'QueryName', 'DisplayName']
304
- * );
305
- */
306
- getDataSourceQueries(filterFn, columns) {
307
- try {
308
- // Get all data source queries from all app objects
309
- const allQueries = [];
310
- Common.tabJson.AppObjects.forEach((obj) => {
311
- if (obj.DataSourceQueries && obj.DataSourceQueries.length > 0) {
312
- allQueries.push(...obj.DataSourceQueries);
313
- }
314
- });
315
- // Apply filter if provided
316
- let filteredQueries = allQueries;
317
- if (filterFn) {
318
- filteredQueries = allQueries.filter(filterFn);
319
- }
320
- return this.formatResults(filteredQueries, columns);
321
- }
322
- catch (error) {
323
- console.error('Error in getDataSourceQueries:', error);
324
- return [];
325
- }
151
+ getOrgInfoByIdOrTenantCode(nameOrTenantCode) {
152
+ return this.getFromMapOrCreate(this.orgInfoMap, nameOrTenantCode, Common.tabJson.OrgInfos,
153
+ // Search for the organization info by ID or TenantCode
154
+ org => org.ID === nameOrTenantCode || org.TenantCode === nameOrTenantCode,
155
+ // Create a new OrgInfoModel if the organization info is found
156
+ org => new OrgInfoModel(org));
326
157
  }
327
158
  /**
328
- * Gets data source queries for a specific app object
329
- *
330
- * @param appObject ID or Name of the app object
331
- * @param filterFn Optional filter function for queries
332
- * @param columns Optional columns to include in the result
333
- * @returns Array of queries for the specified object
159
+ * Retrieves a list of all organization info.
160
+ * If a filter function is given, it is applied to the list of organization info.
334
161
  *
335
- * @example
336
- * // Get all queries for an object
337
- * const queries = metadataUtils.getDataSourceQueriesByAppObject('b4887d4d-bb1e-4d52-a7e8-2f943d69e44c');
338
- *
339
- * // Get queries with specific pattern
340
- * const filteredQueries = metadataUtils.getDataSourceQueriesByAppObject(
341
- * 'TABD_Blueprint_SLASchemes',
342
- * query => query.QueryName.includes('List')
343
- * );
162
+ * @param {function} filterFn - The filter function to apply to the organization info.
163
+ * @returns {OrgInfoModel[]} - The list of organization info.
344
164
  */
345
- getDataSourceQueriesByAppObject(appObject, filterFn, columns) {
346
- try {
347
- const filteredAppObject = this.getAppObjectDetails(appObject);
348
- if (!filteredAppObject || !filteredAppObject.DataSourceQueries) {
349
- return [];
350
- }
351
- let queries = filteredAppObject.DataSourceQueries;
352
- // Apply filter if provided
353
- if (filterFn) {
354
- queries = queries.filter(filterFn);
355
- }
356
- return this.formatResults(queries, columns);
357
- }
358
- catch (error) {
359
- console.error('Error in getAppObjectQueries:', error);
360
- return [];
361
- }
165
+ getAllOrgInfos(filterFn) {
166
+ // Initialize the list of organization info lazily.
167
+ const list = this.lazyInitList(this.allOrgInfos, val => (this.allOrgInfos = val), Common.tabJson.OrgInfos, this.orgInfoMap, (org) => [org?.ID, org?.TenantCode], org => new OrgInfoModel(org));
168
+ // If a filter function is given, apply it to the list of organization info.
169
+ return filterFn ? list.filter(filterFn) : list;
362
170
  }
363
171
  /**
364
- * Gets a specific Data Source Query by ID or Name
365
- *
366
- * @param query ID or Name of the data source query to retrieve
367
- * @param columns Optional columns to include in the result
368
- * @returns The data source query with specified columns or null if not found
172
+ * Performs a global search across all metadata for a given search term.
173
+ * You can narrow the search by providing a list of entity types to search within.
369
174
  *
370
- * @example
371
- * // Get a specific query with all properties
372
- * const query = metadataUtils.getDataSourceQueryDetails('73e590d0-c4eb-464d-abf9-01943e30ae09');
373
- *
374
- * // Get specific columns from a query by name
375
- * const query = metadataUtils.getDataSourceQueryDetails(
376
- * 'Get_SLASchemes_List',
377
- * ['ID', 'QueryName', 'DisplayName']
378
- * );
175
+ * @param {string} term - The search term to search for.
176
+ * @param {MetadataEntityType[]} entityTypes - The list of entity types to search within. If omitted, all entity types are searched.
177
+ * @returns {Record<string, any[]>} - A dictionary with results grouped by entity type.
379
178
  */
380
- getDataSourceQueryDetails(query, columns) {
381
- try {
382
- return this.getDataSourceQueries(q => q.ID?.toLowerCase() === query?.toLowerCase() || q.QueryName === query, columns)?.[0] ?? null;
179
+ searchMetadata(term, entityTypes) {
180
+ const searchTerm = term.toLowerCase();
181
+ const result = {};
182
+ /**
183
+ * Helper function to determine if a given entity type should be searched.
184
+ * @param {MetadataEntityType} type - The entity type to check.
185
+ * @returns {boolean} - Whether the entity type should be searched.
186
+ */
187
+ const shouldSearch = (type) => !entityTypes || entityTypes.includes(type);
188
+ if (shouldSearch(MetadataEntityType.APP_OBJECTS)) {
189
+ // Search for app objects by ID, ObjectName, DisplayName, or SystemDBTableName
190
+ result[MetadataEntityType.APP_OBJECTS] = this.getAllAppObjects(obj => [obj?.ID, obj?.ObjectName, obj?.DisplayName, obj?.SystemDBTableName]
191
+ .some(val => val === searchTerm || val?.toLowerCase().includes(searchTerm)));
383
192
  }
384
- catch (error) {
385
- console.error('Error in getDataSourceQuery:', error);
386
- return null;
193
+ if (shouldSearch(MetadataEntityType.APP_FIELDS)) {
194
+ // Search for app fields by using the search method
195
+ result[MetadataEntityType.APP_FIELDS] = this.getAllFields(field => field.search(searchTerm));
387
196
  }
388
- }
389
- /**
390
- * Gets fields from a data source query
391
- *
392
- * @param query ID or Name of the data source query
393
- * @param filterFn Optional filter function for query fields
394
- * @param columns Optional columns to include in the result
395
- * @returns Array of fields for the specified query with app field details
396
- *
397
- * @example
398
- * // Get all fields for a query
399
- * const queryFields = metadataUtils.getDataSourceQueryFields('73e590d0-c4eb-464d-abf9-01943e30ae09');
400
- *
401
- * // Get fields for a query by name
402
- * const queryFields = metadataUtils.getDataSourceQueryFields('Get_SLASchemes_List');
403
- *
404
- * // Get fields with filter and specific columns
405
- * const fields = metadataUtils.getDataSourceQueryFields(
406
- * '73e590d0-c4eb-464d-abf9-01943e30ae09',
407
- * field => field.FieldType === 1,
408
- * ['ID', 'AppFieldID', 'FieldType']
409
- * );
410
- */
411
- getFieldsByDSQ(query, filterFn, columns) {
412
- try {
413
- // Find the query using our existing method
414
- const dsQuery = this.getDataSourceQueryDetails(query);
415
- if (!dsQuery || !dsQuery.Fields?.length) {
416
- return [];
417
- }
418
- // Get enhanced fields with app field details
419
- let queryFields = this.enhanceQueryFieldsWithAppFields(dsQuery);
420
- // Apply filter if provided
421
- if (filterFn) {
422
- queryFields = queryFields.filter(filterFn);
423
- }
424
- return this.formatResults(queryFields, columns);
197
+ if (shouldSearch(MetadataEntityType.DATA_SOURCE_QUERIES)) {
198
+ // Search for data source queries by using the search method
199
+ result[MetadataEntityType.DATA_SOURCE_QUERIES] = this.getAllDataSourceQueries(dsq => dsq.search(searchTerm));
425
200
  }
426
- catch (error) {
427
- console.error('Error in getDataSourceQueryFields:', error);
428
- return [];
429
- }
430
- }
431
- /**
432
- * Enhances query fields with their corresponding app field details
433
- * @private
434
- */
435
- enhanceQueryFieldsWithAppFields(dsQuery) {
436
- if (!dsQuery || !dsQuery.Fields?.length) {
437
- return [];
438
- }
439
- // Find the parent app object
440
- const parentAppObject = this.findParentAppObjectForQuery(dsQuery);
441
- if (!parentAppObject) {
442
- return dsQuery.Fields;
443
- }
444
- // Add app field details to each query field
445
- return dsQuery.Fields.map((field) => {
446
- const appField = this.findAppFieldById(parentAppObject, field.AppFieldID);
447
- return {
448
- ...field,
449
- Field: appField || {}
450
- };
451
- });
452
- }
453
- /**
454
- * Finds the parent app object that contains a specific data source query
455
- * @private
456
- */
457
- findParentAppObjectForQuery(dsQuery) {
458
- return this.getAppObjects(obj => obj.DataSourceQueries?.some((q) => q.ID?.toLowerCase() === dsQuery.ID?.toLowerCase() ||
459
- q.QueryName === dsQuery.QueryName))[0];
460
- }
461
- /**
462
- * Finds an app field by ID within a specific app object
463
- * @private
464
- */
465
- findAppFieldById(appObject, fieldId) {
466
- if (!appObject || !appObject.Fields?.length || !fieldId) {
467
- return undefined;
468
- }
469
- return appObject.Fields.find((field) => field.ID?.toLowerCase() === fieldId?.toLowerCase());
470
- }
471
- /**
472
- * Gets query parameters from a data source query
473
- *
474
- * @param query ID or Name of the data source query
475
- * @param filterFn Optional filter function for query parameters
476
- * @param columns Optional columns to include in the result
477
- * @returns Array of parameters for the specified query
478
- *
479
- * @example
480
- * // Get all parameters for a query
481
- * const queryParams = metadataUtils.getParametersByDSQ('73e590d0-c4eb-464d-abf9-01943e30ae09');
482
- *
483
- * // Get all parameters for a query by name
484
- * const queryParams = metadataUtils.getParametersByDSQ('Get_SLASchemes_List');
485
- *
486
- * // Get mandatory parameters only
487
- * const mandatoryParams = metadataUtils.getParametersByDSQ(
488
- * '73e590d0-c4eb-464d-abf9-01943e30ae09',
489
- * param => param.IsMandatory === true
490
- * );
491
- */
492
- getParametersByDSQ(query, filterFn, columns) {
493
- try {
494
- // Find the query using our existing method
495
- const dsQuery = this.getDataSourceQueryDetails(query);
496
- if (!dsQuery || !dsQuery.Parameters?.length) {
497
- return [];
498
- }
499
- let queryParameters = dsQuery.Parameters || [];
500
- // Apply filter if provided
501
- if (filterFn) {
502
- queryParameters = queryParameters.filter(filterFn);
503
- }
504
- return this.formatResults(queryParameters, columns);
505
- }
506
- catch (error) {
507
- console.error('Error in getDataSourceQueryParameters:', error);
508
- return [];
509
- }
510
- }
511
- /**
512
- * Gets App Screens with filter criteria
513
- *
514
- * @param filterFn Optional filter function to apply to app screens
515
- * @param columns Optional columns to include in the result
516
- * @returns Array of filtered app screens
517
- *
518
- * @example
519
- * // Get all system screens
520
- * const systemScreens = metadataUtils.getAppScreens(screen => screen.IsSystemRecord === true);
521
- *
522
- * // Get specific columns from all screens
523
- * const screens = metadataUtils.getAppScreens(
524
- * undefined,
525
- * ['ID', 'Name', 'ScreenType']
526
- * );
527
- */
528
- getAppScreens(filterFn, columns) {
529
- try {
530
- let appScreens = Common.tabJson.AppScreens || [];
531
- // Apply filter if provided
532
- if (filterFn) {
533
- appScreens = appScreens.filter(filterFn);
534
- }
535
- return this.formatResults(appScreens, columns);
536
- }
537
- catch (error) {
538
- console.error('Error in getAppScreens:', error);
539
- return [];
540
- }
541
- }
542
- /**
543
- * Gets a specific App Screen by ID or Name
544
- *
545
- * @param screen ID or Name of the app screen to retrieve
546
- * @param columns Optional columns to include in the result
547
- * @returns The app screen with specified columns or null if not found
548
- *
549
- * @example
550
- * // Get a specific screen with all properties
551
- * const screen = metadataUtils.getAppScreen('a5cd639e-31ba-4d33-8800-005a5248dfb2');
552
- *
553
- * // Get specific columns from a screen by name
554
- * const screen = metadataUtils.getAppScreen(
555
- * 'New Detail Role/Permission Appoject acess wise',
556
- * ['ID', 'Name', 'ScreenType']
557
- * );
558
- */
559
- getAppScreen(screen, columns) {
560
- try {
561
- return this.getAppScreens(scr => scr.ID?.toLowerCase() === screen?.toLowerCase() || scr.Name === screen, columns)?.[0] ?? null;
562
- }
563
- catch (error) {
564
- console.error('Error in getAppScreen:', error);
565
- return null;
566
- }
567
- }
568
- /**
569
- * Gets App Menus with filter criteria
570
- *
571
- * @param filterFn Optional filter function to apply to app menus
572
- * @param columns Optional columns to include in the result
573
- * @returns Array of filtered app menus
574
- *
575
- * @example
576
- * // Get all top-level menus
577
- * const topMenus = metadataUtils.getAppMenus(menu => !menu.ParentID);
578
- *
579
- * // Get specific columns from all menus
580
- * const menus = metadataUtils.getAppMenus(
581
- * undefined,
582
- * ['ID', 'MenuName', 'DisplayName', 'ScreenID']
583
- * );
584
- */
585
- getAppMenus(filterFn, columns) {
586
- try {
587
- let appMenus = Common.tabJson.AppMenus || [];
588
- // Apply filter if provided
589
- if (filterFn) {
590
- appMenus = appMenus.filter(filterFn);
591
- }
592
- return this.formatResults(appMenus, columns);
593
- }
594
- catch (error) {
595
- console.error('Error in getAppMenus:', error);
596
- return [];
597
- }
598
- }
599
- /**
600
- * Gets organization information with filter criteria
601
- *
602
- * @param filterFn Optional filter function to apply to organizations
603
- * @param columns Optional columns to include in the result
604
- * @returns Array of filtered organizations
605
- *
606
- * @example
607
- * // Get all organizations
608
- * const orgs = metadataUtils.getOrgs();
609
- *
610
- * // Get organizations with specific subdomain pattern
611
- * const specificOrgs = metadataUtils.getOrgs(
612
- * org => org.Subdomain?.includes('test')
613
- * );
614
- */
615
- getOrgs(filterFn, columns) {
616
- try {
617
- let organizations = Common.tabJson.OrgInfos || [];
618
- // Apply filter if provided
619
- if (filterFn) {
620
- organizations = organizations.filter(filterFn);
621
- }
622
- return this.formatResults(organizations, columns);
623
- }
624
- catch (error) {
625
- console.error('Error in getOrganizations:', error);
626
- return [];
627
- }
628
- }
629
- /**
630
- * Gets a specific organization by ID or Name
631
- *
632
- * @param organization ID or OrganizationName of the organization
633
- * @param columns Optional columns to include in the result
634
- * @returns The organization or null if not found
635
- *
636
- * @example
637
- * // Get organization by ID
638
- * const org = metadataUtils.getOrgInfoDetails('0ec3d0f1-b2ec-47b7-8305-b767d0e5ea63');
639
- *
640
- * // Get organization by name
641
- * const org = metadataUtils.getOrgInfoDetails('SquadFocus');
642
- */
643
- getOrgInfoDetails(organization, columns) {
644
- try {
645
- return this.getOrgs(org => org.ID?.toLowerCase() === organization?.toLowerCase() ||
646
- org.OrganizationName === organization ||
647
- org.Subdomain === organization, columns)[0] || null;
648
- }
649
- catch (error) {
650
- console.error('Error in getOrganization:', error);
651
- return null;
201
+ if (shouldSearch(MetadataEntityType.APP_SCREENS)) {
202
+ // Search for app screens by using the search method
203
+ result[MetadataEntityType.APP_SCREENS] = this.getAllAppScreens(screen => screen.search(searchTerm));
652
204
  }
205
+ return result;
653
206
  }
654
207
  static { this.ɵfac = function MetadataHelper_Factory(t) { return new (t || MetadataHelper)(); }; }
655
208
  static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: MetadataHelper, factory: MetadataHelper.ɵfac, providedIn: 'root' }); }
@@ -658,4 +211,4 @@ export class MetadataHelper {
658
211
  type: Injectable,
659
212
  args: [{ providedIn: 'root' }]
660
213
  }], null, null); })();
661
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0YS1kYXRhLmhlbHBlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL2RhdGEtYWNjZXNzL3NyYy9saWIvdGFiLWNvcmUtdXRpbGl0eS9hcHAvaGVscGVycy9jb21tb24vbWV0YS1kYXRhLmhlbHBlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsdURBQXVEO0FBQ3ZELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFFLGtCQUFrQixFQUFXLE1BQU0sbUNBQW1DLENBQUM7QUFDaEYsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLHdCQUF3QixDQUFDOztBQUloRDs7Ozs7S0FLSztBQUVMLE1BQU0sT0FBTyxjQUFjO0lBQ3ZCLCtDQUErQztJQUN2QyxhQUFhLENBQUksS0FBVSxFQUFFLE9BQWtCO1FBQ25ELElBQUksQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNuQyxPQUFPLEtBQUssQ0FBQztRQUNqQixDQUFDO1FBRUQsT0FBTyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQ3BCLE1BQU0sTUFBTSxHQUFRLEVBQUUsQ0FBQztZQUN2QixPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFO2dCQUNsQixNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUksSUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3JDLENBQUMsQ0FBQyxDQUFDO1lBQ0gsT0FBTyxNQUFNLENBQUM7UUFDbEIsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7T0FnQkc7SUFDSSxvQkFBb0IsQ0FDdkIsVUFBa0IsRUFDbEIsV0FBa0M7UUFFbEMsSUFBSSxDQUFDO1lBQ0QsSUFBSSxDQUFDLFVBQVUsSUFBSSxVQUFVLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxF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LGdCQUFnQixLQUFLLFlBQVk7Z0JBQ3JDLEdBQUcsQ0FBQyxTQUFTLEtBQUssWUFBWSxFQUM5QixPQUFPLENBQ1YsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUM7UUFDakIsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDYixPQUFPLENBQUMsS0FBSyxDQUFDLDJCQUEyQixFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQ2xELE9BQU8sSUFBSSxDQUFDO1FBQ2hCLENBQUM7SUFDTCxDQUFDOytFQXR1QlEsY0FBYzt1RUFBZCxjQUFjLFdBQWQsY0FBYyxtQkFERCxNQUFNOztpRkFDbkIsY0FBYztjQUQxQixVQUFVO2VBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSAqL1xuaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBNZXRhZGF0YUVudGl0eVR5cGUsIE9yZ0luZm8gfSBmcm9tIFwiLi4vLi4vaW50ZXJmYWNlcy9zY2hlbWEuaW50ZXJmYWNlXCI7XG5pbXBvcnQgeyBDb21tb24gfSBmcm9tIFwiLi4vLi4vY29uc3RhbnRzL2NvbW1vblwiO1xuaW1wb3J0IHsgQXBwTWVudSwgQXBwT2JqZWN0LCBBcHBTY3JlZW4gfSBmcm9tIFwiLi4vLi4vbW9kZWxzL2FwcC1vYmplY3QuY2xhc3NcIjtcbmltcG9ydCB7IEFwcEZpZWxkcywgRGF0YVNvdXJjZVF1ZXJpZXMsIERhdGFTb3VyY2VRdWVyaWVzX0ZpZWxkcywgUGFyYW1ldGVycyB9IGZyb20gXCIuLi8uLi9tb2RlbHMvZGF0YS1zb3VyY2UtcXVlcmllcy5jbGFzc1wiO1xuXG4vKipcbiAgICogTWV0YWRhdGFVdGlscyAtIFV0aWxpdHkgc2VydmljZSBmb3IgcmV0cmlldmluZyBhbmQgbWFuaXB1bGF0aW5nIGFwcGxpY2F0aW9uIG1ldGFkYXRhXG4gICAqIFxuICAgKiBUaGlzIHNlcnZpY2UgcHJvdmlkZXMgbWV0aG9kcyB0byBleHRyYWN0LCBmaWx0ZXIsIGFuZCBmb3JtYXQgZGlmZmVyZW50IHBhcnRzIG9mIHRoZVxuICAgKiBhcHBsaWNhdGlvbiBtZXRhZGF0YSwgaW5jbHVkaW5nIG9iamVjdHMsIGZpZWxkcywgc2NyZWVucywgbWVudXMsIGV0Yy5cbiAgICovXG5ASW5qZWN0YWJsZSh7IHByb3ZpZGVkSW46ICdyb290JyB9KVxuZXhwb3J0IGNsYXNzIE1ldGFkYXRhSGVscGVyIHtcbiAgICAvLyBIZWxwZXIgbWV0aG9kIHRvIGNvbnNpc3RlbnRseSBmb3JtYXQgcmVzdWx0c1xuICAgIHByaXZhdGUgZm9ybWF0UmVzdWx0czxUPihpdGVtczogVFtdLCBjb2x1bW5zPzogc3RyaW5nW10pOiBhbnlbXSB7XG4gICAgICAgIGlmICghY29sdW1ucyB8fCBjb2x1bW5zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIGl0ZW1zO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGl0ZW1zLm1hcChpdGVtID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdDogYW55ID0ge307XG4gICAgICAgICAgICBjb2x1bW5zLmZvckVhY2goY29sID0+IHtcbiAgICAgICAgICAgICAgICByZXN1bHRbY29sXSA9IChpdGVtIGFzIGFueSlbY29sXTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2VhcmNoIGFjcm9zcyBhbGwgbWV0YWRhdGEgZm9yIGEgdGVybVxuICAgICAqIFxuICAgICAqIEBwYXJhbSBzZWFyY2hUZXJtIFRlcm0gdG8gc2VhcmNoIGZvclxuICAgICAqIEBwYXJhbSBlbnRpdHlUeXBlcyBPcHRpb25hbCB0eXBlcyBvZiBlbnRpdGllcyB0byBzZWFyY2ggKGlmIG5vdCBwcm92aWRlZCwgc2VhcmNoZXMgYWxsKVxuICAgICAqIEByZXR1cm5zIFNlYXJjaCByZXN1bHRzIGdyb3VwZWQgYnkgZW50aXR5IHR5cGVcbiAgICAgKiBcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIFNlYXJjaCBhY3Jvc3MgYWxsIG1ldGFkYXRhXG4gICAgICogY29uc3QgcmVzdWx0cyA9IG1ldGFkYXRhVXRpbHMuc2VhcmNoQWNyb3NzTWV0YWRhdGEoJ0JsdWVwcmludCcpO1xuICAgICAqIFxuICAgICAqIC8vIFNlYXJjaCBvbmx5IGluIGFwcCBvYmplY3RzIGFuZCBzY3JlZW5zXG4gICAgICogY29uc3QgcmVzdWx0cyA9IG1ldGFkYXRhVXRpbHMuc2VhcmNoQWNyb3NzTWV0YWRhdGEoXG4gICAgICogICAnUm9sZScsIFxuICAgICAqICAgW01ldGFkYXRhRW50aXR5VHlwZS5BUFBfT0JKRUNUUywgTWV0YWRhdGFFbnRpdHlUeXBlLkFQUF9TQ1JFRU5TXVxuICAgICAqICk7XG4gICAgICovXG4gICAgcHVibGljIHNlYXJjaEFjcm9zc01ldGFkYXRhKFxuICAgICAgICBzZWFyY2hUZXJtOiBzdHJpbmcsXG4gICAgICAgIGVudGl0eVR5cGVzPzogTWV0YWRhdGFFbnRpdHlUeXBlW11cbiAgICApOiBSZWNvcmQ8c3RyaW5nLCBhbnlbXT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKCFzZWFyY2hUZXJtIHx8IHNlYXJjaFRlcm0udHJpbSgpID09PSAnJykge1xuICAgICAgICAgICAgICAgIHJldHVybiB7fTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgdGVybSA9IHNlYXJjaFRlcm0udG9Mb3dlckNhc2UoKTtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdHM6IFJlY29yZDxzdHJpbmcsIGFueVtdPiA9IHt9O1xuXG4gICAgICAgICAgICAvLyBJZiBlbnRpdHlUeXBlcyBub3QgcHJvdmlkZWQsIHNlYXJjaCBhbGwgZW50aXR5IHR5cGVzXG4gICAgICAgICAgICBjb25zdCB0eXBlc1RvU2VhcmNoID0gZW50aXR5VHlwZXMgfHwgT2JqZWN0LnZhbHVlcyhNZXRhZGF0YUVudGl0eVR5cGUpO1xuXG4gICAgICAgICAgICAvLyBFeGVjdXRlIHNlYXJjaCBmb3IgZWFjaCBlbnRpdHkgdHlwZVxuICAgICAgICAgICAgaWYgKHR5cGVzVG9TZWFyY2guaW5jbHVkZXMoTWV0YWRhdGFFbnRpdHlUeXBlLkFQUF9PQkpFQ1RTKSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdHNbTWV0YWRhdGFFbnRpdHlUeXBlLkFQUF9PQkpFQ1RTXSA9IHRoaXMuc2VhcmNoQXBwT2JqZWN0cyh0ZXJtKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHR5cGVzVG9TZWFyY2guaW5jbHVkZXMoTWV0YWRhdGFFbnRpdHlUeXBlLkFQUF9GSUVMRFMpKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0c1tNZXRhZGF0YUVudGl0eVR5cGUuQVBQX0ZJRUxEU10gPSB0aGlzLnNlYXJjaEFwcEZpZWxkcyh0ZXJtKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHR5cGVzVG9TZWFyY2guaW5jbHVkZXMoTWV0YWRhdGFFbnRpdHlUeXBlLkRBVEFfU09VUkNFX1FVRVJJRVMpKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0c1tNZXRhZGF0YUVudGl0eVR5cGUuREFUQV9TT1VSQ0VfUVVFUklFU10gPSB0aGlzLnNlYXJjaERhdGFTb3VyY2VRdWVyaWVzKHRlcm0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodHlwZXNUb1NlYXJjaC5pbmNsdWRlcyhNZXRhZGF0YUVudGl0eVR5cGUuQVBQX1NDUkVFTlMpKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0c1tNZXRhZGF0YUVudGl0eVR5cGUuQVBQX1NDUkVFTlNdID0gdGhpcy5zZWFyY2hBcHBTY3JlZW5zKHRlcm0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodHlwZXNUb1NlYXJjaC5pbmNsdWRlcyhNZXRhZGF0YUVudGl0eVR5cGUuQVBQX01FTlVTKSkge1xuICAgICAgICAgICAgICAgIHJlc3VsdHNbTWV0YWRhdGFFbnRpdHlUeXBlLkFQUF9NRU5VU10gPSB0aGlzLnNlYXJjaEFwcE1lbnVzKHRlcm0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gcmVzdWx0cztcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGluIHNlYXJjaE1ldGFkYXRhOicsIGVycm9yKTtcbiAgICAgICAgICAgIHJldHVybiB7fTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlYXJjaCBmb3IgYSB0ZXJtIHdpdGhpbiBBcHAgT2JqZWN0c1xuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgcHJpdmF0ZSBzZWFyY2hBcHBPYmplY3RzKHRlcm06IHN0cmluZyk6IGFueVtdIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXBwT2JqZWN0cyhvYmogPT5cbiAgICAgICAgICAgIHRoaXMuY29udGFpbnNUZXJtKG9iai5PYmplY3ROYW1lLCB0ZXJtKSB8fFxuICAgICAgICAgICAgdGhpcy5jb250YWluc1Rlcm0ob2JqLkRpc3BsYXlOYW1lLCB0ZXJtKSB8fFxuICAgICAgICAgICAgdGhpcy5jb250YWluc1Rlcm0ob2JqLkRlc2NyaXB0aW9uLCB0ZXJtKSB8fFxuICAgICAgICAgICAgdGhpcy5jb250YWluc1Rlcm0ob2JqLlN5c3RlbURCVGFibGVOYW1lLCB0ZXJtKVxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlYXJjaCBmb3IgYSB0ZXJtIHdpdGhpbiBBcHAgRmllbGRzXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBwcml2YXRlIHNlYXJjaEFwcEZpZWxkcyh0ZXJtOiBzdHJpbmcpOiBhbnlbXSB7XG4gICAgICAgIHJldHVybiB0aGlzLmdldEFwcEZpZWxkcyhmaWVsZCA9PlxuICAgICAgICAgICAgdGhpcy5jb250YWluc1Rlcm0oZmllbGQuRmllbGROYW1lLCB0ZXJtKSB8fFxuICAgICAgICAgICAgdGhpcy5jb250YWluc1Rlcm0oZmllbGQuRGlzcGxheU5hbWUsIHRlcm0pIHx8XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5zVGVybShmaWVsZC5EZXNjcmlwdGlvbiwgdGVybSkgfHxcbiAgICAgICAgICAgIHRoaXMuY29udGFpbnNUZXJtKGZpZWxkLlN5c3RlbURCRmllbGROYW1lLCB0ZXJtKVxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlYXJjaCBmb3IgYSB0ZXJtIHdpdGhpbiBEYXRhIFNvdXJjZSBRdWVyaWVzXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBwcml2YXRlIHNlYXJjaERhdGFTb3VyY2VRdWVyaWVzKHRlcm06IHN0cmluZyk6IGFueVtdIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RGF0YVNvdXJjZVF1ZXJpZXMocXVlcnkgPT5cbiAgICAgICAgICAgIHRoaXMuY29udGFpbnNUZXJtKHF1ZXJ5LlF1ZXJ5TmFtZSwgdGVybSkgfHxcbiAgICAgICAgICAgIHRoaXMuY29udGFpbnNUZXJtKHF1ZXJ5LkRpc3BsYXlOYW1lLCB0ZXJtKVxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlYXJjaCBmb3IgYSB0ZXJtIHdpdGhpbiBBcHAgU2NyZWVuc1xuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgcHJpdmF0ZSBzZWFyY2hBcHBTY3JlZW5zKHRlcm06IHN0cmluZyk6IGFueVtdIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXBwU2NyZWVucyhzY3JlZW4gPT5cbiAgICAgICAgICAgIHRoaXMuY29udGFpbnNUZXJtKHNjcmVlbi5OYW1lLCB0ZXJtKSB8fFxuICAgICAgICAgICAgdGhpcy5jb250YWluc1Rlcm0oc2NyZWVuLkRlc2NyaXB0aW9uLCB0ZXJtKVxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNlYXJjaCBmb3IgYSB0ZXJtIHdpdGhpbiBBcHAgTWVudXNcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHByaXZhdGUgc2VhcmNoQXBwTWVudXModGVybTogc3RyaW5nKTogYW55W10ge1xuICAgICAgICByZXR1cm4gdGhpcy5nZXRBcHBNZW51cyhtZW51ID0+XG4gICAgICAgICAgICB0aGlzLmNvbnRhaW5zVGVybShtZW51Lk1lbnVOYW1lLCB0ZXJtKSB8fFxuICAgICAgICAgICAgdGhpcy5jb250YWluc1Rlcm0obWVudS5EaXNwbGF5TmFtZSwgdGVybSlcbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBIZWxwZXIgbWV0aG9kIHRvIGNoZWNrIGlmIGEgc3RyaW5nIGNvbnRhaW5zIGEgc2VhcmNoIHRlcm1cbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHByaXZhdGUgY29udGFpbnNUZXJtKHZhbHVlOiBzdHJpbmcgfCB1bmRlZmluZWQgfCBudWxsLCB0ZXJtOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuICEhdmFsdWUgJiYgdmFsdWUudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyh0ZXJtKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIEFwcCBPYmplY3RzIGJhc2VkIG9uIGZpbHRlciBjcml0ZXJpYVxuICAgICAqIFxuICAgICAqIEBwYXJhbSBmaWx0ZXJGbiBPcHRpb25hbCBmaWx0ZXIgZnVuY3Rpb24gdG8gYXBwbHkgdG8gYXBwIG9iamVjdHNcbiAgICAgKiBAcGFyYW0gY29sdW1ucyBPcHRpb25hbCBjb2x1bW5zIHRvIGluY2x1ZGUgaW4gdGhlIHJlc3VsdFxuICAgICAqIEByZXR1cm5zIEFycmF5IG9mIGZpbHRlcmVkIGFwcCBvYmplY3RzXG4gICAgICogXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBHZXQgYWxsIHN5c3RlbSBhcHAgb2JqZWN0c1xuICAgICAqIGNvbnN0IHN5c3RlbU9iamVjdHMgPSBtZXRhZGF0YVV0aWxzLmdldEFwcE9iamVjdHMob2JqID0+IG9iai5Jc1N5c3RlbSA9PT0gdHJ1ZSk7XG4gICAgICogXG4gICAgICogLy8gR2V0IHNwZWNpZmljIGNvbHVtbnMgZnJvbSBub24tZGVwcmVjYXRlZCBvYmplY3RzXG4gICAgICogY29uc3Qgb2JqZWN0cyA9IG1ldGFkYXRhVXRpbHMuZ2V0QXBwT2JqZWN0cyhcbiAgICAgKiAgIG9iaiA9PiAhb2JqLklzRGVwcmVjYXRlZCwgXG4gICAgICogICBbJ0lEJywgJ0Rpc3BsYXlOYW1lJywgJ09iamVjdE5hbWUnXVxuICAgICAqICk7XG4gICAgICovXG4gICAgcHVibGljIGdldEFwcE9iamVjdHMoZmlsdGVyRm4/OiAoKHZhbHVlOiBBcHBPYmplY3QpID0+IGJvb2xlYW4pLCBjb2x1bW5zPzogc3RyaW5nW10pOiBhbnlbXSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsZXQgYXBwT2JqZWN0cyA9IENvbW1vbi50YWJKc29uLkFwcE9iamVjdHMgfHwgW107XG5cbiAgICAgICAgICAgIC8vIEFwcGx5IGZpbHRlciBpZiBwcm92aWRlZFxuICAgICAgICAgICAgaWYgKGZpbHRlckZuKSB7XG4gICAgICAgICAgICAgICAgYXBwT2JqZWN0cyA9IGFwcE9iamVjdHMuZmlsdGVyKGZpbHRlckZuKTtcbiAgICAgICAgICAgIH1cblxuXG4gICAgICAgICAgICAvLyBSZXR1cm4gYWxsIG9iamVjdCBkYXRhIGlmIG5vIGNvbHVtbnMgc3BlY2lmaWVkXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXRSZXN1bHRzKGFwcE9iamVjdHMsIGNvbHVtbnMpO1xuXG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBpbiBnZXRBcHBPYmplY3RzOicsIGVycm9yKTtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgYSBzcGVjaWZpYyBBcHAgT2JqZWN0IGJ5IElEIG9yIE5hbWVcbiAgICAgKiBcbiAgICAgKiBAcGFyYW0gYXBwT2JqZWN0IElEIG9yIE5hbWUgb2YgdGhlIGFwcCBvYmplY3QgdG8gcmV0cmlldmVcbiAgICAgKiBAcGFyYW0gY29sdW1ucyBPcHRpb25hbCBjb2x1bW5zIHRvIGluY2x1ZGUgaW4gdGhlIHJlc3VsdFxuICAgICAqIEByZXR1cm5zIFRoZSBhcHAgb2JqZWN0IHdpdGggc3BlY2lmaWVkIGNvbHVtbnMgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKiBcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIEdldCBhIHNwZWNpZmljIGFwcCBvYmplY3Qgd2l0aCBhbGwgcHJvcGVydGllc1xuICAgICAqIGNvbnN0IGFwcE9iaiA9IG1ldGFkYXRhVXRpbHMuZ2V0QXBwT2JqZWN0RGV0YWlscygnYjQ4ODdkNGQtYmIxZS00ZDUyLWE3ZTgtMmY5NDNkNjllNDRjJyBvciAnVEFCTURfU1lTVEVNJyk7XG4gICAgICogXG4gICAgICogLy8gR2V0IHNwZWNpZmljIGNvbHVtbnMgZnJvbSBhbiBhcHAgb2JqZWN0XG4gICAgICogY29uc3QgYXBwT2JqID0gbWV0YWRhdGFVdGlscy5nZXRBcHBPYmplY3REZXRhaWxzKFxuICAgICAqICAgJ2I0ODg3ZDRkLWJiMWUtNGQ1Mi1hN2U4LTJmOTQzZDY5ZTQ0YycsIFxuICAgICAqICAgWydJRCcsICdEaXNwbGF5TmFtZScsICdPYmplY3ROYW1lJ11cbiAgICAgKiApO1xuICAgICAqL1xuICAgIHB1YmxpYyBnZXRBcHBPYmplY3REZXRhaWxzKGFwcE9iamVjdDogc3RyaW5nLCBjb2x1bW5zPzogc3RyaW5nW10pOiBhbnkge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXBwT2JqZWN0cyhvYmogPT4gb2JqLklEPy50b0xvd2VyQ2FzZSgpID09PSBhcHBPYmplY3Q/LnRvTG93ZXJDYXNlKCkgfHwgb2JqLk9iamVjdE5hbWUgPT09IGFwcE9iamVjdCwgY29sdW1ucyk/LlswXSA/PyBudWxsO1xuXG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBpbiBnZXRBcHBPYmplY3RCeUlkOicsIGVycm9yKTtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBhbGwgZmllbGRzIGFjcm9zcyBhbGwgYXBwIG9iamVjdHMgd2l0aCBmaWx0ZXIgY3JpdGVyaWFcbiAgICAgKiBcbiAgICAgKiBAcGFyYW0gZmlsdGVyRm4gT3B0aW9uYWwgZmlsdGVyIGZ1bmN0aW9uIHRvIGFwcGx5IHRvIGZpZWxkc1xuICAgICAqIEBwYXJhbSBjb2x1bW5zIE9wdGlvbmFsIGNvbHVtbnMgdG8gaW5jbHVkZSBpbiB0aGUgcmVzdWx0XG4gICAgICogQHJldHVybnMgQXJyYXkgb2YgZmlsdGVyZWQgZmllbGRzXG4gICAgICogXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBHZXQgYWxsIHJlcXVpcmVkIGZpZWxkcyBhY3Jvc3MgYWxsIG9iamVjdHNcbiAgICAgKiBjb25zdCByZXF1aXJlZEZpZWxkcyA9IG1ldGFkYXRhVXRpbHMuZ2V0QXBwRmllbGRzKGZpZWxkID0+IGZpZWxkLklzUmVxdWlyZWQgPT09IHRydWUpO1xuICAgICAqIFxuICAgICAqIC8vIEdldCBzcGVjaWZpYyBjb2x1bW5zIGZyb20gc2VhcmNoYWJsZSBmaWVsZHNcbiAgICAgKiBjb25zdCBmaWVsZHMgPSBtZXRhZGF0YVV0aWxzLmdldEFwcEZpZWxkcyhcbiAgICAgKiAgIGZpZWxkID0+IGZpZWxkLklzU2VhcmNoYWJsZSA9PT0gdHJ1ZSwgXG4gICAgICogICBbJ0lEJywgJ0Rpc3BsYXlOYW1lJywgJ0ZpZWxkTmFtZSddXG4gICAgICogKTtcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0QXBwRmllbGRzKGZpbHRlckZuPzogKCh2YWx1ZTogQXBwRmllbGRzKSA9PiBib29sZWFuKSwgY29sdW1ucz86IHN0cmluZ1tdKTogYW55W10ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gR2V0IGFsbCBmaWVsZHMgZnJvbSBhbGwgYXBwIG9iamVjdHNcbiAgICAgICAgICAgIGNvbnN0IGFsbEZpZWxkczogQXBwRmllbGRzW10gPSBbXTtcbiAgICAgICAgICAgIENvbW1vbi50YWJKc29uLkFwcE9iamVjdHMuZm9yRWFjaCgob2JqOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICBhbGxGaWVsZHMucHVzaCguLi5vYmouRmllbGRzKTtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBBcHBseSBmaWx0ZXIgaWYgcHJvdmlkZWRcbiAgICAgICAgICAgIGxldCBmaWx0ZXJlZEZpZWxkcyA9IGFsbEZpZWxkcztcbiAgICAgICAgICAgIGlmIChmaWx0ZXJGbikge1xuICAgICAgICAgICAgICAgIGZpbHRlcmVkRmllbGRzID0gYWxsRmllbGRzLmZpbHRlcihmaWx0ZXJGbik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFJldHVybiBhbGwgZmllbGQgZGF0YSBpZiBubyBjb2x1bW5zIHNwZWNpZmllZFxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0UmVzdWx0cyhmaWx0ZXJlZEZpZWxkcywgY29sdW1ucyk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBpbiBnZXRBcHBGaWVsZHM6JywgZXJyb3IpO1xuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBmaWVsZHMgZm9yIGEgc3BlY2lmaWMgYXBwIG9iamVjdFxuICAgICAqIFxuICAgICAqIEBwYXJhbSBhcHBPYmplY3QgSUQgb3IgTmFtZSBvZiB0aGUgYXBwIG9iamVjdFxuICAgICAqIEBwYXJhbSBmaWx0ZXJGbiBPcHRpb25hbCBmaWx0ZXIgZnVuY3Rpb24gZm9yIGZpZWxkc1xuICAgICAqIEByZXR1cm5zIEFycmF5IG9mIGZpZWxkcyBmb3IgdGhlIHNwZWNpZmllZCBvYmplY3RcbiAgICAgKiBcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIEdldCBhbGwgZmllbGRzIGZvciBhbiBvYmplY3RcbiAgICAgKiBjb25zdCBmaWVsZHMgPSBtZXRhZGF0YVV0aWxzLmdldEFwcEZpZWxkc0J5QXBwT2JqZWN0KCdiNDg4N2Q0ZC1iYjFlLTRkNTItYTdlOC0yZjk0M2Q2OWU0NGMnIG9yICdUQUJNRF9TWVNURU0nKTtcbiAgICAgKiBcbiAgICAgKiAvLyBHZXQgb25seSByZXF1aXJlZCBmaWVsZHNcbiAgICAgKiBjb25zdCByZXF1aXJlZEZpZWxkcyA9IG1ldGFkYXRhVXRpbHMuZ2V0QXBwRmllbGRzQnlBcHBPYmplY3QoXG4gICAgICogICAnYjQ4ODdkNGQtYmIxZS00ZDUyLWE3ZTgtMmY5NDNkNjllNDRjJyxcbiAgICAgKiAgIGZpZWxkID0+IGZpZWxkLklzUmVxdWlyZWQgPT09IHRydWVcbiAgICAgKiApO1xuICAgICAqL1xuICAgIHB1YmxpYyBnZXRBcHBGaWVsZHNCeUFwcE9iamVjdChcbiAgICAgICAgYXBwT2JqZWN0OiBzdHJpbmcsXG4gICAgICAgIGZpbHRlckZuPzogKCh2YWx1ZTogQXBwRmllbGRzLCBpbmRleDogbnVtYmVyLCBhcnJheTogQXBwRmllbGRzW10pID0+IGJvb2xlYW4pLFxuICAgICAgICBjb2x1bW5zPzogc3RyaW5nW11cbiAgICApOiBhbnlbXSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBmaWx0ZXJlZEFwcE9iamVjdDogYW55ID0gdGhpcy5nZXRBcHBPYmplY3REZXRhaWxzKGFwcE9iamVjdCk7XG4gICAgICAgICAgICBpZiAoIWZpbHRlcmVkQXBwT2JqZWN0KSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgZmllbGRzID0gZmlsdGVyZWRBcHBPYmplY3QuRmllbGRzIHx8IFtdO1xuXG4gICAgICAgICAgICAvLyBBcHBseSBmaWx0ZXIgaWYgcHJvdmlkZWRcbiAgICAgICAgICAgIGlmIChmaWx0ZXJGbikge1xuICAgICAgICAgICAgICAgIGZpZWxkcyA9IGZpZWxkcy5maWx0ZXIoZmlsdGVyRm4pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXRSZXN1bHRzKGZpZWxkcywgY29sdW1ucyk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBpbiBnZXRBcHBGaWVsZEJ5SWQ6JywgZXJyb3IpO1xuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBHZXRzIGxvb2t1cCBmaWVsZHMgZm9yIGEgc3BlY2lmaWMgYXBwIG9iamVjdFxuICAgICogXG4gICAgKiBAcGFyYW0gYXBwT2JqZWN0IElEIG9yIE5hbWUgb2YgdGhlIGFwcCBvYmplY3RcbiAgICAqIEBwYXJhbSBmaWx0ZXJGbiBPcHRpb25hbCBmaWx0ZXIgZnVuY3Rpb24gZm9yIGxvb2t1cCBmaWVsZHNcbiAgICAqIEBwYXJhbSBjb2x1bW5zIE9wdGlvbmFsIGNvbHVtbnMgdG8gaW5jbHVkZSBpbiB0aGUgcmVzdWx0XG4gICAgKiBAcmV0dXJucyBBcnJheSBvZiBsb29rdXAgZmllbGRzIGZvciB0aGUgc3BlY2lmaWVkIG9iamVjdFxuICAgICogXG4gICAgKiBAZXhhbXBsZVxuICAgICogLy8gR2V0IGFsbCBsb29rdXAgZmllbGRzIGZvciBhbiBvYmplY3RcbiAgICAqIGNvbnN0IGxvb2t1cEZpZWxkcyA9IG1ldGFkYXRhVXRpbHMuZ2V0TG9va3VwRmllbGRzQnlBcHBPYmplY3QoJ1RBQkRfQmx1ZXByaW50X1NMQVNjaGVtZXMnKTtcbiAgICAqIFxuICAgICogLy8gR2V0IHNwZWNpZmljIGxvb2t1cCBmaWVsZHNcbiAgICAqIGNvbnN0IGZpZWxkcyA9IG1ldGFkYXRhVXRpbHMuZ2V0TG9va3VwRmllbGRzQnlBcHBPYmplY3QoXG4gICAgKiAgICdiNDg4N2Q0ZC1iYjFlLTRkNTItYTdlOC0yZjk0M2Q2OWU0NGMnLFxuICAgICogICBmaWVsZCA9PiBmaWVsZC5Jc1JlcXVpcmVkID09PSB0cnVlXG4gICAgKiApO1xuICAgICovXG4gICAgcHVibGljIGdldExvb2t1cEZpZWxkc0J5QXBwT2JqZWN0KFxuICAgICAgICBhcHBPYmplY3Q6IHN0cmluZyxcbiAgICAgICAgZmlsdGVyRm4/OiAoKHZhbHVlOiBBcHBGaWVsZHMpID0+IGJvb2xlYW4pLFxuICAgICAgICBjb2x1bW5zPzogc3RyaW5nW11cbiAgICApOiBhbnlbXSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBHZXQgZmllbGRzIGZvciB0aGUgc3BlY2lmaWVkIG9iamVjdCB0aGF0IGFyZSBsb29rdXBzXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBcHBGaWVsZHNCeUFwcE9iamVjdChcbiAgICAgICAgICAgICAgICBhcHBPYmplY3QsXG4gICAgICAgICAgICAgICAgZmllbGQgPT4ge1xuICAgICAgICAgICAgICAgICAgICAvLyBDaGVjayBpZiB0aGUgZmllbGQgaXMgYSBsb29rdXAgdHlwZVxuICAgICAgICAgICAgICAgICAgICBjb25zdCBpc0xvb2t1cCA9IGZpZWxkLkxvb2tVcERldGFpbHMgIT0gbnVsbDtcblxuICAgICAgICAgICAgICAgICAgICAvLyBBcHBseSBhZGRpdGlvbmFsIHVzZXIgZmlsdGVyIGlmIHByb3ZpZGVkXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBpc0xvb2t1cCAmJiAoIWZpbHRlckZuIHx8IGZpbHRlckZuKGZpZWxkKSk7XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICBjb2x1bW5zXG4gICAgICAgICAgICApO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgaW4gZ2V0QXBwT2JqZWN0TG9va3VwRmllbGRzOicsIGVycm9yKTtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgZGF0YSBzb3VyY2UgcXVlcmllcyB3aXRoIGZpbHRlciBjcml0ZXJpYVxuICAgICAqIFxuICAgICAqIEBwYXJhbSBmaWx0ZXJGbiBPcHRpb25hbCBmaWx0ZXIgZnVuY3Rpb24gdG8gYXBwbHkgdG8gcXVlcmllc1xuICAgICAqIEBwYXJhbSBjb2x1bW5zIE9wdGlvbmFsIGNvbHVtbnMgdG8gaW5jbHVkZSBpbiB0aGUgcmVzdWx0XG4gICAgICogQHJldHVybnMgQXJyYXkgb2YgZmlsdGVyZWQgZGF0YSBzb3VyY2UgcXVlcmllc1xuICAgICAqIFxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gR2V0IGFsbCBxdWVyaWVzIHdpdGggYSBzcGVjaWZpYyBuYW1pbmcgcGF0dGVyblxuICAgICAqIGNvbnN0IHF1ZXJpZXMgPSBtZXRhZGF0YVV0aWxzLmdldERhdGFTb3VyY2VRdWVyaWVzKHF1ZXJ5ID0+IHF1ZXJ5LlF1ZXJ5TmFtZS5pbmNsdWRlcygnTGlzdCcpKTtcbiAgICAgKiBcbiAgICAgKiAvLyBHZXQgc3BlY2lmaWMgY29sdW1ucyBmcm9tIGFsbCBxdWVyaWVzXG4gICAgICogY29uc3QgcXVlcmllcyA9IG1ldGFkYXRhVXRpbHMuZ2V0RGF0YVNvdXJjZVF1ZXJpZXMoXG4gICAgICogICB1bmRlZmluZWQsIFxuICAgICAqICAgWydJRCcsICdRdWVyeU5hbWUnLCAnRGlzcGxheU5hbWUnXVxuICAgICAqICk7XG4gICAgICovXG4gICAgcHVibGljIGdldERhdGFTb3VyY2VRdWVyaWVzKGZpbHRlckZuPzogKCh2YWx1ZTogRGF0YVNvdXJjZVF1ZXJpZXMpID0+IGJvb2xlYW4pLCBjb2x1bW5zPzogc3RyaW5nW10pOiBhbnlbXSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBHZXQgYWxsIGRhdGEgc291cmNlIHF1ZXJpZXMgZnJvbSBhbGwgYXBwIG9iamVjdHNcbiAgICAgICAgICAgIGNvbnN0IGFsbFF1ZXJpZXM6IERhdGFTb3VyY2VRdWVyaWVzW10gPSBbXTtcbiAgICAgICAgICAgIENvbW1vbi50YWJKc29uLkFwcE9iamVjdHMuZm9yRWFjaCgob2JqOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAob2JqLkRhdGFTb3VyY2VRdWVyaWVzICYmIG9iai5EYXRhU291cmNlUXVlcmllcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIGFsbFF1ZXJpZXMucHVzaCguLi5vYmouRGF0YVNvdXJjZVF1ZXJpZXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAvLyBBcHBseSBmaWx0ZXIgaWYgcHJvdmlkZWRcbiAgICAgICAgICAgIGxldCBmaWx0ZXJlZFF1ZXJpZXMgPSBhbGxRdWVyaWVzO1xuICAgICAgICAgICAgaWYgKGZpbHRlckZuKSB7XG4gICAgICAgICAgICAgICAgZmlsdGVyZWRRdWVyaWVzID0gYWxsUXVlcmllcy5maWx0ZXIoZmlsdGVyRm4pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXRSZXN1bHRzKGZpbHRlcmVkUXVlcmllcywgY29sdW1ucyk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBpbiBnZXREYXRhU291cmNlUXVlcmllczonLCBlcnJvcik7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIGRhdGEgc291cmNlIHF1ZXJpZXMgZm9yIGEgc3BlY2lmaWMgYXBwIG9iamVjdFxuICAgICAqIFxuICAgICAqIEBwYXJhbSBhcHBPYmplY3QgSUQgb3IgTmFtZSBvZiB0aGUgYXBwIG9iamVjdFxuICAgICAqIEBwYXJhbSBmaWx0ZXJGbiBPcHRpb25hbCBmaWx0ZXIgZnVuY3Rpb24gZm9yIHF1ZXJpZXNcbiAgICAgKiBAcGFyYW0gY29sdW1ucyBPcHRpb25hbCBjb2x1bW5zIHRvIGluY2x1ZGUgaW4gdGhlIHJlc3VsdFxuICAgICAqIEByZXR1cm5zIEFycmF5IG9mIHF1ZXJpZXMgZm9yIHRoZSBzcGVjaWZpZWQgb2JqZWN0XG4gICAgICogXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBHZXQgYWxsIHF1ZXJpZXMgZm9yIGFuIG9iamVjdFxuICAgICAqIGNvbnN0IHF1ZXJpZXMgPSBtZXRhZGF0YVV0aWxzLmdldERhdGFTb3VyY2VRdWVyaWVzQnlBcHBPYmplY3QoJ2I0ODg3ZDRkLWJiMWUtNGQ1Mi1hN2U4LTJmOTQzZDY5ZTQ0YycpO1xuICAgICAqIFxuICAgICAqIC8vIEdldCBxdWVyaWVzIHdpdGggc3BlY2lmaWMgcGF0dGVyblxuICAgICAqIGNvbnN0IGZpbHRlcmVkUXVlcmllcyA9IG1ldGFkYXRhVXRpbHMuZ2V0RGF0YVNvdXJjZVF1ZXJpZXNCeUFwcE9iamVjdChcbiAgICAgKiAgICdUQUJEX0JsdWVwcmludF9TTEFTY2hlbWVzJyxcbiAgICAgKiAgIHF1ZXJ5ID0+IHF1ZXJ5LlF1ZXJ5TmFtZS5pbmNsdWRlcygnTGlzdCcpXG4gICAgICogKTtcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0RGF0YVNvdXJjZVF1ZXJpZXNCeUFwcE9iamVjdChcbiAgICAgICAgYXBwT2JqZWN0OiBzdHJpbmcsXG4gICAgICAgIGZpbHRlckZuPzogKCh2YWx1ZTogRGF0YVNvdXJjZVF1ZXJpZXMpID0+IGJvb2xlYW4pLFxuICAgICAgICBjb2x1bW5zPzogc3RyaW5nW11cbiAgICApOiBhbnlbXSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBjb25zdCBmaWx0ZXJlZEFwcE9iamVjdDogYW55ID0gdGhpcy5nZXRBcHBPYmplY3REZXRhaWxzKGFwcE9iamVjdCk7XG4gICAgICAgICAgICBpZiAoIWZpbHRlcmVkQXBwT2JqZWN0IHx8ICFmaWx0ZXJlZEFwcE9iamVjdC5EYXRhU291cmNlUXVlcmllcykge1xuICAgICAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IHF1ZXJpZXMgPSBmaWx0ZXJlZEFwcE9iamVjdC5EYXRhU291cmNlUXVlcmllcztcblxuICAgICAgICAgICAgLy8gQXBwbHkgZmlsdGVyIGlmIHByb3ZpZGVkXG4gICAgICAgICAgICBpZiAoZmlsdGVyRm4pIHtcbiAgICAgICAgICAgICAgICBxdWVyaWVzID0gcXVlcmllcy5maWx0ZXIoZmlsdGVyRm4pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXRSZXN1bHRzKHF1ZXJpZXMsIGNvbHVtbnMpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgaW4gZ2V0QXBwT2JqZWN0UXVlcmllczonLCBlcnJvcik7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIGEgc3BlY2lmaWMgRGF0YSBTb3VyY2UgUXVlcnkgYnkgSUQgb3IgTmFtZVxuICAgICAqIFxuICAgICAqIEBwYXJhbSBxdWVyeSBJRCBvciBOYW1lIG9mIHRoZSBkYXRhIHNvdXJjZSBxdWVyeSB0byByZXRyaWV2ZVxuICAgICAqIEBwYXJhbSBjb2x1bW5zIE9wdGlvbmFsIGNvbHVtbnMgdG8gaW5jbHVkZSBpbiB0aGUgcmVzdWx0XG4gICAgICogQHJldHVybnMgVGhlIGRhdGEgc291cmNlIHF1ZXJ5IHdpdGggc3BlY2lmaWVkIGNvbHVtbnMgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKiBcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIEdldCBhIHNwZWNpZmljIHF1ZXJ5IHdpdGggYWxsIHByb3BlcnRpZXNcbiAgICAgKiBjb25zdCBxdWVyeSA9IG1ldGFkYXRhVXRpbHMuZ2V0RGF0YVNvdXJjZVF1ZXJ5RGV0YWlscygnNzNlNTkwZDAtYzRlYi00NjRkLWFiZjktMDE5NDNlMzBhZTA5Jyk7XG4gICAgICogXG4gICAgICogLy8gR2V0IHNwZWNpZmljIGNvbHVtbnMgZnJvbSBhIHF1ZXJ5IGJ5IG5hbWVcbiAgICAgKiBjb25zdCBxdWVyeSA9IG1ldGFkYXRhVXRpbHMuZ2V0RGF0YVNvdXJjZVF1ZXJ5RGV0YWlscyhcbiAgICAgKiAgICdHZXRfU0xBU2NoZW1lc19MaXN0JyxcbiAgICAgKiAgIFsnSUQnLCAnUXVlcnlOYW1lJywgJ0Rpc3BsYXlOYW1lJ11cbiAgICAgKiApO1xuICAgICAqL1xuICAgIHB1YmxpYyBnZXREYXRhU291cmNlUXVlcnlEZXRhaWxzKHF1ZXJ5OiBzdHJpbmcsIGNvbHVtbnM/OiBzdHJpbmdbXSk6IGFueSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5nZXREYXRhU291cmNlUXVlcmllcyhxID0+XG4gICAgICAgICAgICAgICAgcS5JRD8udG9Mb3dlckNhc2UoKSA9PT0gcXVlcnk/LnRvTG93ZXJDYXNlKCkgfHwgcS5RdWVyeU5hbWUgPT09IHF1ZXJ5LFxuICAgICAgICAgICAgICAgIGNvbHVtbnNcbiAgICAgICAgICAgICk/LlswXSA/PyBudWxsO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignRXJyb3IgaW4gZ2V0RGF0YVNvdXJjZVF1ZXJ5OicsIGVycm9yKTtcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyBmaWVsZHMgZnJvbSBhIGRhdGEgc291cmNlIHF1ZXJ5XG4gICAgICogXG4gICAgICogQHBhcmFtIHF1ZXJ5IElEIG9yIE5hbWUgb2YgdGhlIGRhdGEgc291cmNlIHF1ZXJ5XG4gICAgICogQHBhcmFtIGZpbHRlckZuIE9wdGlvbmFsIGZpbHRlciBmdW5jdGlvbiBmb3IgcXVlcnkgZmllbGRzXG4gICAgICogQHBhcmFtIGNvbHVtbnMgT3B0aW9uYWwgY29sdW1ucyB0byBpbmNsdWRlIGluIHRoZSByZXN1bHRcbiAgICAgKiBAcmV0dXJucyBBcnJheSBvZiBmaWVsZHMgZm9yIHRoZSBzcGVjaWZpZWQgcXVlcnkgd2l0aCBhcHAgZmllbGQgZGV0YWlsc1xuICAgICAqIFxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gR2V0IGFsbCBmaWVsZHMgZm9yIGEgcXVlcnlcbiAgICAgKiBjb25zdCBxdWVyeUZpZWxkcyA9IG1ldGFkYXRhVXRpbHMuZ2V0RGF0YVNvdXJjZVF1ZXJ5RmllbGRzKCc3M2U1OTBkMC1jNGViLTQ2NGQtYWJmOS0wMTk0M2UzMGFlMDknKTtcbiAgICAgKiBcbiAgICAgKiAvLyBHZXQgZmllbGRzIGZvciBhIHF1ZXJ5IGJ5IG5hbWVcbiAgICAgKiBjb25zdCBxdWVyeUZpZWxkcyA9IG1ldGFkYXRhVXRpbHMuZ2V0RGF0YVNvdXJjZVF1ZXJ5RmllbGRzKCdHZXRfU0xBU2NoZW1lc19MaXN0Jyk7XG4gICAgICogXG4gICAgICogLy8gR2V0IGZpZWxkcyB3aXRoIGZpbHRlciBhbmQgc3BlY2lmaWMgY29sdW1uc1xuICAgICAqIGNvbnN0IGZpZWxkcyA9IG1ldGFkYXRhVXRpbHMuZ2V0RGF0YVNvdXJjZVF1ZXJ5RmllbGRzKFxuICAgICAqICAgJzczZTU5MGQwLWM0ZWItNDY0ZC1hYmY5LTAxOTQzZTMwYWUwOScsXG4gICAgICogICBmaWVsZCA9PiBmaWVsZC5GaWVsZFR5cGUgPT09IDEsXG4gICAgICogICBbJ0lEJywgJ0FwcEZpZWxkSUQnLCAnRmllbGRUeXBlJ11cbiAgICAgKiApO1xuICAgICAqL1xuICAgIHB1YmxpYyBnZXRGaWVsZHNCeURTUShcbiAgICAgICAgcXVlcnk6IHN0cmluZyxcbiAgICAgICAgZmlsdGVyRm4/OiAoKHZhbHVlOiBEYXRhU291cmNlUXVlcmllc19GaWVsZHMpID0+IGJvb2xlYW4pLFxuICAgICAgICBjb2x1bW5zPzogc3RyaW5nW11cbiAgICApOiBhbnlbXSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAvLyBGaW5kIHRoZSBxdWVyeSB1c2luZyBvdXIgZXhpc3RpbmcgbWV0aG9kXG4gICAgICAgICAgICBjb25zdCBkc1F1ZXJ5ID0gdGhpcy5nZXREYXRhU291cmNlUXVlcnlEZXRhaWxzKHF1ZXJ5KTtcbiAgICAgICAgICAgIGlmICghZHNRdWVyeSB8fCAhZHNRdWVyeS5GaWVsZHM/Lmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gR2V0IGVuaGFuY2VkIGZpZWxkcyB3aXRoIGFwcCBmaWVsZCBkZXRhaWxzXG4gICAgICAgICAgICBsZXQgcXVlcnlGaWVsZHMgPSB0aGlzLmVuaGFuY2VRdWVyeUZpZWxkc1dpdGhBcHBGaWVsZHMoZHNRdWVyeSk7XG5cbiAgICAgICAgICAgIC8vIEFwcGx5IGZpbHRlciBpZiBwcm92aWRlZFxuICAgICAgICAgICAgaWYgKGZpbHRlckZuKSB7XG4gICAgICAgICAgICAgICAgcXVlcnlGaWVsZHMgPSBxdWVyeUZpZWxkcy5maWx0ZXIoZmlsdGVyRm4pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXRSZXN1bHRzKHF1ZXJ5RmllbGRzLCBjb2x1bW5zKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGluIGdldERhdGFTb3VyY2VRdWVyeUZpZWxkczonLCBlcnJvcik7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFbmhhbmNlcyBxdWVyeSBmaWVsZHMgd2l0aCB0aGVpciBjb3JyZXNwb25kaW5nIGFwcCBmaWVsZCBkZXRhaWxzXG4gICAgICogQHByaXZhdGVcbiAgICAgKi9cbiAgICBwcml2YXRlIGVuaGFuY2VRdWVyeUZpZWxkc1dpdGhBcHBGaWVsZHMoZHNRdWVyeTogRGF0YVNvdXJjZVF1ZXJpZXMpOiBhbnlbXSB7XG4gICAgICAgIGlmICghZHNRdWVyeSB8fCAhZHNRdWVyeS5GaWVsZHM/Lmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gRmluZCB0aGUgcGFyZW50IGFwcCBvYmplY3RcbiAgICAgICAgY29uc3QgcGFyZW50QXBwT2JqZWN0ID0gdGhpcy5maW5kUGFyZW50QXBwT2JqZWN0Rm9yUXVlcnkoZHNRdWVyeSk7XG4gICAgICAgIGlmICghcGFyZW50QXBwT2JqZWN0KSB7XG4gICAgICAgICAgICByZXR1cm4gZHNRdWVyeS5GaWVsZHM7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBBZGQgYXBwIGZpZWxkIGRldGFpbHMgdG8gZWFjaCBxdWVyeSBmaWVsZFxuICAgICAgICByZXR1cm4gZHNRdWVyeS5GaWVsZHMubWFwKChmaWVsZDogYW55KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhcHBGaWVsZCA9IHRoaXMuZmluZEFwcEZpZWxkQnlJZChwYXJlbnRBcHBPYmplY3QsIGZpZWxkLkFwcEZpZWxkSUQpO1xuICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAuLi5maWVsZCxcbiAgICAgICAgICAgICAgICBGaWVsZDogYXBwRmllbGQgfHwge31cbiAgICAgICAgICAgIH07XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEZpbmRzIHRoZSBwYXJlbnQgYXBwIG9iamVjdCB0aGF0IGNvbnRhaW5zIGEgc3BlY2lmaWMgZGF0YSBzb3VyY2UgcXVlcnlcbiAgICAgKiBAcHJpdmF0ZVxuICAgICAqL1xuICAgIHByaXZhdGUgZmluZFBhcmVudEFwcE9iamVjdEZvclF1ZXJ5KGRzUXVlcnk6IERhdGFTb3VyY2VRdWVyaWVzKTogQXBwT2JqZWN0IHwgdW5kZWZpbmVkIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXBwT2JqZWN0cyhvYmogPT5cbiAgICAgICAgICAgIG9iai5EYXRhU291cmNlUXVlcmllcz8uc29tZSgocTogYW55KSA9PlxuICAgICAgICAgICAgICAgIHEuSUQ/LnRvTG93ZXJDYXNlKCkgPT09IGRzUXVlcnkuSUQ/LnRvTG93ZXJDYXNlKCkgfHxcbiAgICAgICAgICAgICAgICBxLlF1ZXJ5TmFtZSA9PT0gZHNRdWVyeS5RdWVyeU5hbWVcbiAgICAgICAgICAgIClcbiAgICAgICAgKVswXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBGaW5kcyBhbiBhcHAgZmllbGQgYnkgSUQgd2l0aGluIGEgc3BlY2lmaWMgYXBwIG9iamVjdFxuICAgICAqIEBwcml2YXRlXG4gICAgICovXG4gICAgcHJpdmF0ZSBmaW5kQXBwRmllbGRCeUlkKGFwcE9iamVjdDogQXBwT2JqZWN0LCBmaWVsZElkOiBzdHJpbmcpOiBhbnkge1xuICAgICAgICBpZiAoIWFwcE9iamVjdCB8fCAhYXBwT2JqZWN0LkZpZWxkcz8ubGVuZ3RoIHx8ICFmaWVsZElkKSB7XG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGFwcE9iamVjdC5GaWVsZHMuZmluZChcbiAgICAgICAgICAgIChmaWVsZDogYW55KSA9PiBmaWVsZC5JRD8udG9Mb3dlckNhc2UoKSA9PT0gZmllbGRJZD8udG9Mb3dlckNhc2UoKVxuICAgICAgICApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgcXVlcnkgcGFyYW1ldGVycyBmcm9tIGEgZGF0YSBzb3VyY2UgcXVlcnlcbiAgICAgKiBcbiAgICAgKiBAcGFyYW0gcXVlcnkgSUQgb3IgTmFtZSBvZiB0aGUgZGF0YSBzb3VyY2UgcXVlcnlcbiAgICAgKiBAcGFyYW0gZmlsdGVyRm4gT3B0aW9uYWwgZmlsdGVyIGZ1bmN0aW9uIGZvciBxdWVyeSBwYXJhbWV0ZXJzXG4gICAgICogQHBhcmFtIGNvbHVtbnMgT3B0aW9uYWwgY29sdW1ucyB0byBpbmNsdWRlIGluIHRoZSByZXN1bHRcbiAgICAgKiBAcmV0dXJucyBBcnJheSBvZiBwYXJhbWV0ZXJzIGZvciB0aGUgc3BlY2lmaWVkIHF1ZXJ5XG4gICAgICogXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBHZXQgYWxsIHBhcmFtZXRlcnMgZm9yIGEgcXVlcnlcbiAgICAgKiBjb25zdCBxdWVyeVBhcmFtcyA9IG1ldGFkYXRhVXRpbHMuZ2V0UGFyYW1ldGVyc0J5RFNRKCc3M2U1OTBkMC1jNGViLTQ2NGQtYWJmOS0wMTk0M2UzMGFlMDknKTtcbiAgICAgKiBcbiAgICAgKiAvLyBHZXQgYWxsIHBhcmFtZXRlcnMgZm9yIGEgcXVlcnkgYnkgbmFtZVxuICAgICAqIGNvbnN0IHF1ZXJ5UGFyYW1zID0gbWV0YWRhdGFVdGlscy5nZXRQYXJhbWV0ZXJzQnlEU1EoJ0dldF9TTEFTY2hlbWVzX0xpc3QnKTtcbiAgICAgKiBcbiAgICAgKiAvLyBHZXQgbWFuZGF0b3J5IHBhcmFtZXRlcnMgb25seVxuICAgICAqIGNvbnN0IG1hbmRhdG9yeVBhcmFtcyA9IG1ldGFkYXRhVXRpbHMuZ2V0UGFyYW1ldGVyc0J5RFNRKFxuICAgICAqICAgJzczZTU5MGQwLWM0ZWItNDY0ZC1hYmY5LTAxOTQzZTMwYWUwOScsXG4gICAgICogICBwYXJhbSA9PiBwYXJhbS5Jc01hbmRhdG9yeSA9PT0gdHJ1ZVxuICAgICAqICk7XG4gICAgICovXG4gICAgcHVibGljIGdldFBhcmFtZXRlcnNCeURTUShcbiAgICAgICAgcXVlcnk6IHN0cmluZyxcbiAgICAgICAgZmlsdGVyRm4/OiAoKHZhbHVlOiBQYXJhbWV0ZXJzKSA9PiBib29sZWFuKSxcbiAgICAgICAgY29sdW1ucz86IHN0cmluZ1tdXG4gICAgKTogYW55W10ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgLy8gRmluZCB0aGUgcXVlcnkgdXNpbmcgb3VyIGV4aXN0aW5nIG1ldGhvZFxuICAgICAgICAgICAgY29uc3QgZHNRdWVyeSA9IHRoaXMuZ2V0RGF0YVNvdXJjZVF1ZXJ5RGV0YWlscyhxdWVyeSk7XG4gICAgICAgICAgICBpZiAoIWRzUXVlcnkgfHwgIWRzUXVlcnkuUGFyYW1ldGVycz8ubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgcXVlcnlQYXJhbWV0ZXJzOiBQYXJhbWV0ZXJzW10gPSBkc1F1ZXJ5LlBhcmFtZXRlcnMgfHwgW107XG5cbiAgICAgICAgICAgIC8vIEFwcGx5IGZpbHRlciBpZiBwcm92aWRlZFxuICAgICAgICAgICAgaWYgKGZpbHRlckZuKSB7XG4gICAgICAgICAgICAgICAgcXVlcnlQYXJhbWV0ZXJzID0gcXVlcnlQYXJhbWV0ZXJzLmZpbHRlcihmaWx0ZXJGbik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzLmZvcm1hdFJlc3VsdHMocXVlcnlQYXJhbWV0ZXJzLCBjb2x1bW5zKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGluIGdldERhdGFTb3VyY2VRdWVyeVBhcmFtZXRlcnM6JywgZXJyb3IpO1xuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgKiBHZXRzIEFwcCBTY3JlZW5zIHdpdGggZmlsdGVyIGNyaXRlcmlhXG4gICAgKiBcbiAgICAqIEBwYXJhbSBmaWx0ZXJGbiBPcHRpb25hbCBmaWx0ZXIgZnVuY3Rpb24gdG8gYXBwbHkgdG8gYXBwIHNjcmVlbnNcbiAgICAqIEBwYXJhbSBjb2x1bW5zIE9wdGlvbmFsIGNvbHVtbnMgdG8gaW5jbHVkZSBpbiB0aGUgcmVzdWx0XG4gICAgKiBAcmV0dXJucyBBcnJheSBvZiBmaWx0ZXJlZCBhcHAgc2NyZWVuc1xuICAgICogXG4gICAgKiBAZXhhbXBsZVxuICAgICogLy8gR2V0IGFsbCBzeXN0ZW0gc2NyZWVuc1xuICAgICogY29uc3Qgc3lzdGVtU2NyZWVucyA9IG1ldGFkYXRhVXRpbHMuZ2V0QXBwU2NyZWVucyhzY3JlZW4gPT4gc2NyZWVuLklzU3lzdGVtUmVjb3JkID09PSB0cnVlKTtcbiAgICAqIFxuICAgICogLy8gR2V0IHNwZWNpZmljIGNvbHVtbnMgZnJvbSBhbGwgc2NyZWVuc1xuICAgICogY29uc3Qgc2NyZWVucyA9IG1ldGFkYXRhVXRpbHMuZ2V0QXBwU2NyZWVucyhcbiAgICAqICAgdW5kZWZpbmVkLCBcbiAgICAqICAgWydJRCcsICdOYW1lJywgJ1NjcmVlblR5cGUnXVxuICAgICogKTtcbiAgICAqL1xuICAgIHB1YmxpYyBnZXRBcHBTY3JlZW5zKGZpbHRlckZuPzogKCh2YWx1ZTogQXBwU2NyZWVuKSA9PiBib29sZWFuKSwgY29sdW1ucz86IHN0cmluZ1tdKTogYW55W10ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbGV0IGFwcFNjcmVlbnMgPSBDb21tb24udGFiSnNvbi5BcHBTY3JlZW5zIHx8IFtdO1xuXG4gICAgICAgICAgICAvLyBBcHBseSBmaWx0ZXIgaWYgcHJvdmlkZWRcbiAgICAgICAgICAgIGlmIChmaWx0ZXJGbikge1xuICAgICAgICAgICAgICAgIGFwcFNjcmVlbnMgPSBhcHBTY3JlZW5zLmZpbHRlcihmaWx0ZXJGbik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzLmZvcm1hdFJlc3VsdHMoYXBwU2NyZWVucywgY29sdW1ucyk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBpbiBnZXRBcHBTY3JlZW5zOicsIGVycm9yKTtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgYSBzcGVjaWZpYyBBcHAgU2NyZWVuIGJ5IElEIG9yIE5hbWVcbiAgICAgKiBcbiAgICAgKiBAcGFyYW0gc2NyZWVuIElEIG9yIE5hbWUgb2YgdGhlIGFwcCBzY3JlZW4gdG8gcmV0cmlldmVcbiAgICAgKiBAcGFyYW0gY29sdW1ucyBPcHRpb25hbCBjb2x1bW5zIHRvIGluY2x1ZGUgaW4gdGhlIHJlc3VsdFxuICAgICAqIEByZXR1cm5zIFRoZSBhcHAgc2NyZWVuIHdpdGggc3BlY2lmaWVkIGNvbHVtbnMgb3IgbnVsbCBpZiBub3QgZm91bmRcbiAgICAgKiBcbiAgICAgKiBAZXhhbXBsZVxuICAgICAqIC8vIEdldCBhIHNwZWNpZmljIHNjcmVlbiB3aXRoIGFsbCBwcm9wZXJ0aWVzXG4gICAgICogY29uc3Qgc2NyZWVuID0gbWV0YWRhdGFVdGlscy5nZXRBcHBTY3JlZW4oJ2E1Y2Q2MzllLTMxYmEtNGQzMy04ODAwLTAwNWE1MjQ4ZGZiMicpO1xuICAgICAqIFxuICAgICAqIC8vIEdldCBzcGVjaWZpYyBjb2x1bW5zIGZyb20gYSBzY3JlZW4gYnkgbmFtZVxuICAgICAqIGNvbnN0IHNjcmVlbiA9IG1ldGFkYXRhVXRpbHMuZ2V0QXBwU2NyZWVuKFxuICAgICAqICAgJ05ldyBEZXRhaWwgUm9sZS9QZXJtaXNzaW9uIEFwcG9qZWN0IGFjZXNzIHdpc2UnLFxuICAgICAqICAgWydJRCcsICdOYW1lJywgJ1NjcmVlblR5cGUnXVxuICAgICAqICk7XG4gICAgICovXG4gICAgcHVibGljIGdldEFwcFNjcmVlbihzY3JlZW46IHN0cmluZywgY29sdW1ucz86IHN0cmluZ1tdKTogYW55IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEFwcFNjcmVlbnMoc2NyID0+XG4gICAgICAgICAgICAgICAgc2NyLklEPy50b0xvd2VyQ2FzZSgpID09PSBzY3JlZW4/LnRvTG93ZXJDYXNlKCkgfHwgc2NyLk5hbWUgPT09IHNjcmVlbixcbiAgICAgICAgICAgICAgICBjb2x1bW5zXG4gICAgICAgICAgICApPy5bMF0gPz8gbnVsbDtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGluIGdldEFwcFNjcmVlbjonLCBlcnJvcik7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgQXBwIE1lbnVzIHdpdGggZmlsdGVyIGNyaXRlcmlhXG4gICAgICogXG4gICAgICogQHBhcmFtIGZpbHRlckZuIE9wdGlvbmFsIGZpbHRlciBmdW5jdGlvbiB0byBhcHBseSB0byBhcHAgbWVudXNcbiAgICAgKiBAcGFyYW0gY29sdW1ucyBPcHRpb25hbCBjb2x1bW5zIHRvIGluY2x1ZGUgaW4gdGhlIHJlc3VsdFxuICAgICAqIEByZXR1cm5zIEFycmF5IG9mIGZpbHRlcmVkIGFwcCBtZW51c1xuICAgICAqIFxuICAgICAqIEBleGFtcGxlXG4gICAgICogLy8gR2V0IGFsbCB0b3AtbGV2ZWwgbWVudXNcbiAgICAgKiBjb25zdCB0b3BNZW51cyA9IG1ldGFkYXRhVXRpbHMuZ2V0QXBwTWVudXMobWVudSA9PiAhbWVudS5QYXJlbnRJRCk7XG4gICAgICogXG4gICAgICogLy8gR2V0IHNwZWNpZmljIGNvbHVtbnMgZnJvbSBhbGwgbWVudXNcbiAgICAgKiBjb25zdCBtZW51cyA9IG1ldGFkYXRhVXRpbHMuZ2V0QXBwTWVudXMoXG4gICAgICogICB1bmRlZmluZWQsIFxuICAgICAqICAgWydJRCcsICdNZW51TmFtZScsICdEaXNwbGF5TmFtZScsICdTY3JlZW5JRCddXG4gICAgICogKTtcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0QXBwTWVudXMoZmlsdGVyRm4/OiAoKHZhbHVlOiBBcHBNZW51KSA9PiBib29sZWFuKSwgY29sdW1ucz86IHN0cmluZ1tdKTogYW55W10ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgbGV0IGFwcE1lbnVzID0gQ29tbW9uLnRhYkpzb24uQXBwTWVudXMgfHwgW107XG5cbiAgICAgICAgICAgIC8vIEFwcGx5IGZpbHRlciBpZiBwcm92aWRlZFxuICAgICAgICAgICAgaWYgKGZpbHRlckZuKSB7XG4gICAgICAgICAgICAgICAgYXBwTWVudXMgPSBhcHBNZW51cy5maWx0ZXIoZmlsdGVyRm4pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5mb3JtYXRSZXN1bHRzKGFwcE1lbnVzLCBjb2x1bW5zKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGluIGdldEFwcE1lbnVzOicsIGVycm9yKTtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgb3JnYW5pemF0aW9uIGluZm9ybWF0aW9uIHdpdGggZmlsdGVyIGNyaXRlcmlhXG4gICAgICogXG4gICAgICogQHBhcmFtIGZpbHRlckZuIE9wdGlvbmFsIGZpbHRlciBmdW5jdGlvbiB0byBhcHBseSB0byBvcmdhbml6YXRpb25zXG4gICAgICogQHBhcmFtIGNvbHVtbnMgT3B0aW9uYWwgY29sdW1ucyB0byBpbmNsdWRlIGluIHRoZSByZXN1bHRcbiAgICAgKiBAcmV0dXJucyBBcnJheSBvZiBmaWx0ZXJlZCBvcmdhbml6YXRpb25zXG4gICAgICogXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBHZXQgYWxsIG9yZ2FuaXphdGlvbnNcbiAgICAgKiBjb25zdCBvcmdzID0gbWV0YWRhdGFVdGlscy5nZXRPcmdzKCk7XG4gICAgICogXG4gICAgICogLy8gR2V0IG9yZ2FuaXphdGlvbnMgd2l0aCBzcGVjaWZpYyBzdWJkb21haW4gcGF0dGVyblxuICAgICAqIGNvbnN0IHNwZWNpZmljT3JncyA9IG1ldGFkYXRhVXRpbHMuZ2V0T3JncyhcbiAgICAgKiAgIG9yZyA9PiBvcmcuU3ViZG9tYWluPy5pbmNsdWRlcygndGVzdCcpXG4gICAgICogKTtcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0T3JncyhmaWx0ZXJGbj86ICgodmFsdWU6IE9yZ0luZm8pID0+IGJvb2xlYW4pLCBjb2x1bW5zPzogc3RyaW5nW10pOiBhbnlbXSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsZXQgb3JnYW5pemF0aW9ucyA9IENvbW1vbi50YWJKc29uLk9yZ0luZm9zIHx8IFtdO1xuXG4gICAgICAgICAgICAvLyBBcHBseSBmaWx0ZXIgaWYgcHJvdmlkZWRcbiAgICAgICAgICAgIGlmIChmaWx0ZXJGbikge1xuICAgICAgICAgICAgICAgIG9yZ2FuaXphdGlvbnMgPSBvcmdhbml6YXRpb25zLmZpbHRlcihmaWx0ZXJGbik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0aGlzLmZvcm1hdFJlc3VsdHMob3JnYW5pemF0aW9ucywgY29sdW1ucyk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBpbiBnZXRPcmdhbml6YXRpb25zOicsIGVycm9yKTtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgYSBzcGVjaWZpYyBvcmdhbml6YXRpb24gYnkgSUQgb3IgTmFtZVxuICAgICAqIFxuICAgICAqIEBwYXJhbSBvcmdhbml6YXRpb24gSUQgb3IgT3JnYW5pemF0aW9uTmFtZSBvZiB0aGUgb3JnYW5pemF0aW9uXG4gICAgICogQHBhcmFtIGNvbHVtbnMgT3B0aW9uYWwgY29sdW1ucyB0byBpbmNsdWRlIGluIHRoZSByZXN1bHRcbiAgICAgKiBAcmV0dXJucyBUaGUgb3JnYW5pemF0aW9uIG9yIG51bGwgaWYgbm90IGZvdW5kXG4gICAgICogXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiAvLyBHZXQgb3JnYW5pemF0aW9uIGJ5IElEXG4gICAgICogY29uc3Qgb3JnID0gbWV0YWRhdGFVdGlscy5nZXRPcmdJbmZvRGV0YWlscygnMGVjM2QwZjEtYjJlYy00N2I3LTgzMDUtYjc2N2QwZTVlYTYzJyk7XG4gICAgICogXG4gICAgICogLy8gR2V0IG9yZ2FuaXphdGlvbiBieSBuYW1lXG4gICAgICogY29uc3Qgb3JnID0gbWV0YWRhdGFVdGlscy5nZXRPcmdJbmZvRGV0YWlscygnU3F1YWRGb2N1cycpO1xuICAgICAqL1xuICAgIHB1YmxpYyBnZXRPcmdJbmZvRGV0YWlscyhvcmdhbml6YXRpb246IHN0cmluZywgY29sdW1ucz86IHN0cmluZ1tdKTogYW55IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldE9yZ3Mob3JnID0+XG4gICAgICAgICAgICAgICAgb3JnLklEPy50b0xvd2VyQ2FzZSgpID09PSBvcmdhbml6YXRpb24/LnRvTG93ZXJDYXNlKCkgfHxcbiAgICAgICAgICAgICAgICBvcmcuT3JnYW5pemF0aW9uTmFtZSA9PT0gb3JnYW5pemF0aW9uIHx8XG4gICAgICAgICAgICAgICAgb3JnLlN1YmRvbWFpbiA9PT0gb3JnYW5pemF0aW9uLFxuICAgICAgICAgICAgICAgIGNvbHVtbnNcbiAgICAgICAgICAgIClbMF0gfHwgbnVsbDtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGluIGdldE9yZ2FuaXphdGlvbjonLCBlcnJvcik7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cbn0iXX0=
214
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWV0YS1kYXRhLmhlbHBlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL2RhdGEtYWNjZXNzL3NyYy9saWIvdGFiLWNvcmUtdXRpbGl0eS9hcHAvaGVscGVycy9jb21tb24vbWV0YS1kYXRhLmhlbHBlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDaEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBRy9ELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUMvRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7O0FBRzFELE1BQU0sT0FBTyxjQUFjO0lBRDNCO1FBRVUsaUJBQVksR0FBRyxJQUFJLEdBQUcsRUFBaUMsQ0FBQztRQUN4RCxrQkFBYSxHQUE0QixJQUFJLENBQUM7UUFFOUMsaUJBQVksR0FBRyxJQUFJLEdBQUcsRUFBaUMsQ0FBQztRQUN4RCxrQkFBYSxHQUE0QixJQUFJLENBQUM7UUFFOUMsZUFBVSxHQUFHLElBQUksR0FBRyxFQUErQixDQUFDO1FBQ3BELGdCQUFXLEdBQTBCLElBQUksQ0FBQztLQTZRbkQ7SUEzUUM7Ozs7Ozs7Ozs7T0FVRztJQUNLLGtCQUFrQixDQUN4QixHQUEwQixFQUMxQixHQUFXLEVBQ1gsVUFBZSxFQUNmLE9BQTZCLEVBQzdCLFlBQTRCO1FBRTVCLElBQUksQ0FBQyxHQUFHO1lBQUUsT0FBTyxJQUFJLENBQUM7UUFDdEIsSUFBSSxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQztZQUFFLE9BQU8sR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENB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QyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7UUFDL0YsQ0FBQztRQUVELElBQUksWUFBWSxDQUFDLGtCQUFrQixDQUFDLG1CQUFtQixDQUFDLEVBQUUsQ0FBQztZQUN6RCw0REFBNEQ7WUFDNUQsTUFBTSxDQUFDLGtCQUFrQixDQUFDLG1CQUFtQixDQUFDLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBQy9HLENBQUM7UUFFRCxJQUFJLFlBQVksQ0FBQyxrQkFBa0IsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO1lBQ2pELG9EQUFvRDtZQUNwRCxNQUFNLENBQUMsa0JBQWtCLENBQUMsV0FBVyxDQUFDLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBQ3RHLENBQUM7UUFFRCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDOytFQXBSVSxjQUFjO3VFQUFkLGNBQWMsV0FBZCxjQUFjLG1CQURELE1BQU07O2lGQUNuQixjQUFjO2NBRDFCLFVBQVU7ZUFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IENvbW1vbiB9IGZyb20gXCIuLi8uLi9jb25zdGFudHMvY29tbW9uXCI7XG5pbXBvcnQgeyBBcHBPYmplY3RNb2RlbCB9IGZyb20gXCIuLi8uLi9tb2RlbHMvYXBwLW9iamVjdC5tb2RlbFwiO1xuaW1wb3J0IHsgQXBwRmllbGRNb2RlbCB9IGZyb20gXCIuLi8uLi9tb2RlbHMvYXBwLWZpZWxkLm1vZGVsXCI7XG5pbXBvcnQgeyBEYXRhU291cmNlUXVlcnlNb2RlbCB9IGZyb20gXCIuLi8uLi9tb2RlbHMvZGF0YS1zb3VyY2UtcXVlcnkubW9kZWxcIjtcbmltcG9ydCB7IE1ldGFkYXRhRW50aXR5VHlwZSB9IGZyb20gXCIuLi8uLi9pbnRlcmZhY2VzL3NjaGVtYS5pbnRlcmZhY2VcIjtcbmltcG9ydCB7IEFwcFNjcmVlbk1vZGVsIH0gZnJvbSBcIi4uLy4uL21vZGVscy9hcHAtc2NyZWVuLm1vZGVsXCI7XG5pbXBvcnQgeyBPcmdJbmZvTW9kZWwgfSBmcm9tIFwiLi4vLi4vbW9kZWxzL29yZ0luZm8ubW9kZWxcIjtcblxuQEluamVjdGFibGUoeyBwcm92aWRlZEluOiAncm9vdCcgfSlcbmV4cG9ydCBjbGFzcyBNZXRhZGF0YUhlbHBlciB7XG4gIHByaXZhdGUgYXBwT2JqZWN0TWFwID0gbmV3IE1hcDxzdHJpbmcsIEFwcE9iamVjdE1vZGVsIHwgbnVsbD4oKTtcbiAgcHJpdmF0ZSBhbGxBcHBPYmplY3RzOiBBcHBPYmplY3RNb2RlbFtdIHwgbnVsbCA9IG51bGw7XG5cbiAgcHJpdmF0ZSBhcHBTY3JlZW5NYXAgPSBuZXcgTWFwPHN0cmluZywgQXBwU2NyZWVuTW9kZWwgfCBudWxsPigpO1xuICBwcml2YXRlIGFsbEFwcFNjcmVlbnM6IEFwcFNjcmVlbk1vZGVsW10gfCBudWxsID0gbnVsbDtcblxuICBwcml2YXRlIG9yZ0luZm9NYXAgPSBuZXcgTWFwPHN0cmluZywgT3JnSW5mb01vZGVsIHwgbnVsbD4oKTtcbiAgcHJpdmF0ZSBhbGxPcmdJbmZvczogT3JnSW5mb01vZGVsW10gfCBudWxsID0gbnVsbDtcblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBrZXkgZnJvbSB0aGUgZ2l2ZW4gbWFwLlxuICAgKiBJZiB0aGUga2V5IGRvZXMgbm90IGV4aXN0IGluIHRoZSBtYXAsIGFuZCB0aGUgc291cmNlIGxpc3QgY29udGFpbnMgYW4gaXRlbSB0aGF0IG1hdGNoZXNcbiAgICogdGhlIGdpdmVuIGNvbmRpdGlvbiwgaXQgY3JlYXRlcyBhIG5ldyBtb2RlbCB1c2luZyB0aGUgZ2l2ZW4gbW9kZWwgZmFjdG9yeSBhbmQgYWRkcyBpdCB0byB0aGUgbWFwLlxuICAgKiBAcGFyYW0gbWFwIFRoZSBtYXAgdG8gc2VhcmNoIGluLlxuICAgKiBAcGFyYW0ga2V5IFRoZSBrZXkgdG8gc2VhcmNoIGZvci5cbiAgICogQHBhcmFtIHNvdXJjZUxpc3QgVGhlIGxpc3Qgb2YgaXRlbXMgdG8gc2VhcmNoIGluLlxuICAgKiBAcGFyYW0gbWF0Y2hGbiBUaGUgY29uZGl0aW9uIHRvIG1hdGNoLlxuICAgKiBAcGFyYW0gbW9kZWxGYWN0b3J5IFRoZSBmYWN0b3J5IHRvIGNyZWF0ZSBhIG5ldyBtb2RlbCBpZiB0aGUga2V5IGRvZXMgbm90IGV4aXN0LlxuICAgKiBAcmV0dXJucyBUaGUgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIHRoZSBnaXZlbiBrZXksIG9yIG51bGwgaWYgbm8gbWF0Y2ggaXMgZm91bmQuXG4gICAqL1xuICBwcml2YXRlIGdldEZyb21NYXBPckNyZWF0ZTxUPihcbiAgICBtYXA6IE1hcDxzdHJpbmcsIFQgfCBudWxsPixcbiAgICBrZXk6IHN0cmluZyxcbiAgICBzb3VyY2VMaXN0OiBUW10sXG4gICAgbWF0Y2hGbjogKGl0ZW06IFQpID0+IGJvb2xlYW4sXG4gICAgbW9kZWxGYWN0b3J5OiAoaXRlbTogVCkgPT4gVFxuICApOiBUIHwgbnVsbCB7XG4gICAgaWYgKCFrZXkpIHJldHVybiBudWxsO1xuICAgIGlmIChtYXAuaGFzKGtleSkpIHJldHVybiBtYXAuZ2V0KGtleSkgfHwgbnVsbDtcblxuICAgIGNvbnN0IGl0ZW0gPSBzb3VyY2VMaXN0LmZpbmQobWF0Y2hGbik7XG4gICAgY29uc3QgbW9kZWwgPSBpdGVtID8gbW9kZWxGYWN0b3J5KGl0ZW0pIDogbnVsbDtcbiAgICBtYXAuc2V0KGtleSwgbW9kZWwpO1xuICAgIHJldHVybiBtb2RlbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBMYXppbHkgaW5pdGlhbGl6ZXMgYSBsaXN0IG9mIG1vZGVscyBmcm9tIGEgc291cmNlIGxpc3QuXG4gICAqIEl0IGNyZWF0ZXMgYSBuZXcgbW9kZWwgZm9yIGVhY2ggaXRlbSBpbiB0aGUgc291cmNlIGxpc3QgYW5kIGFkZHMgaXQgdG8gdGhlIGdpdmVuIG1hcC5cbiAgICogSXQgYWxzbyBzZXRzIHRoZSBsaXN0IG9mIG1vZGVscyB0byB0aGUgZ2l2ZW4gc2V0dGVyLlxuICAgKiBAcGFyYW0gbGlzdFJlZiBUaGUgcmVmZXJlbmNlIHRvIHRoZSBsaXN0IG9mIG1vZGVscy5cbiAgICogQHBhcmFtIHNldHRlciBUaGUgc2V0dGVyIHRvIHNldCB0aGUgbGlzdCBvZiBtb2RlbHMuXG4gICAqIEBwYXJhbSBzb3VyY2VMaXN0IFRoZSBzb3VyY2UgbGlzdCBvZiBpdGVtcy5cbiAgICogQHBhcmFtIG1hcCBUaGUgbWFwIHRvIHN0b3JlIHRoZSBtb2RlbHMuXG4gICAqIEBwYXJhbSBnZXRLZXlzIFRoZSBmdW5jdGlvbiB0byBnZXQgdGhlIGtleXMgZm9yIHRoZSBnaXZlbiBpdGVtLlxuICAgKiBAcGFyYW0gbW9kZWxGYWN0b3J5IFRoZSBmYWN0b3J5IHRvIGNyZWF0ZSBhIG5ldyBtb2RlbCBmb3IgdGhlIGdpdmVuIGl0ZW0uXG4gICAqIEByZXR1cm5zIFRoZSBsaXN0IG9mIG1vZGVscy5cbiAgICovXG4gIHByaXZhdGUgbGF6eUluaXRMaXN0PFQsIE0+KFxuICAgIGxpc3RSZWY6IE1bXSB8IG51bGwsXG4gICAgc2V0dGVyOiAobGlzdDogTVtdKSA9PiB2b2lkLFxuICAgIHNvdXJjZUxpc3Q6IFRbXSxcbiAgICBtYXA6IE1hcDxzdHJpbmcsIE0gfCBudWxsPixcbiAgICBnZXRLZXlzOiAoaXRlbTogVCkgPT4gc3RyaW5nW10sXG4gICAgbW9kZWxGYWN0b3J5OiAoaXRlbTogVCkgPT4gTVxuICApOiBNW10ge1xuICAgIC8vIElmIHRoZSBsaXN0IGlzIGFscmVhZHkgaW5pdGlhbGl6ZWQsIHJldHVybiBpdC5cbiAgICBpZiAobGlzdFJlZikgcmV0dXJuIGxpc3RSZWY7XG5cbiAgICAvLyBDcmVhdGUgYSBuZXcgbW9kZWwgZm9yIGVhY2ggaXRlbSBpbiB0aGUgc291cmNlIGxpc3QgYW5kIGFkZCBpdCB0byB0aGUgbWFwLlxuICAgIGNvbnN0IG1vZGVscyA9IHNvdXJjZUxpc3QubWFwKChpdGVtOiBUKSA9PiB7XG4gICAgICBjb25zdCBtb2RlbCA9IG1vZGVsRmFjdG9yeShpdGVtKTtcbiAgICAgIGdldEtleXMoaXRlbSkuZm9yRWFjaChrZXkgPT4gbWFwLnNldChrZXksIG1vZGVsKSk7XG4gICAgICByZXR1cm4gbW9kZWw7XG4gICAgfSk7XG5cbiAgICAvLyBTZXQgdGhlIGxpc3Qgb2YgbW9kZWxzIHRvIHRoZSBnaXZlbiBzZXR0ZXIuXG4gICAgc2V0dGVyKG1vZGVscyk7XG5cbiAgICAvLyBSZXR1cm4gdGhlIGxpc3Qgb2YgbW9kZWxzLlxuICAgIHJldHVybiBtb2RlbHM7XG4gIH1cblxuICAvKipcbiAgICogRmluZHMgYW4gYXBwIG9iamVjdCBpbiB0aGUgbWFwIGJ5IGl0cyBuYW1lIG9yIGlkLlxuICAgKiBJZiB0aGUgYXBwIG9iamVjdCBpcyBub3QgZm91bmQsIGl0IGNyZWF0ZXMgYSBuZXcgb25lIGFuZCBhZGRzIGl0IHRvIHRoZSBtYXAuXG4gICAqIEBwYXJhbSBuYW1lT3JJZCBUaGUgbmFtZSBvciBpZCBvZiB0aGUgYXBwIG9iamVjdCB0byBmaW5kLlxuICAgKiBAcmV0dXJucyBUaGUgYXBwIG9iamVjdCBpZiBmb3VuZCwgb3IgbnVsbCBpZiBub3QgZm91bmQuXG4gICAqL1xuICBnZXRBcHBPYmplY3RCeUlkT3JOYW1lKG5hbWVPcklkOiBzdHJpbmcpOiBBcHBPYmplY3RNb2RlbCB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLmdldEZyb21NYXBPckNyZWF0ZShcbiAgICAgIHRoaXMuYXBwT2JqZWN0TWFwLFxuICAgICAgbmFtZU9ySWQsXG4gICAgICBDb21tb24udGFiSnNvbi5BcHBPYmplY3RzLFxuICAgICAgb2JqID0+IG9iai5PYmplY3ROYW1lID09PSBuYW1lT3JJZCB8fCBvYmouSUQgPT09IG5hbWVPcklkLFxuICAgICAgb2JqID0+IG5ldyBBcHBPYmplY3RNb2RlbChvYmopXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGEgbGlzdCBvZiBhcHAgb2JqZWN0cyBpbiB0aGUgbWV0YWRhdGEuXG4gICAqIElmIGEgZmlsdGVyIGZ1bmN0aW9uIGlzIGdpdmVuLCBpdCBpcyBhcHBsaWVkIHRvIGVhY2ggYXBwIG9iamVjdC5cbiAgICogQHBhcmFtIGZpbHRlckZuIFRoZSBmaWx0ZXIgZnVuY3Rpb24gdG8gYXBwbHkgdG8gdGhlIGFwcCBvYmplY3RzLlxuICAgKiBAcmV0dXJucyBUaGUgbGlzdCBvZiBhcHAgb2JqZWN0cy5cbiAgICovXG4gIGdldEFsbEFwcE9iamVjdHMoZmlsdGVyRm4/OiAob2JqOiBBcHBPYmplY3RNb2RlbCkgPT4gYm9vbGVhbik6IEFwcE9iamVjdE1vZGVsW10ge1xuICAgIC8vIEluaXRpYWxpemUgdGhlIGxpc3Qgb2YgYXBwIG9iamVjdHMgbGF6aWx5LlxuICAgIGNvbnN0IGxpc3QgPSB0aGlzLmxhenlJbml0TGlzdChcbiAgICAgIHRoaXMuYWxsQXBwT2JqZWN0cyxcbiAgICAgIHZhbCA9PiAodGhpcy5hbGxBcHBPYmplY3RzID0gdmFsKSxcbiAgICAgIENvbW1vbi50YWJKc29uLkFwcE9iamVjdHMsXG4gICAgICB0aGlzLmFwcE9iamVjdE1hcCxcbiAgICAgIChvYmo6IGFueSkgPT4gW29iai5JRCwgb2JqLk9iamVjdE5hbWVdLFxuICAgICAgb2JqID0+IG5ldyBBcHBPYmplY3RNb2RlbChvYmopXG4gICAgKTtcblxuICAgIC8vIElmIGEgZmlsdGVyIGZ1bmN0aW9uIGlzIGdpdmVuLCBhcHBseSBpdCB0byB0aGUgbGlzdCBvZiBhcHAgb2JqZWN0cy5cbiAgICByZXR1cm4gZmlsdGVyRm4gPyBsaXN0LmZpbHRlcihmaWx0ZXJGbikgOiBsaXN0O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBsaXN0IG9mIGZpZWxkcyBpbiB0aGUgbWV0YWRhdGEuXG4gICAqIElmIGEgZmlsdGVyIGZ1bmN0aW9uIGlzIGdpdmVuLCBpdCBpcyBhcHBsaWVkIHRvIGVhY2ggZmllbGQuXG4gICAqIEBwYXJhbSBmaWx0ZXJGbiBUaGUgZmlsdGVyIGZ1bmN0aW9uIHRvIGFwcGx5IHRvIHRoZSBmaWVsZHMuXG4gICAqIEByZXR1cm5zIFRoZSBsaXN0IG9mIGZpZWxkcy5cbiAgICovXG4gIGdldEFsbEZpZWxkcyhmaWx0ZXJGbj86IChmaWVsZDogQXBwRmllbGRNb2RlbCkgPT4gYm9vbGVhbik6IEFwcEZpZWxkTW9kZWxbXSB7XG4gICAgLy8gR2V0IGEgbGlzdCBvZiBhbGwgZmllbGRzIGZyb20gYWxsIGFwcCBvYmplY3RzLlxuICAgIGNvbnN0IGFsbEZpZWxkcyA9IHRoaXMuZ2V0QWxsQXBwT2JqZWN0cygpLmZsYXRNYXAob2JqID0+IG9iai5maWVsZHMoKSk7XG5cbiAgICAvLyBJZiBhIGZpbHRlciBmdW5jdGlvbiBpcyBnaXZlbiwgYXBwbHkgaXQgdG8gdGhlIGxpc3Qgb2YgZmllbGRzLlxuICAgIHJldHVybiBmaWx0ZXJGbiA/IGFsbEZpZWxkcy5maWx0ZXIoZmlsdGVyRm4pIDogYWxsRmllbGRzO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBsaXN0IG9mIGRhdGEgc291cmNlIHF1ZXJpZXMgaW4gdGhlIG1ldGFkYXRhLlxuICAgKiBJZiBhIGZpbHRlciBmdW5jdGlvbiBpcyBnaXZlbiwgaXQgaXMgYXBwbGllZCB0byBlYWNoIGRhdGEgc291cmNlIHF1ZXJ5LlxuICAgKiBAcGFyYW0gZmlsdGVyRm4gVGhlIGZpbHRlciBmdW5jdGlvbiB0byBhcHBseSB0byB0aGUgZGF0YSBzb3VyY2UgcXVlcmllcy5cbiAgICogQHJldHVybnMgVGhlIGxpc3Qgb2YgZGF0YSBzb3VyY2UgcXVlcmllcy5cbiAgICovXG4gIGdldEFsbERhdGFTb3VyY2VRdWVyaWVzKGZpbHRlckZuPzogKGRzcTogRGF0YVNvdXJjZVF1ZXJ5TW9kZWwpID0+IGJvb2xlYW4pOiBEYXRhU291cmNlUXVlcnlNb2RlbFtdIHtcbiAgICAvLyBHZXQgYSBsaXN0IG9mIGFsbCBkYXRhIHNvdXJjZSBxdWVyaWVzIGZyb20gYWxsIGFwcCBvYmplY3RzLlxuICAgIGNvbnN0IGFsbERTUXMgPSB0aGlzLmdldEFsbEFwcE9iamVjdHMoKS5mbGF0TWFwKG9iaiA9PiBvYmouZGF0YVNvdXJjZVF1ZXJpZXMoKSk7XG5cbiAgICAvLyBJZiBhIGZpbHRlciBmdW5jdGlvbiBpcyBnaXZlbiwgYXBwbHkgaXQgdG8gdGhlIGxpc3Qgb2YgZGF0YSBzb3VyY2UgcXVlcmllcy5cbiAgICByZXR1cm4gZmlsdGVyRm4gPyBhbGxEU1FzLmZpbHRlcihmaWx0ZXJGbikgOiBhbGxEU1FzO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlcyBhIGRhdGEgc291cmNlIHF1ZXJ5IGJ5IGl0cyBJRCwgUXVlcnlOYW1lLCBvciBEaXNwbGF5TmFtZS5cbiAgICogU2VhcmNoZXMgdGhyb3VnaCBhbGwgZGF0YSBzb3VyY2UgcXVlcmllcyBhbmQgcmV0dXJucyB0aGUgZmlyc3QgbWF0Y2guXG4gICAqIFxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZU9ySWQgLSBUaGUgSUQsIFF1ZXJ5TmFtZSwgb3IgRGlzcGxheU5hbWUgb2YgdGhlIGRhdGEgc291cmNlIHF1ZXJ5IHRvIHJldHJpZXZlLlxuICAgKiBAcmV0dXJucyB7RGF0YVNvdXJjZVF1ZXJ5TW9kZWwgfCBudWxsfSAtIFRoZSBkYXRhIHNvdXJjZSBxdWVyeSBtb2RlbCBpZiBmb3VuZCwgb3RoZXJ3aXNlIG51bGwuXG4gICAqL1xuICBnZXREYXRhU291cmNlUXVlcnlCeUlkT3JOYW1lKG5hbWVPcklkOiBzdHJpbmcpOiBEYXRhU291cmNlUXVlcnlNb2RlbCB8IG51bGwge1xuICAgIC8vIFNlYXJjaCBmb3IgdGhlIGRhdGEgc291cmNlIHF1ZXJ5IGJ5IElELCBRdWVyeU5hbWUsIG9yIERpc3BsYXlOYW1lXG4gICAgcmV0dXJuIHRoaXMuZ2V0QWxsRGF0YVNvdXJjZVF1ZXJpZXMoKS5maW5kKFxuICAgICAgZHNxID0+IGRzcT8uSUQgPT09IG5hbWVPcklkIHx8IGRzcT8uUXVlcnlOYW1lID09PSBuYW1lT3JJZCB8fCBkc3E/LkRpc3BsYXlOYW1lID09PSBuYW1lT3JJZFxuICAgICkgfHwgbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZXMgYW4gYXBwIHNjcmVlbiBieSBpdHMgSUQsIE5hbWUsIG9yIERpc3BsYXlOYW1lLlxuICAgKiBTZWFyY2hlcyB0aHJvdWdoIGFsbCBhcHAgc2NyZWVucyBhbmQgcmV0dXJucyB0aGUgZmlyc3QgbWF0Y2guXG4gICAqIFxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZU9ySWQgLSBUaGUgSUQsIE5hbWUsIG9yIERpc3BsYXlOYW1lIG9mIHRoZSBhcHAgc2NyZWVuIHRvIHJldHJpZXZlLlxuICAgKiBAcmV0dXJucyB7QXBwU2NyZWVuTW9kZWwgfCBudWxsfSAtIFRoZSBhcHAgc2NyZWVuIG1vZGVsIGlmIGZvdW5kLCBvdGhlcndpc2UgbnVsbC5cbiAgICovXG4gIGdldEFwcFNjcmVlbkJ5SWRPck5hbWUobmFtZU9ySWQ6IHN0cmluZyk6IEFwcFNjcmVlbk1vZGVsIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0RnJvbU1hcE9yQ3JlYXRlKFxuICAgICAgdGhpcy5hcHBTY3JlZW5NYXAsXG4gICAgICBuYW1lT3JJZCxcbiAgICAgIENvbW1vbi50YWJKc29uLkFwcFNjcmVlbnMsXG4gICAgICBzY3JlZW4gPT4gc2NyZWVuPy5JRCA9PT0gbmFtZU9ySWQgfHwgc2NyZWVuPy5OYW1lID09PSBuYW1lT3JJZCxcbiAgICAgIHNjcmVlbiA9PiBuZXcgQXBwU2NyZWVuTW9kZWwoc2NyZWVuKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIGEgbGlzdCBvZiBhbGwgYXBwIHNjcmVlbnMuXG4gICAqIElmIGEgZmlsdGVyIGZ1bmN0aW9uIGlzIGdpdmVuLCBpdCBpcyBhcHBsaWVkIHRvIHRoZSBsaXN0IG9mIGFwcCBzY3JlZW5zLlxuICAgKiBcbiAgICogQHBhcmFtIHtmdW5jdGlvbn0gZmlsdGVyRm4gLSBUaGUgZmlsdGVyIGZ1bmN0aW9uIHRvIGFwcGx5IHRvIHRoZSBhcHAgc2NyZWVucy5cbiAgICogQHJldHVybnMge0FwcFNjcmVlbk1vZGVsW119IC0gVGhlIGxpc3Qgb2YgYXBwIHNjcmVlbnMuXG4gICAqL1xuICBnZXRBbGxBcHBTY3JlZW5zKGZpbHRlckZuPzogKHNjcmVlbjogQXBwU2NyZWVuTW9kZWwpID0+IGJvb2xlYW4pOiBBcHBTY3JlZW5Nb2RlbFtdIHtcbiAgICAvLyBJbml0aWFsaXplIHRoZSBsaXN0IG9mIGFwcCBzY3JlZW5zIGxhemlseS5cbiAgICBjb25zdCBsaXN0ID0gdGhpcy5sYXp5SW5pdExpc3QoXG4gICAgICB0aGlzLmFsbEFwcFNjcmVlbnMsXG4gICAgICB2YWwgPT4gKHRoaXMuYWxsQXBwU2NyZWVucyA9IHZhbCksXG4gICAgICBDb21tb24udGFiSnNvbi5BcHBTY3JlZW5zLFxuICAgICAgdGhpcy5hcHBTY3JlZW5NYXAsXG4gICAgICAoczogYW55KSA9PiBbcz8uSUQsIHM/Lk5hbWVdLFxuICAgICAgcyA9PiBuZXcgQXBwU2NyZWVuTW9kZWwocylcbiAgICApO1xuXG4gICAgLy8gSWYgYSBmaWx0ZXIgZnVuY3Rpb24gaXMgZ2l2ZW4sIGFwcGx5IGl0IHRvIHRoZSBsaXN0IG9mIGFwcCBzY3JlZW5zLlxuICAgIHJldHVybiBmaWx0ZXJGbiA/IGxpc3QuZmlsdGVyKGZpbHRlckZuKSA6IGxpc3Q7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIGFuIG9yZ2FuaXphdGlvbiBpbmZvIGJ5IGl0cyBJRCBvciBUZW5hbnRDb2RlLlxuICAgKiBTZWFyY2hlcyB0aHJvdWdoIGFsbCBvcmdhbml6YXRpb24gaW5mbyBhbmQgcmV0dXJucyB0aGUgZmlyc3QgbWF0Y2guXG4gICAqIFxuICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZU9yVGVuYW50Q29kZSAtIFRoZSBJRCBvciBUZW5hbnRDb2RlIG9mIHRoZSBvcmdhbml6YXRpb24gaW5mbyB0byByZXRyaWV2ZS5cbiAgICogQHJldHVybnMge09yZ0luZm9Nb2RlbCB8IG51bGx9IC0gVGhlIG9yZ2FuaXphdGlvbiBpbmZvIG1vZGVsIGlmIGZvdW5kLCBvdGhlcndpc2UgbnVsbC5cbiAgICovXG4gIGdldE9yZ0luZm9CeUlkT3JUZW5hbnRDb2RlKG5hbWVPclRlbmFudENvZGU6IHN0cmluZyk6IE9yZ0luZm9Nb2RlbCB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLmdldEZyb21NYXBPckNyZWF0ZShcbiAgICAgIHRoaXMub3JnSW5mb01hcCxcbiAgICAgIG5hbWVPclRlbmFudENvZGUsXG4gICAgICBDb21tb24udGFiSnNvbi5PcmdJbmZvcyxcbiAgICAgIC8vIFNlYXJjaCBmb3IgdGhlIG9yZ2FuaXphdGlvbiBpbmZvIGJ5IElEIG9yIFRlbmFudENvZGVcbiAgICAgIG9yZyA9PiBvcmcuSUQgPT09IG5hbWVPclRlbmFudENvZGUgfHwgb3JnLlRlbmFudENvZGUgPT09IG5hbWVPclRlbmFudENvZGUsXG4gICAgICAvLyBDcmVhdGUgYSBuZXcgT3JnSW5mb01vZGVsIGlmIHRoZSBvcmdhbml6YXRpb24gaW5mbyBpcyBmb3VuZFxuICAgICAgb3JnID0+IG5ldyBPcmdJbmZvTW9kZWwob3JnKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmVzIGEgbGlzdCBvZiBhbGwgb3JnYW5pemF0aW9uIGluZm8uXG4gICAqIElmIGEgZmlsdGVyIGZ1bmN0aW9uIGlzIGdpdmVuLCBpdCBpcyBhcHBsaWVkIHRvIHRoZSBsaXN0IG9mIG9yZ2FuaXphdGlvbiBpbmZvLlxuICAgKiBcbiAgICogQHBhcmFtIHtmdW5jdGlvbn0gZmlsdGVyRm4gLSBUaGUgZmlsdGVyIGZ1bmN0aW9uIHRvIGFwcGx5IHRvIHRoZSBvcmdhbml6YXRpb24gaW5mby5cbiAgICogQHJldHVybnMge09yZ0luZm9Nb2RlbFtdfSAtIFRoZSBsaXN0IG9mIG9yZ2FuaXphdGlvbiBpbmZvLlxuICAgKi9cbiAgZ2V0QWxsT3JnSW5mb3MoZmlsdGVyRm4/OiAob3JnOiBPcmdJbmZvTW9kZWwpID0+IGJvb2xlYW4pOiBPcmdJbmZvTW9kZWxbXSB7XG4gICAgLy8gSW5pdGlhbGl6ZSB0aGUgbGlzdCBvZiBvcmdhbml6YXRpb24gaW5mbyBsYXppbHkuXG4gICAgY29uc3QgbGlzdCA9IHRoaXMubGF6eUluaXRMaXN0KFxuICAgICAgdGhpcy5hbGxPcmdJbmZvcyxcbiAgICAgIHZhbCA9PiAodGhpcy5hbGxPcmdJbmZvcyA9IHZhbCksXG4gICAgICBDb21tb24udGFiSnNvbi5PcmdJbmZvcyxcbiAgICAgIHRoaXMub3JnSW5mb01hcCxcbiAgICAgIChvcmc6IGFueSkgPT4gW29yZz8uSUQsIG9yZz8uVGVuYW50Q29kZV0sXG4gICAgICBvcmcgPT4gbmV3IE9yZ0luZm9Nb2RlbChvcmcpXG4gICAgKTtcblxuICAgIC8vIElmIGEgZmlsdGVyIGZ1bmN0aW9uIGlzIGdpdmVuLCBhcHBseSBpdCB0byB0aGUgbGlzdCBvZiBvcmdhbml6YXRpb24gaW5mby5cbiAgICByZXR1cm4gZmlsdGVyRm4gPyBsaXN0LmZpbHRlcihmaWx0ZXJGbikgOiBsaXN0O1xuICB9XG5cbiAgLyoqXG4gICAqIFBlcmZvcm1zIGEgZ2xvYmFsIHNlYXJjaCBhY3Jvc3MgYWxsIG1ldGFkYXRhIGZvciBhIGdpdmVuIHNlYXJjaCB0ZXJtLlxuICAgKiBZb3UgY2FuIG5hcnJvdyB0aGUgc2VhcmNoIGJ5IHByb3ZpZGluZyBhIGxpc3Qgb2YgZW50aXR5IHR5cGVzIHRvIHNlYXJjaCB3aXRoaW4uXG4gICAqIFxuICAgKiBAcGFyYW0ge3N0cmluZ30gdGVybSAtIFRoZSBzZWFyY2ggdGVybSB0byBzZWFyY2ggZm9yLlxuICAgKiBAcGFyYW0ge01ldGFkYXRhRW50aXR5VHlwZVtdfSBlbnRpdHlUeXBlcyAtIFRoZSBsaXN0IG9mIGVudGl0eSB0eXBlcyB0byBzZWFyY2ggd2l0aGluLiBJZiBvbWl0dGVkLCBhbGwgZW50aXR5IHR5cGVzIGFyZSBzZWFyY2hlZC5cbiAgICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIGFueVtdPn0gLSBBIGRpY3Rpb25hcnkgd2l0aCByZXN1bHRzIGdyb3VwZWQgYnkgZW50aXR5IHR5cGUuXG4gICAqL1xuICBzZWFyY2hNZXRhZGF0YSh0ZXJtOiBzdHJpbmcsIGVudGl0eVR5cGVzPzogTWV0YWRhdGFFbnRpdHlUeXBlW10pOiBSZWNvcmQ8c3RyaW5nLCBhbnlbXT4ge1xuICAgIGNvbnN0IHNlYXJjaFRlcm0gPSB0ZXJtLnRvTG93ZXJDYXNlKCk7XG4gICAgY29uc3QgcmVzdWx0OiBSZWNvcmQ8c3RyaW5nLCBhbnlbXT4gPSB7fTtcblxuICAgIC8qKlxuICAgICAqIEhlbHBlciBmdW5jdGlvbiB0byBkZXRlcm1pbmUgaWYgYSBnaXZlbiBlbnRpdHkgdHlwZSBzaG91bGQgYmUgc2VhcmNoZWQuXG4gICAgICogQHBhcmFtIHtNZXRhZGF0YUVudGl0eVR5cGV9IHR5cGUgLSBUaGUgZW50aXR5IHR5cGUgdG8gY2hlY2suXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciB0aGUgZW50aXR5IHR5cGUgc2hvdWxkIGJlIHNlYXJjaGVkLlxuICAgICAqL1xuICAgIGNvbnN0IHNob3VsZFNlYXJjaCA9ICh0eXBlOiBNZXRhZGF0YUVudGl0eVR5cGUpID0+ICFlbnRpdHlUeXBlcyB8fCBlbnRpdHlUeXBlcy5pbmNsdWRlcyh0eXBlKTtcblxuICAgIGlmIChzaG91bGRTZWFyY2goTWV0YWRhdGFFbnRpdHlUeXBlLkFQUF9PQkpFQ1RTKSkge1xuICAgICAgLy8gU2VhcmNoIGZvciBhcHAgb2JqZWN0cyBieSBJRCwgT2JqZWN0TmFtZSwgRGlzcGxheU5hbWUsIG9yIFN5c3RlbURCVGFibGVOYW1lXG4gICAgICByZXN1bHRbTWV0YWRhdGFFbnRpdHlUeXBlLkFQUF9PQkpFQ1RTXSA9IHRoaXMuZ2V0QWxsQXBwT2JqZWN0cyhvYmogPT5cbiAgICAgICAgW29iaj8uSUQsIG9iaj8uT2JqZWN0TmFtZSwgb2JqPy5EaXNwbGF5TmFtZSwgb2JqPy5TeXN0ZW1EQlRhYmxlTmFtZV1cbiAgICAgICAgICAuc29tZSh2YWwgPT4gdmFsID09PSBzZWFyY2hUZXJtIHx8IHZhbD8udG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhzZWFyY2hUZXJtKSlcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKHNob3VsZFNlYXJjaChNZXRhZGF0YUVudGl0eVR5cGUuQVBQX0ZJRUxEUykpIHtcbiAgICAgIC8vIFNlYXJjaCBmb3IgYXBwIGZpZWxkcyBieSB1c2luZyB0aGUgc2VhcmNoIG1ldGhvZFxuICAgICAgcmVzdWx0W01ldGFkYXRhRW50aXR5VHlwZS5BUFBfRklFTERTXSA9IHRoaXMuZ2V0QWxsRmllbGRzKGZpZWxkID0+IGZpZWxkLnNlYXJjaChzZWFyY2hUZXJtKSk7XG4gICAgfVxuXG4gICAgaWYgKHNob3VsZFNlYXJjaChNZXRhZGF0YUVudGl0eVR5cGUuREFUQV9TT1VSQ0VfUVVFUklFUykpIHtcbiAgICAgIC8vIFNlYXJjaCBmb3IgZGF0YSBzb3VyY2UgcXVlcmllcyBieSB1c2luZyB0aGUgc2VhcmNoIG1ldGhvZFxuICAgICAgcmVzdWx0W01ldGFkYXRhRW50aXR5VHlwZS5EQVRBX1NPVVJDRV9RVUVSSUVTXSA9IHRoaXMuZ2V0QWxsRGF0YVNvdXJjZVF1ZXJpZXMoZHNxID0+IGRzcS5zZWFyY2goc2VhcmNoVGVybSkpO1xuICAgIH1cblxuICAgIGlmIChzaG91bGRTZWFyY2goTWV0YWRhdGFFbnRpdHlUeXBlLkFQUF9TQ1JFRU5TKSkge1xuICAgICAgLy8gU2VhcmNoIGZvciBhcHAgc2NyZWVucyBieSB1c2luZyB0aGUgc2VhcmNoIG1ldGhvZFxuICAgICAgcmVzdWx0W01ldGFkYXRhRW50aXR5VHlwZS5BUFBfU0NSRUVOU10gPSB0aGlzLmdldEFsbEFwcFNjcmVlbnMoc2NyZWVuID0+IHNjcmVlbi5zZWFyY2goc2VhcmNoVGVybSkpO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cbn0iXX0=