@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.
- package/esm2022/lib/tab-core-utility/app/enums/common.enum.mjs +23 -0
- package/esm2022/lib/tab-core-utility/app/enums/dsq.enum.mjs +17 -1
- package/esm2022/lib/tab-core-utility/app/enums/permission.enum.mjs +8 -1
- package/esm2022/lib/tab-core-utility/app/helpers/common/meta-data.helpers.mjs +161 -608
- package/esm2022/lib/tab-core-utility/app/interfaces/schema.interface.mjs +1 -2
- package/esm2022/lib/tab-core-utility/app/models/app-field.model.mjs +72 -0
- package/esm2022/lib/tab-core-utility/app/models/app-object.class.mjs +1 -1
- package/esm2022/lib/tab-core-utility/app/models/app-object.model.mjs +186 -0
- package/esm2022/lib/tab-core-utility/app/models/app-screen.model.mjs +37 -0
- package/esm2022/lib/tab-core-utility/app/models/common.class.mjs +1 -1
- package/esm2022/lib/tab-core-utility/app/models/data-source-queries.class.mjs +1 -1
- package/esm2022/lib/tab-core-utility/app/models/data-source-query.model.mjs +123 -0
- package/esm2022/lib/tab-core-utility/app/models/filter.model.mjs +24 -0
- package/esm2022/lib/tab-core-utility/app/models/orgInfo.model.mjs +38 -0
- package/esm2022/lib/tab-core-utility/app/models/parameter.model.mjs +18 -0
- package/esm2022/lib/tab-core-utility/app/models/sort.model.mjs +18 -0
- package/lib/tab-core-utility/app/enums/common.enum.d.ts +18 -0
- package/lib/tab-core-utility/app/enums/dsq.enum.d.ts +14 -0
- package/lib/tab-core-utility/app/enums/permission.enum.d.ts +6 -0
- package/lib/tab-core-utility/app/helpers/common/meta-data.helpers.d.ts +84 -320
- package/lib/tab-core-utility/app/interfaces/schema.interface.d.ts +1 -2
- package/lib/tab-core-utility/app/models/app-field.model.d.ts +56 -0
- package/lib/tab-core-utility/app/models/app-object.class.d.ts +11 -8
- package/lib/tab-core-utility/app/models/app-object.model.d.ts +124 -0
- package/lib/tab-core-utility/app/models/app-screen.model.d.ts +27 -0
- package/lib/tab-core-utility/app/models/common.class.d.ts +3 -0
- package/lib/tab-core-utility/app/models/data-source-queries.class.d.ts +8 -4
- package/lib/tab-core-utility/app/models/data-source-query.model.d.ts +69 -0
- package/lib/tab-core-utility/app/models/filter.model.d.ts +21 -0
- package/lib/tab-core-utility/app/models/orgInfo.model.d.ts +23 -0
- package/lib/tab-core-utility/app/models/parameter.model.d.ts +14 -0
- package/lib/tab-core-utility/app/models/sort.model.d.ts +15 -0
- 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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
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
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* @param
|
|
30
|
-
* @
|
|
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
|
-
|
|
80
|
-
return this.
|
|
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
|
-
*
|
|
87
|
-
*
|
|
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
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
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
|
-
*
|
|
97
|
-
*
|
|
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
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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
|
-
*
|
|
105
|
-
*
|
|
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
|
-
|
|
108
|
-
|
|
109
|
-
|
|
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
|
-
*
|
|
113
|
-
*
|
|
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
|
-
*
|
|
138
|
-
*
|
|
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
|
-
|
|
144
|
-
|
|
145
|
-
|
|
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
|
-
*
|
|
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
|
-
*
|
|
170
|
-
*
|
|
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
|
-
|
|
176
|
-
|
|
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
|
-
*
|
|
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
|
-
* @
|
|
192
|
-
*
|
|
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
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
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
|
-
*
|
|
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
|
|
225
|
-
* @
|
|
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
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
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
|
-
*
|
|
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
|
-
* @
|
|
336
|
-
*
|
|
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
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
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
|
-
*
|
|
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
|
-
* @
|
|
371
|
-
*
|
|
372
|
-
*
|
|
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
|
-
|
|
381
|
-
|
|
382
|
-
|
|
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
|
-
|
|
385
|
-
|
|
386
|
-
|
|
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
|
-
|
|
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
|
-
|
|
427
|
-
|
|
428
|
-
|
|
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=
|