@algoux/standard-ranklist-renderer-component-angular 0.6.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/README.md +148 -0
  2. package/dist/esm2022/algoux-standard-ranklist-renderer-component-angular.mjs +5 -0
  3. package/dist/esm2022/lib/index.mjs +8 -0
  4. package/dist/esm2022/lib/modal/default-solution-modal.component.mjs +146 -0
  5. package/dist/esm2022/lib/modal/default-user-modal.component.mjs +172 -0
  6. package/dist/esm2022/lib/modal/modal-interactions.mjs +2 -0
  7. package/dist/esm2022/lib/modal/modal.component.mjs +263 -0
  8. package/dist/esm2022/lib/progress/progress-bar.component.mjs +247 -0
  9. package/dist/esm2022/lib/progress/progress-utils.mjs +45 -0
  10. package/dist/esm2022/lib/ranklist/ranklist-utils.mjs +110 -0
  11. package/dist/esm2022/lib/ranklist/ranklist.component.mjs +1013 -0
  12. package/dist/esm2022/lib/ranklist/status-cell-template.directive.mjs +18 -0
  13. package/dist/esm2022/lib/ranklist/user-cell-template.directive.mjs +18 -0
  14. package/dist/esm2022/lib/types.mjs +2 -0
  15. package/dist/esm2022/public-api.mjs +2 -0
  16. package/dist/fesm2022/algoux-standard-ranklist-renderer-component-angular.mjs +2005 -0
  17. package/dist/fesm2022/algoux-standard-ranklist-renderer-component-angular.mjs.map +1 -0
  18. package/dist/index.d.ts +5 -0
  19. package/dist/lib/index.d.ts +8 -0
  20. package/dist/lib/modal/default-solution-modal.component.d.ts +30 -0
  21. package/dist/lib/modal/default-user-modal.component.d.ts +34 -0
  22. package/dist/lib/modal/modal-interactions.d.ts +1 -0
  23. package/dist/lib/modal/modal.component.d.ts +49 -0
  24. package/dist/lib/progress/progress-bar.component.d.ts +31 -0
  25. package/dist/lib/progress/progress-utils.d.ts +15 -0
  26. package/dist/lib/ranklist/ranklist-utils.d.ts +22 -0
  27. package/dist/lib/ranklist/ranklist.component.d.ts +88 -0
  28. package/dist/lib/ranklist/status-cell-template.directive.d.ts +26 -0
  29. package/dist/lib/ranklist/user-cell-template.directive.d.ts +22 -0
  30. package/dist/lib/types.d.ts +29 -0
  31. package/dist/public-api.d.ts +1 -0
  32. package/package.json +3 -3
