@idea-ionic/uncommon 8.2.1

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 (80) hide show
  1. package/LICENSE +373 -0
  2. package/README.md +21 -0
  3. package/css/global.scss +15 -0
  4. package/esm2022/idea-ionic-uncommon.mjs +5 -0
  5. package/esm2022/public-api.mjs +35 -0
  6. package/esm2022/src/AWSAPI.service.mjs +430 -0
  7. package/esm2022/src/AWSAPISocket.service.mjs +187 -0
  8. package/esm2022/src/address/address.component.mjs +94 -0
  9. package/esm2022/src/address/address.module.mjs +21 -0
  10. package/esm2022/src/announcement/announcement.component.mjs +41 -0
  11. package/esm2022/src/announcement/announcement.module.mjs +21 -0
  12. package/esm2022/src/cachedResources.service.mjs +55 -0
  13. package/esm2022/src/colors/colorPicker.component.mjs +135 -0
  14. package/esm2022/src/colors/colorPicker.module.mjs +20 -0
  15. package/esm2022/src/contacts/contacts.component.mjs +64 -0
  16. package/esm2022/src/contacts/contacts.module.mjs +21 -0
  17. package/esm2022/src/dateTime/calendarPicker.component.mjs +196 -0
  18. package/esm2022/src/dateTime/dateTime.component.mjs +133 -0
  19. package/esm2022/src/dateTime/dateTime.module.mjs +22 -0
  20. package/esm2022/src/duration/duration.component.mjs +77 -0
  21. package/esm2022/src/duration/duration.module.mjs +21 -0
  22. package/esm2022/src/echo/echo.module.mjs +26 -0
  23. package/esm2022/src/echo/echo.page.mjs +165 -0
  24. package/esm2022/src/errorReporting.service.mjs +68 -0
  25. package/esm2022/src/mde/mde.component.mjs +44 -0
  26. package/esm2022/src/mde/mde.module.mjs +22 -0
  27. package/esm2022/src/mde/mdeToolbar.component.mjs +12 -0
  28. package/esm2022/src/offline/cacheableResource.component.mjs +18 -0
  29. package/esm2022/src/offline/offline.module.mjs +22 -0
  30. package/esm2022/src/offline/offline.service.mjs +62 -0
  31. package/esm2022/src/offline/offlineData.service.mjs +479 -0
  32. package/esm2022/src/offline/offlineIndicator.component.mjs +58 -0
  33. package/esm2022/src/offline/offlineManager.component.mjs +84 -0
  34. package/esm2022/src/pushNotifications.service.mjs +56 -0
  35. package/esm2022/src/sentiment/sentiment.component.mjs +71 -0
  36. package/esm2022/src/sentiment/sentiment.module.mjs +21 -0
  37. package/esm2022/src/timeInterval/fromTimeToTime.component.mjs +155 -0
  38. package/esm2022/src/timeInterval/timeInterval.component.mjs +122 -0
  39. package/esm2022/src/timeInterval/timeInterval.module.mjs +22 -0
  40. package/esm2022/src/tinCan.service.mjs +49 -0
  41. package/fesm2022/idea-ionic-uncommon.mjs +2891 -0
  42. package/fesm2022/idea-ionic-uncommon.mjs.map +1 -0
  43. package/index.d.ts +5 -0
  44. package/package.json +51 -0
  45. package/public-api.d.ts +34 -0
  46. package/src/AWSAPI.service.d.ts +178 -0
  47. package/src/AWSAPISocket.service.d.ts +129 -0
  48. package/src/address/address.component.d.ts +64 -0
  49. package/src/address/address.module.d.ts +11 -0
  50. package/src/announcement/announcement.component.d.ts +23 -0
  51. package/src/announcement/announcement.module.d.ts +11 -0
  52. package/src/cachedResources.service.d.ts +34 -0
  53. package/src/colors/colorPicker.component.d.ts +78 -0
  54. package/src/colors/colorPicker.module.d.ts +10 -0
  55. package/src/contacts/contacts.component.d.ts +31 -0
  56. package/src/contacts/contacts.module.d.ts +11 -0
  57. package/src/dateTime/calendarPicker.component.d.ts +45 -0
  58. package/src/dateTime/dateTime.component.d.ts +81 -0
  59. package/src/dateTime/dateTime.module.d.ts +12 -0
  60. package/src/duration/duration.component.d.ts +68 -0
  61. package/src/duration/duration.module.d.ts +11 -0
  62. package/src/echo/echo.module.d.ts +12 -0
  63. package/src/echo/echo.page.d.ts +34 -0
  64. package/src/errorReporting.service.d.ts +26 -0
  65. package/src/mde/mde.component.d.ts +39 -0
  66. package/src/mde/mde.module.d.ts +12 -0
  67. package/src/mde/mdeToolbar.component.d.ts +5 -0
  68. package/src/offline/cacheableResource.component.d.ts +11 -0
  69. package/src/offline/offline.module.d.ts +12 -0
  70. package/src/offline/offline.service.d.ts +39 -0
  71. package/src/offline/offlineData.service.d.ts +281 -0
  72. package/src/offline/offlineIndicator.component.d.ts +25 -0
  73. package/src/offline/offlineManager.component.d.ts +17 -0
  74. package/src/pushNotifications.service.d.ts +26 -0
  75. package/src/sentiment/sentiment.component.d.ts +35 -0
  76. package/src/sentiment/sentiment.module.d.ts +11 -0
  77. package/src/timeInterval/fromTimeToTime.component.d.ts +61 -0
  78. package/src/timeInterval/timeInterval.component.d.ts +84 -0
  79. package/src/timeInterval/timeInterval.module.d.ts +12 -0
  80. package/src/tinCan.service.d.ts +31 -0
