@yuuvis/client-core 2.0.0-beta.0 → 2.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/fesm2022/yuuvis-client-core.mjs +773 -645
  2. package/fesm2022/yuuvis-client-core.mjs.map +1 -1
  3. package/index.d.ts +7 -4
  4. package/lib/model/object-flavor.interface.d.ts +4 -1
  5. package/lib/provide.client.core.d.ts +58 -0
  6. package/lib/service/backend/backend.service.d.ts +0 -1
  7. package/lib/service/config/config.service.d.ts +0 -8
  8. package/lib/service/core-init/core-init.service.d.ts +1 -7
  9. package/lib/service/core-init/translate-json-loader.d.ts +1 -1
  10. package/lib/service/dms/dms.service.d.ts +2 -1
  11. package/lib/service/object-config/object-config.interface.d.ts +1 -1
  12. package/lib/service/object-form/object-form-translate.service.d.ts +15 -0
  13. package/lib/service/{system → object-form}/object-form.interface.d.ts +2 -2
  14. package/lib/service/object-form/object-form.model.d.ts +45 -0
  15. package/lib/service/system/system.interface.d.ts +1 -1
  16. package/lib/service/system/system.service.d.ts +1 -1
  17. package/lib/service/toast/toast.interface.d.ts +8 -0
  18. package/lib/service/toast/toast.service.d.ts +17 -0
  19. package/lib/service/toast/toast.styles.d.ts +1 -0
  20. package/lib/service/upload/upload.interface.d.ts +1 -1
  21. package/lib/service/user/user.providers.d.ts +4 -0
  22. package/lib/service/user/user.service.d.ts +2 -4
  23. package/package.json +7 -10
  24. package/esm2022/index.mjs +0 -69
  25. package/esm2022/lib/client-core.module.mjs +0 -117
  26. package/esm2022/lib/client-core.shared.module.mjs +0 -18
  27. package/esm2022/lib/common/pipes/filesize.pipe.mjs +0 -37
  28. package/esm2022/lib/common/pipes/index.mjs +0 -6
  29. package/esm2022/lib/common/pipes/keys.pipe.mjs +0 -17
  30. package/esm2022/lib/common/pipes/locale-date.pipe.mjs +0 -45
  31. package/esm2022/lib/common/pipes/locale-number.pipe.mjs +0 -115
  32. package/esm2022/lib/common/pipes/safe-html.pipe.mjs +0 -44
  33. package/esm2022/lib/common/services/native-notifications.interface.mjs +0 -2
  34. package/esm2022/lib/common/services/native-notifications.mjs +0 -40
  35. package/esm2022/lib/model/dms-object.interface.mjs +0 -2
  36. package/esm2022/lib/model/dms-object.model.mjs +0 -79
  37. package/esm2022/lib/model/object-flavor.interface.mjs +0 -2
  38. package/esm2022/lib/model/range-value.interface.mjs +0 -2
  39. package/esm2022/lib/model/yuv-error.model.mjs +0 -37
  40. package/esm2022/lib/model/yuv-user.model.mjs +0 -38
  41. package/esm2022/lib/service/audit/audit.interface.mjs +0 -2
  42. package/esm2022/lib/service/audit/audit.service.mjs +0 -135
  43. package/esm2022/lib/service/auth/auth.interceptor.mjs +0 -50
  44. package/esm2022/lib/service/auth/auth.interface.mjs +0 -7
  45. package/esm2022/lib/service/auth/auth.service.mjs +0 -130
  46. package/esm2022/lib/service/auth/oidc.service.mjs +0 -81
  47. package/esm2022/lib/service/backend/api.enum.mjs +0 -11
  48. package/esm2022/lib/service/backend/backend.interface.mjs +0 -2
  49. package/esm2022/lib/service/backend/backend.service.mjs +0 -206
  50. package/esm2022/lib/service/bpm/bpm.interface.mjs +0 -8
  51. package/esm2022/lib/service/bpm/bpm.service.mjs +0 -51
  52. package/esm2022/lib/service/cache/app-cache.service.mjs +0 -51
  53. package/esm2022/lib/service/catalog/catalog.interface.mjs +0 -2
  54. package/esm2022/lib/service/catalog/catalog.service.mjs +0 -13
  55. package/esm2022/lib/service/clipboard/clipboard.interface.mjs +0 -2
  56. package/esm2022/lib/service/clipboard/clipboard.service.mjs +0 -99
  57. package/esm2022/lib/service/config/config.interface.mjs +0 -6
  58. package/esm2022/lib/service/config/config.service.mjs +0 -115
  59. package/esm2022/lib/service/config/core-config.mjs +0 -20
  60. package/esm2022/lib/service/config/core-config.tokens.mjs +0 -9
  61. package/esm2022/lib/service/connection/connection.service.mjs +0 -36
  62. package/esm2022/lib/service/connection/offline.interceptor.mjs +0 -28
  63. package/esm2022/lib/service/core-init/core-init.service.mjs +0 -29
  64. package/esm2022/lib/service/core-init/missing-translation-handler.mjs +0 -10
  65. package/esm2022/lib/service/core-init/translate-json-loader.mjs +0 -117
  66. package/esm2022/lib/service/device/device.interface.mjs +0 -6
  67. package/esm2022/lib/service/device/device.service.mjs +0 -144
  68. package/esm2022/lib/service/dms/dms.service.interface.mjs +0 -2
  69. package/esm2022/lib/service/dms/dms.service.mjs +0 -440
  70. package/esm2022/lib/service/event/event.interface.mjs +0 -2
  71. package/esm2022/lib/service/event/event.service.mjs +0 -38
  72. package/esm2022/lib/service/event/events.mjs +0 -14
  73. package/esm2022/lib/service/idm/idm.interface.mjs +0 -2
  74. package/esm2022/lib/service/idm/idm.service.mjs +0 -34
  75. package/esm2022/lib/service/logger/logger-console.service.mjs +0 -73
  76. package/esm2022/lib/service/logger/logger.interface.mjs +0 -2
  77. package/esm2022/lib/service/logger/logger.mjs +0 -27
  78. package/esm2022/lib/service/notification/notification.service.mjs +0 -131
  79. package/esm2022/lib/service/object-config/object-config.interface.mjs +0 -2
  80. package/esm2022/lib/service/object-config/object-config.service.mjs +0 -233
  81. package/esm2022/lib/service/pending-changes/pending-changes-component.interface.mjs +0 -5
  82. package/esm2022/lib/service/pending-changes/pending-changes-guard.service.mjs +0 -25
  83. package/esm2022/lib/service/pending-changes/pending-changes.service.mjs +0 -123
  84. package/esm2022/lib/service/prediction/prediction.interface.mjs +0 -2
  85. package/esm2022/lib/service/prediction/prediction.service.mjs +0 -60
  86. package/esm2022/lib/service/retention/retention.interface.mjs +0 -2
  87. package/esm2022/lib/service/retention/retention.service.mjs +0 -65
  88. package/esm2022/lib/service/search/search.service.interface.mjs +0 -39
  89. package/esm2022/lib/service/search/search.service.mjs +0 -261
  90. package/esm2022/lib/service/search/search.utils.mjs +0 -142
  91. package/esm2022/lib/service/session-storage/session-storage.service.mjs +0 -50
  92. package/esm2022/lib/service/system/object-form.interface.mjs +0 -2
  93. package/esm2022/lib/service/system/system.enum.mjs +0 -167
  94. package/esm2022/lib/service/system/system.interface.mjs +0 -2
  95. package/esm2022/lib/service/system/system.service.mjs +0 -597
  96. package/esm2022/lib/service/upload/upload.interface.mjs +0 -2
  97. package/esm2022/lib/service/upload/upload.service.mjs +0 -228
  98. package/esm2022/lib/service/user/user-storage.service.mjs +0 -38
  99. package/esm2022/lib/service/user/user.service.mjs +0 -211
  100. package/esm2022/lib/util/utils.helper.enum.mjs +0 -15
  101. package/esm2022/lib/util/utils.mjs +0 -373
  102. package/esm2022/yuuvis-client-core.mjs +0 -5
  103. package/lib/client-core.module.d.ts +0 -20
  104. package/lib/client-core.shared.module.d.ts +0 -10
  105. package/lib/service/auth/oidc.service.d.ts +0 -16
