@gnwebsoft/ui 4.0.1 → 4.0.3

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.
@@ -1,1596 +0,0 @@
1
- // src/core/api/CorrelationIdGenerator.ts
2
- var CorrelationIdGenerator = class {
3
- static generateUUID() {
4
- if (typeof crypto !== "undefined" && crypto.randomUUID) {
5
- return crypto.randomUUID();
6
- }
7
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
8
- const r = Math.random() * 16 | 0;
9
- const v = c === "x" ? r : r & 3 | 8;
10
- return v.toString(16);
11
- });
12
- }
13
- static generate(prefix) {
14
- const uuid = this.generateUUID();
15
- return prefix ? `${prefix}-${uuid}` : uuid;
16
- }
17
- };
18
-
19
- // src/core/api/RequestManager.ts
20
- var RequestManager = class {
21
- activeRequests = /* @__PURE__ */ new Map();
22
- correlationMap = /* @__PURE__ */ new Map();
23
- add(key, controller, correlationId) {
24
- this.cancel(key);
25
- this.activeRequests.set(key, controller);
26
- this.correlationMap.set(key, correlationId);
27
- }
28
- remove(key) {
29
- this.activeRequests.delete(key);
30
- this.correlationMap.delete(key);
31
- }
32
- cancel(key) {
33
- const controller = this.activeRequests.get(key);
34
- if (controller) {
35
- controller.abort();
36
- this.activeRequests.delete(key);
37
- this.correlationMap.delete(key);
38
- }
39
- }
40
- cancelAll() {
41
- this.activeRequests.forEach((controller) => controller.abort());
42
- this.activeRequests.clear();
43
- this.correlationMap.clear();
44
- }
45
- has(key) {
46
- return this.activeRequests.has(key);
47
- }
48
- getCorrelationId(key) {
49
- return this.correlationMap.get(key);
50
- }
51
- };
52
-
53
- // src/core/api/ApiClient.ts
54
- var ApiClient = class {
55
- baseURL;
56
- defaultTimeout;
57
- requestInterceptors = [];
58
- responseInterceptors = [];
59
- errorInterceptors = [];
60
- authToken = null;
61
- refreshTokenPromise = null;
62
- requestManager = new RequestManager();
63
- correlationIdPrefix = "api";
64
- includeCorrelationId = true;
65
- constructor(baseURL = "", defaultTimeout = 3e4) {
66
- this.baseURL = baseURL;
67
- this.defaultTimeout = defaultTimeout;
68
- }
69
- // Configuration methods
70
- setCorrelationIdPrefix(prefix) {
71
- this.correlationIdPrefix = prefix;
72
- }
73
- setIncludeCorrelationId(include) {
74
- this.includeCorrelationId = include;
75
- }
76
- // Interceptor management
77
- addRequestInterceptor(interceptor) {
78
- this.requestInterceptors.push(interceptor);
79
- return () => {
80
- const index = this.requestInterceptors.indexOf(interceptor);
81
- if (index > -1) this.requestInterceptors.splice(index, 1);
82
- };
83
- }
84
- addResponseInterceptor(interceptor) {
85
- this.responseInterceptors.push(interceptor);
86
- return () => {
87
- const index = this.responseInterceptors.indexOf(interceptor);
88
- if (index > -1) this.responseInterceptors.splice(index, 1);
89
- };
90
- }
91
- addErrorInterceptor(interceptor) {
92
- this.errorInterceptors.push(interceptor);
93
- return () => {
94
- const index = this.errorInterceptors.indexOf(interceptor);
95
- if (index > -1) this.errorInterceptors.splice(index, 1);
96
- };
97
- }
98
- // Auth token management
99
- setAuthToken(token) {
100
- this.authToken = token;
101
- }
102
- getAuthToken() {
103
- return this.authToken;
104
- }
105
- // Request cancellation
106
- cancelRequest(key) {
107
- this.requestManager.cancel(key);
108
- }
109
- cancelAllRequests() {
110
- this.requestManager.cancelAll();
111
- }
112
- // URL and params handling
113
- buildURL(endpoint, params) {
114
- const url = new URL(endpoint, this.baseURL);
115
- if (params) {
116
- Object.keys(params).forEach((key) => {
117
- const value = params[key];
118
- if (value !== void 0 && value !== null) {
119
- if (Array.isArray(value)) {
120
- value.forEach((v) => url.searchParams.append(key, String(v)));
121
- } else {
122
- url.searchParams.append(key, String(value));
123
- }
124
- }
125
- });
126
- }
127
- return url.toString();
128
- }
129
- // Apply request interceptors
130
- async applyRequestInterceptors(config) {
131
- let modifiedConfig = { ...config };
132
- for (const interceptor of this.requestInterceptors) {
133
- modifiedConfig = await interceptor(modifiedConfig);
134
- }
135
- return modifiedConfig;
136
- }
137
- // Apply response interceptors
138
- async applyResponseInterceptors(response) {
139
- let modifiedResponse = response;
140
- for (const interceptor of this.responseInterceptors) {
141
- modifiedResponse = await interceptor(modifiedResponse);
142
- }
143
- return modifiedResponse;
144
- }
145
- // Apply error interceptors
146
- async applyErrorInterceptors(error) {
147
- let modifiedError = error;
148
- for (const interceptor of this.errorInterceptors) {
149
- try {
150
- modifiedError = await interceptor(modifiedError);
151
- } catch (e) {
152
- modifiedError = e;
153
- }
154
- }
155
- throw modifiedError;
156
- }
157
- // Create combined abort signal
158
- createCombinedSignal(signals) {
159
- const controller = new AbortController();
160
- for (const signal of signals) {
161
- if (signal) {
162
- if (signal.aborted) {
163
- controller.abort(signal.reason);
164
- break;
165
- }
166
- signal.addEventListener(
167
- "abort",
168
- () => {
169
- controller.abort(signal.reason);
170
- },
171
- { once: true }
172
- );
173
- }
174
- }
175
- return controller;
176
- }
177
- // Timeout handling with AbortSignal
178
- createTimeoutSignal(timeout) {
179
- const controller = new AbortController();
180
- const timeoutId = setTimeout(() => {
181
- controller.abort(`Request timeout after ${timeout}ms`);
182
- }, timeout);
183
- controller.signal.addEventListener(
184
- "abort",
185
- () => {
186
- clearTimeout(timeoutId);
187
- },
188
- { once: true }
189
- );
190
- return controller;
191
- }
192
- // Retry logic with abort support
193
- async retryRequest(fn, retries, delay, signal) {
194
- try {
195
- if (signal?.aborted) {
196
- throw new Error(signal.reason || "Request aborted");
197
- }
198
- return await fn();
199
- } catch (error) {
200
- if (error.name === "AbortError" || signal?.aborted) {
201
- throw error;
202
- }
203
- if (error.type === "validation_error" || error.status === 400) {
204
- throw error;
205
- }
206
- if (retries === 0) throw error;
207
- await new Promise((resolve, reject) => {
208
- const timeoutId = setTimeout(resolve, delay);
209
- if (signal) {
210
- signal.addEventListener(
211
- "abort",
212
- () => {
213
- clearTimeout(timeoutId);
214
- reject(new Error(signal.reason || "Request aborted"));
215
- },
216
- { once: true }
217
- );
218
- }
219
- });
220
- return this.retryRequest(fn, retries - 1, delay * 2, signal);
221
- }
222
- }
223
- // Main request method implementation
224
- async request(endpoint, config = {}) {
225
- const correlationId = config.correlationId || (!config.skipCorrelationId && this.includeCorrelationId ? CorrelationIdGenerator.generate(this.correlationIdPrefix) : void 0);
226
- const requestKey = `${config.method || "GET"}_${endpoint}_${Date.now()}`;
227
- const masterController = new AbortController();
228
- try {
229
- const signals = [
230
- config.signal,
231
- config.cancelToken?.signal,
232
- masterController.signal
233
- ];
234
- const timeout = config.timeout || this.defaultTimeout;
235
- const timeoutController = this.createTimeoutSignal(timeout);
236
- signals.push(timeoutController.signal);
237
- const combinedController = this.createCombinedSignal(signals);
238
- if (correlationId) {
239
- this.requestManager.add(requestKey, masterController, correlationId);
240
- }
241
- const finalConfig = await this.applyRequestInterceptors({
242
- ...config,
243
- signal: combinedController.signal,
244
- correlationId
245
- });
246
- const url = this.buildURL(endpoint, finalConfig.params);
247
- const headers = new Headers(finalConfig.headers);
248
- if (correlationId) {
249
- headers.set("X-Correlation-Id", correlationId);
250
- headers.set("X-Request-Id", correlationId);
251
- }
252
- if (this.authToken && !finalConfig.skipAuthRefresh) {
253
- headers.set("Authorization", `Bearer ${this.authToken}`);
254
- }
255
- if (finalConfig.body && typeof finalConfig.body === "object" && !(finalConfig.body instanceof FormData)) {
256
- headers.set("Content-Type", "application/json");
257
- finalConfig.body = JSON.stringify(finalConfig.body);
258
- }
259
- finalConfig.headers = headers;
260
- const fetchPromise = async () => {
261
- try {
262
- const response = await fetch(url, {
263
- ...finalConfig,
264
- signal: combinedController.signal
265
- });
266
- const responseData = await this.parseResponseData(response);
267
- if (!response.ok) {
268
- const error = Object.assign(
269
- new Error(
270
- responseData.title || `HTTP ${response.status}: ${response.statusText}`
271
- ),
272
- {
273
- type: responseData.type || this.getErrorType(response.status),
274
- title: responseData.title || this.getErrorTitle(response.status),
275
- status: response.status,
276
- traceId: responseData.traceId || correlationId,
277
- errors: responseData.errors,
278
- isAborted: false,
279
- config: finalConfig
280
- }
281
- );
282
- if (finalConfig.throwErrors !== false) {
283
- throw error;
284
- } else {
285
- return await this.applyResponseInterceptors({
286
- error
287
- });
288
- }
289
- }
290
- const apiResponse = {
291
- data: responseData
292
- };
293
- return await this.applyResponseInterceptors(apiResponse);
294
- } catch (error) {
295
- if (error.name === "AbortError") {
296
- const abortError = Object.assign(
297
- new Error(error.message || "Request aborted"),
298
- {
299
- type: "request_cancelled",
300
- title: "Request was cancelled",
301
- status: 0,
302
- traceId: correlationId,
303
- isAborted: true,
304
- config: finalConfig
305
- }
306
- );
307
- if (finalConfig.throwErrors !== false) {
308
- throw abortError;
309
- } else {
310
- return await this.applyResponseInterceptors({
311
- error: abortError
312
- });
313
- }
314
- }
315
- throw error;
316
- }
317
- };
318
- if (finalConfig.retries && finalConfig.retries > 0) {
319
- return await this.retryRequest(
320
- fetchPromise,
321
- finalConfig.retries,
322
- finalConfig.retryDelay || 1e3,
323
- combinedController.signal
324
- );
325
- }
326
- return await fetchPromise();
327
- } catch (error) {
328
- const apiError = this.normalizeError(
329
- error,
330
- config,
331
- correlationId
332
- );
333
- if (config.throwErrors !== false) {
334
- await this.applyErrorInterceptors(apiError);
335
- throw apiError;
336
- } else {
337
- return {
338
- error: apiError
339
- };
340
- }
341
- } finally {
342
- this.requestManager.remove(requestKey);
343
- }
344
- }
345
- // Get error type based on status code
346
- getErrorType(status) {
347
- if (status >= 400 && status < 500) {
348
- return status === 400 ? "validation_error" : "client_error";
349
- } else if (status >= 500) {
350
- return "server_error";
351
- }
352
- return "unknown_error";
353
- }
354
- // Get error title based on status code
355
- getErrorTitle(status) {
356
- const titles = {
357
- 400: "Bad Request",
358
- 401: "Unauthorized",
359
- 403: "Forbidden",
360
- 404: "Not Found",
361
- 405: "Method Not Allowed",
362
- 408: "Request Timeout",
363
- 409: "Conflict",
364
- 422: "Unprocessable Entity",
365
- 429: "Too Many Requests",
366
- 500: "Internal Server Error",
367
- 502: "Bad Gateway",
368
- 503: "Service Unavailable",
369
- 504: "Gateway Timeout"
370
- };
371
- return titles[status] || `HTTP Error ${status}`;
372
- }
373
- // Parse response data based on content type
374
- async parseResponseData(response) {
375
- const contentType = response.headers.get("content-type");
376
- if (contentType?.includes("application/json")) {
377
- return response.json();
378
- } else if (contentType?.includes("text/")) {
379
- return response.text();
380
- } else if (contentType?.includes("application/octet-stream")) {
381
- return response.blob();
382
- } else {
383
- const text = await response.text();
384
- try {
385
- return JSON.parse(text);
386
- } catch {
387
- return text;
388
- }
389
- }
390
- }
391
- // Normalize errors
392
- normalizeError(error, config, correlationId) {
393
- if (error.type || error.title || error.errors) {
394
- return Object.assign(
395
- error instanceof Error ? error : new Error(error.message || "Unknown error"),
396
- {
397
- type: error.type,
398
- title: error.title,
399
- status: error.status,
400
- traceId: error.traceId || correlationId,
401
- errors: error.errors,
402
- isAborted: error.isAborted || false,
403
- config
404
- }
405
- );
406
- }
407
- if (error.name === "AbortError" || error.isAborted) {
408
- return Object.assign(new Error(error.message || "Request was aborted"), {
409
- type: "request_cancelled",
410
- title: "Request was cancelled",
411
- status: 0,
412
- traceId: correlationId,
413
- isAborted: true,
414
- config
415
- });
416
- }
417
- if (error.message?.includes("timeout")) {
418
- return Object.assign(new Error(error.message), {
419
- type: "timeout_error",
420
- title: "Request Timeout",
421
- status: 408,
422
- traceId: correlationId,
423
- isAborted: true,
424
- config
425
- });
426
- }
427
- if (error.message?.includes("network")) {
428
- return Object.assign(
429
- new Error(error.message || "Network request failed"),
430
- {
431
- type: "network_error",
432
- title: "Network Error",
433
- status: 0,
434
- traceId: correlationId,
435
- isAborted: false,
436
- config
437
- }
438
- );
439
- }
440
- return Object.assign(
441
- new Error(error.message || "An unknown error occurred"),
442
- {
443
- type: "unknown_error",
444
- title: "Unknown Error",
445
- status: 0,
446
- traceId: correlationId,
447
- isAborted: false,
448
- config
449
- }
450
- );
451
- }
452
- get(endpoint, config) {
453
- return this.request(endpoint, { ...config, method: "GET" });
454
- }
455
- post(endpoint, data, config) {
456
- return this.request(endpoint, { ...config, method: "POST", body: data });
457
- }
458
- put(endpoint, data, config) {
459
- return this.request(endpoint, { ...config, method: "PUT", body: data });
460
- }
461
- patch(endpoint, data, config) {
462
- return this.request(endpoint, {
463
- ...config,
464
- method: "PATCH",
465
- body: data
466
- });
467
- }
468
- delete(endpoint, config) {
469
- return this.request(endpoint, { ...config, method: "DELETE" });
470
- }
471
- filter(url, data, config) {
472
- const mergedData = { ...data, ...data.filterModel };
473
- return this.request(url, {
474
- ...config,
475
- method: "POST",
476
- body: mergedData
477
- });
478
- }
479
- };
480
-
481
- // src/core/api/createApiClient.ts
482
- var globalApiClient = null;
483
- function createApiClient(config = {}) {
484
- const {
485
- baseURL = import.meta.env.VITE_API_URL,
486
- timeout = 3e4,
487
- correlationIdPrefix = "api",
488
- includeCorrelationId = true,
489
- requestInterceptors = [],
490
- responseInterceptors = [],
491
- errorInterceptors = []
492
- } = config;
493
- const client = new ApiClient(baseURL, timeout);
494
- client.addRequestInterceptor((config2) => {
495
- const token = localStorage.getItem("serviceToken");
496
- if (token && !config2.skipAuthRefresh) {
497
- config2.headers = {
498
- ...config2.headers,
499
- Authorization: `Bearer ${token}`
500
- };
501
- }
502
- return config2;
503
- });
504
- client.setCorrelationIdPrefix(correlationIdPrefix);
505
- client.setIncludeCorrelationId(includeCorrelationId);
506
- requestInterceptors.forEach((interceptor) => {
507
- client.addRequestInterceptor(interceptor);
508
- });
509
- responseInterceptors.forEach((interceptor) => {
510
- client.addResponseInterceptor(interceptor);
511
- });
512
- errorInterceptors.forEach((interceptor) => {
513
- client.addErrorInterceptor(interceptor);
514
- });
515
- return client;
516
- }
517
- function getGlobalApiClient(config) {
518
- if (!globalApiClient) {
519
- globalApiClient = createApiClient(config);
520
- }
521
- return globalApiClient;
522
- }
523
- function setGlobalApiClient(client) {
524
- globalApiClient = client;
525
- }
526
- function resetGlobalApiClient() {
527
- globalApiClient = null;
528
- }
529
-
530
- // src/core/api/types/CancelToken.ts
531
- var CancelToken = class _CancelToken {
532
- abortController;
533
- cancelPromise;
534
- cancelResolve;
535
- constructor() {
536
- this.abortController = new AbortController();
537
- this.cancelPromise = new Promise((resolve) => {
538
- this.cancelResolve = resolve;
539
- });
540
- }
541
- get signal() {
542
- return this.abortController.signal;
543
- }
544
- cancel(reason) {
545
- this.abortController.abort(reason);
546
- this.cancelResolve?.();
547
- }
548
- get isCancelled() {
549
- return this.abortController.signal.aborted;
550
- }
551
- throwIfCancelled() {
552
- if (this.isCancelled) {
553
- throw new Error("Request cancelled");
554
- }
555
- }
556
- static source() {
557
- const token = new _CancelToken();
558
- return {
559
- token,
560
- cancel: (reason) => token.cancel(reason)
561
- };
562
- }
563
- };
564
-
565
- // src/core/api/useValidationErrors.ts
566
- import { useCallback } from "react";
567
- function useValidationErrors(error) {
568
- const getFieldError = useCallback(
569
- (field) => {
570
- if (!error?.errors || !error.errors[field]) return null;
571
- const fieldError = error.errors[field];
572
- if (typeof fieldError === "string") return fieldError;
573
- if (Array.isArray(fieldError)) return fieldError[0];
574
- if (typeof fieldError === "object" && "message" in fieldError) {
575
- return fieldError.message;
576
- }
577
- return null;
578
- },
579
- [error]
580
- );
581
- const hasFieldError = useCallback(
582
- (field) => {
583
- return !!getFieldError(field);
584
- },
585
- [getFieldError]
586
- );
587
- const getAllErrors = useCallback(() => {
588
- if (!error?.errors) return {};
589
- const result = {};
590
- Object.entries(error.errors).forEach(([key, value]) => {
591
- if (typeof value === "string") {
592
- result[key] = value;
593
- } else if (Array.isArray(value)) {
594
- result[key] = value.join(", ");
595
- } else if (typeof value === "object" && value && "message" in value) {
596
- result[key] = value.message;
597
- }
598
- });
599
- return result;
600
- }, [error]);
601
- return {
602
- getFieldError,
603
- hasFieldError,
604
- getAllErrors,
605
- hasErrors: error?.errors
606
- };
607
- }
608
-
609
- // src/core/components/AuthorizedView/AuthorizedView.tsx
610
- import { Fragment, jsx } from "react/jsx-runtime";
611
- var AuthorizedView = ({ children, show }) => {
612
- if (!show) return /* @__PURE__ */ jsx(Fragment, {});
613
- return /* @__PURE__ */ jsx(Fragment, { children });
614
- };
615
-
616
- // src/core/components/CancelButton/CancelButton.tsx
617
- import { Button } from "@mui/material";
618
- import { jsx as jsx2 } from "react/jsx-runtime";
619
- var CancelButton = ({
620
- children = "Cancel",
621
- variant = "outlined",
622
- sx,
623
- ...rest
624
- }) => /* @__PURE__ */ jsx2(Button, { variant, sx: { width: "6rem", ...sx }, ...rest, children });
625
-
626
- // src/core/components/ClearButton/ClearButton.tsx
627
- import { Button as Button2 } from "@mui/material";
628
- import { jsx as jsx3 } from "react/jsx-runtime";
629
- var ClearButton = ({
630
- isSubmitting,
631
- handleClear,
632
- sx,
633
- storeKey
634
- }) => {
635
- const onClick = () => {
636
- handleClear();
637
- if (storeKey != null) {
638
- localStorage.removeItem(storeKey);
639
- }
640
- };
641
- return /* @__PURE__ */ jsx3(
642
- Button2,
643
- {
644
- variant: "outlined",
645
- onClick,
646
- disabled: isSubmitting,
647
- sx,
648
- children: "Clear"
649
- }
650
- );
651
- };
652
-
653
- // src/core/components/Containers/SimpleContainer.tsx
654
- import { Container } from "@mui/material";
655
- import { jsx as jsx4 } from "react/jsx-runtime";
656
- var SimpleContainer = ({
657
- children,
658
- className,
659
- sx
660
- }) => /* @__PURE__ */ jsx4(Container, { className, sx: { ...sx }, children });
661
-
662
- // src/core/components/FilterButton/FilterButton.tsx
663
- import FilterAltIcon from "@mui/icons-material/FilterAlt";
664
- import { LoadingButton } from "@mui/lab";
665
- import { Badge } from "@mui/material";
666
- import { jsx as jsx5 } from "react/jsx-runtime";
667
- var FilterButton = ({
668
- isSubmitting,
669
- show,
670
- title,
671
- icon,
672
- sx,
673
- iconSx
674
- }) => {
675
- return /* @__PURE__ */ jsx5(
676
- LoadingButton,
677
- {
678
- type: "submit",
679
- variant: "contained",
680
- loading: isSubmitting,
681
- disabled: !show,
682
- disableRipple: true,
683
- color: "primary",
684
- sx: {
685
- display: "flex",
686
- alignItems: "center",
687
- ...sx
688
- },
689
- startIcon: /* @__PURE__ */ jsx5(Badge, { color: "error", variant: "standard", children: icon ? icon : /* @__PURE__ */ jsx5(FilterAltIcon, { width: "20", height: "20", sx: iconSx }) }),
690
- children: title?.trim() === "" || !title ? "Filter" : title
691
- }
692
- );
693
- };
694
-
695
- // src/core/components/FilterDisplay/FilterChip.tsx
696
- import Chip from "@mui/material/Chip";
697
- import { memo } from "react";
698
- import { jsx as jsx6 } from "react/jsx-runtime";
699
- var FilterChip = memo(
700
- ({
701
- fieldKey,
702
- filter,
703
- onDelete
704
- }) => {
705
- const hasValue = filter.Value !== null && filter.Value !== void 0 && filter.Value !== "";
706
- const label = `${fieldKey.replace("PK", "")}: ${filter.Label}`;
707
- return /* @__PURE__ */ jsx6(
708
- Chip,
709
- {
710
- label,
711
- variant: hasValue ? "filled" : "outlined",
712
- size: "small",
713
- onDelete: hasValue ? onDelete : void 0
714
- },
715
- fieldKey
716
- );
717
- }
718
- );
719
- FilterChip.displayName = "FilterChip";
720
-
721
- // src/core/components/FilterDisplay/FilterDisplay.tsx
722
- import { Card, CardContent, Typography, Box } from "@mui/material";
723
- import { memo as memo2, useMemo } from "react";
724
- import { jsx as jsx7, jsxs } from "react/jsx-runtime";
725
- var ProgramsFilterDisplay = memo2(
726
- (props) => {
727
- const { friendlyFilter, onFriendlyFilterChange } = props;
728
- const deleteHandlers = useMemo(() => {
729
- if (!onFriendlyFilterChange) return {};
730
- const handlers = {};
731
- for (const key of Object.keys(friendlyFilter)) {
732
- handlers[key] = () => onFriendlyFilterChange(key);
733
- }
734
- return handlers;
735
- }, [onFriendlyFilterChange, friendlyFilter]);
736
- const chipList = useMemo(() => {
737
- return Object.entries(friendlyFilter).map(([key, filter]) => /* @__PURE__ */ jsx7(
738
- FilterChip,
739
- {
740
- fieldKey: key,
741
- filter,
742
- onDelete: deleteHandlers[key]
743
- },
744
- key
745
- ));
746
- }, [friendlyFilter, deleteHandlers]);
747
- return /* @__PURE__ */ jsx7(Card, { sx: { mb: 2 }, children: /* @__PURE__ */ jsxs(CardContent, { children: [
748
- /* @__PURE__ */ jsx7(Typography, { variant: "h6", gutterBottom: true, children: "Active Filters" }),
749
- /* @__PURE__ */ jsx7(Box, { display: "flex", gap: 1, flexWrap: "wrap", children: chipList })
750
- ] }) });
751
- }
752
- );
753
- ProgramsFilterDisplay.displayName = "FilterDisplay";
754
-
755
- // src/core/components/FilterWrapper/FilterWrapper.tsx
756
- import ManageSearchIcon from "@mui/icons-material/ManageSearch";
757
- import {
758
- Box as Box2,
759
- Card as Card2,
760
- CardContent as CardContent2,
761
- CardHeader,
762
- Divider,
763
- Grid,
764
- Typography as Typography2,
765
- useTheme
766
- } from "@mui/material";
767
- import { Fragment as Fragment2, jsx as jsx8, jsxs as jsxs2 } from "react/jsx-runtime";
768
- var FilterWrapper = ({
769
- children,
770
- title,
771
- filterCount,
772
- cardSx,
773
- textSx,
774
- icon,
775
- iconSx,
776
- showCount
777
- }) => {
778
- const theme = useTheme();
779
- return /* @__PURE__ */ jsxs2(
780
- Card2,
781
- {
782
- sx: {
783
- position: "relative",
784
- borderRadius: "0px",
785
- mb: 2,
786
- ...cardSx
787
- },
788
- children: [
789
- /* @__PURE__ */ jsx8(
790
- CardHeader,
791
- {
792
- sx: {
793
- display: "flex",
794
- flexWrap: "wrap",
795
- p: "1rem",
796
- ".MuiCardHeader-action": {
797
- margin: 0,
798
- alignSelf: "center"
799
- },
800
- alignItems: "center"
801
- },
802
- title: /* @__PURE__ */ jsxs2(Box2, { sx: { display: "flex", alignItems: "center", gap: 0.5 }, children: [
803
- icon ? icon : /* @__PURE__ */ jsx8(
804
- ManageSearchIcon,
805
- {
806
- sx: {
807
- height: "2.5rem",
808
- color: theme.palette.primary.main,
809
- ...iconSx
810
- }
811
- }
812
- ),
813
- /* @__PURE__ */ jsxs2(
814
- Typography2,
815
- {
816
- variant: "h5",
817
- sx: {
818
- fontWeight: "bold",
819
- color: theme.palette.primary.main,
820
- ...textSx
821
- },
822
- children: [
823
- title ? title : "Filter",
824
- " ",
825
- showCount ? `(${filterCount ? filterCount : 0})` : /* @__PURE__ */ jsx8(Fragment2, {})
826
- ]
827
- }
828
- )
829
- ] })
830
- }
831
- ),
832
- /* @__PURE__ */ jsx8(Divider, {}),
833
- /* @__PURE__ */ jsx8(CardContent2, { sx: { py: 2 }, children: /* @__PURE__ */ jsx8(Grid, { container: true, spacing: 2, children }) })
834
- ]
835
- }
836
- );
837
- };
838
-
839
- // src/core/components/Footer/Footer.tsx
840
- import { Box as Box3, Typography as Typography3 } from "@mui/material";
841
- import { jsx as jsx9 } from "react/jsx-runtime";
842
- var Footer = () => {
843
- const currentYear = (/* @__PURE__ */ new Date()).getFullYear();
844
- return /* @__PURE__ */ jsx9(
845
- Box3,
846
- {
847
- component: "footer",
848
- sx: {
849
- py: 2,
850
- px: 4,
851
- mt: "auto",
852
- backgroundColor: (theme) => theme.palette.mode === "light" ? theme.palette.grey[200] : theme.palette.grey[800]
853
- },
854
- children: /* @__PURE__ */ jsx9(Typography3, { variant: "body2", color: "text.secondary", align: "center", children: `\xA9 Copyright ${currentYear} GN. All rights reserved by Parul University.` })
855
- }
856
- );
857
- };
858
-
859
- // src/core/components/LabelText/LabelText.tsx
860
- import { Grid as Grid2, Tooltip, Typography as Typography4 } from "@mui/material";
861
- import { jsx as jsx10, jsxs as jsxs3 } from "react/jsx-runtime";
862
- var LabelText = ({
863
- label,
864
- value,
865
- gridSize,
866
- containerSize,
867
- labelSx,
868
- valueSx
869
- }) => {
870
- const defaultGridSize = {
871
- labelSize: { xs: 6, sm: 6, md: 6 },
872
- valueSize: { xs: 12, sm: 6, md: 6 }
873
- };
874
- const defaultContainerSize = { xs: 12, sm: 6, md: 6 };
875
- const size = gridSize || defaultGridSize;
876
- const container = containerSize || defaultContainerSize;
877
- return /* @__PURE__ */ jsxs3(
878
- Grid2,
879
- {
880
- size: container,
881
- sx: {
882
- display: "flex",
883
- flexDirection: { xs: "column", sm: "row", md: "row" },
884
- "&:hover": { bgcolor: "#efefef", overflow: "hidden" }
885
- },
886
- children: [
887
- /* @__PURE__ */ jsxs3(
888
- Grid2,
889
- {
890
- size: size.labelSize,
891
- sx: {
892
- padding: "5px",
893
- fontSize: "14px",
894
- textAlign: { xs: "left", sm: "right", md: "right" },
895
- ...labelSx
896
- },
897
- children: [
898
- label,
899
- " :"
900
- ]
901
- }
902
- ),
903
- /* @__PURE__ */ jsx10(
904
- Grid2,
905
- {
906
- size: size.valueSize,
907
- sx: { padding: "5px", display: "flex", flexWrap: "wrap" },
908
- children: /* @__PURE__ */ jsx10(Tooltip, { title: value, arrow: true, children: /* @__PURE__ */ jsx10(
909
- Typography4,
910
- {
911
- sx: {
912
- fontSize: "14px",
913
- wordBreak: "break-word",
914
- overflow: "hidden",
915
- display: "-webkit-box",
916
- textOverflow: "ellipsis",
917
- WebkitLineClamp: 2,
918
- WebkitBoxOrient: "vertical",
919
- ...valueSx,
920
- color: "#078dee"
921
- },
922
- children: value ? value : "-"
923
- }
924
- ) })
925
- }
926
- )
927
- ]
928
- }
929
- );
930
- };
931
-
932
- // src/core/components/RenderIf/RenderIf.tsx
933
- import { Fragment as Fragment3, jsx as jsx11 } from "react/jsx-runtime";
934
- var RenderIf = ({
935
- show,
936
- children
937
- }) => {
938
- return show ? /* @__PURE__ */ jsx11(Fragment3, { children }) : null;
939
- };
940
-
941
- // src/core/components/SectionBox/SectionBox.tsx
942
- import { Box as Box4, Divider as Divider2, Grid as Grid3, Stack, Typography as Typography5 } from "@mui/material";
943
- import { memo as memo3, useMemo as useMemo2 } from "react";
944
- import { Fragment as Fragment4, jsx as jsx12, jsxs as jsxs4 } from "react/jsx-runtime";
945
- var getSectionTheme = (variant = "default") => {
946
- const themes = {
947
- default: {
948
- bgcolor: "#faebd7",
949
- color: "#925d21"
950
- },
951
- form: {
952
- bgcolor: "#cdced1",
953
- color: "black"
954
- },
955
- info: {
956
- bgcolor: "#e3f2fd",
957
- color: "#1976d2"
958
- },
959
- warning: {
960
- bgcolor: "#fff3e0",
961
- color: "#f57c00"
962
- },
963
- error: {
964
- bgcolor: "#ffebee",
965
- color: "#d32f2f"
966
- }
967
- };
968
- return themes[variant];
969
- };
970
- var SectionBox = memo3(
971
- ({
972
- title,
973
- children,
974
- spacing = 0,
975
- containerSx,
976
- titleSx,
977
- variant = "default",
978
- icon,
979
- actions
980
- }) => {
981
- const themeColors = useMemo2(() => getSectionTheme(variant), [variant]);
982
- const headerSx = useMemo2(
983
- () => ({
984
- px: 1.5,
985
- py: 0.1,
986
- width: "fit-content",
987
- ...themeColors,
988
- ...titleSx
989
- }),
990
- [themeColors, titleSx]
991
- );
992
- const contentSx = useMemo2(
993
- () => ({
994
- padding: "16px",
995
- ...containerSx
996
- }),
997
- [containerSx]
998
- );
999
- return /* @__PURE__ */ jsxs4(Fragment4, { children: [
1000
- /* @__PURE__ */ jsxs4(Box4, { sx: { display: "flex", flexDirection: "column", width: "100%" }, children: [
1001
- /* @__PURE__ */ jsxs4(
1002
- Stack,
1003
- {
1004
- direction: "row",
1005
- justifyContent: "space-between",
1006
- alignItems: "center",
1007
- sx: headerSx,
1008
- children: [
1009
- /* @__PURE__ */ jsxs4(Stack, { direction: "row", alignItems: "center", spacing: 1, children: [
1010
- icon,
1011
- /* @__PURE__ */ jsx12(Typography5, { sx: { fontSize: "15px", fontWeight: 400 }, children: title })
1012
- ] }),
1013
- actions
1014
- ]
1015
- }
1016
- ),
1017
- /* @__PURE__ */ jsx12(Divider2, {})
1018
- ] }),
1019
- /* @__PURE__ */ jsx12(Grid3, { container: true, spacing, sx: contentSx, children })
1020
- ] });
1021
- }
1022
- );
1023
-
1024
- // src/core/components/SimpleTabs/SimpleTabs.tsx
1025
- import { TabContext } from "@mui/lab";
1026
- import { Box as Box5, Tab, Tabs } from "@mui/material";
1027
- import { useState } from "react";
1028
- import { jsx as jsx13, jsxs as jsxs5 } from "react/jsx-runtime";
1029
- var SimpleTabs = ({
1030
- tabs,
1031
- defaultValue = 1,
1032
- onTabChange,
1033
- children,
1034
- tabSx,
1035
- tabsSx
1036
- }) => {
1037
- const [value, setValue] = useState(defaultValue);
1038
- const handleChange = (event, newValue) => {
1039
- setValue(newValue);
1040
- if (onTabChange) onTabChange(newValue);
1041
- };
1042
- return /* @__PURE__ */ jsxs5(TabContext, { value, children: [
1043
- /* @__PURE__ */ jsx13(Box5, { sx: { borderBottom: 1, borderColor: "divider", width: "100%" }, children: /* @__PURE__ */ jsx13(
1044
- Tabs,
1045
- {
1046
- value,
1047
- onChange: handleChange,
1048
- sx: { px: 2, py: 0, ...tabsSx },
1049
- children: tabs.map((tab) => /* @__PURE__ */ jsx13(
1050
- Tab,
1051
- {
1052
- label: tab.label,
1053
- value: tab.value,
1054
- disabled: tab.permission === false,
1055
- sx: { fontSize: "1rem", ...tabSx }
1056
- },
1057
- tab.value
1058
- ))
1059
- }
1060
- ) }),
1061
- children
1062
- ] });
1063
- };
1064
-
1065
- // src/core/components/SubmitButton/SubmitButton.tsx
1066
- import { LoadingButton as LoadingButton2 } from "@mui/lab";
1067
- import { jsx as jsx14 } from "react/jsx-runtime";
1068
- var SubmitButton = ({
1069
- loading = false,
1070
- ...rest
1071
- }) => /* @__PURE__ */ jsx14(
1072
- LoadingButton2,
1073
- {
1074
- loading,
1075
- variant: "contained",
1076
- color: "primary",
1077
- type: "submit",
1078
- ...rest,
1079
- sx: { fontWeight: 400 },
1080
- children: "Submit"
1081
- }
1082
- );
1083
-
1084
- // src/core/components/WithRef/WithRef.tsx
1085
- import { forwardRef } from "react";
1086
- function withDataModal(component) {
1087
- return forwardRef(
1088
- (props, ref) => component({ ...props, ref })
1089
- );
1090
- }
1091
-
1092
- // src/core/config.ts
1093
- var Config = {
1094
- defaultPageSize: 20,
1095
- apiBaseUrl: "http://localhost:5143"
1096
- // apiBaseUrl: 'http://192.168.1.246:5143',
1097
- };
1098
- var dateTimePatterns = {
1099
- dateTime: "DD MMM YYYY h:mm A",
1100
- // 17 Apr 2022 12:00 am
1101
- date: "DD MMM YYYY",
1102
- // 17 Apr 2022
1103
- month_year_short_format: "MMM YYYY",
1104
- month_year_full_format: "MMMM YYYY",
1105
- year: "YYYY",
1106
- time: "h:mm a",
1107
- // 12:00 am
1108
- split: {
1109
- dateTime: "DD/MM/YYYY h:mm A",
1110
- // 17/04/2022 12:00 am
1111
- date: "DD/MM/YYYY"
1112
- // 17/04/2022
1113
- },
1114
- paramCase: {
1115
- dateTime: "DD-MM-YYYY h:mm A",
1116
- // 17-04-2022 12:00 am
1117
- date: "DD-MM-YYYY",
1118
- // 17-04-2022
1119
- dateReverse: "YYYY-MM-DD",
1120
- // 2022-04-17 for compare date
1121
- MonthYear: "MMM-YYYY"
1122
- }
1123
- };
1124
-
1125
- // src/core/hooks/useApiClient.ts
1126
- import { useMemo as useMemo3 } from "react";
1127
- function useApiClient(config = {}) {
1128
- return useMemo3(() => {
1129
- return createApiClient(config);
1130
- }, [
1131
- config.baseURL,
1132
- config.timeout,
1133
- config.correlationIdPrefix,
1134
- config.includeCorrelationId,
1135
- config.authToken,
1136
- config.requestInterceptors,
1137
- config.responseInterceptors,
1138
- config.errorInterceptors
1139
- ]);
1140
- }
1141
-
1142
- // src/core/hooks/useFormErrorHandler.ts
1143
- import { useCallback as useCallback2 } from "react";
1144
- import { toast } from "sonner";
1145
- var useFormErrorHandler = ({
1146
- setError,
1147
- successMessage = {
1148
- create: "Created successfully",
1149
- update: "Updated successfully"
1150
- },
1151
- errorMessage = {
1152
- noChanges: "No changes were made",
1153
- general: "Failed to save. Please try again."
1154
- }
1155
- }) => {
1156
- const getFieldError = useCallback2(
1157
- (fields, fieldName) => {
1158
- if (!fields || !fields[fieldName]) return void 0;
1159
- const fieldError = fields[fieldName];
1160
- if (typeof fieldError === "string") {
1161
- return fieldError;
1162
- }
1163
- if (Array.isArray(fieldError)) {
1164
- return fieldError.join(", ");
1165
- }
1166
- if (typeof fieldError === "object" && "message" in fieldError) {
1167
- return fieldError.message;
1168
- }
1169
- return void 0;
1170
- },
1171
- []
1172
- );
1173
- const handleSuccess = useCallback2(
1174
- (isEditing, rowsAffected) => {
1175
- if (rowsAffected !== void 0 && rowsAffected > 0) {
1176
- toast.success(isEditing ? successMessage.update : successMessage.create);
1177
- return true;
1178
- } else if (rowsAffected === 0) {
1179
- toast.error(errorMessage.noChanges);
1180
- return false;
1181
- }
1182
- toast.success(isEditing ? successMessage.update : successMessage.create);
1183
- return true;
1184
- },
1185
- [successMessage, errorMessage]
1186
- );
1187
- const handleError = useCallback2(
1188
- (processedError) => {
1189
- if (processedError.type === "validation_error" && processedError.errors && setError) {
1190
- Object.keys(processedError.errors).forEach((fieldName) => {
1191
- const fieldError = getFieldError(processedError.errors, fieldName);
1192
- if (fieldError) {
1193
- setError(fieldName, {
1194
- type: "server",
1195
- message: fieldError
1196
- });
1197
- }
1198
- });
1199
- toast.error(processedError.title || "Please check the form for validation errors");
1200
- } else {
1201
- toast.error(processedError.title || errorMessage.general);
1202
- }
1203
- },
1204
- [errorMessage.general, getFieldError, setError]
1205
- );
1206
- return {
1207
- handleSuccess,
1208
- handleError
1209
- };
1210
- };
1211
- var useDeleteHandler = ({
1212
- successMessage = "Deleted successfully",
1213
- errorMessage = "Failed to delete. Please try again."
1214
- } = {}) => {
1215
- return useFormErrorHandler({
1216
- successMessage: {
1217
- create: successMessage,
1218
- // Not used for delete, but required for type
1219
- update: successMessage
1220
- },
1221
- errorMessage: {
1222
- noChanges: "No changes were made",
1223
- // Not typically used for delete
1224
- general: errorMessage
1225
- }
1226
- // setError is omitted (undefined) for delete operations
1227
- });
1228
- };
1229
-
1230
- // src/core/utils/CacheUtility/index.ts
1231
- import { useQueryClient } from "@tanstack/react-query";
1232
- import { useMemo as useMemo4 } from "react";
1233
- var CacheUtility = class {
1234
- constructor(queryClient) {
1235
- this.queryClient = queryClient;
1236
- }
1237
- /**
1238
- * Get cached data using only the queryKey from query factory
1239
- */
1240
- getCachedData(queryKey) {
1241
- return this.queryClient.getQueryData(queryKey);
1242
- }
1243
- /**
1244
- * Get cached data with transformation using select function
1245
- */
1246
- getCachedDataWithSelect(queryKey, select) {
1247
- const cachedData = this.queryClient.getQueryData(queryKey);
1248
- if (cachedData === void 0) {
1249
- return void 0;
1250
- }
1251
- return select(cachedData);
1252
- }
1253
- };
1254
- function useCacheUtility() {
1255
- const queryClient = useQueryClient();
1256
- return useMemo4(() => new CacheUtility(queryClient), [queryClient]);
1257
- }
1258
-
1259
- // src/core/utils/watch/core.ts
1260
- import { useWatch } from "react-hook-form";
1261
- var useWatchForm = (control) => useWatch({ control });
1262
- var useWatchField = (control, name) => useWatch({ control, name });
1263
- var useWatchFields = (control, names) => useWatch({ control, name: names });
1264
-
1265
- // src/core/utils/watch/utilities.ts
1266
- import { useEffect, useMemo as useMemo5, useState as useState2 } from "react";
1267
- import { useWatch as useWatch2 } from "react-hook-form";
1268
- var useWatchTransform = (control, name, transform) => {
1269
- const value = useWatch2({ control, name });
1270
- return useMemo5(() => transform(value), [value, transform]);
1271
- };
1272
- var useWatchDefault = (control, name, defaultValue) => {
1273
- const value = useWatch2({ control, name });
1274
- return value ?? defaultValue;
1275
- };
1276
- var useWatchBoolean = (control, name, defaultValue = false) => {
1277
- const value = useWatch2({ control, name });
1278
- return Boolean(value ?? defaultValue);
1279
- };
1280
- var useWatchBatch = (control, fields) => {
1281
- const values = useWatch2({ control, name: fields });
1282
- return useMemo5(() => {
1283
- const result = {};
1284
- fields.forEach((field, index) => {
1285
- result[field] = values[index];
1286
- });
1287
- return result;
1288
- }, [values, fields]);
1289
- };
1290
- var useWatchConditional = (control, name, shouldWatch, fallback) => {
1291
- const activeValue = useWatch2({
1292
- control,
1293
- name,
1294
- disabled: !shouldWatch
1295
- });
1296
- return shouldWatch ? activeValue : fallback;
1297
- };
1298
- var useWatchDebounced = (control, name, delay = 300) => {
1299
- const value = useWatch2({ control, name });
1300
- const [debouncedValue, setDebouncedValue] = useState2(value);
1301
- useEffect(() => {
1302
- const timer = setTimeout(() => {
1303
- setDebouncedValue(value);
1304
- }, delay);
1305
- return () => clearTimeout(timer);
1306
- }, [value, delay]);
1307
- return debouncedValue;
1308
- };
1309
- var useWatchSelector = (control, name, selector, deps = []) => {
1310
- const value = useWatch2({ control, name });
1311
- return useMemo5(
1312
- () => selector(value),
1313
- [value, selector, ...deps]
1314
- // eslint-disable-line react-hooks/exhaustive-deps
1315
- );
1316
- };
1317
-
1318
- // src/core/utils/watch/index.ts
1319
- var typedWatch = {
1320
- // === CORE FUNCTIONS ===
1321
- /** Watch entire form */
1322
- form: useWatchForm,
1323
- /** Watch single field */
1324
- field: useWatchField,
1325
- /** Watch multiple fields */
1326
- fields: useWatchFields,
1327
- // === UTILITY FUNCTIONS ===
1328
- /** Watch with transformation */
1329
- transform: useWatchTransform,
1330
- /** Watch with default value */
1331
- withDefault: useWatchDefault,
1332
- /** Watch as boolean */
1333
- boolean: useWatchBoolean,
1334
- /** Watch multiple with custom keys */
1335
- batch: useWatchBatch,
1336
- /** Watch conditionally */
1337
- conditional: useWatchConditional,
1338
- /** Watch with debouncing */
1339
- debounced: useWatchDebounced,
1340
- /** Watch with selector */
1341
- selector: useWatchSelector
1342
- };
1343
-
1344
- // src/core/utils/calculateFilterCount.ts
1345
- var calculateFilterCount = (model) => Object.values(model).filter(
1346
- (v) => v !== null && v !== void 0 && String(v).trim() !== ""
1347
- ).length;
1348
-
1349
- // src/core/utils/format-time.ts
1350
- import dayjs from "dayjs";
1351
- import duration from "dayjs/plugin/duration";
1352
- import relativeTime from "dayjs/plugin/relativeTime";
1353
- dayjs.extend(duration);
1354
- dayjs.extend(relativeTime);
1355
- var formatPatterns = {
1356
- dateTime: "DD MMM YYYY h:mm A",
1357
- // 17 Apr 2022 12:00 am
1358
- date: "DD MMM YYYY",
1359
- // 17 Apr 2022
1360
- month_year_short_format: "MMM YYYY",
1361
- month_year_full_format: "MMMM YYYY",
1362
- year: "YYYY",
1363
- time: "h:mm a",
1364
- // 12:00 am
1365
- split: {
1366
- dateTime: "DD/MM/YYYY h:mm A",
1367
- // 17/04/2022 12:00 am
1368
- date: "DD/MM/YYYY"
1369
- // 17/04/2022
1370
- },
1371
- paramCase: {
1372
- dateTime: "DD-MM-YYYY h:mm A",
1373
- // 17-04-2022 12:00 am
1374
- date: "DD-MM-YYYY",
1375
- // 17-04-2022
1376
- dateReverse: "YYYY-MM-DD",
1377
- // 2022-04-17 for compare date
1378
- MonthYear: "MMM-YYYY"
1379
- }
1380
- };
1381
- var isValidDate = (date) => date !== null && date !== void 0 && dayjs(date).isValid();
1382
- function today(template) {
1383
- return dayjs(/* @__PURE__ */ new Date()).startOf("day").format(template);
1384
- }
1385
- function fDateTime(date, template) {
1386
- if (!isValidDate(date)) {
1387
- return "Invalid date";
1388
- }
1389
- return dayjs(date).format(template ?? formatPatterns.dateTime);
1390
- }
1391
- function fDate(date, template) {
1392
- if (!isValidDate(date)) {
1393
- return "Invalid date";
1394
- }
1395
- return dayjs(date).format(template ?? formatPatterns.date);
1396
- }
1397
- function fTime(date, template) {
1398
- if (!isValidDate(date)) {
1399
- return "Invalid date";
1400
- }
1401
- return dayjs(date).format(template ?? formatPatterns.time);
1402
- }
1403
- function fTimestamp(date) {
1404
- if (!isValidDate(date)) {
1405
- return "Invalid date";
1406
- }
1407
- return dayjs(date).valueOf();
1408
- }
1409
- function fToNow(date) {
1410
- if (!isValidDate(date)) {
1411
- return "Invalid date";
1412
- }
1413
- return dayjs(date).toNow(true);
1414
- }
1415
- function fIsBetween(inputDate, startDate, endDate) {
1416
- if (!isValidDate(inputDate) || !isValidDate(startDate) || !isValidDate(endDate)) {
1417
- return false;
1418
- }
1419
- const formattedInputDate = fTimestamp(inputDate);
1420
- const formattedStartDate = fTimestamp(startDate);
1421
- const formattedEndDate = fTimestamp(endDate);
1422
- if (formattedInputDate === "Invalid date" || formattedStartDate === "Invalid date" || formattedEndDate === "Invalid date") {
1423
- return false;
1424
- }
1425
- return formattedInputDate >= formattedStartDate && formattedInputDate <= formattedEndDate;
1426
- }
1427
- function fIsAfter(startDate, endDate) {
1428
- if (!isValidDate(startDate) || !isValidDate(endDate)) {
1429
- return false;
1430
- }
1431
- return dayjs(startDate).isAfter(endDate);
1432
- }
1433
- function fIsSame(startDate, endDate, unitToCompare) {
1434
- if (!isValidDate(startDate) || !isValidDate(endDate)) {
1435
- return false;
1436
- }
1437
- return dayjs(startDate).isSame(endDate, unitToCompare ?? "year");
1438
- }
1439
- function fDateRangeShortLabel(startDate, endDate, initial) {
1440
- if (!isValidDate(startDate) || !isValidDate(endDate) || fIsAfter(startDate, endDate)) {
1441
- return "Invalid date";
1442
- }
1443
- let label = `${fDate(startDate)} - ${fDate(endDate)}`;
1444
- if (initial) {
1445
- return label;
1446
- }
1447
- const isSameYear = fIsSame(startDate, endDate, "year");
1448
- const isSameMonth = fIsSame(startDate, endDate, "month");
1449
- const isSameDay = fIsSame(startDate, endDate, "day");
1450
- if (isSameYear && !isSameMonth) {
1451
- label = `${fDate(startDate, "DD MMM")} - ${fDate(endDate)}`;
1452
- } else if (isSameYear && isSameMonth && !isSameDay) {
1453
- label = `${fDate(startDate, "DD")} - ${fDate(endDate)}`;
1454
- } else if (isSameYear && isSameMonth && isSameDay) {
1455
- label = `${fDate(endDate)}`;
1456
- }
1457
- return label;
1458
- }
1459
- function fAdd({
1460
- years = 0,
1461
- months = 0,
1462
- days = 0,
1463
- hours = 0,
1464
- minutes = 0,
1465
- seconds = 0,
1466
- milliseconds = 0
1467
- }) {
1468
- const result = dayjs().add(
1469
- dayjs.duration({
1470
- years,
1471
- months,
1472
- days,
1473
- hours,
1474
- minutes,
1475
- seconds,
1476
- milliseconds
1477
- })
1478
- ).format();
1479
- return result;
1480
- }
1481
- function fSub({
1482
- years = 0,
1483
- months = 0,
1484
- days = 0,
1485
- hours = 0,
1486
- minutes = 0,
1487
- seconds = 0,
1488
- milliseconds = 0
1489
- }) {
1490
- const result = dayjs().subtract(
1491
- dayjs.duration({
1492
- years,
1493
- months,
1494
- days,
1495
- hours,
1496
- minutes,
1497
- seconds,
1498
- milliseconds
1499
- })
1500
- ).format();
1501
- return result;
1502
- }
1503
-
1504
- // src/core/utils/getEmptyObject.ts
1505
- function getEmptyObject(data, defaultValues = {}) {
1506
- const obj = {};
1507
- for (const key of Object.keys(data)) {
1508
- const value = data[key];
1509
- const type = typeof value;
1510
- if (type === "number") {
1511
- obj[key] = 0;
1512
- } else if (type === "string" || type === "boolean") {
1513
- obj[key] = null;
1514
- } else if (value instanceof Date) {
1515
- obj[key] = null;
1516
- } else {
1517
- obj[key] = null;
1518
- }
1519
- }
1520
- return { ...obj, ...defaultValues };
1521
- }
1522
-
1523
- // src/core/utils/useStableRowCount.ts
1524
- import { useRef, useMemo as useMemo6 } from "react";
1525
- function useStableRowCount(currentTotal) {
1526
- const rowCountRef = useRef(currentTotal || 0);
1527
- const stableRowCount = useMemo6(() => {
1528
- if (currentTotal !== void 0) {
1529
- rowCountRef.current = currentTotal;
1530
- }
1531
- return rowCountRef.current;
1532
- }, [currentTotal]);
1533
- return stableRowCount;
1534
- }
1535
-
1536
- export {
1537
- CorrelationIdGenerator,
1538
- RequestManager,
1539
- ApiClient,
1540
- createApiClient,
1541
- getGlobalApiClient,
1542
- setGlobalApiClient,
1543
- resetGlobalApiClient,
1544
- CancelToken,
1545
- useValidationErrors,
1546
- AuthorizedView,
1547
- CancelButton,
1548
- ClearButton,
1549
- SimpleContainer,
1550
- FilterButton,
1551
- FilterChip,
1552
- ProgramsFilterDisplay,
1553
- FilterWrapper,
1554
- Footer,
1555
- LabelText,
1556
- RenderIf,
1557
- SectionBox,
1558
- SimpleTabs,
1559
- SubmitButton,
1560
- withDataModal,
1561
- Config,
1562
- dateTimePatterns,
1563
- useApiClient,
1564
- useFormErrorHandler,
1565
- useDeleteHandler,
1566
- CacheUtility,
1567
- useCacheUtility,
1568
- useWatchForm,
1569
- useWatchField,
1570
- useWatchFields,
1571
- useWatchTransform,
1572
- useWatchDefault,
1573
- useWatchBoolean,
1574
- useWatchBatch,
1575
- useWatchConditional,
1576
- useWatchDebounced,
1577
- useWatchSelector,
1578
- typedWatch,
1579
- calculateFilterCount,
1580
- formatPatterns,
1581
- today,
1582
- fDateTime,
1583
- fDate,
1584
- fTime,
1585
- fTimestamp,
1586
- fToNow,
1587
- fIsBetween,
1588
- fIsAfter,
1589
- fIsSame,
1590
- fDateRangeShortLabel,
1591
- fAdd,
1592
- fSub,
1593
- getEmptyObject,
1594
- useStableRowCount
1595
- };
1596
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vc3JjL2NvcmUvYXBpL0NvcnJlbGF0aW9uSWRHZW5lcmF0b3IudHMiLCAiLi4vc3JjL2NvcmUvYXBpL1JlcXVlc3RNYW5hZ2VyLnRzIiwgIi4uL3NyYy9jb3JlL2FwaS9BcGlDbGllbnQudHMiLCAiLi4vc3JjL2NvcmUvYXBpL2NyZWF0ZUFwaUNsaWVudC50cyIsICIuLi9zcmMvY29yZS9hcGkvdHlwZXMvQ2FuY2VsVG9rZW4udHMiLCAiLi4vc3JjL2NvcmUvYXBpL3VzZVZhbGlkYXRpb25FcnJvcnMudHMiLCAiLi4vc3JjL2NvcmUvY29tcG9uZW50cy9BdXRob3JpemVkVmlldy9BdXRob3JpemVkVmlldy50c3giLCAiLi4vc3JjL2NvcmUvY29tcG9uZW50cy9DYW5jZWxCdXR0b24vQ2FuY2VsQnV0dG9uLnRzeCIsICIuLi9zcmMvY29yZS9jb21wb25lbnRzL0NsZWFyQnV0dG9uL0NsZWFyQnV0dG9uLnRzeCIsICIuLi9zcmMvY29yZS9jb21wb25lbnRzL0NvbnRhaW5lcnMvU2ltcGxlQ29udGFpbmVyLnRzeCIsICIuLi9zcmMvY29yZS9jb21wb25lbnRzL0ZpbHRlckJ1dHRvbi9GaWx0ZXJCdXR0b24udHN4IiwgIi4uL3NyYy9jb3JlL2NvbXBvbmVudHMvRmlsdGVyRGlzcGxheS9GaWx0ZXJDaGlwLnRzeCIsICIuLi9zcmMvY29yZS9jb21wb25lbnRzL0ZpbHRlckRpc3BsYXkvRmlsdGVyRGlzcGxheS50c3giLCAiLi4vc3JjL2NvcmUvY29tcG9uZW50cy9GaWx0ZXJXcmFwcGVyL0ZpbHRlcldyYXBwZXIudHN4IiwgIi4uL3NyYy9jb3JlL2NvbXBvbmVudHMvRm9vdGVyL0Zvb3Rlci50c3giLCAiLi4vc3JjL2NvcmUvY29tcG9uZW50cy9MYWJlbFRleHQvTGFiZWxUZXh0LnRzeCIsICIuLi9zcmMvY29yZS9jb21wb25lbnRzL1JlbmRlcklmL1JlbmRlcklmLnRzeCIsICIuLi9zcmMvY29yZS9jb21wb25lbnRzL1NlY3Rpb25Cb3gvU2VjdGlvbkJveC50c3giLCAiLi4vc3JjL2NvcmUvY29tcG9uZW50cy9TaW1wbGVUYWJzL1NpbXBsZVRhYnMudHN4IiwgIi4uL3NyYy9jb3JlL2NvbXBvbmVudHMvU3VibWl0QnV0dG9uL1N1Ym1pdEJ1dHRvbi50c3giLCAiLi4vc3JjL2NvcmUvY29tcG9uZW50cy9XaXRoUmVmL1dpdGhSZWYudHN4IiwgIi4uL3NyYy9jb3JlL2NvbmZpZy50cyIsICIuLi9zcmMvY29yZS9ob29rcy91c2VBcGlDbGllbnQudHMiLCAiLi4vc3JjL2NvcmUvaG9va3MvdXNlRm9ybUVycm9ySGFuZGxlci50cyIsICIuLi9zcmMvY29yZS91dGlscy9DYWNoZVV0aWxpdHkvaW5kZXgudHMiLCAiLi4vc3JjL2NvcmUvdXRpbHMvd2F0Y2gvY29yZS50cyIsICIuLi9zcmMvY29yZS91dGlscy93YXRjaC91dGlsaXRpZXMudHMiLCAiLi4vc3JjL2NvcmUvdXRpbHMvd2F0Y2gvaW5kZXgudHMiLCAiLi4vc3JjL2NvcmUvdXRpbHMvY2FsY3VsYXRlRmlsdGVyQ291bnQudHMiLCAiLi4vc3JjL2NvcmUvdXRpbHMvZm9ybWF0LXRpbWUudHMiLCAiLi4vc3JjL2NvcmUvdXRpbHMvZ2V0RW1wdHlPYmplY3QudHMiLCAiLi4vc3JjL2NvcmUvdXRpbHMvdXNlU3RhYmxlUm93Q291bnQudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbIi8vIENvcnJlbGF0aW9uIElEIGdlbmVyYXRvclxyXG5leHBvcnQgY2xhc3MgQ29ycmVsYXRpb25JZEdlbmVyYXRvciB7XHJcbiAgcHJpdmF0ZSBzdGF0aWMgZ2VuZXJhdGVVVUlEKCk6IHN0cmluZyB7XHJcbiAgICBpZiAodHlwZW9mIGNyeXB0byAhPT0gJ3VuZGVmaW5lZCcgJiYgY3J5cHRvLnJhbmRvbVVVSUQpIHtcclxuICAgICAgcmV0dXJuIGNyeXB0by5yYW5kb21VVUlEKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gRmFsbGJhY2sgVVVJRCB2NCBnZW5lcmF0b3JcclxuICAgIHJldHVybiAneHh4eHh4eHgteHh4eC00eHh4LXl4eHgteHh4eHh4eHh4eHh4Jy5yZXBsYWNlKC9beHldL2csIGMgPT4ge1xyXG4gICAgICBjb25zdCByID0gKE1hdGgucmFuZG9tKCkgKiAxNikgfCAwO1xyXG4gICAgICBjb25zdCB2ID0gYyA9PT0gJ3gnID8gciA6IChyICYgMHgzKSB8IDB4ODtcclxuXHJcbiAgICAgIHJldHVybiB2LnRvU3RyaW5nKDE2KTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgc3RhdGljIGdlbmVyYXRlKHByZWZpeD86IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICBjb25zdCB1dWlkID0gdGhpcy5nZW5lcmF0ZVVVSUQoKTtcclxuXHJcbiAgICByZXR1cm4gcHJlZml4ID8gYCR7cHJlZml4fS0ke3V1aWR9YCA6IHV1aWQ7XHJcbiAgfVxyXG59XHJcbiIsICIvLyBSZXF1ZXN0IG1hbmFnZXIgZm9yIHRyYWNraW5nIGFjdGl2ZSByZXF1ZXN0c1xyXG5leHBvcnQgY2xhc3MgUmVxdWVzdE1hbmFnZXIge1xyXG4gIHByaXZhdGUgYWN0aXZlUmVxdWVzdHM6IE1hcDxzdHJpbmcsIEFib3J0Q29udHJvbGxlcj4gPSBuZXcgTWFwKCk7XHJcbiAgcHJpdmF0ZSBjb3JyZWxhdGlvbk1hcDogTWFwPHN0cmluZywgc3RyaW5nPiA9IG5ldyBNYXAoKTtcclxuXHJcbiAgYWRkKGtleTogc3RyaW5nLCBjb250cm9sbGVyOiBBYm9ydENvbnRyb2xsZXIsIGNvcnJlbGF0aW9uSWQ6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgLy8gQ2FuY2VsIGV4aXN0aW5nIHJlcXVlc3Qgd2l0aCBzYW1lIGtleSBpZiBleGlzdHNcclxuICAgIHRoaXMuY2FuY2VsKGtleSk7XHJcbiAgICB0aGlzLmFjdGl2ZVJlcXVlc3RzLnNldChrZXksIGNvbnRyb2xsZXIpO1xyXG4gICAgdGhpcy5jb3JyZWxhdGlvbk1hcC5zZXQoa2V5LCBjb3JyZWxhdGlvbklkKTtcclxuICB9XHJcblxyXG4gIHJlbW92ZShrZXk6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgdGhpcy5hY3RpdmVSZXF1ZXN0cy5kZWxldGUoa2V5KTtcclxuICAgIHRoaXMuY29ycmVsYXRpb25NYXAuZGVsZXRlKGtleSk7XHJcbiAgfVxyXG5cclxuICBjYW5jZWwoa2V5OiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSB0aGlzLmFjdGl2ZVJlcXVlc3RzLmdldChrZXkpO1xyXG5cclxuICAgIGlmIChjb250cm9sbGVyKSB7XHJcbiAgICAgIGNvbnRyb2xsZXIuYWJvcnQoKTtcclxuICAgICAgdGhpcy5hY3RpdmVSZXF1ZXN0cy5kZWxldGUoa2V5KTtcclxuICAgICAgdGhpcy5jb3JyZWxhdGlvbk1hcC5kZWxldGUoa2V5KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGNhbmNlbEFsbCgpOiB2b2lkIHtcclxuICAgIHRoaXMuYWN0aXZlUmVxdWVzdHMuZm9yRWFjaChjb250cm9sbGVyID0+IGNvbnRyb2xsZXIuYWJvcnQoKSk7XHJcbiAgICB0aGlzLmFjdGl2ZVJlcXVlc3RzLmNsZWFyKCk7XHJcbiAgICB0aGlzLmNvcnJlbGF0aW9uTWFwLmNsZWFyKCk7XHJcbiAgfVxyXG5cclxuICBoYXMoa2V5OiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLmFjdGl2ZVJlcXVlc3RzLmhhcyhrZXkpO1xyXG4gIH1cclxuXHJcbiAgZ2V0Q29ycmVsYXRpb25JZChrZXk6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XHJcbiAgICByZXR1cm4gdGhpcy5jb3JyZWxhdGlvbk1hcC5nZXQoa2V5KTtcclxuICB9XHJcbn1cclxuIiwgImltcG9ydCB0eXBlIHsgR3JpZFNvcnRNb2RlbCB9IGZyb20gJ0BtdWkveC1kYXRhLWdyaWQnO1xyXG5cclxuaW1wb3J0IHsgQ29ycmVsYXRpb25JZEdlbmVyYXRvciB9IGZyb20gJy4vQ29ycmVsYXRpb25JZEdlbmVyYXRvcic7XHJcbmltcG9ydCB7IFJlcXVlc3RNYW5hZ2VyIH0gZnJvbSAnLi9SZXF1ZXN0TWFuYWdlcic7XHJcbmltcG9ydCB0eXBlIHsgQXBpRXJyb3IgfSBmcm9tICcuL3R5cGVzL0FwaUVycm9yJztcclxuaW1wb3J0IHR5cGUgeyBFcnJvckludGVyY2VwdG9yIH0gZnJvbSAnLi90eXBlcy9FcnJvckludGVyY2VwdG9yJztcclxuaW1wb3J0IHR5cGUgeyBSZXF1ZXN0Q29uZmlnIH0gZnJvbSAnLi90eXBlcy9SZXF1ZXN0Q29uZmlnJztcclxuaW1wb3J0IHR5cGUgeyBSZXF1ZXN0SW50ZXJjZXB0b3IgfSBmcm9tICcuL3R5cGVzL1JlcXVlc3RJbnRlcmNlcHRvcic7XHJcbmltcG9ydCB0eXBlIHsgUmVzcG9uc2VJbnRlcmNlcHRvciB9IGZyb20gJy4vdHlwZXMvUmVzcG9uc2VJbnRlcmNlcHRvcic7XHJcblxyXG5pbXBvcnQgdHlwZSB7IEFwaVJlc3BvbnNlIH0gZnJvbSAnQC90eXBlcyc7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFBvc3RNb2RlbDxURmlsdGVyTW9kZWw+IHtcclxuICBmaWx0ZXJNb2RlbD86IFRGaWx0ZXJNb2RlbDtcclxuICBwYWdlT2Zmc2V0OiBudW1iZXI7XHJcbiAgcGFnZVNpemU6IG51bWJlcjtcclxuICBzb3J0RmllbGQ6IHN0cmluZyB8IG51bGw7XHJcbiAgc29ydE9yZGVyOiAnYXNjJyB8ICdkZXNjJyB8IG51bGwgfCB1bmRlZmluZWQ7XHJcbiAgc29ydE1vZGVsPzogR3JpZFNvcnRNb2RlbDtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBMaXN0UmVzcG9uc2UyPFRMaXN0TW9kZWw+IHtcclxuICBEYXRhOiBUTGlzdE1vZGVsW107XHJcbiAgVG90YWw6IG51bWJlcjtcclxufVxyXG5cclxuLy8gYXBpQ2xpZW50LnRzXHJcbmV4cG9ydCBjbGFzcyBBcGlDbGllbnQge1xyXG4gIHByaXZhdGUgYmFzZVVSTDogc3RyaW5nO1xyXG4gIHByaXZhdGUgZGVmYXVsdFRpbWVvdXQ6IG51bWJlcjtcclxuICBwcml2YXRlIHJlcXVlc3RJbnRlcmNlcHRvcnM6IFJlcXVlc3RJbnRlcmNlcHRvcltdID0gW107XHJcbiAgcHJpdmF0ZSByZXNwb25zZUludGVyY2VwdG9yczogUmVzcG9uc2VJbnRlcmNlcHRvcltdID0gW107XHJcbiAgcHJpdmF0ZSBlcnJvckludGVyY2VwdG9yczogRXJyb3JJbnRlcmNlcHRvcltdID0gW107XHJcbiAgcHJpdmF0ZSBhdXRoVG9rZW46IHN0cmluZyB8IG51bGwgPSBudWxsO1xyXG4gIHByaXZhdGUgcmVmcmVzaFRva2VuUHJvbWlzZTogUHJvbWlzZTxzdHJpbmc+IHwgbnVsbCA9IG51bGw7XHJcbiAgcHJpdmF0ZSByZXF1ZXN0TWFuYWdlcjogUmVxdWVzdE1hbmFnZXIgPSBuZXcgUmVxdWVzdE1hbmFnZXIoKTtcclxuICBwcml2YXRlIGNvcnJlbGF0aW9uSWRQcmVmaXg6IHN0cmluZyA9ICdhcGknO1xyXG4gIHByaXZhdGUgaW5jbHVkZUNvcnJlbGF0aW9uSWQ6IGJvb2xlYW4gPSB0cnVlO1xyXG5cclxuICBjb25zdHJ1Y3RvcihiYXNlVVJMOiBzdHJpbmcgPSAnJywgZGVmYXVsdFRpbWVvdXQ6IG51bWJlciA9IDMwMDAwKSB7XHJcbiAgICB0aGlzLmJhc2VVUkwgPSBiYXNlVVJMO1xyXG4gICAgdGhpcy5kZWZhdWx0VGltZW91dCA9IGRlZmF1bHRUaW1lb3V0O1xyXG4gIH1cclxuXHJcbiAgLy8gQ29uZmlndXJhdGlvbiBtZXRob2RzXHJcbiAgc2V0Q29ycmVsYXRpb25JZFByZWZpeChwcmVmaXg6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgdGhpcy5jb3JyZWxhdGlvbklkUHJlZml4ID0gcHJlZml4O1xyXG4gIH1cclxuXHJcbiAgc2V0SW5jbHVkZUNvcnJlbGF0aW9uSWQoaW5jbHVkZTogYm9vbGVhbik6IHZvaWQge1xyXG4gICAgdGhpcy5pbmNsdWRlQ29ycmVsYXRpb25JZCA9IGluY2x1ZGU7XHJcbiAgfVxyXG5cclxuICAvLyBJbnRlcmNlcHRvciBtYW5hZ2VtZW50XHJcbiAgYWRkUmVxdWVzdEludGVyY2VwdG9yKGludGVyY2VwdG9yOiBSZXF1ZXN0SW50ZXJjZXB0b3IpOiAoKSA9PiB2b2lkIHtcclxuICAgIHRoaXMucmVxdWVzdEludGVyY2VwdG9ycy5wdXNoKGludGVyY2VwdG9yKTtcclxuXHJcbiAgICByZXR1cm4gKCkgPT4ge1xyXG4gICAgICBjb25zdCBpbmRleCA9IHRoaXMucmVxdWVzdEludGVyY2VwdG9ycy5pbmRleE9mKGludGVyY2VwdG9yKTtcclxuXHJcbiAgICAgIGlmIChpbmRleCA+IC0xKSB0aGlzLnJlcXVlc3RJbnRlcmNlcHRvcnMuc3BsaWNlKGluZGV4LCAxKTtcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICBhZGRSZXNwb25zZUludGVyY2VwdG9yKGludGVyY2VwdG9yOiBSZXNwb25zZUludGVyY2VwdG9yKTogKCkgPT4gdm9pZCB7XHJcbiAgICB0aGlzLnJlc3BvbnNlSW50ZXJjZXB0b3JzLnB1c2goaW50ZXJjZXB0b3IpO1xyXG5cclxuICAgIHJldHVybiAoKSA9PiB7XHJcbiAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5yZXNwb25zZUludGVyY2VwdG9ycy5pbmRleE9mKGludGVyY2VwdG9yKTtcclxuXHJcbiAgICAgIGlmIChpbmRleCA+IC0xKSB0aGlzLnJlc3BvbnNlSW50ZXJjZXB0b3JzLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgYWRkRXJyb3JJbnRlcmNlcHRvcihpbnRlcmNlcHRvcjogRXJyb3JJbnRlcmNlcHRvcik6ICgpID0+IHZvaWQge1xyXG4gICAgdGhpcy5lcnJvckludGVyY2VwdG9ycy5wdXNoKGludGVyY2VwdG9yKTtcclxuXHJcbiAgICByZXR1cm4gKCkgPT4ge1xyXG4gICAgICBjb25zdCBpbmRleCA9IHRoaXMuZXJyb3JJbnRlcmNlcHRvcnMuaW5kZXhPZihpbnRlcmNlcHRvcik7XHJcblxyXG4gICAgICBpZiAoaW5kZXggPiAtMSkgdGhpcy5lcnJvckludGVyY2VwdG9ycy5zcGxpY2UoaW5kZXgsIDEpO1xyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIC8vIEF1dGggdG9rZW4gbWFuYWdlbWVudFxyXG4gIHNldEF1dGhUb2tlbih0b2tlbjogc3RyaW5nIHwgbnVsbCk6IHZvaWQge1xyXG4gICAgdGhpcy5hdXRoVG9rZW4gPSB0b2tlbjtcclxuICB9XHJcblxyXG4gIGdldEF1dGhUb2tlbigpOiBzdHJpbmcgfCBudWxsIHtcclxuICAgIHJldHVybiB0aGlzLmF1dGhUb2tlbjtcclxuICB9XHJcblxyXG4gIC8vIFJlcXVlc3QgY2FuY2VsbGF0aW9uXHJcbiAgY2FuY2VsUmVxdWVzdChrZXk6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgdGhpcy5yZXF1ZXN0TWFuYWdlci5jYW5jZWwoa2V5KTtcclxuICB9XHJcblxyXG4gIGNhbmNlbEFsbFJlcXVlc3RzKCk6IHZvaWQge1xyXG4gICAgdGhpcy5yZXF1ZXN0TWFuYWdlci5jYW5jZWxBbGwoKTtcclxuICB9XHJcblxyXG4gIC8vIFVSTCBhbmQgcGFyYW1zIGhhbmRsaW5nXHJcbiAgcHJpdmF0ZSBidWlsZFVSTChlbmRwb2ludDogc3RyaW5nLCBwYXJhbXM/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+KTogc3RyaW5nIHtcclxuICAgIGNvbnN0IHVybCA9IG5ldyBVUkwoZW5kcG9pbnQsIHRoaXMuYmFzZVVSTCk7XHJcblxyXG4gICAgaWYgKHBhcmFtcykge1xyXG4gICAgICBPYmplY3Qua2V5cyhwYXJhbXMpLmZvckVhY2goa2V5ID0+IHtcclxuICAgICAgICBjb25zdCB2YWx1ZSA9IHBhcmFtc1trZXldO1xyXG5cclxuICAgICAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XHJcbiAgICAgICAgICAgIHZhbHVlLmZvckVhY2godiA9PiB1cmwuc2VhcmNoUGFyYW1zLmFwcGVuZChrZXksIFN0cmluZyh2KSkpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdXJsLnNlYXJjaFBhcmFtcy5hcHBlbmQoa2V5LCBTdHJpbmcodmFsdWUpKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB1cmwudG9TdHJpbmcoKTtcclxuICB9XHJcblxyXG4gIC8vIEFwcGx5IHJlcXVlc3QgaW50ZXJjZXB0b3JzXHJcbiAgcHJpdmF0ZSBhc3luYyBhcHBseVJlcXVlc3RJbnRlcmNlcHRvcnMoXHJcbiAgICBjb25maWc6IFJlcXVlc3RDb25maWdcclxuICApOiBQcm9taXNlPFJlcXVlc3RDb25maWc+IHtcclxuICAgIGxldCBtb2RpZmllZENvbmZpZyA9IHsgLi4uY29uZmlnIH07XHJcblxyXG4gICAgZm9yIChjb25zdCBpbnRlcmNlcHRvciBvZiB0aGlzLnJlcXVlc3RJbnRlcmNlcHRvcnMpIHtcclxuICAgICAgbW9kaWZpZWRDb25maWcgPSBhd2FpdCBpbnRlcmNlcHRvcihtb2RpZmllZENvbmZpZyk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIG1vZGlmaWVkQ29uZmlnO1xyXG4gIH1cclxuXHJcbiAgLy8gQXBwbHkgcmVzcG9uc2UgaW50ZXJjZXB0b3JzXHJcbiAgcHJpdmF0ZSBhc3luYyBhcHBseVJlc3BvbnNlSW50ZXJjZXB0b3JzPFQ+KFxyXG4gICAgcmVzcG9uc2U6IEFwaVJlc3BvbnNlPFQ+XHJcbiAgKTogUHJvbWlzZTxBcGlSZXNwb25zZTxUPj4ge1xyXG4gICAgbGV0IG1vZGlmaWVkUmVzcG9uc2UgPSByZXNwb25zZTtcclxuXHJcbiAgICBmb3IgKGNvbnN0IGludGVyY2VwdG9yIG9mIHRoaXMucmVzcG9uc2VJbnRlcmNlcHRvcnMpIHtcclxuICAgICAgbW9kaWZpZWRSZXNwb25zZSA9IGF3YWl0IGludGVyY2VwdG9yKG1vZGlmaWVkUmVzcG9uc2UpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBtb2RpZmllZFJlc3BvbnNlO1xyXG4gIH1cclxuXHJcbiAgLy8gQXBwbHkgZXJyb3IgaW50ZXJjZXB0b3JzXHJcbiAgcHJpdmF0ZSBhc3luYyBhcHBseUVycm9ySW50ZXJjZXB0b3JzKGVycm9yOiBBcGlFcnJvcik6IFByb21pc2U8QXBpRXJyb3I+IHtcclxuICAgIGxldCBtb2RpZmllZEVycm9yID0gZXJyb3I7XHJcblxyXG4gICAgZm9yIChjb25zdCBpbnRlcmNlcHRvciBvZiB0aGlzLmVycm9ySW50ZXJjZXB0b3JzKSB7XHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgbW9kaWZpZWRFcnJvciA9IGF3YWl0IGludGVyY2VwdG9yKG1vZGlmaWVkRXJyb3IpO1xyXG4gICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgbW9kaWZpZWRFcnJvciA9IGUgYXMgQXBpRXJyb3I7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICB0aHJvdyBtb2RpZmllZEVycm9yO1xyXG4gIH1cclxuXHJcbiAgLy8gQ3JlYXRlIGNvbWJpbmVkIGFib3J0IHNpZ25hbFxyXG4gIHByaXZhdGUgY3JlYXRlQ29tYmluZWRTaWduYWwoXHJcbiAgICBzaWduYWxzOiBBcnJheTxBYm9ydFNpZ25hbCB8IHVuZGVmaW5lZD5cclxuICApOiBBYm9ydENvbnRyb2xsZXIge1xyXG4gICAgY29uc3QgY29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcclxuXHJcbiAgICBmb3IgKGNvbnN0IHNpZ25hbCBvZiBzaWduYWxzKSB7XHJcbiAgICAgIGlmIChzaWduYWwpIHtcclxuICAgICAgICBpZiAoc2lnbmFsLmFib3J0ZWQpIHtcclxuICAgICAgICAgIGNvbnRyb2xsZXIuYWJvcnQoc2lnbmFsLnJlYXNvbik7XHJcbiAgICAgICAgICBicmVhaztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHNpZ25hbC5hZGRFdmVudExpc3RlbmVyKFxyXG4gICAgICAgICAgJ2Fib3J0JyxcclxuICAgICAgICAgICgpID0+IHtcclxuICAgICAgICAgICAgY29udHJvbGxlci5hYm9ydChzaWduYWwucmVhc29uKTtcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgICB7IG9uY2U6IHRydWUgfVxyXG4gICAgICAgICk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gY29udHJvbGxlcjtcclxuICB9XHJcblxyXG4gIC8vIFRpbWVvdXQgaGFuZGxpbmcgd2l0aCBBYm9ydFNpZ25hbFxyXG4gIHByaXZhdGUgY3JlYXRlVGltZW91dFNpZ25hbCh0aW1lb3V0OiBudW1iZXIpOiBBYm9ydENvbnRyb2xsZXIge1xyXG4gICAgY29uc3QgY29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcclxuXHJcbiAgICBjb25zdCB0aW1lb3V0SWQgPSBzZXRUaW1lb3V0KCgpID0+IHtcclxuICAgICAgY29udHJvbGxlci5hYm9ydChgUmVxdWVzdCB0aW1lb3V0IGFmdGVyICR7dGltZW91dH1tc2ApO1xyXG4gICAgfSwgdGltZW91dCk7XHJcblxyXG4gICAgLy8gQ2xlYW4gdXAgdGltZW91dCB3aGVuIHNpZ25hbCBpcyBhYm9ydGVkXHJcbiAgICBjb250cm9sbGVyLnNpZ25hbC5hZGRFdmVudExpc3RlbmVyKFxyXG4gICAgICAnYWJvcnQnLFxyXG4gICAgICAoKSA9PiB7XHJcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXRJZCk7XHJcbiAgICAgIH0sXHJcbiAgICAgIHsgb25jZTogdHJ1ZSB9XHJcbiAgICApO1xyXG5cclxuICAgIHJldHVybiBjb250cm9sbGVyO1xyXG4gIH1cclxuXHJcbiAgLy8gUmV0cnkgbG9naWMgd2l0aCBhYm9ydCBzdXBwb3J0XHJcbiAgcHJpdmF0ZSBhc3luYyByZXRyeVJlcXVlc3Q8VD4oXHJcbiAgICBmbjogKCkgPT4gUHJvbWlzZTxUPixcclxuICAgIHJldHJpZXM6IG51bWJlcixcclxuICAgIGRlbGF5OiBudW1iZXIsXHJcbiAgICBzaWduYWw/OiBBYm9ydFNpZ25hbFxyXG4gICk6IFByb21pc2U8VD4ge1xyXG4gICAgdHJ5IHtcclxuICAgICAgLy8gQ2hlY2sgaWYgYWxyZWFkeSBhYm9ydGVkXHJcbiAgICAgIGlmIChzaWduYWw/LmFib3J0ZWQpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3Ioc2lnbmFsLnJlYXNvbiB8fCAnUmVxdWVzdCBhYm9ydGVkJyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiBhd2FpdCBmbigpO1xyXG4gICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xyXG4gICAgICAvLyBEb24ndCByZXRyeSBpZiBhYm9ydGVkXHJcbiAgICAgIGlmIChlcnJvci5uYW1lID09PSAnQWJvcnRFcnJvcicgfHwgc2lnbmFsPy5hYm9ydGVkKSB7XHJcbiAgICAgICAgdGhyb3cgZXJyb3I7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIERvbid0IHJldHJ5IHZhbGlkYXRpb24gZXJyb3JzXHJcbiAgICAgIGlmIChlcnJvci50eXBlID09PSAndmFsaWRhdGlvbl9lcnJvcicgfHwgZXJyb3Iuc3RhdHVzID09PSA0MDApIHtcclxuICAgICAgICB0aHJvdyBlcnJvcjtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKHJldHJpZXMgPT09IDApIHRocm93IGVycm9yO1xyXG5cclxuICAgICAgLy8gV2FpdCB3aXRoIGFib3J0IHN1cHBvcnRcclxuICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICAgIGNvbnN0IHRpbWVvdXRJZCA9IHNldFRpbWVvdXQocmVzb2x2ZSwgZGVsYXkpO1xyXG5cclxuICAgICAgICBpZiAoc2lnbmFsKSB7XHJcbiAgICAgICAgICBzaWduYWwuYWRkRXZlbnRMaXN0ZW5lcihcclxuICAgICAgICAgICAgJ2Fib3J0JyxcclxuICAgICAgICAgICAgKCkgPT4ge1xyXG4gICAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0SWQpO1xyXG4gICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3Ioc2lnbmFsLnJlYXNvbiB8fCAnUmVxdWVzdCBhYm9ydGVkJykpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICB7IG9uY2U6IHRydWUgfVxyXG4gICAgICAgICAgKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgcmV0dXJuIHRoaXMucmV0cnlSZXF1ZXN0KGZuLCByZXRyaWVzIC0gMSwgZGVsYXkgKiAyLCBzaWduYWwpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8gT3ZlcmxvYWRlZCByZXF1ZXN0IG1ldGhvZCBzaWduYXR1cmVzXHJcbiAgYXN5bmMgcmVxdWVzdDxUID0gYW55PihcclxuICAgIGVuZHBvaW50OiBzdHJpbmcsXHJcbiAgICBjb25maWc6IFJlcXVlc3RDb25maWcgJiB7IHRocm93RXJyb3JzOiBmYWxzZSB9XHJcbiAgKTogUHJvbWlzZTxBcGlSZXNwb25zZTxULCBBcGlFcnJvcj4+O1xyXG4gIGFzeW5jIHJlcXVlc3Q8VCA9IGFueT4oXHJcbiAgICBlbmRwb2ludDogc3RyaW5nLFxyXG4gICAgY29uZmlnPzogUmVxdWVzdENvbmZpZyAmIHsgdGhyb3dFcnJvcnM/OiB0cnVlIH1cclxuICApOiBQcm9taXNlPEFwaVJlc3BvbnNlPFQsIEFwaUVycm9yPj47XHJcbiAgYXN5bmMgcmVxdWVzdDxUID0gYW55PihcclxuICAgIGVuZHBvaW50OiBzdHJpbmcsXHJcbiAgICBjb25maWc/OiBSZXF1ZXN0Q29uZmlnXHJcbiAgKTogUHJvbWlzZTxBcGlSZXNwb25zZTxULCBBcGlFcnJvcj4+O1xyXG5cclxuICAvLyBNYWluIHJlcXVlc3QgbWV0aG9kIGltcGxlbWVudGF0aW9uXHJcbiAgYXN5bmMgcmVxdWVzdDxUID0gYW55PihcclxuICAgIGVuZHBvaW50OiBzdHJpbmcsXHJcbiAgICBjb25maWc6IFJlcXVlc3RDb25maWcgPSB7fVxyXG4gICk6IFByb21pc2U8QXBpUmVzcG9uc2U8VCwgQXBpRXJyb3I+PiB7XHJcbiAgICAvLyBHZW5lcmF0ZSBjb3JyZWxhdGlvbiBJRFxyXG4gICAgY29uc3QgY29ycmVsYXRpb25JZCA9XHJcbiAgICAgIGNvbmZpZy5jb3JyZWxhdGlvbklkIHx8XHJcbiAgICAgICghY29uZmlnLnNraXBDb3JyZWxhdGlvbklkICYmIHRoaXMuaW5jbHVkZUNvcnJlbGF0aW9uSWRcclxuICAgICAgICA/IENvcnJlbGF0aW9uSWRHZW5lcmF0b3IuZ2VuZXJhdGUodGhpcy5jb3JyZWxhdGlvbklkUHJlZml4KVxyXG4gICAgICAgIDogdW5kZWZpbmVkKTtcclxuXHJcbiAgICAvLyBHZW5lcmF0ZSByZXF1ZXN0IGtleSBmb3IgdHJhY2tpbmdcclxuICAgIGNvbnN0IHJlcXVlc3RLZXkgPSBgJHtjb25maWcubWV0aG9kIHx8ICdHRVQnfV8ke2VuZHBvaW50fV8ke0RhdGUubm93KCl9YDtcclxuXHJcbiAgICAvLyBDcmVhdGUgbWFzdGVyIGNvbnRyb2xsZXIgZm9yIHRoaXMgcmVxdWVzdFxyXG4gICAgY29uc3QgbWFzdGVyQ29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcclxuXHJcbiAgICB0cnkge1xyXG4gICAgICAvLyBDb21iaW5lIGFsbCBhYm9ydCBzaWduYWxzXHJcbiAgICAgIGNvbnN0IHNpZ25hbHM6IEFycmF5PEFib3J0U2lnbmFsIHwgdW5kZWZpbmVkPiA9IFtcclxuICAgICAgICBjb25maWcuc2lnbmFsLFxyXG4gICAgICAgIGNvbmZpZy5jYW5jZWxUb2tlbj8uc2lnbmFsLFxyXG4gICAgICAgIG1hc3RlckNvbnRyb2xsZXIuc2lnbmFsLFxyXG4gICAgICBdO1xyXG5cclxuICAgICAgLy8gQWRkIHRpbWVvdXQgc2lnbmFsIGlmIGNvbmZpZ3VyZWRcclxuICAgICAgY29uc3QgdGltZW91dCA9IGNvbmZpZy50aW1lb3V0IHx8IHRoaXMuZGVmYXVsdFRpbWVvdXQ7XHJcbiAgICAgIGNvbnN0IHRpbWVvdXRDb250cm9sbGVyID0gdGhpcy5jcmVhdGVUaW1lb3V0U2lnbmFsKHRpbWVvdXQpO1xyXG5cclxuICAgICAgc2lnbmFscy5wdXNoKHRpbWVvdXRDb250cm9sbGVyLnNpZ25hbCk7XHJcblxyXG4gICAgICAvLyBDcmVhdGUgY29tYmluZWQgc2lnbmFsXHJcbiAgICAgIGNvbnN0IGNvbWJpbmVkQ29udHJvbGxlciA9IHRoaXMuY3JlYXRlQ29tYmluZWRTaWduYWwoc2lnbmFscyk7XHJcblxyXG4gICAgICAvLyBUcmFjayB0aGlzIHJlcXVlc3RcclxuICAgICAgaWYgKGNvcnJlbGF0aW9uSWQpIHtcclxuICAgICAgICB0aGlzLnJlcXVlc3RNYW5hZ2VyLmFkZChyZXF1ZXN0S2V5LCBtYXN0ZXJDb250cm9sbGVyLCBjb3JyZWxhdGlvbklkKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gQXBwbHkgcmVxdWVzdCBpbnRlcmNlcHRvcnNcclxuICAgICAgY29uc3QgZmluYWxDb25maWcgPSBhd2FpdCB0aGlzLmFwcGx5UmVxdWVzdEludGVyY2VwdG9ycyh7XHJcbiAgICAgICAgLi4uY29uZmlnLFxyXG4gICAgICAgIHNpZ25hbDogY29tYmluZWRDb250cm9sbGVyLnNpZ25hbCxcclxuICAgICAgICBjb3JyZWxhdGlvbklkLFxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIC8vIEJ1aWxkIGZ1bGwgVVJMXHJcbiAgICAgIGNvbnN0IHVybCA9IHRoaXMuYnVpbGRVUkwoZW5kcG9pbnQsIGZpbmFsQ29uZmlnLnBhcmFtcyk7XHJcblxyXG4gICAgICAvLyBBZGQgZGVmYXVsdCBoZWFkZXJzXHJcbiAgICAgIGNvbnN0IGhlYWRlcnMgPSBuZXcgSGVhZGVycyhmaW5hbENvbmZpZy5oZWFkZXJzKTtcclxuXHJcbiAgICAgIC8vIEFkZCBjb3JyZWxhdGlvbiBJRCBoZWFkZXJcclxuICAgICAgaWYgKGNvcnJlbGF0aW9uSWQpIHtcclxuICAgICAgICBoZWFkZXJzLnNldCgnWC1Db3JyZWxhdGlvbi1JZCcsIGNvcnJlbGF0aW9uSWQpO1xyXG4gICAgICAgIGhlYWRlcnMuc2V0KCdYLVJlcXVlc3QtSWQnLCBjb3JyZWxhdGlvbklkKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gQWRkIGF1dGggaGVhZGVyIGlmIHRva2VuIGV4aXN0c1xyXG4gICAgICBpZiAodGhpcy5hdXRoVG9rZW4gJiYgIWZpbmFsQ29uZmlnLnNraXBBdXRoUmVmcmVzaCkge1xyXG4gICAgICAgIGhlYWRlcnMuc2V0KCdBdXRob3JpemF0aW9uJywgYEJlYXJlciAke3RoaXMuYXV0aFRva2VufWApO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBTZXQgY29udGVudC10eXBlIGZvciBKU09OIHBheWxvYWRzXHJcbiAgICAgIGlmIChcclxuICAgICAgICBmaW5hbENvbmZpZy5ib2R5ICYmXHJcbiAgICAgICAgdHlwZW9mIGZpbmFsQ29uZmlnLmJvZHkgPT09ICdvYmplY3QnICYmXHJcbiAgICAgICAgIShmaW5hbENvbmZpZy5ib2R5IGluc3RhbmNlb2YgRm9ybURhdGEpXHJcbiAgICAgICkge1xyXG4gICAgICAgIGhlYWRlcnMuc2V0KCdDb250ZW50LVR5cGUnLCAnYXBwbGljYXRpb24vanNvbicpO1xyXG4gICAgICAgIGZpbmFsQ29uZmlnLmJvZHkgPSBKU09OLnN0cmluZ2lmeShmaW5hbENvbmZpZy5ib2R5KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgZmluYWxDb25maWcuaGVhZGVycyA9IGhlYWRlcnM7XHJcblxyXG4gICAgICAvLyBDcmVhdGUgZmV0Y2ggcHJvbWlzZVxyXG4gICAgICBjb25zdCBmZXRjaFByb21pc2UgPSBhc3luYyAoKSA9PiB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2godXJsLCB7XHJcbiAgICAgICAgICAgIC4uLmZpbmFsQ29uZmlnLFxyXG4gICAgICAgICAgICBzaWduYWw6IGNvbWJpbmVkQ29udHJvbGxlci5zaWduYWwsXHJcbiAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAvLyBQYXJzZSByZXNwb25zZSBkYXRhXHJcbiAgICAgICAgICBjb25zdCByZXNwb25zZURhdGEgPSBhd2FpdCB0aGlzLnBhcnNlUmVzcG9uc2VEYXRhKHJlc3BvbnNlKTtcclxuXHJcbiAgICAgICAgICAvLyBIYW5kbGUgZXJyb3IgcmVzcG9uc2VzXHJcbiAgICAgICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGVycm9yOiBBcGlFcnJvciA9IE9iamVjdC5hc3NpZ24oXHJcbiAgICAgICAgICAgICAgbmV3IEVycm9yKFxyXG4gICAgICAgICAgICAgICAgcmVzcG9uc2VEYXRhLnRpdGxlIHx8XHJcbiAgICAgICAgICAgICAgICAgIGBIVFRQICR7cmVzcG9uc2Uuc3RhdHVzfTogJHtyZXNwb25zZS5zdGF0dXNUZXh0fWBcclxuICAgICAgICAgICAgICApLFxyXG4gICAgICAgICAgICAgIHtcclxuICAgICAgICAgICAgICAgIHR5cGU6IHJlc3BvbnNlRGF0YS50eXBlIHx8IHRoaXMuZ2V0RXJyb3JUeXBlKHJlc3BvbnNlLnN0YXR1cyksXHJcbiAgICAgICAgICAgICAgICB0aXRsZTpcclxuICAgICAgICAgICAgICAgICAgcmVzcG9uc2VEYXRhLnRpdGxlIHx8IHRoaXMuZ2V0RXJyb3JUaXRsZShyZXNwb25zZS5zdGF0dXMpLFxyXG4gICAgICAgICAgICAgICAgc3RhdHVzOiByZXNwb25zZS5zdGF0dXMsXHJcbiAgICAgICAgICAgICAgICB0cmFjZUlkOiByZXNwb25zZURhdGEudHJhY2VJZCB8fCBjb3JyZWxhdGlvbklkLFxyXG4gICAgICAgICAgICAgICAgZXJyb3JzOiByZXNwb25zZURhdGEuZXJyb3JzLFxyXG4gICAgICAgICAgICAgICAgaXNBYm9ydGVkOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgIGNvbmZpZzogZmluYWxDb25maWcsXHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICApO1xyXG5cclxuICAgICAgICAgICAgLy8gQ2hlY2sgaWYgd2Ugc2hvdWxkIHRocm93IG9yIHJldHVybiBlcnJvciBpbiByZXNwb25zZVxyXG4gICAgICAgICAgICBpZiAoZmluYWxDb25maWcudGhyb3dFcnJvcnMgIT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgICAgdGhyb3cgZXJyb3I7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgLy8gUmV0dXJuIGVycm9yIGluIEFwaVJlc3BvbnNlLmVycm9yIGZpZWxkXHJcbiAgICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuYXBwbHlSZXNwb25zZUludGVyY2VwdG9ycyh7XHJcbiAgICAgICAgICAgICAgICBlcnJvcixcclxuICAgICAgICAgICAgICB9IGFzIEFwaVJlc3BvbnNlPFQsIEFwaUVycm9yPik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAvLyBGb3JtYXQgc3VjY2Vzc2Z1bCByZXNwb25zZVxyXG4gICAgICAgICAgY29uc3QgYXBpUmVzcG9uc2U6IEFwaVJlc3BvbnNlPFQ+ID0ge1xyXG4gICAgICAgICAgICBkYXRhOiByZXNwb25zZURhdGEgYXMgVCxcclxuICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgLy8gQXBwbHkgcmVzcG9uc2UgaW50ZXJjZXB0b3JzXHJcbiAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5hcHBseVJlc3BvbnNlSW50ZXJjZXB0b3JzKGFwaVJlc3BvbnNlKTtcclxuICAgICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XHJcbiAgICAgICAgICAvLyBIYW5kbGUgYWJvcnQgZXJyb3JzXHJcbiAgICAgICAgICBpZiAoZXJyb3IubmFtZSA9PT0gJ0Fib3J0RXJyb3InKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGFib3J0RXJyb3IgPSBPYmplY3QuYXNzaWduKFxyXG4gICAgICAgICAgICAgIG5ldyBFcnJvcihlcnJvci5tZXNzYWdlIHx8ICdSZXF1ZXN0IGFib3J0ZWQnKSxcclxuICAgICAgICAgICAgICB7XHJcbiAgICAgICAgICAgICAgICB0eXBlOiAncmVxdWVzdF9jYW5jZWxsZWQnLFxyXG4gICAgICAgICAgICAgICAgdGl0bGU6ICdSZXF1ZXN0IHdhcyBjYW5jZWxsZWQnLFxyXG4gICAgICAgICAgICAgICAgc3RhdHVzOiAwLFxyXG4gICAgICAgICAgICAgICAgdHJhY2VJZDogY29ycmVsYXRpb25JZCxcclxuICAgICAgICAgICAgICAgIGlzQWJvcnRlZDogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIGNvbmZpZzogZmluYWxDb25maWcsXHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICApO1xyXG5cclxuICAgICAgICAgICAgLy8gQ2hlY2sgaWYgd2Ugc2hvdWxkIHRocm93IG9yIHJldHVybiBlcnJvciBpbiByZXNwb25zZVxyXG4gICAgICAgICAgICBpZiAoZmluYWxDb25maWcudGhyb3dFcnJvcnMgIT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgICAgdGhyb3cgYWJvcnRFcnJvcjtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAvLyBSZXR1cm4gZXJyb3IgaW4gQXBpUmVzcG9uc2UuZXJyb3IgZmllbGRcclxuICAgICAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5hcHBseVJlc3BvbnNlSW50ZXJjZXB0b3JzKHtcclxuICAgICAgICAgICAgICAgIGVycm9yOiBhYm9ydEVycm9yLFxyXG4gICAgICAgICAgICAgIH0gYXMgQXBpUmVzcG9uc2U8VCwgQXBpRXJyb3I+KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIHRocm93IGVycm9yO1xyXG4gICAgICAgIH1cclxuICAgICAgfTtcclxuXHJcbiAgICAgIC8vIEhhbmRsZSByZXRyaWVzIGlmIGNvbmZpZ3VyZWRcclxuICAgICAgaWYgKGZpbmFsQ29uZmlnLnJldHJpZXMgJiYgZmluYWxDb25maWcucmV0cmllcyA+IDApIHtcclxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5yZXRyeVJlcXVlc3QoXHJcbiAgICAgICAgICBmZXRjaFByb21pc2UsXHJcbiAgICAgICAgICBmaW5hbENvbmZpZy5yZXRyaWVzLFxyXG4gICAgICAgICAgZmluYWxDb25maWcucmV0cnlEZWxheSB8fCAxMDAwLFxyXG4gICAgICAgICAgY29tYmluZWRDb250cm9sbGVyLnNpZ25hbFxyXG4gICAgICAgICk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiBhd2FpdCBmZXRjaFByb21pc2UoKTtcclxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgIC8vIEhhbmRsZSBlcnJvcnNcclxuICAgICAgY29uc3QgYXBpRXJyb3I6IEFwaUVycm9yID0gdGhpcy5ub3JtYWxpemVFcnJvcihcclxuICAgICAgICBlcnJvcixcclxuICAgICAgICBjb25maWcsXHJcbiAgICAgICAgY29ycmVsYXRpb25JZFxyXG4gICAgICApO1xyXG5cclxuICAgICAgLy8gQ2hlY2sgaWYgd2Ugc2hvdWxkIHRocm93IG9yIHJldHVybiBlcnJvciBpbiByZXNwb25zZVxyXG4gICAgICBpZiAoY29uZmlnLnRocm93RXJyb3JzICE9PSBmYWxzZSkge1xyXG4gICAgICAgIGF3YWl0IHRoaXMuYXBwbHlFcnJvckludGVyY2VwdG9ycyhhcGlFcnJvcik7XHJcbiAgICAgICAgLy8gVGhpcyBsaW5lIHdpbGwgbmV2ZXIgYmUgcmVhY2hlZCBhcyBhcHBseUVycm9ySW50ZXJjZXB0b3JzIGFsd2F5cyB0aHJvd3MsXHJcbiAgICAgICAgLy8gYnV0IFR5cGVTY3JpcHQgcmVxdWlyZXMgYSByZXR1cm4gc3RhdGVtZW50XHJcbiAgICAgICAgdGhyb3cgYXBpRXJyb3I7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgLy8gUmV0dXJuIGVycm9yIGluIEFwaVJlc3BvbnNlLmVycm9yIGZpZWxkXHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgIGVycm9yOiBhcGlFcnJvcixcclxuICAgICAgICB9IGFzIEFwaVJlc3BvbnNlPFQsIEFwaUVycm9yPjtcclxuICAgICAgfVxyXG4gICAgfSBmaW5hbGx5IHtcclxuICAgICAgLy8gQ2xlYW4gdXAgcmVxdWVzdCB0cmFja2luZ1xyXG4gICAgICB0aGlzLnJlcXVlc3RNYW5hZ2VyLnJlbW92ZShyZXF1ZXN0S2V5KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIEdldCBlcnJvciB0eXBlIGJhc2VkIG9uIHN0YXR1cyBjb2RlXHJcbiAgcHJpdmF0ZSBnZXRFcnJvclR5cGUoc3RhdHVzOiBudW1iZXIpOiBzdHJpbmcge1xyXG4gICAgaWYgKHN0YXR1cyA+PSA0MDAgJiYgc3RhdHVzIDwgNTAwKSB7XHJcbiAgICAgIHJldHVybiBzdGF0dXMgPT09IDQwMCA/ICd2YWxpZGF0aW9uX2Vycm9yJyA6ICdjbGllbnRfZXJyb3InO1xyXG4gICAgfSBlbHNlIGlmIChzdGF0dXMgPj0gNTAwKSB7XHJcbiAgICAgIHJldHVybiAnc2VydmVyX2Vycm9yJztcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gJ3Vua25vd25fZXJyb3InO1xyXG4gIH1cclxuXHJcbiAgLy8gR2V0IGVycm9yIHRpdGxlIGJhc2VkIG9uIHN0YXR1cyBjb2RlXHJcbiAgcHJpdmF0ZSBnZXRFcnJvclRpdGxlKHN0YXR1czogbnVtYmVyKTogc3RyaW5nIHtcclxuICAgIGNvbnN0IHRpdGxlczogUmVjb3JkPG51bWJlciwgc3RyaW5nPiA9IHtcclxuICAgICAgNDAwOiAnQmFkIFJlcXVlc3QnLFxyXG4gICAgICA0MDE6ICdVbmF1dGhvcml6ZWQnLFxyXG4gICAgICA0MDM6ICdGb3JiaWRkZW4nLFxyXG4gICAgICA0MDQ6ICdOb3QgRm91bmQnLFxyXG4gICAgICA0MDU6ICdNZXRob2QgTm90IEFsbG93ZWQnLFxyXG4gICAgICA0MDg6ICdSZXF1ZXN0IFRpbWVvdXQnLFxyXG4gICAgICA0MDk6ICdDb25mbGljdCcsXHJcbiAgICAgIDQyMjogJ1VucHJvY2Vzc2FibGUgRW50aXR5JyxcclxuICAgICAgNDI5OiAnVG9vIE1hbnkgUmVxdWVzdHMnLFxyXG4gICAgICA1MDA6ICdJbnRlcm5hbCBTZXJ2ZXIgRXJyb3InLFxyXG4gICAgICA1MDI6ICdCYWQgR2F0ZXdheScsXHJcbiAgICAgIDUwMzogJ1NlcnZpY2UgVW5hdmFpbGFibGUnLFxyXG4gICAgICA1MDQ6ICdHYXRld2F5IFRpbWVvdXQnLFxyXG4gICAgfTtcclxuXHJcbiAgICByZXR1cm4gdGl0bGVzW3N0YXR1c10gfHwgYEhUVFAgRXJyb3IgJHtzdGF0dXN9YDtcclxuICB9XHJcblxyXG4gIC8vIFBhcnNlIHJlc3BvbnNlIGRhdGEgYmFzZWQgb24gY29udGVudCB0eXBlXHJcbiAgcHJpdmF0ZSBhc3luYyBwYXJzZVJlc3BvbnNlRGF0YShyZXNwb25zZTogUmVzcG9uc2UpOiBQcm9taXNlPGFueT4ge1xyXG4gICAgY29uc3QgY29udGVudFR5cGUgPSByZXNwb25zZS5oZWFkZXJzLmdldCgnY29udGVudC10eXBlJyk7XHJcblxyXG4gICAgaWYgKGNvbnRlbnRUeXBlPy5pbmNsdWRlcygnYXBwbGljYXRpb24vanNvbicpKSB7XHJcbiAgICAgIHJldHVybiByZXNwb25zZS5qc29uKCk7XHJcbiAgICB9IGVsc2UgaWYgKGNvbnRlbnRUeXBlPy5pbmNsdWRlcygndGV4dC8nKSkge1xyXG4gICAgICByZXR1cm4gcmVzcG9uc2UudGV4dCgpO1xyXG4gICAgfSBlbHNlIGlmIChjb250ZW50VHlwZT8uaW5jbHVkZXMoJ2FwcGxpY2F0aW9uL29jdGV0LXN0cmVhbScpKSB7XHJcbiAgICAgIHJldHVybiByZXNwb25zZS5ibG9iKCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAvLyBUcnkgSlNPTiBmaXJzdCwgZmFsbGJhY2sgdG8gdGV4dFxyXG4gICAgICBjb25zdCB0ZXh0ID0gYXdhaXQgcmVzcG9uc2UudGV4dCgpO1xyXG5cclxuICAgICAgdHJ5IHtcclxuICAgICAgICByZXR1cm4gSlNPTi5wYXJzZSh0ZXh0KTtcclxuICAgICAgfSBjYXRjaCB7XHJcbiAgICAgICAgcmV0dXJuIHRleHQ7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIE5vcm1hbGl6ZSBlcnJvcnNcclxuICBwcml2YXRlIG5vcm1hbGl6ZUVycm9yKFxyXG4gICAgZXJyb3I6IGFueSxcclxuICAgIGNvbmZpZzogUmVxdWVzdENvbmZpZyxcclxuICAgIGNvcnJlbGF0aW9uSWQ/OiBzdHJpbmdcclxuICApOiBBcGlFcnJvciB7XHJcbiAgICAvLyBJZiBlcnJvciBhbHJlYWR5IGhhcyBBcGlFcnJvciBzdHJ1Y3R1cmUsIGVuaGFuY2UgaXRcclxuICAgIGlmIChlcnJvci50eXBlIHx8IGVycm9yLnRpdGxlIHx8IGVycm9yLmVycm9ycykge1xyXG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihcclxuICAgICAgICBlcnJvciBpbnN0YW5jZW9mIEVycm9yXHJcbiAgICAgICAgICA/IGVycm9yXHJcbiAgICAgICAgICA6IG5ldyBFcnJvcihlcnJvci5tZXNzYWdlIHx8ICdVbmtub3duIGVycm9yJyksXHJcbiAgICAgICAge1xyXG4gICAgICAgICAgdHlwZTogZXJyb3IudHlwZSxcclxuICAgICAgICAgIHRpdGxlOiBlcnJvci50aXRsZSxcclxuICAgICAgICAgIHN0YXR1czogZXJyb3Iuc3RhdHVzLFxyXG4gICAgICAgICAgdHJhY2VJZDogZXJyb3IudHJhY2VJZCB8fCBjb3JyZWxhdGlvbklkLFxyXG4gICAgICAgICAgZXJyb3JzOiBlcnJvci5lcnJvcnMsXHJcbiAgICAgICAgICBpc0Fib3J0ZWQ6IGVycm9yLmlzQWJvcnRlZCB8fCBmYWxzZSxcclxuICAgICAgICAgIGNvbmZpZyxcclxuICAgICAgICB9XHJcbiAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKGVycm9yLm5hbWUgPT09ICdBYm9ydEVycm9yJyB8fCBlcnJvci5pc0Fib3J0ZWQpIHtcclxuICAgICAgcmV0dXJuIE9iamVjdC5hc3NpZ24obmV3IEVycm9yKGVycm9yLm1lc3NhZ2UgfHwgJ1JlcXVlc3Qgd2FzIGFib3J0ZWQnKSwge1xyXG4gICAgICAgIHR5cGU6ICdyZXF1ZXN0X2NhbmNlbGxlZCcsXHJcbiAgICAgICAgdGl0bGU6ICdSZXF1ZXN0IHdhcyBjYW5jZWxsZWQnLFxyXG4gICAgICAgIHN0YXR1czogMCxcclxuICAgICAgICB0cmFjZUlkOiBjb3JyZWxhdGlvbklkLFxyXG4gICAgICAgIGlzQWJvcnRlZDogdHJ1ZSxcclxuICAgICAgICBjb25maWcsXHJcbiAgICAgIH0gYXMgQXBpRXJyb3IpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChlcnJvci5tZXNzYWdlPy5pbmNsdWRlcygndGltZW91dCcpKSB7XHJcbiAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKG5ldyBFcnJvcihlcnJvci5tZXNzYWdlKSwge1xyXG4gICAgICAgIHR5cGU6ICd0aW1lb3V0X2Vycm9yJyxcclxuICAgICAgICB0aXRsZTogJ1JlcXVlc3QgVGltZW91dCcsXHJcbiAgICAgICAgc3RhdHVzOiA0MDgsXHJcbiAgICAgICAgdHJhY2VJZDogY29ycmVsYXRpb25JZCxcclxuICAgICAgICBpc0Fib3J0ZWQ6IHRydWUsXHJcbiAgICAgICAgY29uZmlnLFxyXG4gICAgICB9IGFzIEFwaUVycm9yKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoZXJyb3IubWVzc2FnZT8uaW5jbHVkZXMoJ25ldHdvcmsnKSkge1xyXG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihcclxuICAgICAgICBuZXcgRXJyb3IoZXJyb3IubWVzc2FnZSB8fCAnTmV0d29yayByZXF1ZXN0IGZhaWxlZCcpLFxyXG4gICAgICAgIHtcclxuICAgICAgICAgIHR5cGU6ICduZXR3b3JrX2Vycm9yJyxcclxuICAgICAgICAgIHRpdGxlOiAnTmV0d29yayBFcnJvcicsXHJcbiAgICAgICAgICBzdGF0dXM6IDAsXHJcbiAgICAgICAgICB0cmFjZUlkOiBjb3JyZWxhdGlvbklkLFxyXG4gICAgICAgICAgaXNBYm9ydGVkOiBmYWxzZSxcclxuICAgICAgICAgIGNvbmZpZyxcclxuICAgICAgICB9IGFzIEFwaUVycm9yXHJcbiAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oXHJcbiAgICAgIG5ldyBFcnJvcihlcnJvci5tZXNzYWdlIHx8ICdBbiB1bmtub3duIGVycm9yIG9jY3VycmVkJyksXHJcbiAgICAgIHtcclxuICAgICAgICB0eXBlOiAndW5rbm93bl9lcnJvcicsXHJcbiAgICAgICAgdGl0bGU6ICdVbmtub3duIEVycm9yJyxcclxuICAgICAgICBzdGF0dXM6IDAsXHJcbiAgICAgICAgdHJhY2VJZDogY29ycmVsYXRpb25JZCxcclxuICAgICAgICBpc0Fib3J0ZWQ6IGZhbHNlLFxyXG4gICAgICAgIGNvbmZpZyxcclxuICAgICAgfSBhcyBBcGlFcnJvclxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIC8vIENvbnZlbmllbmNlIG1ldGhvZHMgd2l0aCBhYm9ydCBzdXBwb3J0IGFuZCBvdmVybG9hZHMgZm9yIGVycm9yIGhhbmRsaW5nXHJcblxyXG4gIC8vIEdFVCBtZXRob2Qgb3ZlcmxvYWRzXHJcbiAgZ2V0PFQgPSBhbnk+KFxyXG4gICAgZW5kcG9pbnQ6IHN0cmluZyxcclxuICAgIGNvbmZpZzogUmVxdWVzdENvbmZpZyAmIHsgdGhyb3dFcnJvcnM6IGZhbHNlIH1cclxuICApOiBQcm9taXNlPEFwaVJlc3BvbnNlPFQsIEFwaUVycm9yPj47XHJcbiAgZ2V0PFQgPSBhbnk+KFxyXG4gICAgZW5kcG9pbnQ6IHN0cmluZyxcclxuICAgIGNvbmZpZz86IFJlcXVlc3RDb25maWcgJiB7IHRocm93RXJyb3JzPzogdHJ1ZSB9XHJcbiAgKTogUHJvbWlzZTxBcGlSZXNwb25zZTxULCBBcGlFcnJvcj4+O1xyXG4gIGdldDxUID0gYW55PihcclxuICAgIGVuZHBvaW50OiBzdHJpbmcsXHJcbiAgICBjb25maWc/OiBSZXF1ZXN0Q29uZmlnXHJcbiAgKTogUHJvbWlzZTxBcGlSZXNwb25zZTxULCBBcGlFcnJvcj4+O1xyXG4gIGdldDxUID0gYW55PihcclxuICAgIGVuZHBvaW50OiBzdHJpbmcsXHJcbiAgICBjb25maWc/OiBSZXF1ZXN0Q29uZmlnXHJcbiAgKTogUHJvbWlzZTxBcGlSZXNwb25zZTxULCBBcGlFcnJvcj4+IHtcclxuICAgIHJldHVybiB0aGlzLnJlcXVlc3Q8VD4oZW5kcG9pbnQsIHsgLi4uY29uZmlnLCBtZXRob2Q6ICdHRVQnIH0pO1xyXG4gIH1cclxuXHJcbiAgLy8gUE9TVCBtZXRob2Qgb3ZlcmxvYWRzXHJcbiAgcG9zdDxUID0gYW55PihcclxuICAgIGVuZHBvaW50OiBzdHJpbmcsXHJcbiAgICBkYXRhOiBhbnksXHJcbiAgICBjb25maWc6IFJlcXVlc3RDb25maWcgJiB7IHRocm93RXJyb3JzOiBmYWxzZSB9XHJcbiAgKTogUHJvbWlzZTxBcGlSZXNwb25zZTxULCBBcGlFcnJvcj4+O1xyXG4gIHBvc3Q8VCA9IGFueT4oXHJcbiAgICBlbmRwb2ludDogc3RyaW5nLFxyXG4gICAgZGF0YT86IGFueSxcclxuICAgIGNvbmZpZz86IFJlcXVlc3RDb25maWcgJiB7IHRocm93RXJyb3JzPzogdHJ1ZSB9XHJcbiAgKTogUHJvbWlzZTxBcGlSZXNwb25zZTxULCBBcGlFcnJvcj4+O1xyXG4gIHBvc3Q8VCA9IGFueT4oXHJcbiAgICBlbmRwb2ludDogc3RyaW5nLFxyXG4gICAgZGF0YT86IGFueSxcclxuICAgIGNvbmZpZz86IFJlcXVlc3RDb25maWdcclxuICApOiBQcm9taXNlPEFwaVJlc3BvbnNlPFQsIEFwaUVycm9yPj47XHJcbiAgcG9zdDxUID0gYW55PihcclxuICAgIGVuZHBvaW50OiBzdHJpbmcsXHJcbiAgICBkYXRhPzogYW55LFxyXG4gICAgY29uZmlnPzogUmVxdWVzdENvbmZpZ1xyXG4gICk6IFByb21pc2U8QXBpUmVzcG9uc2U8VCwgQXBpRXJyb3I+PiB7XHJcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0PFQ+KGVuZHBvaW50LCB7IC4uLmNvbmZpZywgbWV0aG9kOiAnUE9TVCcsIGJvZHk6IGRhdGEgfSk7XHJcbiAgfVxyXG5cclxuICAvLyBQVVQgbWV0aG9kIG92ZXJsb2Fkc1xyXG4gIHB1dDxUID0gYW55PihcclxuICAgIGVuZHBvaW50OiBzdHJpbmcsXHJcbiAgICBkYXRhOiBhbnksXHJcbiAgICBjb25maWc6IFJlcXVlc3RDb25maWcgJiB7IHRocm93RXJyb3JzOiBmYWxzZSB9XHJcbiAgKTogUHJvbWlzZTxBcGlSZXNwb25zZTxULCBBcGlFcnJvcj4+O1xyXG4gIHB1dDxUID0gYW55PihcclxuICAgIGVuZHBvaW50OiBzdHJpbmcsXHJcbiAgICBkYXRhPzogYW55LFxyXG4gICAgY29uZmlnPzogUmVxdWVzdENvbmZpZyAmIHsgdGhyb3dFcnJvcnM/OiB0cnVlIH1cclxuICApOiBQcm9taXNlPEFwaVJlc3BvbnNlPFQsIEFwaUVycm9yPj47XHJcbiAgcHV0PFQgPSBhbnk+KFxyXG4gICAgZW5kcG9pbnQ6IHN0cmluZyxcclxuICAgIGRhdGE/OiBhbnksXHJcbiAgICBjb25maWc/OiBSZXF1ZXN0Q29uZmlnXHJcbiAgKTogUHJvbWlzZTxBcGlSZXNwb25zZTxULCBBcGlFcnJvcj4+O1xyXG4gIHB1dDxUID0gYW55PihcclxuICAgIGVuZHBvaW50OiBzdHJpbmcsXHJcbiAgICBkYXRhPzogYW55LFxyXG4gICAgY29uZmlnPzogUmVxdWVzdENvbmZpZ1xyXG4gICk6IFByb21pc2U8QXBpUmVzcG9uc2U8VCwgQXBpRXJyb3I+PiB7XHJcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0PFQ+KGVuZHBvaW50LCB7IC4uLmNvbmZpZywgbWV0aG9kOiAnUFVUJywgYm9keTogZGF0YSB9KTtcclxuICB9XHJcblxyXG4gIC8vIFBBVENIIG1ldGhvZCBvdmVybG9hZHNcclxuICBwYXRjaDxUID0gYW55PihcclxuICAgIGVuZHBvaW50OiBzdHJpbmcsXHJcbiAgICBkYXRhOiBhbnksXHJcbiAgICBjb25maWc6IFJlcXVlc3RDb25maWcgJiB7IHRocm93RXJyb3JzOiBmYWxzZSB9XHJcbiAgKTogUHJvbWlzZTxBcGlSZXNwb25zZTxULCBBcGlFcnJvcj4+O1xyXG4gIHBhdGNoPFQgPSBhbnk+KFxyXG4gICAgZW5kcG9pbnQ6IHN0cmluZyxcclxuICAgIGRhdGE/OiBhbnksXHJcbiAgICBjb25maWc/OiBSZXF1ZXN0Q29uZmlnICYgeyB0aHJvd0Vycm9ycz86IHRydWUgfVxyXG4gICk6IFByb21pc2U8QXBpUmVzcG9uc2U8VCwgQXBpRXJyb3I+PjtcclxuICBwYXRjaDxUID0gYW55PihcclxuICAgIGVuZHBvaW50OiBzdHJpbmcsXHJcbiAgICBkYXRhPzogYW55LFxyXG4gICAgY29uZmlnPzogUmVxdWVzdENvbmZpZ1xyXG4gICk6IFByb21pc2U8QXBpUmVzcG9uc2U8VCwgQXBpRXJyb3I+PjtcclxuICBwYXRjaDxUID0gYW55PihcclxuICAgIGVuZHBvaW50OiBzdHJpbmcsXHJcbiAgICBkYXRhPzogYW55LFxyXG4gICAgY29uZmlnPzogUmVxdWVzdENvbmZpZ1xyXG4gICk6IFByb21pc2U8QXBpUmVzcG9uc2U8VCwgQXBpRXJyb3I+PiB7XHJcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0PFQ+KGVuZHBvaW50LCB7XHJcbiAgICAgIC4uLmNvbmZpZyxcclxuICAgICAgbWV0aG9kOiAnUEFUQ0gnLFxyXG4gICAgICBib2R5OiBkYXRhLFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvLyBERUxFVEUgbWV0aG9kIG92ZXJsb2Fkc1xyXG4gIGRlbGV0ZTxUID0gYW55PihcclxuICAgIGVuZHBvaW50OiBzdHJpbmcsXHJcbiAgICBjb25maWc6IFJlcXVlc3RDb25maWcgJiB7IHRocm93RXJyb3JzOiBmYWxzZSB9XHJcbiAgKTogUHJvbWlzZTxBcGlSZXNwb25zZTxULCBBcGlFcnJvcj4+O1xyXG4gIGRlbGV0ZTxUID0gYW55PihcclxuICAgIGVuZHBvaW50OiBzdHJpbmcsXHJcbiAgICBjb25maWc/OiBSZXF1ZXN0Q29uZmlnICYgeyB0aHJvd0Vycm9ycz86IHRydWUgfVxyXG4gICk6IFByb21pc2U8QXBpUmVzcG9uc2U8VCwgQXBpRXJyb3I+PjtcclxuICBkZWxldGU8VCA9IGFueT4oXHJcbiAgICBlbmRwb2ludDogc3RyaW5nLFxyXG4gICAgY29uZmlnPzogUmVxdWVzdENvbmZpZ1xyXG4gICk6IFByb21pc2U8QXBpUmVzcG9uc2U8VCwgQXBpRXJyb3I+PjtcclxuICBkZWxldGU8VCA9IGFueT4oXHJcbiAgICBlbmRwb2ludDogc3RyaW5nLFxyXG4gICAgY29uZmlnPzogUmVxdWVzdENvbmZpZ1xyXG4gICk6IFByb21pc2U8QXBpUmVzcG9uc2U8VCwgQXBpRXJyb3I+PiB7XHJcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0PFQ+KGVuZHBvaW50LCB7IC4uLmNvbmZpZywgbWV0aG9kOiAnREVMRVRFJyB9KTtcclxuICB9XHJcblxyXG4gIC8vIEZpbHRlciBtZXRob2Qgb3ZlcmxvYWRzXHJcbiAgZmlsdGVyPFRMaXN0TW9kZWwsIFRGaWx0ZXI+KFxyXG4gICAgdXJsOiBzdHJpbmcsXHJcbiAgICBkYXRhOiBQb3N0TW9kZWw8VEZpbHRlcj4sXHJcbiAgICBjb25maWc6IFJlcXVlc3RDb25maWcgJiB7IHRocm93RXJyb3JzOiBmYWxzZSB9XHJcbiAgKTogUHJvbWlzZTxBcGlSZXNwb25zZTxMaXN0UmVzcG9uc2UyPFRMaXN0TW9kZWw+LCBBcGlFcnJvcj4+O1xyXG4gIGZpbHRlcjxUTGlzdE1vZGVsLCBURmlsdGVyPihcclxuICAgIHVybDogc3RyaW5nLFxyXG4gICAgZGF0YTogUG9zdE1vZGVsPFRGaWx0ZXI+LFxyXG4gICAgY29uZmlnPzogUmVxdWVzdENvbmZpZyAmIHsgdGhyb3dFcnJvcnM/OiB0cnVlIH1cclxuICApOiBQcm9taXNlPEFwaVJlc3BvbnNlPExpc3RSZXNwb25zZTI8VExpc3RNb2RlbD4sIEFwaUVycm9yPj47XHJcbiAgZmlsdGVyPFRMaXN0TW9kZWwsIFRGaWx0ZXI+KFxyXG4gICAgdXJsOiBzdHJpbmcsXHJcbiAgICBkYXRhOiBQb3N0TW9kZWw8VEZpbHRlcj4sXHJcbiAgICBjb25maWc/OiBSZXF1ZXN0Q29uZmlnXHJcbiAgKTogUHJvbWlzZTxBcGlSZXNwb25zZTxMaXN0UmVzcG9uc2UyPFRMaXN0TW9kZWw+LCBBcGlFcnJvcj4+O1xyXG4gIGZpbHRlcjxUTGlzdE1vZGVsLCBURmlsdGVyPihcclxuICAgIHVybDogc3RyaW5nLFxyXG4gICAgZGF0YTogUG9zdE1vZGVsPFRGaWx0ZXI+LFxyXG4gICAgY29uZmlnPzogUmVxdWVzdENvbmZpZ1xyXG4gICk6IFByb21pc2U8QXBpUmVzcG9uc2U8TGlzdFJlc3BvbnNlMjxUTGlzdE1vZGVsPiwgQXBpRXJyb3I+PiB7XHJcbiAgICAvLyBNZXJnZSBib2R5OiB7IC4uLnBvc3RNb2RlbCwgLi4ucG9zdE1vZGVsLmZpbHRlck1vZGVsIH1cclxuICAgIGNvbnN0IG1lcmdlZERhdGEgPSB7IC4uLmRhdGEsIC4uLmRhdGEuZmlsdGVyTW9kZWwgfTtcclxuXHJcbiAgICByZXR1cm4gdGhpcy5yZXF1ZXN0PExpc3RSZXNwb25zZTI8VExpc3RNb2RlbD4+KHVybCwge1xyXG4gICAgICAuLi5jb25maWcsXHJcbiAgICAgIG1ldGhvZDogJ1BPU1QnLFxyXG4gICAgICBib2R5OiBtZXJnZWREYXRhLFxyXG4gICAgfSk7XHJcbiAgfVxyXG59XHJcbiIsICJpbXBvcnQgeyBBcGlDbGllbnQgfSBmcm9tICcuL0FwaUNsaWVudCc7XHJcbmltcG9ydCB0eXBlIHsgRXJyb3JJbnRlcmNlcHRvciB9IGZyb20gJy4vdHlwZXMvRXJyb3JJbnRlcmNlcHRvcic7XHJcbmltcG9ydCB0eXBlIHsgUmVxdWVzdEludGVyY2VwdG9yIH0gZnJvbSAnLi90eXBlcy9SZXF1ZXN0SW50ZXJjZXB0b3InO1xyXG5pbXBvcnQgdHlwZSB7IFJlc3BvbnNlSW50ZXJjZXB0b3IgfSBmcm9tICcuL3R5cGVzL1Jlc3BvbnNlSW50ZXJjZXB0b3InO1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBBcGlDbGllbnRDb25maWcge1xyXG4gIGJhc2VVUkw/OiBzdHJpbmc7XHJcbiAgdGltZW91dD86IG51bWJlcjtcclxuICBjb3JyZWxhdGlvbklkUHJlZml4Pzogc3RyaW5nO1xyXG4gIGluY2x1ZGVDb3JyZWxhdGlvbklkPzogYm9vbGVhbjtcclxuICBhdXRoVG9rZW4/OiBzdHJpbmcgfCBudWxsO1xyXG4gIHJlcXVlc3RJbnRlcmNlcHRvcnM/OiBSZXF1ZXN0SW50ZXJjZXB0b3JbXTtcclxuICByZXNwb25zZUludGVyY2VwdG9ycz86IFJlc3BvbnNlSW50ZXJjZXB0b3JbXTtcclxuICBlcnJvckludGVyY2VwdG9ycz86IEVycm9ySW50ZXJjZXB0b3JbXTtcclxufVxyXG5cclxubGV0IGdsb2JhbEFwaUNsaWVudDogQXBpQ2xpZW50IHwgbnVsbCA9IG51bGw7XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQXBpQ2xpZW50KGNvbmZpZzogQXBpQ2xpZW50Q29uZmlnID0ge30pOiBBcGlDbGllbnQge1xyXG4gIGNvbnN0IHtcclxuICAgIGJhc2VVUkwgPSBpbXBvcnQubWV0YS5lbnYuVklURV9BUElfVVJMLFxyXG4gICAgdGltZW91dCA9IDMwMDAwLFxyXG4gICAgY29ycmVsYXRpb25JZFByZWZpeCA9ICdhcGknLFxyXG4gICAgaW5jbHVkZUNvcnJlbGF0aW9uSWQgPSB0cnVlLFxyXG4gICAgcmVxdWVzdEludGVyY2VwdG9ycyA9IFtdLFxyXG4gICAgcmVzcG9uc2VJbnRlcmNlcHRvcnMgPSBbXSxcclxuICAgIGVycm9ySW50ZXJjZXB0b3JzID0gW10sXHJcbiAgfSA9IGNvbmZpZztcclxuXHJcbiAgY29uc3QgY2xpZW50ID0gbmV3IEFwaUNsaWVudChiYXNlVVJMLCB0aW1lb3V0KTtcclxuXHJcbiAgY2xpZW50LmFkZFJlcXVlc3RJbnRlcmNlcHRvcihjb25maWcgPT4ge1xyXG4gICAgY29uc3QgdG9rZW4gPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnc2VydmljZVRva2VuJyk7XHJcblxyXG4gICAgaWYgKHRva2VuICYmICFjb25maWcuc2tpcEF1dGhSZWZyZXNoKSB7XHJcbiAgICAgIGNvbmZpZy5oZWFkZXJzID0ge1xyXG4gICAgICAgIC4uLmNvbmZpZy5oZWFkZXJzLFxyXG4gICAgICAgIEF1dGhvcml6YXRpb246IGBCZWFyZXIgJHt0b2tlbn1gLFxyXG4gICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBjb25maWc7XHJcbiAgfSk7XHJcblxyXG4gIC8vIENvbmZpZ3VyZSBjb3JyZWxhdGlvbiBJRFxyXG4gIGNsaWVudC5zZXRDb3JyZWxhdGlvbklkUHJlZml4KGNvcnJlbGF0aW9uSWRQcmVmaXgpO1xyXG4gIGNsaWVudC5zZXRJbmNsdWRlQ29ycmVsYXRpb25JZChpbmNsdWRlQ29ycmVsYXRpb25JZCk7XHJcblxyXG4gIC8vIC8vIFNldCBhdXRoIHRva2VuIGlmIHByb3ZpZGVkXHJcbiAgLy8gaWYgKGF1dGhUb2tlbiAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgLy8gICBjbGllbnQuc2V0QXV0aFRva2VuKGF1dGhUb2tlbik7XHJcbiAgLy8gfVxyXG5cclxuICAvLyBBZGQgaW50ZXJjZXB0b3JzXHJcbiAgcmVxdWVzdEludGVyY2VwdG9ycy5mb3JFYWNoKGludGVyY2VwdG9yID0+IHtcclxuICAgIGNsaWVudC5hZGRSZXF1ZXN0SW50ZXJjZXB0b3IoaW50ZXJjZXB0b3IpO1xyXG4gIH0pO1xyXG5cclxuICByZXNwb25zZUludGVyY2VwdG9ycy5mb3JFYWNoKGludGVyY2VwdG9yID0+IHtcclxuICAgIGNsaWVudC5hZGRSZXNwb25zZUludGVyY2VwdG9yKGludGVyY2VwdG9yKTtcclxuICB9KTtcclxuXHJcbiAgZXJyb3JJbnRlcmNlcHRvcnMuZm9yRWFjaChpbnRlcmNlcHRvciA9PiB7XHJcbiAgICBjbGllbnQuYWRkRXJyb3JJbnRlcmNlcHRvcihpbnRlcmNlcHRvcik7XHJcbiAgfSk7XHJcblxyXG4gIHJldHVybiBjbGllbnQ7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRHbG9iYWxBcGlDbGllbnQoY29uZmlnPzogQXBpQ2xpZW50Q29uZmlnKTogQXBpQ2xpZW50IHtcclxuICBpZiAoIWdsb2JhbEFwaUNsaWVudCkge1xyXG4gICAgZ2xvYmFsQXBpQ2xpZW50ID0gY3JlYXRlQXBpQ2xpZW50KGNvbmZpZyk7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gZ2xvYmFsQXBpQ2xpZW50O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gc2V0R2xvYmFsQXBpQ2xpZW50KGNsaWVudDogQXBpQ2xpZW50KTogdm9pZCB7XHJcbiAgZ2xvYmFsQXBpQ2xpZW50ID0gY2xpZW50O1xyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gcmVzZXRHbG9iYWxBcGlDbGllbnQoKTogdm9pZCB7XHJcbiAgZ2xvYmFsQXBpQ2xpZW50ID0gbnVsbDtcclxufVxyXG4iLCAiLy8gQ2FuY2VsVG9rZW4gaW1wbGVtZW50YXRpb25cclxuZXhwb3J0IGNsYXNzIENhbmNlbFRva2VuIHtcclxuICBwcml2YXRlIGFib3J0Q29udHJvbGxlcjogQWJvcnRDb250cm9sbGVyO1xyXG4gIHByaXZhdGUgY2FuY2VsUHJvbWlzZTogUHJvbWlzZTx2b2lkPjtcclxuICBwcml2YXRlIGNhbmNlbFJlc29sdmU/OiAoKSA9PiB2b2lkO1xyXG5cclxuICBjb25zdHJ1Y3RvcigpIHtcclxuICAgIHRoaXMuYWJvcnRDb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xyXG4gICAgdGhpcy5jYW5jZWxQcm9taXNlID0gbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XHJcbiAgICAgIHRoaXMuY2FuY2VsUmVzb2x2ZSA9IHJlc29sdmU7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIGdldCBzaWduYWwoKTogQWJvcnRTaWduYWwge1xyXG4gICAgcmV0dXJuIHRoaXMuYWJvcnRDb250cm9sbGVyLnNpZ25hbDtcclxuICB9XHJcblxyXG4gIGNhbmNlbChyZWFzb24/OiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIHRoaXMuYWJvcnRDb250cm9sbGVyLmFib3J0KHJlYXNvbik7XHJcbiAgICB0aGlzLmNhbmNlbFJlc29sdmU/LigpO1xyXG4gIH1cclxuXHJcbiAgZ2V0IGlzQ2FuY2VsbGVkKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMuYWJvcnRDb250cm9sbGVyLnNpZ25hbC5hYm9ydGVkO1xyXG4gIH1cclxuXHJcbiAgdGhyb3dJZkNhbmNlbGxlZCgpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLmlzQ2FuY2VsbGVkKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcignUmVxdWVzdCBjYW5jZWxsZWQnKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHN0YXRpYyBzb3VyY2UoKTogeyB0b2tlbjogQ2FuY2VsVG9rZW47IGNhbmNlbDogKHJlYXNvbj86IHN0cmluZykgPT4gdm9pZCB9IHtcclxuICAgIGNvbnN0IHRva2VuID0gbmV3IENhbmNlbFRva2VuKCk7XHJcblxyXG4gICAgcmV0dXJuIHtcclxuICAgICAgdG9rZW4sXHJcbiAgICAgIGNhbmNlbDogKHJlYXNvbj86IHN0cmluZykgPT4gdG9rZW4uY2FuY2VsKHJlYXNvbiksXHJcbiAgICB9O1xyXG4gIH1cclxufVxyXG4iLCAiLy8gUmVhY3QgSG9va3Mgd2l0aCBBcGlSZXNwb25zZSBmb3JtYXRcclxuaW1wb3J0IHsgdXNlQ2FsbGJhY2sgfSBmcm9tICdyZWFjdCc7XHJcblxyXG5pbXBvcnQgdHlwZSB7IEFwaUVycm9yIH0gZnJvbSAnLi90eXBlcyc7XHJcblxyXG4vLyBFeHBvcnQgZmFjdG9yeSBtZXRob2RzIGFuZCB0eXBlc1xyXG5leHBvcnQge1xyXG4gIGNyZWF0ZUFwaUNsaWVudCxcclxuICBnZXRHbG9iYWxBcGlDbGllbnQsXHJcbiAgc2V0R2xvYmFsQXBpQ2xpZW50LFxyXG4gIHJlc2V0R2xvYmFsQXBpQ2xpZW50LFxyXG59IGZyb20gJy4vY3JlYXRlQXBpQ2xpZW50JztcclxuXHJcbmV4cG9ydCB0eXBlIHsgQXBpQ2xpZW50Q29uZmlnIH0gZnJvbSAnLi9jcmVhdGVBcGlDbGllbnQnO1xyXG5cclxuZXhwb3J0IHsgQXBpQ2xpZW50IH0gZnJvbSAnLi9BcGlDbGllbnQnO1xyXG5cclxuLy8gSGVscGVyIGhvb2sgZm9yIGZvcm0gdmFsaWRhdGlvbiBlcnJvcnNcclxuZXhwb3J0IGZ1bmN0aW9uIHVzZVZhbGlkYXRpb25FcnJvcnMoZXJyb3I6IEFwaUVycm9yIHwgbnVsbCkge1xyXG4gIGNvbnN0IGdldEZpZWxkRXJyb3IgPSB1c2VDYWxsYmFjayhcclxuICAgIChmaWVsZDogc3RyaW5nKTogc3RyaW5nIHwgbnVsbCA9PiB7XHJcbiAgICAgIGlmICghZXJyb3I/LmVycm9ycyB8fCAhZXJyb3IuZXJyb3JzW2ZpZWxkXSkgcmV0dXJuIG51bGw7XHJcblxyXG4gICAgICBjb25zdCBmaWVsZEVycm9yID0gZXJyb3IuZXJyb3JzW2ZpZWxkXTtcclxuXHJcbiAgICAgIGlmICh0eXBlb2YgZmllbGRFcnJvciA9PT0gJ3N0cmluZycpIHJldHVybiBmaWVsZEVycm9yO1xyXG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShmaWVsZEVycm9yKSkgcmV0dXJuIGZpZWxkRXJyb3JbMF07XHJcbiAgICAgIGlmICh0eXBlb2YgZmllbGRFcnJvciA9PT0gJ29iamVjdCcgJiYgJ21lc3NhZ2UnIGluIGZpZWxkRXJyb3IpIHtcclxuICAgICAgICByZXR1cm4gZmllbGRFcnJvci5tZXNzYWdlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICAgIH0sXHJcbiAgICBbZXJyb3JdXHJcbiAgKTtcclxuXHJcbiAgY29uc3QgaGFzRmllbGRFcnJvciA9IHVzZUNhbGxiYWNrKFxyXG4gICAgKGZpZWxkOiBzdHJpbmcpOiBib29sZWFuID0+IHtcclxuICAgICAgcmV0dXJuICEhZ2V0RmllbGRFcnJvcihmaWVsZCk7XHJcbiAgICB9LFxyXG4gICAgW2dldEZpZWxkRXJyb3JdXHJcbiAgKTtcclxuXHJcbiAgY29uc3QgZ2V0QWxsRXJyb3JzID0gdXNlQ2FsbGJhY2soKCk6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPT4ge1xyXG4gICAgaWYgKCFlcnJvcj8uZXJyb3JzKSByZXR1cm4ge307XHJcblxyXG4gICAgY29uc3QgcmVzdWx0OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XHJcblxyXG4gICAgT2JqZWN0LmVudHJpZXMoZXJyb3IuZXJyb3JzKS5mb3JFYWNoKChba2V5LCB2YWx1ZV0pID0+IHtcclxuICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICByZXN1bHRba2V5XSA9IHZhbHVlO1xyXG4gICAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSB7XHJcbiAgICAgICAgcmVzdWx0W2tleV0gPSB2YWx1ZS5qb2luKCcsICcpO1xyXG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgdmFsdWUgJiYgJ21lc3NhZ2UnIGluIHZhbHVlKSB7XHJcbiAgICAgICAgcmVzdWx0W2tleV0gPSB2YWx1ZS5tZXNzYWdlO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG4gIH0sIFtlcnJvcl0pO1xyXG5cclxuICByZXR1cm4ge1xyXG4gICAgZ2V0RmllbGRFcnJvcixcclxuICAgIGhhc0ZpZWxkRXJyb3IsXHJcbiAgICBnZXRBbGxFcnJvcnMsXHJcbiAgICBoYXNFcnJvcnM6IGVycm9yPy5lcnJvcnMsXHJcbiAgfTtcclxufVxyXG4iLCAiaW1wb3J0IHR5cGUgeyBQcm9wc1dpdGhDaGlsZHJlbiB9IGZyb20gJ3JlYWN0JztcblxudHlwZSBBdXRob3JpemVkVmlld1Byb3BzID0gUHJvcHNXaXRoQ2hpbGRyZW4gJiB7XG4gIHNob3c6IGJvb2xlYW47XG59O1xuXG5leHBvcnQgY29uc3QgQXV0aG9yaXplZFZpZXcgPSAoeyBjaGlsZHJlbiwgc2hvdyB9OiBBdXRob3JpemVkVmlld1Byb3BzKSA9PiB7XG4gIGlmICghc2hvdykgcmV0dXJuIDw+PC8+O1xuXG4gIHJldHVybiA8PntjaGlsZHJlbn08Lz47XG59O1xuIiwgImltcG9ydCB0eXBlIHsgQnV0dG9uUHJvcHMgfSBmcm9tICdAbXVpL21hdGVyaWFsJztcbmltcG9ydCB7IEJ1dHRvbiB9IGZyb20gJ0BtdWkvbWF0ZXJpYWwnO1xuaW1wb3J0IFJlYWN0IGZyb20gJ3JlYWN0JztcblxuZXhwb3J0IGNvbnN0IENhbmNlbEJ1dHRvbjogUmVhY3QuRkM8QnV0dG9uUHJvcHM+ID0gKHtcbiAgY2hpbGRyZW4gPSAnQ2FuY2VsJyxcbiAgdmFyaWFudCA9ICdvdXRsaW5lZCcsXG4gIHN4LFxuICAuLi5yZXN0XG59KSA9PiAoXG4gIDxCdXR0b24gdmFyaWFudD17dmFyaWFudH0gc3g9e3sgd2lkdGg6ICc2cmVtJywgLi4uc3ggfX0gey4uLnJlc3R9PlxuICAgIHtjaGlsZHJlbn1cbiAgPC9CdXR0b24+XG4pO1xuIiwgImltcG9ydCB0eXBlIHsgU3hQcm9wcyB9IGZyb20gJ0BtdWkvbWF0ZXJpYWwnO1xuaW1wb3J0IHsgQnV0dG9uIH0gZnJvbSAnQG11aS9tYXRlcmlhbCc7XG5cbi8qKlxuICogUHJvcHMgZm9yIHRoZSBDbGVhckJ1dHRvbiBjb21wb25lbnQuXG4gKlxuICogQHB1YmxpY1xuICovXG5pbnRlcmZhY2UgQ2xlYXJCdXR0b25Qcm9wcyB7XG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgaWYgYSBmb3JtIG9yIG9wZXJhdGlvbiBpcyBjdXJyZW50bHkgYmVpbmcgc3VibWl0dGVkLlxuICAgKiBXaGVuIHRydWUsIHRoZSBidXR0b24gaXMgZGlzYWJsZWQgdG8gcHJldmVudCBtdWx0aXBsZSBjbGVhciBhY3Rpb25zLlxuICAgKi9cbiAgaXNTdWJtaXR0aW5nOiBib29sZWFuO1xuICAvKipcbiAgICogQ2FsbGJhY2sgZnVuY3Rpb24gZXhlY3V0ZWQgd2hlbiB0aGUgY2xlYXIgYnV0dG9uIGlzIGNsaWNrZWQuXG4gICAqIFNob3VsZCBoYW5kbGUgdGhlIGNsZWFyaW5nIGxvZ2ljIChlLmcuLCBmb3JtIHJlc2V0LCBkYXRhIGNsZWFyaW5nKS5cbiAgICovXG4gIGhhbmRsZUNsZWFyOiAoKSA9PiB2b2lkO1xuICAvKipcbiAgICogT3B0aW9uYWwgTVVJIHN4IHByb3AgZm9yIGN1c3RvbSBzdHlsaW5nLlxuICAgKiBAZXhhbXBsZSB7IG10OiAyLCBjb2xvcjogJ3dhcm5pbmcubWFpbicgfVxuICAgKi9cbiAgc3g/OiBTeFByb3BzO1xuICAvKipcbiAgICogT3B0aW9uYWwgbG9jYWxTdG9yYWdlIGtleSB0byByZW1vdmUgd2hlbiBjbGVhcmluZy5cbiAgICogSWYgcHJvdmlkZWQsIHRoZSBjb3JyZXNwb25kaW5nIGxvY2FsU3RvcmFnZSBpdGVtIHdpbGwgYmUgcmVtb3ZlZCBvbiBjbGljay5cbiAgICogQGV4YW1wbGUgXCJ1c2VyLXByZWZlcmVuY2VzXCIgb3IgXCJmb3JtLWRhdGFcIlxuICAgKi9cbiAgc3RvcmVLZXk/OiBzdHJpbmc7XG59XG5cbi8qKlxuICogU3RhbmRhcmRpemVkIGNsZWFyIGJ1dHRvbiBjb21wb25lbnQgd2l0aCBsb2NhbFN0b3JhZ2UgaW50ZWdyYXRpb24uXG4gKlxuICogVGhpcyBjb21wb25lbnQgcHJvdmlkZXMgYSBjb25zaXN0ZW50IGNsZWFyIGJ1dHRvbiBpbXBsZW1lbnRhdGlvbiB0aGF0IGhhbmRsZXNcbiAqIGJvdGggY2FsbGJhY2sgZXhlY3V0aW9uIGFuZCBvcHRpb25hbCBsb2NhbFN0b3JhZ2UgY2xlYW51cC4gSXQgYXV0b21hdGljYWxseVxuICogZGlzYWJsZXMgZHVyaW5nIGZvcm0gc3VibWlzc2lvbnMgYW5kIGNhbiBjbGVhciBzdG9yZWQgZGF0YSB3aGVuIG5lZWRlZC5cbiAqXG4gKiBAZXhhbXBsZVxuICogQmFzaWMgdXNhZ2U6XG4gKiBgYGB0c3hcbiAqIDxDbGVhckJ1dHRvblxuICogICBpc1N1Ym1pdHRpbmc9e2lzTG9hZGluZ31cbiAqICAgaGFuZGxlQ2xlYXI9eygpID0+IGZvcm0ucmVzZXQoKX1cbiAqIC8+XG4gKiBgYGBcbiAqXG4gKiBAZXhhbXBsZVxuICogV2l0aCBsb2NhbFN0b3JhZ2UgY2xlYW51cDpcbiAqIGBgYHRzeFxuICogPENsZWFyQnV0dG9uXG4gKiAgIGlzU3VibWl0dGluZz17Zm9ybS5mb3JtU3RhdGUuaXNTdWJtaXR0aW5nfVxuICogICBoYW5kbGVDbGVhcj17KCkgPT4gc2V0RmlsdGVycyh7fSl9XG4gKiAgIHN0b3JlS2V5PVwidXNlci1maWx0ZXJzXCJcbiAqIC8+XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0gcHJvcHMgLSBDb21wb25lbnQgcHJvcHMgZm9yIGNsZWFyIGJ1dHRvbiBjb25maWd1cmF0aW9uXG4gKiBAcmV0dXJucyBNVUkgQnV0dG9uIGNvbXBvbmVudCBjb25maWd1cmVkIGFzIGEgY2xlYXIgYnV0dG9uXG4gKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3QgQ2xlYXJCdXR0b24gPSAoe1xuICBpc1N1Ym1pdHRpbmcsXG4gIGhhbmRsZUNsZWFyLFxuICBzeCxcbiAgc3RvcmVLZXksXG59OiBDbGVhckJ1dHRvblByb3BzKSA9PiB7XG4gIGNvbnN0IG9uQ2xpY2sgPSAoKSA9PiB7XG4gICAgaGFuZGxlQ2xlYXIoKTtcbiAgICBpZiAoc3RvcmVLZXkgIT0gbnVsbCkge1xuICAgICAgbG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0oc3RvcmVLZXkpO1xuICAgIH1cbiAgfTtcblxuICByZXR1cm4gKFxuICAgIDxCdXR0b25cbiAgICAgIHZhcmlhbnQ9XCJvdXRsaW5lZFwiXG4gICAgICBvbkNsaWNrPXtvbkNsaWNrfVxuICAgICAgZGlzYWJsZWQ9e2lzU3VibWl0dGluZ31cbiAgICAgIHN4PXtzeH1cbiAgICA+XG4gICAgICBDbGVhclxuICAgIDwvQnV0dG9uPlxuICApO1xufTtcbiIsICJpbXBvcnQgeyBDb250YWluZXIsIHR5cGUgU3hQcm9wcyB9IGZyb20gJ0BtdWkvbWF0ZXJpYWwnO1xyXG5pbXBvcnQgdHlwZSB7IFJlYWN0Tm9kZSB9IGZyb20gJ3JlYWN0JztcclxuXHJcbmludGVyZmFjZSBTaW1wbGVDb250YWluZXJQcm9wcyB7XHJcbiAgY2hpbGRyZW46IFJlYWN0Tm9kZTtcclxuICBjbGFzc05hbWU/OiBzdHJpbmc7XHJcbiAgc3g/OiBTeFByb3BzO1xyXG59XHJcblxyXG5leHBvcnQgY29uc3QgU2ltcGxlQ29udGFpbmVyID0gKHtcclxuICBjaGlsZHJlbixcclxuICBjbGFzc05hbWUsXHJcbiAgc3gsXHJcbn06IFNpbXBsZUNvbnRhaW5lclByb3BzKSA9PiAoXHJcbiAgPENvbnRhaW5lciBjbGFzc05hbWU9e2NsYXNzTmFtZX0gc3g9e3sgLi4uc3ggfX0+XHJcbiAgICB7Y2hpbGRyZW59XHJcbiAgPC9Db250YWluZXI+XHJcbik7XHJcbiIsICJpbXBvcnQgRmlsdGVyQWx0SWNvbiBmcm9tICdAbXVpL2ljb25zLW1hdGVyaWFsL0ZpbHRlckFsdCc7XG5pbXBvcnQgeyBMb2FkaW5nQnV0dG9uIH0gZnJvbSAnQG11aS9sYWInO1xuaW1wb3J0IHR5cGUgeyBTeFByb3BzIH0gZnJvbSAnQG11aS9tYXRlcmlhbCc7XG5pbXBvcnQgeyBCYWRnZSB9IGZyb20gJ0BtdWkvbWF0ZXJpYWwnO1xuXG4vKipcbiAqIFByb3BzIGZvciB0aGUgRmlsdGVyQnV0dG9uIGNvbXBvbmVudC5cbiAqXG4gKiBAcHVibGljXG4gKi9cbmludGVyZmFjZSBGaWx0ZXJCdXR0b25Qcm9wcyB7XG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgaWYgYSBmaWx0ZXIgb3BlcmF0aW9uIGlzIGN1cnJlbnRseSBiZWluZyBwcm9jZXNzZWQuXG4gICAqIFdoZW4gdHJ1ZSwgc2hvd3MgbG9hZGluZyBzcGlubmVyIGFuZCBkaXNhYmxlcyB0aGUgYnV0dG9uLlxuICAgKi9cbiAgaXNTdWJtaXR0aW5nOiBib29sZWFuO1xuICAvKipcbiAgICogQ29udHJvbHMgYnV0dG9uIHZpc2liaWxpdHkgYW5kIGVuYWJsZWQgc3RhdGUuXG4gICAqIFdoZW4gZmFsc2UsIHRoZSBidXR0b24gaXMgZGlzYWJsZWQuXG4gICAqIEBkZWZhdWx0VmFsdWUgdHJ1ZVxuICAgKi9cbiAgc2hvdz86IGJvb2xlYW47XG4gIC8qKlxuICAgKiBDdXN0b20gdGV4dCB0byBkaXNwbGF5IG9uIHRoZSBidXR0b24uXG4gICAqIEBkZWZhdWx0VmFsdWUgXCJGaWx0ZXJcIlxuICAgKiBAZXhhbXBsZSBcIkFwcGx5IEZpbHRlcnNcIiBvciBcIlNlYXJjaFwiXG4gICAqL1xuICB0aXRsZT86IHN0cmluZztcbiAgLyoqXG4gICAqIEN1c3RvbSBpY29uIHRvIGRpc3BsYXkgaW5zdGVhZCBvZiB0aGUgZGVmYXVsdCBmaWx0ZXIgaWNvbi5cbiAgICogQGV4YW1wbGUgPFNlYXJjaEljb24gLz5cbiAgICovXG4gIGljb24/OiBSZWFjdC5SZWFjdE5vZGU7XG4gIC8qKlxuICAgKiBPcHRpb25hbCBNVUkgc3ggcHJvcCBmb3IgY3VzdG9tIGJ1dHRvbiBzdHlsaW5nLlxuICAgKiBAZXhhbXBsZSB7IG10OiAyLCBtaW5XaWR0aDogMTIwIH1cbiAgICovXG4gIHN4PzogU3hQcm9wcztcbiAgLyoqXG4gICAqIE9wdGlvbmFsIE1VSSBzeCBwcm9wIGZvciBjdXN0b20gaWNvbiBzdHlsaW5nLlxuICAgKiBAZXhhbXBsZSB7IGNvbG9yOiAncHJpbWFyeS5tYWluJywgZm9udFNpemU6IDE4IH1cbiAgICovXG4gIGljb25TeD86IFN4UHJvcHM7XG59XG5cbi8qKlxuICogRmlsdGVyIGJ1dHRvbiBjb21wb25lbnQgd2l0aCBsb2FkaW5nIHN0YXRlcyBhbmQgY3VzdG9taXphYmxlIGFwcGVhcmFuY2UuXG4gKlxuICogVGhpcyBjb21wb25lbnQgcHJvdmlkZXMgYSBzdGFuZGFyZGl6ZWQgZmlsdGVyL3N1Ym1pdCBidXR0b24gd2l0aCBpbnRlZ3JhdGVkIGxvYWRpbmdcbiAqIHN0YXRlcywgaWNvbiBzdXBwb3J0LCBhbmQgYmFkZ2Ugc3R5bGluZy4gSXQncyBkZXNpZ25lZCBmb3IgdXNlIGluIGZpbHRlciBmb3Jtc1xuICogYW5kIHNlYXJjaCBpbnRlcmZhY2VzIHdoZXJlIHVzZXJzIG5lZWQgdG8gYXBwbHkgZmlsdGVyaW5nIGNyaXRlcmlhLlxuICpcbiAqIEBleGFtcGxlXG4gKiBCYXNpYyB1c2FnZTpcbiAqIGBgYHRzeFxuICogPEZpbHRlckJ1dHRvblxuICogICBpc1N1Ym1pdHRpbmc9e2lzTG9hZGluZ31cbiAqICAgc2hvdz17aGFzRmlsdGVyc31cbiAqIC8+XG4gKiBgYGBcbiAqXG4gKiBAZXhhbXBsZVxuICogQ3VzdG9tIHRpdGxlIGFuZCBpY29uOlxuICogYGBgdHN4XG4gKiA8RmlsdGVyQnV0dG9uXG4gKiAgIGlzU3VibWl0dGluZz17Zm9ybS5mb3JtU3RhdGUuaXNTdWJtaXR0aW5nfVxuICogICB0aXRsZT1cIkFwcGx5IFNlYXJjaFwiXG4gKiAgIGljb249ezxTZWFyY2hJY29uIC8+fVxuICogICBzaG93PXt0cnVlfVxuICogLz5cbiAqIGBgYFxuICpcbiAqIEBleGFtcGxlXG4gKiBXaXRoIGN1c3RvbSBzdHlsaW5nOlxuICogYGBgdHN4XG4gKiA8RmlsdGVyQnV0dG9uXG4gKiAgIGlzU3VibWl0dGluZz17aXNQcm9jZXNzaW5nfVxuICogICB0aXRsZT1cIkZpbHRlciBSZXN1bHRzXCJcbiAqICAgc3g9e3sgbWluV2lkdGg6IDE1MCwgbXQ6IDIgfX1cbiAqICAgaWNvblN4PXt7IGZvbnRTaXplOiAyMCB9fVxuICogLz5cbiAqIGBgYFxuICpcbiAqIEBwYXJhbSBwcm9wcyAtIENvbXBvbmVudCBwcm9wcyBmb3IgZmlsdGVyIGJ1dHRvbiBjb25maWd1cmF0aW9uXG4gKiBAcmV0dXJucyBNVUkgTG9hZGluZ0J1dHRvbiBjb21wb25lbnQgY29uZmlndXJlZCBhcyBhIGZpbHRlciBidXR0b25cbiAqXG4gKiBAcHVibGljXG4gKi9cbmV4cG9ydCBjb25zdCBGaWx0ZXJCdXR0b24gPSAoe1xuICBpc1N1Ym1pdHRpbmcsXG4gIHNob3csXG4gIHRpdGxlLFxuICBpY29uLFxuICBzeCxcbiAgaWNvblN4LFxufTogRmlsdGVyQnV0dG9uUHJvcHMpID0+IHtcbiAgcmV0dXJuIChcbiAgICA8TG9hZGluZ0J1dHRvblxuICAgICAgdHlwZT1cInN1Ym1pdFwiXG4gICAgICB2YXJpYW50PVwiY29udGFpbmVkXCJcbiAgICAgIGxvYWRpbmc9e2lzU3VibWl0dGluZ31cbiAgICAgIGRpc2FibGVkPXshc2hvd31cbiAgICAgIGRpc2FibGVSaXBwbGVcbiAgICAgIGNvbG9yPVwicHJpbWFyeVwiXG4gICAgICBzeD17e1xuICAgICAgICBkaXNwbGF5OiAnZmxleCcsXG4gICAgICAgIGFsaWduSXRlbXM6ICdjZW50ZXInLFxuICAgICAgICAuLi5zeCxcbiAgICAgIH19XG4gICAgICBzdGFydEljb249e1xuICAgICAgICA8QmFkZ2UgY29sb3I9XCJlcnJvclwiIHZhcmlhbnQ9XCJzdGFuZGFyZFwiPlxuICAgICAgICAgIHtpY29uID8gaWNvbiA6IDxGaWx0ZXJBbHRJY29uIHdpZHRoPVwiMjBcIiBoZWlnaHQ9XCIyMFwiIHN4PXtpY29uU3h9IC8+fVxuICAgICAgICA8L0JhZGdlPlxuICAgICAgfVxuICAgID5cbiAgICAgIHt0aXRsZT8udHJpbSgpID09PSAnJyB8fCAhdGl0bGUgPyAnRmlsdGVyJyA6IHRpdGxlfVxuICAgIDwvTG9hZGluZ0J1dHRvbj5cbiAgKTtcbn07XG4iLCAiaW1wb3J0IENoaXAgZnJvbSAnQG11aS9tYXRlcmlhbC9DaGlwJztcclxuaW1wb3J0IHsgbWVtbyB9IGZyb20gJ3JlYWN0JztcclxuXHJcbi8vIEluZGl2aWR1YWwgY2hpcCBjb21wb25lbnQgdG8gcHJldmVudCB1bm5lY2Vzc2FyeSByZXJlbmRlcnMgb2Ygc2libGluZyBjaGlwc1xyXG5leHBvcnQgY29uc3QgRmlsdGVyQ2hpcCA9IG1lbW8oXHJcbiAgKHtcclxuICAgIGZpZWxkS2V5LFxyXG4gICAgZmlsdGVyLFxyXG4gICAgb25EZWxldGUsXHJcbiAgfToge1xyXG4gICAgZmllbGRLZXk6IHN0cmluZztcclxuICAgIGZpbHRlcjogeyBMYWJlbDogc3RyaW5nOyBWYWx1ZTogdW5rbm93biB9O1xyXG4gICAgb25EZWxldGU/OiAoKSA9PiB2b2lkO1xyXG4gIH0pID0+IHtcclxuICAgIGNvbnN0IGhhc1ZhbHVlID1cclxuICAgICAgZmlsdGVyLlZhbHVlICE9PSBudWxsICYmXHJcbiAgICAgIGZpbHRlci5WYWx1ZSAhPT0gdW5kZWZpbmVkICYmXHJcbiAgICAgIGZpbHRlci5WYWx1ZSAhPT0gJyc7XHJcbiAgICBjb25zdCBsYWJlbCA9IGAke2ZpZWxkS2V5LnJlcGxhY2UoJ1BLJywgJycpfTogJHtmaWx0ZXIuTGFiZWx9YDtcclxuXHJcbiAgICByZXR1cm4gKFxyXG4gICAgICA8Q2hpcFxyXG4gICAgICAgIGtleT17ZmllbGRLZXl9XHJcbiAgICAgICAgbGFiZWw9e2xhYmVsfVxyXG4gICAgICAgIHZhcmlhbnQ9e2hhc1ZhbHVlID8gJ2ZpbGxlZCcgOiAnb3V0bGluZWQnfVxyXG4gICAgICAgIHNpemU9XCJzbWFsbFwiXHJcbiAgICAgICAgb25EZWxldGU9e2hhc1ZhbHVlID8gb25EZWxldGUgOiB1bmRlZmluZWR9XHJcbiAgICAgIC8+XHJcbiAgICApO1xyXG4gIH1cclxuKTtcclxuXHJcbkZpbHRlckNoaXAuZGlzcGxheU5hbWUgPSAnRmlsdGVyQ2hpcCc7XHJcbiIsICJpbXBvcnQgeyBDYXJkLCBDYXJkQ29udGVudCwgVHlwb2dyYXBoeSwgQm94IH0gZnJvbSAnQG11aS9tYXRlcmlhbCc7XHJcbmltcG9ydCB7IG1lbW8sIHVzZU1lbW8gfSBmcm9tICdyZWFjdCc7XHJcblxyXG5pbXBvcnQgeyBGaWx0ZXJDaGlwIH0gZnJvbSAnLi9GaWx0ZXJDaGlwJztcclxuXHJcbmludGVyZmFjZSBGaWx0ZXJEaXNwbGF5UHJvcHM8VEZpbHRlck1vZGVsPiB7XHJcbiAgZnJpZW5kbHlGaWx0ZXI6IFJlY29yZDxzdHJpbmcsIHsgTGFiZWw6IHN0cmluZzsgVmFsdWU6IHVua25vd24gfT47XHJcbiAgb25GcmllbmRseUZpbHRlckNoYW5nZT86IChmaWVsZEtleToga2V5b2YgVEZpbHRlck1vZGVsKSA9PiB2b2lkO1xyXG59XHJcblxyXG5leHBvcnQgY29uc3QgUHJvZ3JhbXNGaWx0ZXJEaXNwbGF5ID0gbWVtbyhcclxuICA8VEZpbHRlck1vZGVsIGV4dGVuZHMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4+KFxyXG4gICAgcHJvcHM6IEZpbHRlckRpc3BsYXlQcm9wczxURmlsdGVyTW9kZWw+XHJcbiAgKSA9PiB7XHJcbiAgICBjb25zdCB7IGZyaWVuZGx5RmlsdGVyLCBvbkZyaWVuZGx5RmlsdGVyQ2hhbmdlIH0gPSBwcm9wcztcclxuXHJcbiAgICAvLyBNZW1vaXplIGRlbGV0ZSBoYW5kbGVycyB0byBwcmV2ZW50IHJlY3JlYXRpb25cclxuICAgIGNvbnN0IGRlbGV0ZUhhbmRsZXJzID0gdXNlTWVtbygoKSA9PiB7XHJcbiAgICAgIGlmICghb25GcmllbmRseUZpbHRlckNoYW5nZSkgcmV0dXJuIHt9O1xyXG5cclxuICAgICAgY29uc3QgaGFuZGxlcnM6IFJlY29yZDxzdHJpbmcsICgpID0+IHZvaWQ+ID0ge307XHJcblxyXG4gICAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhmcmllbmRseUZpbHRlcikpIHtcclxuICAgICAgICBoYW5kbGVyc1trZXldID0gKCkgPT4gb25GcmllbmRseUZpbHRlckNoYW5nZShrZXkgYXMga2V5b2YgVEZpbHRlck1vZGVsKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIGhhbmRsZXJzO1xyXG4gICAgfSwgW29uRnJpZW5kbHlGaWx0ZXJDaGFuZ2UsIGZyaWVuZGx5RmlsdGVyXSk7XHJcblxyXG4gICAgLy8gTWVtb2l6ZSBjaGlwIGxpc3QgdG8gcHJldmVudCB1bm5lY2Vzc2FyeSByZWNhbGN1bGF0aW9uc1xyXG4gICAgY29uc3QgY2hpcExpc3QgPSB1c2VNZW1vKCgpID0+IHtcclxuICAgICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKGZyaWVuZGx5RmlsdGVyKS5tYXAoKFtrZXksIGZpbHRlcl0pID0+IChcclxuICAgICAgICA8RmlsdGVyQ2hpcFxyXG4gICAgICAgICAga2V5PXtrZXl9XHJcbiAgICAgICAgICBmaWVsZEtleT17a2V5fVxyXG4gICAgICAgICAgZmlsdGVyPXtmaWx0ZXIgYXMgeyBMYWJlbDogc3RyaW5nOyBWYWx1ZTogdW5rbm93biB9fVxyXG4gICAgICAgICAgb25EZWxldGU9e2RlbGV0ZUhhbmRsZXJzW2tleV19XHJcbiAgICAgICAgLz5cclxuICAgICAgKSk7XHJcbiAgICB9LCBbZnJpZW5kbHlGaWx0ZXIsIGRlbGV0ZUhhbmRsZXJzXSk7XHJcblxyXG4gICAgcmV0dXJuIChcclxuICAgICAgPENhcmQgc3g9e3sgbWI6IDIgfX0+XHJcbiAgICAgICAgPENhcmRDb250ZW50PlxyXG4gICAgICAgICAgPFR5cG9ncmFwaHkgdmFyaWFudD1cImg2XCIgZ3V0dGVyQm90dG9tPlxyXG4gICAgICAgICAgICBBY3RpdmUgRmlsdGVyc1xyXG4gICAgICAgICAgPC9UeXBvZ3JhcGh5PlxyXG4gICAgICAgICAgPEJveCBkaXNwbGF5PVwiZmxleFwiIGdhcD17MX0gZmxleFdyYXA9XCJ3cmFwXCI+XHJcbiAgICAgICAgICAgIHtjaGlwTGlzdH1cclxuICAgICAgICAgIDwvQm94PlxyXG4gICAgICAgIDwvQ2FyZENvbnRlbnQ+XHJcbiAgICAgIDwvQ2FyZD5cclxuICAgICk7XHJcbiAgfVxyXG4pO1xyXG5cclxuUHJvZ3JhbXNGaWx0ZXJEaXNwbGF5LmRpc3BsYXlOYW1lID0gJ0ZpbHRlckRpc3BsYXknO1xyXG5cclxuZXhwb3J0IHR5cGUgeyBGaWx0ZXJEaXNwbGF5UHJvcHMgfTtcclxuIiwgImltcG9ydCBNYW5hZ2VTZWFyY2hJY29uIGZyb20gJ0BtdWkvaWNvbnMtbWF0ZXJpYWwvTWFuYWdlU2VhcmNoJztcbmltcG9ydCB0eXBlIHsgU3hQcm9wcyB9IGZyb20gJ0BtdWkvbWF0ZXJpYWwnO1xuaW1wb3J0IHtcbiAgQm94LFxuICBDYXJkLFxuICBDYXJkQ29udGVudCxcbiAgQ2FyZEhlYWRlcixcbiAgRGl2aWRlcixcbiAgR3JpZCxcbiAgVHlwb2dyYXBoeSxcbiAgdXNlVGhlbWUsXG59IGZyb20gJ0BtdWkvbWF0ZXJpYWwnO1xuaW1wb3J0IHR5cGUgeyBQcm9wc1dpdGhDaGlsZHJlbiwgUmVhY3ROb2RlIH0gZnJvbSAncmVhY3QnO1xuXG4vKipcbiAqIFByb3BzIGZvciB0aGUgRmlsdGVyV3JhcHBlciBjb21wb25lbnQuXG4gKlxuICogQHB1YmxpY1xuICovXG50eXBlIEZpbHRlcldyYXBwZXJQcm9wcyA9IFByb3BzV2l0aENoaWxkcmVuPHtcbiAgLyoqXG4gICAqIFRpdGxlIHRleHQgZGlzcGxheWVkIGluIHRoZSBjYXJkIGhlYWRlci5cbiAgICogQGRlZmF1bHRWYWx1ZSBcIkZpbHRlclwiXG4gICAqIEBleGFtcGxlIFwiU2VhcmNoIENyaXRlcmlhXCIgb3IgXCJBZHZhbmNlZCBGaWx0ZXJzXCJcbiAgICovXG4gIHRpdGxlPzogc3RyaW5nO1xuICAvKipcbiAgICogTnVtYmVyIG9mIGFjdGl2ZSBmaWx0ZXJzIHRvIGRpc3BsYXkgaW4gdGhlIGhlYWRlci5cbiAgICogT25seSBzaG93biB3aGVuIHNob3dDb3VudCBpcyB0cnVlLlxuICAgKiBAZXhhbXBsZSAzIGZvciBcIkZpbHRlciAoMylcIlxuICAgKi9cbiAgZmlsdGVyQ291bnQ/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBPcHRpb25hbCBNVUkgc3ggcHJvcCBmb3IgY3VzdG9tIGNhcmQgc3R5bGluZy5cbiAgICogQGV4YW1wbGUgeyBtdDogMiwgYm94U2hhZG93OiAyIH1cbiAgICovXG4gIGNhcmRTeD86IFN4UHJvcHM7XG4gIC8qKlxuICAgKiBPcHRpb25hbCBNVUkgc3ggcHJvcCBmb3IgY3VzdG9tIHRpdGxlIHRleHQgc3R5bGluZy5cbiAgICogQGV4YW1wbGUgeyBmb250U2l6ZTogMTgsIGZvbnRXZWlnaHQ6ICdib2xkJyB9XG4gICAqL1xuICB0ZXh0U3g/OiBTeFByb3BzO1xuICAvKipcbiAgICogQ3VzdG9tIGljb24gdG8gZGlzcGxheSBpbnN0ZWFkIG9mIHRoZSBkZWZhdWx0IHNlYXJjaCBpY29uLlxuICAgKiBAZXhhbXBsZSA8RmlsdGVyTGlzdEljb24gLz5cbiAgICovXG4gIGljb24/OiBSZWFjdE5vZGU7XG4gIC8qKlxuICAgKiBPcHRpb25hbCBNVUkgc3ggcHJvcCBmb3IgY3VzdG9tIGljb24gc3R5bGluZy5cbiAgICogQGV4YW1wbGUgeyBjb2xvcjogJ3NlY29uZGFyeS5tYWluJywgZm9udFNpemU6IDI0IH1cbiAgICovXG4gIGljb25TeD86IFN4UHJvcHM7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGRpc3BsYXkgdGhlIGZpbHRlciBjb3VudCBpbiB0aGUgaGVhZGVyLlxuICAgKiBAZGVmYXVsdFZhbHVlIGZhbHNlXG4gICAqL1xuICBzaG93Q291bnQ/OiBib29sZWFuO1xufT47XG5cbi8qKlxuICogQ2FyZC1iYXNlZCB3cmFwcGVyIGNvbXBvbmVudCBmb3Igb3JnYW5pemluZyBmaWx0ZXIgY29udHJvbHMgYW5kIGZvcm0gZWxlbWVudHMuXG4gKlxuICogVGhpcyBjb21wb25lbnQgcHJvdmlkZXMgYSBjb25zaXN0ZW50IGxheW91dCBmb3IgZmlsdGVyIGludGVyZmFjZXMgd2l0aCBhIGhlYWRlcixcbiAqIG9wdGlvbmFsIGZpbHRlciBjb3VudCBkaXNwbGF5LCBhbmQgYSBncmlkLWJhc2VkIGNvbnRlbnQgYXJlYS4gSXQncyBkZXNpZ25lZCB0b1xuICogY29udGFpbiBmb3JtIGNvbnRyb2xzIGFuZCBmaWx0ZXIgZWxlbWVudHMgaW4gYSB2aXN1YWxseSBvcmdhbml6ZWQgbWFubmVyLlxuICpcbiAqIEBleGFtcGxlXG4gKiBCYXNpYyB1c2FnZTpcbiAqIGBgYHRzeFxuICogPEZpbHRlcldyYXBwZXI+XG4gKiAgIDxHcmlkIGl0ZW0geHM9ezEyfSBtZD17Nn0+XG4gKiAgICAgPFRleHRGaWVsZCBsYWJlbD1cIlNlYXJjaFwiIC8+XG4gKiAgIDwvR3JpZD5cbiAqICAgPEdyaWQgaXRlbSB4cz17MTJ9IG1kPXs2fT5cbiAqICAgICA8U2VsZWN0IGxhYmVsPVwiQ2F0ZWdvcnlcIiAvPlxuICogICA8L0dyaWQ+XG4gKiA8L0ZpbHRlcldyYXBwZXI+XG4gKiBgYGBcbiAqXG4gKiBAZXhhbXBsZVxuICogV2l0aCBjdXN0b20gdGl0bGUgYW5kIGNvdW50OlxuICogYGBgdHN4XG4gKiA8RmlsdGVyV3JhcHBlclxuICogICB0aXRsZT1cIkFkdmFuY2VkIFNlYXJjaFwiXG4gKiAgIGZpbHRlckNvdW50PXthY3RpdmVGaWx0ZXJzLmxlbmd0aH1cbiAqICAgc2hvd0NvdW50PXt0cnVlfVxuICogPlxuICogICB7ZmlsdGVyQ29udHJvbHN9XG4gKiA8L0ZpbHRlcldyYXBwZXI+XG4gKiBgYGBcbiAqXG4gKiBAZXhhbXBsZVxuICogV2l0aCBjdXN0b20gc3R5bGluZzpcbiAqIGBgYHRzeFxuICogPEZpbHRlcldyYXBwZXJcbiAqICAgdGl0bGU9XCJQcm9kdWN0IEZpbHRlcnNcIlxuICogICBpY29uPXs8RmlsdGVyTGlzdEljb24gLz59XG4gKiAgIGNhcmRTeD17eyBtdDogMywgYm9yZGVyUmFkaXVzOiAyIH19XG4gKiAgIHRleHRTeD17eyBjb2xvcjogJ3NlY29uZGFyeS5tYWluJyB9fVxuICogPlxuICogICB7Y2hpbGRyZW59XG4gKiA8L0ZpbHRlcldyYXBwZXI+XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0gcHJvcHMgLSBDb21wb25lbnQgcHJvcHMgaW5jbHVkaW5nIGNoaWxkcmVuIGFuZCBzdHlsaW5nIG9wdGlvbnNcbiAqIEByZXR1cm5zIE1VSSBDYXJkIGNvbXBvbmVudCB3aXRoIHN0cnVjdHVyZWQgZmlsdGVyIGxheW91dFxuICpcbiAqIEBwdWJsaWNcbiAqL1xuZXhwb3J0IGNvbnN0IEZpbHRlcldyYXBwZXIgPSAoe1xuICBjaGlsZHJlbixcbiAgdGl0bGUsXG4gIGZpbHRlckNvdW50LFxuICBjYXJkU3gsXG4gIHRleHRTeCxcbiAgaWNvbixcbiAgaWNvblN4LFxuICBzaG93Q291bnQsXG59OiBGaWx0ZXJXcmFwcGVyUHJvcHMpID0+IHtcbiAgY29uc3QgdGhlbWUgPSB1c2VUaGVtZSgpO1xuXG4gIHJldHVybiAoXG4gICAgPENhcmRcbiAgICAgIHN4PXt7XG4gICAgICAgIHBvc2l0aW9uOiAncmVsYXRpdmUnLFxuICAgICAgICBib3JkZXJSYWRpdXM6ICcwcHgnLFxuICAgICAgICBtYjogMixcbiAgICAgICAgLi4uY2FyZFN4LFxuICAgICAgfX1cbiAgICA+XG4gICAgICA8Q2FyZEhlYWRlclxuICAgICAgICBzeD17e1xuICAgICAgICAgIGRpc3BsYXk6ICdmbGV4JyxcbiAgICAgICAgICBmbGV4V3JhcDogJ3dyYXAnLFxuICAgICAgICAgIHA6ICcxcmVtJyxcbiAgICAgICAgICAnLk11aUNhcmRIZWFkZXItYWN0aW9uJzoge1xuICAgICAgICAgICAgbWFyZ2luOiAwLFxuICAgICAgICAgICAgYWxpZ25TZWxmOiAnY2VudGVyJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGFsaWduSXRlbXM6ICdjZW50ZXInLFxuICAgICAgICB9fVxuICAgICAgICB0aXRsZT17XG4gICAgICAgICAgPEJveCBzeD17eyBkaXNwbGF5OiAnZmxleCcsIGFsaWduSXRlbXM6ICdjZW50ZXInLCBnYXA6IDAuNSB9fT5cbiAgICAgICAgICAgIHtpY29uID8gKFxuICAgICAgICAgICAgICBpY29uXG4gICAgICAgICAgICApIDogKFxuICAgICAgICAgICAgICA8TWFuYWdlU2VhcmNoSWNvblxuICAgICAgICAgICAgICAgIHN4PXt7XG4gICAgICAgICAgICAgICAgICBoZWlnaHQ6ICcyLjVyZW0nLFxuICAgICAgICAgICAgICAgICAgY29sb3I6IHRoZW1lLnBhbGV0dGUucHJpbWFyeS5tYWluLFxuICAgICAgICAgICAgICAgICAgLi4uaWNvblN4LFxuICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICApfVxuICAgICAgICAgICAgPFR5cG9ncmFwaHlcbiAgICAgICAgICAgICAgdmFyaWFudD1cImg1XCJcbiAgICAgICAgICAgICAgc3g9e3tcbiAgICAgICAgICAgICAgICBmb250V2VpZ2h0OiAnYm9sZCcsXG4gICAgICAgICAgICAgICAgY29sb3I6IHRoZW1lLnBhbGV0dGUucHJpbWFyeS5tYWluLFxuICAgICAgICAgICAgICAgIC4uLnRleHRTeCxcbiAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAge3RpdGxlID8gdGl0bGUgOiAnRmlsdGVyJ317JyAnfVxuICAgICAgICAgICAgICB7c2hvd0NvdW50ID8gYCgke2ZpbHRlckNvdW50ID8gZmlsdGVyQ291bnQgOiAwfSlgIDogPD48Lz59XG4gICAgICAgICAgICA8L1R5cG9ncmFwaHk+XG4gICAgICAgICAgPC9Cb3g+XG4gICAgICAgIH1cbiAgICAgID48L0NhcmRIZWFkZXI+XG4gICAgICA8RGl2aWRlciAvPlxuICAgICAgPENhcmRDb250ZW50IHN4PXt7IHB5OiAyIH19PlxuICAgICAgICA8R3JpZCBjb250YWluZXIgc3BhY2luZz17Mn0+XG4gICAgICAgICAge2NoaWxkcmVufVxuICAgICAgICA8L0dyaWQ+XG4gICAgICA8L0NhcmRDb250ZW50PlxuICAgIDwvQ2FyZD5cbiAgKTtcbn07XG4iLCAiLy8gY29yZS9jb21wb25lbnRzL0Zvb3Rlci9pbmRleC50c3hcclxuaW1wb3J0IHsgQm94LCBUeXBvZ3JhcGh5IH0gZnJvbSAnQG11aS9tYXRlcmlhbCc7XHJcbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcblxyXG5leHBvcnQgY29uc3QgRm9vdGVyOiBSZWFjdC5GQyA9ICgpID0+IHtcclxuICBjb25zdCBjdXJyZW50WWVhciA9IG5ldyBEYXRlKCkuZ2V0RnVsbFllYXIoKTtcclxuXHJcbiAgcmV0dXJuIChcclxuICAgIDxCb3hcclxuICAgICAgY29tcG9uZW50PVwiZm9vdGVyXCJcclxuICAgICAgc3g9e3tcclxuICAgICAgICBweTogMixcclxuICAgICAgICBweDogNCxcclxuICAgICAgICBtdDogJ2F1dG8nLFxyXG4gICAgICAgIGJhY2tncm91bmRDb2xvcjogdGhlbWUgPT5cclxuICAgICAgICAgIHRoZW1lLnBhbGV0dGUubW9kZSA9PT0gJ2xpZ2h0J1xyXG4gICAgICAgICAgICA/IHRoZW1lLnBhbGV0dGUuZ3JleVsyMDBdXHJcbiAgICAgICAgICAgIDogdGhlbWUucGFsZXR0ZS5ncmV5WzgwMF0sXHJcbiAgICAgIH19XHJcbiAgICA+XHJcbiAgICAgIDxUeXBvZ3JhcGh5IHZhcmlhbnQ9XCJib2R5MlwiIGNvbG9yPVwidGV4dC5zZWNvbmRhcnlcIiBhbGlnbj1cImNlbnRlclwiPlxyXG4gICAgICAgIHtgXHUwMEE5IENvcHlyaWdodCAke2N1cnJlbnRZZWFyfSBHTi4gQWxsIHJpZ2h0cyByZXNlcnZlZCBieSBQYXJ1bCBVbml2ZXJzaXR5LmB9XHJcbiAgICAgIDwvVHlwb2dyYXBoeT5cclxuICAgIDwvQm94PlxyXG4gICk7XHJcbn07XHJcbiIsICJpbXBvcnQgdHlwZSB7IFN4UHJvcHMgfSBmcm9tICdAbXVpL21hdGVyaWFsJztcbmltcG9ydCB7IEdyaWQsIFRvb2x0aXAsIFR5cG9ncmFwaHkgfSBmcm9tICdAbXVpL21hdGVyaWFsJztcblxuLyoqXG4gKiBQcm9wcyBmb3IgdGhlIExhYmVsVGV4dCBjb21wb25lbnQuXG4gKlxuICogQHB1YmxpY1xuICovXG5pbnRlcmZhY2UgTGFiZWxUZXh0UHJvcHMge1xuICAvKipcbiAgICogTGFiZWwgdGV4dCB0byBkaXNwbGF5IG9uIHRoZSBsZWZ0IHNpZGUuXG4gICAqIEBleGFtcGxlIFwiTmFtZVwiIG9yIFwiRW1haWwgQWRkcmVzc1wiXG4gICAqL1xuICBsYWJlbDogc3RyaW5nO1xuICAvKipcbiAgICogVmFsdWUgY29udGVudCB0byBkaXNwbGF5IG9uIHRoZSByaWdodCBzaWRlLlxuICAgKiBDYW4gYmUgdGV4dCwgbnVtYmVycywgb3IgUmVhY3QgZWxlbWVudHMuXG4gICAqIEBleGFtcGxlIFwiSm9obiBEb2VcIiBvciA8TGluaz5WaWV3IERldGFpbHM8L0xpbms+XG4gICAqL1xuICB2YWx1ZTogUmVhY3QuUmVhY3ROb2RlO1xuICAvKipcbiAgICogQ3VzdG9tIGdyaWQgc2l6aW5nIGZvciBsYWJlbCBhbmQgdmFsdWUgc2VjdGlvbnMuXG4gICAqIEBkZWZhdWx0VmFsdWUgeyBsYWJlbFNpemU6IHsgeHM6IDYsIHNtOiA2LCBtZDogNiB9LCB2YWx1ZVNpemU6IHsgeHM6IDEyLCBzbTogNiwgbWQ6IDYgfSB9XG4gICAqL1xuICBncmlkU2l6ZT86IHtcbiAgICAvKiogR3JpZCBzaXplIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSBsYWJlbCBzZWN0aW9uICovXG4gICAgbGFiZWxTaXplOiB7IHhzOiBudW1iZXI7IHNtOiBudW1iZXI7IG1kOiBudW1iZXIgfTtcbiAgICAvKiogR3JpZCBzaXplIGNvbmZpZ3VyYXRpb24gZm9yIHRoZSB2YWx1ZSBzZWN0aW9uICovXG4gICAgdmFsdWVTaXplOiB7IHhzOiBudW1iZXI7IHNtOiBudW1iZXI7IG1kOiBudW1iZXIgfTtcbiAgfTtcbiAgLyoqXG4gICAqIEdyaWQgc2l6ZSBjb25maWd1cmF0aW9uIGZvciB0aGUgZW50aXJlIGNvbnRhaW5lci5cbiAgICogQGRlZmF1bHRWYWx1ZSB7IHhzOiAxMiwgc206IDYsIG1kOiA2IH1cbiAgICovXG4gIGNvbnRhaW5lclNpemU/OiB7IHhzOiBudW1iZXI7IHNtOiBudW1iZXI7IG1kOiBudW1iZXIgfTtcbiAgLyoqXG4gICAqIE9wdGlvbmFsIE1VSSBzeCBwcm9wIGZvciBjdXN0b20gbGFiZWwgc3R5bGluZy5cbiAgICogQGV4YW1wbGUgeyBmb250V2VpZ2h0OiAnYm9sZCcsIGNvbG9yOiAncHJpbWFyeS5tYWluJyB9XG4gICAqL1xuICBsYWJlbFN4PzogU3hQcm9wcztcbiAgLyoqXG4gICAqIE9wdGlvbmFsIE1VSSBzeCBwcm9wIGZvciBjdXN0b20gdmFsdWUgc3R5bGluZy5cbiAgICogQGV4YW1wbGUgeyBjb2xvcjogJ3RleHQuc2Vjb25kYXJ5JywgZm9udFN0eWxlOiAnaXRhbGljJyB9XG4gICAqL1xuICB2YWx1ZVN4PzogU3hQcm9wcztcbn1cblxuLyoqXG4gKiBSZXNwb25zaXZlIGxhYmVsLXZhbHVlIGRpc3BsYXkgY29tcG9uZW50IHdpdGggaG92ZXIgZWZmZWN0cyBhbmQgdGV4dCB0cnVuY2F0aW9uLlxuICpcbiAqIFRoaXMgY29tcG9uZW50IGNyZWF0ZXMgYSBjb25zaXN0ZW50IGxhYmVsLXZhbHVlIHBhaXIgbGF5b3V0IHRoYXQgYWRhcHRzIHRvIGRpZmZlcmVudFxuICogc2NyZWVuIHNpemVzLiBJdCBpbmNsdWRlcyBob3ZlciBlZmZlY3RzLCB0ZXh0IHRydW5jYXRpb24gd2l0aCB0b29sdGlwcywgYW5kXG4gKiBjdXN0b21pemFibGUgZ3JpZCBzaXppbmcgZm9yIGZsZXhpYmxlIGxheW91dHMuXG4gKlxuICogQGV4YW1wbGVcbiAqIEJhc2ljIHVzYWdlOlxuICogYGBgdHN4XG4gKiA8TGFiZWxUZXh0XG4gKiAgIGxhYmVsPVwiRnVsbCBOYW1lXCJcbiAqICAgdmFsdWU9XCJKb2huIERvZVwiXG4gKiAvPlxuICogYGBgXG4gKlxuICogQGV4YW1wbGVcbiAqIFdpdGggUmVhY3QgZWxlbWVudCB2YWx1ZTpcbiAqIGBgYHRzeFxuICogPExhYmVsVGV4dFxuICogICBsYWJlbD1cIlByb2ZpbGVcIlxuICogICB2YWx1ZT17PExpbmsgaHJlZj1cIi9wcm9maWxlXCI+VmlldyBQcm9maWxlPC9MaW5rPn1cbiAqIC8+XG4gKiBgYGBcbiAqXG4gKiBAZXhhbXBsZVxuICogQ3VzdG9tIGdyaWQgc2l6aW5nOlxuICogYGBgdHN4XG4gKiA8TGFiZWxUZXh0XG4gKiAgIGxhYmVsPVwiRGVzY3JpcHRpb25cIlxuICogICB2YWx1ZT17bG9uZ0Rlc2NyaXB0aW9ufVxuICogICBncmlkU2l6ZT17e1xuICogICAgIGxhYmVsU2l6ZTogeyB4czogMTIsIHNtOiAzLCBtZDogMiB9LFxuICogICAgIHZhbHVlU2l6ZTogeyB4czogMTIsIHNtOiA5LCBtZDogMTAgfVxuICogICB9fVxuICogICBjb250YWluZXJTaXplPXt7IHhzOiAxMiwgc206IDEyLCBtZDogMTIgfX1cbiAqIC8+XG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0gcHJvcHMgLSBDb21wb25lbnQgcHJvcHMgZm9yIGxhYmVsLXZhbHVlIGNvbmZpZ3VyYXRpb25cbiAqIEByZXR1cm5zIEdyaWQtYmFzZWQgbGF5b3V0IHdpdGggbGFiZWwgYW5kIHZhbHVlIHNlY3Rpb25zXG4gKlxuICogQHB1YmxpY1xuICovXG5leHBvcnQgY29uc3QgTGFiZWxUZXh0ID0gKHtcbiAgbGFiZWwsXG4gIHZhbHVlLFxuICBncmlkU2l6ZSxcbiAgY29udGFpbmVyU2l6ZSxcbiAgbGFiZWxTeCxcbiAgdmFsdWVTeCxcbn06IExhYmVsVGV4dFByb3BzKSA9PiB7XG4gIGNvbnN0IGRlZmF1bHRHcmlkU2l6ZSA9IHtcbiAgICBsYWJlbFNpemU6IHsgeHM6IDYsIHNtOiA2LCBtZDogNiB9LFxuICAgIHZhbHVlU2l6ZTogeyB4czogMTIsIHNtOiA2LCBtZDogNiB9LFxuICB9O1xuICBjb25zdCBkZWZhdWx0Q29udGFpbmVyU2l6ZSA9IHsgeHM6IDEyLCBzbTogNiwgbWQ6IDYgfTtcbiAgY29uc3Qgc2l6ZSA9IGdyaWRTaXplIHx8IGRlZmF1bHRHcmlkU2l6ZTtcbiAgY29uc3QgY29udGFpbmVyID0gY29udGFpbmVyU2l6ZSB8fCBkZWZhdWx0Q29udGFpbmVyU2l6ZTtcblxuICByZXR1cm4gKFxuICAgIDxHcmlkXG4gICAgICBzaXplPXtjb250YWluZXJ9XG4gICAgICBzeD17e1xuICAgICAgICBkaXNwbGF5OiAnZmxleCcsXG4gICAgICAgIGZsZXhEaXJlY3Rpb246IHsgeHM6ICdjb2x1bW4nLCBzbTogJ3JvdycsIG1kOiAncm93JyB9LFxuICAgICAgICAnJjpob3Zlcic6IHsgYmdjb2xvcjogJyNlZmVmZWYnLCBvdmVyZmxvdzogJ2hpZGRlbicgfSxcbiAgICAgIH19XG4gICAgPlxuICAgICAgPEdyaWRcbiAgICAgICAgc2l6ZT17c2l6ZS5sYWJlbFNpemV9XG4gICAgICAgIHN4PXt7XG4gICAgICAgICAgcGFkZGluZzogJzVweCcsXG4gICAgICAgICAgZm9udFNpemU6ICcxNHB4JyxcbiAgICAgICAgICB0ZXh0QWxpZ246IHsgeHM6ICdsZWZ0Jywgc206ICdyaWdodCcsIG1kOiAncmlnaHQnIH0sXG4gICAgICAgICAgLi4ubGFiZWxTeCxcbiAgICAgICAgfX1cbiAgICAgID5cbiAgICAgICAge2xhYmVsfSA6XG4gICAgICA8L0dyaWQ+XG4gICAgICA8R3JpZFxuICAgICAgICBzaXplPXtzaXplLnZhbHVlU2l6ZX1cbiAgICAgICAgc3g9e3sgcGFkZGluZzogJzVweCcsIGRpc3BsYXk6ICdmbGV4JywgZmxleFdyYXA6ICd3cmFwJyB9fVxuICAgICAgPlxuICAgICAgICA8VG9vbHRpcCB0aXRsZT17dmFsdWV9IGFycm93PlxuICAgICAgICAgIDxUeXBvZ3JhcGh5XG4gICAgICAgICAgICBzeD17e1xuICAgICAgICAgICAgICBmb250U2l6ZTogJzE0cHgnLFxuICAgICAgICAgICAgICB3b3JkQnJlYWs6ICdicmVhay13b3JkJyxcbiAgICAgICAgICAgICAgb3ZlcmZsb3c6ICdoaWRkZW4nLFxuICAgICAgICAgICAgICBkaXNwbGF5OiAnLXdlYmtpdC1ib3gnLFxuICAgICAgICAgICAgICB0ZXh0T3ZlcmZsb3c6ICdlbGxpcHNpcycsXG4gICAgICAgICAgICAgIFdlYmtpdExpbmVDbGFtcDogMixcbiAgICAgICAgICAgICAgV2Via2l0Qm94T3JpZW50OiAndmVydGljYWwnLFxuICAgICAgICAgICAgICAuLi52YWx1ZVN4LFxuICAgICAgICAgICAgICBjb2xvcjogJyMwNzhkZWUnLFxuICAgICAgICAgICAgfX1cbiAgICAgICAgICA+XG4gICAgICAgICAgICB7dmFsdWUgPyB2YWx1ZSA6ICctJ31cbiAgICAgICAgICA8L1R5cG9ncmFwaHk+XG4gICAgICAgIDwvVG9vbHRpcD5cbiAgICAgIDwvR3JpZD5cbiAgICA8L0dyaWQ+XG4gICk7XG59O1xuIiwgImltcG9ydCB0eXBlIHsgUHJvcHNXaXRoQ2hpbGRyZW4gfSBmcm9tICdyZWFjdCc7XHJcblxyXG5pbnRlcmZhY2UgUmVuZGVySWZQcm9wcyB7XHJcbiAgc2hvdzogYm9vbGVhbjtcclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IFJlbmRlcklmID0gKHtcclxuICBzaG93LFxyXG4gIGNoaWxkcmVuLFxyXG59OiBQcm9wc1dpdGhDaGlsZHJlbjxSZW5kZXJJZlByb3BzPikgPT4ge1xyXG4gIHJldHVybiBzaG93ID8gPD57Y2hpbGRyZW59PC8+IDogbnVsbDtcclxufTtcclxuIiwgImltcG9ydCB0eXBlIHsgU3hQcm9wcywgVGhlbWUgfSBmcm9tICdAbXVpL21hdGVyaWFsJztcclxuaW1wb3J0IHsgQm94LCBEaXZpZGVyLCBHcmlkLCBTdGFjaywgVHlwb2dyYXBoeSB9IGZyb20gJ0BtdWkvbWF0ZXJpYWwnO1xyXG5pbXBvcnQgdHlwZSB7IFByb3BzV2l0aENoaWxkcmVuLCBSZWFjdE5vZGUgfSBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCB7IG1lbW8sIHVzZU1lbW8gfSBmcm9tICdyZWFjdCc7XHJcblxyXG4vLyBTZWN0aW9uIGJveCBjb25maWd1cmF0aW9uXHJcbmV4cG9ydCBpbnRlcmZhY2UgU2VjdGlvbkJveFByb3BzIGV4dGVuZHMgUHJvcHNXaXRoQ2hpbGRyZW4ge1xyXG4gIHRpdGxlOiBzdHJpbmc7XHJcbiAgc3BhY2luZz86IG51bWJlcjtcclxuICBjb250YWluZXJTeD86IFN4UHJvcHM8VGhlbWU+O1xyXG4gIHRpdGxlU3g/OiBTeFByb3BzPFRoZW1lPjtcclxuICB2YXJpYW50PzogJ2RlZmF1bHQnIHwgJ2Zvcm0nIHwgJ2luZm8nIHwgJ3dhcm5pbmcnIHwgJ2Vycm9yJztcclxuICBpY29uPzogUmVhY3ROb2RlO1xyXG4gIGFjdGlvbnM/OiBSZWFjdE5vZGU7XHJcbiAgY29sbGFwc2libGU/OiBib29sZWFuO1xyXG4gIGRlZmF1bHRFeHBhbmRlZD86IGJvb2xlYW47XHJcbn1cclxuXHJcbi8vIFRoZW1lIGNvbmZpZ3VyYXRpb24gZm9yIHNlY3Rpb24gdmFyaWFudHNcclxuY29uc3QgZ2V0U2VjdGlvblRoZW1lID0gKHZhcmlhbnQ6IFNlY3Rpb25Cb3hQcm9wc1sndmFyaWFudCddID0gJ2RlZmF1bHQnKSA9PiB7XHJcbiAgY29uc3QgdGhlbWVzID0ge1xyXG4gICAgZGVmYXVsdDoge1xyXG4gICAgICBiZ2NvbG9yOiAnI2ZhZWJkNycsXHJcbiAgICAgIGNvbG9yOiAnIzkyNWQyMScsXHJcbiAgICB9LFxyXG4gICAgZm9ybToge1xyXG4gICAgICBiZ2NvbG9yOiAnI2NkY2VkMScsXHJcbiAgICAgIGNvbG9yOiAnYmxhY2snLFxyXG4gICAgfSxcclxuICAgIGluZm86IHtcclxuICAgICAgYmdjb2xvcjogJyNlM2YyZmQnLFxyXG4gICAgICBjb2xvcjogJyMxOTc2ZDInLFxyXG4gICAgfSxcclxuICAgIHdhcm5pbmc6IHtcclxuICAgICAgYmdjb2xvcjogJyNmZmYzZTAnLFxyXG4gICAgICBjb2xvcjogJyNmNTdjMDAnLFxyXG4gICAgfSxcclxuICAgIGVycm9yOiB7XHJcbiAgICAgIGJnY29sb3I6ICcjZmZlYmVlJyxcclxuICAgICAgY29sb3I6ICcjZDMyZjJmJyxcclxuICAgIH0sXHJcbiAgfTtcclxuXHJcbiAgcmV0dXJuIHRoZW1lc1t2YXJpYW50XTtcclxufTtcclxuXHJcbi8vIE1lbW9pemVkIFNlY3Rpb25Cb3ggY29tcG9uZW50IGZvciBwZXJmb3JtYW5jZVxyXG5leHBvcnQgY29uc3QgU2VjdGlvbkJveCA9IG1lbW88U2VjdGlvbkJveFByb3BzPihcclxuICAoe1xyXG4gICAgdGl0bGUsXHJcbiAgICBjaGlsZHJlbixcclxuICAgIHNwYWNpbmcgPSAwLFxyXG4gICAgY29udGFpbmVyU3gsXHJcbiAgICB0aXRsZVN4LFxyXG4gICAgdmFyaWFudCA9ICdkZWZhdWx0JyxcclxuICAgIGljb24sXHJcbiAgICBhY3Rpb25zLFxyXG4gIH0pID0+IHtcclxuICAgIGNvbnN0IHRoZW1lQ29sb3JzID0gdXNlTWVtbygoKSA9PiBnZXRTZWN0aW9uVGhlbWUodmFyaWFudCksIFt2YXJpYW50XSk7XHJcblxyXG4gICAgY29uc3QgaGVhZGVyU3ggPSB1c2VNZW1vKFxyXG4gICAgICAoKSA9PiAoe1xyXG4gICAgICAgIHB4OiAxLjUsXHJcbiAgICAgICAgcHk6IDAuMSxcclxuICAgICAgICB3aWR0aDogJ2ZpdC1jb250ZW50JyxcclxuICAgICAgICAuLi50aGVtZUNvbG9ycyxcclxuICAgICAgICAuLi50aXRsZVN4LFxyXG4gICAgICB9KSxcclxuICAgICAgW3RoZW1lQ29sb3JzLCB0aXRsZVN4XVxyXG4gICAgKTtcclxuXHJcbiAgICBjb25zdCBjb250ZW50U3ggPSB1c2VNZW1vKFxyXG4gICAgICAoKSA9PiAoe1xyXG4gICAgICAgIHBhZGRpbmc6ICcxNnB4JyxcclxuICAgICAgICAuLi5jb250YWluZXJTeCxcclxuICAgICAgfSksXHJcbiAgICAgIFtjb250YWluZXJTeF1cclxuICAgICk7XHJcblxyXG4gICAgcmV0dXJuIChcclxuICAgICAgPD5cclxuICAgICAgICA8Qm94IHN4PXt7IGRpc3BsYXk6ICdmbGV4JywgZmxleERpcmVjdGlvbjogJ2NvbHVtbicsIHdpZHRoOiAnMTAwJScgfX0+XHJcbiAgICAgICAgICA8U3RhY2tcclxuICAgICAgICAgICAgZGlyZWN0aW9uPVwicm93XCJcclxuICAgICAgICAgICAganVzdGlmeUNvbnRlbnQ9XCJzcGFjZS1iZXR3ZWVuXCJcclxuICAgICAgICAgICAgYWxpZ25JdGVtcz1cImNlbnRlclwiXHJcbiAgICAgICAgICAgIHN4PXtoZWFkZXJTeH1cclxuICAgICAgICAgID5cclxuICAgICAgICAgICAgPFN0YWNrIGRpcmVjdGlvbj1cInJvd1wiIGFsaWduSXRlbXM9XCJjZW50ZXJcIiBzcGFjaW5nPXsxfT5cclxuICAgICAgICAgICAgICB7aWNvbn1cclxuICAgICAgICAgICAgICA8VHlwb2dyYXBoeSBzeD17eyBmb250U2l6ZTogJzE1cHgnLCBmb250V2VpZ2h0OiA0MDAgfX0+XHJcbiAgICAgICAgICAgICAgICB7dGl0bGV9XHJcbiAgICAgICAgICAgICAgPC9UeXBvZ3JhcGh5PlxyXG4gICAgICAgICAgICA8L1N0YWNrPlxyXG4gICAgICAgICAgICB7YWN0aW9uc31cclxuICAgICAgICAgIDwvU3RhY2s+XHJcbiAgICAgICAgICA8RGl2aWRlciAvPlxyXG4gICAgICAgIDwvQm94PlxyXG4gICAgICAgIDxHcmlkIGNvbnRhaW5lciBzcGFjaW5nPXtzcGFjaW5nfSBzeD17Y29udGVudFN4fT5cclxuICAgICAgICAgIHtjaGlsZHJlbn1cclxuICAgICAgICA8L0dyaWQ+XHJcbiAgICAgIDwvPlxyXG4gICAgKTtcclxuICB9XHJcbik7XHJcbiIsICJpbXBvcnQgeyBUYWJDb250ZXh0IH0gZnJvbSAnQG11aS9sYWInO1xyXG5pbXBvcnQgdHlwZSB7IFN4UHJvcHMgfSBmcm9tICdAbXVpL21hdGVyaWFsJztcclxuaW1wb3J0IHsgQm94LCBUYWIsIFRhYnMgfSBmcm9tICdAbXVpL21hdGVyaWFsJztcclxuaW1wb3J0IHR5cGUgeyBQcm9wc1dpdGhDaGlsZHJlbiB9IGZyb20gJ3JlYWN0JztcclxuaW1wb3J0IFJlYWN0LCB7IHVzZVN0YXRlIH0gZnJvbSAncmVhY3QnO1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBUYWJJdGVtIHtcclxuICBsYWJlbDogc3RyaW5nO1xyXG4gIHZhbHVlOiBudW1iZXI7XHJcbiAgcGVybWlzc2lvbj86IGJvb2xlYW47XHJcbn1cclxuXHJcbmludGVyZmFjZSBDdXN0b21UYWJzUHJvcHMge1xyXG4gIHRhYnM6IFRhYkl0ZW1bXTtcclxuICBkZWZhdWx0VmFsdWU/OiBudW1iZXI7XHJcbiAgb25UYWJDaGFuZ2U/OiAobmV3VmFsdWU6IG51bWJlcikgPT4gdm9pZDtcclxuICB0YWJTeD86IFN4UHJvcHM7XHJcbiAgdGFic1N4PzogU3hQcm9wcztcclxufVxyXG5cclxuZXhwb3J0IGNvbnN0IFNpbXBsZVRhYnMgPSAoe1xyXG4gIHRhYnMsXHJcbiAgZGVmYXVsdFZhbHVlID0gMSxcclxuICBvblRhYkNoYW5nZSxcclxuICBjaGlsZHJlbixcclxuICB0YWJTeCxcclxuICB0YWJzU3gsXHJcbn06IEN1c3RvbVRhYnNQcm9wcyAmIFByb3BzV2l0aENoaWxkcmVuKSA9PiB7XHJcbiAgY29uc3QgW3ZhbHVlLCBzZXRWYWx1ZV0gPSB1c2VTdGF0ZTxudW1iZXI+KGRlZmF1bHRWYWx1ZSk7XHJcblxyXG4gIGNvbnN0IGhhbmRsZUNoYW5nZSA9IChldmVudDogUmVhY3QuU3ludGhldGljRXZlbnQsIG5ld1ZhbHVlOiBudW1iZXIpID0+IHtcclxuICAgIHNldFZhbHVlKG5ld1ZhbHVlKTtcclxuICAgIGlmIChvblRhYkNoYW5nZSkgb25UYWJDaGFuZ2UobmV3VmFsdWUpO1xyXG4gIH07XHJcblxyXG4gIHJldHVybiAoXHJcbiAgICA8VGFiQ29udGV4dCB2YWx1ZT17dmFsdWV9PlxyXG4gICAgICA8Qm94IHN4PXt7IGJvcmRlckJvdHRvbTogMSwgYm9yZGVyQ29sb3I6ICdkaXZpZGVyJywgd2lkdGg6ICcxMDAlJyB9fT5cclxuICAgICAgICA8VGFic1xyXG4gICAgICAgICAgdmFsdWU9e3ZhbHVlfVxyXG4gICAgICAgICAgb25DaGFuZ2U9e2hhbmRsZUNoYW5nZX1cclxuICAgICAgICAgIHN4PXt7IHB4OiAyLCBweTogMCwgLi4udGFic1N4IH19XHJcbiAgICAgICAgPlxyXG4gICAgICAgICAge3RhYnMubWFwKHRhYiA9PiAoXHJcbiAgICAgICAgICAgIDxUYWJcclxuICAgICAgICAgICAgICBrZXk9e3RhYi52YWx1ZX1cclxuICAgICAgICAgICAgICBsYWJlbD17dGFiLmxhYmVsfVxyXG4gICAgICAgICAgICAgIHZhbHVlPXt0YWIudmFsdWV9XHJcbiAgICAgICAgICAgICAgZGlzYWJsZWQ9e3RhYi5wZXJtaXNzaW9uID09PSBmYWxzZX1cclxuICAgICAgICAgICAgICBzeD17eyBmb250U2l6ZTogJzFyZW0nLCAuLi50YWJTeCB9fVxyXG4gICAgICAgICAgICAvPlxyXG4gICAgICAgICAgKSl9XHJcbiAgICAgICAgPC9UYWJzPlxyXG4gICAgICA8L0JveD5cclxuXHJcbiAgICAgIHtjaGlsZHJlbn1cclxuICAgIDwvVGFiQ29udGV4dD5cclxuICApO1xyXG59O1xyXG4iLCAiaW1wb3J0IHR5cGUgeyBMb2FkaW5nQnV0dG9uUHJvcHMgfSBmcm9tICdAbXVpL2xhYic7XHJcbmltcG9ydCB7IExvYWRpbmdCdXR0b24gfSBmcm9tICdAbXVpL2xhYic7XHJcbmltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XHJcblxyXG50eXBlIFN1Ym1pdEJ1dHRvblByb3BzID0gT21pdDxcclxuICBMb2FkaW5nQnV0dG9uUHJvcHMsXHJcbiAgJ2NoaWxkcmVuJyB8ICd2YXJpYW50JyB8ICdjb2xvcicgfCAndHlwZSdcclxuPjtcclxuXHJcbmV4cG9ydCBjb25zdCBTdWJtaXRCdXR0b246IFJlYWN0LkZDPFN1Ym1pdEJ1dHRvblByb3BzPiA9ICh7XHJcbiAgbG9hZGluZyA9IGZhbHNlLFxyXG4gIC4uLnJlc3RcclxufSkgPT4gKFxyXG4gIDxMb2FkaW5nQnV0dG9uXHJcbiAgICBsb2FkaW5nPXtsb2FkaW5nfVxyXG4gICAgdmFyaWFudD1cImNvbnRhaW5lZFwiXHJcbiAgICBjb2xvcj1cInByaW1hcnlcIlxyXG4gICAgdHlwZT1cInN1Ym1pdFwiXHJcbiAgICB7Li4ucmVzdH1cclxuICAgIHN4PXt7IGZvbnRXZWlnaHQ6IDQwMCB9fVxyXG4gID5cclxuICAgIFN1Ym1pdFxyXG4gIDwvTG9hZGluZ0J1dHRvbj5cclxuKTtcclxuIiwgImltcG9ydCB0eXBlIFJlYWN0IGZyb20gJ3JlYWN0JztcclxuaW1wb3J0IHsgZm9yd2FyZFJlZiB9IGZyb20gJ3JlYWN0JztcclxuXHJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuLy8gU2hhcmVkIHR5cGVzXHJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuZXhwb3J0IGludGVyZmFjZSBEYXRhTW9kYWxCdXR0b25zIHtcclxuICBvblN1Ym1pdD86ICgpID0+IHZvaWQ7XHJcbiAgb25DYW5jZWw/OiAoKSA9PiB2b2lkO1xyXG4gIGlzUGVuZGluZz86IGJvb2xlYW47XHJcbiAgaXNTdWNjZXNzPzogYm9vbGVhbjtcclxufVxyXG5cclxuZXhwb3J0IGludGVyZmFjZSBEYXRhTW9kYWxDb21wb25lbnRQcm9wczxURGF0YT4ge1xyXG4gIGRhdGE/OiBURGF0YTtcclxuICBpc0VkaXRpbmc/OiBib29sZWFuO1xyXG4gIHJlZj86IFJlYWN0LlJlZjxEYXRhTW9kYWxCdXR0b25zPjsgLy8gXHVEODNEXHVEQzQ4IHB1dCByZWYgaW50byBwcm9wc1xyXG59XHJcblxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbi8vIFByb2plY3Qtc3BlY2lmaWMgSE9DXHJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuZXhwb3J0IGZ1bmN0aW9uIHdpdGhEYXRhTW9kYWw8VERhdGE+KFxyXG4gIGNvbXBvbmVudDogKFxyXG4gICAgcHJvcHM6IERhdGFNb2RhbENvbXBvbmVudFByb3BzPFREYXRhPlxyXG4gICkgPT4gUmVhY3QuUmVhY3RFbGVtZW50IHwgbnVsbFxyXG4pIHtcclxuICByZXR1cm4gZm9yd2FyZFJlZjxEYXRhTW9kYWxCdXR0b25zLCBEYXRhTW9kYWxDb21wb25lbnRQcm9wczxURGF0YT4+KFxyXG4gICAgKHByb3BzLCByZWYpID0+IGNvbXBvbmVudCh7IC4uLnByb3BzLCByZWYgfSlcclxuICApO1xyXG59XHJcbiIsICJleHBvcnQgaW50ZXJmYWNlIENvbmZpZ1ZhbHVlIHtcclxuICBhcGlCYXNlVXJsOiBzdHJpbmc7XHJcbiAgZGVmYXVsdFBhZ2VTaXplOiBudW1iZXI7XHJcbn1cclxuXHJcbmV4cG9ydCBjb25zdCBDb25maWc6IENvbmZpZ1ZhbHVlID0ge1xyXG4gIGRlZmF1bHRQYWdlU2l6ZTogMjAsXHJcbiAgYXBpQmFzZVVybDogJ2h0dHA6Ly9sb2NhbGhvc3Q6NTE0MycsXHJcbiAgLy8gYXBpQmFzZVVybDogJ2h0dHA6Ly8xOTIuMTY4LjEuMjQ2OjUxNDMnLFxyXG59O1xyXG5cclxuZXhwb3J0IGNvbnN0IGRhdGVUaW1lUGF0dGVybnMgPSB7XHJcbiAgZGF0ZVRpbWU6ICdERCBNTU0gWVlZWSBoOm1tIEEnLCAvLyAxNyBBcHIgMjAyMiAxMjowMCBhbVxyXG4gIGRhdGU6ICdERCBNTU0gWVlZWScsIC8vIDE3IEFwciAyMDIyXHJcbiAgbW9udGhfeWVhcl9zaG9ydF9mb3JtYXQ6ICdNTU0gWVlZWScsXHJcbiAgbW9udGhfeWVhcl9mdWxsX2Zvcm1hdDogJ01NTU0gWVlZWScsXHJcbiAgeWVhcjogJ1lZWVknLFxyXG4gIHRpbWU6ICdoOm1tIGEnLCAvLyAxMjowMCBhbVxyXG4gIHNwbGl0OiB7XHJcbiAgICBkYXRlVGltZTogJ0REL01NL1lZWVkgaDptbSBBJywgLy8gMTcvMDQvMjAyMiAxMjowMCBhbVxyXG4gICAgZGF0ZTogJ0REL01NL1lZWVknLCAvLyAxNy8wNC8yMDIyXHJcbiAgfSxcclxuICBwYXJhbUNhc2U6IHtcclxuICAgIGRhdGVUaW1lOiAnREQtTU0tWVlZWSBoOm1tIEEnLCAvLyAxNy0wNC0yMDIyIDEyOjAwIGFtXHJcbiAgICBkYXRlOiAnREQtTU0tWVlZWScsIC8vIDE3LTA0LTIwMjJcclxuICAgIGRhdGVSZXZlcnNlOiAnWVlZWS1NTS1ERCcsIC8vIDIwMjItMDQtMTcgZm9yIGNvbXBhcmUgZGF0ZVxyXG4gICAgTW9udGhZZWFyOiAnTU1NLVlZWVknLFxyXG4gIH0sXHJcbn07XHJcbiIsICJpbXBvcnQgeyB1c2VNZW1vIH0gZnJvbSAncmVhY3QnO1xyXG5cclxuaW1wb3J0IHsgY3JlYXRlQXBpQ2xpZW50IH0gZnJvbSAnLi4vYXBpL2NyZWF0ZUFwaUNsaWVudCc7XHJcbmltcG9ydCB0eXBlIHsgQXBpQ2xpZW50Q29uZmlnIH0gZnJvbSAnLi4vYXBpL2NyZWF0ZUFwaUNsaWVudCc7XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gdXNlQXBpQ2xpZW50KGNvbmZpZzogQXBpQ2xpZW50Q29uZmlnID0ge30pIHtcclxuICByZXR1cm4gdXNlTWVtbygoKSA9PiB7XHJcbiAgICByZXR1cm4gY3JlYXRlQXBpQ2xpZW50KGNvbmZpZyk7XHJcbiAgfSwgW1xyXG4gICAgY29uZmlnLmJhc2VVUkwsXHJcbiAgICBjb25maWcudGltZW91dCxcclxuICAgIGNvbmZpZy5jb3JyZWxhdGlvbklkUHJlZml4LFxyXG4gICAgY29uZmlnLmluY2x1ZGVDb3JyZWxhdGlvbklkLFxyXG4gICAgY29uZmlnLmF1dGhUb2tlbixcclxuICAgIGNvbmZpZy5yZXF1ZXN0SW50ZXJjZXB0b3JzLFxyXG4gICAgY29uZmlnLnJlc3BvbnNlSW50ZXJjZXB0b3JzLFxyXG4gICAgY29uZmlnLmVycm9ySW50ZXJjZXB0b3JzLFxyXG4gIF0pO1xyXG59XHJcbiIsICJpbXBvcnQgdHlwZSB7IFZhbGlkYXRpb25FcnJvcnMgfSBmcm9tICdAZ253ZWJzb2Z0L3VpJztcclxuaW1wb3J0IHsgdXNlQ2FsbGJhY2sgfSBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCB0eXBlIHsgVXNlRm9ybVNldEVycm9yLCBGaWVsZFZhbHVlcywgUGF0aCB9IGZyb20gJ3JlYWN0LWhvb2stZm9ybSc7XHJcbmltcG9ydCB7IHRvYXN0IH0gZnJvbSAnc29ubmVyJztcclxuXHJcbmltcG9ydCB0eXBlIHsgQXBpRXJyb3IgfSBmcm9tICcuLi9hcGkvdHlwZXMnO1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBTdWNjZXNzTWVzc2FnZSB7XHJcbiAgY3JlYXRlOiBzdHJpbmc7XHJcbiAgdXBkYXRlOiBzdHJpbmc7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgRXJyb3JNZXNzYWdlIHtcclxuICBub0NoYW5nZXM6IHN0cmluZztcclxuICBnZW5lcmFsOiBzdHJpbmc7XHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgVXNlRm9ybUVycm9ySGFuZGxlck9wdGlvbnM8VEZpZWxkVmFsdWVzIGV4dGVuZHMgRmllbGRWYWx1ZXM+IHtcclxuICBzZXRFcnJvcj86IFVzZUZvcm1TZXRFcnJvcjxURmllbGRWYWx1ZXM+O1xyXG4gIHN1Y2Nlc3NNZXNzYWdlPzogU3VjY2Vzc01lc3NhZ2U7XHJcbiAgZXJyb3JNZXNzYWdlPzogRXJyb3JNZXNzYWdlO1xyXG59XHJcblxyXG5leHBvcnQgdHlwZSBTdWNjZXNzSGFuZGxlciA9IChpc0VkaXRpbmc6IGJvb2xlYW4sIHJvd3NBZmZlY3RlZD86IG51bWJlcikgPT4gYm9vbGVhbjtcblxyXG5leHBvcnQgdHlwZSBFcnJvckhhbmRsZXIgPSAocHJvY2Vzc2VkRXJyb3I6IEFwaUVycm9yKSA9PiB2b2lkO1xyXG5cclxuZXhwb3J0IGludGVyZmFjZSBVc2VGb3JtRXJyb3JIYW5kbGVyUmV0dXJuIHtcclxuICBoYW5kbGVTdWNjZXNzOiBTdWNjZXNzSGFuZGxlcjtcclxuICBoYW5kbGVFcnJvcjogRXJyb3JIYW5kbGVyO1xyXG59XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIFVzZURlbGV0ZUhhbmRsZXJPcHRpb25zIHtcclxuICBzdWNjZXNzTWVzc2FnZT86IHN0cmluZztcclxuICBlcnJvck1lc3NhZ2U/OiBzdHJpbmc7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBIb29rIHRvIGhhbmRsZSBBUEkgZXJyb3JzIGluIGZvcm1zIHdpdGggc3RhbmRhcmRpemVkIGVycm9yIGhhbmRsaW5nIGFuZCB0b2FzdCBtZXNzYWdlc1xyXG4gKi9cclxuZXhwb3J0IGNvbnN0IHVzZUZvcm1FcnJvckhhbmRsZXIgPSA8VEZpZWxkVmFsdWVzIGV4dGVuZHMgRmllbGRWYWx1ZXM+KHtcclxuICBzZXRFcnJvcixcclxuICBzdWNjZXNzTWVzc2FnZSA9IHtcclxuICAgIGNyZWF0ZTogJ0NyZWF0ZWQgc3VjY2Vzc2Z1bGx5JyxcclxuICAgIHVwZGF0ZTogJ1VwZGF0ZWQgc3VjY2Vzc2Z1bGx5JyxcclxuICB9LFxyXG4gIGVycm9yTWVzc2FnZSA9IHtcclxuICAgIG5vQ2hhbmdlczogJ05vIGNoYW5nZXMgd2VyZSBtYWRlJyxcclxuICAgIGdlbmVyYWw6ICdGYWlsZWQgdG8gc2F2ZS4gUGxlYXNlIHRyeSBhZ2Fpbi4nLFxyXG4gIH0sXHJcbn06IFVzZUZvcm1FcnJvckhhbmRsZXJPcHRpb25zPFRGaWVsZFZhbHVlcz4pOiBVc2VGb3JtRXJyb3JIYW5kbGVyUmV0dXJuID0+IHtcclxuICBjb25zdCBnZXRGaWVsZEVycm9yID0gdXNlQ2FsbGJhY2soXHJcbiAgICAoZmllbGRzOiBWYWxpZGF0aW9uRXJyb3JzIHwgdW5kZWZpbmVkLCBmaWVsZE5hbWU6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCA9PiB7XHJcbiAgICAgIGlmICghZmllbGRzIHx8ICFmaWVsZHNbZmllbGROYW1lXSkgcmV0dXJuIHVuZGVmaW5lZDtcclxuXHJcbiAgICAgIGNvbnN0IGZpZWxkRXJyb3IgPSBmaWVsZHNbZmllbGROYW1lXTtcclxuXHJcbiAgICAgIGlmICh0eXBlb2YgZmllbGRFcnJvciA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgICByZXR1cm4gZmllbGRFcnJvcjtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZmllbGRFcnJvcikpIHtcclxuICAgICAgICByZXR1cm4gZmllbGRFcnJvci5qb2luKCcsICcpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAodHlwZW9mIGZpZWxkRXJyb3IgPT09ICdvYmplY3QnICYmICdtZXNzYWdlJyBpbiBmaWVsZEVycm9yKSB7XHJcbiAgICAgICAgcmV0dXJuIGZpZWxkRXJyb3IubWVzc2FnZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgIH0sXHJcbiAgICBbXVxyXG4gICk7XHJcblxyXG4gIGNvbnN0IGhhbmRsZVN1Y2Nlc3MgPSB1c2VDYWxsYmFjayhcclxuICAgIChpc0VkaXRpbmc6IGJvb2xlYW4sIHJvd3NBZmZlY3RlZD86IG51bWJlcikgPT4ge1xyXG4gICAgICBpZiAocm93c0FmZmVjdGVkICE9PSB1bmRlZmluZWQgJiYgcm93c0FmZmVjdGVkID4gMCkge1xyXG4gICAgICAgIHRvYXN0LnN1Y2Nlc3MoaXNFZGl0aW5nID8gc3VjY2Vzc01lc3NhZ2UudXBkYXRlIDogc3VjY2Vzc01lc3NhZ2UuY3JlYXRlKTtcblxyXG4gICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICB9IGVsc2UgaWYgKHJvd3NBZmZlY3RlZCA9PT0gMCkge1xyXG4gICAgICAgIHRvYXN0LmVycm9yKGVycm9yTWVzc2FnZS5ub0NoYW5nZXMpO1xuXHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICB9XG5cclxuICAgICAgLy8gSWYgcm93c0FmZmVjdGVkIGlzIHVuZGVmaW5lZCwgYXNzdW1lIHN1Y2Nlc3NcclxuICAgICAgdG9hc3Quc3VjY2Vzcyhpc0VkaXRpbmcgPyBzdWNjZXNzTWVzc2FnZS51cGRhdGUgOiBzdWNjZXNzTWVzc2FnZS5jcmVhdGUpO1xuXHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfSxcclxuICAgIFtzdWNjZXNzTWVzc2FnZSwgZXJyb3JNZXNzYWdlXVxyXG4gICk7XHJcblxyXG4gIGNvbnN0IGhhbmRsZUVycm9yID0gdXNlQ2FsbGJhY2soXHJcbiAgICAocHJvY2Vzc2VkRXJyb3I6IEFwaUVycm9yKSA9PiB7XHJcbiAgICAgIGlmIChwcm9jZXNzZWRFcnJvci50eXBlID09PSAndmFsaWRhdGlvbl9lcnJvcicgJiYgcHJvY2Vzc2VkRXJyb3IuZXJyb3JzICYmIHNldEVycm9yKSB7XHJcbiAgICAgICAgLy8gU2V0IGZpZWxkLXNwZWNpZmljIGVycm9ycyB1c2luZyByZWFjdC1ob29rLWZvcm0ncyBzZXRFcnJvciAob25seSBpZiBzZXRFcnJvciBpcyBwcm92aWRlZClcclxuICAgICAgICBPYmplY3Qua2V5cyhwcm9jZXNzZWRFcnJvci5lcnJvcnMpLmZvckVhY2goZmllbGROYW1lID0+IHtcclxuICAgICAgICAgIGNvbnN0IGZpZWxkRXJyb3IgPSBnZXRGaWVsZEVycm9yKHByb2Nlc3NlZEVycm9yLmVycm9ycywgZmllbGROYW1lKTtcblxyXG4gICAgICAgICAgaWYgKGZpZWxkRXJyb3IpIHtcclxuICAgICAgICAgICAgc2V0RXJyb3IoZmllbGROYW1lIGFzIFBhdGg8VEZpZWxkVmFsdWVzPiwge1xyXG4gICAgICAgICAgICAgIHR5cGU6ICdzZXJ2ZXInLFxyXG4gICAgICAgICAgICAgIG1lc3NhZ2U6IGZpZWxkRXJyb3IsXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICAvLyBTaG93IGdlbmVyYWwgdmFsaWRhdGlvbiBlcnJvciB0b2FzdFxyXG4gICAgICAgIHRvYXN0LmVycm9yKHByb2Nlc3NlZEVycm9yLnRpdGxlIHx8ICdQbGVhc2UgY2hlY2sgdGhlIGZvcm0gZm9yIHZhbGlkYXRpb24gZXJyb3JzJyk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgLy8gU2hvdyBnZW5lcmFsIGVycm9yIHRvYXN0IGZvciBub24tdmFsaWRhdGlvbiBlcnJvcnMgb3Igd2hlbiBzZXRFcnJvciBpcyBub3QgYXZhaWxhYmxlXHJcbiAgICAgICAgdG9hc3QuZXJyb3IocHJvY2Vzc2VkRXJyb3IudGl0bGUgfHwgZXJyb3JNZXNzYWdlLmdlbmVyYWwpO1xyXG4gICAgICB9XHJcbiAgICB9LFxyXG4gICAgW2Vycm9yTWVzc2FnZS5nZW5lcmFsLCBnZXRGaWVsZEVycm9yLCBzZXRFcnJvcl1cclxuICApO1xyXG5cclxuICByZXR1cm4ge1xyXG4gICAgaGFuZGxlU3VjY2VzcyxcclxuICAgIGhhbmRsZUVycm9yLFxyXG4gIH07XHJcbn07XHJcblxyXG4vKipcclxuICogQ29udmVuaWVuY2UgaG9vayBmb3IgZGVsZXRlIG9wZXJhdGlvbnMgdGhhdCBkb24ndCBuZWVkIGZvcm0gZmllbGQgdmFsaWRhdGlvblxyXG4gKiBVc2VzIHVzZUZvcm1FcnJvckhhbmRsZXIgaW50ZXJuYWxseSBidXQgd2l0aCBzaW1wbGlmaWVkIG9wdGlvbnNcclxuICovXHJcbmV4cG9ydCBjb25zdCB1c2VEZWxldGVIYW5kbGVyID0gKHtcclxuICBzdWNjZXNzTWVzc2FnZSA9ICdEZWxldGVkIHN1Y2Nlc3NmdWxseScsXHJcbiAgZXJyb3JNZXNzYWdlID0gJ0ZhaWxlZCB0byBkZWxldGUuIFBsZWFzZSB0cnkgYWdhaW4uJyxcclxufTogVXNlRGVsZXRlSGFuZGxlck9wdGlvbnMgPSB7fSk6IFVzZUZvcm1FcnJvckhhbmRsZXJSZXR1cm4gPT4ge1xyXG4gIHJldHVybiB1c2VGb3JtRXJyb3JIYW5kbGVyKHtcclxuICAgIHN1Y2Nlc3NNZXNzYWdlOiB7XHJcbiAgICAgIGNyZWF0ZTogc3VjY2Vzc01lc3NhZ2UsIC8vIE5vdCB1c2VkIGZvciBkZWxldGUsIGJ1dCByZXF1aXJlZCBmb3IgdHlwZVxyXG4gICAgICB1cGRhdGU6IHN1Y2Nlc3NNZXNzYWdlLFxyXG4gICAgfSxcclxuICAgIGVycm9yTWVzc2FnZToge1xyXG4gICAgICBub0NoYW5nZXM6ICdObyBjaGFuZ2VzIHdlcmUgbWFkZScsIC8vIE5vdCB0eXBpY2FsbHkgdXNlZCBmb3IgZGVsZXRlXHJcbiAgICAgIGdlbmVyYWw6IGVycm9yTWVzc2FnZSxcclxuICAgIH0sXHJcbiAgICAvLyBzZXRFcnJvciBpcyBvbWl0dGVkICh1bmRlZmluZWQpIGZvciBkZWxldGUgb3BlcmF0aW9uc1xyXG4gIH0pO1xyXG59O1xyXG4iLCAiaW1wb3J0IHR5cGUgeyBRdWVyeUNsaWVudCwgUXVlcnlLZXkgfSBmcm9tICdAdGFuc3RhY2svcmVhY3QtcXVlcnknO1xyXG5pbXBvcnQgeyB1c2VRdWVyeUNsaWVudCB9IGZyb20gJ0B0YW5zdGFjay9yZWFjdC1xdWVyeSc7XHJcbmltcG9ydCB7IHVzZU1lbW8gfSBmcm9tICdyZWFjdCc7XHJcblxyXG4vLyBNaW5pbWFsIHR5cGUtc2FmZSBjYWNoZSB1dGlsaXR5IGZvciBxdWVyeSBrZXkgZmFjdG9yaWVzXHJcbmV4cG9ydCBjbGFzcyBDYWNoZVV0aWxpdHkge1xyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcXVlcnlDbGllbnQ6IFF1ZXJ5Q2xpZW50KSB7fVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgY2FjaGVkIGRhdGEgdXNpbmcgb25seSB0aGUgcXVlcnlLZXkgZnJvbSBxdWVyeSBmYWN0b3J5XHJcbiAgICovXHJcbiAgZ2V0Q2FjaGVkRGF0YTxUPihxdWVyeUtleTogUXVlcnlLZXkpOiBUIHwgdW5kZWZpbmVkIHtcclxuICAgIHJldHVybiB0aGlzLnF1ZXJ5Q2xpZW50LmdldFF1ZXJ5RGF0YTxUPihxdWVyeUtleSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgY2FjaGVkIGRhdGEgd2l0aCB0cmFuc2Zvcm1hdGlvbiB1c2luZyBzZWxlY3QgZnVuY3Rpb25cclxuICAgKi9cclxuICBnZXRDYWNoZWREYXRhV2l0aFNlbGVjdDxULCBSPihcclxuICAgIHF1ZXJ5S2V5OiBRdWVyeUtleSxcclxuICAgIHNlbGVjdDogKGRhdGE6IFQpID0+IFJcclxuICApOiBSIHwgdW5kZWZpbmVkIHtcclxuICAgIGNvbnN0IGNhY2hlZERhdGEgPSB0aGlzLnF1ZXJ5Q2xpZW50LmdldFF1ZXJ5RGF0YTxUPihxdWVyeUtleSk7XHJcblxyXG4gICAgaWYgKGNhY2hlZERhdGEgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBzZWxlY3QoY2FjaGVkRGF0YSk7XHJcbiAgfVxyXG59XHJcblxyXG5leHBvcnQgZnVuY3Rpb24gdXNlQ2FjaGVVdGlsaXR5KCk6IENhY2hlVXRpbGl0eSB7XHJcbiAgY29uc3QgcXVlcnlDbGllbnQgPSB1c2VRdWVyeUNsaWVudCgpO1xyXG5cclxuICByZXR1cm4gdXNlTWVtbygoKSA9PiBuZXcgQ2FjaGVVdGlsaXR5KHF1ZXJ5Q2xpZW50KSwgW3F1ZXJ5Q2xpZW50XSk7XHJcbn1cclxuIiwgImltcG9ydCB0eXBlIHtcclxuICBDb250cm9sLFxyXG4gIERlZXBQYXJ0aWFsU2tpcEFycmF5S2V5LFxyXG4gIEZpZWxkVmFsdWVzLFxyXG4gIFBhdGgsXHJcbiAgUGF0aFZhbHVlLFxyXG59IGZyb20gJ3JlYWN0LWhvb2stZm9ybSc7XHJcbmltcG9ydCB7IHVzZVdhdGNoIH0gZnJvbSAncmVhY3QtaG9vay1mb3JtJztcclxuXHJcbi8qKlxyXG4gKiBDb3JlIHdhdGNoIGZ1bmN0aW9ucyBmb3IgUmVhY3QgSG9vayBGb3JtXHJcbiAqIFRoZXNlIGFyZSB0aGUgcHJpbWFyeSBidWlsZGluZyBibG9ja3MgZm9yIGZvcm0gd2F0Y2hpbmdcclxuICovXHJcblxyXG4vKipcclxuICogVXRpbGl0eSB0eXBlIHRvIGVuc3VyZSBhcnJheSBlbGVtZW50cyBhcmUgYWxsIFBhdGg8VD5cclxuICovXHJcbmV4cG9ydCB0eXBlIFBhdGhBcnJheTxUIGV4dGVuZHMgRmllbGRWYWx1ZXM+ID0gUmVhZG9ubHlBcnJheTxQYXRoPFQ+PjtcclxuXHJcbi8qKlxyXG4gKiBIb29rIHRvIHdhdGNoIGVudGlyZSBmb3JtIC0gcmV0dXJucyBhbGwgZm9ybSB2YWx1ZXNcclxuICovXHJcbmV4cG9ydCBjb25zdCB1c2VXYXRjaEZvcm0gPSA8VEZpZWxkVmFsdWVzIGV4dGVuZHMgRmllbGRWYWx1ZXM+KFxyXG4gIGNvbnRyb2w6IENvbnRyb2w8VEZpZWxkVmFsdWVzPlxyXG4pOiBEZWVwUGFydGlhbFNraXBBcnJheUtleTxURmllbGRWYWx1ZXM+ID0+IHVzZVdhdGNoKHsgY29udHJvbCB9KTtcclxuXHJcbi8qKlxyXG4gKiBIb29rIHRvIHdhdGNoIHNpbmdsZSBmaWVsZCBieSBwYXRoIC0gc3VwcG9ydHMgYW55IG5lc3RlZCBwYXRoXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgdXNlV2F0Y2hGaWVsZCA9IDxcclxuICBURmllbGRWYWx1ZXMgZXh0ZW5kcyBGaWVsZFZhbHVlcyxcclxuICBUTmFtZSBleHRlbmRzIFBhdGg8VEZpZWxkVmFsdWVzPixcclxuPihcclxuICBjb250cm9sOiBDb250cm9sPFRGaWVsZFZhbHVlcz4sXHJcbiAgbmFtZTogVE5hbWVcclxuKTogUGF0aFZhbHVlPFRGaWVsZFZhbHVlcywgVE5hbWU+ID0+IHVzZVdhdGNoKHsgY29udHJvbCwgbmFtZSB9KTtcclxuXHJcbi8qKlxyXG4gKiBIb29rIHRvIHdhdGNoIG11bHRpcGxlIGZpZWxkcyBieSBwYXRocyAtIHJldHVybnMgYXJyYXkgb2YgdmFsdWVzXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgdXNlV2F0Y2hGaWVsZHMgPSA8XHJcbiAgVEZpZWxkVmFsdWVzIGV4dGVuZHMgRmllbGRWYWx1ZXMsXHJcbiAgVE5hbWVzIGV4dGVuZHMgUmVhZG9ubHlBcnJheTxQYXRoPFRGaWVsZFZhbHVlcz4+LFxyXG4+KFxyXG4gIGNvbnRyb2w6IENvbnRyb2w8VEZpZWxkVmFsdWVzPixcclxuICBuYW1lczogVE5hbWVzXHJcbik6IEFycmF5PFBhdGhWYWx1ZTxURmllbGRWYWx1ZXMsIFROYW1lc1tudW1iZXJdPj4gPT5cclxuICB1c2VXYXRjaCh7IGNvbnRyb2wsIG5hbWU6IG5hbWVzIH0pIGFzIEFycmF5PFxyXG4gICAgUGF0aFZhbHVlPFRGaWVsZFZhbHVlcywgVE5hbWVzW251bWJlcl0+XHJcbiAgPjtcclxuIiwgImltcG9ydCB7IHVzZUVmZmVjdCwgdXNlTWVtbywgdXNlU3RhdGUgfSBmcm9tICdyZWFjdCc7XHJcbmltcG9ydCB0eXBlIHsgQ29udHJvbCwgRmllbGRWYWx1ZXMsIFBhdGgsIFBhdGhWYWx1ZSB9IGZyb20gJ3JlYWN0LWhvb2stZm9ybSc7XHJcbmltcG9ydCB7IHVzZVdhdGNoIH0gZnJvbSAncmVhY3QtaG9vay1mb3JtJztcclxuXHJcbi8qKlxyXG4gKiBVdGlsaXR5IHdhdGNoIGZ1bmN0aW9ucyBmb3IgUmVhY3QgSG9vayBGb3JtXHJcbiAqIEVuaGFuY2VkIGZ1bmN0aW9uYWxpdHkgZm9yIHNwZWNpZmljIHVzZSBjYXNlc1xyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBXYXRjaCBmaWVsZCB3aXRoIHRyYW5zZm9ybWF0aW9uL3NlbGVjdG9yXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgdXNlV2F0Y2hUcmFuc2Zvcm0gPSA8XHJcbiAgVEZpZWxkVmFsdWVzIGV4dGVuZHMgRmllbGRWYWx1ZXMsXHJcbiAgVE5hbWUgZXh0ZW5kcyBQYXRoPFRGaWVsZFZhbHVlcz4sXHJcbiAgVE91dHB1dCxcclxuPihcclxuICBjb250cm9sOiBDb250cm9sPFRGaWVsZFZhbHVlcz4sXHJcbiAgbmFtZTogVE5hbWUsXHJcbiAgdHJhbnNmb3JtOiAodmFsdWU6IFBhdGhWYWx1ZTxURmllbGRWYWx1ZXMsIFROYW1lPikgPT4gVE91dHB1dFxyXG4pOiBUT3V0cHV0ID0+IHtcclxuICBjb25zdCB2YWx1ZSA9IHVzZVdhdGNoKHsgY29udHJvbCwgbmFtZSB9KTtcclxuXHJcbiAgcmV0dXJuIHVzZU1lbW8oKCkgPT4gdHJhbnNmb3JtKHZhbHVlKSwgW3ZhbHVlLCB0cmFuc2Zvcm1dKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBXYXRjaCBmaWVsZCB3aXRoIGRlZmF1bHQgZmFsbGJhY2sgdmFsdWVcclxuICovXHJcbmV4cG9ydCBjb25zdCB1c2VXYXRjaERlZmF1bHQgPSA8XHJcbiAgVEZpZWxkVmFsdWVzIGV4dGVuZHMgRmllbGRWYWx1ZXMsXHJcbiAgVE5hbWUgZXh0ZW5kcyBQYXRoPFRGaWVsZFZhbHVlcz4sXHJcbj4oXHJcbiAgY29udHJvbDogQ29udHJvbDxURmllbGRWYWx1ZXM+LFxyXG4gIG5hbWU6IFROYW1lLFxyXG4gIGRlZmF1bHRWYWx1ZTogUGF0aFZhbHVlPFRGaWVsZFZhbHVlcywgVE5hbWU+XHJcbik6IFBhdGhWYWx1ZTxURmllbGRWYWx1ZXMsIFROYW1lPiA9PiB7XHJcbiAgY29uc3QgdmFsdWUgPSB1c2VXYXRjaCh7IGNvbnRyb2wsIG5hbWUgfSk7XHJcblxyXG4gIHJldHVybiB2YWx1ZSA/PyBkZWZhdWx0VmFsdWU7XHJcbn07XHJcblxyXG4vKipcclxuICogV2F0Y2ggZmllbGQgYXMgYm9vbGVhbiB3aXRoIGd1YXJhbnRlZWQgYm9vbGVhbiByZXR1cm5cclxuICovXHJcbmV4cG9ydCBjb25zdCB1c2VXYXRjaEJvb2xlYW4gPSA8XHJcbiAgVEZpZWxkVmFsdWVzIGV4dGVuZHMgRmllbGRWYWx1ZXMsXHJcbiAgVE5hbWUgZXh0ZW5kcyBQYXRoPFRGaWVsZFZhbHVlcz4sXHJcbj4oXHJcbiAgY29udHJvbDogQ29udHJvbDxURmllbGRWYWx1ZXM+LFxyXG4gIG5hbWU6IFROYW1lLFxyXG4gIGRlZmF1bHRWYWx1ZSA9IGZhbHNlXHJcbik6IGJvb2xlYW4gPT4ge1xyXG4gIGNvbnN0IHZhbHVlID0gdXNlV2F0Y2goeyBjb250cm9sLCBuYW1lIH0pO1xyXG5cclxuICByZXR1cm4gQm9vbGVhbih2YWx1ZSA/PyBkZWZhdWx0VmFsdWUpO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFdhdGNoIG11bHRpcGxlIGZpZWxkcyBhbmQgcmV0dXJuIGFuIG9iamVjdCB3aXRoIGZpZWxkIHBhdGhzIGFzIGtleXNcclxuICovXHJcbmV4cG9ydCBjb25zdCB1c2VXYXRjaEJhdGNoID0gPFxyXG4gIFRGaWVsZFZhbHVlcyBleHRlbmRzIEZpZWxkVmFsdWVzLFxyXG4gIFRGaWVsZHMgZXh0ZW5kcyBSZWFkb25seUFycmF5PFBhdGg8VEZpZWxkVmFsdWVzPj4sXHJcbj4oXHJcbiAgY29udHJvbDogQ29udHJvbDxURmllbGRWYWx1ZXM+LFxyXG4gIGZpZWxkczogVEZpZWxkc1xyXG4pOiB7IFtLIGluIFRGaWVsZHNbbnVtYmVyXV06IFBhdGhWYWx1ZTxURmllbGRWYWx1ZXMsIEs+IH0gPT4ge1xyXG4gIGNvbnN0IHZhbHVlcyA9IHVzZVdhdGNoKHsgY29udHJvbCwgbmFtZTogZmllbGRzIH0pO1xyXG5cclxuICByZXR1cm4gdXNlTWVtbygoKSA9PiB7XHJcbiAgICBjb25zdCByZXN1bHQgPSB7fSBhcyB7IFtLIGluIFRGaWVsZHNbbnVtYmVyXV06IFBhdGhWYWx1ZTxURmllbGRWYWx1ZXMsIEs+IH07XHJcblxyXG4gICAgZmllbGRzLmZvckVhY2goKGZpZWxkLCBpbmRleCkgPT4ge1xyXG4gICAgICByZXN1bHRbZmllbGQgYXMgVEZpZWxkc1tudW1iZXJdXSA9IHZhbHVlc1tpbmRleF07XHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG4gIH0sIFt2YWx1ZXMsIGZpZWxkc10pO1xyXG59O1xyXG5cclxuLyoqXHJcbiAqIFdhdGNoIGZpZWxkIGNvbmRpdGlvbmFsbHkgYmFzZWQgb24gYm9vbGVhbiBmbGFnXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgdXNlV2F0Y2hDb25kaXRpb25hbCA9IDxcclxuICBURmllbGRWYWx1ZXMgZXh0ZW5kcyBGaWVsZFZhbHVlcyxcclxuICBUTmFtZSBleHRlbmRzIFBhdGg8VEZpZWxkVmFsdWVzPixcclxuPihcclxuICBjb250cm9sOiBDb250cm9sPFRGaWVsZFZhbHVlcz4sXHJcbiAgbmFtZTogVE5hbWUsXHJcbiAgc2hvdWxkV2F0Y2g6IGJvb2xlYW4sXHJcbiAgZmFsbGJhY2s/OiBQYXRoVmFsdWU8VEZpZWxkVmFsdWVzLCBUTmFtZT5cclxuKTogUGF0aFZhbHVlPFRGaWVsZFZhbHVlcywgVE5hbWU+IHwgdW5kZWZpbmVkID0+IHtcclxuICBjb25zdCBhY3RpdmVWYWx1ZSA9IHVzZVdhdGNoKHtcclxuICAgIGNvbnRyb2wsXHJcbiAgICBuYW1lLFxyXG4gICAgZGlzYWJsZWQ6ICFzaG91bGRXYXRjaCxcclxuICB9KTtcclxuXHJcbiAgcmV0dXJuIHNob3VsZFdhdGNoID8gYWN0aXZlVmFsdWUgOiBmYWxsYmFjaztcclxufTtcclxuXHJcbi8qKlxyXG4gKiBXYXRjaCBmaWVsZCB3aXRoIGRlYm91bmNlZCB1cGRhdGVzXHJcbiAqL1xyXG5leHBvcnQgY29uc3QgdXNlV2F0Y2hEZWJvdW5jZWQgPSA8XHJcbiAgVEZpZWxkVmFsdWVzIGV4dGVuZHMgRmllbGRWYWx1ZXMsXHJcbiAgVE5hbWUgZXh0ZW5kcyBQYXRoPFRGaWVsZFZhbHVlcz4sXHJcbj4oXHJcbiAgY29udHJvbDogQ29udHJvbDxURmllbGRWYWx1ZXM+LFxyXG4gIG5hbWU6IFROYW1lLFxyXG4gIGRlbGF5ID0gMzAwXHJcbik6IFBhdGhWYWx1ZTxURmllbGRWYWx1ZXMsIFROYW1lPiA9PiB7XHJcbiAgY29uc3QgdmFsdWUgPSB1c2VXYXRjaCh7IGNvbnRyb2wsIG5hbWUgfSk7XHJcbiAgY29uc3QgW2RlYm91bmNlZFZhbHVlLCBzZXREZWJvdW5jZWRWYWx1ZV0gPVxyXG4gICAgdXNlU3RhdGU8UGF0aFZhbHVlPFRGaWVsZFZhbHVlcywgVE5hbWU+Pih2YWx1ZSk7XHJcblxyXG4gIHVzZUVmZmVjdCgoKSA9PiB7XHJcbiAgICBjb25zdCB0aW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICBzZXREZWJvdW5jZWRWYWx1ZSh2YWx1ZSk7XHJcbiAgICB9LCBkZWxheSk7XHJcblxyXG4gICAgcmV0dXJuICgpID0+IGNsZWFyVGltZW91dCh0aW1lcik7XHJcbiAgfSwgW3ZhbHVlLCBkZWxheV0pO1xyXG5cclxuICByZXR1cm4gZGVib3VuY2VkVmFsdWU7XHJcbn07XHJcblxyXG4vKipcclxuICogV2F0Y2ggZmllbGQgd2l0aCBtZW1vaXplZCBzZWxlY3RvciBmdW5jdGlvblxyXG4gKi9cclxuZXhwb3J0IGNvbnN0IHVzZVdhdGNoU2VsZWN0b3IgPSA8XHJcbiAgVEZpZWxkVmFsdWVzIGV4dGVuZHMgRmllbGRWYWx1ZXMsXHJcbiAgVE5hbWUgZXh0ZW5kcyBQYXRoPFRGaWVsZFZhbHVlcz4sXHJcbiAgVE91dHB1dCxcclxuPihcclxuICBjb250cm9sOiBDb250cm9sPFRGaWVsZFZhbHVlcz4sXHJcbiAgbmFtZTogVE5hbWUsXHJcbiAgc2VsZWN0b3I6ICh2YWx1ZTogUGF0aFZhbHVlPFRGaWVsZFZhbHVlcywgVE5hbWU+KSA9PiBUT3V0cHV0LFxyXG4gIGRlcHM6IFJlYWN0LkRlcGVuZGVuY3lMaXN0ID0gW11cclxuKTogVE91dHB1dCA9PiB7XHJcbiAgY29uc3QgdmFsdWUgPSB1c2VXYXRjaCh7IGNvbnRyb2wsIG5hbWUgfSk7XHJcblxyXG4gIHJldHVybiB1c2VNZW1vKFxyXG4gICAgKCkgPT4gc2VsZWN0b3IodmFsdWUpLFxyXG4gICAgW3ZhbHVlLCBzZWxlY3RvciwgLi4uZGVwc10gLy8gZXNsaW50LWRpc2FibGUtbGluZSByZWFjdC1ob29rcy9leGhhdXN0aXZlLWRlcHNcclxuICApO1xyXG59O1xyXG4iLCAiLyoqXHJcbiAqIEVuaGFuY2VkIFR5cGVTY3JpcHQgdXRpbGl0aWVzIGZvciBSZWFjdCBIb29rIEZvcm0ncyB1c2VXYXRjaFxyXG4gKlxyXG4gKiBUaGlzIG1vZHVsZSBwcm92aWRlcyBhIGNvbXByZWhlbnNpdmUgc2V0IG9mIHR5cGUtc2FmZSB3YXRjaCBmdW5jdGlvbnNcclxuICogd2l0aCBiZXR0ZXIgZXJnb25vbWljcyBhbmQgYWRkaXRpb25hbCBmdW5jdGlvbmFsaXR5LlxyXG4gKlxyXG4gKiBAZXhhbXBsZVxyXG4gKiBgYGB0eXBlc2NyaXB0XHJcbiAqIGltcG9ydCB7IHVzZVdhdGNoRmllbGQsIHVzZVdhdGNoQm9vbGVhbiwgdHlwZWRXYXRjaCB9IGZyb20gJ3NyYy91dGlscy93YXRjaCc7XHJcbiAqXHJcbiAqIC8vIERpcmVjdCB1c2FnZSAoaW5zaWRlIFJlYWN0IGNvbXBvbmVudHMpXHJcbiAqIGNvbnN0IGVtYWlsID0gdXNlV2F0Y2hGaWVsZChjb250cm9sLCAndXNlci5lbWFpbCcpO1xyXG4gKiBjb25zdCBpc0FkbWluID0gdXNlV2F0Y2hCb29sZWFuKGNvbnRyb2wsICd1c2VyLmlzQWRtaW4nKTtcclxuICpcclxuICogLy8gT2JqZWN0LWJhc2VkIHVzYWdlIChpbnNpZGUgUmVhY3QgY29tcG9uZW50cylcclxuICogY29uc3QgZW1haWwgPSB0eXBlZFdhdGNoLmZpZWxkKGNvbnRyb2wsICd1c2VyLmVtYWlsJyk7XHJcbiAqIGNvbnN0IGlzQWRtaW4gPSB0eXBlZFdhdGNoLmJvb2xlYW4oY29udHJvbCwgJ3VzZXIuaXNBZG1pbicpO1xyXG4gKiBgYGBcclxuICovXHJcblxyXG4vLyBDb3JlIGZ1bmN0aW9uc1xyXG5leHBvcnQgeyB1c2VXYXRjaEZpZWxkLCB1c2VXYXRjaEZpZWxkcywgdXNlV2F0Y2hGb3JtIH0gZnJvbSAnLi9jb3JlJztcclxuXHJcbi8vIFV0aWxpdHkgZnVuY3Rpb25zXHJcbmV4cG9ydCB7XHJcbiAgdXNlV2F0Y2hCYXRjaCxcclxuICB1c2VXYXRjaEJvb2xlYW4sXHJcbiAgdXNlV2F0Y2hDb25kaXRpb25hbCxcclxuICB1c2VXYXRjaERlYm91bmNlZCxcclxuICB1c2VXYXRjaERlZmF1bHQsXHJcbiAgdXNlV2F0Y2hTZWxlY3RvcixcclxuICB1c2VXYXRjaFRyYW5zZm9ybSxcclxufSBmcm9tICcuL3V0aWxpdGllcyc7XHJcblxyXG5leHBvcnQgdHlwZSB7IFBhdGhBcnJheSB9IGZyb20gJy4vY29yZSc7XHJcblxyXG4vLyBJbXBvcnQgYWxsIGZ1bmN0aW9ucyBmb3IgZGVmYXVsdCBleHBvcnRcclxuaW1wb3J0IHsgdXNlV2F0Y2hGaWVsZCwgdXNlV2F0Y2hGaWVsZHMsIHVzZVdhdGNoRm9ybSB9IGZyb20gJy4vY29yZSc7XHJcbmltcG9ydCB7XHJcbiAgdXNlV2F0Y2hCYXRjaCxcclxuICB1c2VXYXRjaEJvb2xlYW4sXHJcbiAgdXNlV2F0Y2hDb25kaXRpb25hbCxcclxuICB1c2VXYXRjaERlYm91bmNlZCxcclxuICB1c2VXYXRjaERlZmF1bHQsXHJcbiAgdXNlV2F0Y2hTZWxlY3RvcixcclxuICB1c2VXYXRjaFRyYW5zZm9ybSxcclxufSBmcm9tICcuL3V0aWxpdGllcyc7XHJcblxyXG4vKipcclxuICogT3JnYW5pemVkIHV0aWxpdGllcyBieSB1c2UgY2FzZVxyXG4gKiBQcm92aWRlcyBhIGNvbnZlbmllbnQgb2JqZWN0LWJhc2VkIEFQSSBmb3IgYWxsIHdhdGNoIGZ1bmN0aW9uc1xyXG4gKi9cclxuZXhwb3J0IGNvbnN0IHR5cGVkV2F0Y2ggPSB7XHJcbiAgLy8gPT09IENPUkUgRlVOQ1RJT05TID09PVxyXG4gIC8qKiBXYXRjaCBlbnRpcmUgZm9ybSAqL1xyXG4gIGZvcm06IHVzZVdhdGNoRm9ybSxcclxuICAvKiogV2F0Y2ggc2luZ2xlIGZpZWxkICovXHJcbiAgZmllbGQ6IHVzZVdhdGNoRmllbGQsXHJcbiAgLyoqIFdhdGNoIG11bHRpcGxlIGZpZWxkcyAqL1xyXG4gIGZpZWxkczogdXNlV2F0Y2hGaWVsZHMsXHJcblxyXG4gIC8vID09PSBVVElMSVRZIEZVTkNUSU9OUyA9PT1cclxuICAvKiogV2F0Y2ggd2l0aCB0cmFuc2Zvcm1hdGlvbiAqL1xyXG4gIHRyYW5zZm9ybTogdXNlV2F0Y2hUcmFuc2Zvcm0sXHJcbiAgLyoqIFdhdGNoIHdpdGggZGVmYXVsdCB2YWx1ZSAqL1xyXG4gIHdpdGhEZWZhdWx0OiB1c2VXYXRjaERlZmF1bHQsXHJcbiAgLyoqIFdhdGNoIGFzIGJvb2xlYW4gKi9cclxuICBib29sZWFuOiB1c2VXYXRjaEJvb2xlYW4sXHJcbiAgLyoqIFdhdGNoIG11bHRpcGxlIHdpdGggY3VzdG9tIGtleXMgKi9cclxuICBiYXRjaDogdXNlV2F0Y2hCYXRjaCxcclxuICAvKiogV2F0Y2ggY29uZGl0aW9uYWxseSAqL1xyXG4gIGNvbmRpdGlvbmFsOiB1c2VXYXRjaENvbmRpdGlvbmFsLFxyXG4gIC8qKiBXYXRjaCB3aXRoIGRlYm91bmNpbmcgKi9cclxuICBkZWJvdW5jZWQ6IHVzZVdhdGNoRGVib3VuY2VkLFxyXG4gIC8qKiBXYXRjaCB3aXRoIHNlbGVjdG9yICovXHJcbiAgc2VsZWN0b3I6IHVzZVdhdGNoU2VsZWN0b3IsXHJcbn0gYXMgY29uc3Q7XHJcbiIsICJleHBvcnQgY29uc3QgY2FsY3VsYXRlRmlsdGVyQ291bnQgPSAobW9kZWw6IG9iamVjdCk6IG51bWJlciA9PlxyXG4gIE9iamVjdC52YWx1ZXMobW9kZWwpLmZpbHRlcihcclxuICAgIHYgPT4gdiAhPT0gbnVsbCAmJiB2ICE9PSB1bmRlZmluZWQgJiYgU3RyaW5nKHYpLnRyaW0oKSAhPT0gJydcclxuICApLmxlbmd0aDtcclxuIiwgImltcG9ydCB0eXBlIHsgRGF5anMsIE9wVW5pdFR5cGUgfSBmcm9tICdkYXlqcyc7XHJcbmltcG9ydCBkYXlqcyBmcm9tICdkYXlqcyc7XHJcbmltcG9ydCBkdXJhdGlvbiBmcm9tICdkYXlqcy9wbHVnaW4vZHVyYXRpb24nO1xyXG5pbXBvcnQgcmVsYXRpdmVUaW1lIGZyb20gJ2RheWpzL3BsdWdpbi9yZWxhdGl2ZVRpbWUnO1xyXG5cclxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuLyoqXHJcbiAqIEBEb2NzXHJcbiAqIGh0dHBzOi8vZGF5LmpzLm9yZy9kb2NzL2VuL2Rpc3BsYXkvZm9ybWF0XHJcbiAqL1xyXG5cclxuLyoqXHJcbiAqIERlZmF1bHQgdGltZXpvbmVzXHJcbiAqIGh0dHBzOi8vZGF5LmpzLm9yZy9kb2NzL2VuL3RpbWV6b25lL3NldC1kZWZhdWx0LXRpbWV6b25lI2RvY3NOYXZcclxuICpcclxuICovXHJcblxyXG4vKipcclxuICogVVRDXHJcbiAqIGh0dHBzOi8vZGF5LmpzLm9yZy9kb2NzL2VuL3BsdWdpbi91dGNcclxuICogQGluc3RhbGxcclxuICogaW1wb3J0IHV0YyBmcm9tICdkYXlqcy9wbHVnaW4vdXRjJztcclxuICogZGF5anMuZXh0ZW5kKHV0Yyk7XHJcbiAqIEB1c2FnZVxyXG4gKiBkYXlqcygpLnV0YygpLmZvcm1hdCgpXHJcbiAqXHJcbiAqL1xyXG5cclxuZGF5anMuZXh0ZW5kKGR1cmF0aW9uKTtcclxuZGF5anMuZXh0ZW5kKHJlbGF0aXZlVGltZSk7XHJcblxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblxyXG5leHBvcnQgdHlwZSBEYXRlUGlja2VyRm9ybWF0ID1cclxuICB8IERheWpzXHJcbiAgfCBEYXRlXHJcbiAgfCBzdHJpbmdcclxuICB8IG51bWJlclxyXG4gIHwgbnVsbFxyXG4gIHwgdW5kZWZpbmVkO1xyXG5cclxuZXhwb3J0IGNvbnN0IGZvcm1hdFBhdHRlcm5zID0ge1xyXG4gIGRhdGVUaW1lOiAnREQgTU1NIFlZWVkgaDptbSBBJywgLy8gMTcgQXByIDIwMjIgMTI6MDAgYW1cclxuICBkYXRlOiAnREQgTU1NIFlZWVknLCAvLyAxNyBBcHIgMjAyMlxyXG4gIG1vbnRoX3llYXJfc2hvcnRfZm9ybWF0OiAnTU1NIFlZWVknLFxyXG4gIG1vbnRoX3llYXJfZnVsbF9mb3JtYXQ6ICdNTU1NIFlZWVknLFxyXG4gIHllYXI6ICdZWVlZJyxcclxuICB0aW1lOiAnaDptbSBhJywgLy8gMTI6MDAgYW1cclxuICBzcGxpdDoge1xyXG4gICAgZGF0ZVRpbWU6ICdERC9NTS9ZWVlZIGg6bW0gQScsIC8vIDE3LzA0LzIwMjIgMTI6MDAgYW1cclxuICAgIGRhdGU6ICdERC9NTS9ZWVlZJywgLy8gMTcvMDQvMjAyMlxyXG4gIH0sXHJcbiAgcGFyYW1DYXNlOiB7XHJcbiAgICBkYXRlVGltZTogJ0RELU1NLVlZWVkgaDptbSBBJywgLy8gMTctMDQtMjAyMiAxMjowMCBhbVxyXG4gICAgZGF0ZTogJ0RELU1NLVlZWVknLCAvLyAxNy0wNC0yMDIyXHJcbiAgICBkYXRlUmV2ZXJzZTogJ1lZWVktTU0tREQnLCAvLyAyMDIyLTA0LTE3IGZvciBjb21wYXJlIGRhdGVcclxuICAgIE1vbnRoWWVhcjogJ01NTS1ZWVlZJyxcclxuICB9LFxyXG59O1xyXG5cclxuY29uc3QgaXNWYWxpZERhdGUgPSAoZGF0ZTogRGF0ZVBpY2tlckZvcm1hdCkgPT5cclxuICBkYXRlICE9PSBudWxsICYmIGRhdGUgIT09IHVuZGVmaW5lZCAmJiBkYXlqcyhkYXRlKS5pc1ZhbGlkKCk7XHJcblxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblxyXG5leHBvcnQgZnVuY3Rpb24gdG9kYXkodGVtcGxhdGU/OiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gIHJldHVybiBkYXlqcyhuZXcgRGF0ZSgpKS5zdGFydE9mKCdkYXknKS5mb3JtYXQodGVtcGxhdGUpO1xyXG59XHJcblxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblxyXG4vKipcclxuICogQG91dHB1dCAxNyBBcHIgMjAyMiAxMjowMCBhbVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGZEYXRlVGltZShkYXRlOiBEYXRlUGlja2VyRm9ybWF0LCB0ZW1wbGF0ZT86IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgaWYgKCFpc1ZhbGlkRGF0ZShkYXRlKSkge1xyXG4gICAgcmV0dXJuICdJbnZhbGlkIGRhdGUnO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGRheWpzKGRhdGUpLmZvcm1hdCh0ZW1wbGF0ZSA/PyBmb3JtYXRQYXR0ZXJucy5kYXRlVGltZSk7XHJcbn1cclxuXHJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcbi8qKlxyXG4gKiBAb3V0cHV0IDE3IEFwciAyMDIyXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZkRhdGUoZGF0ZTogRGF0ZVBpY2tlckZvcm1hdCwgdGVtcGxhdGU/OiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gIGlmICghaXNWYWxpZERhdGUoZGF0ZSkpIHtcclxuICAgIHJldHVybiAnSW52YWxpZCBkYXRlJztcclxuICB9XHJcblxyXG4gIHJldHVybiBkYXlqcyhkYXRlKS5mb3JtYXQodGVtcGxhdGUgPz8gZm9ybWF0UGF0dGVybnMuZGF0ZSk7XHJcbn1cclxuXHJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcbi8qKlxyXG4gKiBAb3V0cHV0IDEyOjAwIGFtXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZlRpbWUoZGF0ZTogRGF0ZVBpY2tlckZvcm1hdCwgdGVtcGxhdGU/OiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gIGlmICghaXNWYWxpZERhdGUoZGF0ZSkpIHtcclxuICAgIHJldHVybiAnSW52YWxpZCBkYXRlJztcclxuICB9XHJcblxyXG4gIHJldHVybiBkYXlqcyhkYXRlKS5mb3JtYXQodGVtcGxhdGUgPz8gZm9ybWF0UGF0dGVybnMudGltZSk7XHJcbn1cclxuXHJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcbi8qKlxyXG4gKiBAb3V0cHV0IDE3MTMyNTAxMDBcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBmVGltZXN0YW1wKGRhdGU6IERhdGVQaWNrZXJGb3JtYXQpOiBudW1iZXIgfCAnSW52YWxpZCBkYXRlJyB7XHJcbiAgaWYgKCFpc1ZhbGlkRGF0ZShkYXRlKSkge1xyXG4gICAgcmV0dXJuICdJbnZhbGlkIGRhdGUnO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGRheWpzKGRhdGUpLnZhbHVlT2YoKTtcclxufVxyXG5cclxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuLyoqXHJcbiAqIEBvdXRwdXQgYSBmZXcgc2Vjb25kcywgMiB5ZWFyc1xyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGZUb05vdyhkYXRlOiBEYXRlUGlja2VyRm9ybWF0KTogc3RyaW5nIHtcclxuICBpZiAoIWlzVmFsaWREYXRlKGRhdGUpKSB7XHJcbiAgICByZXR1cm4gJ0ludmFsaWQgZGF0ZSc7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gZGF5anMoZGF0ZSkudG9Ob3codHJ1ZSk7XHJcbn1cclxuXHJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcbi8qKlxyXG4gKiBAb3V0cHV0IGJvb2xlYW5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBmSXNCZXR3ZWVuKFxyXG4gIGlucHV0RGF0ZTogRGF0ZVBpY2tlckZvcm1hdCxcclxuICBzdGFydERhdGU6IERhdGVQaWNrZXJGb3JtYXQsXHJcbiAgZW5kRGF0ZTogRGF0ZVBpY2tlckZvcm1hdFxyXG4pOiBib29sZWFuIHtcclxuICBpZiAoXHJcbiAgICAhaXNWYWxpZERhdGUoaW5wdXREYXRlKSB8fFxyXG4gICAgIWlzVmFsaWREYXRlKHN0YXJ0RGF0ZSkgfHxcclxuICAgICFpc1ZhbGlkRGF0ZShlbmREYXRlKVxyXG4gICkge1xyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG4gIH1cclxuXHJcbiAgY29uc3QgZm9ybWF0dGVkSW5wdXREYXRlID0gZlRpbWVzdGFtcChpbnB1dERhdGUpO1xyXG4gIGNvbnN0IGZvcm1hdHRlZFN0YXJ0RGF0ZSA9IGZUaW1lc3RhbXAoc3RhcnREYXRlKTtcclxuICBjb25zdCBmb3JtYXR0ZWRFbmREYXRlID0gZlRpbWVzdGFtcChlbmREYXRlKTtcclxuXHJcbiAgaWYgKFxyXG4gICAgZm9ybWF0dGVkSW5wdXREYXRlID09PSAnSW52YWxpZCBkYXRlJyB8fFxyXG4gICAgZm9ybWF0dGVkU3RhcnREYXRlID09PSAnSW52YWxpZCBkYXRlJyB8fFxyXG4gICAgZm9ybWF0dGVkRW5kRGF0ZSA9PT0gJ0ludmFsaWQgZGF0ZSdcclxuICApIHtcclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9XHJcblxyXG4gIHJldHVybiAoXHJcbiAgICBmb3JtYXR0ZWRJbnB1dERhdGUgPj0gZm9ybWF0dGVkU3RhcnREYXRlICYmXHJcbiAgICBmb3JtYXR0ZWRJbnB1dERhdGUgPD0gZm9ybWF0dGVkRW5kRGF0ZVxyXG4gICk7XHJcbn1cclxuXHJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcbi8qKlxyXG4gKiBAb3V0cHV0IGJvb2xlYW5cclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBmSXNBZnRlcihcclxuICBzdGFydERhdGU6IERhdGVQaWNrZXJGb3JtYXQsXHJcbiAgZW5kRGF0ZTogRGF0ZVBpY2tlckZvcm1hdFxyXG4pOiBib29sZWFuIHtcclxuICBpZiAoIWlzVmFsaWREYXRlKHN0YXJ0RGF0ZSkgfHwgIWlzVmFsaWREYXRlKGVuZERhdGUpKSB7XHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gZGF5anMoc3RhcnREYXRlKS5pc0FmdGVyKGVuZERhdGUpO1xyXG59XHJcblxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblxyXG4vKipcclxuICogQG91dHB1dCBib29sZWFuXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZklzU2FtZShcclxuICBzdGFydERhdGU6IERhdGVQaWNrZXJGb3JtYXQsXHJcbiAgZW5kRGF0ZTogRGF0ZVBpY2tlckZvcm1hdCxcclxuICB1bml0VG9Db21wYXJlPzogT3BVbml0VHlwZVxyXG4pOiBib29sZWFuIHtcclxuICBpZiAoIWlzVmFsaWREYXRlKHN0YXJ0RGF0ZSkgfHwgIWlzVmFsaWREYXRlKGVuZERhdGUpKSB7XHJcbiAgICByZXR1cm4gZmFsc2U7XHJcbiAgfVxyXG5cclxuICByZXR1cm4gZGF5anMoc3RhcnREYXRlKS5pc1NhbWUoZW5kRGF0ZSwgdW5pdFRvQ29tcGFyZSA/PyAneWVhcicpO1xyXG59XHJcblxyXG4vKipcclxuICogQG91dHB1dFxyXG4gKiBTYW1lIGRheTogMjYgQXByIDIwMjRcclxuICogU2FtZSBtb250aDogMjUgLSAyNiBBcHIgMjAyNFxyXG4gKiBTYW1lIG1vbnRoOiAyNSAtIDI2IEFwciAyMDI0XHJcbiAqIFNhbWUgeWVhcjogMjUgQXByIC0gMjYgTWF5IDIwMjRcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBmRGF0ZVJhbmdlU2hvcnRMYWJlbChcclxuICBzdGFydERhdGU6IERhdGVQaWNrZXJGb3JtYXQsXHJcbiAgZW5kRGF0ZTogRGF0ZVBpY2tlckZvcm1hdCxcclxuICBpbml0aWFsPzogYm9vbGVhblxyXG4pOiBzdHJpbmcge1xyXG4gIGlmIChcclxuICAgICFpc1ZhbGlkRGF0ZShzdGFydERhdGUpIHx8XHJcbiAgICAhaXNWYWxpZERhdGUoZW5kRGF0ZSkgfHxcclxuICAgIGZJc0FmdGVyKHN0YXJ0RGF0ZSwgZW5kRGF0ZSlcclxuICApIHtcclxuICAgIHJldHVybiAnSW52YWxpZCBkYXRlJztcclxuICB9XHJcblxyXG4gIGxldCBsYWJlbCA9IGAke2ZEYXRlKHN0YXJ0RGF0ZSl9IC0gJHtmRGF0ZShlbmREYXRlKX1gO1xyXG5cclxuICBpZiAoaW5pdGlhbCkge1xyXG4gICAgcmV0dXJuIGxhYmVsO1xyXG4gIH1cclxuXHJcbiAgY29uc3QgaXNTYW1lWWVhciA9IGZJc1NhbWUoc3RhcnREYXRlLCBlbmREYXRlLCAneWVhcicpO1xyXG4gIGNvbnN0IGlzU2FtZU1vbnRoID0gZklzU2FtZShzdGFydERhdGUsIGVuZERhdGUsICdtb250aCcpO1xyXG4gIGNvbnN0IGlzU2FtZURheSA9IGZJc1NhbWUoc3RhcnREYXRlLCBlbmREYXRlLCAnZGF5Jyk7XHJcblxyXG4gIGlmIChpc1NhbWVZZWFyICYmICFpc1NhbWVNb250aCkge1xyXG4gICAgbGFiZWwgPSBgJHtmRGF0ZShzdGFydERhdGUsICdERCBNTU0nKX0gLSAke2ZEYXRlKGVuZERhdGUpfWA7XHJcbiAgfSBlbHNlIGlmIChpc1NhbWVZZWFyICYmIGlzU2FtZU1vbnRoICYmICFpc1NhbWVEYXkpIHtcclxuICAgIGxhYmVsID0gYCR7ZkRhdGUoc3RhcnREYXRlLCAnREQnKX0gLSAke2ZEYXRlKGVuZERhdGUpfWA7XHJcbiAgfSBlbHNlIGlmIChpc1NhbWVZZWFyICYmIGlzU2FtZU1vbnRoICYmIGlzU2FtZURheSkge1xyXG4gICAgbGFiZWwgPSBgJHtmRGF0ZShlbmREYXRlKX1gO1xyXG4gIH1cclxuXHJcbiAgcmV0dXJuIGxhYmVsO1xyXG59XHJcblxyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblxyXG4vKipcclxuICogQG91dHB1dCAyMDI0LTA1LTI4VDA1OjU1OjMxKzAwOjAwXHJcbiAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIER1cmF0aW9uUHJvcHMge1xyXG4gIHllYXJzPzogbnVtYmVyO1xyXG4gIG1vbnRocz86IG51bWJlcjtcclxuICBkYXlzPzogbnVtYmVyO1xyXG4gIGhvdXJzPzogbnVtYmVyO1xyXG4gIG1pbnV0ZXM/OiBudW1iZXI7XHJcbiAgc2Vjb25kcz86IG51bWJlcjtcclxuICBtaWxsaXNlY29uZHM/OiBudW1iZXI7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBmQWRkKHtcclxuICB5ZWFycyA9IDAsXHJcbiAgbW9udGhzID0gMCxcclxuICBkYXlzID0gMCxcclxuICBob3VycyA9IDAsXHJcbiAgbWludXRlcyA9IDAsXHJcbiAgc2Vjb25kcyA9IDAsXHJcbiAgbWlsbGlzZWNvbmRzID0gMCxcclxufTogRHVyYXRpb25Qcm9wcykge1xyXG4gIGNvbnN0IHJlc3VsdCA9IGRheWpzKClcclxuICAgIC5hZGQoXHJcbiAgICAgIGRheWpzLmR1cmF0aW9uKHtcclxuICAgICAgICB5ZWFycyxcclxuICAgICAgICBtb250aHMsXHJcbiAgICAgICAgZGF5cyxcclxuICAgICAgICBob3VycyxcclxuICAgICAgICBtaW51dGVzLFxyXG4gICAgICAgIHNlY29uZHMsXHJcbiAgICAgICAgbWlsbGlzZWNvbmRzLFxyXG4gICAgICB9KVxyXG4gICAgKVxyXG4gICAgLmZvcm1hdCgpO1xyXG5cclxuICByZXR1cm4gcmVzdWx0O1xyXG59XHJcblxyXG4vKipcclxuICogQG91dHB1dCAyMDI0LTA1LTI4VDA1OjU1OjMxKzAwOjAwXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZlN1Yih7XHJcbiAgeWVhcnMgPSAwLFxyXG4gIG1vbnRocyA9IDAsXHJcbiAgZGF5cyA9IDAsXHJcbiAgaG91cnMgPSAwLFxyXG4gIG1pbnV0ZXMgPSAwLFxyXG4gIHNlY29uZHMgPSAwLFxyXG4gIG1pbGxpc2Vjb25kcyA9IDAsXHJcbn06IER1cmF0aW9uUHJvcHMpIHtcclxuICBjb25zdCByZXN1bHQgPSBkYXlqcygpXHJcbiAgICAuc3VidHJhY3QoXHJcbiAgICAgIGRheWpzLmR1cmF0aW9uKHtcclxuICAgICAgICB5ZWFycyxcclxuICAgICAgICBtb250aHMsXHJcbiAgICAgICAgZGF5cyxcclxuICAgICAgICBob3VycyxcclxuICAgICAgICBtaW51dGVzLFxyXG4gICAgICAgIHNlY29uZHMsXHJcbiAgICAgICAgbWlsbGlzZWNvbmRzLFxyXG4gICAgICB9KVxyXG4gICAgKVxyXG4gICAgLmZvcm1hdCgpO1xyXG5cclxuICByZXR1cm4gcmVzdWx0O1xyXG59XHJcbiIsICJ0eXBlIEVtcHR5VmFsdWU8VD4gPSBUIGV4dGVuZHMgbnVtYmVyXHJcbiAgPyAwXHJcbiAgOiBUIGV4dGVuZHMgc3RyaW5nXHJcbiAgICA/IG51bGxcclxuICAgIDogVCBleHRlbmRzIGJvb2xlYW5cclxuICAgICAgPyBudWxsXHJcbiAgICAgIDogVCBleHRlbmRzIERhdGVcclxuICAgICAgICA/IG51bGxcclxuICAgICAgICA6IFQgZXh0ZW5kcyBvYmplY3RcclxuICAgICAgICAgID8gbnVsbFxyXG4gICAgICAgICAgOiBudWxsO1xyXG5cclxudHlwZSBFbXB0eU9iamVjdDxUIGV4dGVuZHMgb2JqZWN0PiA9IHtcclxuICBbSyBpbiBrZXlvZiBUXTogRW1wdHlWYWx1ZTxUW0tdPjtcclxufTtcclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRFbXB0eU9iamVjdDxUIGV4dGVuZHMgb2JqZWN0PihcclxuICBkYXRhOiBULFxyXG4gIGRlZmF1bHRWYWx1ZXM6IFBhcnRpYWw8VD4gPSB7fVxyXG4pOiBFbXB0eU9iamVjdDxUPiAmIFBhcnRpYWw8VD4ge1xyXG4gIGNvbnN0IG9iaiA9IHt9IGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xyXG5cclxuICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhkYXRhKSBhcyBBcnJheTxrZXlvZiBUPikge1xyXG4gICAgY29uc3QgdmFsdWUgPSBkYXRhW2tleV07XHJcbiAgICBjb25zdCB0eXBlID0gdHlwZW9mIHZhbHVlO1xyXG5cclxuICAgIGlmICh0eXBlID09PSAnbnVtYmVyJykge1xyXG4gICAgICBvYmpba2V5IGFzIHN0cmluZ10gPSAwO1xyXG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJyB8fCB0eXBlID09PSAnYm9vbGVhbicpIHtcclxuICAgICAgb2JqW2tleSBhcyBzdHJpbmddID0gbnVsbDtcclxuICAgIH0gZWxzZSBpZiAodmFsdWUgaW5zdGFuY2VvZiBEYXRlKSB7XHJcbiAgICAgIG9ialtrZXkgYXMgc3RyaW5nXSA9IG51bGw7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBvYmpba2V5IGFzIHN0cmluZ10gPSBudWxsO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcmV0dXJuIHsgLi4ub2JqLCAuLi5kZWZhdWx0VmFsdWVzIH0gYXMgRW1wdHlPYmplY3Q8VD4gJiBQYXJ0aWFsPFQ+O1xyXG59XHJcbiIsICJpbXBvcnQgeyB1c2VSZWYsIHVzZU1lbW8gfSBmcm9tICdyZWFjdCc7XHJcblxyXG4vKipcclxuICogSG9vayB0byBtYWludGFpbiBzdGFibGUgcm93IGNvdW50IGZvciBkYXRhIGdyaWRzIGR1cmluZyBsb2FkaW5nIHN0YXRlcy5cclxuICogUHJldmVudHMgcGFnaW5hdGlvbiBqdW1waW5nIGJ5IHByZXNlcnZpbmcgdGhlIGxhc3Qga25vd24gdG90YWwgY291bnQuXHJcbiAqXHJcbiAqIEBwYXJhbSBjdXJyZW50VG90YWwgLSBDdXJyZW50IHRvdGFsIGZyb20gQVBJIHJlc3BvbnNlXHJcbiAqIEByZXR1cm5zIFN0YWJsZSByb3cgY291bnQgdGhhdCBwZXJzaXN0cyBkdXJpbmcgbG9hZGluZ1xyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIHVzZVN0YWJsZVJvd0NvdW50KGN1cnJlbnRUb3RhbDogbnVtYmVyIHwgdW5kZWZpbmVkKTogbnVtYmVyIHtcclxuICBjb25zdCByb3dDb3VudFJlZiA9IHVzZVJlZihjdXJyZW50VG90YWwgfHwgMCk7XHJcblxyXG4gIGNvbnN0IHN0YWJsZVJvd0NvdW50ID0gdXNlTWVtbygoKSA9PiB7XHJcbiAgICBpZiAoY3VycmVudFRvdGFsICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgcm93Q291bnRSZWYuY3VycmVudCA9IGN1cnJlbnRUb3RhbDtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gcm93Q291bnRSZWYuY3VycmVudDtcclxuICB9LCBbY3VycmVudFRvdGFsXSk7XHJcblxyXG4gIHJldHVybiBzdGFibGVSb3dDb3VudDtcclxufVxyXG4iXSwKICAibWFwcGluZ3MiOiAiO0FBQ08sSUFBTSx5QkFBTixNQUE2QjtBQUFBLEVBQ2xDLE9BQWUsZUFBdUI7QUFDcEMsUUFBSSxPQUFPLFdBQVcsZUFBZSxPQUFPLFlBQVk7QUFDdEQsYUFBTyxPQUFPLFdBQVc7QUFBQSxJQUMzQjtBQUdBLFdBQU8sdUNBQXVDLFFBQVEsU0FBUyxPQUFLO0FBQ2xFLFlBQU0sSUFBSyxLQUFLLE9BQU8sSUFBSSxLQUFNO0FBQ2pDLFlBQU0sSUFBSSxNQUFNLE1BQU0sSUFBSyxJQUFJLElBQU87QUFFdEMsYUFBTyxFQUFFLFNBQVMsRUFBRTtBQUFBLElBQ3RCLENBQUM7QUFBQSxFQUNIO0FBQUEsRUFFQSxPQUFPLFNBQVMsUUFBeUI7QUFDdkMsVUFBTSxPQUFPLEtBQUssYUFBYTtBQUUvQixXQUFPLFNBQVMsR0FBRyxNQUFNLElBQUksSUFBSSxLQUFLO0FBQUEsRUFDeEM7QUFDRjs7O0FDcEJPLElBQU0saUJBQU4sTUFBcUI7QUFBQSxFQUNsQixpQkFBK0Msb0JBQUksSUFBSTtBQUFBLEVBQ3ZELGlCQUFzQyxvQkFBSSxJQUFJO0FBQUEsRUFFdEQsSUFBSSxLQUFhLFlBQTZCLGVBQTZCO0FBRXpFLFNBQUssT0FBTyxHQUFHO0FBQ2YsU0FBSyxlQUFlLElBQUksS0FBSyxVQUFVO0FBQ3ZDLFNBQUssZUFBZSxJQUFJLEtBQUssYUFBYTtBQUFBLEVBQzVDO0FBQUEsRUFFQSxPQUFPLEtBQW1CO0FBQ3hCLFNBQUssZUFBZSxPQUFPLEdBQUc7QUFDOUIsU0FBSyxlQUFlLE9BQU8sR0FBRztBQUFBLEVBQ2hDO0FBQUEsRUFFQSxPQUFPLEtBQW1CO0FBQ3hCLFVBQU0sYUFBYSxLQUFLLGVBQWUsSUFBSSxHQUFHO0FBRTlDLFFBQUksWUFBWTtBQUNkLGlCQUFXLE1BQU07QUFDakIsV0FBSyxlQUFl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TUFBTSxDQUFDO0FBRWIsYUFBVyxPQUFPLE9BQU8sS0FBSyxJQUFJLEdBQXFCO0FBQ3JELFVBQU0sUUFBUSxLQUFLLEdBQUc7QUFDdEIsVUFBTSxPQUFPLE9BQU87QUFFcEIsUUFBSSxTQUFTLFVBQVU7QUFDckIsVUFBSSxHQUFhLElBQUk7QUFBQSxJQUN2QixXQUFXLFNBQVMsWUFBWSxTQUFTLFdBQVc7QUFDbEQsVUFBSSxHQUFhLElBQUk7QUFBQSxJQUN2QixXQUFXLGlCQUFpQixNQUFNO0FBQ2hDLFVBQUksR0FBYSxJQUFJO0FBQUEsSUFDdkIsT0FBTztBQUNMLFVBQUksR0FBYSxJQUFJO0FBQUEsSUFDdkI7QUFBQSxFQUNGO0FBRUEsU0FBTyxFQUFFLEdBQUcsS0FBSyxHQUFHLGNBQWM7QUFDcEM7OztBQ3RDQSxTQUFTLFFBQVEsV0FBQUcsZ0JBQWU7QUFTekIsU0FBUyxrQkFBa0IsY0FBMEM7QUFDMUUsUUFBTSxjQUFjLE9BQU8sZ0JBQWdCLENBQUM7QUFFNUMsUUFBTSxpQkFBaUJBLFNBQVEsTUFBTTtBQUNuQyxRQUFJLGlCQUFpQixRQUFXO0FBQzlCLGtCQUFZLFVBQVU7QUFBQSxJQUN4QjtBQUVBLFdBQU8sWUFBWTtBQUFBLEVBQ3JCLEdBQUcsQ0FBQyxZQUFZLENBQUM7QUFFakIsU0FBTztBQUNUOyIsCiAgIm5hbWVzIjogWyJjb25maWciLCAianN4IiwgIkJ1dHRvbiIsICJqc3giLCAianN4IiwgImpzeCIsICJqc3giLCAibWVtbyIsICJqc3giLCAibWVtbyIsICJCb3giLCAiQ2FyZCIsICJDYXJkQ29udGVudCIsICJUeXBvZ3JhcGh5IiwgIkZyYWdtZW50IiwgImpzeCIsICJqc3hzIiwgIkJveCIsICJUeXBvZ3JhcGh5IiwgImpzeCIsICJHcmlkIiwgIlR5cG9ncmFwaHkiLCAianN4IiwgImpzeHMiLCAiRnJhZ21lbnQiLCAianN4IiwgIkJveCIsICJEaXZpZGVyIiwgIkdyaWQiLCAiVHlwb2dyYXBoeSIsICJtZW1vIiwgInVzZU1lbW8iLCAiRnJhZ21lbnQiLCAianN4IiwgImpzeHMiLCAiQm94IiwgImpzeCIsICJqc3hzIiwgIkxvYWRpbmdCdXR0b24iLCAianN4IiwgInVzZU1lbW8iLCAidXNlTWVtbyIsICJ1c2VDYWxsYmFjayIsICJ1c2VNZW1vIiwgInVzZU1lbW8iLCAidXNlU3RhdGUiLCAidXNlV2F0Y2giLCAidXNlTWVtbyJdCn0K