@@ -0,0 +1,430 @@
1
+ import { Injectable, inject } from '@angular/core';
2
+ import { HttpClient, HttpHeaders, HttpParams } from '@angular/common/http';
3
+ import { Observable } from 'rxjs';
4
+ import { Platform } from '@ionic/angular';
5
+ import { IDEAEnvironment, IDEAStorageService } from '@idea-ionic/common';
6
+ import { IDEAErrorReportingService } from './errorReporting.service';
7
+ import { IDEATinCanService } from './tinCan.service';
8
+ import { IDEAOfflineService } from './offline/offline.service';
9
+ import * as i0 from "@angular/core";
10
+ /**
11
+ * To communicate with an AWS's API Gateway istance.
12
+ *
13
+ * Includes a rundimental cache on GET requests, until Android doesn't support SWs on local files.
14
+ *
15
+ * Note: requires an `AWSAPIAuthToken` variable to be set by IDEATinCanService service.
16
+ */
17
+ export class IDEAAWSAPIService {
18
+ constructor() {
19
+ this._env = inject(IDEAEnvironment);
20
+ this._http = inject(HttpClient);
21
+ this._platform = inject(Platform);
22
+ this._tc = inject(IDEATinCanService);
23
+ this._storage = inject(IDEAStorageService);
24
+ this._errorReporting = inject(IDEAErrorReportingService);
25
+ this._offline = inject(IDEAOfflineService);
26
+ this.apiStage = this._env.idea.api?.stage || this._env.idea.api?.version;
27
+ this.apiUrlProject = 'https://'.concat([this._env.idea.api?.url, this.apiStage].filter(x => x).join('/'));
28
+ this.ideaApiStage = this._env.idea.ideaApi?.stage || this._env.idea.ideaApi?.version;
29
+ this.apiUrlIDEA = 'https://'.concat([this._env.idea.ideaApi?.url, this.ideaApiStage].filter(x => x).join('/'));
30
+ }
31
+ /**
32
+ * Execute an online API request.
33
+ * @param resource resource name (e.g. `users`)
34
+ * @param method enum HTTP methods
35
+ * @param options the request options
36
+ */
37
+ request(resource, method, options) {
38
+ return new Promise((resolve, reject) => {
39
+ const opt = options || {};
40
+ // prepare the url
41
+ const url = this.prepareURL(resource, opt);
42
+ // prepare the headers and set the Authorization token
43
+ const headers = this.prepareHeaders(opt.headers);
44
+ // prepare the query params and add some info about the client
45
+ const params = this.prepareQueryParams(opt.params, true);
46
+ // execute the request
47
+ let req;
48
+ switch (method) {
49
+ case 'HEAD':
50
+ req = this._http.head(url, { headers, params });
51
+ break;
52
+ case 'POST':
53
+ req = this._http.post(url, opt.body, { headers, params });
54
+ break;
55
+ case 'PUT':
56
+ req = this._http.put(url, opt.body, { headers, params });
57
+ break;
58
+ case 'PATCH':
59
+ req = this._http.patch(url, opt.body, { headers, params });
60
+ break;
61
+ case 'DELETE':
62
+ req = this._http.delete(url, { headers, params });
63
+ break;
64
+ case 'GET':
65
+ default:
66
+ req = this._http.get(url, { headers, params });
67
+ }
68
+ // handle the request response
69
+ req.subscribe((res) => resolve(res), async (err) => {
70
+ // check if the request failed for network reasons (to trigger offline mode if needed)
71
+ await this._offline.check();
72
+ // (async) send a report, if wanted
73
+ if (opt.reportError)
74
+ this._errorReporting.sendReport(err);
75
+ // fix and return the error
76
+ this.fixErrMessageBeforeReject(err, reject);
77
+ });
78
+ });
79
+ }
80
+ /**
81
+ * Prepare the URL to which execute the request.
82
+ */
83
+ prepareURL(resource, opt) {
84
+ // decide whether to use IDEA's API or the project's API (or an alternative API)
85
+ let url = opt.idea ? this.apiUrlIDEA : opt.alternativeAPI || this.apiUrlProject;
86
+ // prepare a single-resource request (by id) or a normal one
87
+ url = `${url}/${resource}`;
88
+ if (opt.resourceId)
89
+ url = `${url}/${encodeURIComponent(opt.resourceId)}`;
90
+ return url;
91
+ }
92
+ /**
93
+ * Prepare the headers object to send with a request.
94
+ * Note: it always adds the Authorization token (`AWSAPIAuthToken`) and the API key (`AWSAPIKey`), if set.
95
+ */
96
+ prepareHeaders(h) {
97
+ // preare the headers; note: HttpHeaders is immutable!
98
+ let headers = new HttpHeaders(h || null);
99
+ // set the Authorization token
100
+ if (!headers.get('Authorization') && this._tc.get('AWSAPIAuthToken'))
101
+ headers = headers.set('Authorization', this._tc.get('AWSAPIAuthToken'));
102
+ // set the API key
103
+ if (!headers.get('X-API-Key') && this._tc.get('AWSAPIKey'))
104
+ headers = headers.set('X-API-Key', this._tc.get('AWSAPIKey'));
105
+ return headers;
106
+ }
107
+ /**
108
+ * Prepare the queryParams object to send with a request; if requested, add some info about the client.
109
+ */
110
+ prepareQueryParams(qp, addClientInfo) {
111
+ // prepare the query params; note: HttpParams is immutable!
112
+ let searchParams = new HttpParams();
113
+ if (qp && qp instanceof HttpParams)
114
+ searchParams = qp;
115
+ else if (qp)
116
+ for (const prop in qp)
117
+ if (qp[prop])
118
+ searchParams = searchParams.set(prop, qp[prop]);
119
+ // if requested, add app version and client platform to the info we send to the back-end
120
+ if (addClientInfo) {
121
+ searchParams = searchParams.set('_v', this._env.idea.app.version);
122
+ searchParams = searchParams.set('_p', this._platform.platforms().join(' '));
123
+ }
124
+ return searchParams;
125
+ }
126
+ /**
127
+ * Converts the error message to be readable.
128
+ */
129
+ fixErrMessageBeforeReject(err, reject) {
130
+ let e;
131
+ try {
132
+ if (!err || !err.error)
133
+ e = {};
134
+ else if (typeof err.error === 'string')
135
+ e = JSON.parse(err.error);
136
+ else
137
+ e = err.error;
138
+ }
139
+ catch (_) {
140
+ e = {};
141
+ }
142
+ reject(new Error(e.message || 'Unknown error!'));
143
+ }
144
+ /**
145
+ * Use the HttpClient to execute a raw request.
146
+ */
147
+ rawRequest() {
148
+ return this._http;
149
+ }
150
+ /**
151
+ * HEAD request.
152
+ * @param resource resource name (e.g. `users`)
153
+ * @param options the request options
154
+ */
155
+ headResource(resource, options) {
156
+ return this.request(resource, 'HEAD', options);
157
+ }
158
+ /**
159
+ * GET request. Include options to cache the requests (`options.useCache`), to work also offline.
160
+ * @param resource resource name (e.g. `users`)
161
+ * @param options the request options
162
+ */
163
+ getResource(resource, options) {
164
+ return new Promise((resolve, reject) => {
165
+ const opt = options || {};
166
+ // if offline and with a cache mode set, force the request to the cache
167
+ if (!navigator.onLine && opt.useCache)
168
+ opt.useCache = CacheModes.CACHE_ONLY;
169
+ // execute the GET request online or through the cache, depending on the chosen mode
170
+ switch (opt.useCache) {
171
+ case CacheModes.CACHE_ONLY:
172
+ // return the result from the cache, without retrying online if a result wasn't found
173
+ this.getFromCache(resource, opt).then((res) => {
174
+ if (res)
175
+ resolve(res);
176
+ else
177
+ reject();
178
+ });
179
+ break;
180
+ case CacheModes.CACHE_FIRST:
181
+ // return the result from the cache
182
+ this.getFromCache(resource, opt).then((localRes) => {
183
+ // check whether the local resource is present (element or list)
184
+ if (localRes && (opt.resourceId || localRes.length)) {
185
+ resolve(localRes);
186
+ // asynchrounously execute the request online, to update the cache with latest data
187
+ this.request(resource, 'GET', opt)
188
+ .then((cloudRes) => {
189
+ // update the cache (if it fails, it's ok)
190
+ this.putInCache(resource, cloudRes, opt).catch(() => { });
191
+ })
192
+ .catch(() => { }); // we already returned the result, an error is acceptable
193
+ }
194
+ else {
195
+ // if the result isn't found in the cache, return the result of the online request
196
+ this.request(resource, 'GET', opt)
197
+ .then((res) => {
198
+ resolve(res);
199
+ // update the cache (if it fails, it's ok)
200
+ this.putInCache(resource, res, opt).catch(() => { });
201
+ })
202
+ .catch((err) => reject(err)); // element not found
203
+ }
204
+ });
205
+ break;
206
+ case CacheModes.NETWORK_FIRST:
207
+ // return the result from an online request
208
+ this.request(resource, 'GET', opt)
209
+ .then((cloudRes) => {
210
+ resolve(cloudRes);
211
+ // asynchrounously get the same element from cache and decide whether to update or not
212
+ this.getFromCache(resource, opt).then(() => {
213
+ // update the cache (if it fails, it's ok)
214
+ this.putInCache(resource, cloudRes, opt).catch(() => { });
215
+ });
216
+ })
217
+ .catch(() => {
218
+ // if a request to the network fails, check in cache
219
+ this.getFromCache(resource, opt).then((res) => {
220
+ if (res)
221
+ resolve(res);
222
+ else
223
+ reject();
224
+ });
225
+ });
226
+ break;
227
+ default:
228
+ /* CacheModes.NO_CACHE */
229
+ // return the result from an online request, with no cache involved
230
+ this.request(resource, 'GET', opt)
231
+ .then((res) => resolve(res))
232
+ .catch((err) => reject(err));
233
+ }
234
+ });
235
+ }
236
+ /**
237
+ * Observe a GET request. Include options to cache the requests (`options.useCache`), to work also offline.
238
+ * @param resource resource name (e.g. `users`)
239
+ * @param options the request options
240
+ */
241
+ getResourceObserver(resource, options) {
242
+ return new Observable(observer => {
243
+ const opt = options || {};
244
+ // if offline and with a cache mode set, force the request to the cache
245
+ if (!navigator.onLine && opt.useCache)
246
+ opt.useCache = CacheModes.CACHE_ONLY;
247
+ // execute the GET request online or through the cache, depending on the chosen mode
248
+ switch (opt.useCache) {
249
+ case CacheModes.CACHE_ONLY:
250
+ // return the result from the cache, without retrying online if a result wasn't found
251
+ this.getFromCache(resource, opt).then((res) => {
252
+ if (res)
253
+ observer.next(res);
254
+ else
255
+ observer.error();
256
+ });
257
+ break;
258
+ case CacheModes.CACHE_FIRST:
259
+ // return the result from the cache
260
+ this.getFromCache(resource, opt).then((localRes) => {
261
+ if (localRes) {
262
+ observer.next(localRes);
263
+ // asynchrounously execute the request online, to update the cache with latest data
264
+ this.request(resource, 'GET', opt)
265
+ .then((cloudRes) => {
266
+ observer.next(cloudRes);
267
+ // update the cache (if it fails, it's ok)
268
+ this.putInCache(resource, cloudRes, opt).catch(() => { });
269
+ })
270
+ .catch(() => { }); // we already returned the result, an error is acceptable
271
+ }
272
+ else {
273
+ // if the result isn't found in the cache, return the result of the online request
274
+ this.request(resource, 'GET', opt)
275
+ .then((res) => {
276
+ observer.next(res);
277
+ // update the cache (if it fails, it's ok)
278
+ this.putInCache(resource, res, opt).catch(() => { });
279
+ })
280
+ .catch((err) => observer.error(err)); // element not found
281
+ }
282
+ });
283
+ break;
284
+ case CacheModes.NETWORK_FIRST:
285
+ // return the result from an online request
286
+ this.request(resource, 'GET', opt)
287
+ .then((cloudRes) => {
288
+ observer.next(cloudRes);
289
+ // update the cache (if it fails, it's ok)
290
+ this.putInCache(resource, cloudRes, opt).catch(() => { });
291
+ })
292
+ .catch(() => {
293
+ // if a request to the network fails, check in cache
294
+ this.getFromCache(resource, opt).then((res) => {
295
+ if (res)
296
+ observer.next(res);
297
+ else
298
+ observer.error();
299
+ });
300
+ });
301
+ break;
302
+ default:
303
+ /* CacheModes.NO_CACHE */
304
+ // return the result from an online request, with no cache involved
305
+ this.request(resource, 'GET', opt)
306
+ .then((res) => observer.next(res))
307
+ .catch((err) => observer.error(err));
308
+ }
309
+ });
310
+ }
311
+ /**
312
+ * Execute a GET request from the local storage.
313
+ * @param resource resource name (e.g. `users`)
314
+ * @param options the request options
315
+ */
316
+ getFromCache(resource, options) {
317
+ return new Promise(resolve => {
318
+ const opt = options || {};
319
+ // prepare the url and the query params
320
+ const url = this.prepareURL(resource, opt);
321
+ const queryParams = this.prepareQueryParams(opt.params);
322
+ // get from storage, by the complete url
323
+ this._storage
324
+ .get(url.concat(queryParams.toString()))
325
+ .then((res) => (res ? resolve(res) : opt.resourceId ? resolve(null) : resolve([])));
326
+ });
327
+ }
328
+ /**
329
+ * Execute a PUT request in the local storage.
330
+ * @param resource resource name (e.g. `users`)
331
+ * @param data resource data
332
+ * @param options the request options
333
+ */
334
+ putInCache(resource, data, options) {
335
+ return new Promise((resolve, reject) => {
336
+ const opt = options || {};
337
+ // prepare the url and the query params
338
+ const url = this.prepareURL(resource, opt);
339
+ const queryParams = this.prepareQueryParams(opt.params);
340
+ // put in the storage, by the complete url
341
+ this._storage
342
+ .set(url.concat(queryParams.toString()), data)
343
+ .then(() => resolve())
344
+ .catch((err) => reject(err));
345
+ });
346
+ }
347
+ /**
348
+ * Execute a DELETE request in the local storage.
349
+ * @param resource resource name (e.g. `users`)
350
+ * @param options the request options
351
+ */
352
+ deleteFromCache(resource, options) {
353
+ return new Promise((resolve, reject) => {
354
+ const opt = options || {};
355
+ // prepare the url and the query params
356
+ const url = this.prepareURL(resource, opt);
357
+ const queryParams = this.prepareQueryParams(opt.params);
358
+ // delete from storage, by the complete url
359
+ this._storage
360
+ .remove(url.concat(queryParams.toString()))
361
+ .then(() => resolve())
362
+ .catch((err) => reject(err));
363
+ });
364
+ }
365
+ /**
366
+ * POST request.
367
+ * @param resource resource name (e.g. `users`)
368
+ * @param options the request options
369
+ */
370
+ postResource(resource, options) {
371
+ return this.request(resource, 'POST', options);
372
+ }
373
+ /**
374
+ * PUT request.
375
+ * @param resource resource name (e.g. `users`)
376
+ * @param options the request options
377
+ */
378
+ putResource(resource, options) {
379
+ return this.request(resource, 'PUT', options);
380
+ }
381
+ /**
382
+ * PATCH request.
383
+ * @param resource resource name (e.g. `users`)
384
+ * @param options the request options
385
+ */
386
+ patchResource(resource, options) {
387
+ return this.request(resource, 'PATCH', options);
388
+ }
389
+ /**
390
+ * DELETE request.
391
+ * @param resource resource name (e.g. `users`)
392
+ * @param options the request options
393
+ */
394
+ deleteResource(resource, options) {
395
+ return this.request(resource, 'DELETE', options);
396
+ }
397
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: IDEAAWSAPIService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
398
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: IDEAAWSAPIService }); }
399
+ }
400
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.1", ngImport: i0, type: IDEAAWSAPIService, decorators: [{
401
+ type: Injectable
402
+ }], ctorParameters: () => [] });
403
+ /**
404
+ * The options of an API request.
405
+ */
406
+ export class APIRequestOption {
407
+ }
408
+ /**
409
+ * Set of usable cache modes.
410
+ */
411
+ export var CacheModes;
412
+ (function (CacheModes) {
413
+ /**
414
+ * Return the result from an online request, with no cache involved.
415
+ */
416
+ CacheModes[CacheModes["NO_CACHE"] = 0] = "NO_CACHE";
417
+ /**
418
+ * Return the result from an online request, storing the result in the cache, to update it with the latest data.
419
+ */
420
+ CacheModes[CacheModes["NETWORK_FIRST"] = 1] = "NETWORK_FIRST";
421
+ /**
422
+ * Return the result from the cache, but also execute the request online, to update the cache with the latest data.
423
+ */
424
+ CacheModes[CacheModes["CACHE_FIRST"] = 2] = "CACHE_FIRST";
425
+ /**
426
+ * Return the result from the cache, without retrying online if a result wasn't found.
427
+ */
428
+ CacheModes[CacheModes["CACHE_ONLY"] = 3] = "CACHE_ONLY";
429
+ })(CacheModes || (CacheModes = {}));
430
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQVdTQVBJLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9tb2R1bGVzL3VuY29tbW9uL3NyYy9BV1NBUEkuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxVQUFVLEVBQXFCLE1BQU0sc0JBQXNCLENBQUM7QUFDOUYsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNsQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDMUMsT0FBTyxFQUFFLGVBQWUsRUFBRSxrQkFBa0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRXpFLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3JFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDOztBQUUvRDs7Ozs7O0dBTUc7QUFFSCxNQUFNLE9BQU8saUJBQWlCO0lBYzVCO1FBYlUsU0FBSSxHQUFHLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUMvQixVQUFLLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQzNCLGNBQVMsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDN0IsUUFBRyxHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBQ2hDLGFBQVEsR0FBRyxNQUFNLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQUN0QyxvQkFBZSxHQUFHLE1BQU0sQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO1FBQ3BELGFBQVEsR0FBRyxNQUFNLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQVE5QyxJQUFJLENBQUMsUUFBUSxHQUFHLElB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c0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBIdHRwQ2xpZW50LCBIdHRwSGVhZGVycywgSHR0cFBhcmFtcywgSHR0cEVycm9yUmVzcG9uc2UgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBQbGF0Zm9ybSB9IGZyb20gJ0Bpb25pYy9hbmd1bGFyJztcbmltcG9ydCB7IElERUFFbnZpcm9ubWVudCwgSURFQVN0b3JhZ2VTZXJ2aWNlIH0gZnJvbSAnQGlkZWEtaW9uaWMvY29tbW9uJztcblxuaW1wb3J0IHsgSURFQUVycm9yUmVwb3J0aW5nU2VydmljZSB9IGZyb20gJy4vZXJyb3JSZXBvcnRpbmcuc2VydmljZSc7XG5pbXBvcnQgeyBJREVBVGluQ2FuU2VydmljZSB9IGZyb20gJy4vdGluQ2FuLnNlcnZpY2UnO1xuaW1wb3J0IHsgSURFQU9mZmxpbmVTZXJ2aWNlIH0gZnJvbSAnLi9vZmZsaW5lL29mZmxpbmUuc2VydmljZSc7XG5cbi8qKlxuICogVG8gY29tbXVuaWNhdGUgd2l0aCBhbiBBV1MncyBBUEkgR2F0ZXdheSBpc3RhbmNlLlxuICpcbiAqIEluY2x1ZGVzIGEgcnVuZGltZW50YWwgY2FjaGUgb24gR0VUIHJlcXVlc3RzLCB1bnRpbCBBbmRyb2lkIGRvZXNuJ3Qgc3VwcG9ydCBTV3Mgb24gbG9jYWwgZmlsZXMuXG4gKlxuICogTm90ZTogcmVxdWlyZXMgYW4gYEFXU0FQSUF1dGhUb2tlbmAgdmFyaWFibGUgdG8gYmUgc2V0IGJ5IElERUFUaW5DYW5TZXJ2aWNlIHNlcnZpY2UuXG4gKi9cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBJREVBQVdTQVBJU2VydmljZSB7XG4gIHByb3RlY3RlZCBfZW52ID0gaW5qZWN0KElERUFFbnZpcm9ubWVudCk7XG4gIHByb3RlY3RlZCBfaHR0cCA9IGluamVjdChIdHRwQ2xpZW50KTtcbiAgcHJvdGVjdGVkIF9wbGF0Zm9ybSA9IGluamVjdChQbGF0Zm9ybSk7XG4gIHByb3RlY3RlZCBfdGMgPSBpbmplY3QoSURFQVRpbkNhblNlcnZpY2UpO1xuICBwcm90ZWN0ZWQgX3N0b3JhZ2UgPSBpbmplY3QoSURFQVN0b3JhZ2VTZXJ2aWNlKTtcbiAgcHJvdGVjdGVkIF9lcnJvclJlcG9ydGluZyA9IGluamVjdChJREVBRXJyb3JSZXBvcnRpbmdTZXJ2aWNlKTtcbiAgcHJvdGVjdGVkIF9vZmZsaW5lID0gaW5qZWN0KElERUFPZmZsaW5lU2VydmljZSk7XG5cbiAgYXBpU3RhZ2U6IHN0cmluZztcbiAgYXBpVXJsUHJvamVjdDogc3RyaW5nO1xuICBpZGVhQXBpU3RhZ2U6IHN0cmluZztcbiAgYXBpVXJsSURFQTogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuYXBpU3RhZ2UgPSB0aGlzLl9lbnYuaWRlYS5hcGk/LnN0YWdlIHx8ICh0aGlzLl9lbnYuaWRlYS5hcGkgYXMgYW55KT8udmVyc2lvbjtcbiAgICB0aGlzLmFwaVVybFByb2plY3QgPSAnaHR0cHM6Ly8nLmNvbmNhdChbdGhpcy5fZW52LmlkZWEuYXBpPy51cmwsIHRoaXMuYXBpU3RhZ2VdLmZpbHRlcih4ID0+IHgpLmpvaW4oJy8nKSk7XG4gICAgdGhpcy5pZGVhQXBpU3RhZ2UgPSB0aGlzLl9lbnYuaWRlYS5pZGVhQXBpPy5zdGFnZSB8fCAodGhpcy5fZW52LmlkZWEuaWRlYUFwaSBhcyBhbnkpPy52ZXJzaW9uO1xuICAgIHRoaXMuYXBpVXJsSURFQSA9ICdodHRwczovLycuY29uY2F0KFt0aGlzLl9lbnYuaWRlYS5pZGVhQXBpPy51cmwsIHRoaXMuaWRlYUFwaVN0YWdlXS5maWx0ZXIoeCA9PiB4KS5qb2luKCcvJykpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4ZWN1dGUgYW4gb25saW5lIEFQSSByZXF1ZXN0LlxuICAgKiBAcGFyYW0gcmVzb3VyY2UgcmVzb3VyY2UgbmFtZSAoZS5nLiBgdXNlcnNgKVxuICAgKiBAcGFyYW0gbWV0aG9kIGVudW0gSFRUUCBtZXRob2RzXG4gICAqIEBwYXJhbSBvcHRpb25zIHRoZSByZXF1ZXN0IG9wdGlvbnNcbiAgICovXG4gIHByb3RlY3RlZCByZXF1ZXN0KHJlc291cmNlOiBzdHJpbmcsIG1ldGhvZDogc3RyaW5nLCBvcHRpb25zPzogQVBJUmVxdWVzdE9wdGlvbik6IFByb21pc2U8YW55PiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IG9wdCA9IG9wdGlvbnMgfHwge307XG4gICAgICAvLyBwcmVwYXJlIHRoZSB1cmxcbiAgICAgIGNvbnN0IHVybCA9IHRoaXMucHJlcGFyZVVSTChyZXNvdXJjZSwgb3B0KTtcbiAgICAgIC8vIHByZXBhcmUgdGhlIGhlYWRlcnMgYW5kIHNldCB0aGUgQXV0aG9yaXphdGlvbiB0b2tlblxuICAgICAgY29uc3QgaGVhZGVycyA9IHRoaXMucHJlcGFyZUhlYWRlcnMob3B0LmhlYWRlcnMpO1xuICAgICAgLy8gcHJlcGFyZSB0aGUgcXVlcnkgcGFyYW1zIGFuZCBhZGQgc29tZSBpbmZvIGFib3V0IHRoZSBjbGllbnRcbiAgICAgIGNvbnN0IHBhcmFtcyA9IHRoaXMucHJlcGFyZVF1ZXJ5UGFyYW1zKG9wdC5wYXJhbXMsIHRydWUpO1xuICAgICAgLy8gZXhlY3V0ZSB0aGUgcmVxdWVzdFxuICAgICAgbGV0IHJlcTogYW55O1xuICAgICAgc3dpdGNoIChtZXRob2QpIHtcbiAgICAgICAgY2FzZSAnSEVBRCc6XG4gICAgICAgICAgcmVxID0gdGhpcy5faHR0cC5oZWFkKHVybCwgeyBoZWFkZXJzLCBwYXJhbXMgfSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ1BPU1QnOlxuICAgICAgICAgIHJlcSA9IHRoaXMuX2h0dHAucG9zdCh1cmwsIG9wdC5ib2R5LCB7IGhlYWRlcnMsIHBhcmFtcyB9KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnUFVUJzpcbiAgICAgICAgICByZXEgPSB0aGlzLl9odHRwLnB1dCh1cmwsIG9wdC5ib2R5LCB7IGhlYWRlcnMsIHBhcmFtcyB9KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnUEFUQ0gnOlxuICAgICAgICAgIHJlcSA9IHRoaXMuX2h0dHAucGF0Y2godXJsLCBvcHQuYm9keSwgeyBoZWFkZXJzLCBwYXJhbXMgfSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ0RFTEVURSc6XG4gICAgICAgICAgcmVxID0gdGhpcy5faHR0cC5kZWxldGUodXJsLCB7IGhlYWRlcnMsIHBhcmFtcyB9KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnR0VUJzpcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICByZXEgPSB0aGlzLl9odHRwLmdldCh1cmwsIHsgaGVhZGVycywgcGFyYW1zIH0pO1xuICAgICAgfVxuICAgICAgLy8gaGFuZGxlIHRoZSByZXF1ZXN0IHJlc3BvbnNlXG4gICAgICByZXEuc3Vic2NyaWJlKFxuICAgICAgICAocmVzOiBhbnkpID0+IHJlc29sdmUocmVzKSxcbiAgICAgICAgYXN5bmMgKGVycjogSHR0cEVycm9yUmVzcG9uc2UpID0+IHtcbiAgICAgICAgICAvLyBjaGVjayBpZiB0aGUgcmVxdWVzdCBmYWlsZWQgZm9yIG5ldHdvcmsgcmVhc29ucyAodG8gdHJpZ2dlciBvZmZsaW5lIG1vZGUgaWYgbmVlZGVkKVxuICAgICAgICAgIGF3YWl0IHRoaXMuX29mZmxpbmUuY2hlY2soKTtcbiAgICAgICAgICAvLyAoYXN5bmMpIHNlbmQgYSByZXBvcnQsIGlmIHdhbnRlZFxuICAgICAgICAgIGlmIChvcHQucmVwb3J0RXJyb3IpIHRoaXMuX2Vycm9yUmVwb3J0aW5nLnNlbmRSZXBvcnQoZXJyKTtcbiAgICAgICAgICAvLyBmaXggYW5kIHJldHVybiB0aGUgZXJyb3JcbiAgICAgICAgICB0aGlzLmZpeEVyck1lc3NhZ2VCZWZvcmVSZWplY3QoZXJyLCByZWplY3QpO1xuICAgICAgICB9XG4gICAgICApO1xuICAgIH0pO1xuICB9XG4gIC8qKlxuICAgKiBQcmVwYXJlIHRoZSBVUkwgdG8gd2hpY2ggZXhlY3V0ZSB0aGUgcmVxdWVzdC5cbiAgICovXG4gIHByb3RlY3RlZCBwcmVwYXJlVVJMKHJlc291cmNlOiBzdHJpbmcsIG9wdDogQVBJUmVxdWVzdE9wdGlvbik6IHN0cmluZyB7XG4gICAgLy8gZGVjaWRlIHdoZXRoZXIgdG8gdXNlIElERUEncyBBUEkgb3IgdGhlIHByb2plY3QncyBBUEkgKG9yIGFuIGFsdGVybmF0aXZlIEFQSSlcbiAgICBsZXQgdXJsID0gb3B0LmlkZWEgPyB0aGlzLmFwaVVybElERUEgOiBvcHQuYWx0ZXJuYXRpdmVBUEkgfHwgdGhpcy5hcGlVcmxQcm9qZWN0O1xuICAgIC8vIHByZXBhcmUgYSBzaW5nbGUtcmVzb3VyY2UgcmVxdWVzdCAoYnkgaWQpIG9yIGEgbm9ybWFsIG9uZVxuICAgIHVybCA9IGAke3VybH0vJHtyZXNvdXJjZX1gO1xuICAgIGlmIChvcHQucmVzb3VyY2VJZCkgdXJsID0gYCR7dXJsfS8ke2VuY29kZVVSSUNvbXBvbmVudChvcHQucmVzb3VyY2VJZCl9YDtcbiAgICByZXR1cm4gdXJsO1xuICB9XG4gIC8qKlxuICAgKiBQcmVwYXJlIHRoZSBoZWFkZXJzIG9iamVjdCB0byBzZW5kIHdpdGggYSByZXF1ZXN0LlxuICAgKiBOb3RlOiBpdCBhbHdheXMgYWRkcyB0aGUgQXV0aG9yaXphdGlvbiB0b2tlbiAoYEFXU0FQSUF1dGhUb2tlbmApIGFuZCB0aGUgQVBJIGtleSAoYEFXU0FQSUtleWApLCBpZiBzZXQuXG4gICAqL1xuICBwcm90ZWN0ZWQgcHJlcGFyZUhlYWRlcnMoaDogSHR0cEhlYWRlcnMgfCBhbnkpOiBIdHRwSGVhZGVycyB7XG4gICAgLy8gcHJlYXJlIHRoZSBoZWFkZXJzOyBub3RlOiBIdHRwSGVhZGVycyBpcyBpbW11dGFibGUhXG4gICAgbGV0IGhlYWRlcnMgPSBuZXcgSHR0cEhlYWRlcnMoaCB8fCBudWxsKTtcbiAgICAvLyBzZXQgdGhlIEF1dGhvcml6YXRpb24gdG9rZW5cbiAgICBpZiAoIWhlYWRlcnMuZ2V0KCdBdXRob3JpemF0aW9uJykgJiYgdGhpcy5fdGMuZ2V0KCdBV1NBUElBdXRoVG9rZW4nKSlcbiAgICAgIGhlYWRlcnMgPSBoZWFkZXJzLnNldCgnQXV0aG9yaXphdGlvbicsIHRoaXMuX3RjLmdldCgnQVdTQVBJQXV0aFRva2VuJykpO1xuICAgIC8vIHNldCB0aGUgQVBJIGtleVxuICAgIGlmICghaGVhZGVycy5nZXQoJ1gtQVBJLUtleScpICYmIHRoaXMuX3RjLmdldCgnQVdTQVBJS2V5JykpXG4gICAgICBoZWFkZXJzID0gaGVhZGVycy5zZXQoJ1gtQVBJLUtleScsIHRoaXMuX3RjLmdldCgnQVdTQVBJS2V5JykpO1xuICAgIHJldHVybiBoZWFkZXJzO1xuICB9XG4gIC8qKlxuICAgKiBQcmVwYXJlIHRoZSBxdWVyeVBhcmFtcyBvYmplY3QgdG8gc2VuZCB3aXRoIGEgcmVxdWVzdDsgaWYgcmVxdWVzdGVkLCBhZGQgc29tZSBpbmZvIGFib3V0IHRoZSBjbGllbnQuXG4gICAqL1xuICBwcm90ZWN0ZWQgcHJlcGFyZVF1ZXJ5UGFyYW1zKHFwOiBIdHRwUGFyYW1zIHwgYW55LCBhZGRDbGllbnRJbmZvPzogYm9vbGVhbik6IEh0dHBQYXJhbXMge1xuICAgIC8vIHByZXBhcmUgdGhlIHF1ZXJ5IHBhcmFtczsgbm90ZTogSHR0cFBhcmFtcyBpcyBpbW11dGFibGUhXG4gICAgbGV0IHNlYXJjaFBhcmFtcyA9IG5ldyBIdHRwUGFyYW1zKCk7XG4gICAgaWYgKHFwICYmIHFwIGluc3RhbmNlb2YgSHR0cFBhcmFtcykgc2VhcmNoUGFyYW1zID0gcXA7XG4gICAgZWxzZSBpZiAocXApIGZvciAoY29uc3QgcHJvcCBpbiBxcCkgaWYgKHFwW3Byb3BdKSBzZWFyY2hQYXJhbXMgPSBzZWFyY2hQYXJhbXMuc2V0KHByb3AsIHFwW3Byb3BdKTtcbiAgICAvLyBpZiByZXF1ZXN0ZWQsIGFkZCBhcHAgdmVyc2lvbiBhbmQgY2xpZW50IHBsYXRmb3JtIHRvIHRoZSBpbmZvIHdlIHNlbmQgdG8gdGhlIGJhY2stZW5kXG4gICAgaWYgKGFkZENsaWVudEluZm8pIHtcbiAgICAgIHNlYXJjaFBhcmFtcyA9IHNlYXJjaFBhcmFtcy5zZXQoJ192JywgdGhpcy5fZW52LmlkZWEuYXBwLnZlcnNpb24pO1xuICAgICAgc2VhcmNoUGFyYW1zID0gc2VhcmNoUGFyYW1zLnNldCgnX3AnLCB0aGlzLl9wbGF0Zm9ybS5wbGF0Zm9ybXMoKS5qb2luKCcgJykpO1xuICAgIH1cbiAgICByZXR1cm4gc2VhcmNoUGFyYW1zO1xuICB9XG4gIC8qKlxuICAgKiBDb252ZXJ0cyB0aGUgZXJyb3IgbWVzc2FnZSB0byBiZSByZWFkYWJsZS5cbiAgICovXG4gIHByb3RlY3RlZCBmaXhFcnJNZXNzYWdlQmVmb3JlUmVqZWN0KGVycjogSHR0cEVycm9yUmVzcG9uc2UsIHJlamVjdDogYW55KSB7XG4gICAgbGV0IGU7XG4gICAgdHJ5IHtcbiAgICAgIGlmICghZXJyIHx8ICFlcnIuZXJyb3IpIGUgPSB7fTtcbiAgICAgIGVsc2UgaWYgKHR5cGVvZiBlcnIuZXJyb3IgPT09ICdzdHJpbmcnKSBlID0gSlNPTi5wYXJzZShlcnIuZXJyb3IpO1xuICAgICAgZWxzZSBlID0gZXJyLmVycm9yO1xuICAgIH0gY2F0Y2ggKF8pIHtcbiAgICAgIGUgPSB7fTtcbiAgICB9XG4gICAgcmVqZWN0KG5ldyBFcnJvcihlLm1lc3NhZ2UgfHwgJ1Vua25vd24gZXJyb3IhJykpO1xuICB9XG5cbiAgLyoqXG4gICAqIFVzZSB0aGUgSHR0cENsaWVudCB0byBleGVjdXRlIGEgcmF3IHJlcXVlc3QuXG4gICAqL1xuICByYXdSZXF1ZXN0KCk6IEh0dHBDbGllbnQge1xuICAgIHJldHVybiB0aGlzLl9odHRwO1xuICB9XG5cbiAgLyoqXG4gICAqIEhFQUQgcmVxdWVzdC5cbiAgICogQHBhcmFtIHJlc291cmNlIHJlc291cmNlIG5hbWUgKGUuZy4gYHVzZXJzYClcbiAgICogQHBhcmFtIG9wdGlvbnMgdGhlIHJlcXVlc3Qgb3B0aW9uc1xuICAgKi9cbiAgaGVhZFJlc291cmNlKHJlc291cmNlOiBzdHJpbmcsIG9wdGlvbnM/OiBBUElSZXF1ZXN0T3B0aW9uKTogUHJvbWlzZTxhbnk+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KHJlc291cmNlLCAnSEVBRCcsIG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdFVCByZXF1ZXN0LiBJbmNsdWRlIG9wdGlvbnMgdG8gY2FjaGUgdGhlIHJlcXVlc3RzIChgb3B0aW9ucy51c2VDYWNoZWApLCB0byB3b3JrIGFsc28gb2ZmbGluZS5cbiAgICogQHBhcmFtIHJlc291cmNlIHJlc291cmNlIG5hbWUgKGUuZy4gYHVzZXJzYClcbiAgICogQHBhcmFtIG9wdGlvbnMgdGhlIHJlcXVlc3Qgb3B0aW9uc1xuICAgKi9cbiAgZ2V0UmVzb3VyY2UocmVzb3VyY2U6IHN0cmluZywgb3B0aW9ucz86IEFQSVJlcXVlc3RPcHRpb24pOiBQcm9taXNlPGFueT4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCBvcHQgPSBvcHRpb25zIHx8IHt9O1xuICAgICAgLy8gaWYgb2ZmbGluZSBhbmQgd2l0aCBhIGNhY2hlIG1vZGUgc2V0LCBmb3JjZSB0aGUgcmVxdWVzdCB0byB0aGUgY2FjaGVcbiAgICAgIGlmICghbmF2aWdhdG9yLm9uTGluZSAmJiBvcHQudXNlQ2FjaGUpIG9wdC51c2VDYWNoZSA9IENhY2hlTW9kZXMuQ0FDSEVfT05MWTtcbiAgICAgIC8vIGV4ZWN1dGUgdGhlIEdFVCByZXF1ZXN0IG9ubGluZSBvciB0aHJvdWdoIHRoZSBjYWNoZSwgZGVwZW5kaW5nIG9uIHRoZSBjaG9zZW4gbW9kZVxuICAgICAgc3dpdGNoIChvcHQudXNlQ2FjaGUpIHtcbiAgICAgICAgY2FzZSBDYWNoZU1vZGVzLkNBQ0hFX09OTFk6XG4gICAgICAgICAgLy8gcmV0dXJuIHRoZSByZXN1bHQgZnJvbSB0aGUgY2FjaGUsIHdpdGhvdXQgcmV0cnlpbmcgb25saW5lIGlmIGEgcmVzdWx0IHdhc24ndCBmb3VuZFxuICAgICAgICAgIHRoaXMuZ2V0RnJvbUNhY2hlKHJlc291cmNlLCBvcHQpLnRoZW4oKHJlczogYW55KSA9PiB7XG4gICAgICAgICAgICBpZiAocmVzKSByZXNvbHZlKHJlcyk7XG4gICAgICAgICAgICBlbHNlIHJlamVjdCgpO1xuICAgICAgICAgIH0pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIENhY2hlTW9kZXMuQ0FDSEVfRklSU1Q6XG4gICAgICAgICAgLy8gcmV0dXJuIHRoZSByZXN1bHQgZnJvbSB0aGUgY2FjaGVcbiAgICAgICAgICB0aGlzLmdldEZyb21DYWNoZShyZXNvdXJjZSwgb3B0KS50aGVuKChsb2NhbFJlczogYW55KSA9PiB7XG4gICAgICAgICAgICAvLyBjaGVjayB3aGV0aGVyIHRoZSBsb2NhbCByZXNvdXJjZSBpcyBwcmVzZW50IChlbGVtZW50IG9yIGxpc3QpXG4gICAgICAgICAgICBpZiAobG9jYWxSZXMgJiYgKG9wdC5yZXNvdXJjZUlkIHx8IGxvY2FsUmVzLmxlbmd0aCkpIHtcbiAgICAgICAgICAgICAgcmVzb2x2ZShsb2NhbFJlcyk7XG4gICAgICAgICAgICAgIC8vIGFzeW5jaHJvdW5vdXNseSBleGVjdXRlIHRoZSByZXF1ZXN0IG9ubGluZSwgdG8gdXBkYXRlIHRoZSBjYWNoZSB3aXRoIGxhdGVzdCBkYXRhXG4gICAgICAgICAgICAgIHRoaXMucmVxdWVzdChyZXNvdXJjZSwgJ0dFVCcsIG9wdClcbiAgICAgICAgICAgICAgICAudGhlbigoY2xvdWRSZXM6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgLy8gdXBkYXRlIHRoZSBjYWNoZSAoaWYgaXQgZmFpbHMsIGl0J3Mgb2spXG4gICAgICAgICAgICAgICAgICB0aGlzLnB1dEluQ2FjaGUocmVzb3VyY2UsIGNsb3VkUmVzLCBvcHQpLmNhdGNoKCgpID0+IHt9KTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaCgoKSA9PiB7fSk7IC8vIHdlIGFscmVhZHkgcmV0dXJuZWQgdGhlIHJlc3VsdCwgYW4gZXJyb3IgaXMgYWNjZXB0YWJsZVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgLy8gaWYgdGhlIHJlc3VsdCBpc24ndCBmb3VuZCBpbiB0aGUgY2FjaGUsIHJldHVybiB0aGUgcmVzdWx0IG9mIHRoZSBvbmxpbmUgcmVxdWVzdFxuICAgICAgICAgICAgICB0aGlzLnJlcXVlc3QocmVzb3VyY2UsICdHRVQnLCBvcHQpXG4gICAgICAgICAgICAgICAgLnRoZW4oKHJlczogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgICByZXNvbHZlKHJlcyk7XG4gICAgICAgICAgICAgICAgICAvLyB1cGRhdGUgdGhlIGNhY2hlIChpZiBpdCBmYWlscywgaXQncyBvaylcbiAgICAgICAgICAgICAgICAgIHRoaXMucHV0SW5DYWNoZShyZXNvdXJjZSwgcmVzLCBvcHQpLmNhdGNoKCgpID0+IHt9KTtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgIC5jYXRjaCgoZXJyOiBFcnJvcikgPT4gcmVqZWN0KGVycikpOyAvLyBlbGVtZW50IG5vdCBmb3VuZFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIENhY2hlTW9kZXMuTkVUV09SS19GSVJTVDpcbiAgICAgICAgICAvLyByZXR1cm4gdGhlIHJlc3VsdCBmcm9tIGFuIG9ubGluZSByZXF1ZXN0XG4gICAgICAgICAgdGhpcy5yZXF1ZXN0KHJlc291cmNlLCAnR0VUJywgb3B0KVxuICAgICAgICAgICAgLnRoZW4oKGNsb3VkUmVzOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgcmVzb2x2ZShjbG91ZFJlcyk7XG4gICAgICAgICAgICAgIC8vIGFzeW5jaHJvdW5vdXNseSBnZXQgdGhlIHNhbWUgZWxlbWVudCBmcm9tIGNhY2hlIGFuZCBkZWNpZGUgd2hldGhlciB0byB1cGRhdGUgb3Igbm90XG4gICAgICAgICAgICAgIHRoaXMuZ2V0RnJvbUNhY2hlKHJlc291cmNlLCBvcHQpLnRoZW4oKCkgPT4ge1xuICAgICAgICAgICAgICAgIC8vIHVwZGF0ZSB0aGUgY2FjaGUgKGlmIGl0IGZhaWxzLCBpdCdzIG9rKVxuICAgICAgICAgICAgICAgIHRoaXMucHV0SW5DYWNoZShyZXNvdXJjZSwgY2xvdWRSZXMsIG9wdCkuY2F0Y2goKCkgPT4ge30pO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgICAgICAvLyBpZiBhIHJlcXVlc3QgdG8gdGhlIG5ldHdvcmsgZmFpbHMsIGNoZWNrIGluIGNhY2hlXG4gICAgICAgICAgICAgIHRoaXMuZ2V0RnJvbUNhY2hlKHJlc291cmNlLCBvcHQpLnRoZW4oKHJlczogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHJlcykgcmVzb2x2ZShyZXMpO1xuICAgICAgICAgICAgICAgIGVsc2UgcmVqZWN0KCk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgLyogQ2FjaGVNb2Rlcy5OT19DQUNIRSAqL1xuICAgICAgICAgIC8vIHJldHVybiB0aGUgcmVzdWx0IGZyb20gYW4gb25saW5lIHJlcXVlc3QsIHdpdGggbm8gY2FjaGUgaW52b2x2ZWRcbiAgICAgICAgICB0aGlzLnJlcXVlc3QocmVzb3VyY2UsICdHRVQnLCBvcHQpXG4gICAgICAgICAgICAudGhlbigocmVzOiBhbnkpID0+IHJlc29sdmUocmVzKSlcbiAgICAgICAgICAgIC5jYXRjaCgoZXJyOiBFcnJvcikgPT4gcmVqZWN0KGVycikpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE9ic2VydmUgYSBHRVQgcmVxdWVzdC4gSW5jbHVkZSBvcHRpb25zIHRvIGNhY2hlIHRoZSByZXF1ZXN0cyAoYG9wdGlvbnMudXNlQ2FjaGVgKSwgdG8gd29yayBhbHNvIG9mZmxpbmUuXG4gICAqIEBwYXJhbSByZXNvdXJjZSByZXNvdXJjZSBuYW1lIChlLmcuIGB1c2Vyc2ApXG4gICAqIEBwYXJhbSBvcHRpb25zIHRoZSByZXF1ZXN0IG9wdGlvbnNcbiAgICovXG4gIGdldFJlc291cmNlT2JzZXJ2ZXIocmVzb3VyY2U6IHN0cmluZywgb3B0aW9ucz86IEFQSVJlcXVlc3RPcHRpb24pOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgIHJldHVybiBuZXcgT2JzZXJ2YWJsZShvYnNlcnZlciA9PiB7XG4gICAgICBjb25zdCBvcHQgPSBvcHRpb25zIHx8IHt9O1xuICAgICAgLy8gaWYgb2ZmbGluZSBhbmQgd2l0aCBhIGNhY2hlIG1vZGUgc2V0LCBmb3JjZSB0aGUgcmVxdWVzdCB0byB0aGUgY2FjaGVcbiAgICAgIGlmICghbmF2aWdhdG9yLm9uTGluZSAmJiBvcHQudXNlQ2FjaGUpIG9wdC51c2VDYWNoZSA9IENhY2hlTW9kZXMuQ0FDSEVfT05MWTtcbiAgICAgIC8vIGV4ZWN1dGUgdGhlIEdFVCByZXF1ZXN0IG9ubGluZSBvciB0aHJvdWdoIHRoZSBjYWNoZSwgZGVwZW5kaW5nIG9uIHRoZSBjaG9zZW4gbW9kZVxuICAgICAgc3dpdGNoIChvcHQudXNlQ2FjaGUpIHtcbiAgICAgICAgY2FzZSBDYWNoZU1vZGVzLkNBQ0hFX09OTFk6XG4gICAgICAgICAgLy8gcmV0dXJuIHRoZSByZXN1bHQgZnJvbSB0aGUgY2FjaGUsIHdpdGhvdXQgcmV0cnlpbmcgb25saW5lIGlmIGEgcmVzdWx0IHdhc24ndCBmb3VuZFxuICAgICAgICAgIHRoaXMuZ2V0RnJvbUNhY2hlKHJlc291cmNlLCBvcHQpLnRoZW4oKHJlczogYW55KSA9PiB7XG4gICAgICAgICAgICBpZiAocmVzKSBvYnNlcnZlci5uZXh0KHJlcyk7XG4gICAgICAgICAgICBlbHNlIG9ic2VydmVyLmVycm9yKCk7XG4gICAgICAgICAgfSk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgQ2FjaGVNb2Rlcy5DQUNIRV9GSVJTVDpcbiAgICAgICAgICAvLyByZXR1cm4gdGhlIHJlc3VsdCBmcm9tIHRoZSBjYWNoZVxuICAgICAgICAgIHRoaXMuZ2V0RnJvbUNhY2hlKHJlc291cmNlLCBvcHQpLnRoZW4oKGxvY2FsUmVzOiBhbnkpID0+IHtcbiAgICAgICAgICAgIGlmIChsb2NhbFJlcykge1xuICAgICAgICAgICAgICBvYnNlcnZlci5uZXh0KGxvY2FsUmVzKTtcbiAgICAgICAgICAgICAgLy8gYXN5bmNocm91bm91c2x5IGV4ZWN1dGUgdGhlIHJlcXVlc3Qgb25saW5lLCB0byB1cGRhdGUgdGhlIGNhY2hlIHdpdGggbGF0ZXN0IGRhdGFcbiAgICAgICAgICAgICAgdGhpcy5yZXF1ZXN0KHJlc291cmNlLCAnR0VUJywgb3B0KVxuICAgICAgICAgICAgICAgIC50aGVuKChjbG91ZFJlczogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgICBvYnNlcnZlci5uZXh0KGNsb3VkUmVzKTtcbiAgICAgICAgICAgICAgICAgIC8vIHVwZGF0ZSB0aGUgY2FjaGUgKGlmIGl0IGZhaWxzLCBpdCdzIG9rKVxuICAgICAgICAgICAgICAgICAgdGhpcy5wdXRJbkNhY2hlKHJlc291cmNlLCBjbG91ZFJlcywgb3B0KS5jYXRjaCgoKSA9PiB7fSk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKCkgPT4ge30pOyAvLyB3ZSBhbHJlYWR5IHJldHVybmVkIHRoZSByZXN1bHQsIGFuIGVycm9yIGlzIGFjY2VwdGFibGVcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIGlmIHRoZSByZXN1bHQgaXNuJ3QgZm91bmQgaW4gdGhlIGNhY2hlLCByZXR1cm4gdGhlIHJlc3VsdCBvZiB0aGUgb25saW5lIHJlcXVlc3RcbiAgICAgICAgICAgICAgdGhpcy5yZXF1ZXN0KHJlc291cmNlLCAnR0VUJywgb3B0KVxuICAgICAgICAgICAgICAgIC50aGVuKChyZXM6IGFueSkgPT4ge1xuICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dChyZXMpO1xuICAgICAgICAgICAgICAgICAgLy8gdXBkYXRlIHRoZSBjYWNoZSAoaWYgaXQgZmFpbHMsIGl0J3Mgb2spXG4gICAgICAgICAgICAgICAgICB0aGlzLnB1dEluQ2FjaGUocmVzb3VyY2UsIHJlcywgb3B0KS5jYXRjaCgoKSA9PiB7fSk7XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuY2F0Y2goKGVycjogRXJyb3IpID0+IG9ic2VydmVyLmVycm9yKGVycikpOyAvLyBlbGVtZW50IG5vdCBmb3VuZFxuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIENhY2hlTW9kZXMuTkVUV09SS19GSVJTVDpcbiAgICAgICAgICAvLyByZXR1cm4gdGhlIHJlc3VsdCBmcm9tIGFuIG9ubGluZSByZXF1ZXN0XG4gICAgICAgICAgdGhpcy5yZXF1ZXN0KHJlc291cmNlLCAnR0VUJywgb3B0KVxuICAgICAgICAgICAgLnRoZW4oKGNsb3VkUmVzOiBhbnkpID0+IHtcbiAgICAgICAgICAgICAgb2JzZXJ2ZXIubmV4dChjbG91ZFJlcyk7XG4gICAgICAgICAgICAgIC8vIHVwZGF0ZSB0aGUgY2FjaGUgKGlmIGl0IGZhaWxzLCBpdCdzIG9rKVxuICAgICAgICAgICAgICB0aGlzLnB1dEluQ2FjaGUocmVzb3VyY2UsIGNsb3VkUmVzLCBvcHQpLmNhdGNoKCgpID0+IHt9KTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAuY2F0Y2goKCkgPT4ge1xuICAgICAgICAgICAgICAvLyBpZiBhIHJlcXVlc3QgdG8gdGhlIG5ldHdvcmsgZmFpbHMsIGNoZWNrIGluIGNhY2hlXG4gICAgICAgICAgICAgIHRoaXMuZ2V0RnJvbUNhY2hlKHJlc291cmNlLCBvcHQpLnRoZW4oKHJlczogYW55KSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHJlcykgb2JzZXJ2ZXIubmV4dChyZXMpO1xuICAgICAgICAgICAgICAgIGVsc2Ugb2JzZXJ2ZXIuZXJyb3IoKTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAvKiBDYWNoZU1vZGVzLk5PX0NBQ0hFICovXG4gICAgICAgICAgLy8gcmV0dXJuIHRoZSByZXN1bHQgZnJvbSBhbiBvbmxpbmUgcmVxdWVzdCwgd2l0aCBubyBjYWNoZSBpbnZvbHZlZFxuICAgICAgICAgIHRoaXMucmVxdWVzdChyZXNvdXJjZSwgJ0dFVCcsIG9wdClcbiAgICAgICAgICAgIC50aGVuKChyZXM6IGFueSkgPT4gb2JzZXJ2ZXIubmV4dChyZXMpKVxuICAgICAgICAgICAgLmNhdGNoKChlcnI6IEVycm9yKSA9PiBvYnNlcnZlci5lcnJvcihlcnIpKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeGVjdXRlIGEgR0VUIHJlcXVlc3QgZnJvbSB0aGUgbG9jYWwgc3RvcmFnZS5cbiAgICogQHBhcmFtIHJlc291cmNlIHJlc291cmNlIG5hbWUgKGUuZy4gYHVzZXJzYClcbiAgICogQHBhcmFtIG9wdGlvbnMgdGhlIHJlcXVlc3Qgb3B0aW9uc1xuICAgKi9cbiAgZ2V0RnJvbUNhY2hlKHJlc291cmNlOiBzdHJpbmcsIG9wdGlvbnM/OiBBUElSZXF1ZXN0T3B0aW9uKTogUHJvbWlzZTxhbnk+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICBjb25zdCBvcHQgPSBvcHRpb25zIHx8IHt9O1xuICAgICAgLy8gcHJlcGFyZSB0aGUgdXJsIGFuZCB0aGUgcXVlcnkgcGFyYW1zXG4gICAgICBjb25zdCB1cmwgPSB0aGlzLnByZXBhcmVVUkwocmVzb3VyY2UsIG9wdCk7XG4gICAgICBjb25zdCBxdWVyeVBhcmFtcyA9IHRoaXMucHJlcGFyZVF1ZXJ5UGFyYW1zKG9wdC5wYXJhbXMpO1xuICAgICAgLy8gZ2V0IGZyb20gc3RvcmFnZSwgYnkgdGhlIGNvbXBsZXRlIHVybFxuICAgICAgdGhpcy5fc3RvcmFnZVxuICAgICAgICAuZ2V0KHVybC5jb25jYXQocXVlcnlQYXJhbXMudG9TdHJpbmcoKSkpXG4gICAgICAgIC50aGVuKChyZXM6IGFueSkgPT4gKHJlcyA/IHJlc29sdmUocmVzKSA6IG9wdC5yZXNvdXJjZUlkID8gcmVzb2x2ZShudWxsKSA6IHJlc29sdmUoW10pKSk7XG4gICAgfSk7XG4gIH1cbiAgLyoqXG4gICAqIEV4ZWN1dGUgYSBQVVQgcmVxdWVzdCBpbiB0aGUgbG9jYWwgc3RvcmFnZS5cbiAgICogQHBhcmFtIHJlc291cmNlIHJlc291cmNlIG5hbWUgKGUuZy4gYHVzZXJzYClcbiAgICogQHBhcmFtIGRhdGEgcmVzb3VyY2UgZGF0YVxuICAgKiBAcGFyYW0gb3B0aW9ucyB0aGUgcmVxdWVzdCBvcHRpb25zXG4gICAqL1xuICBwdXRJbkNhY2hlKHJlc291cmNlOiBzdHJpbmcsIGRhdGE6IGFueSwgb3B0aW9ucz86IEFQSVJlcXVlc3RPcHRpb24pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgY29uc3Qgb3B0ID0gb3B0aW9ucyB8fCB7fTtcbiAgICAgIC8vIHByZXBhcmUgdGhlIHVybCBhbmQgdGhlIHF1ZXJ5IHBhcmFtc1xuICAgICAgY29uc3QgdXJsID0gdGhpcy5wcmVwYXJlVVJMKHJlc291cmNlLCBvcHQpO1xuICAgICAgY29uc3QgcXVlcnlQYXJhbXMgPSB0aGlzLnByZXBhcmVRdWVyeVBhcmFtcyhvcHQucGFyYW1zKTtcbiAgICAgIC8vIHB1dCBpbiB0aGUgc3RvcmFnZSwgYnkgdGhlIGNvbXBsZXRlIHVybFxuICAgICAgdGhpcy5fc3RvcmFnZVxuICAgICAgICAuc2V0KHVybC5jb25jYXQocXVlcnlQYXJhbXMudG9TdHJpbmcoKSksIGRhdGEpXG4gICAgICAgIC50aGVuKCgpID0+IHJlc29sdmUoKSlcbiAgICAgICAgLmNhdGNoKChlcnI6IEVycm9yKSA9PiByZWplY3QoZXJyKSk7XG4gICAgfSk7XG4gIH1cbiAgLyoqXG4gICAqIEV4ZWN1dGUgYSBERUxFVEUgcmVxdWVzdCBpbiB0aGUgbG9jYWwgc3RvcmFnZS5cbiAgICogQHBhcmFtIHJlc291cmNlIHJlc291cmNlIG5hbWUgKGUuZy4gYHVzZXJzYClcbiAgICogQHBhcmFtIG9wdGlvbnMgdGhlIHJlcXVlc3Qgb3B0aW9uc1xuICAgKi9cbiAgZGVsZXRlRnJvbUNhY2hlKHJlc291cmNlOiBzdHJpbmcsIG9wdGlvbnM/OiBBUElSZXF1ZXN0T3B0aW9uKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgIGNvbnN0IG9wdCA9IG9wdGlvbnMgfHwge307XG4gICAgICAvLyBwcmVwYXJlIHRoZSB1cmwgYW5kIHRoZSBxdWVyeSBwYXJhbXNcbiAgICAgIGNvbnN0IHVybCA9IHRoaXMucHJlcGFyZVVSTChyZXNvdXJjZSwgb3B0KTtcbiAgICAgIGNvbnN0IHF1ZXJ5UGFyYW1zID0gdGhpcy5wcmVwYXJlUXVlcnlQYXJhbXMob3B0LnBhcmFtcyk7XG4gICAgICAvLyBkZWxldGUgZnJvbSBzdG9yYWdlLCBieSB0aGUgY29tcGxldGUgdXJsXG4gICAgICB0aGlzLl9zdG9yYWdlXG4gICAgICAgIC5yZW1vdmUodXJsLmNvbmNhdChxdWVyeVBhcmFtcy50b1N0cmluZygpKSlcbiAgICAgICAgLnRoZW4oKCkgPT4gcmVzb2x2ZSgpKVxuICAgICAgICAuY2F0Y2goKGVycjogRXJyb3IpID0+IHJlamVjdChlcnIpKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQT1NUIHJlcXVlc3QuXG4gICAqIEBwYXJhbSByZXNvdXJjZSByZXNvdXJjZSBuYW1lIChlLmcuIGB1c2Vyc2ApXG4gICAqIEBwYXJhbSBvcHRpb25zIHRoZSByZXF1ZXN0IG9wdGlvbnNcbiAgICovXG4gIHBvc3RSZXNvdXJjZShyZXNvdXJjZTogc3RyaW5nLCBvcHRpb25zPzogQVBJUmVxdWVzdE9wdGlvbik6IFByb21pc2U8YW55PiB7XG4gICAgcmV0dXJuIHRoaXMucmVxdWVzdChyZXNvdXJjZSwgJ1BPU1QnLCBvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQVVQgcmVxdWVzdC5cbiAgICogQHBhcmFtIHJlc291cmNlIHJlc291cmNlIG5hbWUgKGUuZy4gYHVzZXJzYClcbiAgICogQHBhcmFtIG9wdGlvbnMgdGhlIHJlcXVlc3Qgb3B0aW9uc1xuICAgKi9cbiAgcHV0UmVzb3VyY2UocmVzb3VyY2U6IHN0cmluZywgb3B0aW9ucz86IEFQSVJlcXVlc3RPcHRpb24pOiBQcm9taXNlPGFueT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QocmVzb3VyY2UsICdQVVQnLCBvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQQVRDSCByZXF1ZXN0LlxuICAgKiBAcGFyYW0gcmVzb3VyY2UgcmVzb3VyY2UgbmFtZSAoZS5nLiBgdXNlcnNgKVxuICAgKiBAcGFyYW0gb3B0aW9ucyB0aGUgcmVxdWVzdCBvcHRpb25zXG4gICAqL1xuICBwYXRjaFJlc291cmNlKHJlc291cmNlOiBzdHJpbmcsIG9wdGlvbnM/OiBBUElSZXF1ZXN0T3B0aW9uKTogUHJvbWlzZTxhbnk+IHtcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0KHJlc291cmNlLCAnUEFUQ0gnLCBvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBERUxFVEUgcmVxdWVzdC5cbiAgICogQHBhcmFtIHJlc291cmNlIHJlc291cmNlIG5hbWUgKGUuZy4gYHVzZXJzYClcbiAgICogQHBhcmFtIG9wdGlvbnMgdGhlIHJlcXVlc3Qgb3B0aW9uc1xuICAgKi9cbiAgZGVsZXRlUmVzb3VyY2UocmVzb3VyY2U6IHN0cmluZywgb3B0aW9ucz86IEFQSVJlcXVlc3RPcHRpb24pOiBQcm9taXNlPGFueT4ge1xuICAgIHJldHVybiB0aGlzLnJlcXVlc3QocmVzb3VyY2UsICdERUxFVEUnLCBvcHRpb25zKTtcbiAgfVxufVxuXG4vKipcbiAqIFRoZSBvcHRpb25zIG9mIGFuIEFQSSByZXF1ZXN0LlxuICovXG5leHBvcnQgY2xhc3MgQVBJUmVxdWVzdE9wdGlvbiB7XG4gIC8qKlxuICAgKiBUbyBpZGVudGlmeSBhIHNwZWNpZmljIHJlc291cmNlIGJ5IGlkLlxuICAgKi9cbiAgcmVzb3VyY2VJZD86IHN0cmluZztcbiAgLyoqXG4gICAqIFRoZSBxdWVyeSBwYXJhbWV0ZXJzIG9mIHRoZSByZXF1ZXN0LlxuICAgKi9cbiAgcGFyYW1zPzogYW55O1xuICAvKipcbiAgICogVGhlIGJvZHkgb2YgdGhlIHJlcXVlc3QuXG4gICAqL1xuICBib2R5PzogYW55O1xuICAvKipcbiAgICogVGhlIGFkZGl0aW9uYWwgaGVhZGVycyBvZiB0aGUgcmVxdWVzdDsgYEF1dGhvcml6YXRpb25gIGlzIGluY2x1ZGVkIGJ5IGRlZmF1bHQuXG4gICAqL1xuICBoZWFkZXJzPzogYW55O1xuICAvKipcbiAgICogV2hpY2ggbW9kZSB0byB1c2UgdG8gdGFrZSBhZHZhbmNlIG9mIHRoZSByZXF1ZXN0cyBjYWNoaW5nIG1lY2hhbmlzbS5cbiAgICovXG4gIHVzZUNhY2hlPzogQ2FjaGVNb2RlcztcbiAgLyoqXG4gICAqIElmIHRydWUsIHJlcG9ydCB0aGUgZXJyb3JzIHRoYXQgb2NjdXJzIGR1cmluZyB0aGUgcmVxdWVzdC5cbiAgICovXG4gIHJlcG9ydEVycm9yPzogYm9vbGVhbjtcbiAgLyoqXG4gICAqIElmIHRydWUsIHVzZSBJREVBJ3MgQVBJIGluc3RlYWQgb2YgdGhlIHByb2plY3QncyBBUEkpLlxuICAgKi9cbiAgaWRlYT86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBJZiBgaWRlYWAgaXMgbm90IHNldCwgc2V0IHRoaXMgdG8gdXNlIGFuIGFsdGVybmF0aXZlIEFQSSBVUkwgZm9yIHRoZSByZXF1ZXN0LlxuICAgKi9cbiAgYWx0ZXJuYXRpdmVBUEk/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogU2V0IG9mIHVzYWJsZSBjYWNoZSBtb2Rlcy5cbiAqL1xuZXhwb3J0IGVudW0gQ2FjaGVNb2RlcyB7XG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIHJlc3VsdCBmcm9tIGFuIG9ubGluZSByZXF1ZXN0LCB3aXRoIG5vIGNhY2hlIGludm9sdmVkLlxuICAgKi9cbiAgTk9fQ0FDSEUgPSAwLFxuICAvKipcbiAgICogUmV0dXJuIHRoZSByZXN1bHQgZnJvbSBhbiBvbmxpbmUgcmVxdWVzdCwgc3RvcmluZyB0aGUgcmVzdWx0IGluIHRoZSBjYWNoZSwgdG8gdXBkYXRlIGl0IHdpdGggdGhlIGxhdGVzdCBkYXRhLlxuICAgKi9cbiAgTkVUV09SS19GSVJTVCxcbiAgLyoqXG4gICAqIFJldHVybiB0aGUgcmVzdWx0IGZyb20gdGhlIGNhY2hlLCBidXQgYWxzbyBleGVjdXRlIHRoZSByZXF1ZXN0IG9ubGluZSwgdG8gdXBkYXRlIHRoZSBjYWNoZSB3aXRoIHRoZSBsYXRlc3QgZGF0YS5cbiAgICovXG4gIENBQ0hFX0ZJUlNULFxuICAvKipcbiAgICogUmV0dXJuIHRoZSByZXN1bHQgZnJvbSB0aGUgY2FjaGUsIHdpdGhvdXQgcmV0cnlpbmcgb25saW5lIGlmIGEgcmVzdWx0IHdhc24ndCBmb3VuZC5cbiAgICovXG4gIENBQ0hFX09OTFlcbn1cbiJdfQ==