@@ -1,597 +0,0 @@
1
- import { inject, Injectable } from '@angular/core';
2
- import { forkJoin, of, ReplaySubject } from 'rxjs';
3
- import { catchError, map, switchMap, tap } from 'rxjs/operators';
4
- import { Utils } from '../../util/utils';
5
- import { ApiBase } from '../backend/api.enum';
6
- import { BackendService } from '../backend/backend.service';
7
- import { AppCacheService } from '../cache/app-cache.service';
8
- import { Logger } from '../logger/logger';
9
- import { BaseObjectTypeField, Classification, ContentStreamAllowed, InternalFieldType, ObjectTypeClassification, SystemType } from './system.enum';
10
- import * as i0 from "@angular/core";
11
- /**
12
- * Providing system definitions.
13
- */
14
- export class SystemService {
15
- constructor() {
16
- this.#backend = inject(BackendService);
17
- this.#appCache = inject(AppCacheService);
18
- this.#logger = inject(Logger);
19
- this.#STORAGE_KEY = 'yuv.core.system.definition';
20
- this.#STORAGE_KEY_AUTH_DATA = 'yuv.core.auth.data';
21
- // cached icons to avoid backend calls (session cache)
22
- this.#iconCache = {};
23
- this.#resolvedClassificationsCache = {};
24
- this.#systemSource = new ReplaySubject();
25
- this.system$ = this.#systemSource.asObservable();
26
- // cache for resolved visible tags because they are used in lists and therefore should not be re-evaluated all the time
27
- this.#visibleTagsCache = {};
28
- }
29
- #backend;
30
- #appCache;
31
- #logger;
32
- #STORAGE_KEY;
33
- #STORAGE_KEY_AUTH_DATA;
34
- // cached icons to avoid backend calls (session cache)
35
- #iconCache;
36
- #resolvedClassificationsCache;
37
- #systemSource;
38
- // cache for resolved visible tags because they are used in lists and therefore should not be re-evaluated all the time
39
- #visibleTagsCache;
40
- #permissions;
41
- /**
42
- * Get all object types
43
- * @param withLabels Whether or not to also add the types labels
44
- */
45
- getObjectTypes(withLabels, situation) {
46
- // Filter by user permissions based on situation
47
- const objectTypes = this.#filterByPermissions([...this.system.objectTypes, ...this.system.secondaryObjectTypes.map((sot) => this.#sotToGenericType(sot))], situation);
48
- return withLabels ? objectTypes.map((t) => ({ ...t, label: this.getLocalizedResource(`${t.id}_label`) })) : objectTypes;
49
- }
50
- #sotToGenericType(sot) {
51
- return {
52
- ...sot,
53
- isFolder: false,
54
- creatable: true,
55
- secondaryObjectTypes: [],
56
- isSot: true
57
- };
58
- }
59
- /**
60
- * Get all secondary object types
61
- * @param withLabels Whether or not to also add the types labels
62
- */
63
- getSecondaryObjectTypes(withLabels, situation) {
64
- const sots = this.#filterByPermissions(this.system.secondaryObjectTypes.map((sot) => this.#sotToGenericType(sot)), situation);
65
- return ((withLabels ? sots.map((t) => ({ ...t, label: this.getLocalizedResource(`${t.id}_label`) })) : sots)
66
- // ignore
67
- .filter((t) => t.id !== t.baseId && !t.id.startsWith('system:') && t.id !== 'appClientsystem:leadingType'));
68
- }
69
- #filterByPermissions(types, situation) {
70
- if (!situation)
71
- return types;
72
- const allowedTypes = situation === 'search' ? this.#permissions.searchableObjectTypes : this.#permissions.createableObjectTypes;
73
- return types.filter((t) => allowedTypes.includes(t.id));
74
- }
75
- /**
76
- * Get a particular object type
77
- * @param objectTypeId ID of the object type
78
- * @param withLabel Whether or not to also add the types label
79
- */
80
- getObjectType(objectTypeId, withLabel) {
81
- let objectType = objectTypeId === SystemType.OBJECT ? this.getBaseType() : this.system.objectTypes.find((ot) => ot.id === objectTypeId);
82
- if (objectType && withLabel) {
83
- objectType.label = this.getLocalizedResource(`${objectType.id}_label`) || objectTypeId;
84
- }
85
- if (!objectType) {
86
- // no 'real' object type found. Try to find a matching SOT and treat it like a real type
87
- // by filling up the missing properties
88
- const sot = this.getSecondaryObjectType(objectTypeId, withLabel);
89
- if (sot) {
90
- objectType = this.#sotToGenericType(sot);
91
- }
92
- }
93
- return objectType;
94
- }
95
- /**
96
- * Get a particular secondary object type
97
- * @param objectTypeId ID of the object type
98
- * @param withLabel Whether or not to also add the types label
99
- */
100
- getSecondaryObjectType(objectTypeId, withLabel) {
101
- const objectType = this.system.secondaryObjectTypes.find((ot) => ot.id === objectTypeId);
102
- if (objectType && withLabel) {
103
- objectType.label = this.getLocalizedResource(`${objectType.id}_label`) || objectType.id;
104
- }
105
- return objectType;
106
- }
107
- /**
108
- * Get the base document type all documents belong to
109
- * @param withLabel Whether or not to also add the types label
110
- */
111
- getBaseDocumentType(withLabel) {
112
- return this.getObjectType(SystemType.DOCUMENT, withLabel);
113
- }
114
- /**
115
- * Get the base folder type all folders belong to
116
- * @param withLabel Whether or not to also add the types label
117
- */
118
- getBaseFolderType(withLabel) {
119
- return this.getObjectType(SystemType.FOLDER, withLabel);
120
- }
121
- /**
122
- * Get the base object type all dms objects belong to
123
- */
124
- getBaseType() {
125
- const sysFolder = this.getBaseFolderType();
126
- const sysDocument = this.getBaseDocumentType();
127
- // base type contains only fields that are shared by base document and base folder ...
128
- const folderTypeFieldIDs = sysFolder.fields.map((f) => f.id);
129
- const baseTypeFields = sysDocument.fields.filter((f) => folderTypeFieldIDs.includes(f.id));
130
- return {
131
- id: SystemType.OBJECT,
132
- creatable: false,
133
- isFolder: false,
134
- secondaryObjectTypes: [],
135
- fields: baseTypeFields
136
- // rawFields: baseTypeFields
137
- };
138
- }
139
- /**
140
- * Get the resolved object type with all fields ( including fields from related secondary types )
141
- */
142
- getResolvedType(objectTypeId) {
143
- const abstractTypes = Object.values(SystemType);
144
- if (!objectTypeId || abstractTypes.includes(objectTypeId)) {
145
- const baseType = this.getBaseType();
146
- return { id: baseType.id, fields: baseType.fields };
147
- }
148
- const ot = this.getObjectType(objectTypeId);
149
- if (!ot) {
150
- const sot = this.getSecondaryObjectType(objectTypeId) || { id: objectTypeId, fields: [] };
151
- const baseType = this.getBaseType();
152
- return {
153
- id: sot.id,
154
- fields: [...sot.fields, ...baseType.fields]
155
- };
156
- }
157
- return {
158
- id: ot.id,
159
- fields: ot.fields
160
- };
161
- }
162
- /**
163
- * Get the resolved object tags
164
- */
165
- getResolvedTags(objectTypeId) {
166
- const vTags = this.getVisibleTags(objectTypeId);
167
- return Object.keys(vTags).map((k) => ({
168
- id: objectTypeId,
169
- tagName: k,
170
- tagValues: vTags[k],
171
- fields: this.getBaseType().fields.filter((f) => f.id === BaseObjectTypeField.TAGS)
172
- }));
173
- }
174
- /**
175
- * Get a list of classifications for a given object type including the
176
- * classifications of its static secondary object types
177
- * @param objectTypeId ID of the object type
178
- */
179
- getResolvedClassifications(objectTypeId) {
180
- return this.#resolvedClassificationsCache[objectTypeId] || this.#resolveClassifications(objectTypeId);
181
- }
182
- #resolveClassifications(objectTypeId) {
183
- let classifications = [];
184
- const ot = this.getObjectType(objectTypeId);
185
- if (ot) {
186
- classifications = ot.classification || [];
187
- const staticSOTs = ot.secondaryObjectTypes ? ot.secondaryObjectTypes.filter((sot) => sot.static).map((sot) => sot.id) : [];
188
- staticSOTs.forEach((id) => {
189
- const sot = this.getSecondaryObjectType(id);
190
- classifications = sot?.classification
191
- ? [
192
- ...classifications,
193
- ...sot.classification.filter((c) => {
194
- // also filter classifications that should not be inherited
195
- return c !== ObjectTypeClassification.CREATE_FALSE && c !== ObjectTypeClassification.SEARCH_FALSE;
196
- })
197
- ]
198
- : classifications;
199
- });
200
- this.#resolvedClassificationsCache[objectTypeId] = classifications;
201
- }
202
- return classifications;
203
- }
204
- /**
205
- * Visible tags are defined by a classification on the object type (e.g. 'tag[tenkolibri:process,1,2,3]').
206
- *
207
- * The example will only return tags with the name 'tenkolibri:process'
208
- * and values of either 1, 2 or 3. All other tags will be ignored.
209
- *
210
- * @param objectTypeId ID of the object type to get the visible tags for
211
- * @returns object where the property name is the name of the tag and its value are the visible values
212
- * for that tag (if values is emoty all values are allowed)
213
- */
214
- getVisibleTags(objectTypeId) {
215
- return this.#visibleTagsCache[objectTypeId] || this.fetchVisibleTags(objectTypeId);
216
- }
217
- fetchVisibleTags(objectTypeId) {
218
- const ot = this.getObjectType(objectTypeId) || this.getSecondaryObjectType(objectTypeId);
219
- const tagClassifications = this.getResolvedClassifications(objectTypeId).filter((t) => t.startsWith('tag['));
220
- const parentType = ot && ot.id;
221
- const to = {};
222
- (tagClassifications || []).forEach((tag) => {
223
- const m = tag.match(/\[(.*)\]/i)[1].split(',');
224
- const tagName = m.splice(0, 1)[0];
225
- const tagValues = m.map((v) => parseInt(v.trim()));
226
- to[tagName] = tagValues;
227
- });
228
- this.#visibleTagsCache[objectTypeId] = parentType ? { ...this.getVisibleTags(parentType), ...to } : to;
229
- return this.#visibleTagsCache[objectTypeId];
230
- }
231
- filterVisibleTags(objectTypeId, tagsValue) {
232
- if (!tagsValue)
233
- return [];
234
- const vTags = this.getVisibleTags(objectTypeId);
235
- // Tag value looks like this: [tagName: string, state: number, date: Date, traceId: string]
236
- return tagsValue.filter((v) => !!vTags[v[0]] && vTags[v[0]].includes(v[1]));
237
- }
238
- /**
239
- * Get the icon for an object type. This will return an SVG as a string.
240
- * @param objectTypeId ID of the object type
241
- * @param fallback ID of a fallback icon that should be used if the given object type has no icon yet
242
- */
243
- getObjectTypeIcon(objectTypeId, fallback) {
244
- if (this.#iconCache[objectTypeId] && this.#iconCache[objectTypeId].icon) {
245
- return of(this.#iconCache[objectTypeId].icon);
246
- }
247
- else {
248
- const iconUri = this.getObjectTypeIconUri(objectTypeId, fallback);
249
- return this.#backend.get(iconUri).pipe(tap((icon) => (this.#iconCache[objectTypeId] = { uri: iconUri, icon })));
250
- }
251
- }
252
- /**
253
- * Get the URI of an object type icon.
254
- * @param objectTypeId ID of the object type
255
- * @param fallback ID of a fallback icon that should be used if the given object type has no icon yet
256
- */
257
- getObjectTypeIconUri(objectTypeId, fallback) {
258
- if (this.#iconCache[objectTypeId]) {
259
- return this.#iconCache[objectTypeId].uri;
260
- }
261
- else {
262
- const ci = this.#getIconFromClassification(objectTypeId);
263
- const fb = this.getFallbackIcon(objectTypeId, fallback);
264
- const uri = `/resources/icons/${encodeURIComponent(ci || objectTypeId)}${fb ? `?fallback=${encodeURIComponent(fb)}` : ''}`;
265
- this.#iconCache[objectTypeId] = { uri: `${this.#backend.getApiBase(ApiBase.apiWeb)}${uri}` };
266
- return this.#iconCache[objectTypeId].uri;
267
- }
268
- }
269
- getFallbackIcon(objectTypeId, fallback) {
270
- const ot = this.getObjectType(objectTypeId);
271
- if (ot && !fallback) {
272
- // add default fallbacks for system:document and system:folder if now other fallback has been provided
273
- fallback = ot.isFolder ? 'system:folder' : 'system:document';
274
- // if (this.isFloatingObjectType(ot)) {
275
- // // types that do not have no object type assigned to them (primary FSOTs)
276
- // fallback = 'system:dlm';
277
- // }
278
- }
279
- return fallback;
280
- }
281
- #getIconFromClassification(objectTypeId) {
282
- const ce = this.getClassifications(this.getResolvedClassifications(objectTypeId));
283
- return ce.has(ObjectTypeClassification.OBJECT_TYPE_ICON) ? ce.get(ObjectTypeClassification.OBJECT_TYPE_ICON).options[0] : null;
284
- }
285
- getLocalizedResource(key) {
286
- return this.system.i18n[key];
287
- }
288
- getLocalizedLabel(id) {
289
- return this.getLocalizedResource(`${id}_label`);
290
- }
291
- getLocalizedDescription(id) {
292
- return this.getLocalizedResource(`${id}_description`);
293
- }
294
- /**
295
- * Determine whether or not the given object type field is a system field
296
- * @param field Object type field to be checked
297
- */
298
- isSystemProperty(field) {
299
- return field.id.startsWith('system:');
300
- }
301
- /**
302
- * Fetches the backends system definition and updates system$ Observable.
303
- * Subscribe to the system$ observable instead of calling this function, otherwise you'll trigger fetching the
304
- * system definition every time.
305
- *
306
- * @param user The user to load the system definition for
307
- */
308
- getSystemDefinition(authData) {
309
- // TODO: Supposed to return 304 if nothing changes
310
- return this.#fetchSystemDefinition(authData);
311
- // TODO: remove when 304 is there???
312
- // // try to fetch system definition from cache first
313
- // return this.appCache.getItem(this.STORAGE_KEY).pipe(
314
- // switchMap(res => {
315
- // if (res) {
316
- // // check if the system definition from the cache is up to date
317
- // this.system = res;
318
- // this.systemSource.next(this.system);
319
- // return of(true);
320
- // } else {
321
- // // nothing cached so far
322
- // return this.fetchSystemDefinition();
323
- // }
324
- // })
325
- // );
326
- }
327
- /**
328
- * Actually fetch the system definition from the backend.
329
- * @param user User to fetch definition for
330
- */
331
- #fetchSystemDefinition(authData) {
332
- return (authData ? of(authData) : this.#appCache.getItem(this.#STORAGE_KEY_AUTH_DATA)).pipe(switchMap((data) => {
333
- this.updateAuthData(data).subscribe();
334
- const fetchTasks = [this.#backend.get('/dms/schema/native.json', ApiBase.core), this.#fetchLocalizations()];
335
- return forkJoin(fetchTasks);
336
- }), catchError((error) => {
337
- this.#logger.error('Error fetching recent version of system definition from server.', error);
338
- this.#systemSource.error('Error fetching recent version of system definition from server.');
339
- return of(null);
340
- }), map((data) => {
341
- if (data?.length) {
342
- this.setSchema(data[0], data[1]);
343
- }
344
- return !!data;
345
- }));
346
- }
347
- setPermissions(p) {
348
- this.#permissions = p;
349
- }
350
- /**
351
- * Create the schema from the servers schema response
352
- * @param schemaResponse Response from the backend
353
- */
354
- setSchema(schemaResponse, localizedResource = {}) {
355
- // prepare a quick access object for the fields
356
- const propertiesQA = {};
357
- const orgTypeFields = [BaseObjectTypeField.MODIFIED_BY, BaseObjectTypeField.CREATED_BY];
358
- schemaResponse.propertyDefinition.forEach((p) => {
359
- p.classifications = p.classification;
360
- // TODO: Remove once schema supports organization classification for base params
361
- // map certain fields to organization type (fake it until you make it ;-)
362
- if (orgTypeFields.includes(p.id)) {
363
- p.classifications = [Classification.STRING_ORGANIZATION];
364
- }
365
- propertiesQA[p.id] = p;
366
- });
367
- // prepare a quick access object for object types (including secondary objects)
368
- const objectTypesQA = {};
369
- schemaResponse.typeFolderDefinition.forEach((ot) => {
370
- objectTypesQA[ot.id] = ot;
371
- });
372
- schemaResponse.typeDocumentDefinition.forEach((ot) => {
373
- objectTypesQA[ot.id] = ot;
374
- });
375
- schemaResponse.typeSecondaryDefinition.forEach((sot) => {
376
- objectTypesQA[sot.id] = sot;
377
- });
378
- const objectTypes = [
379
- // folder types
380
- ...schemaResponse.typeFolderDefinition.map((fd) => ({
381
- id: fd.id,
382
- description: fd.description,
383
- classification: fd.classification,
384
- baseId: fd.baseId,
385
- creatable: this.#isCreatable(fd.id),
386
- contentStreamAllowed: ContentStreamAllowed.NOT_ALLOWED,
387
- isFolder: true,
388
- secondaryObjectTypes: fd.secondaryObjectTypeId ? fd.secondaryObjectTypeId.map((t) => ({ id: t.value, static: t.static })) : [],
389
- fields: this.#resolveObjectTypeFields(fd, propertiesQA, objectTypesQA)
390
- // rawFields: this.resolveObjectTypeFields(fd, propertiesQA, objectTypesQA, true),
391
- })),
392
- // document types
393
- ...schemaResponse.typeDocumentDefinition.map((dd) => ({
394
- id: dd.id,
395
- description: dd.description,
396
- classification: dd.classification,
397
- baseId: dd.baseId,
398
- creatable: this.#isCreatable(dd.id),
399
- contentStreamAllowed: dd.contentStreamAllowed,
400
- isFolder: false,
401
- secondaryObjectTypes: dd.secondaryObjectTypeId ? dd.secondaryObjectTypeId.map((t) => ({ id: t.value, static: t.static })) : [],
402
- fields: this.#resolveObjectTypeFields(dd, propertiesQA, objectTypesQA)
403
- // rawFields: this.resolveObjectTypeFields(dd, propertiesQA, objectTypesQA, true),
404
- }))
405
- ];
406
- const secondaryObjectTypes = schemaResponse.typeSecondaryDefinition.map((std) => ({
407
- id: std.id,
408
- description: std.description,
409
- classification: std.classification,
410
- contentStreamAllowed: std.contentStreamAllowed,
411
- baseId: std.baseId,
412
- // TODO: Could a SOT be a folder too?
413
- isFolder: false,
414
- fields: this.#resolveObjectTypeFields(std, propertiesQA, objectTypesQA)
415
- }));
416
- this.system = {
417
- version: schemaResponse.version,
418
- lastModificationDate: schemaResponse.lastModificationDate,
419
- objectTypes,
420
- secondaryObjectTypes,
421
- i18n: localizedResource,
422
- allFields: propertiesQA
423
- };
424
- this.#appCache.setItem(this.#STORAGE_KEY, this.system).subscribe();
425
- this.#systemSource.next(this.system);
426
- }
427
- /**
428
- * Resolve all the fields for an object type. This also includes secondary object types and the fields inherited from
429
- * the base type (... and of course the base type (and its secondary object types) of the base type and so on)
430
- * @param schemaTypeDefinition object type definition from the native schema
431
- * @param propertiesQA Quick access object of all properties
432
- * @param objectTypesQA Quick access object of all object types
433
- * @param raw If set to 'true' only the properties of the object type itself will be returned (without SOTs)
434
- */
435
- #resolveObjectTypeFields(schemaTypeDefinition, propertiesQA, objectTypesQA) {
436
- const objectTypeFieldIDs = schemaTypeDefinition.propertyReference.map((pr) => pr.value);
437
- if (schemaTypeDefinition.secondaryObjectTypeId) {
438
- schemaTypeDefinition.secondaryObjectTypeId
439
- .filter((sot) => sot.static)
440
- .map((sot) => sot.value)
441
- .forEach((sotID) => objectTypesQA[sotID].propertyReference.forEach((pr) => objectTypeFieldIDs.push(pr.value)));
442
- }
443
- let fields = objectTypeFieldIDs.map((id) => ({
444
- ...propertiesQA[id],
445
- _internalType: this.getInternalFormElementType(propertiesQA[id].propertyType, propertiesQA[id].classifications)
446
- }));
447
- // also resolve properties of the base type
448
- if (schemaTypeDefinition.baseId !== schemaTypeDefinition.id && !!objectTypesQA[schemaTypeDefinition.baseId]) {
449
- fields = fields.concat(this.#resolveObjectTypeFields(objectTypesQA[schemaTypeDefinition.baseId], propertiesQA, objectTypesQA));
450
- }
451
- return fields;
452
- }
453
- #isCreatable(objectTypeId) {
454
- return ![SystemType.FOLDER, SystemType.DOCUMENT].includes(objectTypeId);
455
- }
456
- /**
457
- * Fetch a collection of form models.
458
- * @param objectTypeIDs Object type IDs to fetch form model for
459
- * @param situation Form situation
460
- * @returns Object where the object type id is key and the form model is the value
461
- */
462
- getObjectTypeForms(objectTypeIDs, situation) {
463
- return forkJoin(objectTypeIDs.map((o) => this.getObjectTypeForm(o, situation).pipe(catchError((e) => of(null)), map((res) => ({
464
- id: o,
465
- formModel: res
466
- }))))).pipe(map((res) => {
467
- const resMap = {};
468
- res.filter((r) => this.#formHasElements(r.formModel)).forEach((r) => (resMap[r.id] = r.formModel));
469
- return resMap;
470
- }));
471
- }
472
- /**
473
- * Get the form model of an object type.
474
- *
475
- * @param objectTypeId ID of the object type to fetch the form for
476
- * @param situation The form situation to be fetched
477
- * @returns Form model
478
- */
479
- getObjectTypeForm(objectTypeId, situation) {
480
- return this.#backend.get(Utils.buildUri(`/dms/forms/${objectTypeId}`, { situation }));
481
- }
482
- /**
483
- * Check whether or not the model has at least one form element. Recursive.
484
- * @param element Form element to check child elements for
485
- */
486
- #formHasElements(element) {
487
- let hasElement = false;
488
- element.elements?.forEach((e) => {
489
- if (!['o2mGroup', 'o2mGroupStack'].includes(e.type)) {
490
- hasElement = true;
491
- }
492
- else if (!hasElement) {
493
- hasElement = this.#formHasElements(e);
494
- }
495
- });
496
- return hasElement;
497
- }
498
- /**
499
- * Generates an internal type for a given object type field.
500
- * Adding this to a form element or object type field enables us to render forms
501
- * based on object type fields in a more performant way. Otherwise we would
502
- * have to evaluate the conditions for every form element on every digest cycle.
503
- * @param type propertyType of the ObjectTypeField
504
- * @param classifications classifications of the ObjectTypeField
505
- */
506
- getInternalFormElementType(type, classifications) {
507
- const _classifications = this.getClassifications(classifications || []);
508
- if (type === 'string' && _classifications.has(Classification.STRING_REFERENCE)) {
509
- return InternalFieldType.STRING_REFERENCE;
510
- }
511
- else if (type === 'string' && _classifications.has(Classification.STRING_ORGANIZATION)) {
512
- return InternalFieldType.STRING_ORGANIZATION;
513
- }
514
- else if (type === 'string' && _classifications.has(Classification.STRING_ORGANIZATION_SET)) {
515
- return InternalFieldType.STRING_ORGANIZATION_SET;
516
- }
517
- else if (type === 'string' && _classifications.has(Classification.STRING_CATALOG)) {
518
- return InternalFieldType.STRING_CATALOG;
519
- }
520
- else if (type === 'boolean' && _classifications.has(Classification.BOOLEAN_SWITCH)) {
521
- return InternalFieldType.BOOLEAN_SWITCH;
522
- }
523
- else if (type === 'string' &&
524
- (_classifications.has(Classification.STRING_CATALOG_DYNAMIC) || _classifications.has(Classification.STRING_CATALOG_CUSTOM))) {
525
- return InternalFieldType.STRING_DYNAMIC_CATALOG;
526
- }
527
- else {
528
- // if there are no matching conditions just return the original type
529
- return type;
530
- }
531
- }
532
- getObjectTypeField(id) {
533
- const f = this.system?.allFields[id];
534
- return f ? { ...f, _internalType: this.getInternalFormElementType(f.propertyType, f.classifications) } : undefined;
535
- }
536
- /**
537
- * Extract classifications from object type fields classification
538
- * string. This string may contain more than one classification entry.
539
- *
540
- * Classification is a comma separated string that may contain additional
541
- * properties related to on classification entry. Example:
542
- *
543
- * `id:reference[system:folder], email`
544
- *
545
- * @param classifications Object type fields classification property (schema)
546
- */
547
- getClassifications(classifications) {
548
- const res = new Map();
549
- if (classifications) {
550
- classifications.forEach((c) => {
551
- const matches = c.match(/^([^\[]*)(\[(.*)\])?$/);
552
- if (matches && matches.length) {
553
- res.set(matches[1], {
554
- classification: matches[1],
555
- options: matches[3] ? matches[3].split(',').map((o) => o.trim()) : []
556
- });
557
- }
558
- });
559
- }
560
- return res;
561
- }
562
- toFormElement(field) {
563
- return { ...field, label: this.getLocalizedLabel(field.id), name: field.id, type: field.propertyType };
564
- }
565
- updateAuthData(data) {
566
- this.authData = { ...this.authData, ...data };
567
- this.#backend.setHeader('Accept-Language', this.authData.language);
568
- return this.#appCache.setItem(this.#STORAGE_KEY_AUTH_DATA, this.authData);
569
- }
570
- updateLocalizations(iso) {
571
- return this.updateAuthData({ language: iso }).pipe(switchMap(() => this.#fetchLocalizations()), tap((res) => {
572
- this.system.i18n = res;
573
- this.#appCache.setItem(this.#STORAGE_KEY, this.system).subscribe();
574
- this.#systemSource.next(this.system);
575
- }));
576
- }
577
- #fetchLocalizations() {
578
- return this.#backend.get('/resources/text');
579
- }
580
- fetchResources(id) {
581
- return this.#backend
582
- .batch([
583
- { uri: `/system/resources/${id}`, base: ApiBase.core },
584
- { uri: `/admin/resources/${id}`, base: ApiBase.core }
585
- ])
586
- .pipe(map(([global, tenant]) => ({ global, tenant })));
587
- }
588
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SystemService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
589
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SystemService, providedIn: 'root' }); }
590
- }
591
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: SystemService, decorators: [{
592
- type: Injectable,
593
- args: [{
594
- providedIn: 'root'
595
- }]
596
- }] });
597
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3lzdGVtLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL3l1dXZpcy9jbGllbnQtY29yZS9zcmMvbGliL3NlcnZpY2Uvc3lzdGVtL3N5c3RlbS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxRQUFRLEVBQWMsRUFBRSxFQUFFLGFBQWEsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMvRCxPQUFPLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDakUsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ3pDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUM5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDNUQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQzdELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUcxQyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsY0FBYyxFQUFFLG9CQUFvQixFQUFFLGlCQUFpQixFQUFFLHdCQUF3QixFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQzs7QUFlbko7O0dBRUc7QUFJSCxNQUFNLE9BQU8sYUFBYTtJQUgxQjtRQUlFLGFBQVEsR0FBRyxNQUFNLENBQUMsY0FBYyxDQUFDLENBQUM7UUFDbEMsY0FBUyxHQUFHLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUNwQyxZQUFPLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRXpCLGlCQUFZLEdBQUcsNEJBQTRCLENBQUM7UUFDNUMsMkJBQXNCLEdBQUcsb0JBQW9CLENBQUM7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Q0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDOUMsQ0FBQztJQUVELGNBQWMsQ0FBQyxFQUFVO1FBQ3ZCLE9BQU8sSUFBSSxDQUFDLFFBQVE7YUFDakIsS0FBSyxDQUFDO1lBQ0wsRUFBRSxHQUFHLEVBQUUscUJBQXFCLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxPQUFPLENBQUMsSUFBSSxFQUFFO1lBQ3RELEVBQUUsR0FBRyxFQUFFLG9CQUFvQixFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUksRUFBRTtTQUN0RCxDQUFDO2FBQ0QsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzNELENBQUM7K0dBdm9CVSxhQUFhO21IQUFiLGFBQWEsY0FGWixNQUFNOzs0RkFFUCxhQUFhO2tCQUh6QixVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGluamVjdCwgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgZm9ya0pvaW4sIE9ic2VydmFibGUsIG9mLCBSZXBsYXlTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBjYXRjaEVycm9yLCBtYXAsIHN3aXRjaE1hcCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVXRpbHMgfSBmcm9tICcuLi8uLi91dGlsL3V0aWxzJztcbmltcG9ydCB7IEFwaUJhc2UgfSBmcm9tICcuLi9iYWNrZW5kL2FwaS5lbnVtJztcbmltcG9ydCB7IEJhY2tlbmRTZXJ2aWNlIH0gZnJvbSAnLi4vYmFja2VuZC9iYWNrZW5kLnNlcnZpY2UnO1xuaW1wb3J0IHsgQXBwQ2FjaGVTZXJ2aWNlIH0gZnJvbSAnLi4vY2FjaGUvYXBwLWNhY2hlLnNlcnZpY2UnO1xuaW1wb3J0IHsgTG9nZ2VyIH0gZnJvbSAnLi4vbG9nZ2VyL2xvZ2dlcic7XG5pbXBvcnQgeyBBdXRoRGF0YSB9IGZyb20gJy4vLi4vYXV0aC9hdXRoLnNlcnZpY2UnO1xuaW1wb3J0IHsgT2JqZWN0VHlwZUZpZWxkSW50ZXJuYWxUeXBlLCBPYmplY3RUeXBlRmllbGRUeXBlIH0gZnJvbSAnLi9vYmplY3QtZm9ybS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgQmFzZU9iamVjdFR5cGVGaWVsZCwgQ2xhc3NpZmljYXRpb24sIENvbnRlbnRTdHJlYW1BbGxvd2VkLCBJbnRlcm5hbEZpZWxkVHlwZSwgT2JqZWN0VHlwZUNsYXNzaWZpY2F0aW9uLCBTeXN0ZW1UeXBlIH0gZnJvbSAnLi9zeXN0ZW0uZW51bSc7XG5pbXBvcnQge1xuICBDbGFzc2lmaWNhdGlvbkVudHJ5LFxuICBHZW5lcmljT2JqZWN0VHlwZSxcbiAgTG9jYWxpemF0aW9uLFxuICBPYmplY3RUeXBlLFxuICBPYmplY3RUeXBlRmllbGQsXG4gIE9iamVjdFR5cGVQZXJtaXNzaW9ucyxcbiAgU2NoZW1hUmVzcG9uc2UsXG4gIFNjaGVtYVJlc3BvbnNlRmllbGREZWZpbml0aW9uLFxuICBTY2hlbWFSZXNwb25zZVR5cGVEZWZpbml0aW9uLFxuICBTZWNvbmRhcnlPYmplY3RUeXBlLFxuICBTeXN0ZW1EZWZpbml0aW9uXG59IGZyb20gJy4vc3lzdGVtLmludGVyZmFjZSc7XG5cbi8qKlxuICogUHJvdmlkaW5nIHN5c3RlbSBkZWZpbml0aW9ucy5cbiAqL1xuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgU3lzdGVtU2VydmljZSB7XG4gICNiYWNrZW5kID0gaW5qZWN0KEJhY2tlbmRTZXJ2aWNlKTtcbiAgI2FwcENhY2hlID0gaW5qZWN0KEFwcENhY2hlU2VydmljZSk7XG4gICNsb2dnZXIgPSBpbmplY3QoTG9nZ2VyKTtcblxuICAjU1RPUkFHRV9LRVkgPSAneXV2LmNvcmUuc3lzdGVtLmRlZmluaXRpb24nO1xuICAjU1RPUkFHRV9LRVlfQVVUSF9EQVRBID0gJ3l1di5jb3JlLmF1dGguZGF0YSc7XG4gIC8vIGNhY2hlZCBpY29ucyB0byBhdm9pZCBiYWNrZW5kIGNhbGxzIChzZXNzaW9uIGNhY2hlKVxuICAjaWNvbkNhY2hlOiB7XG4gICAgW29iamVjdFR5cGVJZDogc3RyaW5nXToge1xuICAgICAgdXJpOiBzdHJpbmc7XG4gICAgICBpY29uPzogc3RyaW5nO1xuICAgIH07XG4gIH0gPSB7fTtcbiAgI3Jlc29sdmVkQ2xhc3NpZmljYXRpb25zQ2FjaGU6IHsgW29iamVjdFR5cGVJZDogc3RyaW5nXTogYW55IH0gPSB7fTtcblxuICBzeXN0ZW0/OiBTeXN0ZW1EZWZpbml0aW9uO1xuICAjc3lzdGVtU291cmNlID0gbmV3IFJlcGxheVN1YmplY3Q8U3lzdGVtRGVmaW5pdGlvbj4oKTtcbiAgc3lzdGVtJDogT2JzZXJ2YWJsZTxTeXN0ZW1EZWZpbml0aW9uPiA9IHRoaXMuI3N5c3RlbVNvdXJjZS5hc09ic2VydmFibGUoKTtcblxuICAvLyBjYWNoZSBmb3IgcmVzb2x2ZWQgdmlzaWJsZSB0YWdzIGJlY2F1c2UgdGhleSBhcmUgdXNlZCBpbiBsaXN0cyBhbmQgdGhlcmVmb3JlIHNob3VsZCBub3QgYmUgcmUtZXZhbHVhdGVkIGFsbCB0aGUgdGltZVxuICAjdmlzaWJsZVRhZ3NDYWNoZTogeyBbb2JqZWN0SWQ6IHN0cmluZ106IHsgW3RhZ05hbWU6IHN0cmluZ106IGFueVtdIH0gfSA9IHt9O1xuICAjcGVybWlzc2lvbnM/OiBPYmplY3RUeXBlUGVybWlzc2lvbnM7XG4gIGF1dGhEYXRhPzogQXV0aERhdGE7XG5cbiAgLyoqXG4gICAqIEdldCBhbGwgb2JqZWN0IHR5cGVzXG4gICAqIEBwYXJhbSB3aXRoTGFiZWxzIFdoZXRoZXIgb3Igbm90IHRvIGFsc28gYWRkIHRoZSB0eXBlcyBsYWJlbHNcbiAgICovXG4gIGdldE9iamVjdFR5cGVzKHdpdGhMYWJlbHM/OiBib29sZWFuLCBzaXR1YXRpb24/OiAnc2VhcmNoJyB8ICdjcmVhdGUnKTogR2VuZXJpY09iamVjdFR5cGVbXSB7XG4gICAgLy8gRmlsdGVyIGJ5IHVzZXIgcGVybWlzc2lvbnMgYmFzZWQgb24gc2l0dWF0aW9uXG4gICAgY29uc3Qgb2JqZWN0VHlwZXMgPSB0aGlzLiNmaWx0ZXJCeVBlcm1pc3Npb25zKFxuICAgICAgWy4uLnRoaXMuc3lzdGVtIS5vYmplY3RUeXBlcywgLi4udGhpcy5zeXN0ZW0hLnNlY29uZGFyeU9iamVjdFR5cGVzLm1hcCgoc290KSA9PiB0aGlzLiNzb3RUb0dlbmVyaWNUeXBlKHNvdCkpXSxcbiAgICAgIHNpdHVhdGlvblxuICAgICkgYXMgR2VuZXJpY09iamVjdFR5cGVbXTtcbiAgICByZXR1cm4gd2l0aExhYmVscyA/IG9iamVjdFR5cGVzLm1hcCgodCkgPT4gKHsgLi4udCwgbGFiZWw6IHRoaXMuZ2V0TG9jYWxpemVkUmVzb3VyY2UoYCR7dC5pZH1fbGFiZWxgKSB9KSkgOiBvYmplY3RUeXBlcztcbiAgfVxuXG4gICNzb3RUb0dlbmVyaWNUeXBlKHNvdDogU2Vjb25kYXJ5T2JqZWN0VHlwZSk6IEdlbmVyaWNPYmplY3RUeXBlIHtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uc290LFxuICAgICAgaXNGb2xkZXI6IGZhbHNlLFxuICAgICAgY3JlYXRhYmxlOiB0cnVlLFxuICAgICAgc2Vjb25kYXJ5T2JqZWN0VHlwZXM6IFtdLFxuICAgICAgaXNTb3Q6IHRydWVcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhbGwgc2Vjb25kYXJ5IG9iamVjdCB0eXBlc1xuICAgKiBAcGFyYW0gd2l0aExhYmVscyBXaGV0aGVyIG9yIG5vdCB0byBhbHNvIGFkZCB0aGUgdHlwZXMgbGFiZWxzXG4gICAqL1xuICBnZXRTZWNvbmRhcnlPYmplY3RUeXBlcyh3aXRoTGFiZWxzPzogYm9vbGVhbiwgc2l0dWF0aW9uPzogJ3NlYXJjaCcgfCAnY3JlYXRlJyk6IFNlY29uZGFyeU9iamVjdFR5cGVbXSB7XG4gICAgY29uc3Qgc290cyA9IHRoaXMuI2ZpbHRlckJ5UGVybWlzc2lvbnMoXG4gICAgICB0aGlzLnN5c3RlbSEuc2Vjb25kYXJ5T2JqZWN0VHlwZXMubWFwKChzb3QpID0+IHRoaXMuI3NvdFRvR2VuZXJpY1R5cGUoc290KSksXG4gICAgICBzaXR1YXRpb25cbiAgICApIGFzIFNlY29uZGFyeU9iamVjdFR5cGVbXTtcblxuICAgIHJldHVybiAoXG4gICAgICAod2l0aExhYmVscyA/IHNvdHMubWFwKCh0KSA9PiAoeyAuLi50LCBsYWJlbDogdGhpcy5nZXRMb2NhbGl6ZWRSZXNvdXJjZShgJHt0LmlkfV9sYWJlbGApIH0pKSA6IHNvdHMpXG4gICAgICAgIC8vIGlnbm9yZVxuICAgICAgICAuZmlsdGVyKCh0KSA9PiB0LmlkICE9PSB0LmJhc2VJZCAmJiAhdC5pZC5zdGFydHNXaXRoKCdzeXN0ZW06JykgJiYgdC5pZCAhPT0gJ2FwcENsaWVudHN5c3RlbTpsZWFkaW5nVHlwZScpXG4gICAgKTtcbiAgfVxuXG4gICNmaWx0ZXJCeVBlcm1pc3Npb25zKHR5cGVzOiBHZW5lcmljT2JqZWN0VHlwZVtdLCBzaXR1YXRpb24/OiAnc2VhcmNoJyB8ICdjcmVhdGUnKTogR2VuZXJpY09iamVjdFR5cGVbXSB7XG4gICAgaWYgKCFzaXR1YXRpb24pIHJldHVybiB0eXBlcztcbiAgICBjb25zdCBhbGxvd2VkVHlwZXMgPSBzaXR1YXRpb24gPT09ICdzZWFyY2gnID8gdGhpcy4jcGVybWlzc2lvbnMhLnNlYXJjaGFibGVPYmplY3RUeXBlcyA6IHRoaXMuI3Blcm1pc3Npb25zIS5jcmVhdGVhYmxlT2JqZWN0VHlwZXM7XG4gICAgcmV0dXJuIHR5cGVzLmZpbHRlcigodCkgPT4gYWxsb3dlZFR5cGVzLmluY2x1ZGVzKHQuaWQpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYSBwYXJ0aWN1bGFyIG9iamVjdCB0eXBlXG4gICAqIEBwYXJhbSBvYmplY3RUeXBlSWQgSUQgb2YgdGhlIG9iamVjdCB0eXBlXG4gICAqIEBwYXJhbSB3aXRoTGFiZWwgV2hldGhlciBvciBub3QgdG8gYWxzbyBhZGQgdGhlIHR5cGVzIGxhYmVsXG4gICAqL1xuICBnZXRPYmplY3RUeXBlKG9iamVjdFR5cGVJZDogc3RyaW5nLCB3aXRoTGFiZWw/OiBib29sZWFuKTogR2VuZXJpY09iamVjdFR5cGUgfCB1bmRlZmluZWQge1xuICAgIGxldCBvYmplY3RUeXBlOiBHZW5lcmljT2JqZWN0VHlwZSB8IHVuZGVmaW5lZCA9XG4gICAgICBvYmplY3RUeXBlSWQgPT09IFN5c3RlbVR5cGUuT0JKRUNUID8gdGhpcy5nZXRCYXNlVHlwZSgpIDogdGhpcy5zeXN0ZW0hLm9iamVjdFR5cGVzLmZpbmQoKG90KSA9PiBvdC5pZCA9PT0gb2JqZWN0VHlwZUlkKTtcblxuICAgIGlmIChvYmplY3RUeXBlICYmIHdpdGhMYWJlbCkge1xuICAgICAgb2JqZWN0VHlwZS5sYWJlbCA9IHRoaXMuZ2V0TG9jYWxpemVkUmVzb3VyY2UoYCR7b2JqZWN0VHlwZS5pZH1fbGFiZWxgKSB8fCBvYmplY3RUeXBlSWQ7XG4gICAgfVxuXG4gICAgaWYgKCFvYmplY3RUeXBlKSB7XG4gICAgICAvLyBubyAncmVhbCcgb2JqZWN0IHR5cGUgZm91bmQuIFRyeSB0byBmaW5kIGEgbWF0Y2hpbmcgU09UIGFuZCB0cmVhdCBpdCBsaWtlIGEgcmVhbCB0eXBlXG4gICAgICAvLyBieSBmaWxsaW5nIHVwIHRoZSBtaXNzaW5nIHByb3BlcnRpZXNcbiAgICAgIGNvbnN0IHNvdCA9IHRoaXMuZ2V0U2Vjb25kYXJ5T2JqZWN0VHlwZShvYmplY3RUeXBlSWQsIHdpdGhMYWJlbCk7XG4gICAgICBpZiAoc290KSB7XG4gICAgICAgIG9iamVjdFR5cGUgPSB0aGlzLiNzb3RUb0dlbmVyaWNUeXBlKHNvdCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvYmplY3RUeXBlO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBhIHBhcnRpY3VsYXIgc2Vjb25kYXJ5IG9iamVjdCB0eXBlXG4gICAqIEBwYXJhbSBvYmplY3RUeXBlSWQgSUQgb2YgdGhlIG9iamVjdCB0eXBlXG4gICAqIEBwYXJhbSB3aXRoTGFiZWwgV2hldGhlciBvciBub3QgdG8gYWxzbyBhZGQgdGhlIHR5cGVzIGxhYmVsXG4gICAqL1xuICBnZXRTZWNvbmRhcnlPYmplY3RUeXBlKG9iamVjdFR5cGVJZDogc3RyaW5nLCB3aXRoTGFiZWw/OiBib29sZWFuKTogU2Vjb25kYXJ5T2JqZWN0VHlwZSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3Qgb2JqZWN0VHlwZTogU2Vjb25kYXJ5T2JqZWN0VHlwZSB8IHVuZGVmaW5lZCA9IHRoaXMuc3lzdGVtIS5zZWNvbmRhcnlPYmplY3RUeXBlcy5maW5kKChvdCkgPT4gb3QuaWQgPT09IG9iamVjdFR5cGVJZCk7XG4gICAgaWYgKG9iamVjdFR5cGUgJiYgd2l0aExhYmVsKSB7XG4gICAgICBvYmplY3RUeXBlLmxhYmVsID0gdGhpcy5nZXRMb2NhbGl6ZWRSZXNvdXJjZShgJHtvYmplY3RUeXBlLmlkfV9sYWJlbGApIHx8IG9iamVjdFR5cGUuaWQ7XG4gICAgfVxuICAgIHJldHVybiBvYmplY3RUeXBlO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgYmFzZSBkb2N1bWVudCB0eXBlIGFsbCBkb2N1bWVudHMgYmVsb25nIHRvXG4gICAqIEBwYXJhbSB3aXRoTGFiZWwgV2hldGhlciBvciBub3QgdG8gYWxzbyBhZGQgdGhlIHR5cGVzIGxhYmVsXG4gICAqL1xuICBnZXRCYXNlRG9jdW1lbnRUeXBlKHdpdGhMYWJlbD86IGJvb2xlYW4pOiBPYmplY3RUeXBlIHtcbiAgICByZXR1cm4gdGhpcy5nZXRPYmplY3RUeXBlKFN5c3RlbVR5cGUuRE9DVU1FTlQsIHdpdGhMYWJlbCkhO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgYmFzZSBmb2xkZXIgdHlwZSBhbGwgZm9sZGVycyBiZWxvbmcgdG9cbiAgICogQHBhcmFtIHdpdGhMYWJlbCBXaGV0aGVyIG9yIG5vdCB0byBhbHNvIGFkZCB0aGUgdHlwZXMgbGFiZWxcbiAgICovXG4gIGdldEJhc2VGb2xkZXJUeXBlKHdpdGhMYWJlbD86IGJvb2xlYW4pOiBPYmplY3RUeXBlIHtcbiAgICByZXR1cm4gdGhpcy5nZXRPYmplY3RUeXBlKFN5c3RlbVR5cGUuRk9MREVSLCB3aXRoTGFiZWwpITtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGJhc2Ugb2JqZWN0IHR5cGUgYWxsIGRtcyBvYmplY3RzIGJlbG9uZyB0b1xuICAgKi9cbiAgZ2V0QmFzZVR5cGUoKTogT2JqZWN0VHlwZSB7XG4gICAgY29uc3Qgc3lzRm9sZGVyID0gdGhpcy5nZXRCYXNlRm9sZGVyVHlwZSgpO1xuICAgIGNvbnN0IHN5c0RvY3VtZW50ID0gdGhpcy5nZXRCYXNlRG9jdW1lbnRUeXBlKCk7XG5cbiAgICAvLyBiYXNlIHR5cGUgY29udGFpbnMgb25seSBmaWVsZHMgdGhhdCBhcmUgc2hhcmVkIGJ5IGJhc2UgZG9jdW1lbnQgYW5kIGJhc2UgZm9sZGVyIC4uLlxuICAgIGNvbnN0IGZvbGRlclR5cGVGaWVsZElEcyA9IHN5c0ZvbGRlci5maWVsZHMubWFwKChmKSA9PiBmLmlkKTtcbiAgICBjb25zdCBiYXNlVHlwZUZpZWxkczogT2JqZWN0VHlwZUZpZWxkW10gPSBzeXNEb2N1bWVudC5maWVsZHMuZmlsdGVyKChmKSA9PiBmb2xkZXJUeXBlRmllbGRJRHMuaW5jbHVkZXMoZi5pZCkpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiBTeXN0ZW1UeXBlLk9CSkVDVCxcbiAgICAgIGNyZWF0YWJsZTogZmFsc2UsXG4gICAgICBpc0ZvbGRlcjogZmFsc2UsXG4gICAgICBzZWNvbmRhcnlPYmplY3RUeXBlczogW10sXG4gICAgICBmaWVsZHM6IGJhc2VUeXBlRmllbGRzXG4gICAgICAvLyByYXdGaWVsZHM6IGJhc2VUeXBlRmllbGRzXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIHJlc29sdmVkIG9iamVjdCB0eXBlIHdpdGggYWxsIGZpZWxkcyAoIGluY2x1ZGluZyBmaWVsZHMgZnJvbSByZWxhdGVkIHNlY29uZGFyeSB0eXBlcyApXG4gICAqL1xuICBnZXRSZXNvbHZlZFR5cGUob2JqZWN0VHlwZUlkPzogc3RyaW5nKTogeyBpZDogc3RyaW5nOyBmaWVsZHM6IE9iamVjdFR5cGVGaWVsZFtdIH0ge1xuICAgIGNvbnN0IGFic3RyYWN0VHlwZXMgPSBPYmplY3QudmFsdWVzKFN5c3RlbVR5cGUpO1xuICAgIGlmICghb2JqZWN0VHlwZUlkIHx8IGFic3RyYWN0VHlwZXMuaW5jbHVkZXMob2JqZWN0VHlwZUlkKSkge1xuICAgICAgY29uc3QgYmFzZVR5cGUgPSB0aGlzLmdldEJhc2VUeXBlKCk7XG4gICAgICByZXR1cm4geyBpZDogYmFzZVR5cGUuaWQsIGZpZWxkczogYmFzZVR5cGUuZmllbGRzIH07XG4gICAgfVxuXG4gICAgY29uc3Qgb3QgPSB0aGlzLmdldE9iamVjdFR5cGUob2JqZWN0VHlwZUlkKTtcbiAgICBpZiAoIW90KSB7XG4gICAgICBjb25zdCBzb3QgPSB0aGlzLmdldFNlY29uZGFyeU9iamVjdFR5cGUob2JqZWN0VHlwZUlkKSB8fCB7IGlkOiBvYmplY3RUeXBlSWQsIGZpZWxkczogW10gfTtcbiAgICAgIGNvbnN0IGJhc2VUeXBlID0gdGhpcy5nZXRCYXNlVHlwZSgpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgaWQ6IHNvdC5pZCxcbiAgICAgICAgZmllbGRzOiBbLi4uc290LmZpZWxkcywgLi4uYmFzZVR5cGUuZmllbGRzXVxuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgaWQ6IG90LmlkLFxuICAgICAgZmllbGRzOiBvdC5maWVsZHNcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgcmVzb2x2ZWQgb2JqZWN0IHRhZ3NcbiAgICovXG4gIGdldFJlc29sdmVkVGFncyhvYmplY3RUeXBlSWQ6IHN0cmluZyk6IHsgaWQ6IHN0cmluZzsgdGFnTmFtZTogc3RyaW5nOyB0YWdWYWx1ZXM6IGFueTsgZmllbGRzOiBPYmplY3RUeXBlRmllbGRbXSB9W10ge1xuICAgIGNvbnN0IHZUYWdzID0gdGhpcy5nZXRWaXNpYmxlVGFncyhvYmplY3RUeXBlSWQpO1xuICAgIHJldHVybiBPYmplY3Qua2V5cyh2VGFncykubWFwKChrKSA9PiAoe1xuICAgICAgaWQ6IG9iamVjdFR5cGVJZCxcbiAgICAgIHRhZ05hbWU6IGssXG4gICAgICB0YWdWYWx1ZXM6IHZUYWdzW2tdLFxuICAgICAgZmllbGRzOiB0aGlzLmdldEJhc2VUeXBlKCkuZmllbGRzLmZpbHRlcigoZikgPT4gZi5pZCA9PT0gQmFzZU9iamVjdFR5cGVGaWVsZC5UQUdTKVxuICAgIH0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgYSBsaXN0IG9mIGNsYXNzaWZpY2F0aW9ucyBmb3IgYSBnaXZlbiBvYmplY3QgdHlwZSBpbmNsdWRpbmcgdGhlXG4gICAqIGNsYXNzaWZpY2F0aW9ucyBvZiBpdHMgc3RhdGljIHNlY29uZGFyeSBvYmplY3QgdHlwZXNcbiAgICogQHBhcmFtIG9iamVjdFR5cGVJZCBJRCBvZiB0aGUgb2JqZWN0IHR5cGVcbiAgICovXG4gIGdldFJlc29sdmVkQ2xhc3NpZmljYXRpb25zKG9iamVjdFR5cGVJZDogc3RyaW5nKTogc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLiNyZXNvbHZlZENsYXNzaWZpY2F0aW9uc0NhY2hlW29iamVjdFR5cGVJZF0gfHwgdGhpcy4jcmVzb2x2ZUNsYXNzaWZpY2F0aW9ucyhvYmplY3RUeXBlSWQpO1xuICB9XG5cbiAgI3Jlc29sdmVDbGFzc2lmaWNhdGlvbnMob2JqZWN0VHlwZUlkOiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gICAgbGV0IGNsYXNzaWZpY2F0aW9uczogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCBvdCA9IHRoaXMuZ2V0T2JqZWN0VHlwZShvYmplY3RUeXBlSWQpO1xuICAgIGlmIChvdCkge1xuICAgICAgY2xhc3NpZmljYXRpb25zID0gb3QuY2xhc3NpZmljYXRpb24gfHwgW107XG4gICAgICBjb25zdCBzdGF0aWNTT1RzOiBzdHJpbmdbXSA9IG90LnNlY29uZGFyeU9iamVjdFR5cGVzID8gb3Quc2Vjb25kYXJ5T2JqZWN0VHlwZXMuZmlsdGVyKChzb3QpID0+IHNvdC5zdGF0aWMpLm1hcCgoc290KSA9PiBzb3QuaWQpIDogW107XG4gICAgICBzdGF0aWNTT1RzLmZvckVhY2goKGlkKSA9PiB7XG4gICAgICAgIGNvbnN0IHNvdCA9IHRoaXMuZ2V0U2Vjb25kYXJ5T2JqZWN0VHlwZShpZCk7XG4gICAgICAgIGNsYXNzaWZpY2F0aW9ucyA9IHNvdD8uY2xhc3NpZmljYXRpb25cbiAgICAgICAgICA/IFtcbiAgICAgICAgICAgICAgLi4uY2xhc3NpZmljYXRpb25zLFxuICAgICAgICAgICAgICAuLi5zb3QuY2xhc3NpZmljYXRpb24uZmlsdGVyKChjKSA9PiB7XG4gICAgICAgICAgICAgICAgLy8gYWxzbyBmaWx0ZXIgY2xhc3NpZmljYXRpb25zIHRoYXQgc2hvdWxkIG5vdCBiZSBpbmhlcml0ZWRcbiAgICAgICAgICAgICAgICByZXR1cm4gYyAhPT0gT2JqZWN0VHlwZUNsYXNzaWZpY2F0aW9uLkNSRUFURV9GQUxTRSAmJiBjICE9PSBPYmplY3RUeXBlQ2xhc3NpZmljYXRpb24uU0VBUkNIX0ZBTFNFO1xuICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgXVxuICAgICAgICAgIDogY2xhc3NpZmljYXRpb25zO1xuICAgICAgfSk7XG4gICAgICB0aGlzLiNyZXNvbHZlZENsYXNzaWZpY2F0aW9uc0NhY2hlW29iamVjdFR5cGVJZF0gPSBjbGFzc2lmaWNhdGlvbnM7XG4gICAgfVxuICAgIHJldHVybiBjbGFzc2lmaWNhdGlvbnM7XG4gIH1cblxuICAvKipcbiAgICogVmlzaWJsZSB0YWdzIGFyZSBkZWZpbmVkIGJ5IGEgY2xhc3NpZmljYXRpb24gb24gdGhlIG9iamVjdCB0eXBlIChlLmcuICd0YWdbdGVua29saWJyaTpwcm9jZXNzLDEsMiwzXScpLlxuICAgKlxuICAgKiBUaGUgZXhhbXBsZSB3aWxsIG9ubHkgcmV0dXJuIHRhZ3Mgd2l0aCB0aGUgbmFtZSAndGVua29saWJyaTpwcm9jZXNzJ1xuICAgKiBhbmQgdmFsdWVzIG9mIGVpdGhlciAxLCAyIG9yIDMuIEFsbCBvdGhlciB0YWdzIHdpbGwgYmUgaWdub3JlZC5cbiAgICpcbiAgICogQHBhcmFtIG9iamVjdFR5cGVJZCBJRCBvZiB0aGUgb2JqZWN0IHR5cGUgdG8gZ2V0IHRoZSB2aXNpYmxlIHRhZ3MgZm9yXG4gICAqIEByZXR1cm5zIG9iamVjdCB3aGVyZSB0aGUgcHJvcGVydHkgbmFtZSBpcyB0aGUgbmFtZSBvZiB0aGUgdGFnIGFuZCBpdHMgdmFsdWUgYXJlIHRoZSB2aXNpYmxlIHZhbHVlc1xuICAgKiBmb3IgdGhhdCB0YWcgKGlmIHZhbHVlcyBpcyBlbW90eSBhbGwgdmFsdWVzIGFyZSBhbGxvd2VkKVxuICAgKi9cbiAgZ2V0VmlzaWJsZVRhZ3Mob2JqZWN0VHlwZUlkOiBzdHJpbmcpOiB7IFt0YWdOYW1lOiBzdHJpbmddOiBhbnlbXSB9IHtcbiAgICByZXR1cm4gdGhpcy4jdmlzaWJsZVRhZ3NDYWNoZVtvYmplY3RUeXBlSWRdIHx8IHRoaXMuZmV0Y2hWaXNpYmxlVGFncyhvYmplY3RUeXBlSWQpO1xuICB9XG5cbiAgcHJpdmF0ZSBmZXRjaFZpc2libGVUYWdzKG9iamVjdFR5cGVJZDogc3RyaW5nKTogeyBbdGFnTmFtZTogc3RyaW5nXTogYW55W10gfSB7XG4gICAgY29uc3Qgb3QgPSB0aGlzLmdldE9iamVjdFR5cGUob2JqZWN0VHlwZUlkKSB8fCB0aGlzLmdldFNlY29uZGFyeU9iamVjdFR5cGUob2JqZWN0VHlwZUlkKTtcbiAgICBjb25zdCB0YWdDbGFzc2lmaWNhdGlvbnMgPSB0aGlzLmdldFJlc29sdmVkQ2xhc3NpZmljYXRpb25zKG9iamVjdFR5cGVJZCkuZmlsdGVyKCh0KSA9PiB0LnN0YXJ0c1dpdGgoJ3RhZ1snKSk7XG4gICAgY29uc3QgcGFyZW50VHlwZSA9IG90ICYmIChvdCBhcyBPYmplY3RUeXBlKS5pZDtcblxuICAgIGNvbnN0IHRvOiB7IFt0YWdOYW1lOiBzdHJpbmddOiBhbnlbXSB9ID0ge307XG4gICAgKHRhZ0NsYXNzaWZpY2F0aW9ucyB8fCBbXSkuZm9yRWFjaCgodGFnKSA9PiB7XG4gICAgICBjb25zdCBtID0gdGFnLm1hdGNoKC9cXFsoLiopXFxdL2kpIVsxXS5zcGxpdCgnLCcpO1xuICAgICAgY29uc3QgdGFnTmFtZSA9IG0uc3BsaWNlKDAsIDEpWzBdO1xuICAgICAgY29uc3QgdGFnVmFsdWVzID0gbS5tYXAoKHYpID0+IHBhcnNlSW50KHYudHJpbSgpKSk7XG4gICAgICB0b1t0YWdOYW1lXSA9IHRhZ1ZhbHVlcztcbiAgICB9KTtcblxuICAgIHRoaXMuI3Zpc2libGVUYWdzQ2FjaGVbb2JqZWN0VHlwZUlkXSA9IHBhcmVudFR5cGUgPyB7IC4uLnRoaXMuZ2V0VmlzaWJsZVRhZ3MocGFyZW50VHlwZSksIC4uLnRvIH0gOiB0bztcbiAgICByZXR1cm4gdGhpcy4jdmlzaWJsZVRhZ3NDYWNoZVtvYmplY3RUeXBlSWRdO1xuICB9XG5cbiAgZmlsdGVyVmlzaWJsZVRhZ3Mob2JqZWN0VHlwZUlkOiBzdHJpbmcsIHRhZ3NWYWx1ZTogQXJyYXk8QXJyYXk8YW55Pj4pOiBBcnJheTxBcnJheTxhbnk+PiB7XG4gICAgaWYgKCF0YWdzVmFsdWUpIHJldHVybiBbXTtcbiAgICBjb25zdCB2VGFnczogeyBbdGFnTmFtZTogc3RyaW5nXTogYW55W10gfSA9IHRoaXMuZ2V0VmlzaWJsZVRhZ3Mob2JqZWN0VHlwZUlkKTtcbiAgICAvLyBUYWcgdmFsdWUgbG9va3MgbGlrZSB0aGlzOiBbdGFnTmFtZTogc3RyaW5nLCBzdGF0ZTogbnVtYmVyLCBkYXRlOiBEYXRlLCB0cmFjZUlkOiBzdHJpbmddXG4gICAgcmV0dXJuIHRhZ3NWYWx1ZS5maWx0ZXIoKHY6IGFueVtdKSA9PiAhIXZUYWdzW3ZbMF1dICYmIHZUYWdzW3ZbMF1dLmluY2x1ZGVzKHZbMV0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGljb24gZm9yIGFuIG9iamVjdCB0eXBlLiBUaGlzIHdpbGwgcmV0dXJuIGFuIFNWRyBhcyBhIHN0cmluZy5cbiAgICogQHBhcmFtIG9iamVjdFR5cGVJZCBJRCBvZiB0aGUgb2JqZWN0IHR5cGVcbiAgICogQHBhcmFtIGZhbGxiYWNrIElEIG9mIGEgZmFsbGJhY2sgaWNvbiB0aGF0IHNob3VsZCBiZSB1c2VkIGlmIHRoZSBnaXZlbiBvYmplY3QgdHlwZSBoYXMgbm8gaWNvbiB5ZXRcbiAgICovXG4gIGdldE9iamVjdFR5cGVJY29uKG9iamVjdFR5cGVJZDogc3RyaW5nLCBmYWxsYmFjaz86IHN0cmluZyk6IE9ic2VydmFibGU8c3RyaW5nPiB7XG4gICAgaWYgKHRoaXMuI2ljb25DYWNoZVtvYmplY3RUeXBlSWRdICYmIHRoaXMuI2ljb25DYWNoZVtvYmplY3RUeXBlSWRdLmljb24pIHtcbiAgICAgIHJldHVybiBvZih0aGlzLiNpY29uQ2FjaGVbb2JqZWN0VHlwZUlkXS5pY29uISk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGljb25VcmkgPSB0aGlzLmdldE9iamVjdFR5cGVJY29uVXJpKG9iamVjdFR5cGVJZCwgZmFsbGJhY2spO1xuICAgICAgcmV0dXJuIHRoaXMuI2JhY2tlbmQuZ2V0KGljb25VcmkpLnBpcGUodGFwKChpY29uKSA9PiAodGhpcy4jaWNvbkNhY2hlW29iamVjdFR5cGVJZF0gPSB7IHVyaTogaWNvblVyaSwgaWNvbiB9KSkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIFVSSSBvZiBhbiBvYmplY3QgdHlwZSBpY29uLlxuICAgKiBAcGFyYW0gb2JqZWN0VHlwZUlkIElEIG9mIHRoZSBvYmplY3QgdHlwZVxuICAgKiBAcGFyYW0gZmFsbGJhY2sgSUQgb2YgYSBmYWxsYmFjayBpY29uIHRoYXQgc2hvdWxkIGJlIHVzZWQgaWYgdGhlIGdpdmVuIG9iamVjdCB0eXBlIGhhcyBubyBpY29uIHlldFxuICAgKi9cbiAgZ2V0T2JqZWN0VHlwZUljb25Vcmkob2JqZWN0VHlwZUlkOiBzdHJpbmcsIGZhbGxiYWNrPzogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBpZiAodGhpcy4jaWNvbkNhY2hlW29iamVjdFR5cGVJZF0pIHtcbiAgICAgIHJldHVybiB0aGlzLiNpY29uQ2FjaGVbb2JqZWN0VHlwZUlkXS51cmk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGNpID0gdGhpcy4jZ2V0SWNvbkZyb21DbGFzc2lmaWNhdGlvbihvYmplY3RUeXBlSWQpO1xuICAgICAgY29uc3QgZmIgPSB0aGlzLmdldEZhbGxiYWNrSWNvbihvYmplY3RUeXBlSWQsIGZhbGxiYWNrKTtcbiAgICAgIGNvbnN0IHVyaSA9IGAvcmVzb3VyY2VzL2ljb25zLyR7ZW5jb2RlVVJJQ29tcG9uZW50KGNpIHx8IG9iamVjdFR5cGVJZCl9JHtmYiA/IGA/ZmFsbGJhY2s9JHtlbmNvZGVVUklDb21wb25lbnQoZmIpfWAgOiAnJ31gO1xuICAgICAgdGhpcy4jaWNvbkNhY2hlW29iamVjdFR5cGVJZF0gPSB7IHVyaTogYCR7dGhpcy4jYmFja2VuZC5nZXRBcGlCYXNlKEFwaUJhc2UuYXBpV2ViKX0ke3VyaX1gIH07XG4gICAgICByZXR1cm4gdGhpcy4jaWNvbkNhY2hlW29iamVjdFR5cGVJZF0udXJpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0RmFsbGJhY2tJY29uKG9iamVjdFR5cGVJZDogc3RyaW5nLCBmYWxsYmFjaz86IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3Qgb3QgPSB0aGlzLmdldE9iamVjdFR5cGUob2JqZWN0VHlwZUlkKTtcbiAgICBpZiAob3QgJiYgIWZhbGxiYWNrKSB7XG4gICAgICAvLyBhZGQgZGVmYXVsdCBmYWxsYmFja3MgZm9yIHN5c3RlbTpkb2N1bWVudCBhbmQgc3lzdGVtOmZvbGRlciBpZiBub3cgb3RoZXIgZmFsbGJhY2sgaGFzIGJlZW4gcHJvdmlkZWRcbiAgICAgIGZhbGxiYWNrID0gb3QuaXNGb2xkZXIgPyAnc3lzdGVtOmZvbGRlcicgOiAnc3lzdGVtOmRvY3VtZW50JztcbiAgICAgIC8vIGlmICh0aGlzLmlzRmxvYXRpbmdPYmplY3RUeXBlKG90KSkge1xuICAgICAgLy8gICAvLyB0eXBlcyB0aGF0IGRvIG5vdCBoYXZlIG5vIG9iamVjdCB0eXBlIGFzc2lnbmVkIHRvIHRoZW0gKHByaW1hcnkgRlNPVHMpXG4gICAgICAvLyAgIGZhbGxiYWNrID0gJ3N5c3RlbTpkbG0nO1xuICAgICAgLy8gfVxuICAgIH1cbiAgICByZXR1cm4gZmFsbGJhY2shO1xuICB9XG5cbiAgI2dldEljb25Gcm9tQ2xhc3NpZmljYXRpb24ob2JqZWN0VHlwZUlkOiBzdHJpbmcpIHtcbiAgICBjb25zdCBjZTogTWFwPHN0cmluZywgQ2xhc3NpZmljYXRpb25FbnRyeT4gPSB0aGlzLmdldENsYXNzaWZpY2F0aW9ucyh0aGlzLmdldFJlc29sdmVkQ2xhc3NpZmljYXRpb25zKG9iamVjdFR5cGVJZCkpO1xuICAgIHJldHVybiBjZS5oYXMoT2JqZWN0VHlwZUNsYXNzaWZpY2F0aW9uLk9CSkVDVF9UWVBFX0lDT04pID8gY2UuZ2V0KE9iamVjdFR5cGVDbGFzc2lmaWNhdGlvbi5PQkpFQ1RfVFlQRV9JQ09OKSEub3B0aW9uc1swXSA6IG51bGw7XG4gIH1cblxuICBnZXRMb2NhbGl6ZWRSZXNvdXJjZShrZXk6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuc3lzdGVtIS5pMThuW2tleV07XG4gIH1cblxuICBnZXRMb2NhbGl6ZWRMYWJlbChpZDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0TG9jYWxpemVkUmVzb3VyY2UoYCR7aWR9X2xhYmVsYCk7XG4gIH1cblxuICBnZXRMb2NhbGl6ZWREZXNjcmlwdGlvbihpZDogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0TG9jYWxpemVkUmVzb3VyY2UoYCR7aWR9X2Rlc2NyaXB0aW9uYCk7XG4gIH1cblxuICAvKipcbiAgICogRGV0ZXJtaW5lIHdoZXRoZXIgb3Igbm90IHRoZSBnaXZlbiBvYmplY3QgdHlwZSBmaWVsZCBpcyBhIHN5c3RlbSBmaWVsZFxuICAgKiBAcGFyYW0gZmllbGQgT2JqZWN0IHR5cGUgZmllbGQgdG8gYmUgY2hlY2tlZFxuICAgKi9cbiAgaXNTeXN0ZW1Qcm9wZXJ0eShmaWVsZDogT2JqZWN0VHlwZUZpZWxkKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGZpZWxkLmlkLnN0YXJ0c1dpdGgoJ3N5c3RlbTonKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGZXRjaGVzIHRoZSBiYWNrZW5kcyBzeXN0ZW0gZGVmaW5pdGlvbiBhbmQgdXBkYXRlcyBzeXN0ZW0kIE9ic2VydmFibGUuXG4gICAqIFN1YnNjcmliZSB0byB0aGUgc3lzdGVtJCBvYnNlcnZhYmxlIGluc3RlYWQgb2YgY2FsbGluZyB0aGlzIGZ1bmN0aW9uLCBvdGhlcndpc2UgeW91J2xsIHRyaWdnZXIgZmV0Y2hpbmcgdGhlXG4gICAqIHN5c3RlbSBkZWZpbml0aW9uIGV2ZXJ5IHRpbWUuXG4gICAqXG4gICAqIEBwYXJhbSB1c2VyIFRoZSB1c2VyIHRvIGxvYWQgdGhlIHN5c3RlbSBkZWZpbml0aW9uIGZvclxuICAgKi9cbiAgZ2V0U3lzdGVtRGVmaW5pdGlvbihhdXRoRGF0YT86IEF1dGhEYXRhKTogT2JzZXJ2YWJsZTxib29sZWFuPiB7XG4gICAgLy8gVE9ETzogU3VwcG9zZWQgdG8gcmV0dXJuIDMwNCBpZiBub3RoaW5nIGNoYW5nZXNcbiAgICByZXR1cm4gdGhpcy4jZmV0Y2hTeXN0ZW1EZWZpbml0aW9uKGF1dGhEYXRhKTtcblxuICAgIC8vIFRPRE86IHJlbW92ZSB3aGVuIDMwNCBpcyB0aGVyZT8/P1xuICAgIC8vIC8vIHRyeSB0byBmZXRjaCBzeXN0ZW0gZGVmaW5pdGlvbiBmcm9tIGNhY2hlIGZpcnN0XG4gICAgLy8gcmV0dXJuIHRoaXMuYXBwQ2FjaGUuZ2V0SXRlbSh0aGlzLlNUT1JBR0VfS0VZKS5waXBlKFxuICAgIC8vICAgc3dpdGNoTWFwKHJlcyA9PiB7XG4gICAgLy8gICAgIGlmIChyZXMpIHtcbiAgICAvLyAgICAgICAvLyBjaGVjayBpZiB0aGUgc3lzdGVtIGRlZmluaXRpb24gZnJvbSB0aGUgY2FjaGUgaXMgdXAgdG8gZGF0ZVxuICAgIC8vICAgICAgIHRoaXMuc3lzdGVtID0gcmVzO1xuICAgIC8vICAgICAgIHRoaXMuc3lzdGVtU291cmNlLm5leHQodGhpcy5zeXN0ZW0pO1xuICAgIC8vICAgICAgIHJldHVybiBvZih0cnVlKTtcbiAgICAvLyAgICAgfSBlbHNlIHtcbiAgICAvLyAgICAgICAvLyBub3RoaW5nIGNhY2hlZCBzbyBmYXJcbiAgICAvLyAgICAgICByZXR1cm4gdGhpcy5mZXRjaFN5c3RlbURlZmluaXRpb24oKTtcbiAgICAvLyAgICAgfVxuICAgIC8vICAgfSlcbiAgICAvLyApO1xuICB9XG5cbiAgLyoqXG4gICAqIEFjdHVhbGx5IGZldGNoIHRoZSBzeXN0ZW0gZGVmaW5pdGlvbiBmcm9tIHRoZSBiYWNrZW5kLlxuICAgKiBAcGFyYW0gdXNlciBVc2VyIHRvIGZldGNoIGRlZmluaXRpb24gZm9yXG4gICAqL1xuICAjZmV0Y2hTeXN0ZW1EZWZpbml0aW9uKGF1dGhEYXRhPzogQXV0aERhdGEpOiBPYnNlcnZhYmxlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gKGF1dGhEYXRhID8gb2YoYXV0aERhdGEpIDogdGhpcy4jYXBwQ2FjaGUuZ2V0SXRlbSh0aGlzLiNTVE9SQUdFX0tFWV9BVVRIX0RBVEEpKS5waXBlKFxuICAgICAgc3dpdGNoTWFwKChkYXRhOiBBdXRoRGF0YSkgPT4ge1xuICAgICAgICB0aGlzLnVwZGF0ZUF1dGhEYXRhKGRhdGEpLnN1YnNjcmliZSgpO1xuICAgICAgICBjb25zdCBmZXRjaFRhc2tzID0gW3RoaXMuI2JhY2tlbmQuZ2V0KCcvZG1zL3NjaGVtYS9uYXRpdmUuanNvbicsIEFwaUJhc2UuY29yZSksIHRoaXMuI2ZldGNoTG9jYWxpemF0aW9ucygpXTtcbiAgICAgICAgcmV0dXJuIGZvcmtKb2luKGZldGNoVGFza3MpO1xuICAgICAgfSksXG4gICAgICBjYXRjaEVycm9yKChlcnJvcikgPT4ge1xuICAgICAgICB0aGlzLiNsb2dnZXIuZXJyb3IoJ0Vycm9yIGZldGNoaW5nIHJlY2VudCB2ZXJzaW9uIG9mIHN5c3RlbSBkZWZpbml0aW9uIGZyb20gc2VydmVyLicsIGVycm9yKTtcbiAgICAgICAgdGhpcy4jc3lzdGVtU291cmNlLmVycm9yKCdFcnJvciBmZXRjaGluZyByZWNlbnQgdmVyc2lvbiBvZiBzeXN0ZW0gZGVmaW5pdGlvbiBmcm9tIHNlcnZlci4nKTtcbiAgICAgICAgcmV0dXJuIG9mKG51bGwpO1xuICAgICAgfSksXG4gICAgICBtYXAoKGRhdGEpID0+IHtcbiAgICAgICAgaWYgKGRhdGE/Lmxlbmd0aCkge1xuICAgICAgICAgIHRoaXMuc2V0U2NoZW1hKGRhdGFbMF0sIGRhdGFbMV0pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAhIWRhdGE7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBzZXRQZXJtaXNzaW9ucyhwOiBPYmplY3RUeXBlUGVybWlzc2lvbnMpIHtcbiAgICB0aGlzLiNwZXJtaXNzaW9ucyA9IHA7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlIHRoZSBzY2hlbWEgZnJvbSB0aGUgc2VydmVycyBzY2hlbWEgcmVzcG9uc2VcbiAgICogQHBhcmFtIHNjaGVtYVJlc3BvbnNlIFJlc3BvbnNlIGZyb20gdGhlIGJhY2tlbmRcbiAgICovXG4gIHNldFNjaGVtYShzY2hlbWFSZXNwb25zZTogU2NoZW1hUmVzcG9uc2UsIGxvY2FsaXplZFJlc291cmNlOiBMb2NhbGl6YXRpb24gPSB7fSkge1xuICAgIC8vIHByZXBhcmUgYSBxdWljayBhY2Nlc3Mgb2JqZWN0IGZvciB0aGUgZmllbGRzXG4gICAgY29uc3QgcHJvcGVydGllc1FBOiBSZWNvcmQ8c3RyaW5nLCBTY2hlbWFSZXNwb25zZUZpZWxkRGVmaW5pdGlvbj4gPSB7fTtcbiAgICBjb25zdCBvcmdUeXBlRmllbGRzID0gW0Jhc2VPYmplY3RUeXBlRmllbGQuTU9ESUZJRURfQlksIEJhc2VPYmplY3RUeXBlRmllbGQuQ1JFQVRFRF9CWV07XG4gICAgc2NoZW1hUmVzcG9uc2UucHJvcGVydHlEZWZpbml0aW9uLmZvckVhY2goKHA6IGFueSkgPT4ge1xuICAgICAgcC5jbGFzc2lmaWNhdGlvbnMgPSBwLmNsYXNzaWZpY2F0aW9uO1xuICAgICAgLy8gVE9ETzogUmVtb3ZlIG9uY2Ugc2NoZW1hIHN1cHBvcnRzIG9yZ2FuaXphdGlvbiBjbGFzc2lmaWNhdGlvbiBmb3IgYmFzZSBwYXJhbXNcbiAgICAgIC8vIG1hcCBjZXJ0YWluIGZpZWxkcyB0byBvcmdhbml6YXRpb24gdHlwZSAoZmFrZSBpdCB1bnRpbCB5b3UgbWFrZSBpdCA7LSlcbiAgICAgIGlmIChvcmdUeXBlRmllbGRzLmluY2x1ZGVzKHAuaWQpKSB7XG4gICAgICAgIHAuY2xhc3NpZmljYXRpb25zID0gW0NsYXNzaWZpY2F0aW9uLlNUUklOR19PUkdBTklaQVRJT05dO1xuICAgICAgfVxuICAgICAgcHJvcGVydGllc1FBW3AuaWRdID0gcDtcbiAgICB9KTtcbiAgICAvLyBwcmVwYXJlIGEgcXVpY2sgYWNjZXNzIG9iamVjdCBmb3Igb2JqZWN0IHR5cGVzIChpbmNsdWRpbmcgc2Vjb25kYXJ5IG9iamVjdHMpXG4gICAgY29uc3Qgb2JqZWN0VHlwZXNRQTogeyBbaWQ6IHN0cmluZ106IFNjaGVtYVJlc3BvbnNlVHlwZURlZmluaXRpb24gfSA9IHt9O1xuICAgIHNjaGVtYVJlc3BvbnNlLnR5cGVGb2xkZXJEZWZpbml0aW9uLmZvckVhY2goKG90OiBhbnkpID0+IHtcbiAgICAgIG9iamVjdFR5cGVzUUFbb3QuaWRdID0gb3Q7XG4gICAgfSk7XG4gICAgc2NoZW1hUmVzcG9uc2UudHlwZURvY3VtZW50RGVmaW5pdGlvbi5mb3JFYWNoKChvdDogYW55KSA9PiB7XG4gICAgICBvYmplY3RUeXBlc1FBW290LmlkXSA9IG90O1xuICAgIH0pO1xuICAgIHNjaGVtYVJlc3BvbnNlLnR5cGVTZWNvbmRhcnlEZWZpbml0aW9uLmZvckVhY2goKHNvdDogYW55KSA9PiB7XG4gICAgICBvYmplY3RUeXBlc1FBW3NvdC5pZF0gPSBzb3Q7XG4gICAgfSk7XG5cbiAgICBjb25zdCBvYmplY3RUeXBlczogT2JqZWN0VHlwZVtdID0gW1xuICAgICAgLy8gZm9sZGVyIHR5cGVzXG4gICAgICAuLi5zY2hlbWFSZXNwb25zZS50eXBlRm9sZGVyRGVmaW5pdGlvbi5tYXAoKGZkKSA9PiAoe1xuICAgICAgICBpZDogZmQuaWQsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBmZC5kZXNjcmlwdGlvbixcbiAgICAgICAgY2xhc3NpZmljYXRpb246IGZkLmNsYXNzaWZpY2F0aW9uLFxuICAgICAgICBiYXNlSWQ6IGZkLmJhc2VJZCxcbiAgICAgICAgY3JlYXRhYmxlOiB0aGlzLiNpc0NyZWF0YWJsZShmZC5pZCksXG4gICAgICAgIGNvbnRlbnRTdHJlYW1BbGxvd2VkOiBDb250ZW50U3RyZWFtQWxsb3dlZC5OT1RfQUxMT1dFRCxcbiAgICAgICAgaXNGb2xkZXI6IHRydWUsXG4gICAgICAgIHNlY29uZGFyeU9iamVjdFR5cGVzOiBmZC5zZWNvbmRhcnlPYmplY3RUeXBlSWQgPyBmZC5zZWNvbmRhcnlPYmplY3RUeXBlSWQubWFwKCh0KSA9PiAoeyBpZDogdC52YWx1ZSwgc3RhdGljOiB0LnN0YXRpYyB9KSkgOiBbXSxcbiAgICAgICAgZmllbGRzOiB0aGlzLiNyZXNvbHZlT2JqZWN0VHlwZUZpZWxkcyhmZCwgcHJvcGVydGllc1FBLCBvYmplY3RUeXBlc1FBKVxuICAgICAgICAvLyByYXdGaWVsZHM6IHRoaXMucmVzb2x2ZU9iamVjdFR5cGVGaWVsZHMoZmQsIHByb3BlcnRpZXNRQSwgb2JqZWN0VHlwZXNRQSwgdHJ1ZSksXG4gICAgICB9KSksXG4gICAgICAvLyBkb2N1bWVudCB0eXBlc1xuICAgICAgLi4uc2NoZW1hUmVzcG9uc2UudHlwZURvY3VtZW50RGVmaW5pdGlvbi5tYXAoKGRkKSA9PiAoe1xuICAgICAgICBpZDogZGQuaWQsXG4gICAgICAgIGRlc2NyaXB0aW9uOiBkZC5kZXNjcmlwdGlvbixcbiAgICAgICAgY2xhc3NpZmljYXRpb246IGRkLmNsYXNzaWZpY2F0aW9uLFxuICAgICAgICBiYXNlSWQ6IGRkLmJhc2VJZCxcbiAgICAgICAgY3JlYXRhYmxlOiB0aGlzLiNpc0NyZWF0YWJsZShkZC5pZCksXG4gICAgICAgIGNvbnRlbnRTdHJlYW1BbGxvd2VkOiBkZC5jb250ZW50U3RyZWFtQWxsb3dlZCxcbiAgICAgICAgaXNGb2xkZXI6IGZhbHNlLFxuICAgICAgICBzZWNvbmRhcnlPYmplY3RUeXBlczogZGQuc2Vjb25kYXJ5T2JqZWN0VHlwZUlkID8gZGQuc2Vjb25kYXJ5T2JqZWN0VHlwZUlkLm1hcCgodCkgPT4gKHsgaWQ6IHQudmFsdWUsIHN0YXRpYzogdC5zdGF0aWMgfSkpIDogW10sXG4gICAgICAgIGZpZWxkczogdGhpcy4jcmVzb2x2ZU9iamVjdFR5cGVGaWVsZHMoZGQsIHByb3BlcnRpZXNRQSwgb2JqZWN0VHlwZXNRQSlcbiAgICAgICAgLy8gcmF3RmllbGRzOiB0aGlzLnJlc29sdmVPYmplY3RUeXBlRmllbGRzKGRkLCBwcm9wZXJ0aWVzUUEsIG9iamVjdFR5cGVzUUEsIHRydWUpLFxuICAgICAgfSkpXG4gICAgXTtcblxuICAgIGNvbnN0IHNlY29uZGFyeU9iamVjdFR5cGVzOiBTZWNvbmRhcnlPYmplY3RUeXBlW10gPSBzY2hlbWFSZXNwb25zZS50eXBlU2Vjb25kYXJ5RGVmaW5pdGlvbi5tYXAoKHN0ZCkgPT4gKHtcbiAgICAgIGlkOiBzdGQuaWQsXG4gICAgICBkZXNjcmlwdGlvbjogc3RkLmRlc2NyaXB0aW9uLFxuICAgICAgY2xhc3NpZmljYXRpb246IHN0ZC5jbGFzc2lmaWNhdGlvbixcbiAgICAgIGNvbnRlbnRTdHJlYW1BbGxvd2VkOiBzdGQuY29udGVudFN0cmVhbUFsbG93ZWQsXG4gICAgICBiYXNlSWQ6IHN0ZC5iYXNlSWQsXG4gICAgICAvLyBUT0RPOiBDb3VsZCBhIFNPVCBiZSBhIGZvbGRlciB0b28/XG4gICAgICBpc0ZvbGRlcjogZmFsc2UsXG4gICAgICBmaWVsZHM6IHRoaXMuI3Jlc29sdmVPYmplY3RUeXBlRmllbGRzKHN0ZCwgcHJvcGVydGllc1FBLCBvYmplY3RUeXBlc1FBKVxuICAgIH0pKTtcblxuICAgIHRoaXMuc3lzdGVtID0ge1xuICAgICAgdmVyc2lvbjogc2NoZW1hUmVzcG9uc2UudmVyc2lvbixcbiAgICAgIGxhc3RNb2RpZmljYXRpb25EYXRlOiBzY2hlbWFSZXNwb25zZS5sYXN0TW9kaWZpY2F0aW9uRGF0ZSxcbiAgICAgIG9iamVjdFR5cGVzLFxuICAgICAgc2Vjb25kYXJ5T2JqZWN0VHlwZXMsXG4gICAgICBpMThuOiBsb2NhbGl6ZWRSZXNvdXJjZSxcbiAgICAgIGFsbEZpZWxkczogcHJvcGVydGllc1FBXG4gICAgfTtcbiAgICB0aGlzLiNhcHBDYWNoZS5zZXRJdGVtKHRoaXMuI1NUT1JBR0VfS0VZLCB0aGlzLnN5c3RlbSkuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy4jc3lzdGVtU291cmNlLm5leHQodGhpcy5zeXN0ZW0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmUgYWxsIHRoZSBmaWVsZHMgZm9yIGFuIG9iamVjdCB0eXBlLiBUaGlzIGFsc28gaW5jbHVkZXMgc2Vjb25kYXJ5IG9iamVjdCB0eXBlcyBhbmQgdGhlIGZpZWxkcyBpbmhlcml0ZWQgZnJvbVxuICAgKiB0aGUgYmFzZSB0eXBlICguLi4gYW5kIG9mIGNvdXJzZSB0aGUgYmFzZSB0eXBlIChhbmQgaXRzIHNlY29uZGFyeSBvYmplY3QgdHlwZXMpIG9mIHRoZSBiYXNlIHR5cGUgYW5kIHNvIG9uKVxuICAgKiBAcGFyYW0gc2NoZW1hVHlwZURlZmluaXRpb24gb2JqZWN0IHR5cGUgZGVmaW5pdGlvbiBmcm9tIHRoZSBuYXRpdmUgc2NoZW1hXG4gICAqIEBwYXJhbSBwcm9wZXJ0aWVzUUEgUXVpY2sgYWNjZXNzIG9iamVjdCBvZiBhbGwgcHJvcGVydGllc1xuICAgKiBAcGFyYW0gb2JqZWN0VHlwZXNRQSBRdWljayBhY2Nlc3Mgb2JqZWN0IG9mIGFsbCBvYmplY3QgdHlwZXNcbiAgICogQHBhcmFtIHJhdyBJZiBzZXQgdG8gJ3RydWUnIG9ubHkgdGhlIHByb3BlcnRpZXMgb2YgdGhlIG9iamVjdCB0eXBlIGl0c2VsZiB3aWxsIGJlIHJldHVybmVkICh3aXRob3V0IFNPVHMpXG4gICAqL1xuICAjcmVzb2x2ZU9iamVjdFR5cGVGaWVsZHMoXG4gICAgc2NoZW1hVHlwZURlZmluaXRpb246IFNjaGVtYVJlc3BvbnNlVHlwZURlZmluaXRpb24sXG4gICAgcHJvcGVydGllc1FBOiB7IFtpZDogc3RyaW5nXTogU2NoZW1hUmVzcG9uc2VGaWVsZERlZmluaXRpb24gfSxcbiAgICBvYmplY3RUeXBlc1FBOiB7IFtpZDogc3RyaW5nXTogU2NoZW1hUmVzcG9uc2VUeXBlRGVmaW5pdGlvbiB9XG4gICk6IE9iamVjdFR5cGVGaWVsZFtdIHtcbiAgICBjb25zdCBvYmplY3RUeXBlRmllbGRJRHMgPSBzY2hlbWFUeXBlRGVmaW5pdGlvbi5wcm9wZXJ0eVJlZmVyZW5jZS5tYXAoKHByKSA9PiBwci52YWx1ZSk7XG4gICAgaWYgKHNjaGVtYVR5cGVEZWZpbml0aW9uLnNlY29uZGFyeU9iamVjdFR5cGVJZCkge1xuICAgICAgc2NoZW1hVHlwZURlZmluaXRpb24uc2Vjb25kYXJ5T2JqZWN0VHlwZUlkXG4gICAgICAgIC5maWx0ZXIoKHNvdCkgPT4gc290LnN0YXRpYylcbiAgICAgICAgLm1hcCgoc290KSA9PiBzb3QudmFsdWUpXG4gICAgICAgIC5mb3JFYWNoKChzb3RJRCkgPT4gb2JqZWN0VHlwZXNRQVtzb3RJRF0ucHJvcGVydHlSZWZlcmVuY2UuZm9yRWFjaCgocHI6IHsgdmFsdWU6IHN0cmluZyB9KSA9PiBvYmplY3RUeXBlRmllbGRJRHMucHVzaChwci52YWx1ZSkpKTtcbiAgICB9XG5cbiAgICBsZXQgZmllbGRzOiBPYmplY3RUeXBlRmllbGRbXSA9IG9iamVjdFR5cGVGaWVsZElEcy5tYXAoKGlkKSA9PiAoe1xuICAgICAgLi4ucHJvcGVydGllc1FBW2lkXSxcbiAgICAgIF9pbnRlcm5hbFR5cGU6IHRoaXMuZ2V0SW50ZXJuYWxGb3JtRWxlbWVudFR5cGUocHJvcGVydGllc1FBW2lkXS5wcm9wZXJ0eVR5cGUsIHByb3BlcnRpZXNRQVtpZF0uY2xhc3NpZmljYXRpb25zKVxuICAgIH0pKTtcblxuICAgIC8vIGFsc28gcmVzb2x2ZSBwcm9wZXJ0aWVzIG9mIHRoZSBiYXNlIHR5cGVcbiAgICBpZiAoc2NoZW1hVHlwZURlZmluaXRpb24uYmFzZUlkICE9PSBzY2hlbWFUeXBlRGVmaW5pdGlvbi5pZCAmJiAhIW9iamVjdFR5cGVzUUFbc2NoZW1hVHlwZURlZmluaXRpb24uYmFzZUlkXSkge1xuICAgICAgZmllbGRzID0gZmllbGRzLmNvbmNhdCh0aGlzLiNyZXNvbHZlT2JqZWN0VHlwZUZpZWxkcyhvYmplY3RUeXBlc1FBW3NjaGVtYVR5cGVEZWZpbml0aW9uLmJhc2VJZF0sIHByb3BlcnRpZXNRQSwgb2JqZWN0VHlwZXNRQSkpO1xuICAgIH1cbiAgICByZXR1cm4gZmllbGRzO1xuICB9XG5cbiAgI2lzQ3JlYXRhYmxlKG9iamVjdFR5cGVJZDogc3RyaW5nKSB7XG4gICAgcmV0dXJuICFbU3lzdGVtVHlwZS5GT0xERVIsIFN5c3RlbVR5cGUuRE9DVU1FTlRdLmluY2x1ZGVzKG9iamVjdFR5cGVJZCk7XG4gIH1cblxuICAvKipcbiAgICogRmV0Y2ggYSBjb2xsZWN0aW9uIG9mIGZvcm0gbW9kZWxzLlxuICAgKiBAcGFyYW0gb2JqZWN0VHlwZUlEcyBPYmplY3QgdHlwZSBJRHMgdG8gZmV0Y2ggZm9ybSBtb2RlbCBmb3JcbiAgICogQHBhcmFtIHNpdHVhdGlvbiBGb3JtIHNpdHVhdGlvblxuICAgKiBAcmV0dXJucyBPYmplY3Qgd2hlcmUgdGhlIG9iamVjdCB0eXBlIGlkIGlzIGtleSBhbmQgdGhlIGZvcm0gbW9kZWwgaXMgdGhlIHZhbHVlXG4gICAqL1xuICBnZXRPYmplY3RUeXBlRm9ybXMob2JqZWN0VHlwZUlEczogc3RyaW5nW10sIHNpdHVhdGlvbjogc3RyaW5nKTogT2JzZXJ2YWJsZTxSZWNvcmQ8c3RyaW5nLCBhbnk+PiB7XG4gICAgcmV0dXJuIGZvcmtKb2luKFxuICAgICAgb2JqZWN0VHlwZUlEcy5tYXAoKG8pID0+XG4gICAgICAgIHRoaXMuZ2V0T2JqZWN0VHlwZUZvcm0obywgc2l0dWF0aW9uKS5waXBlKFxuICAgICAgICAgIGNhdGNoRXJyb3IoKGUpID0+IG9mKG51bGwpKSxcbiAgICAgICAgICBtYXAoKHJlcykgPT4gKHtcbiAgICAgICAgICAgIGlkOiBvLFxuICAgICAgICAgICAgZm9ybU1vZGVsOiByZXNcbiAgICAgICAgICB9KSlcbiAgICAgICAgKVxuICAgICAgKVxuICAgICkucGlwZShcbiAgICAgIG1hcCgocmVzKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc01hcDogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xuICAgICAgICByZXMuZmlsdGVyKChyKSA9PiB0aGlzLiNmb3JtSGFzRWxlbWVudHMoci5mb3JtTW9kZWwpKS5mb3JFYWNoKChyOiBhbnkpID0+IChyZXNNYXBbci5pZF0gPSByLmZvcm1Nb2RlbCkpO1xuICAgICAgICByZXR1cm4gcmVzTWFwO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0aGUgZm9ybSBtb2RlbCBvZiBhbiBvYmplY3QgdHlwZS5cbiAgICpcbiAgICogQHBhcmFtIG9iamVjdFR5cGVJZCBJRCBvZiB0aGUgb2JqZWN0IHR5cGUgdG8gZmV0Y2ggdGhlIGZvcm0gZm9yXG4gICAqIEBwYXJhbSBzaXR1YXRpb24gVGhlIGZvcm0gc2l0dWF0aW9uIHRvIGJlIGZldGNoZWRcbiAgICogQHJldHVybnMgRm9ybSBtb2RlbFxuICAgKi9cbiAgZ2V0T2JqZWN0VHlwZUZvcm0ob2JqZWN0VHlwZUlkOiBzdHJpbmcsIHNpdHVhdGlvbjogc3RyaW5nKTogT2JzZXJ2YWJsZTxhbnk+IHtcbiAgICByZXR1cm4gdGhpcy4jYmFja2VuZC5nZXQoVXRpbHMuYnVpbGRVcmkoYC9kbXMvZm9ybXMvJHtvYmplY3RUeXBlSWR9YCwgeyBzaXR1YXRpb24gfSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrIHdoZXRoZXIgb3Igbm90IHRoZSBtb2RlbCBoYXMgYXQgbGVhc3Qgb25lIGZvcm0gZWxlbWVudC4gUmVjdXJzaXZlLlxuICAgKiBAcGFyYW0gZWxlbWVudCBGb3JtIGVsZW1lbnQgdG8gY2hlY2sgY2hpbGQgZWxlbWVudHMgZm9yXG4gICAqL1xuICAjZm9ybUhhc0VsZW1lbnRzKGVsZW1lbnQ6IGFueSk6IGJvb2xlYW4ge1xuICAgIGxldCBoYXNFbGVtZW50ID0gZmFsc2U7XG4gICAgZWxlbWVudC5lbGVtZW50cz8uZm9yRWFjaCgoZTogYW55KSA9PiB7XG4gICAgICBpZiAoIVsnbzJtR3JvdXAnLCAnbzJtR3JvdXBTdGFjayddLmluY2x1ZGVzKGUudHlwZSkpIHtcbiAgICAgICAgaGFzRWxlbWVudCA9IHRydWU7XG4gICAgICB9IGVsc2UgaWYgKCFoYXNFbGVtZW50KSB7XG4gICAgICAgIGhhc0VsZW1lbnQgPSB0aGlzLiNmb3JtSGFzRWxlbWVudHMoZSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGhhc0VsZW1lbnQ7XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGVzIGFuIGludGVybmFsIHR5cGUgZm9yIGEgZ2l2ZW4gb2JqZWN0IHR5cGUgZmllbGQuXG4gICAqIEFkZGluZyB0aGlzIHRvIGEgZm9ybSBlbGVtZW50IG9yIG9iamVjdCB0eXBlIGZpZWxkIGVuYWJsZXMgdXMgdG8gcmVuZGVyIGZvcm1zXG4gICAqIGJhc2VkIG9uIG9iamVjdCB0eXBlIGZpZWxkcyBpbiBhIG1vcmUgcGVyZm9ybWFudCB3YXkuIE90aGVyd2lzZSB3ZSB3b3VsZFxuICAgKiBoYXZlIHRvIGV2YWx1YXRlIHRoZSBjb25kaXRpb25zIGZvciBldmVyeSBmb3JtIGVsZW1lbnQgb24gZXZlcnkgZGlnZXN0IGN5Y2xlLlxuICAgKiBAcGFyYW0gdHlwZSBwcm9wZXJ0eVR5cGUgb2YgdGhlIE9iamVjdFR5cGVGaWVsZFxuICAgKiBAcGFyYW0gY2xhc3NpZmljYXRpb25zIGNsYXNzaWZpY2F0aW9ucyBvZiB0aGUgT2JqZWN0VHlwZUZpZWxkXG4gICAqL1xuICBnZXRJbnRlcm5hbEZvcm1FbGVtZW50VHlwZSh0eXBlOiBzdHJpbmcsIGNsYXNzaWZpY2F0aW9ucz86IHN0cmluZ1tdKTogT2JqZWN0VHlwZUZpZWxkSW50ZXJuYWxUeXBlIHtcbiAgICBjb25zdCBfY2xhc3NpZmljYXRpb25zID0gdGhpcy5nZXRDbGFzc2lmaWNhdGlvbnMoY2xhc3NpZmljYXRpb25zIHx8IFtdKTtcblxuICAgIGlmICh0eXBlID09PSAnc3RyaW5nJyAmJiBfY2xhc3NpZmljYXRpb25zLmhhcyhDbGFzc2lmaWNhdGlvbi5TVFJJTkdfUkVGRVJFTkNFKSkge1xuICAgICAgcmV0dXJuIEludGVybmFsRmllbGRUeXBlLlNUUklOR19SRUZFUkVOQ0U7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJyAmJiBfY2xhc3NpZmljYXRpb25zLmhhcyhDbGFzc2lmaWNhdGlvbi5TVFJJTkdfT1JHQU5JWkFUSU9OKSkge1xuICAgICAgcmV0dXJuIEludGVybmFsRmllbGRUeXBlLlNUUklOR19PUkdBTklaQVRJT047XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJyAmJiBfY2xhc3NpZmljYXRpb25zLmhhcyhDbGFzc2lmaWNhdGlvbi5TVFJJTkdfT1JHQU5JWkFUSU9OX1NFVCkpIHtcbiAgICAgIHJldHVybiBJbnRlcm5hbEZpZWxkVHlwZS5TVFJJTkdfT1JHQU5JWkFUSU9OX1NFVDtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICdzdHJpbmcnICYmIF9jbGFzc2lmaWNhdGlvbnMuaGFzKENsYXNzaWZpY2F0aW9uLlNUUklOR19DQVRBTE9HKSkge1xuICAgICAgcmV0dXJuIEludGVybmFsRmllbGRUeXBlLlNUUklOR19DQVRBTE9HO1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJ2Jvb2xlYW4nICYmIF9jbGFzc2lmaWNhdGlvbnMuaGFzKENsYXNzaWZpY2F0aW9uLkJPT0xFQU5fU1dJVENIKSkge1xuICAgICAgcmV0dXJuIEludGVybmFsRmllbGRUeXBlLkJPT0xFQU5fU1dJVENIO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICB0eXBlID09PSAnc3RyaW5nJyAmJlxuICAgICAgKF9jbGFzc2lmaWNhdGlvbnMuaGFzKENsYXNzaWZpY2F0aW9uLlNUUklOR19DQVRBTE9HX0RZTkFNSUMpIHx8IF9jbGFzc2lmaWNhdGlvbnMuaGFzKENsYXNzaWZpY2F0aW9uLlNUUklOR19DQVRBTE9HX0NVU1RPTSkpXG4gICAgKSB7XG4gICAgICByZXR1cm4gSW50ZXJuYWxGaWVsZFR5cGUuU1RSSU5HX0RZTkFNSUNfQ0FUQUxPRztcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gaWYgdGhlcmUgYXJlIG5vIG1hdGNoaW5nIGNvbmRpdGlvbnMganVzdCByZXR1cm4gdGhlIG9yaWdpbmFsIHR5cGVcbiAgICAgIHJldHVybiB0eXBlIGFzIE9iamVjdFR5cGVGaWVsZFR5cGU7XG4gICAgfVxuICB9XG5cbiAgZ2V0T2JqZWN0VHlwZUZpZWxkKGlkOiBzdHJpbmcpOiBPYmplY3RUeXBlRmllbGQgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IGYgPSB0aGlzLnN5c3RlbT8uYWxsRmllbGRzW2lkXTtcbiAgICByZXR1cm4gZiA/IHsgLi4uZiwgX2ludGVybmFsVHlwZTogdGhpcy5nZXRJbnRlcm5hbEZvcm1FbGVtZW50VHlwZShmLnByb3BlcnR5VHlwZSwgZi5jbGFzc2lmaWNhdGlvbnMpIH0gOiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogRXh0cmFjdCBjbGFzc2lmaWNhdGlvbnMgZnJvbSBvYmplY3QgdHlwZSBmaWVsZHMgY2xhc3NpZmljYXRpb25cbiAgICogc3RyaW5nLiBUaGlzIHN0cmluZyBtYXkgY29udGFpbiBtb3JlIHRoYW4gb25lIGNsYXNzaWZpY2F0aW9uIGVudHJ5LlxuICAgKlxuICAgKiBDbGFzc2lmaWNhdGlvbiBpcyBhIGNvbW1hIHNlcGFyYXRlZCBzdHJpbmcgdGhhdCBtYXkgY29udGFpbiBhZGRpdGlvbmFsXG4gICAqIHByb3BlcnRpZXMgcmVsYXRlZCB0byBvbiBjbGFzc2lmaWNhdGlvbiBlbnRyeS4gRXhhbXBsZTpcbiAgICpcbiAgICogYGlkOnJlZmVyZW5jZVtzeXN0ZW06Zm9sZGVyXSwgZW1haWxgXG4gICAqXG4gICAqIEBwYXJhbSBjbGFzc2lmaWNhdGlvbnMgT2JqZWN0IHR5cGUgZmllbGRzIGNsYXNzaWZpY2F0aW9uIHByb3BlcnR5IChzY2hlbWEpXG4gICAqL1xuICBnZXRDbGFzc2lmaWNhdGlvbnMoY2xhc3NpZmljYXRpb25zOiBzdHJpbmdbXSk6IE1hcDxzdHJpbmcsIENsYXNzaWZpY2F0aW9uRW50cnk+IHtcbiAgICBjb25zdCByZXMgPSBuZXcgTWFwPHN0cmluZywgQ2xhc3NpZmljYXRpb25FbnRyeT4oKTtcbiAgICBpZiAoY2xhc3NpZmljYXRpb25zKSB7XG4gICAgICBjbGFzc2lmaWNhdGlvbnMuZm9yRWFjaCgoYykgPT4ge1xuICAgICAgICBjb25zdCBtYXRjaGVzOiBSZWdFeHBNYXRjaEFycmF5IHwgbnVsbCA9IGMubWF0Y2goL14oW15cXFtdKikoXFxbKC4qKVxcXSk/JC8pO1xuICAgICAgICBpZiAobWF0Y2hlcyAmJiBtYXRjaGVzLmxlbmd0aCkge1xuICAgICAgICAgIHJlcy5zZXQobWF0Y2hlc1sxXSwge1xuICAgICAgICAgICAgY2xhc3NpZmljYXRpb246IG1hdGNoZXNbMV0sXG4gICAgICAgICAgICBvcHRpb25zOiBtYXRjaGVzWzNdID8gbWF0Y2hlc1szXS5zcGxpdCgnLCcpLm1hcCgobykgPT4gby50cmltKCkpIDogW11cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiByZXM7XG4gIH1cblxuICB0b0Zvcm1FbGVtZW50KGZpZWxkOiBPYmplY3RUeXBlRmllbGQpOiBhbnkge1xuICAgIHJldHVybiB7IC4uLmZpZWxkLCBsYWJlbDogdGhpcy5nZXRMb2NhbGl6ZWRMYWJlbChmaWVsZC5pZCksIG5hbWU6IGZpZWxkLmlkLCB0eXBlOiBmaWVsZC5wcm9wZXJ0eVR5cGUgfTtcbiAgfVxuXG4gIHVwZGF0ZUF1dGhEYXRhKGRhdGE6IFBhcnRpYWw8QXV0aERhdGE+KSB7XG4gICAgdGhpcy5hdXRoRGF0YSA9IHsgLi4udGhpcy5hdXRoRGF0YSEsIC4uLmRhdGEgfTtcbiAgICB0aGlzLiNiYWNrZW5kLnNldEhlYWRlcignQWNjZXB0LUxhbmd1YWdlJywgdGhpcy5hdXRoRGF0YS5sYW5ndWFnZSk7XG4gICAgcmV0dXJuIHRoaXMuI2FwcENhY2hlLnNldEl0ZW0odGhpcy4jU1RPUkFHRV9LRVlfQVVUSF9EQVRBLCB0aGlzLmF1dGhEYXRhKTtcbiAgfVxuXG4gIHVwZGF0ZUxvY2FsaXphdGlvbnMoaXNvOiBzdHJpbmcpOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgIHJldHVybiB0aGlzLnVwZGF0ZUF1dGhEYXRhKHsgbGFuZ3VhZ2U6IGlzbyB9KS5waXBlKFxuICAgICAgc3dpdGNoTWFwKCgpID0+IHRoaXMuI2ZldGNoTG9jYWxpemF0aW9ucygpKSxcbiAgICAgIHRhcCgocmVzKSA9PiB7XG4gICAgICAgIHRoaXMuc3lzdGVtIS5pMThuID0gcmVzO1xuICAgICAgICB0aGlzLiNhcHBDYWNoZS5zZXRJdGVtKHRoaXMuI1NUT1JBR0VfS0VZLCB0aGlzLnN5c3RlbSkuc3Vic2NyaWJlKCk7XG4gICAgICAgIHRoaXMuI3N5c3RlbVNvdXJjZS5uZXh0KHRoaXMuc3lzdGVtISk7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICAjZmV0Y2hMb2NhbGl6YXRpb25zKCk6IE9ic2VydmFibGU8TG9jYWxpemF0aW9uPiB7XG4gICAgcmV0dXJuIHRoaXMuI2JhY2tlbmQuZ2V0KCcvcmVzb3VyY2VzL3RleHQnKTtcbiAgfVxuXG4gIGZldGNoUmVzb3VyY2VzKGlkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPHsgZ2xvYmFsOiBhbnk7IHRlbmFudDogYW55IH0+IHtcbiAgICByZXR1cm4gdGhpcy4jYmFja2VuZFxuICAgICAgLmJhdGNoKFtcbiAgICAgICAgeyB1cmk6IGAvc3lzdGVtL3Jlc291cmNlcy8ke2lkfWAsIGJhc2U6IEFwaUJhc2UuY29yZSB9LFxuICAgICAgICB7IHVyaTogYC9hZG1pbi9yZXNvdXJjZXMvJHtpZH1gLCBiYXNlOiBBcGlCYXNlLmNvcmUgfVxuICAgICAgXSlcbiAgICAgIC5waXBlKG1hcCgoW2dsb2JhbCwgdGVuYW50XSkgPT4gKHsgZ2xvYmFsLCB0ZW5hbnQgfSkpKTtcbiAgfVxufVxuIl19