@@ -0,0 +1,1013 @@
1
+ import { CommonModule } from '@angular/common';
2
+ import { ChangeDetectionStrategy, Component, ContentChild, EventEmitter, Input, Output, } from '@angular/core';
3
+ import { EnumTheme, formatTimeDuration, numberToAlphabet, resolveStyle, resolveText, resolveUserMarkers, } from '@algoux/standard-ranklist-utils';
4
+ import { calculateDirtPercentage, calculateProblemStatisticsFooter, calculateSEValue, caniuse, formatProblemStatisticsAcceptedMinute, formatProblemStatisticsAverageHardness, formatProblemStatisticsPercent, getMarkerPresentation, getProblemHeaderBackgroundImage, getRankProblemStatusCellPresentation, resolveSrkAssetUrl, shouldShowTimeColumn, srkSupportedVersions, } from '@algoux/standard-ranklist-renderer-component-core';
5
+ import { captureModalTriggerPointFromMouseEvent } from '../modal/modal-interactions';
6
+ import { SrkStatusCellTemplateDirective, } from './status-cell-template.directive';
7
+ import { SrkUserCellTemplateDirective, } from './user-cell-template.directive';
8
+ import * as i0 from "@angular/core";
9
+ import * as i1 from "@angular/common";
10
+ export class RanklistComponent {
11
+ data;
12
+ theme = EnumTheme.light;
13
+ borderedRows = false;
14
+ rowBordered = false;
15
+ columnBordered = false;
16
+ stripedRows = false;
17
+ formatSrkAssetUrl;
18
+ splitOrganization = false;
19
+ columnTitles;
20
+ statusCellPreset = 'classic';
21
+ statusColorAsText = false;
22
+ showProblemStatisticsFooter = false;
23
+ showDirtColumn = false;
24
+ showSEColumn = false;
25
+ emptyStatusPlaceholder = null;
26
+ userAvatarPlacement = 'user';
27
+ userClick = new EventEmitter();
28
+ solutionClick = new EventEmitter();
29
+ statusCellTemplate;
30
+ userCellTemplate;
31
+ supportedVersions = srkSupportedVersions;
32
+ firstBloodStar = '\u2605';
33
+ statusSeparator = ' ';
34
+ problemStatisticsFooterRows = [
35
+ {
36
+ key: 'accepted',
37
+ label: 'Accepted',
38
+ tooltip: 'Number of participants who solved this problem',
39
+ },
40
+ {
41
+ key: 'tried',
42
+ label: 'Tried',
43
+ tooltip: 'Number of participants who attempted this problem',
44
+ },
45
+ {
46
+ key: 'submitted',
47
+ label: 'Submitted',
48
+ tooltip: 'Total number of valid submissions for this problem',
49
+ },
50
+ {
51
+ key: 'dirt',
52
+ label: 'Dirt',
53
+ tooltip: 'Wrong submissions among participants who solved this problem',
54
+ },
55
+ {
56
+ key: 'se',
57
+ label: 'SE',
58
+ tooltip: 'Average hardness, calculated as (participants - accepted) / participants',
59
+ },
60
+ {
61
+ key: 'firstAccepted',
62
+ label: 'FB at',
63
+ tooltip: 'First Blood at, also known as first solve time, in minutes',
64
+ },
65
+ {
66
+ key: 'lastAccepted',
67
+ label: 'LB at',
68
+ tooltip: 'Last Blood at, also known as last solve time, in minutes',
69
+ },
70
+ ];
71
+ problemStatisticsSource;
72
+ problemStatisticsCache;
73
+ get problemStatistics() {
74
+ if (!this.showProblemStatisticsFooter && !this.showSEColumn) {
75
+ return [];
76
+ }
77
+ if (this.problemStatisticsSource !== this.data || !this.problemStatisticsCache) {
78
+ this.problemStatisticsSource = this.data;
79
+ this.problemStatisticsCache = calculateProblemStatisticsFooter(this.data);
80
+ }
81
+ return this.problemStatisticsCache;
82
+ }
83
+ isSupportedVersion() {
84
+ return caniuse(this.data.version);
85
+ }
86
+ showTimeColumn() {
87
+ return shouldShowTimeColumn(this.data.rows);
88
+ }
89
+ showAvatarInOrganization() {
90
+ return this.splitOrganization && this.userAvatarPlacement === 'organization';
91
+ }
92
+ leftFooterColumnCount() {
93
+ return this.data.series.length + 1 + 1 + (this.showTimeColumn() ? 1 : 0) + (this.splitOrganization ? 1 : 0);
94
+ }
95
+ getRankValues(row) {
96
+ return row.rankValues || this.data.series.map(() => ({ rank: null, segmentIndex: null }));
97
+ }
98
+ getRankText(rankValue, row) {
99
+ return rankValue.rank ? rankValue.rank : row.user.official === false ? '*' : '';
100
+ }
101
+ resolveDisplayText(text) {
102
+ return resolveText(text);
103
+ }
104
+ resolveSeriesColumnTitle(series, index) {
105
+ const seriesTitles = this.columnTitles?.series;
106
+ if (typeof seriesTitles === 'function') {
107
+ return seriesTitles(series, index) ?? series.title;
108
+ }
109
+ if (Array.isArray(seriesTitles)) {
110
+ return seriesTitles[index] ?? series.title;
111
+ }
112
+ return series.title;
113
+ }
114
+ resolveColumnTitle(key, fallback) {
115
+ return this.columnTitles?.[key] ?? fallback;
116
+ }
117
+ problemAlias(problem, problemIndex) {
118
+ return problem.alias || numberToAlphabet(problemIndex);
119
+ }
120
+ problemStatsTitle(statistics) {
121
+ const ratio = statistics.submitted ? ((statistics.accepted / statistics.submitted) * 100).toFixed(1) : 0;
122
+ return `${statistics.accepted} / ${statistics.submitted} (${ratio}%)`;
123
+ }
124
+ problemHeaderBackgroundImage(problem, gradientDirection = 180) {
125
+ return getProblemHeaderBackgroundImage(problem.style, this.theme, gradientDirection);
126
+ }
127
+ resolvedUserMarkers(user) {
128
+ return resolveUserMarkers(user, this.data.markers).map((marker) => ({
129
+ marker,
130
+ presentation: getMarkerPresentation(marker, this.theme),
131
+ }));
132
+ }
133
+ formatAssetUrl(url, field) {
134
+ return resolveSrkAssetUrl(url, field, this.formatSrkAssetUrl);
135
+ }
136
+ formatTime(time) {
137
+ return formatTimeDuration(time, 'min', Math.floor);
138
+ }
139
+ calculateDirtPercentage(row) {
140
+ return calculateDirtPercentage(row);
141
+ }
142
+ calculateSEValue(row, problemStatistics) {
143
+ return calculateSEValue(row, problemStatistics);
144
+ }
145
+ statusPresentation(status) {
146
+ return getRankProblemStatusCellPresentation(status, this.data, this.statusCellPreset);
147
+ }
148
+ isNumber(value) {
149
+ return typeof value === 'number';
150
+ }
151
+ getStatusSolutions(status) {
152
+ return [...(status.solutions || [])].reverse();
153
+ }
154
+ statusCellClass(status) {
155
+ const classNames = ['srk-prest-status-block', 'srk--text-center', 'srk--nowrap'];
156
+ if (this.isStatusClickable(status)) {
157
+ classNames.push('srk--cursor-pointer');
158
+ }
159
+ if (this.statusColorAsText) {
160
+ classNames.push('srk-prest-status-block-color-text');
161
+ }
162
+ if (status.result === 'FB') {
163
+ classNames.push('srk-prest-status-block-fb');
164
+ }
165
+ else if (status.result === 'AC') {
166
+ classNames.push('srk-prest-status-block-accepted');
167
+ }
168
+ else if (status.result === '?') {
169
+ classNames.push('srk-prest-status-block-frozen');
170
+ }
171
+ else if (status.result === 'RJ') {
172
+ classNames.push('srk-prest-status-block-failed');
173
+ }
174
+ return classNames.join(' ');
175
+ }
176
+ isStatusClickable(status) {
177
+ return this.getStatusSolutions(status).length > 0;
178
+ }
179
+ statusCellRole(status) {
180
+ return this.isStatusClickable(status) ? 'button' : null;
181
+ }
182
+ statusCellTabIndex(status) {
183
+ return this.isStatusClickable(status) ? 0 : null;
184
+ }
185
+ buildUserCellContext(row, rowIndex) {
186
+ return {
187
+ $implicit: row.user,
188
+ user: row.user,
189
+ row,
190
+ rowIndex,
191
+ ranklist: this.data,
192
+ markers: this.data.markers,
193
+ hideOrganization: this.splitOrganization,
194
+ hideAvatar: this.showAvatarInOrganization(),
195
+ onClick: (event) => this.emitUserClick(event, row, rowIndex),
196
+ };
197
+ }
198
+ buildStatusCellContext(row, rowIndex, status, problemIndex) {
199
+ return {
200
+ $implicit: status,
201
+ status,
202
+ problem: this.data.problems[problemIndex],
203
+ problemIndex,
204
+ user: row.user,
205
+ row,
206
+ rowIndex,
207
+ ranklist: this.data,
208
+ solutions: this.getStatusSolutions(status),
209
+ statusCellPreset: this.statusCellPreset,
210
+ statusColorAsText: this.statusColorAsText,
211
+ emptyStatusPlaceholder: this.emptyStatusPlaceholder,
212
+ onClick: (event) => this.emitSolutionClick(event, row, rowIndex, status, problemIndex),
213
+ };
214
+ }
215
+ activateUserCellFromKeyboard(event, row, rowIndex) {
216
+ event.preventDefault();
217
+ this.emitUserClick(undefined, row, rowIndex);
218
+ }
219
+ activateStatusCellFromKeyboard(event, row, rowIndex, status, problemIndex) {
220
+ event.preventDefault();
221
+ this.emitSolutionClick(undefined, row, rowIndex, status, problemIndex);
222
+ }
223
+ emitUserClick(event, row, rowIndex) {
224
+ if (event) {
225
+ captureModalTriggerPointFromMouseEvent(event, {
226
+ source: 'user-cell',
227
+ context: {
228
+ rowIndex,
229
+ userId: row.user.id || null,
230
+ userName: this.resolveDisplayText(row.user.name),
231
+ },
232
+ });
233
+ }
234
+ this.userClick.emit({
235
+ user: row.user,
236
+ row,
237
+ rowIndex,
238
+ ranklist: this.data,
239
+ });
240
+ }
241
+ emitSolutionClick(event, row, rowIndex, status, problemIndex) {
242
+ const solutions = this.getStatusSolutions(status);
243
+ if (!solutions.length) {
244
+ return;
245
+ }
246
+ if (event) {
247
+ captureModalTriggerPointFromMouseEvent(event, {
248
+ source: 'status-cell',
249
+ context: {
250
+ rowIndex,
251
+ problemIndex,
252
+ problemAlias: this.data.problems[problemIndex]?.alias || null,
253
+ problemTitle: this.data.problems[problemIndex] ? this.resolveDisplayText(this.data.problems[problemIndex].title) : null,
254
+ userId: row.user.id || null,
255
+ },
256
+ });
257
+ }
258
+ this.solutionClick.emit({
259
+ user: row.user,
260
+ row,
261
+ rowIndex,
262
+ problemIndex,
263
+ problem: this.data.problems[problemIndex],
264
+ status,
265
+ solutions,
266
+ ranklist: this.data,
267
+ });
268
+ }
269
+ resolveSeriesSegment(rankValue, series) {
270
+ const index = rankValue.segmentIndex || rankValue.segmentIndex === 0 ? rankValue.segmentIndex : -1;
271
+ return (series?.segments || [])[index] || {};
272
+ }
273
+ isSeriesSegmentedColumn(series) {
274
+ return (series?.segments || []).some((segment) => typeof segment.style === 'string');
275
+ }
276
+ getSeriesSegmentClass(rankValue, series) {
277
+ const segmentStyle = this.resolveSeriesSegment(rankValue, series).style;
278
+ return typeof segmentStyle === 'string' ? `srk-preset-series-segment-${segmentStyle}` : '';
279
+ }
280
+ getSeriesSegmentStyle(rankValue, series) {
281
+ const emptyColor = {
282
+ [EnumTheme.light]: undefined,
283
+ [EnumTheme.dark]: undefined,
284
+ };
285
+ const segmentStyle = this.resolveSeriesSegment(rankValue, series).style;
286
+ if (!segmentStyle || typeof segmentStyle === 'string') {
287
+ return {};
288
+ }
289
+ const style = resolveStyle(segmentStyle);
290
+ const textColor = style.textColor || emptyColor;
291
+ const backgroundColor = style.backgroundColor || emptyColor;
292
+ return {
293
+ color: textColor[this.theme],
294
+ backgroundColor: backgroundColor[this.theme],
295
+ };
296
+ }
297
+ getProblemStatisticsFooterCellPrimary(key, stat) {
298
+ switch (key) {
299
+ case 'accepted':
300
+ return stat.accepted;
301
+ case 'tried':
302
+ return stat.tried;
303
+ case 'submitted':
304
+ return stat.submitted;
305
+ case 'dirt':
306
+ return stat.dirt;
307
+ case 'se':
308
+ return formatProblemStatisticsAverageHardness(stat);
309
+ case 'firstAccepted':
310
+ return formatProblemStatisticsAcceptedMinute(stat.firstAcceptedTime);
311
+ case 'lastAccepted':
312
+ return formatProblemStatisticsAcceptedMinute(stat.lastAcceptedTime);
313
+ default:
314
+ return '';
315
+ }
316
+ }
317
+ getProblemStatisticsFooterCellSecondary(key, stat) {
318
+ switch (key) {
319
+ case 'accepted':
320
+ return formatProblemStatisticsPercent(stat.accepted, stat.participantCount);
321
+ case 'tried':
322
+ return formatProblemStatisticsPercent(stat.tried, stat.participantCount);
323
+ case 'dirt':
324
+ return formatProblemStatisticsPercent(stat.dirt, stat.dirtSubmitted);
325
+ default:
326
+ return undefined;
327
+ }
328
+ }
329
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RanklistComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
330
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: RanklistComponent, isStandalone: true, selector: "srk-ranklist", inputs: { data: "data", theme: "theme", borderedRows: "borderedRows", rowBordered: "rowBordered", columnBordered: "columnBordered", stripedRows: "stripedRows", formatSrkAssetUrl: "formatSrkAssetUrl", splitOrganization: "splitOrganization", columnTitles: "columnTitles", statusCellPreset: "statusCellPreset", statusColorAsText: "statusColorAsText", showProblemStatisticsFooter: "showProblemStatisticsFooter", showDirtColumn: "showDirtColumn", showSEColumn: "showSEColumn", emptyStatusPlaceholder: "emptyStatusPlaceholder", userAvatarPlacement: "userAvatarPlacement" }, outputs: { userClick: "userClick", solutionClick: "solutionClick" }, queries: [{ propertyName: "statusCellTemplate", first: true, predicate: SrkStatusCellTemplateDirective, descendants: true }, { propertyName: "userCellTemplate", first: true, predicate: SrkUserCellTemplateDirective, descendants: true }], ngImport: i0, template: `
331
+ <div *ngIf="data.type !== 'general'; else versionState">
332
+ srk type "{{ data.type }}" is not supported
333
+ </div>
334
+
335
+ <ng-template #versionState>
336
+ <div *ngIf="!isSupportedVersion(); else ranklistTable">
337
+ srk version "{{ data.version }}" is not supported (current supported: {{ supportedVersions }})
338
+ </div>
339
+ </ng-template>
340
+
341
+ <ng-template #ranklistTable>
342
+ <div class="srk-common-table srk-main">
343
+ <table
344
+ [class.srk-table-row-bordered]="borderedRows || rowBordered"
345
+ [class.srk-table-column-bordered]="columnBordered"
346
+ [class.srk-table-row-striped]="stripedRows"
347
+ >
348
+ <thead>
349
+ <tr>
350
+ <th
351
+ *ngFor="let seriesItem of data.series; let seriesIndex = index"
352
+ class="srk-series-header srk--text-right srk--nowrap"
353
+ [class.srk-series-segmented-column]="isSeriesSegmentedColumn(seriesItem)"
354
+ >
355
+ {{ resolveSeriesColumnTitle(seriesItem, seriesIndex) }}
356
+ </th>
357
+ <th
358
+ *ngIf="splitOrganization"
359
+ class="srk-organization-header srk--text-left srk--nowrap"
360
+ >
361
+ {{ resolveColumnTitle('organization', 'Organization') }}
362
+ </th>
363
+ <th class="srk--text-left srk--nowrap">{{ resolveColumnTitle('user', 'Name') }}</th>
364
+ <th class="srk--text-right srk--nowrap">{{ resolveColumnTitle('score', 'Score') }}</th>
365
+ <th *ngIf="showTimeColumn()" class="srk--text-right srk--nowrap">
366
+ {{ resolveColumnTitle('time', 'Time') }}
367
+ </th>
368
+ <th
369
+ *ngFor="let problem of data.problems; let problemIndex = index"
370
+ class="srk--nowrap srk-problem-header"
371
+ [style.background-image]="problemHeaderBackgroundImage(problem)"
372
+ >
373
+ <a
374
+ *ngIf="problem.link; else unlinkedProblemHeader"
375
+ [href]="problem.link"
376
+ target="_blank"
377
+ rel="noopener noreferrer"
378
+ style="color: unset"
379
+ >
380
+ <span class="srk--display-block">{{ problemAlias(problem, problemIndex) }}</span>
381
+ <span
382
+ *ngIf="problem.statistics"
383
+ class="srk--display-block srk-problem-stats"
384
+ [title]="problemStatsTitle(problem.statistics)"
385
+ >
386
+ {{ problem.statistics.accepted }}
387
+ </span>
388
+ </a>
389
+ <ng-template #unlinkedProblemHeader>
390
+ <span class="srk--display-block">{{ problemAlias(problem, problemIndex) }}</span>
391
+ <span
392
+ *ngIf="problem.statistics"
393
+ class="srk--display-block srk-problem-stats"
394
+ [title]="problemStatsTitle(problem.statistics)"
395
+ >
396
+ {{ problem.statistics.accepted }}
397
+ </span>
398
+ </ng-template>
399
+ </th>
400
+ <th *ngIf="showDirtColumn" class="srk-dirt-header srk--text-right srk--nowrap">
401
+ {{ resolveColumnTitle('dirt', 'Dirt') }}
402
+ </th>
403
+ <th *ngIf="showSEColumn" class="srk-se-header srk--text-right srk--nowrap">
404
+ {{ resolveColumnTitle('se', 'SE') }}
405
+ </th>
406
+ </tr>
407
+ </thead>
408
+ <tbody>
409
+ <tr *ngFor="let row of data.rows; let rowIndex = index">
410
+ <td
411
+ *ngFor="let rankValue of getRankValues(row); let seriesIndex = index"
412
+ class="srk--text-right srk--nowrap"
413
+ [ngClass]="getSeriesSegmentClass(rankValue, data.series[seriesIndex])"
414
+ [class.srk-series-segmented-column]="isSeriesSegmentedColumn(data.series[seriesIndex])"
415
+ [ngStyle]="getSeriesSegmentStyle(rankValue, data.series[seriesIndex])"
416
+ >
417
+ {{ getRankText(rankValue, row) }}
418
+ </td>
419
+
420
+ <td
421
+ *ngIf="splitOrganization"
422
+ class="srk-organization-cell srk--text-left srk--nowrap"
423
+ [class.srk-organization-cell-avatar]="showAvatarInOrganization() && !!row.user.avatar"
424
+ >
425
+ <div class="srk-organization-cell-content">
426
+ <div *ngIf="showAvatarInOrganization() && row.user.avatar" class="srk-user-avatar">
427
+ <img
428
+ [src]="formatAssetUrl(row.user.avatar, 'user.avatar')"
429
+ alt="User Avatar"
430
+ />
431
+ </div>
432
+ <span
433
+ class="srk-organization-name-text"
434
+ [title]="row.user.organization ? resolveDisplayText(row.user.organization) : ''"
435
+ [textContent]="row.user.organization ? resolveDisplayText(row.user.organization) : ''"
436
+ ></span>
437
+ </div>
438
+ </td>
439
+
440
+ <ng-container *ngIf="userCellTemplate; else defaultUserCell">
441
+ <ng-container
442
+ [ngTemplateOutlet]="userCellTemplate.templateRef"
443
+ [ngTemplateOutletContext]="buildUserCellContext(row, rowIndex)"
444
+ />
445
+ </ng-container>
446
+ <ng-template #defaultUserCell>
447
+ <td
448
+ class="srk--text-left srk--nowrap srk-user-cell srk--cursor-pointer"
449
+ role="button"
450
+ tabindex="0"
451
+ (click)="emitUserClick($event, row, rowIndex)"
452
+ (keydown.enter)="activateUserCellFromKeyboard($event, row, rowIndex)"
453
+ (keydown.space)="activateUserCellFromKeyboard($event, row, rowIndex)"
454
+ >
455
+ <div class="srk-user-cell-content">
456
+ <div *ngIf="row.user.avatar && !showAvatarInOrganization()" class="srk-user-avatar">
457
+ <img
458
+ [src]="formatAssetUrl(row.user.avatar, 'user.avatar')"
459
+ alt="User Avatar"
460
+ />
461
+ </div>
462
+ <div class="srk-user-body">
463
+ <div class="srk-user-name-row">
464
+ <span
465
+ class="srk-user-name-text"
466
+ [title]="resolveDisplayText(row.user.name)"
467
+ >
468
+ {{ resolveDisplayText(row.user.name) }}
469
+ </span>
470
+ <span class="srk-marker-dot-group">
471
+ <span
472
+ *ngFor="let marker of resolvedUserMarkers(row.user)"
473
+ class="srk-marker srk-marker-dot srk--c-tooltip"
474
+ [ngClass]="marker.presentation.className"
475
+ [ngStyle]="marker.presentation.style"
476
+ [attr.data-tooltip]="resolveDisplayText(marker.marker.label)"
477
+ ></span>
478
+ </span>
479
+ </div>
480
+ <p
481
+ *ngIf="row.user.organization && !splitOrganization"
482
+ class="srk-user-secondary-text srk--text-ellipsis"
483
+ title=""
484
+ >
485
+ {{ resolveDisplayText(row.user.organization) }}
486
+ </p>
487
+ </div>
488
+ </div>
489
+ </td>
490
+ </ng-template>
491
+
492
+ <td class="srk--text-right srk--nowrap">{{ row.score.value }}</td>
493
+ <td *ngIf="showTimeColumn()" class="srk--text-right srk--nowrap">
494
+ {{ row.score.time ? formatTime(row.score.time) : '-' }}
495
+ </td>
496
+
497
+ <ng-container *ngFor="let status of row.statuses; let problemIndex = index">
498
+ <ng-container *ngIf="statusCellTemplate; else defaultStatusCell">
499
+ <ng-container
500
+ [ngTemplateOutlet]="statusCellTemplate.templateRef"
501
+ [ngTemplateOutletContext]="buildStatusCellContext(row, rowIndex, status, problemIndex)"
502
+ />
503
+ </ng-container>
504
+ <ng-template #defaultStatusCell>
505
+ <td
506
+ *ngIf="status.result === 'FB' || status.result === 'AC'; else failedOrFrozenStatus"
507
+ [ngClass]="statusCellClass(status)"
508
+ [attr.role]="statusCellRole(status)"
509
+ [attr.tabindex]="statusCellTabIndex(status)"
510
+ (click)="emitSolutionClick($event, row, rowIndex, status, problemIndex)"
511
+ (keydown.enter)="activateStatusCellFromKeyboard($event, row, rowIndex, status, problemIndex)"
512
+ (keydown.space)="activateStatusCellFromKeyboard($event, row, rowIndex, status, problemIndex)"
513
+ >
514
+ <span
515
+ *ngIf="statusColorAsText && status.result === 'FB'"
516
+ class="srk-prest-status-block-fb-star"
517
+ [textContent]="firstBloodStar"
518
+ ></span>
519
+ <ng-container *ngIf="statusPresentation(status) as presentation">
520
+ <ng-container *ngIf="isNumber(presentation.score); else statusText">
521
+ <span class="srk-prest-status-block-score">{{ presentation.score }}</span>
522
+ <span class="srk-prest-status-block-score-details">
523
+ {{ presentation.scoreDetails }}
524
+ </span>
525
+ </ng-container>
526
+ <ng-template #statusText>
527
+ <ng-container *ngIf="presentation.secondary !== undefined; else singleStatus">
528
+ <span class="srk-prest-status-block-primary">{{ presentation.primary || '' }}</span>
529
+ <span [textContent]="statusSeparator"></span>
530
+ <span class="srk-prest-status-block-secondary">{{ presentation.secondary }}</span>
531
+ </ng-container>
532
+ <ng-template #singleStatus>{{ presentation.primary }}</ng-template>
533
+ </ng-template>
534
+ </ng-container>
535
+ </td>
536
+ <ng-template #failedOrFrozenStatus>
537
+ <td
538
+ *ngIf="status.result === '?' || status.result === 'RJ'; else emptyStatus"
539
+ [ngClass]="statusCellClass(status)"
540
+ [attr.role]="statusCellRole(status)"
541
+ [attr.tabindex]="statusCellTabIndex(status)"
542
+ (click)="emitSolutionClick($event, row, rowIndex, status, problemIndex)"
543
+ (keydown.enter)="activateStatusCellFromKeyboard($event, row, rowIndex, status, problemIndex)"
544
+ (keydown.space)="activateStatusCellFromKeyboard($event, row, rowIndex, status, problemIndex)"
545
+ >
546
+ <ng-container *ngIf="statusPresentation(status) as presentation">
547
+ <ng-container *ngIf="presentation.secondary !== undefined; else singleStatus">
548
+ <span class="srk-prest-status-block-primary">{{ presentation.primary || '' }}</span>
549
+ <span [textContent]="statusSeparator"></span>
550
+ <span class="srk-prest-status-block-secondary">{{ presentation.secondary }}</span>
551
+ </ng-container>
552
+ <ng-template #singleStatus>{{ presentation.primary }}</ng-template>
553
+ </ng-container>
554
+ </td>
555
+ </ng-template>
556
+ <ng-template #emptyStatus>
557
+ <td class="srk-status-placeholder-cell srk--text-center srk--nowrap">
558
+ {{ emptyStatusPlaceholder }}
559
+ </td>
560
+ </ng-template>
561
+ </ng-template>
562
+ </ng-container>
563
+
564
+ <td *ngIf="showDirtColumn" class="srk-dirt-cell srk--text-right srk--nowrap">
565
+ {{ calculateDirtPercentage(row) }}
566
+ </td>
567
+ <td *ngIf="showSEColumn" class="srk-se-cell srk--text-right srk--nowrap">
568
+ {{ calculateSEValue(row, problemStatistics) }}
569
+ </td>
570
+ </tr>
571
+ </tbody>
572
+ <tfoot *ngIf="showProblemStatisticsFooter">
573
+ <tr
574
+ *ngFor="let footerRow of problemStatisticsFooterRows"
575
+ class="srk-problem-statistics-footer-row"
576
+ >
577
+ <td
578
+ class="srk-problem-statistics-footer-labels srk--text-right srk--nowrap"
579
+ [attr.colspan]="leftFooterColumnCount()"
580
+ >
581
+ <span
582
+ class="srk-problem-statistics-footer-label srk--c-tooltip"
583
+ [attr.data-tooltip]="footerRow.tooltip"
584
+ >
585
+ {{ footerRow.label }}
586
+ </span>
587
+ </td>
588
+ <td
589
+ *ngFor="let stat of problemStatistics"
590
+ class="srk-problem-statistics-footer-cell srk--text-center srk--nowrap"
591
+ >
592
+ <span class="srk-problem-statistics-footer-primary">
593
+ {{ getProblemStatisticsFooterCellPrimary(footerRow.key, stat) }}
594
+ </span>
595
+ <ng-container *ngIf="getProblemStatisticsFooterCellSecondary(footerRow.key, stat) !== undefined">
596
+ <span> </span>
597
+ <span class="srk-problem-statistics-footer-secondary">
598
+ {{ getProblemStatisticsFooterCellSecondary(footerRow.key, stat) }}
599
+ </span>
600
+ </ng-container>
601
+ </td>
602
+ <td
603
+ *ngIf="showDirtColumn"
604
+ class="srk-problem-statistics-footer-cell srk-extra-statistics-footer-cell srk-dirt-footer-cell srk--nowrap"
605
+ >
606
+ <span class="srk-problem-statistics-footer-primary"></span>
607
+ </td>
608
+ <td
609
+ *ngIf="showSEColumn"
610
+ class="srk-problem-statistics-footer-cell srk-extra-statistics-footer-cell srk-se-footer-cell srk--nowrap"
611
+ >
612
+ <span class="srk-problem-statistics-footer-primary"></span>
613
+ </td>
614
+ </tr>
615
+ <tr class="srk-problem-statistics-footer-row srk-problem-statistics-footer-problem-label-row">
616
+ <td
617
+ class="srk-problem-statistics-footer-labels srk--text-right srk--nowrap"
618
+ [attr.colspan]="leftFooterColumnCount()"
619
+ ></td>
620
+ <td
621
+ *ngFor="let problem of data.problems; let problemIndex = index"
622
+ class="srk-problem-statistics-footer-cell srk-problem-statistics-footer-problem-header srk-problem-header srk--text-center srk--nowrap"
623
+ [style.background-image]="problemHeaderBackgroundImage(problem, 0)"
624
+ >
625
+ <span class="srk--display-block">{{ problemAlias(problem, problemIndex) }}</span>
626
+ </td>
627
+ <td
628
+ *ngIf="showDirtColumn"
629
+ class="srk-problem-statistics-footer-cell srk-extra-statistics-footer-cell srk-dirt-footer-cell srk--nowrap"
630
+ >
631
+ <span class="srk-problem-statistics-footer-primary"></span>
632
+ </td>
633
+ <td
634
+ *ngIf="showSEColumn"
635
+ class="srk-problem-statistics-footer-cell srk-extra-statistics-footer-cell srk-se-footer-cell srk--nowrap"
636
+ >
637
+ <span class="srk-problem-statistics-footer-primary"></span>
638
+ </td>
639
+ </tr>
640
+ </tfoot>
641
+ </table>
642
+ </div>
643
+ </ng-template>
644
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
645
+ }
646
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RanklistComponent, decorators: [{
647
+ type: Component,
648
+ args: [{
649
+ selector: 'srk-ranklist',
650
+ standalone: true,
651
+ changeDetection: ChangeDetectionStrategy.OnPush,
652
+ imports: [CommonModule],
653
+ template: `
654
+ <div *ngIf="data.type !== 'general'; else versionState">
655
+ srk type "{{ data.type }}" is not supported
656
+ </div>
657
+
658
+ <ng-template #versionState>
659
+ <div *ngIf="!isSupportedVersion(); else ranklistTable">
660
+ srk version "{{ data.version }}" is not supported (current supported: {{ supportedVersions }})
661
+ </div>
662
+ </ng-template>
663
+
664
+ <ng-template #ranklistTable>
665
+ <div class="srk-common-table srk-main">
666
+ <table
667
+ [class.srk-table-row-bordered]="borderedRows || rowBordered"
668
+ [class.srk-table-column-bordered]="columnBordered"
669
+ [class.srk-table-row-striped]="stripedRows"
670
+ >
671
+ <thead>
672
+ <tr>
673
+ <th
674
+ *ngFor="let seriesItem of data.series; let seriesIndex = index"
675
+ class="srk-series-header srk--text-right srk--nowrap"
676
+ [class.srk-series-segmented-column]="isSeriesSegmentedColumn(seriesItem)"
677
+ >
678
+ {{ resolveSeriesColumnTitle(seriesItem, seriesIndex) }}
679
+ </th>
680
+ <th
681
+ *ngIf="splitOrganization"
682
+ class="srk-organization-header srk--text-left srk--nowrap"
683
+ >
684
+ {{ resolveColumnTitle('organization', 'Organization') }}
685
+ </th>
686
+ <th class="srk--text-left srk--nowrap">{{ resolveColumnTitle('user', 'Name') }}</th>
687
+ <th class="srk--text-right srk--nowrap">{{ resolveColumnTitle('score', 'Score') }}</th>
688
+ <th *ngIf="showTimeColumn()" class="srk--text-right srk--nowrap">
689
+ {{ resolveColumnTitle('time', 'Time') }}
690
+ </th>
691
+ <th
692
+ *ngFor="let problem of data.problems; let problemIndex = index"
693
+ class="srk--nowrap srk-problem-header"
694
+ [style.background-image]="problemHeaderBackgroundImage(problem)"
695
+ >
696
+ <a
697
+ *ngIf="problem.link; else unlinkedProblemHeader"
698
+ [href]="problem.link"
699
+ target="_blank"
700
+ rel="noopener noreferrer"
701
+ style="color: unset"
702
+ >
703
+ <span class="srk--display-block">{{ problemAlias(problem, problemIndex) }}</span>
704
+ <span
705
+ *ngIf="problem.statistics"
706
+ class="srk--display-block srk-problem-stats"
707
+ [title]="problemStatsTitle(problem.statistics)"
708
+ >
709
+ {{ problem.statistics.accepted }}
710
+ </span>
711
+ </a>
712
+ <ng-template #unlinkedProblemHeader>
713
+ <span class="srk--display-block">{{ problemAlias(problem, problemIndex) }}</span>
714
+ <span
715
+ *ngIf="problem.statistics"
716
+ class="srk--display-block srk-problem-stats"
717
+ [title]="problemStatsTitle(problem.statistics)"
718
+ >
719
+ {{ problem.statistics.accepted }}
720
+ </span>
721
+ </ng-template>
722
+ </th>
723
+ <th *ngIf="showDirtColumn" class="srk-dirt-header srk--text-right srk--nowrap">
724
+ {{ resolveColumnTitle('dirt', 'Dirt') }}
725
+ </th>
726
+ <th *ngIf="showSEColumn" class="srk-se-header srk--text-right srk--nowrap">
727
+ {{ resolveColumnTitle('se', 'SE') }}
728
+ </th>
729
+ </tr>
730
+ </thead>
731
+ <tbody>
732
+ <tr *ngFor="let row of data.rows; let rowIndex = index">
733
+ <td
734
+ *ngFor="let rankValue of getRankValues(row); let seriesIndex = index"
735
+ class="srk--text-right srk--nowrap"
736
+ [ngClass]="getSeriesSegmentClass(rankValue, data.series[seriesIndex])"
737
+ [class.srk-series-segmented-column]="isSeriesSegmentedColumn(data.series[seriesIndex])"
738
+ [ngStyle]="getSeriesSegmentStyle(rankValue, data.series[seriesIndex])"
739
+ >
740
+ {{ getRankText(rankValue, row) }}
741
+ </td>
742
+
743
+ <td
744
+ *ngIf="splitOrganization"
745
+ class="srk-organization-cell srk--text-left srk--nowrap"
746
+ [class.srk-organization-cell-avatar]="showAvatarInOrganization() && !!row.user.avatar"
747
+ >
748
+ <div class="srk-organization-cell-content">
749
+ <div *ngIf="showAvatarInOrganization() && row.user.avatar" class="srk-user-avatar">
750
+ <img
751
+ [src]="formatAssetUrl(row.user.avatar, 'user.avatar')"
752
+ alt="User Avatar"
753
+ />
754
+ </div>
755
+ <span
756
+ class="srk-organization-name-text"
757
+ [title]="row.user.organization ? resolveDisplayText(row.user.organization) : ''"
758
+ [textContent]="row.user.organization ? resolveDisplayText(row.user.organization) : ''"
759
+ ></span>
760
+ </div>
761
+ </td>
762
+
763
+ <ng-container *ngIf="userCellTemplate; else defaultUserCell">
764
+ <ng-container
765
+ [ngTemplateOutlet]="userCellTemplate.templateRef"
766
+ [ngTemplateOutletContext]="buildUserCellContext(row, rowIndex)"
767
+ />
768
+ </ng-container>
769
+ <ng-template #defaultUserCell>
770
+ <td
771
+ class="srk--text-left srk--nowrap srk-user-cell srk--cursor-pointer"
772
+ role="button"
773
+ tabindex="0"
774
+ (click)="emitUserClick($event, row, rowIndex)"
775
+ (keydown.enter)="activateUserCellFromKeyboard($event, row, rowIndex)"
776
+ (keydown.space)="activateUserCellFromKeyboard($event, row, rowIndex)"
777
+ >
778
+ <div class="srk-user-cell-content">
779
+ <div *ngIf="row.user.avatar && !showAvatarInOrganization()" class="srk-user-avatar">
780
+ <img
781
+ [src]="formatAssetUrl(row.user.avatar, 'user.avatar')"
782
+ alt="User Avatar"
783
+ />
784
+ </div>
785
+ <div class="srk-user-body">
786
+ <div class="srk-user-name-row">
787
+ <span
788
+ class="srk-user-name-text"
789
+ [title]="resolveDisplayText(row.user.name)"
790
+ >
791
+ {{ resolveDisplayText(row.user.name) }}
792
+ </span>
793
+ <span class="srk-marker-dot-group">
794
+ <span
795
+ *ngFor="let marker of resolvedUserMarkers(row.user)"
796
+ class="srk-marker srk-marker-dot srk--c-tooltip"
797
+ [ngClass]="marker.presentation.className"
798
+ [ngStyle]="marker.presentation.style"
799
+ [attr.data-tooltip]="resolveDisplayText(marker.marker.label)"
800
+ ></span>
801
+ </span>
802
+ </div>
803
+ <p
804
+ *ngIf="row.user.organization && !splitOrganization"
805
+ class="srk-user-secondary-text srk--text-ellipsis"
806
+ title=""
807
+ >
808
+ {{ resolveDisplayText(row.user.organization) }}
809
+ </p>
810
+ </div>
811
+ </div>
812
+ </td>
813
+ </ng-template>
814
+
815
+ <td class="srk--text-right srk--nowrap">{{ row.score.value }}</td>
816
+ <td *ngIf="showTimeColumn()" class="srk--text-right srk--nowrap">
817
+ {{ row.score.time ? formatTime(row.score.time) : '-' }}
818
+ </td>
819
+
820
+ <ng-container *ngFor="let status of row.statuses; let problemIndex = index">
821
+ <ng-container *ngIf="statusCellTemplate; else defaultStatusCell">
822
+ <ng-container
823
+ [ngTemplateOutlet]="statusCellTemplate.templateRef"
824
+ [ngTemplateOutletContext]="buildStatusCellContext(row, rowIndex, status, problemIndex)"
825
+ />
826
+ </ng-container>
827
+ <ng-template #defaultStatusCell>
828
+ <td
829
+ *ngIf="status.result === 'FB' || status.result === 'AC'; else failedOrFrozenStatus"
830
+ [ngClass]="statusCellClass(status)"
831
+ [attr.role]="statusCellRole(status)"
832
+ [attr.tabindex]="statusCellTabIndex(status)"
833
+ (click)="emitSolutionClick($event, row, rowIndex, status, problemIndex)"
834
+ (keydown.enter)="activateStatusCellFromKeyboard($event, row, rowIndex, status, problemIndex)"
835
+ (keydown.space)="activateStatusCellFromKeyboard($event, row, rowIndex, status, problemIndex)"
836
+ >
837
+ <span
838
+ *ngIf="statusColorAsText && status.result === 'FB'"
839
+ class="srk-prest-status-block-fb-star"
840
+ [textContent]="firstBloodStar"
841
+ ></span>
842
+ <ng-container *ngIf="statusPresentation(status) as presentation">
843
+ <ng-container *ngIf="isNumber(presentation.score); else statusText">
844
+ <span class="srk-prest-status-block-score">{{ presentation.score }}</span>
845
+ <span class="srk-prest-status-block-score-details">
846
+ {{ presentation.scoreDetails }}
847
+ </span>
848
+ </ng-container>
849
+ <ng-template #statusText>
850
+ <ng-container *ngIf="presentation.secondary !== undefined; else singleStatus">
851
+ <span class="srk-prest-status-block-primary">{{ presentation.primary || '' }}</span>
852
+ <span [textContent]="statusSeparator"></span>
853
+ <span class="srk-prest-status-block-secondary">{{ presentation.secondary }}</span>
854
+ </ng-container>
855
+ <ng-template #singleStatus>{{ presentation.primary }}</ng-template>
856
+ </ng-template>
857
+ </ng-container>
858
+ </td>
859
+ <ng-template #failedOrFrozenStatus>
860
+ <td
861
+ *ngIf="status.result === '?' || status.result === 'RJ'; else emptyStatus"
862
+ [ngClass]="statusCellClass(status)"
863
+ [attr.role]="statusCellRole(status)"
864
+ [attr.tabindex]="statusCellTabIndex(status)"
865
+ (click)="emitSolutionClick($event, row, rowIndex, status, problemIndex)"
866
+ (keydown.enter)="activateStatusCellFromKeyboard($event, row, rowIndex, status, problemIndex)"
867
+ (keydown.space)="activateStatusCellFromKeyboard($event, row, rowIndex, status, problemIndex)"
868
+ >
869
+ <ng-container *ngIf="statusPresentation(status) as presentation">
870
+ <ng-container *ngIf="presentation.secondary !== undefined; else singleStatus">
871
+ <span class="srk-prest-status-block-primary">{{ presentation.primary || '' }}</span>
872
+ <span [textContent]="statusSeparator"></span>
873
+ <span class="srk-prest-status-block-secondary">{{ presentation.secondary }}</span>
874
+ </ng-container>
875
+ <ng-template #singleStatus>{{ presentation.primary }}</ng-template>
876
+ </ng-container>
877
+ </td>
878
+ </ng-template>
879
+ <ng-template #emptyStatus>
880
+ <td class="srk-status-placeholder-cell srk--text-center srk--nowrap">
881
+ {{ emptyStatusPlaceholder }}
882
+ </td>
883
+ </ng-template>
884
+ </ng-template>
885
+ </ng-container>
886
+
887
+ <td *ngIf="showDirtColumn" class="srk-dirt-cell srk--text-right srk--nowrap">
888
+ {{ calculateDirtPercentage(row) }}
889
+ </td>
890
+ <td *ngIf="showSEColumn" class="srk-se-cell srk--text-right srk--nowrap">
891
+ {{ calculateSEValue(row, problemStatistics) }}
892
+ </td>
893
+ </tr>
894
+ </tbody>
895
+ <tfoot *ngIf="showProblemStatisticsFooter">
896
+ <tr
897
+ *ngFor="let footerRow of problemStatisticsFooterRows"
898
+ class="srk-problem-statistics-footer-row"
899
+ >
900
+ <td
901
+ class="srk-problem-statistics-footer-labels srk--text-right srk--nowrap"
902
+ [attr.colspan]="leftFooterColumnCount()"
903
+ >
904
+ <span
905
+ class="srk-problem-statistics-footer-label srk--c-tooltip"
906
+ [attr.data-tooltip]="footerRow.tooltip"
907
+ >
908
+ {{ footerRow.label }}
909
+ </span>
910
+ </td>
911
+ <td
912
+ *ngFor="let stat of problemStatistics"
913
+ class="srk-problem-statistics-footer-cell srk--text-center srk--nowrap"
914
+ >
915
+ <span class="srk-problem-statistics-footer-primary">
916
+ {{ getProblemStatisticsFooterCellPrimary(footerRow.key, stat) }}
917
+ </span>
918
+ <ng-container *ngIf="getProblemStatisticsFooterCellSecondary(footerRow.key, stat) !== undefined">
919
+ <span> </span>
920
+ <span class="srk-problem-statistics-footer-secondary">
921
+ {{ getProblemStatisticsFooterCellSecondary(footerRow.key, stat) }}
922
+ </span>
923
+ </ng-container>
924
+ </td>
925
+ <td
926
+ *ngIf="showDirtColumn"
927
+ class="srk-problem-statistics-footer-cell srk-extra-statistics-footer-cell srk-dirt-footer-cell srk--nowrap"
928
+ >
929
+ <span class="srk-problem-statistics-footer-primary"></span>
930
+ </td>
931
+ <td
932
+ *ngIf="showSEColumn"
933
+ class="srk-problem-statistics-footer-cell srk-extra-statistics-footer-cell srk-se-footer-cell srk--nowrap"
934
+ >
935
+ <span class="srk-problem-statistics-footer-primary"></span>
936
+ </td>
937
+ </tr>
938
+ <tr class="srk-problem-statistics-footer-row srk-problem-statistics-footer-problem-label-row">
939
+ <td
940
+ class="srk-problem-statistics-footer-labels srk--text-right srk--nowrap"
941
+ [attr.colspan]="leftFooterColumnCount()"
942
+ ></td>
943
+ <td
944
+ *ngFor="let problem of data.problems; let problemIndex = index"
945
+ class="srk-problem-statistics-footer-cell srk-problem-statistics-footer-problem-header srk-problem-header srk--text-center srk--nowrap"
946
+ [style.background-image]="problemHeaderBackgroundImage(problem, 0)"
947
+ >
948
+ <span class="srk--display-block">{{ problemAlias(problem, problemIndex) }}</span>
949
+ </td>
950
+ <td
951
+ *ngIf="showDirtColumn"
952
+ class="srk-problem-statistics-footer-cell srk-extra-statistics-footer-cell srk-dirt-footer-cell srk--nowrap"
953
+ >
954
+ <span class="srk-problem-statistics-footer-primary"></span>
955
+ </td>
956
+ <td
957
+ *ngIf="showSEColumn"
958
+ class="srk-problem-statistics-footer-cell srk-extra-statistics-footer-cell srk-se-footer-cell srk--nowrap"
959
+ >
960
+ <span class="srk-problem-statistics-footer-primary"></span>
961
+ </td>
962
+ </tr>
963
+ </tfoot>
964
+ </table>
965
+ </div>
966
+ </ng-template>
967
+ `,
968
+ }]
969
+ }], propDecorators: { data: [{
970
+ type: Input,
971
+ args: [{ required: true }]
972
+ }], theme: [{
973
+ type: Input
974
+ }], borderedRows: [{
975
+ type: Input
976
+ }], rowBordered: [{
977
+ type: Input
978
+ }], columnBordered: [{
979
+ type: Input
980
+ }], stripedRows: [{
981
+ type: Input
982
+ }], formatSrkAssetUrl: [{
983
+ type: Input
984
+ }], splitOrganization: [{
985
+ type: Input
986
+ }], columnTitles: [{
987
+ type: Input
988
+ }], statusCellPreset: [{
989
+ type: Input
990
+ }], statusColorAsText: [{
991
+ type: Input
992
+ }], showProblemStatisticsFooter: [{
993
+ type: Input
994
+ }], showDirtColumn: [{
995
+ type: Input
996
+ }], showSEColumn: [{
997
+ type: Input
998
+ }], emptyStatusPlaceholder: [{
999
+ type: Input
1000
+ }], userAvatarPlacement: [{
1001
+ type: Input
1002
+ }], userClick: [{
1003
+ type: Output
1004
+ }], solutionClick: [{
1005
+ type: Output
1006
+ }], statusCellTemplate: [{
1007
+ type: ContentChild,
1008
+ args: [SrkStatusCellTemplateDirective]
1009
+ }], userCellTemplate: [{
1010
+ type: ContentChild,
1011
+ args: [SrkUserCellTemplateDirective]
1012
+ }] } });
1013
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmFua2xpc3QuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9yYW5rbGlzdC9yYW5rbGlzdC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsU0FBUyxFQUNULFlBQVksRUFDWixZQUFZLEVBQ1osS0FBSyxFQUNMLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQ0wsU0FBUyxFQUNULGtCQUFrQixFQUNsQixnQkFBZ0IsRUFDaEIsWUFBWSxFQUNaLFdBQVcsRUFDWCxrQkFBa0IsR0FDbkIsTUFBTSxpQ0FBaUMsQ0FBQztBQUV6QyxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGdDQUFnQyxFQUNoQyxnQkFBZ0IsRUFDaEIsT0FBTyxFQUNQLHFDQUFxQyxFQUNyQyxzQ0FBc0MsRUFDdEMsOEJBQThCLEVBQzlCLHFCQUFxQixFQUNyQiwrQkFBK0IsRUFDL0Isb0NBQW9DLEVBQ3BDLGtCQUFrQixFQUNsQixvQkFBb0IsRUFDcEIsb0JBQW9CLEdBQ3JCLE1BQU0sbURBQW1ELENBQUM7QUFPM0QsT0FBTyxFQUFFLHNDQUFzQyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFRckYsT0FBTyxFQUNMLDhCQUE4QixHQUUvQixNQUFNLGtDQUFrQyxDQUFDO0FBQzFDLE9BQU8sRUFDTCw0QkFBNEIsR0FFN0IsTUFBTSxnQ0FBZ0MsQ0FBQzs7O0FBbVV4QyxNQUFNLE9BQU8saUJBQWlCO0lBQ0QsSUFBSSxDQUFrQjtJQUN4QyxLQUFLLEdBQWMsU0FBUyxDQUFDLEtBQUssQ0FBQztJQUNuQyxZQUFZLEdBQUcsS0FBSyxDQUFDO0lBQ3JCLFdBQVcsR0FBRyxLQUFLLENBQUM7SUFDcEIsY0FBYyxHQUFHLEtBQUssQ0FBQztJQUN2QixXQUFXLEdBQUcsS0FBSyxDQUFDO0lBQ3BCLGlCQUFpQixDQUEwQztJQUMzRCxpQkFBaUIsR0FBRyxLQUFLLENBQUM7SUFDMUIsWUFBWSxDQUF3QjtJQUNwQyxnQkFBZ0IsR0FBNkIsU0FBUyxDQUFDO0lBQ3ZELGlCQUFpQixHQUFHLEtBQUssQ0FBQztJQUMxQiwyQkFBMkIsR0FBRyxLQUFLLENBQUM7SUFDcEMsY0FBYyxHQUFHLEtBQUssQ0FBQztJQUN2QixZQUFZLEdBQUcsS0FBSyxDQUFDO0lBQ3JCLHNCQUFzQixHQUFrQixJQUFJLENBQUM7SUFDN0MsbUJBQW1CLEdBQWdDLE1BQU0sQ0FBQztJQUV6RCxTQUFTLEdBQUcsSUFBSSxZQUFZLEVBQW9CLENBQUM7SUFDakQsYUFBYSxHQUFHLElBQUksWUFBWSxFQUF3QixDQUFDO0lBR25FLGtCQUFrQixDQUFrQztJQUdwRCxnQkFBZ0IsQ0FBZ0M7SUFFdkMsaUJBQWlCLEdBQUcsb0JBQW9CLENBQUM7SUFDekMsY0FBYyxHQUFHLFFBQVEsQ0FBQztJQUMxQixlQUFlLEdBQUcsR0FBRyxDQUFDO0lBQ3RCLDJCQUEyQixHQUFHO1FBQ3JDO1lBQ0UsR0FBRyxFQUFFLFVBQVU7WUFDZixLQUFLLEVBQUUsVUFBVTtZQUNqQixPQUFPLEVBQUUsZ0RBQWdEO1NBQzFEO1FBQ0Q7WUFDRSxHQUFHLEVBQUUsT0FBTztZQUNaLEtBQUssRUFBRSxPQUFPO1lBQ2QsT0FBTyxFQUFFLG1EQUFtRDtTQUM3RDtRQUNEO1lBQ0UsR0FBRyxFQUFFLFdBQVc7WUFDaEIsS0FBSyxFQUFFLFdBQVc7WUFDbEIsT0FBTyxFQUFFLG9EQUFvRDtTQUM5RDtRQUNEO1lBQ0UsR0FBRyxFQUFFLE1BQU07WUFDWCxLQUFLLEVBQUUsTUFBTTtZQUNiLE9BQU8sRUFBRSw4REFBOEQ7U0FDeEU7UUFDRDtZQUNFLEdBQUcsRUFBRSxJQUFJO1lBQ1QsS0FBSyxFQUFFLElBQUk7WUFDWCxPQUFPLEVBQUUsMEVBQTBFO1NBQ3BGO1FBQ0Q7WUFDRSxHQUFHLEVBQUUsZUFBZTtZQUNwQixLQUFLLEVBQUUsT0FBTztZQUNkLE9BQU8sRUFBRSw0REFBNEQ7U0FDdEU7UUFDRDtZQUNFLEdBQUcsRUFBRSxjQUFjO1lBQ25CLEtBQUssRUFBRSxPQUFPO1lBQ2QsT0FBTyxFQUFFLDBEQUEwRDtTQUNwRTtLQUNGLENBQUM7SUFDTSx1QkFBdUIsQ0FBa0I7SUFDekMsc0JBQXNCLENBQTZCO0lBRTNELElBQUksaUJBQWlCO1FBQ25CLElBQUksQ0FBQyxJQUFJLENBQUMsMkJBQTJCLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDNUQsT0FBTyxFQUFFLENBQUM7UUFDWixDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsdUJBQXVCLEtBQUssSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxzQkFBc0IsRUFBRSxDQUFDO1lBQy9FLElBQUksQ0FBQyx1QkFBdUIsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO1lBQ3pDLElBQUksQ0FBQyxzQkFBc0IsR0FBRyxnQ0FBZ0MsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDNUUsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLHNCQUFzQixDQUFDO0lBQ3JDLENBQUM7SUFFRCxrQkFBa0I7UUFDaEIsT0FBTyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBRUQsY0FBYztRQUNaLE9BQU8sb0JBQW9CLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM5QyxDQUFDO0lBRUQsd0JBQXdCO1FBQ3RCLE9BQU8sSUFBSSxDQUFDLGlCQUFpQixJQUFJLElBQUksQ0FBQyxtQkFBbUIsS0FBSyxjQUFjLENBQUM7SUFDL0UsQ0FBQztJQUVELHFCQUFxQjtRQUNuQixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzlHLENBQUM7SUFFRCxhQUFhLENBQUMsR0FBc0I7UUFDbEMsT0FBTyxHQUFHLENBQUMsVUFBVSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQzVGLENBQUM7SUFFRCxXQUFXLENBQUMsU0FBb0IsRUFBRSxHQUFzQjtRQUN0RCxPQUFPLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsUUFBUSxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7SUFDbEYsQ0FBQztJQUVELGtCQUFrQixDQUFDLElBQXVDO1FBQ3hELE9BQU8sV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzNCLENBQUM7SUFFRCx3QkFBd0IsQ0FBQyxNQUFzQixFQUFFLEtBQWE7UUFDNUQsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxNQUFNLENBQUM7UUFDL0MsSUFBSSxPQUFPLFlBQVksS0FBSyxVQUFVLEVBQUUsQ0FBQztZQUN2QyxPQUFPLFlBQVksQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQztRQUNyRCxDQUFDO1FBQ0QsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7WUFDaEMsT0FBTyxZQUFZLENBQUMsS0FBSyxDQUFDLElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQztRQUM3QyxDQUFDO1FBQ0QsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDO0lBQ3RCLENBQUM7SUFFRCxrQkFBa0IsQ0FBQyxHQUFrRCxFQUFFLFFBQWdCO1FBQ3JGLE9BQU8sSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLFFBQVEsQ0FBQztJQUM5QyxDQUFDO0lBRUQsWUFBWSxDQUFDLE9BQW9CLEVBQUUsWUFBb0I7UUFDckQsT0FBTyxPQUFPLENBQUMsS0FBSyxJQUFJLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxDQUFDO0lBQ3pELENBQUM7SUFFRCxpQkFBaUIsQ0FBQyxVQUFpQztRQUNqRCxNQUFNLEtBQUssR0FBRyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLFFBQVEsR0FBRyxVQUFVLENBQUMsU0FBUyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDekcsT0FBTyxHQUFHLFVBQVUsQ0FBQyxRQUFRLE1BQU0sVUFBVSxDQUFDLFNBQVMsS0FBSyxLQUFLLElBQUksQ0FBQztJQUN4RSxDQUFDO0lBRUQsNEJBQTRCLENBQUMsT0FBb0IsRUFBRSxpQkFBaUIsR0FBRyxHQUFHO1FBQ3hFLE9BQU8sK0JBQStCLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLGlCQUFpQixDQUFDLENBQUM7SUFDdkYsQ0FBQztJQUVELG1CQUFtQixDQUFDLElBQWM7UUFDaEMsT0FBTyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDbEUsTUFBTTtZQUNOLFlBQVksRUFBRSxxQkFBcUIsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQztTQUN4RCxDQUFDLENBQUMsQ0FBQztJQUNOLENBQUM7SUFFRCxjQUFjLENBQUMsR0FBVyxFQUFFLEtBQWE7UUFDdkMsT0FBTyxrQkFBa0IsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0lBQ2hFLENBQUM7SUFFRCxVQUFVLENBQUMsSUFBOEM7UUFDdkQsT0FBTyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNyRCxDQUFDO0lBRUQsdUJBQXVCLENBQUMsR0FBc0I7UUFDNUMsT0FBTyx1QkFBdUIsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUN0QyxDQUFDO0lBRUQsZ0JBQWdCLENBQUMsR0FBc0IsRUFBRSxpQkFBNEM7UUFDbkYsT0FBTyxnQkFBZ0IsQ0FBQyxHQUFHLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztJQUNsRCxDQUFDO0lBRUQsa0JBQWtCLENBQUMsTUFBNkI7UUFDOUMsT0FBTyxvQ0FBb0MsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUN4RixDQUFDO0lBRUQsUUFBUSxDQUFDLEtBQWM7UUFDckIsT0FBTyxPQUFPLEtBQUssS0FBSyxRQUFRLENBQUM7SUFDbkMsQ0FBQztJQUVELGtCQUFrQixDQUFDLE1BQTZCO1FBQzlDLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLFNBQVMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ2pELENBQUM7SUFFRCxlQUFlLENBQUMsTUFBNkI7UUFDM0MsTUFBTSxVQUFVLEdBQUcsQ0FBQyx3QkFBd0IsRUFBRSxrQkFBa0IsRUFBRSxhQUFhLENBQUMsQ0FBQztRQUNqRixJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1lBQ25DLFVBQVUsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsQ0FBQztRQUN6QyxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztZQUMzQixVQUFVLENBQUMsSUFBSSxDQUFDLG1DQUFtQyxDQUFDLENBQUM7UUFDdkQsQ0FBQztRQUNELElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUMzQixVQUFVLENBQUMsSUFBSSxDQUFDLDJCQUEyQixDQUFDLENBQUM7UUFDL0MsQ0FBQzthQUFNLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUNsQyxVQUFVLENBQUMsSUFBSSxDQUFDLGlDQUFpQyxDQUFDLENBQUM7UUFDckQsQ0FBQzthQUFNLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUNqQyxVQUFVLENBQUMsSUFBSSxDQUFDLCtCQUErQixDQUFDLENBQUM7UUFDbkQsQ0FBQzthQUFNLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUNsQyxVQUFVLENBQUMsSUFBSSxDQUFDLCtCQUErQixDQUFDLENBQUM7UUFDbkQsQ0FBQztRQUNELE9BQU8sVUFBVSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM5QixDQUFDO0lBRUQsaUJBQWlCLENBQUMsTUFBNkI7UUFDN0MsT0FBTyxJQUFJLENBQUMsa0JBQWtCLENBQUMsTUFBTSxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBRUQsY0FBYyxDQUFDLE1BQTZCO1FBQzFDLE9BQU8sSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUMxRCxDQUFDO0lBRUQsa0JBQWtCLENBQUMsTUFBNkI7UUFDOUMsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ25ELENBQUM7SUFFRCxvQkFBb0IsQ0FBQyxHQUFzQixFQUFFLFFBQWdCO1FBQzNELE9BQU87WUFDTCxTQUFTLEVBQUUsR0FBRyxDQUFDLElBQUk7WUFDbkIsSUFBSSxFQUFFLEdBQUcsQ0FBQyxJQUFJO1lBQ2QsR0FBRztZQUNILFFBQVE7WUFDUixRQUFRLEVBQUUsSUFBSSxDQUFDLElBQUk7WUFDbkIsT0FBTyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTztZQUMxQixnQkFBZ0IsRUFBRSxJQUFJLENBQUMsaUJBQWlCO1lBQ3hDLFVBQVUsRUFBRSxJQUFJLENBQUMsd0JBQXdCLEVBQUU7WUFDM0MsT0FBTyxFQUFFLENBQUMsS0FBa0IsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLFFBQVEsQ0FBQztTQUMxRSxDQUFDO0lBQ0osQ0FBQztJQUVELHNCQUFzQixDQUNwQixHQUFzQixFQUN0QixRQUFnQixFQUNoQixNQUE2QixFQUM3QixZQUFvQjtRQUVwQixPQUFPO1lBQ0wsU0FBUyxFQUFFLE1BQU07WUFDakIsTUFBTTtZQUNOLE9BQU8sRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUM7WUFDekMsWUFBWTtZQUNaLElBQUksRUFBRSxHQUFHLENBQUMsSUFBSTtZQUNkLEdBQUc7WUFDSCxRQUFRO1lBQ1IsUUFBUSxFQUFFLElBQUksQ0FBQyxJQUFJO1lBQ25CLFNBQVMsRUFBRSxJQUFJLENBQUMsa0JBQWtCLENBQUMsTUFBTSxDQUFDO1lBQzFDLGdCQUFnQixFQUFFLElBQUksQ0FBQyxnQkFBZ0I7WUFDdkMsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLGlCQUFpQjtZQUN6QyxzQkFBc0IsRUFBRSxJQUFJLENBQUMsc0JBQXNCO1lBQ25ELE9BQU8sRUFBRSxDQUFDLEtBQWtCLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsWUFBWSxDQUFDO1NBQ3BHLENBQUM7SUFDSixDQUFDO0lBRUQsNEJBQTRCLENBQUMsS0FBWSxFQUFFLEdBQXNCLEVBQUUsUUFBZ0I7UUFDakYsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxhQUFhLENBQUMsU0FBUyxFQUFFLEdBQUcsRUFBRSxRQUFRLENBQUMsQ0FBQztJQUMvQyxDQUFDO0lBRUQsOEJBQThCLENBQzVCLEtBQVksRUFDWixHQUFzQixFQUN0QixRQUFnQixFQUNoQixNQUE2QixFQUM3QixZQUFvQjtRQUVwQixLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFNBQVMsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxZQUFZLENBQUMsQ0FBQztJQUN6RSxDQUFDO0lBRUQsYUFBYSxDQUFDLEtBQTZCLEVBQUUsR0FBc0IsRUFBRSxRQUFnQjtRQUNuRixJQUFJLEtBQUssRUFBRSxDQUFDO1lBQ1Ysc0NBQXNDLENBQUMsS0FBSyxFQUFFO2dCQUM1QyxNQUFNLEVBQUUsV0FBVztnQkFDbkIsT0FBTyxFQUFFO29CQUNQLFFBQVE7b0JBQ1IsTUFBTSxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLElBQUk7b0JBQzNCLFFBQVEsRUFBRSxJQUFJLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7aUJBQ2pEO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUNELElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDO1lBQ2xCLElBQUksRUFBRSxHQUFHLENBQUMsSUFBSTtZQUNkLEdBQUc7WUFDSCxRQUFRO1lBQ1IsUUFBUSxFQUFFLElBQUksQ0FBQyxJQUFJO1NBQ3BCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxpQkFBaUIsQ0FDZixLQUE2QixFQUM3QixHQUFzQixFQUN0QixRQUFnQixFQUNoQixNQUE2QixFQUM3QixZQUFvQjtRQUVwQixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsa0JBQWtCLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDbEQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUN0QixPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksS0FBSyxFQUFFLENBQUM7WUFDVixzQ0FBc0MsQ0FBQyxLQUFLLEVBQUU7Z0JBQzVDLE1BQU0sRUFBRSxhQUFhO2dCQUNyQixPQUFPLEVBQUU7b0JBQ1AsUUFBUTtvQkFDUixZQUFZO29CQUNaLFlBQVksRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsRUFBRSxLQUFLLElBQUksSUFBSTtvQkFDN0QsWUFBWSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUk7b0JBQ3ZILE1BQU0sRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxJQUFJO2lCQUM1QjthQUNGLENBQUMsQ0FBQztRQUNMLENBQUM7UUFDRCxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQztZQUN0QixJQUFJLEVBQUUsR0FBRyxDQUFDLElBQUk7WUFDZCxHQUFHO1lBQ0gsUUFBUTtZQUNSLFlBQVk7WUFDWixPQUFPLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxDQUFDO1lBQ3pDLE1BQU07WUFDTixTQUFTO1lBQ1QsUUFBUSxFQUFFLElBQUksQ0FBQyxJQUFJO1NBQ3BCLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTyxvQkFBb0IsQ0FBQyxTQUFvQixFQUFFLE1BQWtDO1FBQ25GLE1BQU0sS0FBSyxHQUFHLFNBQVMsQ0FBQyxZQUFZLElBQUksU0FBUyxDQUFDLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ25HLE9BQU8sQ0FBQyxNQUFNLEVBQUUsUUFBUSxJQUFJLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUMvQyxDQUFDO0lBRUQsdUJBQXVCLENBQUMsTUFBa0M7UUFDeEQsT0FBTyxDQUFDLE1BQU0sRUFBRSxRQUFRLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxPQUFPLE9BQU8sQ0FBQyxLQUFLLEtBQUssUUFBUSxDQUFDLENBQUM7SUFDdkYsQ0FBQztJQUVELHFCQUFxQixDQUFDLFNBQW9CLEVBQUUsTUFBa0M7UUFDNUUsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQyxLQUFLLENBQUM7UUFDeEUsT0FBTyxPQUFPLFlBQVksS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLDZCQUE2QixZQUFZLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0lBQzdGLENBQUM7SUFFRCxxQkFBcUIsQ0FBQyxTQUFvQixFQUFFLE1BQWtDO1FBQzVFLE1BQU0sVUFBVSxHQUFlO1lBQzdCLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFFLFNBQVM7WUFDNUIsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsU0FBUztTQUM1QixDQUFDO1FBQ0YsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLFNBQVMsRUFBRSxNQUFNLENBQUMsQ0FBQyxLQUFLLENBQUM7UUFDeEUsSUFBSSxDQUFDLFlBQVksSUFBSSxPQUFPLFlBQVksS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUN0RCxPQUFPLEVBQUUsQ0FBQztRQUNaLENBQUM7UUFDRCxNQUFNLEtBQUssR0FBRyxZQUFZLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDekMsTUFBTSxTQUFTLEdBQUcsS0FBSyxDQUFDLFNBQVMsSUFBSSxVQUFVLENBQUM7UUFDaEQsTUFBTSxlQUFlLEdBQUcsS0FBSyxDQUFDLGVBQWUsSUFBSSxVQUFVLENBQUM7UUFDNUQsT0FBTztZQUNMLEtBQUssRUFBRSxTQUFTLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztZQUM1QixlQUFlLEVBQUUsZUFBZSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7U0FDN0MsQ0FBQztJQUNKLENBQUM7SUFFRCxxQ0FBcUMsQ0FBQyxHQUFXLEVBQUUsSUFBNkI7UUFDOUUsUUFBUSxHQUFHLEVBQUUsQ0FBQztZQUNaLEtBQUssVUFBVTtnQkFDYixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUM7WUFDdkIsS0FBSyxPQUFPO2dCQUNWLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztZQUNwQixLQUFLLFdBQVc7Z0JBQ2QsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO1lBQ3hCLEtBQUssTUFBTTtnQkFDVCxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUM7WUFDbkIsS0FBSyxJQUFJO2dCQUNQLE9BQU8sc0NBQXNDLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDdEQsS0FBSyxlQUFlO2dCQUNsQixPQUFPLHFDQUFxQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1lBQ3ZFLEtBQUssY0FBYztnQkFDakIsT0FBTyxxQ0FBcUMsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUN0RTtnQkFDRSxPQUFPLEVBQUUsQ0FBQztRQUNkLENBQUM7SUFDSCxDQUFDO0lBRUQsdUNBQXVDLENBQUMsR0FBVyxFQUFFLElBQTZCO1FBQ2hGLFFBQVEsR0FBRyxFQUFFLENBQUM7WUFDWixLQUFLLFVBQVU7Z0JBQ2IsT0FBTyw4QkFBOEIsQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQzlFLEtBQUssT0FBTztnQkFDVixPQUFPLDhCQUE4QixDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDM0UsS0FBSyxNQUFNO2dCQUNULE9BQU8sOEJBQThCLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDdkU7Z0JBQ0UsT0FBTyxTQUFTLENBQUM7UUFDckIsQ0FBQztJQUNILENBQUM7d0dBdlhVLGlCQUFpQjs0RkFBakIsaUJBQWlCLHF2QkFxQmQsOEJBQThCLG1GQUc5Qiw0QkFBNEIsZ0RBcFZoQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0EwVFQsMkRBM1RTLFlBQVk7OzRGQTZUWCxpQkFBaUI7a0JBalU3QixTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxjQUFjO29CQUN4QixVQUFVLEVBQUUsSUFBSTtvQkFDaEIsZUFBZSxFQUFFLHVCQUF1QixDQUFDLE1BQU07b0JBQy9DLE9BQU8sRUFBRSxDQUFDLFlBQVksQ0FBQztvQkFDdkIsUUFBUSxFQUFFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTBUVDtpQkFDRjs4QkFFNEIsSUFBSTtzQkFBOUIsS0FBSzt1QkFBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUU7Z0JBQ2hCLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxZQUFZO3NCQUFwQixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csY0FBYztzQkFBdEIsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLGlCQUFpQjtzQkFBekIsS0FBSztnQkFDRyxpQkFBaUI7c0JBQXpCLEtBQUs7Z0JBQ0csWUFBWTtzQkFBcEIsS0FBSztnQkFDRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBQ0csaUJBQWlCO3NCQUF6QixLQUFLO2dCQUNHLDJCQUEyQjtzQkFBbkMsS0FBSztnQkFDRyxjQUFjO3NCQUF0QixLQUFLO2dCQUNHLFlBQVk7c0JBQXBCLEtBQUs7Z0JBQ0csc0JBQXNCO3NCQUE5QixLQUFLO2dCQUNHLG1CQUFtQjtzQkFBM0IsS0FBSztnQkFFSSxTQUFTO3NCQUFsQixNQUFNO2dCQUNHLGFBQWE7c0JBQXRCLE1BQU07Z0JBR1Asa0JBQWtCO3NCQURqQixZQUFZO3VCQUFDLDhCQUE4QjtnQkFJNUMsZ0JBQWdCO3NCQURmLFlBQVk7dUJBQUMsNEJBQTRCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgKiBhcyBzcmsgZnJvbSAnQGFsZ291eC9zdGFuZGFyZC1yYW5rbGlzdCc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgQ29udGVudENoaWxkLFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPdXRwdXQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgRW51bVRoZW1lLFxuICBmb3JtYXRUaW1lRHVyYXRpb24sXG4gIG51bWJlclRvQWxwaGFiZXQsXG4gIHJlc29sdmVTdHlsZSxcbiAgcmVzb2x2ZVRleHQsXG4gIHJlc29sdmVVc2VyTWFya2Vycyxcbn0gZnJvbSAnQGFsZ291eC9zdGFuZGFyZC1yYW5rbGlzdC11dGlscyc7XG5pbXBvcnQgdHlwZSB7IFRoZW1lQ29sb3IgfSBmcm9tICdAYWxnb3V4L3N0YW5kYXJkLXJhbmtsaXN0LXV0aWxzJztcbmltcG9ydCB7XG4gIGNhbGN1bGF0ZURpcnRQZXJjZW50YWdlLFxuICBjYWxjdWxhdGVQcm9ibGVtU3RhdGlzdGljc0Zvb3RlcixcbiAgY2FsY3VsYXRlU0VWYWx1ZSxcbiAgY2FuaXVzZSxcbiAgZm9ybWF0UHJvYmxlbVN0YXRpc3RpY3NBY2NlcHRlZE1pbnV0ZSxcbiAgZm9ybWF0UHJvYmxlbVN0YXRpc3RpY3NBdmVyYWdlSGFyZG5lc3MsXG4gIGZvcm1hdFByb2JsZW1TdGF0aXN0aWNzUGVyY2VudCxcbiAgZ2V0TWFya2VyUHJlc2VudGF0aW9uLFxuICBnZXRQcm9ibGVtSGVhZGVyQmFja2dyb3VuZEltYWdlLFxuICBnZXRSYW5rUHJvYmxlbVN0YXR1c0NlbGxQcmVzZW50YXRpb24sXG4gIHJlc29sdmVTcmtBc3NldFVybCxcbiAgc2hvdWxkU2hvd1RpbWVDb2x1bW4sXG4gIHNya1N1cHBvcnRlZFZlcnNpb25zLFxufSBmcm9tICdAYWxnb3V4L3N0YW5kYXJkLXJhbmtsaXN0LXJlbmRlcmVyLWNvbXBvbmVudC1jb3JlJztcbmltcG9ydCB0eXBlIHtcbiAgUHJvYmxlbVN0YXRpc3RpY3NGb290ZXIsXG4gIFJhbmtsaXN0Q29sdW1uVGl0bGVzLFxuICBSYW5rbGlzdFN0YXR1c0NlbGxQcmVzZXQsXG4gIFJhbmtsaXN0VXNlckF2YXRhclBsYWNlbWVudCxcbn0gZnJvbSAnQGFsZ291eC9zdGFuZGFyZC1yYW5rbGlzdC1yZW5kZXJlci1jb21wb25lbnQtY29yZSc7XG5pbXBvcnQgeyBjYXB0dXJlTW9kYWxUcmlnZ2VyUG9pbnRGcm9tTW91c2VFdmVudCB9IGZyb20gJy4uL21vZGFsL21vZGFsLWludGVyYWN0aW9ucyc7XG5pbXBvcnQgdHlwZSB7XG4gIFJhbmtWYWx1ZSxcbiAgU29sdXRpb25DbGlja1BheWxvYWQsXG4gIFN0YXRpY1JhbmtsaXN0LFxuICBTdGF0aWNSYW5rbGlzdFJvdyxcbiAgVXNlckNsaWNrUGF5bG9hZCxcbn0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHtcbiAgU3JrU3RhdHVzQ2VsbFRlbXBsYXRlRGlyZWN0aXZlLFxuICB0eXBlIFN0YXR1c0NlbGxUZW1wbGF0ZUNvbnRleHQsXG59IGZyb20gJy4vc3RhdHVzLWNlbGwtdGVtcGxhdGUuZGlyZWN0aXZlJztcbmltcG9ydCB7XG4gIFNya1VzZXJDZWxsVGVtcGxhdGVEaXJlY3RpdmUsXG4gIHR5cGUgVXNlckNlbGxUZW1wbGF0ZUNvbnRleHQsXG59IGZyb20gJy4vdXNlci1jZWxsLXRlbXBsYXRlLmRpcmVjdGl2ZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3Nyay1yYW5rbGlzdCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlXSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2ICpuZ0lmPVwiZGF0YS50eXBlICE9PSAnZ2VuZXJhbCc7IGVsc2UgdmVyc2lvblN0YXRlXCI+XG4gICAgICBzcmsgdHlwZSBcInt7IGRhdGEudHlwZSB9fVwiIGlzIG5vdCBzdXBwb3J0ZWRcbiAgICA8L2Rpdj5cblxuICAgIDxuZy10ZW1wbGF0ZSAjdmVyc2lvblN0YXRlPlxuICAgICAgPGRpdiAqbmdJZj1cIiFpc1N1cHBvcnRlZFZlcnNpb24oKTsgZWxzZSByYW5rbGlzdFRhYmxlXCI+XG4gICAgICAgIHNyayB2ZXJzaW9uIFwie3sgZGF0YS52ZXJzaW9uIH19XCIgaXMgbm90IHN1cHBvcnRlZCAoY3VycmVudCBzdXBwb3J0ZWQ6IHt7IHN1cHBvcnRlZFZlcnNpb25zIH19KVxuICAgICAgPC9kaXY+XG4gICAgPC9uZy10ZW1wbGF0ZT5cblxuICAgIDxuZy10ZW1wbGF0ZSAjcmFua2xpc3RUYWJsZT5cbiAgICAgIDxkaXYgY2xhc3M9XCJzcmstY29tbW9uLXRhYmxlIHNyay1tYWluXCI+XG4gICAgICAgIDx0YWJsZVxuICAgICAgICAgIFtjbGFzcy5zcmstdGFibGUtcm93LWJvcmRlcmVkXT1cImJvcmRlcmVkUm93cyB8fCByb3dCb3JkZXJlZFwiXG4gICAgICAgICAgW2NsYXNzLnNyay10YWJsZS1jb2x1bW4tYm9yZGVyZWRdPVwiY29sdW1uQm9yZGVyZWRcIlxuICAgICAgICAgIFtjbGFzcy5zcmstdGFibGUtcm93LXN0cmlwZWRdPVwic3RyaXBlZFJvd3NcIlxuICAgICAgICA+XG4gICAgICAgICAgPHRoZWFkPlxuICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICA8dGhcbiAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgc2VyaWVzSXRlbSBvZiBkYXRhLnNlcmllczsgbGV0IHNlcmllc0luZGV4ID0gaW5kZXhcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwic3JrLXNlcmllcy1oZWFkZXIgc3JrLS10ZXh0LXJpZ2h0IHNyay0tbm93cmFwXCJcbiAgICAgICAgICAgICAgICBbY2xhc3Muc3JrLXNlcmllcy1zZWdtZW50ZWQtY29sdW1uXT1cImlzU2VyaWVzU2VnbWVudGVkQ29sdW1uKHNlcmllc0l0ZW0pXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIHt7IHJlc29sdmVTZXJpZXNDb2x1bW5UaXRsZShzZXJpZXNJdGVtLCBzZXJpZXNJbmRleCkgfX1cbiAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgPHRoXG4gICAgICAgICAgICAgICAgKm5nSWY9XCJzcGxpdE9yZ2FuaXphdGlvblwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJzcmstb3JnYW5pemF0aW9uLWhlYWRlciBzcmstLXRleHQtbGVmdCBzcmstLW5vd3JhcFwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICB7eyByZXNvbHZlQ29sdW1uVGl0bGUoJ29yZ2FuaXphdGlvbicsICdPcmdhbml6YXRpb24nKSB9fVxuICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICA8dGggY2xhc3M9XCJzcmstLXRleHQtbGVmdCBzcmstLW5vd3JhcFwiPnt7IHJlc29sdmVDb2x1bW5UaXRsZSgndXNlcicsICdOYW1lJykgfX08L3RoPlxuICAgICAgICAgICAgICA8dGggY2xhc3M9XCJzcmstLXRleHQtcmlnaHQgc3JrLS1ub3dyYXBcIj57eyByZXNvbHZlQ29sdW1uVGl0bGUoJ3Njb3JlJywgJ1Njb3JlJykgfX08L3RoPlxuICAgICAgICAgICAgICA8dGggKm5nSWY9XCJzaG93VGltZUNvbHVtbigpXCIgY2xhc3M9XCJzcmstLXRleHQtcmlnaHQgc3JrLS1ub3dyYXBcIj5cbiAgICAgICAgICAgICAgICB7eyByZXNvbHZlQ29sdW1uVGl0bGUoJ3RpbWUnLCAnVGltZScpIH19XG4gICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgIDx0aFxuICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBwcm9ibGVtIG9mIGRhdGEucHJvYmxlbXM7IGxldCBwcm9ibGVtSW5kZXggPSBpbmRleFwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJzcmstLW5vd3JhcCBzcmstcHJvYmxlbS1oZWFkZXJcIlxuICAgICAgICAgICAgICAgIFtzdHlsZS5iYWNrZ3JvdW5kLWltYWdlXT1cInByb2JsZW1IZWFkZXJCYWNrZ3JvdW5kSW1hZ2UocHJvYmxlbSlcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPGFcbiAgICAgICAgICAgICAgICAgICpuZ0lmPVwicHJvYmxlbS5saW5rOyBlbHNlIHVubGlua2VkUHJvYmxlbUhlYWRlclwiXG4gICAgICAgICAgICAgICAgICBbaHJlZl09XCJwcm9ibGVtLmxpbmtcIlxuICAgICAgICAgICAgICAgICAgdGFyZ2V0PVwiX2JsYW5rXCJcbiAgICAgICAgICAgICAgICAgIHJlbD1cIm5vb3BlbmVyIG5vcmVmZXJyZXJcIlxuICAgICAgICAgICAgICAgICAgc3R5bGU9XCJjb2xvcjogdW5zZXRcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3JrLS1kaXNwbGF5LWJsb2NrXCI+e3sgcHJvYmxlbUFsaWFzKHByb2JsZW0sIHByb2JsZW1JbmRleCkgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICAgICAgICAqbmdJZj1cInByb2JsZW0uc3RhdGlzdGljc1wiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwic3JrLS1kaXNwbGF5LWJsb2NrIHNyay1wcm9ibGVtLXN0YXRzXCJcbiAgICAgICAgICAgICAgICAgICAgW3RpdGxlXT1cInByb2JsZW1TdGF0c1RpdGxlKHByb2JsZW0uc3RhdGlzdGljcylcIlxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICB7eyBwcm9ibGVtLnN0YXRpc3RpY3MuYWNjZXB0ZWQgfX1cbiAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8L2E+XG4gICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICN1bmxpbmtlZFByb2JsZW1IZWFkZXI+XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNyay0tZGlzcGxheS1ibG9ja1wiPnt7IHByb2JsZW1BbGlhcyhwcm9ibGVtLCBwcm9ibGVtSW5kZXgpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJwcm9ibGVtLnN0YXRpc3RpY3NcIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInNyay0tZGlzcGxheS1ibG9jayBzcmstcHJvYmxlbS1zdGF0c1wiXG4gICAgICAgICAgICAgICAgICAgIFt0aXRsZV09XCJwcm9ibGVtU3RhdHNUaXRsZShwcm9ibGVtLnN0YXRpc3RpY3MpXCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAge3sgcHJvYmxlbS5zdGF0aXN0aWNzLmFjY2VwdGVkIH19XG4gICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgPHRoICpuZ0lmPVwic2hvd0RpcnRDb2x1bW5cIiBjbGFzcz1cInNyay1kaXJ0LWhlYWRlciBzcmstLXRleHQtcmlnaHQgc3JrLS1ub3dyYXBcIj5cbiAgICAgICAgICAgICAgICB7eyByZXNvbHZlQ29sdW1uVGl0bGUoJ2RpcnQnLCAnRGlydCcpIH19XG4gICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgIDx0aCAqbmdJZj1cInNob3dTRUNvbHVtblwiIGNsYXNzPVwic3JrLXNlLWhlYWRlciBzcmstLXRleHQtcmlnaHQgc3JrLS1ub3dyYXBcIj5cbiAgICAgICAgICAgICAgICB7eyByZXNvbHZlQ29sdW1uVGl0bGUoJ3NlJywgJ1NFJykgfX1cbiAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgPC90aGVhZD5cbiAgICAgICAgICA8dGJvZHk+XG4gICAgICAgICAgICA8dHIgKm5nRm9yPVwibGV0IHJvdyBvZiBkYXRhLnJvd3M7IGxldCByb3dJbmRleCA9IGluZGV4XCI+XG4gICAgICAgICAgICAgIDx0ZFxuICAgICAgICAgICAgICAgICpuZ0Zvcj1cImxldCByYW5rVmFsdWUgb2YgZ2V0UmFua1ZhbHVlcyhyb3cpOyBsZXQgc2VyaWVzSW5kZXggPSBpbmRleFwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJzcmstLXRleHQtcmlnaHQgc3JrLS1ub3dyYXBcIlxuICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cImdldFNlcmllc1NlZ21lbnRDbGFzcyhyYW5rVmFsdWUsIGRhdGEuc2VyaWVzW3Nlcmllc0luZGV4XSlcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5zcmstc2VyaWVzLXNlZ21lbnRlZC1jb2x1bW5dPVwiaXNTZXJpZXNTZWdtZW50ZWRDb2x1bW4oZGF0YS5zZXJpZXNbc2VyaWVzSW5kZXhdKVwiXG4gICAgICAgICAgICAgICAgW25nU3R5bGVdPVwiZ2V0U2VyaWVzU2VnbWVudFN0eWxlKHJhbmtWYWx1ZSwgZGF0YS5zZXJpZXNbc2VyaWVzSW5kZXhdKVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICB7eyBnZXRSYW5rVGV4dChyYW5rVmFsdWUsIHJvdykgfX1cbiAgICAgICAgICAgICAgPC90ZD5cblxuICAgICAgICAgICAgICA8dGRcbiAgICAgICAgICAgICAgICAqbmdJZj1cInNwbGl0T3JnYW5pemF0aW9uXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInNyay1vcmdhbml6YXRpb24tY2VsbCBzcmstLXRleHQtbGVmdCBzcmstLW5vd3JhcFwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLnNyay1vcmdhbml6YXRpb24tY2VsbC1hdmF0YXJdPVwic2hvd0F2YXRhckluT3JnYW5pemF0aW9uKCkgJiYgISFyb3cudXNlci5hdmF0YXJcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNyay1vcmdhbml6YXRpb24tY2VsbC1jb250ZW50XCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwic2hvd0F2YXRhckluT3JnYW5pemF0aW9uKCkgJiYgcm93LnVzZXIuYXZhdGFyXCIgY2xhc3M9XCJzcmstdXNlci1hdmF0YXJcIj5cbiAgICAgICAgICAgICAgICAgICAgPGltZ1xuICAgICAgICAgICAgICAgICAgICAgIFtzcmNdPVwiZm9ybWF0QXNzZXRVcmwocm93LnVzZXIuYXZhdGFyLCAndXNlci5hdmF0YXInKVwiXG4gICAgICAgICAgICAgICAgICAgICAgYWx0PVwiVXNlciBBdmF0YXJcIlxuICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInNyay1vcmdhbml6YXRpb24tbmFtZS10ZXh0XCJcbiAgICAgICAgICAgICAgICAgICAgW3RpdGxlXT1cInJvdy51c2VyLm9yZ2FuaXphdGlvbiA/IHJlc29sdmVEaXNwbGF5VGV4dChyb3cudXNlci5vcmdhbml6YXRpb24pIDogJydcIlxuICAgICAgICAgICAgICAgICAgICBbdGV4dENvbnRlbnRdPVwicm93LnVzZXIub3JnYW5pemF0aW9uID8gcmVzb2x2ZURpc3BsYXlUZXh0KHJvdy51c2VyLm9yZ2FuaXphdGlvbikgOiAnJ1wiXG4gICAgICAgICAgICAgICAgICA+PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L3RkPlxuXG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJ1c2VyQ2VsbFRlbXBsYXRlOyBlbHNlIGRlZmF1bHRVc2VyQ2VsbFwiPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cInVzZXJDZWxsVGVtcGxhdGUudGVtcGxhdGVSZWZcIlxuICAgICAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cImJ1aWxkVXNlckNlbGxDb250ZXh0KHJvdywgcm93SW5kZXgpXCJcbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNkZWZhdWx0VXNlckNlbGw+XG4gICAgICAgICAgICAgICAgPHRkXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cInNyay0tdGV4dC1sZWZ0IHNyay0tbm93cmFwIHNyay11c2VyLWNlbGwgc3JrLS1jdXJzb3ItcG9pbnRlclwiXG4gICAgICAgICAgICAgICAgICByb2xlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgIHRhYmluZGV4PVwiMFwiXG4gICAgICAgICAgICAgICAgICAoY2xpY2spPVwiZW1pdFVzZXJDbGljaygkZXZlbnQsIHJvdywgcm93SW5kZXgpXCJcbiAgICAgICAgICAgICAgICAgIChrZXlkb3duLmVudGVyKT1cImFjdGl2YXRlVXNlckNlbGxGcm9tS2V5Ym9hcmQoJGV2ZW50LCByb3csIHJvd0luZGV4KVwiXG4gICAgICAgICAgICAgICAgICAoa2V5ZG93bi5zcGFjZSk9XCJhY3RpdmF0ZVVzZXJDZWxsRnJvbUtleWJvYXJkKCRldmVudCwgcm93LCByb3dJbmRleClcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzcmstdXNlci1jZWxsLWNvbnRlbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cInJvdy51c2VyLmF2YXRhciAmJiAhc2hvd0F2YXRhckluT3JnYW5pemF0aW9uKClcIiBjbGFzcz1cInNyay11c2VyLWF2YXRhclwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxpbWdcbiAgICAgICAgICAgICAgICAgICAgICAgIFtzcmNdPVwiZm9ybWF0QXNzZXRVcmwocm93LnVzZXIuYXZhdGFyLCAndXNlci5hdmF0YXInKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICBhbHQ9XCJVc2VyIEF2YXRhclwiXG4gICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzcmstdXNlci1ib2R5XCI+XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNyay11c2VyLW5hbWUtcm93XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInNyay11c2VyLW5hbWUtdGV4dFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFt0aXRsZV09XCJyZXNvbHZlRGlzcGxheVRleHQocm93LnVzZXIubmFtZSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgICB7eyByZXNvbHZlRGlzcGxheVRleHQocm93LnVzZXIubmFtZSkgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3JrLW1hcmtlci1kb3QtZ3JvdXBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgbWFya2VyIG9mIHJlc29sdmVkVXNlck1hcmtlcnMocm93LnVzZXIpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInNyay1tYXJrZXIgc3JrLW1hcmtlci1kb3Qgc3JrLS1jLXRvb2x0aXBcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ0NsYXNzXT1cIm1hcmtlci5wcmVzZW50YXRpb24uY2xhc3NOYW1lXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdTdHlsZV09XCJtYXJrZXIucHJlc2VudGF0aW9uLnN0eWxlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbYXR0ci5kYXRhLXRvb2x0aXBdPVwicmVzb2x2ZURpc3BsYXlUZXh0KG1hcmtlci5tYXJrZXIubGFiZWwpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICA8cFxuICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJyb3cudXNlci5vcmdhbml6YXRpb24gJiYgIXNwbGl0T3JnYW5pemF0aW9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwic3JrLXVzZXItc2Vjb25kYXJ5LXRleHQgc3JrLS10ZXh0LWVsbGlwc2lzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlPVwiXCJcbiAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICB7eyByZXNvbHZlRGlzcGxheVRleHQocm93LnVzZXIub3JnYW5pemF0aW9uKSB9fVxuICAgICAgICAgICAgICAgICAgICAgIDwvcD5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuXG4gICAgICAgICAgICAgIDx0ZCBjbGFzcz1cInNyay0tdGV4dC1yaWdodCBzcmstLW5vd3JhcFwiPnt7IHJvdy5zY29yZS52YWx1ZSB9fTwvdGQ+XG4gICAgICAgICAgICAgIDx0ZCAqbmdJZj1cInNob3dUaW1lQ29sdW1uKClcIiBjbGFzcz1cInNyay0tdGV4dC1yaWdodCBzcmstLW5vd3JhcFwiPlxuICAgICAgICAgICAgICAgIHt7IHJvdy5zY29yZS50aW1lID8gZm9ybWF0VGltZShyb3cuc2NvcmUudGltZSkgOiAnLScgfX1cbiAgICAgICAgICAgICAgPC90ZD5cblxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBzdGF0dXMgb2Ygcm93LnN0YXR1c2VzOyBsZXQgcHJvYmxlbUluZGV4ID0gaW5kZXhcIj5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic3RhdHVzQ2VsbFRlbXBsYXRlOyBlbHNlIGRlZmF1bHRTdGF0dXNDZWxsXCI+XG4gICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cInN0YXR1c0NlbGxUZW1wbGF0ZS50ZW1wbGF0ZVJlZlwiXG4gICAgICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJidWlsZFN0YXR1c0NlbGxDb250ZXh0KHJvdywgcm93SW5kZXgsIHN0YXR1cywgcHJvYmxlbUluZGV4KVwiXG4gICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjZGVmYXVsdFN0YXR1c0NlbGw+XG4gICAgICAgICAgICAgICAgICA8dGRcbiAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJzdGF0dXMucmVzdWx0ID09PSAnRkInIHx8IHN0YXR1cy5yZXN1bHQgPT09ICdBQyc7IGVsc2UgZmFpbGVkT3JGcm96ZW5TdGF0dXNcIlxuICAgICAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJzdGF0dXNDZWxsQ2xhc3Moc3RhdHVzKVwiXG4gICAgICAgICAgICAgICAgICAgIFthdHRyLnJvbGVdPVwic3RhdHVzQ2VsbFJvbGUoc3RhdHVzKVwiXG4gICAgICAgICAgICAgICAgICAgIFthdHRyLnRhYmluZGV4XT1cInN0YXR1c0NlbGxUYWJJbmRleChzdGF0dXMpXCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImVtaXRTb2x1dGlvbkNsaWNrKCRldmVudCwgcm93LCByb3dJbmRleCwgc3RhdHVzLCBwcm9ibGVtSW5kZXgpXCJcbiAgICAgICAgICAgICAgICAgICAgKGtleWRvd24uZW50ZXIpPVwiYWN0aXZhdGVTdGF0dXNDZWxsRnJvbUtleWJvYXJkKCRldmVudCwgcm93LCByb3dJbmRleCwgc3RhdHVzLCBwcm9ibGVtSW5kZXgpXCJcbiAgICAgICAgICAgICAgICAgICAgKGtleWRvd24uc3BhY2UpPVwiYWN0aXZhdGVTdGF0dXNDZWxsRnJvbUtleWJvYXJkKCRldmVudCwgcm93LCByb3dJbmRleCwgc3RhdHVzLCBwcm9ibGVtSW5kZXgpXCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cInN0YXR1c0NvbG9yQXNUZXh0ICYmIHN0YXR1cy5yZXN1bHQgPT09ICdGQidcIlxuICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwic3JrLXByZXN0LXN0YXR1cy1ibG9jay1mYi1zdGFyXCJcbiAgICAgICAgICAgICAgICAgICAgICBbdGV4dENvbnRlbnRdPVwiZmlyc3RCbG9vZFN0YXJcIlxuICAgICAgICAgICAgICAgICAgICA+PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic3RhdHVzUHJlc2VudGF0aW9uKHN0YXR1cykgYXMgcHJlc2VudGF0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzTnVtYmVyKHByZXNlbnRhdGlvbi5zY29yZSk7IGVsc2Ugc3RhdHVzVGV4dFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzcmstcHJlc3Qtc3RhdHVzLWJsb2NrLXNjb3JlXCI+e3sgcHJlc2VudGF0aW9uLnNjb3JlIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzcmstcHJlc3Qtc3RhdHVzLWJsb2NrLXNjb3JlLWRldGFpbHNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAge3sgcHJlc2VudGF0aW9uLnNjb3JlRGV0YWlscyB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjc3RhdHVzVGV4dD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJwcmVzZW50YXRpb24uc2Vjb25kYXJ5ICE9PSB1bmRlZmluZWQ7IGVsc2Ugc2luZ2xlU3RhdHVzXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3JrLXByZXN0LXN0YXR1cy1ibG9jay1wcmltYXJ5XCI+e3sgcHJlc2VudGF0aW9uLnByaW1hcnkgfHwgJycgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIFt0ZXh0Q29udGVudF09XCJzdGF0dXNTZXBhcmF0b3JcIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3JrLXByZXN0LXN0YXR1cy1ibG9jay1zZWNvbmRhcnlcIj57eyBwcmVzZW50YXRpb24uc2Vjb25kYXJ5IH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI3NpbmdsZVN0YXR1cz57eyBwcmVzZW50YXRpb24ucHJpbWFyeSB9fTwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNmYWlsZWRPckZyb3plblN0YXR1cz5cbiAgICAgICAgICAgICAgICAgICAgPHRkXG4gICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJzdGF0dXMucmVzdWx0ID09PSAnPycgfHwgc3RhdHVzLnJlc3VsdCA9PT0gJ1JKJzsgZWxzZSBlbXB0eVN0YXR1c1wiXG4gICAgICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwic3RhdHVzQ2VsbENsYXNzKHN0YXR1cylcIlxuICAgICAgICAgICAgICAgICAgICAgIFthdHRyLnJvbGVdPVwic3RhdHVzQ2VsbFJvbGUoc3RhdHVzKVwiXG4gICAgICAgICAgICAgICAgICAgICAgW2F0dHIudGFiaW5kZXhdPVwic3RhdHVzQ2VsbFRhYkluZGV4KHN0YXR1cylcIlxuICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJlbWl0U29sdXRpb25DbGljaygkZXZlbnQsIHJvdywgcm93SW5kZXgsIHN0YXR1cywgcHJvYmxlbUluZGV4KVwiXG4gICAgICAgICAgICAgICAgICAgICAgKGtleWRvd24uZW50ZXIpPVwiYWN0aXZhdGVTdGF0dXNDZWxsRnJvbUtleWJvYXJkKCRldmVudCwgcm93LCByb3dJbmRleCwgc3RhdHVzLCBwcm9ibGVtSW5kZXgpXCJcbiAgICAgICAgICAgICAgICAgICAgICAoa2V5ZG93bi5zcGFjZSk9XCJhY3RpdmF0ZVN0YXR1c0NlbGxGcm9tS2V5Ym9hcmQoJGV2ZW50LCByb3csIHJvd0luZGV4LCBzdGF0dXMsIHByb2JsZW1JbmRleClcIlxuICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInN0YXR1c1ByZXNlbnRhdGlvbihzdGF0dXMpIGFzIHByZXNlbnRhdGlvblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInByZXNlbnRhdGlvbi5zZWNvbmRhcnkgIT09IHVuZGVmaW5lZDsgZWxzZSBzaW5nbGVTdGF0dXNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzcmstcHJlc3Qtc3RhdHVzLWJsb2NrLXByaW1hcnlcIj57eyBwcmVzZW50YXRpb24ucHJpbWFyeSB8fCAnJyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gW3RleHRDb250ZW50XT1cInN0YXR1c1NlcGFyYXRvclwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzcmstcHJlc3Qtc3RhdHVzLWJsb2NrLXNlY29uZGFyeVwiPnt7IHByZXNlbnRhdGlvbi5zZWNvbmRhcnkgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSAjc2luZ2xlU3RhdHVzPnt7IHByZXNlbnRhdGlvbi5wcmltYXJ5IH19PC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgI2VtcHR5U3RhdHVzPlxuICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJzcmstc3RhdHVzLXBsYWNlaG9sZGVyLWNlbGwgc3JrLS10ZXh0LWNlbnRlciBzcmstLW5vd3JhcFwiPlxuICAgICAgICAgICAgICAgICAgICAgIHt7IGVtcHR5U3RhdHVzUGxhY2Vob2xkZXIgfX1cbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG5cbiAgICAgICAgICAgICAgPHRkICpuZ0lmPVwic2hvd0RpcnRDb2x1bW5cIiBjbGFzcz1cInNyay1kaXJ0LWNlbGwgc3JrLS10ZXh0LXJpZ2h0IHNyay0tbm93cmFwXCI+XG4gICAgICAgICAgICAgICAge3sgY2FsY3VsYXRlRGlydFBlcmNlbnRhZ2Uocm93KSB9fVxuICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICA8dGQgKm5nSWY9XCJzaG93U0VDb2x1bW5cIiBjbGFzcz1cInNyay1zZS1jZWxsIHNyay0tdGV4dC1yaWdodCBzcmstLW5vd3JhcFwiPlxuICAgICAgICAgICAgICAgIHt7IGNhbGN1bGF0ZVNFVmFsdWUocm93LCBwcm9ibGVtU3RhdGlzdGljcykgfX1cbiAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgPC90Ym9keT5cbiAgICAgICAgICA8dGZvb3QgKm5nSWY9XCJzaG93UHJvYmxlbVN0YXRpc3RpY3NGb290ZXJcIj5cbiAgICAgICAgICAgIDx0clxuICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgZm9vdGVyUm93IG9mIHByb2JsZW1TdGF0aXN0aWNzRm9vdGVyUm93c1wiXG4gICAgICAgICAgICAgIGNsYXNzPVwic3JrLXByb2JsZW0tc3RhdGlzdGljcy1mb290ZXItcm93XCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPHRkXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJzcmstcHJvYmxlbS1zdGF0aXN0aWNzLWZvb3Rlci1sYWJlbHMgc3JrLS10ZXh0LXJpZ2h0IHNyay0tbm93cmFwXCJcbiAgICAgICAgICAgICAgICBbYXR0ci5jb2xzcGFuXT1cImxlZnRGb290ZXJDb2x1bW5Db3VudCgpXCJcbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cInNyay1wcm9ibGVtLXN0YXRpc3RpY3MtZm9vdGVyLWxhYmVsIHNyay0tYy10b29sdGlwXCJcbiAgICAgICAgICAgICAgICAgIFthdHRyLmRhdGEtdG9vbHRpcF09XCJmb290ZXJSb3cudG9vbHRpcFwiXG4gICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAge3sgZm9vdGVyUm93LmxhYmVsIH19XG4gICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICA8dGRcbiAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgc3RhdCBvZiBwcm9ibGVtU3RhdGlzdGljc1wiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJzcmstcHJvYmxlbS1zdGF0aXN0aWNzLWZvb3Rlci1jZWxsIHNyay0tdGV4dC1jZW50ZXIgc3JrLS1ub3dyYXBcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzcmstcHJvYmxlbS1zdGF0aXN0aWNzLWZvb3Rlci1wcmltYXJ5XCI+XG4gICAgICAgICAgICAgICAgICB7eyBnZXRQcm9ibGVtU3RhdGlzdGljc0Zvb3RlckNlbGxQcmltYXJ5KGZvb3RlclJvdy5rZXksIHN0YXQpIH19XG4gICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJnZXRQcm9ibGVtU3RhdGlzdGljc0Zvb3RlckNlbGxTZWNvbmRhcnkoZm9vdGVyUm93LmtleSwgc3RhdCkgIT09IHVuZGVmaW5lZFwiPlxuICAgICAgICAgICAgICAgICAgPHNwYW4+IDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3JrLXByb2JsZW0tc3RhdGlzdGljcy1mb290ZXItc2Vjb25kYXJ5XCI+XG4gICAgICAgICAgICAgICAgICAgIHt7IGdldFByb2JsZW1TdGF0aXN0aWNzRm9vdGVyQ2VsbFNlY29uZGFyeShmb290ZXJSb3cua2V5LCBzdGF0KSB9fVxuICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICA8dGRcbiAgICAgICAgICAgICAgICAqbmdJZj1cInNob3dEaXJ0Q29sdW1uXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInNyay1wcm9ibGVtLXN0YXRpc3RpY3MtZm9vdGVyLWNlbGwgc3JrLWV4dHJhLXN0YXRpc3RpY3MtZm9vdGVyLWNlbGwgc3JrLWRpcnQtZm9vdGVyLWNlbGwgc3JrLS1ub3dyYXBcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzcmstcHJvYmxlbS1zdGF0aXN0aWNzLWZvb3Rlci1wcmltYXJ5XCI+PC9zcGFuPlxuICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICA8dGRcbiAgICAgICAgICAgICAgICAqbmdJZj1cInNob3dTRUNvbHVtblwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJzcmstcHJvYmxlbS1zdGF0aXN0aWNzLWZvb3Rlci1jZWxsIHNyay1leHRyYS1zdGF0aXN0aWNzLWZvb3Rlci1jZWxsIHNyay1zZS1mb290ZXItY2VsbCBzcmstLW5vd3JhcFwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNyay1wcm9ibGVtLXN0YXRpc3RpY3MtZm9vdGVyLXByaW1hcnlcIj48L3NwYW4+XG4gICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgPHRyIGNsYXNzPVwic3JrLXByb2JsZW0tc3RhdGlzdGljcy1mb290ZXItcm93IHNyay1wcm9ibGVtLXN0YXRpc3RpY3MtZm9vdGVyLXByb2JsZW0tbGFiZWwtcm93XCI+XG4gICAgICAgICAgICAgIDx0ZFxuICAgICAgICAgICAgICAgIGNsYXNzPVwic3JrLXByb2JsZW0tc3RhdGlzdGljcy1mb290ZXItbGFiZWxzIHNyay0tdGV4dC1yaWdodCBzcmstLW5vd3JhcFwiXG4gICAgICAgICAgICAgICAgW2F0dHIuY29sc3Bhbl09XCJsZWZ0Rm9vdGVyQ29sdW1uQ291bnQoKVwiXG4gICAgICAgICAgICAgID48L3RkPlxuICAgICAgICAgICAgICA8dGRcbiAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgcHJvYmxlbSBvZiBkYXRhLnByb2JsZW1zOyBsZXQgcHJvYmxlbUluZGV4ID0gaW5kZXhcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwic3JrLXByb2JsZW0tc3RhdGlzdGljcy1mb290ZXItY2VsbCBzcmstcHJvYmxlbS1zdGF0aXN0aWNzLWZvb3Rlci1wcm9ibGVtLWhlYWRlciBzcmstcHJvYmxlbS1oZWFkZXIgc3JrLS10ZXh0LWNlbnRlciBzcmstLW5vd3JhcFwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLmJhY2tncm91bmQtaW1hZ2VdPVwicHJvYmxlbUhlYWRlckJhY2tncm91bmRJbWFnZShwcm9ibGVtLCAwKVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNyay0tZGlzcGxheS1ibG9ja1wiPnt7IHByb2JsZW1BbGlhcyhwcm9ibGVtLCBwcm9ibGVtSW5kZXgpIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICA8dGRcbiAgICAgICAgICAgICAgICAqbmdJZj1cInNob3dEaXJ0Q29sdW1uXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInNyay1wcm9ibGVtLXN0YXRpc3RpY3MtZm9vdGVyLWNlbGwgc3JrLWV4dHJhLXN0YXRpc3RpY3MtZm9vdGVyLWNlbGwgc3JrLWRpcnQtZm9vdGVyLWNlbGwgc3JrLS1ub3dyYXBcIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzcmstcHJvYmxlbS1zdGF0aXN0aWNzLWZvb3Rlci1wcmltYXJ5XCI+PC9zcGFuPlxuICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICA8dGRcbiAgICAgICAgICAgICAgICAqbmdJZj1cInNob3dTRUNvbHVtblwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJzcmstcHJvYmxlbS1zdGF0aXN0aWNzLWZvb3Rlci1jZWxsIHNyay1leHRyYS1zdGF0aXN0aWNzLWZvb3Rlci1jZWxsIHNyay1zZS1mb290ZXItY2VsbCBzcmstLW5vd3JhcFwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNyay1wcm9ibGVtLXN0YXRpc3RpY3MtZm9vdGVyLXByaW1hcnlcIj48L3NwYW4+XG4gICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgIDwvdGZvb3Q+XG4gICAgICAgIDwvdGFibGU+XG4gICAgICA8L2Rpdj5cbiAgICA8L25nLXRlbXBsYXRlPlxuICBgLFxufSlcbmV4cG9ydCBjbGFzcyBSYW5rbGlzdENvbXBvbmVudCB7XG4gIEBJbnB1dCh7IHJlcXVpcmVkOiB0cnVlIH0pIGRhdGEhOiBTdGF0aWNSYW5rbGlzdDtcbiAgQElucHV0KCkgdGhlbWU6IEVudW1UaGVtZSA9IEVudW1UaGVtZS5saWdodDtcbiAgQElucHV0KCkgYm9yZGVyZWRSb3dzID0gZmFsc2U7XG4gIEBJbnB1dCgpIHJvd0JvcmRlcmVkID0gZmFsc2U7XG4gIEBJbnB1dCgpIGNvbHVtbkJvcmRlcmVkID0gZmFsc2U7XG4gIEBJbnB1dCgpIHN0cmlwZWRSb3dzID0gZmFsc2U7XG4gIEBJbnB1dCgpIGZvcm1hdFNya0Fzc2V0VXJsPzogKHVybDogc3RyaW5nLCBmaWVsZDogc3RyaW5nKSA9PiBzdHJpbmc7XG4gIEBJbnB1dCgpIHNwbGl0T3JnYW5pemF0aW9uID0gZmFsc2U7XG4gIEBJbnB1dCgpIGNvbHVtblRpdGxlcz86IFJhbmtsaXN0Q29sdW1uVGl0bGVzO1xuICBASW5wdXQoKSBzdGF0dXNDZWxsUHJlc2V0OiBSYW5rbGlzdFN0YXR1c0NlbGxQcmVzZXQgPSAnY2xhc3NpYyc7XG4gIEBJbnB1dCgpIHN0YXR1c0NvbG9yQXNUZXh0ID0gZmFsc2U7XG4gIEBJbnB1dCgpIHNob3dQcm9ibGVtU3RhdGlzdGljc0Zvb3RlciA9IGZhbHNlO1xuICBASW5wdXQoKSBzaG93RGlydENvbHVtbiA9IGZhbHNlO1xuICBASW5wdXQoKSBzaG93U0VDb2x1bW4gPSBmYWxzZTtcbiAgQElucHV0KCkgZW1wdHlTdGF0dXNQbGFjZWhvbGRlcjogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG4gIEBJbnB1dCgpIHVzZXJBdmF0YXJQbGFjZW1lbnQ6IFJhbmtsaXN0VXNlckF2YXRhclBsYWNlbWVudCA9ICd1c2VyJztcblxuICBAT3V0cHV0KCkgdXNlckNsaWNrID0gbmV3IEV2ZW50RW1pdHRlcjxVc2VyQ2xpY2tQYXlsb2FkPigpO1xuICBAT3V0cHV0KCkgc29sdXRpb25DbGljayA9IG5ldyBFdmVudEVtaXR0ZXI8U29sdXRpb25DbGlja1BheWxvYWQ+KCk7XG5cbiAgQENvbnRlbnRDaGlsZChTcmtTdGF0dXNDZWxsVGVtcGxhdGVEaXJlY3RpdmUpXG4gIHN0YXR1c0NlbGxUZW1wbGF0ZT86IFNya1N0YXR1c0NlbGxUZW1wbGF0ZURpcmVjdGl2ZTtcblxuICBAQ29udGVudENoaWxkKFNya1VzZXJDZWxsVGVtcGxhdGVEaXJlY3RpdmUpXG4gIHVzZXJDZWxsVGVtcGxhdGU/OiBTcmtVc2VyQ2VsbFRlbXBsYXRlRGlyZWN0aXZlO1xuXG4gIHJlYWRvbmx5IHN1cHBvcnRlZFZlcnNpb25zID0gc3JrU3VwcG9ydGVkVmVyc2lvbnM7XG4gIHJlYWRvbmx5IGZpcnN0Qmxvb2RTdGFyID0gJ1xcdTI2MDUnO1xuICByZWFkb25seSBzdGF0dXNTZXBhcmF0b3IgPSAnICc7XG4gIHJlYWRvbmx5IHByb2JsZW1TdGF0aXN0aWNzRm9vdGVyUm93cyA9IFtcbiAgICB7XG4gICAgICBrZXk6ICdhY2NlcHRlZCcsXG4gICAgICBsYWJlbDogJ0FjY2VwdGVkJyxcbiAgICAgIHRvb2x0aXA6ICdOdW1iZXIgb2YgcGFydGljaXBhbnRzIHdobyBzb2x2ZWQgdGhpcyBwcm9ibGVtJyxcbiAgICB9LFxuICAgIHtcbiAgICAgIGtleTogJ3RyaWVkJyxcbiAgICAgIGxhYmVsOiAnVHJpZWQnLFxuICAgICAgdG9vbHRpcDogJ051bWJlciBvZiBwYXJ0aWNpcGFudHMgd2hvIGF0dGVtcHRlZCB0aGlzIHByb2JsZW0nLFxuICAgIH0sXG4gICAge1xuICAgICAga2V5OiAnc3VibWl0dGVkJyxcbiAgICAgIGxhYmVsOiAnU3VibWl0dGVkJyxcbiAgICAgIHRvb2x0aXA6ICdUb3RhbCBudW1iZXIgb2YgdmFsaWQgc3VibWlzc2lvbnMgZm9yIHRoaXMgcHJvYmxlbScsXG4gICAgfSxcbiAgICB7XG4gICAgICBrZXk6ICdkaXJ0JyxcbiAgICAgIGxhYmVsOiAnRGlydCcsXG4gICAgICB0b29sdGlwOiAnV3Jvbmcgc3VibWlzc2lvbnMgYW1vbmcgcGFydGljaXBhbnRzIHdobyBzb2x2ZWQgdGhpcyBwcm9ibGVtJyxcbiAgICB9LFxuICAgIHtcbiAgICAgIGtleTogJ3NlJyxcbiAgICAgIGxhYmVsOiAnU0UnLFxuICAgICAgdG9vbHRpcDogJ0F2ZXJhZ2UgaGFyZG5lc3MsIGNhbGN1bGF0ZWQgYXMgKHBhcnRpY2lwYW50cyAtIGFjY2VwdGVkKSAvIHBhcnRpY2lwYW50cycsXG4gICAgfSxcbiAgICB7XG4gICAgICBrZXk6ICdmaXJzdEFjY2VwdGVkJyxcbiAgICAgIGxhYmVsOiAnRkIgYXQnLFxuICAgICAgdG9vbHRpcDogJ0ZpcnN0IEJsb29kIGF0LCBhbHNvIGtub3duIGFzIGZpcnN0IHNvbHZlIHRpbWUsIGluIG1pbnV0ZXMnLFxuICAgIH0sXG4gICAge1xuICAgICAga2V5OiAnbGFzdEFjY2VwdGVkJyxcbiAgICAgIGxhYmVsOiAnTEIgYXQnLFxuICAgICAgdG9vbHRpcDogJ0xhc3QgQmxvb2QgYXQsIGFsc28ga25vd24gYXMgbGFzdCBzb2x2ZSB0aW1lLCBpbiBtaW51dGVzJyxcbiAgICB9LFxuICBdO1xuICBwcml2YXRlIHByb2JsZW1TdGF0aXN0aWNzU291cmNlPzogU3RhdGljUmFua2xpc3Q7XG4gIHByaXZhdGUgcHJvYmxlbVN0YXRpc3RpY3NDYWNoZT86IFByb2JsZW1TdGF0aXN0aWNzRm9vdGVyW107XG5cbiAgZ2V0IHByb2JsZW1TdGF0aXN0aWNzKCkge1xuICAgIGlmICghdGhpcy5zaG93UHJvYmxlbVN0YXRpc3RpY3NGb290ZXIgJiYgIXRoaXMuc2hvd1NFQ29sdW1uKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIGlmICh0aGlzLnByb2JsZW1TdGF0aXN0aWNzU291cmNlICE9PSB0aGlzLmRhdGEgfHwgIXRoaXMucHJvYmxlbVN0YXRpc3RpY3NDYWNoZSkge1xuICAgICAgdGhpcy5wcm9ibGVtU3RhdGlzdGljc1NvdXJjZSA9IHRoaXMuZGF0YTtcbiAgICAgIHRoaXMucHJvYmxlbVN0YXRpc3RpY3NDYWNoZSA9IGNhbGN1bGF0ZVByb2JsZW1TdGF0aXN0aWNzRm9vdGVyKHRoaXMuZGF0YSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnByb2JsZW1TdGF0aXN0aWNzQ2FjaGU7XG4gIH1cblxuICBpc1N1cHBvcnRlZFZlcnNpb24oKSB7XG4gICAgcmV0dXJuIGNhbml1c2UodGhpcy5kYXRhLnZlcnNpb24pO1xuICB9XG5cbiAgc2hvd1RpbWVDb2x1bW4oKSB7XG4gICAgcmV0dXJuIHNob3VsZFNob3dUaW1lQ29sdW1uKHRoaXMuZGF0YS5yb3dzKTtcbiAgfVxuXG4gIHNob3dBdmF0YXJJbk9yZ2FuaXphdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5zcGxpdE9yZ2FuaXphdGlvbiAmJiB0aGlzLnVzZXJBdmF0YXJQbGFjZW1lbnQgPT09ICdvcmdhbml6YXRpb24nO1xuICB9XG5cbiAgbGVmdEZvb3RlckNvbHVtbkNvdW50KCkge1xuICAgIHJldHVybiB0aGlzLmRhdGEuc2VyaWVzLmxlbmd0aCArIDEgKyAxICsgKHRoaXMuc2hvd1RpbWVDb2x1bW4oKSA/IDEgOiAwKSArICh0aGlzLnNwbGl0T3JnYW5pemF0aW9uID8gMSA6IDApO1xuICB9XG5cbiAgZ2V0UmFua1ZhbHVlcyhyb3c6IFN0YXRpY1JhbmtsaXN0Um93KTogUmFua1ZhbHVlW10ge1xuICAgIHJldHVybiByb3cucmFua1ZhbHVlcyB8fCB0aGlzLmRhdGEuc2VyaWVzLm1hcCgoKSA9PiAoeyByYW5rOiBudWxsLCBzZWdtZW50SW5kZXg6IG51bGwgfSkpO1xuICB9XG5cbiAgZ2V0UmFua1RleHQocmFua1ZhbHVlOiBSYW5rVmFsdWUsIHJvdzogU3RhdGljUmFua2xpc3RSb3cpIHtcbiAgICByZXR1cm4gcmFua1ZhbHVlLnJhbmsgPyByYW5rVmFsdWUucmFuayA6IHJvdy51c2VyLm9mZmljaWFsID09PSBmYWxzZSA/ICfvvIonIDogJyc7XG4gIH1cblxuICByZXNvbHZlRGlzcGxheVRleHQodGV4dDogUGFyYW1ldGVyczx0eXBlb2YgcmVzb2x2ZVRleHQ+WzBdKSB7XG4gICAgcmV0dXJuIHJlc29sdmVUZXh0KHRleHQpO1xuICB9XG5cbiAgcmVzb2x2ZVNlcmllc0NvbHVtblRpdGxlKHNlcmllczogc3JrLlJhbmtTZXJpZXMsIGluZGV4OiBudW1iZXIpIHtcbiAgICBjb25zdCBzZXJpZXNUaXRsZXMgPSB0aGlzLmNvbHVtblRpdGxlcz8uc2VyaWVzO1xuICAgIGlmICh0eXBlb2Ygc2VyaWVzVGl0bGVzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICByZXR1cm4gc2VyaWVzVGl0bGVzKHNlcmllcywgaW5kZXgpID8/IHNlcmllcy50aXRsZTtcbiAgICB9XG4gICAgaWYgKEFycmF5LmlzQXJyYXkoc2VyaWVzVGl0bGVzKSkge1xuICAgICAgcmV0dXJuIHNlcmllc1RpdGxlc1tpbmRleF0gPz8gc2VyaWVzLnRpdGxlO1xuICAgIH1cbiAgICByZXR1cm4gc2VyaWVzLnRpdGxlO1xuICB9XG5cbiAgcmVzb2x2ZUNvbHVtblRpdGxlKGtleTogRXhjbHVkZTxrZXlvZiBSYW5rbGlzdENvbHVtblRpdGxlcywgJ3Nlcmllcyc+LCBmYWxsYmFjazogc3RyaW5nKSB7XG4gICAgcmV0dXJuIHRoaXMuY29sdW1uVGl0bGVzPy5ba2V5XSA/PyBmYWxsYmFjaztcbiAgfVxuXG4gIHByb2JsZW1BbGlhcyhwcm9ibGVtOiBzcmsuUHJvYmxlbSwgcHJvYmxlbUluZGV4OiBudW1iZXIpIHtcbiAgICByZXR1cm4gcHJvYmxlbS5hbGlhcyB8fCBudW1iZXJUb0FscGhhYmV0KHByb2JsZW1JbmRleCk7XG4gIH1cblxuICBwcm9ibGVtU3RhdHNUaXRsZShzdGF0aXN0aWNzOiBzcmsuUHJvYmxlbVN0YXRpc3RpY3MpIHtcbiAgICBjb25zdCByYXRpbyA9IHN0YXRpc3RpY3Muc3VibWl0dGVkID8gKChzdGF0aXN0aWNzLmFjY2VwdGVkIC8gc3RhdGlzdGljcy5zdWJtaXR0ZWQpICogMTAwKS50b0ZpeGVkKDEpIDogMDtcbiAgICByZXR1cm4gYCR7c3RhdGlzdGljcy5hY2NlcHRlZH0gLyAke3N0YXRpc3RpY3Muc3VibWl0dGVkfSAoJHtyYXRpb30lKWA7XG4gIH1cblxuICBwcm9ibGVtSGVhZGVyQmFja2dyb3VuZEltYWdlKHByb2JsZW06IHNyay5Qcm9ibGVtLCBncmFkaWVudERpcmVjdGlvbiA9IDE4MCkge1xuICAgIHJldHVybiBnZXRQcm9ibGVtSGVhZGVyQmFja2dyb3VuZEltYWdlKHByb2JsZW0uc3R5bGUsIHRoaXMudGhlbWUsIGdyYWRpZW50RGlyZWN0aW9uKTtcbiAgfVxuXG4gIHJlc29sdmVkVXNlck1hcmtlcnModXNlcjogc3JrLlVzZXIpIHtcbiAgICByZXR1cm4gcmVzb2x2ZVVzZXJNYXJrZXJzKHVzZXIsIHRoaXMuZGF0YS5tYXJrZXJzKS5tYXAoKG1hcmtlcikgPT4gKHtcbiAgICAgIG1hcmtlcixcbiAgICAgIHByZXNlbnRhdGlvbjogZ2V0TWFya2VyUHJlc2VudGF0aW9uKG1hcmtlciwgdGhpcy50aGVtZSksXG4gICAgfSkpO1xuICB9XG5cbiAgZm9ybWF0QXNzZXRVcmwodXJsOiBzdHJpbmcsIGZpZWxkOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gcmVzb2x2ZVNya0Fzc2V0VXJsKHVybCwgZmllbGQsIHRoaXMuZm9ybWF0U3JrQXNzZXRVcmwpO1xuICB9XG5cbiAgZm9ybWF0VGltZSh0aW1lOiBQYXJhbWV0ZXJzPHR5cGVvZiBmb3JtYXRUaW1lRHVyYXRpb24+WzBdKSB7XG4gICAgcmV0dXJuIGZvcm1hdFRpbWVEdXJhdGlvbih0aW1lLCAnbWluJywgTWF0aC5mbG9vcik7XG4gIH1cblxuICBjYWxjdWxhdGVEaXJ0UGVyY2VudGFnZShyb3c6IFN0YXRpY1JhbmtsaXN0Um93KSB7XG4gICAgcmV0dXJuIGNhbGN1bGF0ZURpcnRQZXJjZW50YWdlKHJvdyk7XG4gIH1cblxuICBjYWxjdWxhdGVTRVZhbHVlKHJvdzogU3RhdGljUmFua2xpc3RSb3csIHByb2JsZW1TdGF0aXN0aWNzOiBQcm9ibGVtU3RhdGlzdGljc0Zvb3RlcltdKSB7XG4gICAgcmV0dXJuIGNhbGN1bGF0ZVNFVmFsdWUocm93LCBwcm9ibGVtU3RhdGlzdGljcyk7XG4gIH1cblxuICBzdGF0dXNQcmVzZW50YXRpb24oc3RhdHVzOiBzcmsuUmFua1Byb2JsZW1TdGF0dXMpIHtcbiAgICByZXR1cm4gZ2V0UmFua1Byb2JsZW1TdGF0dXNDZWxsUHJlc2VudGF0aW9uKHN0YXR1cywgdGhpcy5kYXRhLCB0aGlzLnN0YXR1c0NlbGxQcmVzZXQpO1xuICB9XG5cbiAgaXNOdW1iZXIodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBudW1iZXIge1xuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInO1xuICB9XG5cbiAgZ2V0U3RhdHVzU29sdXRpb25zKHN0YXR1czogc3JrLlJhbmtQcm9ibGVtU3RhdHVzKSB7XG4gICAgcmV0dXJuIFsuLi4oc3RhdHVzLnNvbHV0aW9ucyB8fCBbXSldLnJldmVyc2UoKTtcbiAgfVxuXG4gIHN0YXR1c0NlbGxDbGFzcyhzdGF0dXM6IHNyay5SYW5rUHJvYmxlbVN0YXR1cykge1xuICAgIGNvbnN0IGNsYXNzTmFtZXMgPSBbJ3Nyay1wcmVzdC1zdGF0dXMtYmxvY2snLCAnc3JrLS10ZXh0LWNlbnRlcicsICdzcmstLW5vd3JhcCddO1xuICAgIGlmICh0aGlzLmlzU3RhdHVzQ2xpY2thYmxlKHN0YXR1cykpIHtcbiAgICAgIGNsYXNzTmFtZXMucHVzaCgnc3JrLS1jdXJzb3ItcG9pbnRlcicpO1xuICAgIH1cbiAgICBpZiAodGhpcy5zdGF0dXNDb2xvckFzVGV4dCkge1xuICAgICAgY2xhc3NOYW1lcy5wdXNoKCdzcmstcHJlc3Qtc3RhdHVzLWJsb2NrLWNvbG9yLXRleHQnKTtcbiAgICB9XG4gICAgaWYgKHN0YXR1cy5yZXN1bHQgPT09ICdGQicpIHtcbiAgICAgIGNsYXNzTmFtZXMucHVzaCgnc3JrLXByZXN0LXN0YXR1cy1ibG9jay1mYicpO1xuICAgIH0gZWxzZSBpZiAoc3RhdHVzLnJlc3VsdCA9PT0gJ0FDJykge1xuICAgICAgY2xhc3NOYW1lcy5wdXNoKCdzcmstcHJlc3Qtc3RhdHVzLWJsb2NrLWFjY2VwdGVkJyk7XG4gICAgfSBlbHNlIGlmIChzdGF0dXMucmVzdWx0ID09PSAnPycpIHtcbiAgICAgIGNsYXNzTmFtZXMucHVzaCgnc3JrLXByZXN0LXN0YXR1cy1ibG9jay1mcm96ZW4nKTtcbiAgICB9IGVsc2UgaWYgKHN0YXR1cy5yZXN1bHQgPT09ICdSSicpIHtcbiAgICAgIGNsYXNzTmFtZXMucHVzaCgnc3JrLXByZXN0LXN0YXR1cy1ibG9jay1mYWlsZWQnKTtcbiAgICB9XG4gICAgcmV0dXJuIGNsYXNzTmFtZXMuam9pbignICcpO1xuICB9XG5cbiAgaXNTdGF0dXNDbGlja2FibGUoc3RhdHVzOiBzcmsuUmFua1Byb2JsZW1TdGF0dXMpIHtcbiAgICByZXR1cm4gdGhpcy5nZXRTdGF0dXNTb2x1dGlvbnMoc3RhdHVzKS5sZW5ndGggPiAwO1xuICB9XG5cbiAgc3RhdHVzQ2VsbFJvbGUoc3RhdHVzOiBzcmsuUmFua1Byb2JsZW1TdGF0dXMpIHtcbiAgICByZXR1cm4gdGhpcy5pc1N0YXR1c0NsaWNrYWJsZShzdGF0dXMpID8gJ2J1dHRvbicgOiBudWxsO1xuICB9XG5cbiAgc3RhdHVzQ2VsbFRhYkluZGV4KHN0YXR1czogc3JrLlJhbmtQcm9ibGVtU3RhdHVzKSB7XG4gICAgcmV0dXJuIHRoaXMuaXNTdGF0dXNDbGlja2FibGUoc3RhdHVzKSA/IDAgOiBudWxsO1xuICB9XG5cbiAgYnVpbGRVc2VyQ2VsbENvbnRleHQocm93OiBTdGF0aWNSYW5rbGlzdFJvdywgcm93SW5kZXg6IG51bWJlcik6IFVzZXJDZWxsVGVtcGxhdGVDb250ZXh0IHtcbiAgICByZXR1cm4ge1xuICAgICAgJGltcGxpY2l0OiByb3cudXNlcixcbiAgICAgIHVzZXI6IHJvdy51c2VyLFxuICAgICAgcm93LFxuICAgICAgcm93SW5kZXgsXG4gICAgICByYW5rbGlzdDogdGhpcy5kYXRhLFxuICAgICAgbWFya2VyczogdGhpcy5kYXRhLm1hcmtlcnMsXG4gICAgICBoaWRlT3JnYW5pemF0aW9uOiB0aGlzLnNwbGl0T3JnYW5pemF0aW9uLFxuICAgICAgaGlkZUF2YXRhcjogdGhpcy5zaG93QXZhdGFySW5Pcmdhbml6YXRpb24oKSxcbiAgICAgIG9uQ2xpY2s6IChldmVudD86IE1vdXNlRXZlbnQpID0+IHRoaXMuZW1pdFVzZXJDbGljayhldmVudCwgcm93LCByb3dJbmRleCksXG4gICAgfTtcbiAgfVxuXG4gIGJ1aWxkU3RhdHVzQ2VsbENvbnRleHQoXG4gICAgcm93OiBTdGF0aWNSYW5rbGlzdFJvdyxcbiAgICByb3dJbmRleDogbnVtYmVyLFxuICAgIHN0YXR1czogc3JrLlJhbmtQcm9ibGVtU3RhdHVzLFxuICAgIHByb2JsZW1JbmRleDogbnVtYmVyLFxuICApOiBTdGF0dXNDZWxsVGVtcGxhdGVDb250ZXh0IHtcbiAgICByZXR1cm4ge1xuICAgICAgJGltcGxpY2l0OiBzdGF0dXMsXG4gICAgICBzdGF0dXMsXG4gICAgICBwcm9ibGVtOiB0aGlzLmRhdGEucHJvYmxlbXNbcHJvYmxlbUluZGV4XSxcbiAgICAgIHByb2JsZW1JbmRleCxcbiAgICAgIHVzZXI6IHJvdy51c2VyLFxuICAgICAgcm93LFxuICAgICAgcm93SW5kZXgsXG4gICAgICByYW5rbGlzdDogdGhpcy5kYXRhLFxuICAgICAgc29sdXRpb25zOiB0aGlzLmdldFN0YXR1c1NvbHV0aW9ucyhzdGF0dXMpLFxuICAgICAgc3RhdHVzQ2VsbFByZXNldDogdGhpcy5zdGF0dXNDZWxsUHJlc2V0LFxuICAgICAgc3RhdHVzQ29sb3JBc1RleHQ6IHRoaXMuc3RhdHVzQ29sb3JBc1RleHQsXG4gICAgICBlbXB0eVN0YXR1c1BsYWNlaG9sZGVyOiB0aGlzLmVtcHR5U3RhdHVzUGxhY2Vob2xkZXIsXG4gICAgICBvbkNsaWNrOiAoZXZlbnQ/OiBNb3VzZUV2ZW50KSA9PiB0aGlzLmVtaXRTb2x1dGlvbkNsaWNrKGV2ZW50LCByb3csIHJvd0luZGV4LCBzdGF0dXMsIHByb2JsZW1JbmRleCksXG4gICAgfTtcbiAgfVxuXG4gIGFjdGl2YXRlVXNlckNlbGxGcm9tS2V5Ym9hcmQoZXZlbnQ6IEV2ZW50LCByb3c6IFN0YXRpY1JhbmtsaXN0Um93LCByb3dJbmRleDogbnVtYmVyKSB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB0aGlzLmVtaXRVc2VyQ2xpY2sodW5kZWZpbmVkLCByb3csIHJvd0luZGV4KTtcbiAgfVxuXG4gIGFjdGl2YXRlU3RhdHVzQ2VsbEZyb21LZXlib2FyZChcbiAgICBldmVudDogRXZlbnQsXG4gICAgcm93OiBTdGF0aWNSYW5rbGlzdFJvdyxcbiAgICByb3dJbmRleDogbnVtYmVyLFxuICAgIHN0YXR1czogc3JrLlJhbmtQcm9ibGVtU3RhdHVzLFxuICAgIHByb2JsZW1JbmRleDogbnVtYmVyLFxuICApIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHRoaXMuZW1pdFNvbHV0aW9uQ2xpY2sodW5kZWZpbmVkLCByb3csIHJvd0luZGV4LCBzdGF0dXMsIHByb2JsZW1JbmRleCk7XG4gIH1cblxuICBlbWl0VXNlckNsaWNrKGV2ZW50OiBNb3VzZUV2ZW50IHwgdW5kZWZpbmVkLCByb3c6IFN0YXRpY1JhbmtsaXN0Um93LCByb3dJbmRleDogbnVtYmVyKSB7XG4gICAgaWYgKGV2ZW50KSB7XG4gICAgICBjYXB0dXJlTW9kYWxUcmlnZ2VyUG9pbnRGcm9tTW91c2VFdmVudChldmVudCwge1xuICAgICAgICBzb3VyY2U6ICd1c2VyLWNlbGwnLFxuICAgICAgICBjb250ZXh0OiB7XG4gICAgICAgICAgcm93SW5kZXgsXG4gICAgICAgICAgdXNlcklkOiByb3cudXNlci5pZCB8fCBudWxsLFxuICAgICAgICAgIHVzZXJOYW1lOiB0aGlzLnJlc29sdmVEaXNwbGF5VGV4dChyb3cudXNlci5uYW1lKSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICB0aGlzLnVzZXJDbGljay5lbWl0KHtcbiAgICAgIHVzZXI6IHJvdy51c2VyLFxuICAgICAgcm93LFxuICAgICAgcm93SW5kZXgsXG4gICAgICByYW5rbGlzdDogdGhpcy5kYXRhLFxuICAgIH0pO1xuICB9XG5cbiAgZW1pdFNvbHV0aW9uQ2xpY2soXG4gICAgZXZlbnQ6IE1vdXNlRXZlbnQgfCB1bmRlZmluZWQsXG4gICAgcm93OiBTdGF0aWNSYW5rbGlzdFJvdyxcbiAgICByb3dJbmRleDogbnVtYmVyLFxuICAgIHN0YXR1czogc3JrLlJhbmtQcm9ibGVtU3RhdHVzLFxuICAgIHByb2JsZW1JbmRleDogbnVtYmVyLFxuICApIHtcbiAgICBjb25zdCBzb2x1dGlvbnMgPSB0aGlzLmdldFN0YXR1c1NvbHV0aW9ucyhzdGF0dXMpO1xuICAgIGlmICghc29sdXRpb25zLmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoZXZlbnQpIHtcbiAgICAgIGNhcHR1cmVNb2RhbFRyaWdnZXJQb2ludEZyb21Nb3VzZUV2ZW50KGV2ZW50LCB7XG4gICAgICAgIHNvdXJjZTogJ3N0YXR1cy1jZWxsJyxcbiAgICAgICAgY29udGV4dDoge1xuICAgICAgICAgIHJvd0luZGV4LFxuICAgICAgICAgIHByb2JsZW1JbmRleCxcbiAgICAgICAgICBwcm9ibGVtQWxpYXM6IHRoaXMuZGF0YS5wcm9ibGVtc1twcm9ibGVtSW5kZXhdPy5hbGlhcyB8fCBudWxsLFxuICAgICAgICAgIHByb2JsZW1UaXRsZTogdGhpcy5kYXRhLnByb2JsZW1zW3Byb2JsZW1JbmRleF0gPyB0aGlzLnJlc29sdmVEaXNwbGF5VGV4dCh0aGlzLmRhdGEucHJvYmxlbXNbcHJvYmxlbUluZGV4XS50aXRsZSkgOiBudWxsLFxuICAgICAgICAgIHVzZXJJZDogcm93LnVzZXIuaWQgfHwgbnVsbCxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICB0aGlzLnNvbHV0aW9uQ2xpY2suZW1pdCh7XG4gICAgICB1c2VyOiByb3cudXNlcixcbiAgICAgIHJvdyxcbiAgICAgIHJvd0luZGV4LFxuICAgICAgcHJvYmxlbUluZGV4LFxuICAgICAgcHJvYmxlbTogdGhpcy5kYXRhLnByb2JsZW1zW3Byb2JsZW1JbmRleF0sXG4gICAgICBzdGF0dXMsXG4gICAgICBzb2x1dGlvbnMsXG4gICAgICByYW5rbGlzdDogdGhpcy5kYXRhLFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSByZXNvbHZlU2VyaWVzU2VnbWVudChyYW5rVmFsdWU6IFJhbmtWYWx1ZSwgc2VyaWVzOiBzcmsuUmFua1NlcmllcyB8IHVuZGVmaW5lZCkge1xuICAgIGNvbnN0IGluZGV4ID0gcmFua1ZhbHVlLnNlZ21lbnRJbmRleCB8fCByYW5rVmFsdWUuc2VnbWVudEluZGV4ID09PSAwID8gcmFua1ZhbHVlLnNlZ21lbnRJbmRleCA6IC0xO1xuICAgIHJldHVybiAoc2VyaWVzPy5zZWdtZW50cyB8fCBbXSlbaW5kZXhdIHx8IHt9O1xuICB9XG5cbiAgaXNTZXJpZXNTZWdtZW50ZWRDb2x1bW4oc2VyaWVzOiBzcmsuUmFua1NlcmllcyB8IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiAoc2VyaWVzPy5zZWdtZW50cyB8fCBbXSkuc29tZSgoc2VnbWVudCkgPT4gdHlwZW9mIHNlZ21lbnQuc3R5bGUgPT09ICdzdHJpbmcnKTtcbiAgfVxuXG4gIGdldFNlcmllc1NlZ21lbnRDbGFzcyhyYW5rVmFsdWU6IFJhbmtWYWx1ZSwgc2VyaWVzOiBzcmsuUmFua1NlcmllcyB8IHVuZGVmaW5lZCkge1xuICAgIGNvbnN0IHNlZ21lbnRTdHlsZSA9IHRoaXMucmVzb2x2ZVNlcmllc1NlZ21lbnQocmFua1ZhbHVlLCBzZXJpZXMpLnN0eWxlO1xuICAgIHJldHVybiB0eXBlb2Ygc2VnbWVudFN0eWxlID09PSAnc3RyaW5nJyA/IGBzcmstcHJlc2V0LXNlcmllcy1zZWdtZW50LSR7c2VnbWVudFN0eWxlfWAgOiAnJztcbiAgfVxuXG4gIGdldFNlcmllc1NlZ21lbnRTdHlsZShyYW5rVmFsdWU6IFJhbmtWYWx1ZSwgc2VyaWVzOiBzcmsuUmFua1NlcmllcyB8IHVuZGVmaW5lZCkge1xuICAgIGNvbnN0IGVtcHR5Q29sb3I6IFRoZW1lQ29sb3IgPSB7XG4gICAgICBbRW51bVRoZW1lLmxpZ2h0XTogdW5kZWZpbmVkLFxuICAgICAgW0VudW1UaGVtZS5kYXJrXTogdW5kZWZpbmVkLFxuICAgIH07XG4gICAgY29uc3Qgc2VnbWVudFN0eWxlID0gdGhpcy5yZXNvbHZlU2VyaWVzU2VnbWVudChyYW5rVmFsdWUsIHNlcmllcykuc3R5bGU7XG4gICAgaWYgKCFzZWdtZW50U3R5bGUgfHwgdHlwZW9mIHNlZ21lbnRTdHlsZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiB7fTtcbiAgICB9XG4gICAgY29uc3Qgc3R5bGUgPSByZXNvbHZlU3R5bGUoc2VnbWVudFN0eWxlKTtcbiAgICBjb25zdCB0ZXh0Q29sb3IgPSBzdHlsZS50ZXh0Q29sb3IgfHwgZW1wdHlDb2xvcjtcbiAgICBjb25zdCBiYWNrZ3JvdW5kQ29sb3IgPSBzdHlsZS5iYWNrZ3JvdW5kQ29sb3IgfHwgZW1wdHlDb2xvcjtcbiAgICByZXR1cm4ge1xuICAgICAgY29sb3I6IHRleHRDb2xvclt0aGlzLnRoZW1lXSxcbiAgICAgIGJhY2tncm91bmRDb2xvcjogYmFja2dyb3VuZENvbG9yW3RoaXMudGhlbWVdLFxuICAgIH07XG4gIH1cblxuICBnZXRQcm9ibGVtU3RhdGlzdGljc0Zvb3RlckNlbGxQcmltYXJ5KGtleTogc3RyaW5nLCBzdGF0OiBQcm9ibGVtU3RhdGlzdGljc0Zvb3Rlcikge1xuICAgIHN3aXRjaCAoa2V5KSB7XG4gICAgICBjYXNlICdhY2NlcHRlZCc6XG4gICAgICAgIHJldHVybiBzdGF0LmFjY2VwdGVkO1xuICAgICAgY2FzZSAndHJpZWQnOlxuICAgICAgICByZXR1cm4gc3RhdC50cmllZDtcbiAgICAgIGNhc2UgJ3N1Ym1pdHRlZCc6XG4gICAgICAgIHJldHVybiBzdGF0LnN1Ym1pdHRlZDtcbiAgICAgIGNhc2UgJ2RpcnQnOlxuICAgICAgICByZXR1cm4gc3RhdC5kaXJ0O1xuICAgICAgY2FzZSAnc2UnOlxuICAgICAgICByZXR1cm4gZm9ybWF0UHJvYmxlbVN0YXRpc3RpY3NBdmVyYWdlSGFyZG5lc3Moc3RhdCk7XG4gICAgICBjYXNlICdmaXJzdEFjY2VwdGVkJzpcbiAgICAgICAgcmV0dXJuIGZvcm1hdFByb2JsZW1TdGF0aXN0aWNzQWNjZXB0ZWRNaW51dGUoc3RhdC5maXJzdEFjY2VwdGVkVGltZSk7XG4gICAgICBjYXNlICdsYXN0QWNjZXB0ZWQnOlxuICAgICAgICByZXR1cm4gZm9ybWF0UHJvYmxlbVN0YXRpc3RpY3NBY2NlcHRlZE1pbnV0ZShzdGF0Lmxhc3RBY2NlcHRlZFRpbWUpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgfVxuXG4gIGdldFByb2JsZW1TdGF0aXN0aWNzRm9vdGVyQ2VsbFNlY29uZGFyeShrZXk6IHN0cmluZywgc3RhdDogUHJvYmxlbVN0YXRpc3RpY3NGb290ZXIpIHtcbiAgICBzd2l0Y2ggKGtleSkge1xuICAgICAgY2FzZSAnYWNjZXB0ZWQnOlxuICAgICAgICByZXR1cm4gZm9ybWF0UHJvYmxlbVN0YXRpc3RpY3NQZXJjZW50KHN0YXQuYWNjZXB0ZWQsIHN0YXQucGFydGljaXBhbnRDb3VudCk7XG4gICAgICBjYXNlICd0cmllZCc6XG4gICAgICAgIHJldHVybiBmb3JtYXRQcm9ibGVtU3RhdGlzdGljc1BlcmNlbnQoc3RhdC50cmllZCwgc3RhdC5wYXJ0aWNpcGFudENvdW50KTtcbiAgICAgIGNhc2UgJ2RpcnQnOlxuICAgICAgICByZXR1cm4gZm9ybWF0UHJvYmxlbVN0YXRpc3RpY3NQZXJjZW50KHN0YXQuZGlydCwgc3RhdC5kaXJ0U3VibWl0dGVkKTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG59XG4iXX0=