bways-report 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/README.md +150 -51
  2. package/esm2022/lib/core/errors/reporting-errors.mjs +2 -2
  3. package/esm2022/lib/core/index.mjs +3 -1
  4. package/esm2022/lib/core/models/report-datasource.model.mjs +1 -1
  5. package/esm2022/lib/core/models/report-definition.model.mjs +1 -1
  6. package/esm2022/lib/core/models/report-grid.model.mjs +1 -1
  7. package/esm2022/lib/core/services/report-session-context.service.mjs +50 -5
  8. package/esm2022/lib/core/utils/data-normalization.util.mjs +56 -0
  9. package/esm2022/lib/core/utils/report-parameter.util.mjs +180 -0
  10. package/esm2022/lib/data-access/adapters/http-datasource.adapter.mjs +82 -0
  11. package/esm2022/lib/data-access/adapters/http-lookup.adapter.mjs +34 -9
  12. package/esm2022/lib/data-access/adapters/http-masterdata.adapter.mjs +38 -0
  13. package/esm2022/lib/data-access/adapters/http-persistence.adapter.mjs +217 -0
  14. package/esm2022/lib/data-access/adapters/http-schema-discovery.adapter.mjs +3 -1
  15. package/esm2022/lib/data-access/adapters/index.mjs +8 -3
  16. package/esm2022/lib/data-access/adapters/local-storage-persistence.adapter.mjs +167 -0
  17. package/esm2022/lib/data-access/adapters/mock-datasource.adapter.mjs +60 -0
  18. package/esm2022/lib/data-access/contracts/api-dtos.mjs +6 -0
  19. package/esm2022/lib/data-access/contracts/index.mjs +2 -1
  20. package/esm2022/lib/features/designer/components/design-canvas/design-canvas.component.mjs +555 -92
  21. package/esm2022/lib/features/designer/components/property-editor/property-editor-action.component.mjs +593 -0
  22. package/esm2022/lib/features/designer/components/property-editor/property-editor-datasource.component.mjs +164 -23
  23. package/esm2022/lib/features/designer/components/property-editor/property-editor-grid.component.mjs +410 -12
  24. package/esm2022/lib/features/designer/components/property-editor/property-editor.component.mjs +149 -2
  25. package/esm2022/lib/features/designer/components/toolbar/designer-toolbar.component.mjs +109 -6
  26. package/esm2022/lib/features/designer/designer.component.mjs +101 -12
  27. package/esm2022/lib/features/designer/index.mjs +4 -1
  28. package/esm2022/lib/features/designer/rpt-report-designer.component.mjs +102 -0
  29. package/esm2022/lib/features/designer/services/designer-state.service.mjs +10 -9
  30. package/esm2022/lib/features/designer/services/report-template.service.mjs +318 -0
  31. package/esm2022/lib/features/designer/utilities/canvas-layout.util.mjs +41 -9
  32. package/esm2022/lib/features/export/index.mjs +2 -2
  33. package/esm2022/lib/features/export/models/export.models.mjs +1 -1
  34. package/esm2022/lib/features/export/services/report-export.service.mjs +420 -5
  35. package/esm2022/lib/features/routing/components/routed-report-runtime.component.mjs +2 -2
  36. package/esm2022/lib/features/runtime/dynamic-renderer.component.mjs +231 -33
  37. package/esm2022/lib/features/runtime/index.mjs +2 -1
  38. package/esm2022/lib/features/runtime/report-execution.service.mjs +64 -0
  39. package/esm2022/lib/features/runtime/report-grid-bridge.component.mjs +224 -26
  40. package/esm2022/lib/features/runtime/report-runtime.component.mjs +341 -7
  41. package/esm2022/lib/features/runtime/rpt-report.component.mjs +537 -0
  42. package/esm2022/lib/primitives/components/button/rpt-button.component.mjs +19 -8
  43. package/esm2022/lib/primitives/components/chart-bridge/report-chart-bridge.component.mjs +18 -7
  44. package/esm2022/lib/primitives/components/date-range/rpt-date-range.component.mjs +346 -0
  45. package/esm2022/lib/primitives/components/dropdown/rpt-dropdown.component.mjs +727 -73
  46. package/esm2022/lib/primitives/components/icon/rpt-icon.component.mjs +8 -1
  47. package/esm2022/lib/primitives/components/index.mjs +2 -1
  48. package/esm2022/lib/primitives/register-builtins.mjs +51 -2
  49. package/esm2022/lib/provide-reporting.mjs +145 -24
  50. package/fesm2022/bways-report.mjs +6871 -753
  51. package/fesm2022/bways-report.mjs.map +1 -1
  52. package/lib/core/index.d.ts +2 -0
  53. package/lib/core/models/report-datasource.model.d.ts +9 -0
  54. package/lib/core/models/report-definition.model.d.ts +2 -0
  55. package/lib/core/models/report-grid.model.d.ts +44 -0
  56. package/lib/core/services/report-session-context.service.d.ts +6 -1
  57. package/lib/core/utils/data-normalization.util.d.ts +15 -0
  58. package/lib/core/utils/report-parameter.util.d.ts +35 -0
  59. package/lib/data-access/adapters/http-datasource.adapter.d.ts +20 -0
  60. package/lib/data-access/adapters/http-lookup.adapter.d.ts +3 -0
  61. package/lib/data-access/adapters/http-masterdata.adapter.d.ts +13 -0
  62. package/lib/data-access/adapters/http-persistence.adapter.d.ts +27 -0
  63. package/lib/data-access/adapters/http-schema-discovery.adapter.d.ts +2 -0
  64. package/lib/data-access/adapters/index.d.ts +7 -2
  65. package/lib/data-access/adapters/local-storage-persistence.adapter.d.ts +19 -0
  66. package/lib/data-access/adapters/mock-datasource.adapter.d.ts +9 -0
  67. package/lib/data-access/contracts/api-dtos.d.ts +67 -0
  68. package/lib/data-access/contracts/index.d.ts +1 -0
  69. package/lib/features/designer/components/design-canvas/design-canvas.component.d.ts +22 -0
  70. package/lib/features/designer/components/property-editor/parameter-binding-editor.component.d.ts +1 -1
  71. package/lib/features/designer/components/property-editor/property-editor-action.component.d.ts +33 -0
  72. package/lib/features/designer/components/property-editor/property-editor-datasource.component.d.ts +4 -0
  73. package/lib/features/designer/components/property-editor/property-editor-grid.component.d.ts +16 -2
  74. package/lib/features/designer/components/property-editor/property-editor.component.d.ts +5 -0
  75. package/lib/features/designer/components/toolbar/designer-toolbar.component.d.ts +7 -0
  76. package/lib/features/designer/designer.component.d.ts +5 -0
  77. package/lib/features/designer/index.d.ts +4 -0
  78. package/lib/features/designer/rpt-report-designer.component.d.ts +38 -0
  79. package/lib/features/designer/services/designer-state.service.d.ts +1 -1
  80. package/lib/features/designer/services/report-template.service.d.ts +32 -0
  81. package/lib/features/designer/utilities/canvas-layout.util.d.ts +4 -0
  82. package/lib/features/export/index.d.ts +2 -2
  83. package/lib/features/export/models/export.models.d.ts +23 -0
  84. package/lib/features/export/services/report-export.service.d.ts +31 -2
  85. package/lib/features/runtime/dynamic-renderer.component.d.ts +39 -2
  86. package/lib/features/runtime/index.d.ts +2 -0
  87. package/lib/features/runtime/report-execution.service.d.ts +16 -0
  88. package/lib/features/runtime/report-grid-bridge.component.d.ts +129 -6
  89. package/lib/features/runtime/report-runtime.component.d.ts +83 -1
  90. package/lib/features/runtime/rpt-report.component.d.ts +66 -0
  91. package/lib/primitives/components/button/rpt-button.component.d.ts +5 -2
  92. package/lib/primitives/components/chart-bridge/report-chart-bridge.component.d.ts +1 -0
  93. package/lib/primitives/components/date-range/rpt-date-range.component.d.ts +43 -0
  94. package/lib/primitives/components/dropdown/rpt-dropdown.component.d.ts +55 -7
  95. package/lib/primitives/components/index.d.ts +2 -0
  96. package/lib/provide-reporting.d.ts +79 -26
  97. package/package.json +2 -1
  98. package/schematics/collection.json +10 -0
  99. package/schematics/ng-add/index.js +45 -0
  100. package/schematics/ng-add/schema.json +17 -0
@@ -1,5 +1,6 @@
1
1
  import { Injectable, inject } from '@angular/core';
2
2
  import { DOCUMENT } from '@angular/common';
3
+ import { ReportSessionContextService } from '../../../core/services/report-session-context.service';
3
4
  import * as i0 from "@angular/core";
4
5
  /**
5
6
  * Sanitizes and escapes a single cell value for CSV output.
@@ -19,11 +20,55 @@ export function sanitizeCsvCell(value, delimiter = ',') {
19
20
  }
20
21
  return str;
21
22
  }
23
+ /**
24
+ * Formats a record or string of active filter criteria into a clean text line.
25
+ */
26
+ export function formatFilterSummary(summary) {
27
+ if (!summary)
28
+ return '';
29
+ if (typeof summary === 'string')
30
+ return summary;
31
+ return Object.entries(summary)
32
+ .filter(([_, v]) => v !== undefined && v !== null && v !== '')
33
+ .map(([k, v]) => {
34
+ if (typeof v === 'object' && v !== null && 'from' in v && 'to' in v) {
35
+ return `${k}: ${v.from} to ${v.to}`;
36
+ }
37
+ return `${k}: ${v}`;
38
+ })
39
+ .join(' | ');
40
+ }
22
41
  /**
23
42
  * Pure generator function to create CSV content string from row data and columns.
24
43
  */
25
- export function generateCsvContent(rows, columns, delimiter = ',', includeHeader = true, addBom = true) {
44
+ export function generateCsvContent(rows, columns, delimiter = ',', includeHeader = true, addBom = true, brandedHeader) {
26
45
  const lines = [];
46
+ if (brandedHeader) {
47
+ if (brandedHeader.companyName || brandedHeader.branchName) {
48
+ lines.push(`# Company: ${brandedHeader.companyName ?? ''}${brandedHeader.branchName ? ` | Branch: ${brandedHeader.branchName}` : ''}`);
49
+ }
50
+ if (brandedHeader.reportTitle) {
51
+ lines.push(`# Report: ${brandedHeader.reportTitle}`);
52
+ }
53
+ const genInfo = [];
54
+ if (brandedHeader.generatedAt) {
55
+ const dt = brandedHeader.generatedAt instanceof Date
56
+ ? brandedHeader.generatedAt.toISOString().replace('T', ' ').slice(0, 19)
57
+ : String(brandedHeader.generatedAt);
58
+ genInfo.push(`Generated: ${dt}`);
59
+ }
60
+ if (brandedHeader.generatedBy) {
61
+ genInfo.push(`User: ${brandedHeader.generatedBy}`);
62
+ }
63
+ if (genInfo.length > 0) {
64
+ lines.push(`# ${genInfo.join(' | ')}`);
65
+ }
66
+ const filterText = formatFilterSummary(brandedHeader.activeFilterSummary);
67
+ if (filterText) {
68
+ lines.push(`# Active Filters: ${filterText}`);
69
+ }
70
+ lines.push('# ' + '-'.repeat(40));
71
+ }
27
72
  if (includeHeader) {
28
73
  const headerLine = columns
29
74
  .map((col) => sanitizeCsvCell(col.header, delimiter))
@@ -41,8 +86,302 @@ export function generateCsvContent(rows, columns, delimiter = ',', includeHeader
41
86
  const csvBody = lines.join('\r\n');
42
87
  return addBom ? '\uFEFF' + csvBody : csvBody;
43
88
  }
89
+ /**
90
+ * Generates an Excel-compatible XML Spreadsheet (SpreadsheetML) document string.
91
+ */
92
+ export function generateExcelXml(rows, columns, sheetName = 'Report Data', brandedHeader) {
93
+ const escapeXml = (val) => {
94
+ if (val === null || val === undefined)
95
+ return '';
96
+ return String(val)
97
+ .replace(/&/g, '&')
98
+ .replace(/</g, '&lt;')
99
+ .replace(/>/g, '&gt;')
100
+ .replace(/"/g, '&quot;')
101
+ .replace(/'/g, '&apos;');
102
+ };
103
+ const xmlRows = [];
104
+ if (brandedHeader) {
105
+ if (brandedHeader.companyName || brandedHeader.reportTitle) {
106
+ const title = [brandedHeader.companyName, brandedHeader.reportTitle]
107
+ .filter(Boolean)
108
+ .join(' - ');
109
+ xmlRows.push(`
110
+ <Row ss:Height="24">
111
+ <Cell ss:StyleID="TitleStyle" ss:MergeAcross="${Math.max(0, columns.length - 1)}">
112
+ <Data ss:Type="String">${escapeXml(title)}</Data>
113
+ </Cell>
114
+ </Row>`);
115
+ }
116
+ const metaParts = [];
117
+ if (brandedHeader.branchName)
118
+ metaParts.push(`Branch: ${brandedHeader.branchName}`);
119
+ if (brandedHeader.generatedAt) {
120
+ const dt = brandedHeader.generatedAt instanceof Date
121
+ ? brandedHeader.generatedAt.toISOString().replace('T', ' ').slice(0, 19)
122
+ : String(brandedHeader.generatedAt);
123
+ metaParts.push(`Date: ${dt}`);
124
+ }
125
+ if (brandedHeader.generatedBy)
126
+ metaParts.push(`User: ${brandedHeader.generatedBy}`);
127
+ if (metaParts.length > 0) {
128
+ xmlRows.push(`
129
+ <Row ss:Height="16">
130
+ <Cell ss:StyleID="SubTitleStyle" ss:MergeAcross="${Math.max(0, columns.length - 1)}">
131
+ <Data ss:Type="String">${escapeXml(metaParts.join(' | '))}</Data>
132
+ </Cell>
133
+ </Row>`);
134
+ }
135
+ const filterText = formatFilterSummary(brandedHeader.activeFilterSummary);
136
+ if (filterText) {
137
+ xmlRows.push(`
138
+ <Row ss:Height="16">
139
+ <Cell ss:StyleID="FilterStyle" ss:MergeAcross="${Math.max(0, columns.length - 1)}">
140
+ <Data ss:Type="String">${escapeXml(`Filters: ${filterText}`)}</Data>
141
+ </Cell>
142
+ </Row>`);
143
+ }
144
+ // Blank row separator
145
+ xmlRows.push('<Row ss:Height="8" />');
146
+ }
147
+ // Column Headers
148
+ const headerCells = columns
149
+ .map((col) => `
150
+ <Cell ss:StyleID="HeaderStyle"><Data ss:Type="String">${escapeXml(col.header)}</Data></Cell>`)
151
+ .join('');
152
+ xmlRows.push(`<Row ss:Height="20">${headerCells}\n </Row>`);
153
+ // Data rows
154
+ rows.forEach((row, idx) => {
155
+ const isEven = idx % 2 === 0;
156
+ const styleId = isEven ? 'DataRowEven' : 'DataRowOdd';
157
+ const cells = columns
158
+ .map((col) => {
159
+ const val = row[col.field];
160
+ const formatted = col.formatter ? col.formatter(val, row) : val;
161
+ const isNum = typeof formatted === 'number' && !isNaN(formatted);
162
+ const type = isNum ? 'Number' : 'String';
163
+ return `<Cell ss:StyleID="${styleId}"><Data ss:Type="${type}">${escapeXml(formatted)}</Data></Cell>`;
164
+ })
165
+ .join('');
166
+ xmlRows.push(` <Row ss:Height="17">${cells}</Row>`);
167
+ });
168
+ return `<?xml version="1.0" encoding="UTF-8"?>
169
+ <?mso-application progid="Excel.Sheet"?>
170
+ <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
171
+ xmlns:o="urn:schemas-microsoft-com:office:office"
172
+ xmlns:x="urn:schemas-microsoft-com:office:excel"
173
+ xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet">
174
+ <Styles>
175
+ <Style ss:ID="Default" ss:Name="Normal">
176
+ <Alignment ss:Vertical="Center"/>
177
+ <Font ss:FontName="Segoe UI" ss:Size="10" ss:Color="#0F172A"/>
178
+ </Style>
179
+ <Style ss:ID="TitleStyle">
180
+ <Alignment ss:Horizontal="Left" ss:Vertical="Center"/>
181
+ <Font ss:FontName="Segoe UI" ss:Size="14" ss:Bold="1" ss:Color="#1E293B"/>
182
+ </Style>
183
+ <Style ss:ID="SubTitleStyle">
184
+ <Alignment ss:Horizontal="Left" ss:Vertical="Center"/>
185
+ <Font ss:FontName="Segoe UI" ss:Size="9" ss:Italic="1" ss:Color="#64748B"/>
186
+ </Style>
187
+ <Style ss:ID="FilterStyle">
188
+ <Alignment ss:Horizontal="Left" ss:Vertical="Center"/>
189
+ <Font ss:FontName="Segoe UI" ss:Size="9" ss:Bold="1" ss:Color="#2563EB"/>
190
+ <Interior ss:Color="#EFF6FF" ss:Pattern="Solid"/>
191
+ </Style>
192
+ <Style ss:ID="HeaderStyle">
193
+ <Alignment ss:Horizontal="Left" ss:Vertical="Center"/>
194
+ <Borders>
195
+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" ss:Color="#CBD5E1"/>
196
+ </Borders>
197
+ <Font ss:FontName="Segoe UI" ss:Size="10" ss:Bold="1" ss:Color="#FFFFFF"/>
198
+ <Interior ss:Color="#2563EB" ss:Pattern="Solid"/>
199
+ </Style>
200
+ <Style ss:ID="DataRowEven">
201
+ <Borders>
202
+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" ss:Color="#F1F5F9"/>
203
+ </Borders>
204
+ <Interior ss:Color="#FFFFFF" ss:Pattern="Solid"/>
205
+ </Style>
206
+ <Style ss:ID="DataRowOdd">
207
+ <Borders>
208
+ <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1" ss:Color="#F1F5F9"/>
209
+ </Borders>
210
+ <Interior ss:Color="#F8FAFC" ss:Pattern="Solid"/>
211
+ </Style>
212
+ </Styles>
213
+ <Worksheet ss:Name="${escapeXml(sheetName)}">
214
+ <Table>
215
+ ${columns.map(() => ' <Column ss:AutoFitWidth="1" ss:Width="120"/>').join('\n')}
216
+ ${xmlRows.join('\n')}
217
+ </Table>
218
+ </Worksheet>
219
+ </Workbook>`;
220
+ }
221
+ /**
222
+ * Generates an HTML document string formatted for printing and clean PDF conversion.
223
+ */
224
+ export function generateHtmlContent(rows, columns, title = 'Report Export', brandedHeader) {
225
+ const escapeHtml = (val) => {
226
+ if (val === null || val === undefined)
227
+ return '';
228
+ return String(val)
229
+ .replace(/&/g, '&amp;')
230
+ .replace(/</g, '&lt;')
231
+ .replace(/>/g, '&gt;');
232
+ };
233
+ const headerHtml = brandedHeader
234
+ ? `
235
+ <header class="rpt-print-header">
236
+ <div class="rpt-print-meta">
237
+ ${brandedHeader.companyName
238
+ ? `<h1 class="rpt-company-title">${escapeHtml(brandedHeader.companyName)}</h1>`
239
+ : ''}
240
+ <h2 class="rpt-report-title">${escapeHtml(brandedHeader.reportTitle || title)}</h2>
241
+ <div class="rpt-meta-row">
242
+ ${brandedHeader.branchName ? `<span><strong>Branch:</strong> ${escapeHtml(brandedHeader.branchName)}</span>` : ''}
243
+ ${brandedHeader.generatedAt
244
+ ? `<span><strong>Date:</strong> ${escapeHtml(brandedHeader.generatedAt instanceof Date
245
+ ? brandedHeader.generatedAt.toLocaleString()
246
+ : brandedHeader.generatedAt)}</span>`
247
+ : ''}
248
+ ${brandedHeader.generatedBy ? `<span><strong>User:</strong> ${escapeHtml(brandedHeader.generatedBy)}</span>` : ''}
249
+ </div>
250
+ </div>
251
+ ${brandedHeader.activeFilterSummary
252
+ ? `<div class="rpt-filter-box"><strong>Active Filters:</strong> ${escapeHtml(formatFilterSummary(brandedHeader.activeFilterSummary))}</div>`
253
+ : ''}
254
+ </header>
255
+ `
256
+ : `<h2 class="rpt-report-title">${escapeHtml(title)}</h2>`;
257
+ const rowsHtml = rows
258
+ .map((r, idx) => `
259
+ <tr class="${idx % 2 === 0 ? 'even' : 'odd'}">
260
+ ${columns
261
+ .map((col) => {
262
+ const val = r[col.field];
263
+ const formatted = col.formatter ? col.formatter(val, r) : val;
264
+ return `<td>${escapeHtml(formatted)}</td>`;
265
+ })
266
+ .join('')}
267
+ </tr>`)
268
+ .join('');
269
+ return `<!DOCTYPE html>
270
+ <html lang="en">
271
+ <head>
272
+ <meta charset="utf-8">
273
+ <title>${escapeHtml(title)}</title>
274
+ <style>
275
+ body {
276
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
277
+ margin: 24px;
278
+ color: #0f172a;
279
+ background: #ffffff;
280
+ }
281
+ .rpt-print-header {
282
+ border-bottom: 2px solid #2563eb;
283
+ padding-bottom: 12px;
284
+ margin-bottom: 16px;
285
+ }
286
+ .rpt-company-title {
287
+ font-size: 1.25rem;
288
+ font-weight: 700;
289
+ color: #1e293b;
290
+ margin: 0 0 4px 0;
291
+ }
292
+ .rpt-report-title {
293
+ font-size: 1.1rem;
294
+ font-weight: 600;
295
+ color: #2563eb;
296
+ margin: 0 0 6px 0;
297
+ }
298
+ .rpt-meta-row {
299
+ display: flex;
300
+ gap: 16px;
301
+ font-size: 0.75rem;
302
+ color: #64748b;
303
+ }
304
+ .rpt-filter-box {
305
+ margin-top: 8px;
306
+ padding: 6px 10px;
307
+ background: #eff6ff;
308
+ border: 1px solid #bfdbfe;
309
+ border-radius: 4px;
310
+ font-size: 0.75rem;
311
+ color: #1e40af;
312
+ }
313
+ table {
314
+ width: 100%;
315
+ border-collapse: collapse;
316
+ font-size: 0.8rem;
317
+ }
318
+ th {
319
+ background: #2563eb;
320
+ color: #ffffff;
321
+ font-weight: 600;
322
+ text-align: left;
323
+ padding: 8px 10px;
324
+ border: 1px solid #1d4ed8;
325
+ }
326
+ td {
327
+ padding: 6px 10px;
328
+ border: 1px solid #e2e8f0;
329
+ }
330
+ tr.even {
331
+ background: #ffffff;
332
+ }
333
+ tr.odd {
334
+ background: #f8fafc;
335
+ }
336
+ @media print {
337
+ body { margin: 0; }
338
+ th { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
339
+ .rpt-filter-box { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
340
+ }
341
+ </style>
342
+ </head>
343
+ <body>
344
+ ${headerHtml}
345
+ <table>
346
+ <thead>
347
+ <tr>
348
+ ${columns.map((c) => `<th>${escapeHtml(c.header)}</th>`).join('')}
349
+ </tr>
350
+ </thead>
351
+ <tbody>
352
+ ${rowsHtml}
353
+ </tbody>
354
+ </table>
355
+ </body>
356
+ </html>`;
357
+ }
44
358
  export class ReportExportService {
45
359
  document = inject(DOCUMENT);
360
+ sessionService = inject(ReportSessionContextService, { optional: true });
361
+ /**
362
+ * Enriches branded header options with fallback session context data if available.
363
+ */
364
+ resolveBrandedHeader(header) {
365
+ const session = this.sessionService?.sessionContext() ?? {};
366
+ if (!header && Object.keys(session).length === 0) {
367
+ return undefined;
368
+ }
369
+ return {
370
+ companyName: header?.companyName ||
371
+ session['companyName'] ||
372
+ session['tenantName'] ||
373
+ session['company'],
374
+ branchName: header?.branchName ||
375
+ session['branchName'] ||
376
+ session['branchCode'],
377
+ reportTitle: header?.reportTitle,
378
+ generatedAt: header?.generatedAt || new Date(),
379
+ generatedBy: header?.generatedBy ||
380
+ session['userName'] ||
381
+ session['userId'],
382
+ activeFilterSummary: header?.activeFilterSummary,
383
+ };
384
+ }
46
385
  /**
47
386
  * Generates and triggers browser download of a CSV file.
48
387
  */
@@ -55,17 +394,93 @@ export class ReportExportService {
55
394
  const includeHeader = options.includeHeader !== false;
56
395
  const addBom = options.addBom !== false;
57
396
  const fileName = options.fileName || `report-export-${Date.now()}.csv`;
397
+ const brandedHeader = this.resolveBrandedHeader(options.brandedHeader);
58
398
  // If columns not provided, infer from first row keys
59
399
  const columns = options.columns && options.columns.length > 0
60
400
  ? options.columns
61
401
  : Object.keys(rows[0]).map((key) => ({
62
402
  field: key,
63
- header: key
403
+ header: key,
64
404
  }));
65
- const csvContent = generateCsvContent(rows, columns, delimiter, includeHeader, addBom);
405
+ const csvContent = generateCsvContent(rows, columns, delimiter, includeHeader, addBom, brandedHeader);
66
406
  const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
67
407
  this.downloadBlob(blob, fileName);
68
408
  }
409
+ /**
410
+ * Generates and triggers browser download of an Excel spreadsheet (.xls SpreadsheetML).
411
+ */
412
+ exportExcel(rows, options = {}) {
413
+ if (!rows || rows.length === 0) {
414
+ console.warn('[bways-report] No rows to export to Excel');
415
+ return;
416
+ }
417
+ const rawName = options.fileName || `report-export-${Date.now()}`;
418
+ const fileName = rawName.endsWith('.xls') || rawName.endsWith('.xlsx')
419
+ ? rawName
420
+ : `${rawName}.xls`;
421
+ const sheetName = options.sheetName || 'Report Data';
422
+ const brandedHeader = this.resolveBrandedHeader(options.brandedHeader);
423
+ const columns = options.columns && options.columns.length > 0
424
+ ? options.columns
425
+ : Object.keys(rows[0]).map((key) => ({
426
+ field: key,
427
+ header: key,
428
+ }));
429
+ const xmlContent = generateExcelXml(rows, columns, sheetName, brandedHeader);
430
+ const blob = new Blob([xmlContent], {
431
+ type: 'application/vnd.ms-excel;charset=utf-8;',
432
+ });
433
+ this.downloadBlob(blob, fileName);
434
+ }
435
+ /**
436
+ * Generates and triggers browser download of a styled, printable HTML report file.
437
+ */
438
+ exportHtml(rows, options = {}) {
439
+ if (!rows || rows.length === 0) {
440
+ console.warn('[bways-report] No rows to export to HTML');
441
+ return;
442
+ }
443
+ const fileName = options.fileName || `report-export-${Date.now()}.html`;
444
+ const title = options.title || 'Report Export';
445
+ const brandedHeader = this.resolveBrandedHeader(options.brandedHeader);
446
+ const columns = options.columns && options.columns.length > 0
447
+ ? options.columns
448
+ : Object.keys(rows[0]).map((key) => ({
449
+ field: key,
450
+ header: key,
451
+ }));
452
+ const htmlContent = generateHtmlContent(rows, columns, title, brandedHeader);
453
+ const blob = new Blob([htmlContent], { type: 'text/html;charset=utf-8;' });
454
+ this.downloadBlob(blob, fileName);
455
+ }
456
+ /**
457
+ * Opens a printable window with branded styling and optionally calls window.print().
458
+ */
459
+ printReport(rows, options = {}) {
460
+ if (!rows || rows.length === 0) {
461
+ console.warn('[bways-report] No rows to print');
462
+ return;
463
+ }
464
+ const title = options.title || 'Report Print Preview';
465
+ const brandedHeader = this.resolveBrandedHeader(options.brandedHeader);
466
+ const columns = options.columns && options.columns.length > 0
467
+ ? options.columns
468
+ : Object.keys(rows[0]).map((key) => ({
469
+ field: key,
470
+ header: key,
471
+ }));
472
+ const html = generateHtmlContent(rows, columns, title, brandedHeader);
473
+ const win = window.open('', '_blank', 'width=900,height=700');
474
+ if (win) {
475
+ win.document.open();
476
+ win.document.write(html);
477
+ win.document.close();
478
+ if (options.autoPrint !== false) {
479
+ win.focus();
480
+ setTimeout(() => win.print(), 250);
481
+ }
482
+ }
483
+ }
69
484
  /**
70
485
  * Generates and triggers browser download of a JSON file.
71
486
  */
@@ -101,7 +516,7 @@ export class ReportExportService {
101
516
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportExportService, decorators: [{
102
517
  type: Injectable,
103
518
  args: [{
104
- providedIn: 'root'
519
+ providedIn: 'root',
105
520
  }]
106
521
  }] });
107
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LWV4cG9ydC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYndheXMtcmVwb3J0L3NyYy9saWIvZmVhdHVyZXMvZXhwb3J0L3NlcnZpY2VzL3JlcG9ydC1leHBvcnQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7O0FBRzNDOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGVBQWUsQ0FBQyxLQUFjLEVBQUUsWUFBb0IsR0FBRztJQUNyRSxJQUFJLEtBQUssS0FBSyxJQUFJLElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQzFDLE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQztJQUVELElBQUksR0FBRyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUV4Qiw0RUFBNEU7SUFDNUUsTUFBTSxTQUFTLEdBQ2IsR0FBRyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUM7UUFDdkIsR0FBRyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUM7UUFDakIsR0FBRyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7UUFDbEIsR0FBRyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUVyQixJQUFJLFNBQVMsRUFBRSxDQUFDO1FBQ2QsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUM7SUFDNUMsQ0FBQztJQUVELE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGtCQUFrQixDQUNoQyxJQUErQixFQUMvQixPQUF1QixFQUN2QixZQUFvQixHQUFHLEVBQ3ZCLGdCQUF5QixJQUFJ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LENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUViLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDZCxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDckMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMzQixDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDVixDQUFDO3dHQWhFVSxtQkFBbUI7NEdBQW5CLG1CQUFtQixjQUZsQixNQUFNOzs0RkFFUCxtQkFBbUI7a0JBSC9CLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBET0NVTUVOVCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBDc3ZFeHBvcnRPcHRpb25zLCBFeHBvcnRDb2x1bW4sIEpzb25FeHBvcnRPcHRpb25zIH0gZnJvbSAnLi4vbW9kZWxzL2V4cG9ydC5tb2RlbHMnO1xuXG4vKipcbiAqIFNhbml0aXplcyBhbmQgZXNjYXBlcyBhIHNpbmdsZSBjZWxsIHZhbHVlIGZvciBDU1Ygb3V0cHV0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2FuaXRpemVDc3ZDZWxsKHZhbHVlOiB1bmtub3duLCBkZWxpbWl0ZXI6IHN0cmluZyA9ICcsJyk6IHN0cmluZyB7XG4gIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgbGV0IHN0ciA9IFN0cmluZyh2YWx1ZSk7XG5cbiAgLy8gSWYgdmFsdWUgY29udGFpbnMgZGVsaW1pdGVyLCBxdW90ZSwgb3IgbmV3bGluZSwgZXNjYXBlIGFuZCB3cmFwIGluIHF1b3Rlc1xuICBjb25zdCBtdXN0UXVvdGUgPVxuICAgIHN0ci5pbmNsdWRlcyhkZWxpbWl0ZXIpIHx8XG4gICAgc3RyLmluY2x1ZGVzKCdcIicpIHx8XG4gICAgc3RyLmluY2x1ZGVzKCdcXG4nKSB8fFxuICAgIHN0ci5pbmNsdWRlcygnXFxyJyk7XG5cbiAgaWYgKG11c3RRdW90ZSkge1xuICAgIHN0ciA9ICdcIicgKyBzdHIucmVwbGFjZSgvXCIvZywgJ1wiXCInKSArICdcIic7XG4gIH1cblxuICByZXR1cm4gc3RyO1xufVxuXG4vKipcbiAqIFB1cmUgZ2VuZXJhdG9yIGZ1bmN0aW9uIHRvIGNyZWF0ZSBDU1YgY29udGVudCBzdHJpbmcgZnJvbSByb3cgZGF0YSBhbmQgY29sdW1ucy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlQ3N2Q29udGVudChcbiAgcm93czogUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXSxcbiAgY29sdW1uczogRXhwb3J0Q29sdW1uW10sXG4gIGRlbGltaXRlcjogc3RyaW5nID0gJywnLFxuICBpbmNsdWRlSGVhZGVyOiBib29sZWFuID0gdHJ1ZSxcbiAgYWRkQm9tOiBib29sZWFuID0gdHJ1ZVxuKTogc3RyaW5nIHtcbiAgY29uc3QgbGluZXM6IHN0cmluZ1tdID0gW107XG5cbiAgaWYgKGluY2x1ZGVIZWFkZXIpIHtcbiAgICBjb25zdCBoZWFkZXJMaW5lID0gY29sdW1uc1xuICAgICAgLm1hcCgoY29sKSA9PiBzYW5pdGl6ZUNzdkNlbGwoY29sLmhlYWRlciwgZGVsaW1pdGVyKSlcbiAgICAgIC5qb2luKGRlbGltaXRlcik7XG4gICAgbGluZXMucHVzaChoZWFkZXJMaW5lKTtcbiAgfVxuXG4gIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICBjb25zdCByb3dWYWx1ZXMgPSBjb2x1bW5zLm1hcCgoY29sKSA9PiB7XG4gICAgICBjb25zdCB2YWwgPSByb3dbY29sLmZpZWxkXTtcbiAgICAgIGNvbnN0IGZvcm1hdHRlZCA9IGNvbC5mb3JtYXR0ZXIgPyBjb2wuZm9ybWF0dGVyKHZhbCwgcm93KSA6IHZhbDtcbiAgICAgIHJldHVybiBzYW5pdGl6ZUNzdkNlbGwoZm9ybWF0dGVkLCBkZWxpbWl0ZXIpO1xuICAgIH0pO1xuICAgIGxpbmVzLnB1c2gocm93VmFsdWVzLmpvaW4oZGVsaW1pdGVyKSk7XG4gIH1cblxuICBjb25zdCBjc3ZCb2R5ID0gbGluZXMuam9pbignXFxyXFxuJyk7XG4gIHJldHVybiBhZGRCb20gPyAnXFx1RkVGRicgKyBjc3ZCb2R5IDogY3N2Qm9keTtcbn1cblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgUmVwb3J0RXhwb3J0U2VydmljZSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgZG9jdW1lbnQgPSBpbmplY3QoRE9DVU1FTlQpO1xuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgYW5kIHRyaWdnZXJzIGJyb3dzZXIgZG93bmxvYWQgb2YgYSBDU1YgZmlsZS5cbiAgICovXG4gIGV4cG9ydENzdihyb3dzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdLCBvcHRpb25zOiBDc3ZFeHBvcnRPcHRpb25zID0ge30pOiB2b2lkIHtcbiAgICBpZiAoIXJvd3MgfHwgcm93cy5sZW5ndGggPT09IDApIHtcbiAgICAgIGNvbnNvbGUud2FybignW2J3YXlzLXJlcG9ydF0gTm8gcm93cyB0byBleHBvcnQnKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBkZWxpbWl0ZXIgPSBvcHRpb25zLmRlbGltaXRlciA/PyAnLCc7XG4gICAgY29uc3QgaW5jbHVkZUhlYWRlciA9IG9wdGlvbnMuaW5jbHVkZUhlYWRlciAhPT0gZmFsc2U7XG4gICAgY29uc3QgYWRkQm9tID0gb3B0aW9ucy5hZGRCb20gIT09IGZhbHNlO1xuICAgIGNvbnN0IGZpbGVOYW1lID0gb3B0aW9ucy5maWxlTmFtZSB8fCBgcmVwb3J0LWV4cG9ydC0ke0RhdGUubm93KCl9LmNzdmA7XG5cbiAgICAvLyBJZiBjb2x1bW5zIG5vdCBwcm92aWRlZCwgaW5mZXIgZnJvbSBmaXJzdCByb3cga2V5c1xuICAgIGNvbnN0IGNvbHVtbnM6IEV4cG9ydENvbHVtbltdID1cbiAgICAgIG9wdGlvbnMuY29sdW1ucyAmJiBvcHRpb25zLmNvbHVtbnMubGVuZ3RoID4gMFxuICAgICAgICA/IG9wdGlvbnMuY29sdW1uc1xuICAgICAgICA6IE9iamVjdC5rZXlzKHJvd3NbMF0pLm1hcCgoa2V5KSA9PiAoe1xuICAgICAgICAgICAgZmllbGQ6IGtleSxcbiAgICAgICAgICAgIGhlYWRlcjoga2V5XG4gICAgICAgICAgfSkpO1xuXG4gICAgY29uc3QgY3N2Q29udGVudCA9IGdlbmVyYXRlQ3N2Q29udGVudChyb3dzLCBjb2x1bW5zLCBkZWxpbWl0ZXIsIGluY2x1ZGVIZWFkZXIsIGFkZEJvbSk7XG4gICAgY29uc3QgYmxvYiA9IG5ldyBCbG9iKFtjc3ZDb250ZW50XSwgeyB0eXBlOiAndGV4dC9jc3Y7Y2hhcnNldD11dGYtODsnIH0pO1xuICAgIHRoaXMuZG93bmxvYWRCbG9iKGJsb2IsIGZpbGVOYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgYW5kIHRyaWdnZXJzIGJyb3dzZXIgZG93bmxvYWQgb2YgYSBKU09OIGZpbGUuXG4gICAqL1xuICBleHBvcnRKc29uKGRhdGE6IHVua25vd24sIG9wdGlvbnM6IEpzb25FeHBvcnRPcHRpb25zID0ge30pOiB2b2lkIHtcbiAgICBjb25zdCBmaWxlTmFtZSA9IG9wdGlvbnMuZmlsZU5hbWUgfHwgYHJlcG9ydC1leHBvcnQtJHtEYXRlLm5vdygpfS5qc29uYDtcbiAgICBjb25zdCBwcmV0dHkgPSBvcHRpb25zLnByZXR0eSAhPT0gZmFsc2U7XG4gICAgY29uc3QganNvblN0cmluZyA9IHByZXR0eSA/IEpTT04uc3RyaW5naWZ5KGRhdGEsIG51bGwsIDIpIDogSlNPTi5zdHJpbmdpZnkoZGF0YSk7XG5cbiAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoW2pzb25TdHJpbmddLCB7IHR5cGU6ICdhcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7JyB9KTtcbiAgICB0aGlzLmRvd25sb2FkQmxvYihibG9iLCBmaWxlTmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogU2FmZSBmaWxlIGRvd25sb2FkIHRyaWdnZXIgdmlhIHRlbXBvcmFyeSBhbmNob3IgdGFnLlxuICAgKi9cbiAgcHJpdmF0ZSBkb3dubG9hZEJsb2IoYmxvYjogQmxvYiwgZmlsZU5hbWU6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghdGhpcy5kb2N1bWVudCB8fCAhdGhpcy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgdXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcbiAgICBjb25zdCBsaW5rID0gdGhpcy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XG4gICAgbGluay5ocmVmID0gdXJsO1xuICAgIGxpbmsuZG93bmxvYWQgPSBmaWxlTmFtZTtcbiAgICBsaW5rLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG5cbiAgICB0aGlzLmRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQobGluayk7XG4gICAgbGluay5jbGljaygpO1xuXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQobGluayk7XG4gICAgICBVUkwucmV2b2tlT2JqZWN0VVJMKHVybCk7XG4gICAgfSwgMTAwKTtcbiAgfVxufVxuIl19
522
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LWV4cG9ydC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYndheXMtcmVwb3J0L3NyYy9saWIvZmVhdHVyZXMvZXhwb3J0L3NlcnZpY2VzL3JlcG9ydC1leHBvcnQuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFTM0MsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sdURBQXVELENBQUM7O0FBRXBHOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGVBQWUsQ0FBQyxLQUFjLEVBQUUsWUFBb0IsR0FBRztJQUNyRSxJQUFJLEtBQUssS0FBSyxJQUFJLElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQzFDLE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQztJQUVELElBQUksR0FBRyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUV4Qiw0RUFBNEU7SUFDNUUsTUFBTSxTQUFTLEdBQ2IsR0FBRyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUM7UUFDdkIsR0FBRyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUM7UUFDakIsR0FBRyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUM7UUFDbEIsR0FBRyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUVyQixJQUFJLFNBQVMsRUFBRSxDQUFDO1FBQ2QsR0FBRyxHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUM7SUFDNUMsQ0FBQztJQUVELE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLG1CQUFtQixDQUFDLE9BQTBDO0lBQzVFLElBQUksQ0FBQyxPQUFPO1FBQUUsT0FBTyxFQUFFLENBQUM7SUFDeEIsSUFBSSxPQUFPLE9BQU8sS0FBSyxRQUFRO1FBQUUsT0FBTyxPQUFPLENBQUM7SUFFaEQsT0FBTyxNQUFNLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQztTQUMzQixNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLFNBQVMsSUFBSSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7U0FDN0QsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRTtRQUNkLElBQUksT0FBTyxDQUFDLEtBQUssUUFBUSxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksTUFBTSxJQUFJLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDcEUsT0FBTyxHQUFHLENBQUMsS0FBTSxDQUFTLENBQUMsSUFBSSxPQUFRLENBQVMsQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUN4RCxDQUFDO1FBQ0QsT0FBTyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztJQUN0QixDQUFDLENBQUM7U0FDRCxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDakIsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLGtCQUFrQixDQUNoQyxJQUErQixFQUMvQixPQUF1QixFQUN2QixZQUFvQixHQUFHLEVBQ3ZCLGdCQUF5QixJQUFJLEVBQzdCLFNBQWtCLElBQUksRUFDdEIsYUFBb0M7SUFFcEMsTUFBTSxLQUFLLEdBQWEsRUFBRSxDQUFDO0lBRTNCLElBQUksYUFBYSxFQUFFLENBQUM7UUFDbEIsSUFBSSxhQUFhLENBQUMsV0FBVyxJQUFJLGFBQWEsQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUMxRCxLQUFLLENBQUMsSUFBSSxDQUNSLGNBQWMsYUFBYSxDQUFDLFdBQVcsSUFBSSxFQUFFLEdBQzNDLGFBQWEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLGNBQWMsYUFBYSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUN4RSxFQUFFLENBQ0gsQ0FBQztRQUNKLENBQUM7UUFDRCxJQUFJLGFBQWEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUM5QixLQUFLLENBQUMsSUFBSSxDQUFDLGFBQWEsYUFBYSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7UUFDdkQsQ0FBQztRQUNELE1BQU0sT0FBTyxHQUFhLEVBQUUsQ0FBQztRQUM3QixJQUFJLGFBQWEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUM5QixNQUFNLEVBQUUsR0FDTixhQUFhLENBQUMsV0FBVyxZQUFZLElBQUk7Z0JBQ3ZDLENBQUMsQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLFdBQVcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUM7Z0JBQ3hFLENBQUMsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1lBQ3hDLE9BQU8sQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ25DLENBQUM7UUFDRCxJQUFJLGFBQWEsQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUM5QixPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsYUFBYSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7UUFDckQsQ0FBQztRQUNELElBQUksT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN2QixLQUFLLENBQUMsSUFBSSxDQUFDLEtBQUssT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDekMsQ0FBQztRQUNELE1BQU0sVUFBVSxHQUFHLG1CQUFtQixDQUFDLGFBQWEsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBQzFFLElBQUksVUFBVSxFQUFFLENBQUM7WUFDZixLQUFLLENBQUMsSUFBSSxDQUFDLHFCQUFxQixVQUFVLEVBQUUsQ0FBQyxDQUFDO1FBQ2hELENBQUM7UUFDRCxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDcEMsQ0FBQztJQUVELElBQUksYUFBYSxFQUFFLENBQUM7UUFDbEIsTUFBTSxVQUFVLEdBQUcsT0FBTzthQUN2QixHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQyxDQUFDO2FBQ3BELElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNuQixLQUFLLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3pCLENBQUM7SUFFRCxLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ3ZCLE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtZQUNwQyxNQUFNLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQzNCLE1BQU0sU0FBUyxHQUFHLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUM7WUFDaEUsT0FBTyxlQUFlLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQy9DLENBQUMsQ0FBQyxDQUFDO1FBQ0gsS0FBSyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7SUFDeEMsQ0FBQztJQUVELE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDbkMsT0FBTyxNQUFNLENBQUMsQ0FBQyxDQUFDLFFBQVEsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQztBQUMvQyxDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLFVBQVUsZ0JBQWdCLENBQzlCLElBQStCLEVBQy9CLE9BQXVCLEVBQ3ZCLFlBQW9CLGFBQWEsRUFDakMsYUFBb0M7SUFFcEMsTUFBTSxTQUFTLEdBQUcsQ0FBQyxHQUFZLEVBQVUsRUFBRTtRQUN6QyxJQUFJLEdBQUcsS0FBSyxJQUFJLElBQUksR0FBRyxLQUFLLFNBQVM7WUFBRSxPQUFPLEVBQUUsQ0FBQztRQUNqRCxPQUFPLE1BQU0sQ0FBQyxHQUFHLENBQUM7YUFDZixPQUFPLENBQUMsSUFBSSxFQUFFLE9BQU8sQ0FBQzthQUN0QixPQUFPLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQzthQUNyQixPQUFPLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQzthQUNyQixPQUFPLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQzthQUN2QixPQUFPLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQzdCLENBQUMsQ0FBQztJQUVGLE1BQU0sT0FBTyxHQUFhLEVBQUUsQ0FBQztJQUU3QixJQUFJLGFBQWEsRUFBRSxDQUFDO1FBQ2xCLElBQUksYUFBYSxDQUFDLFdBQVcsSUFBSSxhQUFhLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDM0QsTUFBTSxLQUFLLEdBQUcsQ0FBQyxhQUFhLENBQUMsV0FBVyxFQUFFLGFBQWEsQ0FBQyxXQUFXLENBQUM7aUJBQ2pFLE1BQU0sQ0FBQyxPQUFPLENBQUM7aUJBQ2YsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2YsT0FBTyxDQUFDLElBQUksQ0FBQzs7d0RBRXFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO21DQUNwRCxTQUFTLENBQUMsS0FBSyxDQUFDOzthQUV0QyxDQUFDLENBQUM7UUFDWCxDQUFDO1FBRUQsTUFBTSxTQUFTLEdBQWEsRUFBRSxDQUFDO1FBQy9CLElBQUksYUFBYSxDQUFDLFVBQVU7WUFBRSxTQUFTLENBQUMsSUFBSSxDQUFDLFdBQVcsYUFBYSxDQUFDLFVBQVUsRUFBRSxDQUFDLENBQUM7UUFDcEYsSUFBSSxhQUFhLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDOUIsTUFBTSxFQUFFLEdBQ04sYUFBYSxDQUFDLFdBQVcsWUFBWSxJQUFJO2dCQUN2QyxDQUFDLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDO2dCQUN4RSxDQUFDLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUN4QyxTQUFTLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNoQyxDQUFDO1FBQ0QsSUFBSSxhQUFhLENBQUMsV0FBVztZQUFFLFNBQVMsQ0FBQyxJQUFJLENBQUMsU0FBUyxhQUFhLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztRQUVwRixJQUFJLFNBQVMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDekIsT0FBTyxDQUFDLElBQUksQ0FBQzs7MkRBRXdDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO21DQUN2RCxTQUFTLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQzs7YUFFdEQsQ0FBQyxDQUFDO1FBQ1gsQ0FBQztRQUVELE1BQU0sVUFBVSxHQUFHLG1CQUFtQixDQUFDLGFBQWEsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1FBQzFFLElBQUksVUFBVSxFQUFFLENBQUM7WUFDZixPQUFPLENBQUMsSUFBSSxDQUFDOzt5REFFc0MsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7bUNBQ3JELFNBQVMsQ0FBQyxZQUFZLFVBQVUsRUFBRSxDQUFDOzthQUV6RCxDQUFDLENBQUM7UUFDWCxDQUFDO1FBRUQsc0JBQXNCO1FBQ3RCLE9BQU8sQ0FBQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBRUQsaUJBQWlCO0lBQ2pCLE1BQU0sV0FBVyxHQUFHLE9BQU87U0FDeEIsR0FBRyxDQUNGLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQztnRUFDaUQsU0FBUyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQ2hHO1NBQ0EsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ1osT0FBTyxDQUFDLElBQUksQ0FBQyx1QkFBdUIsV0FBVyxnQkFBZ0IsQ0FBQyxDQUFDO0lBRWpFLFlBQVk7SUFDWixJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFO1FBQ3hCLE1BQU0sTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQzdCLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUM7UUFDdEQsTUFBTSxLQUFLLEdBQUcsT0FBTzthQUNsQixHQUFHLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtZQUNYLE1BQU0sR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDM0IsTUFBTSxTQUFTLEdBQUcsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQztZQUNoRSxNQUFNLEtBQUssR0FBRyxPQUFPLFNBQVMsS0FBSyxRQUFRLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDakUsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQztZQUN6QyxPQUFPLHFCQUFxQixPQUFPLG9CQUFvQixJQUFJLEtBQUssU0FBUyxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQztRQUN2RyxDQUFDLENBQUM7YUFDRCxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDWixPQUFPLENBQUMsSUFBSSxDQUFDLDZCQUE2QixLQUFLLFFBQVEsQ0FBQyxDQUFDO0lBQzNELENBQUMsQ0FBQyxDQUFDO0lBRUgsT0FBTzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O3VCQTZDYyxTQUFTLENBQUMsU0FBUyxDQUFDOztFQUV6QyxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDLGlEQUFpRCxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztFQUMvRSxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQzs7O1lBR1IsQ0FBQztBQUNiLENBQUM7QUFFRDs7R0FFRztBQUNILE1BQU0sVUFBVSxtQkFBbUIsQ0FDakMsSUFBK0IsRUFDL0IsT0FBdUIsRUFDdkIsUUFBZ0IsZUFBZSxFQUMvQixhQUFvQztJQUVwQyxNQUFNLFVBQVUsR0FBRyxDQUFDLEdBQVksRUFBVSxFQUFFO1FBQzFDLElBQUksR0FBRyxLQUFLLElBQUksSUFBSSxHQUFHLEtBQUssU0FBUztZQUFFLE9BQU8sRUFBRSxDQUFDO1FBQ2pELE9BQU8sTUFBTSxDQUFDLEdBQUcsQ0FBQzthQUNmLE9BQU8sQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDO2FBQ3RCLE9BQU8sQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDO2FBQ3JCLE9BQU8sQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDM0IsQ0FBQyxDQUFDO0lBRUYsTUFBTSxVQUFVLEdBQUcsYUFBYTtRQUM5QixDQUFDLENBQUM7OztVQUlJLGFBQWEsQ0FBQyxXQUFXO1lBQ3ZCLENBQUMsQ0FBQyxpQ0FBaUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUMsT0FBTztZQUMvRSxDQUFDLENBQUMsRUFDTjt1Q0FDK0IsVUFBVSxDQUFDLGFBQWEsQ0FBQyxXQUFXLElBQUksS0FBSyxDQUFDOztZQUV6RSxhQUFhLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxrQ0FBa0MsVUFBVSxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBRS9HLGFBQWEsQ0FBQyxXQUFXO1lBQ3ZCLENBQUMsQ0FBQyxnQ0FBZ0MsVUFBVSxDQUN4QyxhQUFhLENBQUMsV0FBVyxZQUFZLElBQUk7Z0JBQ3ZDLENBQUMsQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLGNBQWMsRUFBRTtnQkFDNUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQzlCLFNBQVM7WUFDWixDQUFDLENBQUMsRUFDTjtZQUNFLGFBQWEsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLGdDQUFnQyxVQUFVLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUU7OztRQUluSCxhQUFhLENBQUMsbUJBQW1CO1lBQy9CLENBQUMsQ0FBQyxnRUFBZ0UsVUFBVSxDQUN4RSxtQkFBbUIsQ0FBQyxhQUFhLENBQUMsbUJBQW1CLENBQUMsQ0FDdkQsUUFBUTtZQUNYLENBQUMsQ0FBQyxFQUNOOztHQUVIO1FBQ0MsQ0FBQyxDQUFDLGdDQUFnQyxVQUFVLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQztJQUU3RCxNQUFNLFFBQVEsR0FBRyxJQUFJO1NBQ2xCLEdBQUcsQ0FDRixDQUFDLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDO2lCQUNELEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEtBQUs7UUFDdkMsT0FBTztTQUNOLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO1FBQ1gsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN6QixNQUFNLFNBQVMsR0FBRyxHQUFHLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO1FBQzlELE9BQU8sT0FBTyxVQUFVLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQztJQUM3QyxDQUFDLENBQUM7U0FDRCxJQUFJLENBQUMsRUFBRSxDQUFDO1VBQ1AsQ0FDTDtTQUNBLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUVaLE9BQU87Ozs7V0FJRSxVQUFVLENBQUMsS0FBSyxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQXVFeEIsVUFBVTs7OztVQUlKLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLE9BQU8sVUFBVSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQzs7OztRQUlqRSxRQUFROzs7O1FBSVIsQ0FBQztBQUNULENBQUM7QUFLRCxNQUFNLE9BQU8sbUJBQW1CO0lBQ2IsUUFBUSxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUM1QixjQUFjLEdBQUcsTUFBTSxDQUFDLDJCQUEyQixFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFFMUY7O09BRUc7SUFDSyxvQkFBb0IsQ0FBQyxNQUE2QjtRQUN4RCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsY0FBYyxFQUFFLGNBQWMsRUFBRSxJQUFJLEVBQUUsQ0FBQztRQUM1RCxJQUFJLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ2pELE9BQU8sU0FBUyxDQUFDO1FBQ25CLENBQUM7UUFFRCxPQUFPO1lBQ0wsV0FBVyxFQUNULE1BQU0sRUFBRSxXQUFXO2dCQUNsQixPQUFPLENBQUMsYUFBYSxDQUFZO2dCQUNqQyxPQUFPLENBQUMsWUFBWSxDQUFZO2dCQUNoQyxPQUFPLENBQUMsU0FBUyxDQUFZO1lBQ2hDLFVBQVUsRUFDUixNQUFNLEVBQUUsVUFBVTtnQkFDakIsT0FBTyxDQUFDLFlBQVksQ0FBWTtnQkFDaEMsT0FBTyxDQUFDLFlBQVksQ0FBWTtZQUNuQyxXQUFXLEVBQUUsTUFBTSxFQUFFLFdBQVc7WUFDaEMsV0FBVyxFQUFFLE1BQU0sRUFBRSxXQUFXLElBQUksSUFBSSxJQUFJLEVBQUU7WUFDOUMsV0FBVyxFQUNULE1BQU0sRUFBRSxXQUFXO2dCQUNsQixPQUFPLENBQUMsVUFBVSxDQUFZO2dCQUM5QixPQUFPLENBQUMsUUFBUSxDQUFZO1lBQy9CLG1CQUFtQixFQUFFLE1BQU0sRUFBRSxtQkFBbUI7U0FDakQsQ0FBQztJQUNKLENBQUM7SUFFRDs7T0FFRztJQUNILFNBQVMsQ0FBQyxJQUErQixFQUFFLFVBQTRCLEVBQUU7UUFDdkUsSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQy9CLE9BQU8sQ0FBQyxJQUFJLENBQUMsa0NBQWtDLENBQUMsQ0FBQztZQUNqRCxPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxTQUFTLElBQUksR0FBRyxDQUFDO1FBQzNDLE1BQU0sYUFBYSxHQUFHLE9BQU8sQ0FBQyxhQUFhLEtBQUssS0FBSyxDQUFDO1FBQ3RELE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLEtBQUssS0FBSyxDQUFDO1FBQ3hDLE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxRQUFRLElBQUksaUJBQWlCLElBQUksQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDO1FBQ3ZFLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQUM7UUFFdkUscURBQXFEO1FBQ3JELE1BQU0sT0FBTyxHQUNYLE9BQU8sQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQztZQUMzQyxDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU87WUFDakIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUNqQyxLQUFLLEVBQUUsR0FBRztnQkFDVixNQUFNLEVBQUUsR0FBRzthQUNaLENBQUMsQ0FBQyxDQUFDO1FBRVYsTUFBTSxVQUFVLEdBQUcsa0JBQWtCLENBQ25DLElBQUksRUFDSixPQUFPLEVBQ1AsU0FBUyxFQUNULGFBQWEsRUFDYixNQUFNLEVBQ04sYUFBYSxDQUNkLENBQUM7UUFDRixNQUFNLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxDQUFDLFVBQVUsQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLHlCQUF5QixFQUFFLENBQUMsQ0FBQztRQUN6RSxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxXQUFXLENBQUMsSUFBK0IsRUFBRSxVQUE4QixFQUFFO1FBQzNFLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMvQixPQUFPLENBQUMsSUFBSSxDQUFDLDJDQUEyQyxDQUFDLENBQUM7WUFDMUQsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLE9BQU8sR0FBRyxPQUFPLENBQUMsUUFBUSxJQUFJLGlCQUFpQixJQUFJLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQztRQUNsRSxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDO1lBQ3BFLENBQUMsQ0FBQyxPQUFPO1lBQ1QsQ0FBQyxDQUFDLEdBQUcsT0FBTyxNQUFNLENBQUM7UUFDckIsTUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFDLFNBQVMsSUFBSSxhQUFhLENBQUM7UUFDckQsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUV2RSxNQUFNLE9BQU8sR0FDWCxPQUFPLENBQUMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUM7WUFDM0MsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxPQUFPO1lBQ2pCLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDakMsS0FBSyxFQUFFLEdBQUc7Z0JBQ1YsTUFBTSxFQUFFLEdBQUc7YUFDWixDQUFDLENBQUMsQ0FBQztRQUVWLE1BQU0sVUFBVSxHQUFHLGdCQUFnQixDQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLGFBQWEsQ0FBQyxDQUFDO1FBQzdFLE1BQU0sSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLENBQUMsVUFBVSxDQUFDLEVBQUU7WUFDbEMsSUFBSSxFQUFFLHlDQUF5QztTQUNoRCxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxVQUFVLENBQUMsSUFBK0IsRUFBRSxVQUE2QixFQUFFO1FBQ3pFLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMvQixPQUFPLENBQUMsSUFBSSxDQUFDLDBDQUEwQyxDQUFDLENBQUM7WUFDekQsT0FBTztRQUNULENBQUM7UUFFRCxNQUFNLFFBQVEsR0FBRyxPQUFPLENBQUMsUUFBUSxJQUFJLGlCQUFpQixJQUFJLENBQUMsR0FBRyxFQUFFLE9BQU8sQ0FBQztRQUN4RSxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsS0FBSyxJQUFJLGVBQWUsQ0FBQztRQUMvQyxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBRXZFLE1BQU0sT0FBTyxHQUNYLE9BQU8sQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQztZQUMzQyxDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU87WUFDakIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUNqQyxLQUFLLEVBQUUsR0FBRztnQkFDVixNQUFNLEVBQUUsR0FBRzthQUNaLENBQUMsQ0FBQyxDQUFDO1FBRVYsTUFBTSxXQUFXLEdBQUcsbUJBQW1CLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsYUFBYSxDQUFDLENBQUM7UUFDN0UsTUFBTSxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsQ0FBQyxXQUFXLENBQUMsRUFBRSxFQUFFLElBQUksRUFBRSwwQkFBMEIsRUFBRSxDQUFDLENBQUM7UUFDM0UsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDcEMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsV0FBVyxDQUFDLElBQStCLEVBQUUsVUFBNkIsRUFBRTtRQUMxRSxJQUFJLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDL0IsT0FBTyxDQUFDLElBQUksQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO1lBQ2hELE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLEtBQUssSUFBSSxzQkFBc0IsQ0FBQztRQUN0RCxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQ3ZFLE1BQU0sT0FBTyxHQUNYLE9BQU8sQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQztZQUMzQyxDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU87WUFDakIsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUNqQyxLQUFLLEVBQUUsR0FBRztnQkFDVixNQUFNLEVBQUUsR0FBRzthQUNaLENBQUMsQ0FBQyxDQUFDO1FBRVYsTUFBTSxJQUFJLEdBQUcsbUJBQW1CLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsYUFBYSxDQUFDLENBQUM7UUFDdEUsTUFBTSxHQUFHLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsUUFBUSxFQUFFLHNCQUFzQixDQUFDLENBQUM7UUFDOUQsSUFBSSxHQUFHLEVBQUUsQ0FBQztZQUNSLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDcEIsR0FBRyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDekIsR0FBRyxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNyQixJQUFJLE9BQU8sQ0FBQyxTQUFTLEtBQUssS0FBSyxFQUFFLENBQUM7Z0JBQ2hDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDWixVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQ3JDLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUVEOztPQUVHO0lBQ0gsVUFBVSxDQUFDLElBQWEsRUFBRSxVQUE2QixFQUFFO1FBQ3ZELE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxRQUFRLElBQUksaUJBQWlCLElBQUksQ0FBQyxHQUFHLEVBQUUsT0FBTyxDQUFDO1FBQ3hFLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLEtBQUssS0FBSyxDQUFDO1FBQ3hDLE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBRWpGLE1BQU0sSUFBSSxHQUFHLElBQUksSUFBSSxDQUFDLENBQUMsVUFBVSxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsaUNBQWlDLEVBQUUsQ0FBQyxDQUFDO1FBQ2pGLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFRDs7T0FFRztJQUNLLFlBQVksQ0FBQyxJQUFVLEVBQUUsUUFBZ0I7UUFDL0MsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ25ELE9BQU87UUFDVCxDQUFDO1FBRUQsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN0QyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUM5QyxJQUFJLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQztRQUNoQixJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQztRQUN6QixJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUM7UUFFNUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUViLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDZCxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDckMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMzQixDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDVixDQUFDO3dHQS9MVSxtQkFBbUI7NEdBQW5CLG1CQUFtQixjQUZsQixNQUFNOzs0RkFFUCxtQkFBbUI7a0JBSC9CLFVBQVU7bUJBQUM7b0JBQ1YsVUFBVSxFQUFFLE1BQU07aUJBQ25CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBET0NVTUVOVCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge1xuICBCcmFuZGVkSGVhZGVyT3B0aW9ucyxcbiAgQ3N2RXhwb3J0T3B0aW9ucyxcbiAgRXhjZWxFeHBvcnRPcHRpb25zLFxuICBFeHBvcnRDb2x1bW4sXG4gIEh0bWxFeHBvcnRPcHRpb25zLFxuICBKc29uRXhwb3J0T3B0aW9ucyxcbn0gZnJvbSAnLi4vbW9kZWxzL2V4cG9ydC5tb2RlbHMnO1xuaW1wb3J0IHsgUmVwb3J0U2Vzc2lvbkNvbnRleHRTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vY29yZS9zZXJ2aWNlcy9yZXBvcnQtc2Vzc2lvbi1jb250ZXh0LnNlcnZpY2UnO1xuXG4vKipcbiAqIFNhbml0aXplcyBhbmQgZXNjYXBlcyBhIHNpbmdsZSBjZWxsIHZhbHVlIGZvciBDU1Ygb3V0cHV0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2FuaXRpemVDc3ZDZWxsKHZhbHVlOiB1bmtub3duLCBkZWxpbWl0ZXI6IHN0cmluZyA9ICcsJyk6IHN0cmluZyB7XG4gIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgbGV0IHN0ciA9IFN0cmluZyh2YWx1ZSk7XG5cbiAgLy8gSWYgdmFsdWUgY29udGFpbnMgZGVsaW1pdGVyLCBxdW90ZSwgb3IgbmV3bGluZSwgZXNjYXBlIGFuZCB3cmFwIGluIHF1b3Rlc1xuICBjb25zdCBtdXN0UXVvdGUgPVxuICAgIHN0ci5pbmNsdWRlcyhkZWxpbWl0ZXIpIHx8XG4gICAgc3RyLmluY2x1ZGVzKCdcIicpIHx8XG4gICAgc3RyLmluY2x1ZGVzKCdcXG4nKSB8fFxuICAgIHN0ci5pbmNsdWRlcygnXFxyJyk7XG5cbiAgaWYgKG11c3RRdW90ZSkge1xuICAgIHN0ciA9ICdcIicgKyBzdHIucmVwbGFjZSgvXCIvZywgJ1wiXCInKSArICdcIic7XG4gIH1cblxuICByZXR1cm4gc3RyO1xufVxuXG4vKipcbiAqIEZvcm1hdHMgYSByZWNvcmQgb3Igc3RyaW5nIG9mIGFjdGl2ZSBmaWx0ZXIgY3JpdGVyaWEgaW50byBhIGNsZWFuIHRleHQgbGluZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZvcm1hdEZpbHRlclN1bW1hcnkoc3VtbWFyeT86IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgc3RyaW5nKTogc3RyaW5nIHtcbiAgaWYgKCFzdW1tYXJ5KSByZXR1cm4gJyc7XG4gIGlmICh0eXBlb2Ygc3VtbWFyeSA9PT0gJ3N0cmluZycpIHJldHVybiBzdW1tYXJ5O1xuXG4gIHJldHVybiBPYmplY3QuZW50cmllcyhzdW1tYXJ5KVxuICAgIC5maWx0ZXIoKFtfLCB2XSkgPT4gdiAhPT0gdW5kZWZpbmVkICYmIHYgIT09IG51bGwgJiYgdiAhPT0gJycpXG4gICAgLm1hcCgoW2ssIHZdKSA9PiB7XG4gICAgICBpZiAodHlwZW9mIHYgPT09ICdvYmplY3QnICYmIHYgIT09IG51bGwgJiYgJ2Zyb20nIGluIHYgJiYgJ3RvJyBpbiB2KSB7XG4gICAgICAgIHJldHVybiBgJHtrfTogJHsodiBhcyBhbnkpLmZyb219IHRvICR7KHYgYXMgYW55KS50b31gO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGAke2t9OiAke3Z9YDtcbiAgICB9KVxuICAgIC5qb2luKCcgfCAnKTtcbn1cblxuLyoqXG4gKiBQdXJlIGdlbmVyYXRvciBmdW5jdGlvbiB0byBjcmVhdGUgQ1NWIGNvbnRlbnQgc3RyaW5nIGZyb20gcm93IGRhdGEgYW5kIGNvbHVtbnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZUNzdkNvbnRlbnQoXG4gIHJvd3M6IFJlY29yZDxzdHJpbmcsIHVua25vd24+W10sXG4gIGNvbHVtbnM6IEV4cG9ydENvbHVtbltdLFxuICBkZWxpbWl0ZXI6IHN0cmluZyA9ICcsJyxcbiAgaW5jbHVkZUhlYWRlcjogYm9vbGVhbiA9IHRydWUsXG4gIGFkZEJvbTogYm9vbGVhbiA9IHRydWUsXG4gIGJyYW5kZWRIZWFkZXI/OiBCcmFuZGVkSGVhZGVyT3B0aW9uc1xuKTogc3RyaW5nIHtcbiAgY29uc3QgbGluZXM6IHN0cmluZ1tdID0gW107XG5cbiAgaWYgKGJyYW5kZWRIZWFkZXIpIHtcbiAgICBpZiAoYnJhbmRlZEhlYWRlci5jb21wYW55TmFtZSB8fCBicmFuZGVkSGVhZGVyLmJyYW5jaE5hbWUpIHtcbiAgICAgIGxpbmVzLnB1c2goXG4gICAgICAgIGAjIENvbXBhbnk6ICR7YnJhbmRlZEhlYWRlci5jb21wYW55TmFtZSA/PyAnJ30ke1xuICAgICAgICAgIGJyYW5kZWRIZWFkZXIuYnJhbmNoTmFtZSA/IGAgfCBCcmFuY2g6ICR7YnJhbmRlZEhlYWRlci5icmFuY2hOYW1lfWAgOiAnJ1xuICAgICAgICB9YFxuICAgICAgKTtcbiAgICB9XG4gICAgaWYgKGJyYW5kZWRIZWFkZXIucmVwb3J0VGl0bGUpIHtcbiAgICAgIGxpbmVzLnB1c2goYCMgUmVwb3J0OiAke2JyYW5kZWRIZWFkZXIucmVwb3J0VGl0bGV9YCk7XG4gICAgfVxuICAgIGNvbnN0IGdlbkluZm86IHN0cmluZ1tdID0gW107XG4gICAgaWYgKGJyYW5kZWRIZWFkZXIuZ2VuZXJhdGVkQXQpIHtcbiAgICAgIGNvbnN0IGR0ID1cbiAgICAgICAgYnJhbmRlZEhlYWRlci5nZW5lcmF0ZWRBdCBpbnN0YW5jZW9mIERhdGVcbiAgICAgICAgICA/IGJyYW5kZWRIZWFkZXIuZ2VuZXJhdGVkQXQudG9JU09TdHJpbmcoKS5yZXBsYWNlKCdUJywgJyAnKS5zbGljZSgwLCAxOSlcbiAgICAgICAgICA6IFN0cmluZyhicmFuZGVkSGVhZGVyLmdlbmVyYXRlZEF0KTtcbiAgICAgIGdlbkluZm8ucHVzaChgR2VuZXJhdGVkOiAke2R0fWApO1xuICAgIH1cbiAgICBpZiAoYnJhbmRlZEhlYWRlci5nZW5lcmF0ZWRCeSkge1xuICAgICAgZ2VuSW5mby5wdXNoKGBVc2VyOiAke2JyYW5kZWRIZWFkZXIuZ2VuZXJhdGVkQnl9YCk7XG4gICAgfVxuICAgIGlmIChnZW5JbmZvLmxlbmd0aCA+IDApIHtcbiAgICAgIGxpbmVzLnB1c2goYCMgJHtnZW5JbmZvLmpvaW4oJyB8ICcpfWApO1xuICAgIH1cbiAgICBjb25zdCBmaWx0ZXJUZXh0ID0gZm9ybWF0RmlsdGVyU3VtbWFyeShicmFuZGVkSGVhZGVyLmFjdGl2ZUZpbHRlclN1bW1hcnkpO1xuICAgIGlmIChmaWx0ZXJUZXh0KSB7XG4gICAgICBsaW5lcy5wdXNoKGAjIEFjdGl2ZSBGaWx0ZXJzOiAke2ZpbHRlclRleHR9YCk7XG4gICAgfVxuICAgIGxpbmVzLnB1c2goJyMgJyArICctJy5yZXBlYXQoNDApKTtcbiAgfVxuXG4gIGlmIChpbmNsdWRlSGVhZGVyKSB7XG4gICAgY29uc3QgaGVhZGVyTGluZSA9IGNvbHVtbnNcbiAgICAgIC5tYXAoKGNvbCkgPT4gc2FuaXRpemVDc3ZDZWxsKGNvbC5oZWFkZXIsIGRlbGltaXRlcikpXG4gICAgICAuam9pbihkZWxpbWl0ZXIpO1xuICAgIGxpbmVzLnB1c2goaGVhZGVyTGluZSk7XG4gIH1cblxuICBmb3IgKGNvbnN0IHJvdyBvZiByb3dzKSB7XG4gICAgY29uc3Qgcm93VmFsdWVzID0gY29sdW1ucy5tYXAoKGNvbCkgPT4ge1xuICAgICAgY29uc3QgdmFsID0gcm93W2NvbC5maWVsZF07XG4gICAgICBjb25zdCBmb3JtYXR0ZWQgPSBjb2wuZm9ybWF0dGVyID8gY29sLmZvcm1hdHRlcih2YWwsIHJvdykgOiB2YWw7XG4gICAgICByZXR1cm4gc2FuaXRpemVDc3ZDZWxsKGZvcm1hdHRlZCwgZGVsaW1pdGVyKTtcbiAgICB9KTtcbiAgICBsaW5lcy5wdXNoKHJvd1ZhbHVlcy5qb2luKGRlbGltaXRlcikpO1xuICB9XG5cbiAgY29uc3QgY3N2Qm9keSA9IGxpbmVzLmpvaW4oJ1xcclxcbicpO1xuICByZXR1cm4gYWRkQm9tID8gJ1xcdUZFRkYnICsgY3N2Qm9keSA6IGNzdkJvZHk7XG59XG5cbi8qKlxuICogR2VuZXJhdGVzIGFuIEV4Y2VsLWNvbXBhdGlibGUgWE1MIFNwcmVhZHNoZWV0IChTcHJlYWRzaGVldE1MKSBkb2N1bWVudCBzdHJpbmcuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZW5lcmF0ZUV4Y2VsWG1sKFxuICByb3dzOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPltdLFxuICBjb2x1bW5zOiBFeHBvcnRDb2x1bW5bXSxcbiAgc2hlZXROYW1lOiBzdHJpbmcgPSAnUmVwb3J0IERhdGEnLFxuICBicmFuZGVkSGVhZGVyPzogQnJhbmRlZEhlYWRlck9wdGlvbnNcbik6IHN0cmluZyB7XG4gIGNvbnN0IGVzY2FwZVhtbCA9ICh2YWw6IHVua25vd24pOiBzdHJpbmcgPT4ge1xuICAgIGlmICh2YWwgPT09IG51bGwgfHwgdmFsID09PSB1bmRlZmluZWQpIHJldHVybiAnJztcbiAgICByZXR1cm4gU3RyaW5nKHZhbClcbiAgICAgIC5yZXBsYWNlKC8mL2csICcmYW1wOycpXG4gICAgICAucmVwbGFjZSgvPC9nLCAnJmx0OycpXG4gICAgICAucmVwbGFjZSgvPi9nLCAnJmd0OycpXG4gICAgICAucmVwbGFjZSgvXCIvZywgJyZxdW90OycpXG4gICAgICAucmVwbGFjZSgvJy9nLCAnJmFwb3M7Jyk7XG4gIH07XG5cbiAgY29uc3QgeG1sUm93czogc3RyaW5nW10gPSBbXTtcblxuICBpZiAoYnJhbmRlZEhlYWRlcikge1xuICAgIGlmIChicmFuZGVkSGVhZGVyLmNvbXBhbnlOYW1lIHx8IGJyYW5kZWRIZWFkZXIucmVwb3J0VGl0bGUpIHtcbiAgICAgIGNvbnN0IHRpdGxlID0gW2JyYW5kZWRIZWFkZXIuY29tcGFueU5hbWUsIGJyYW5kZWRIZWFkZXIucmVwb3J0VGl0bGVdXG4gICAgICAgIC5maWx0ZXIoQm9vbGVhbilcbiAgICAgICAgLmpvaW4oJyAtICcpO1xuICAgICAgeG1sUm93cy5wdXNoKGBcbiAgICAgIDxSb3cgc3M6SGVpZ2h0PVwiMjRcIj5cbiAgICAgICAgPENlbGwgc3M6U3R5bGVJRD1cIlRpdGxlU3R5bGVcIiBzczpNZXJnZUFjcm9zcz1cIiR7TWF0aC5tYXgoMCwgY29sdW1ucy5sZW5ndGggLSAxKX1cIj5cbiAgICAgICAgICA8RGF0YSBzczpUeXBlPVwiU3RyaW5nXCI+JHtlc2NhcGVYbWwodGl0bGUpfTwvRGF0YT5cbiAgICAgICAgPC9DZWxsPlxuICAgICAgPC9Sb3c+YCk7XG4gICAgfVxuXG4gICAgY29uc3QgbWV0YVBhcnRzOiBzdHJpbmdbXSA9IFtdO1xuICAgIGlmIChicmFuZGVkSGVhZGVyLmJyYW5jaE5hbWUpIG1ldGFQYXJ0cy5wdXNoKGBCcmFuY2g6ICR7YnJhbmRlZEhlYWRlci5icmFuY2hOYW1lfWApO1xuICAgIGlmIChicmFuZGVkSGVhZGVyLmdlbmVyYXRlZEF0KSB7XG4gICAgICBjb25zdCBkdCA9XG4gICAgICAgIGJyYW5kZWRIZWFkZXIuZ2VuZXJhdGVkQXQgaW5zdGFuY2VvZiBEYXRlXG4gICAgICAgICAgPyBicmFuZGVkSGVhZGVyLmdlbmVyYXRlZEF0LnRvSVNPU3RyaW5nKCkucmVwbGFjZSgnVCcsICcgJykuc2xpY2UoMCwgMTkpXG4gICAgICAgICAgOiBTdHJpbmcoYnJhbmRlZEhlYWRlci5nZW5lcmF0ZWRBdCk7XG4gICAgICBtZXRhUGFydHMucHVzaChgRGF0ZTogJHtkdH1gKTtcbiAgICB9XG4gICAgaWYgKGJyYW5kZWRIZWFkZXIuZ2VuZXJhdGVkQnkpIG1ldGFQYXJ0cy5wdXNoKGBVc2VyOiAke2JyYW5kZWRIZWFkZXIuZ2VuZXJhdGVkQnl9YCk7XG5cbiAgICBpZiAobWV0YVBhcnRzLmxlbmd0aCA+IDApIHtcbiAgICAgIHhtbFJvd3MucHVzaChgXG4gICAgICA8Um93IHNzOkhlaWdodD1cIjE2XCI+XG4gICAgICAgIDxDZWxsIHNzOlN0eWxlSUQ9XCJTdWJUaXRsZVN0eWxlXCIgc3M6TWVyZ2VBY3Jvc3M9XCIke01hdGgubWF4KDAsIGNvbHVtbnMubGVuZ3RoIC0gMSl9XCI+XG4gICAgICAgICAgPERhdGEgc3M6VHlwZT1cIlN0cmluZ1wiPiR7ZXNjYXBlWG1sKG1ldGFQYXJ0cy5qb2luKCcgfCAnKSl9PC9EYXRhPlxuICAgICAgICA8L0NlbGw+XG4gICAgICA8L1Jvdz5gKTtcbiAgICB9XG5cbiAgICBjb25zdCBmaWx0ZXJUZXh0ID0gZm9ybWF0RmlsdGVyU3VtbWFyeShicmFuZGVkSGVhZGVyLmFjdGl2ZUZpbHRlclN1bW1hcnkpO1xuICAgIGlmIChmaWx0ZXJUZXh0KSB7XG4gICAgICB4bWxSb3dzLnB1c2goYFxuICAgICAgPFJvdyBzczpIZWlnaHQ9XCIxNlwiPlxuICAgICAgICA8Q2VsbCBzczpTdHlsZUlEPVwiRmlsdGVyU3R5bGVcIiBzczpNZXJnZUFjcm9zcz1cIiR7TWF0aC5tYXgoMCwgY29sdW1ucy5sZW5ndGggLSAxKX1cIj5cbiAgICAgICAgICA8RGF0YSBzczpUeXBlPVwiU3RyaW5nXCI+JHtlc2NhcGVYbWwoYEZpbHRlcnM6ICR7ZmlsdGVyVGV4dH1gKX08L0RhdGE+XG4gICAgICAgIDwvQ2VsbD5cbiAgICAgIDwvUm93PmApO1xuICAgIH1cblxuICAgIC8vIEJsYW5rIHJvdyBzZXBhcmF0b3JcbiAgICB4bWxSb3dzLnB1c2goJzxSb3cgc3M6SGVpZ2h0PVwiOFwiIC8+Jyk7XG4gIH1cblxuICAvLyBDb2x1bW4gSGVhZGVyc1xuICBjb25zdCBoZWFkZXJDZWxscyA9IGNvbHVtbnNcbiAgICAubWFwKFxuICAgICAgKGNvbCkgPT4gYFxuICAgICAgICA8Q2VsbCBzczpTdHlsZUlEPVwiSGVhZGVyU3R5bGVcIj48RGF0YSBzczpUeXBlPVwiU3RyaW5nXCI+JHtlc2NhcGVYbWwoY29sLmhlYWRlcil9PC9EYXRhPjwvQ2VsbD5gXG4gICAgKVxuICAgIC5qb2luKCcnKTtcbiAgeG1sUm93cy5wdXNoKGA8Um93IHNzOkhlaWdodD1cIjIwXCI+JHtoZWFkZXJDZWxsc31cXG4gICAgICA8L1Jvdz5gKTtcblxuICAvLyBEYXRhIHJvd3NcbiAgcm93cy5mb3JFYWNoKChyb3csIGlkeCkgPT4ge1xuICAgIGNvbnN0IGlzRXZlbiA9IGlkeCAlIDIgPT09IDA7XG4gICAgY29uc3Qgc3R5bGVJZCA9IGlzRXZlbiA/ICdEYXRhUm93RXZlbicgOiAnRGF0YVJvd09kZCc7XG4gICAgY29uc3QgY2VsbHMgPSBjb2x1bW5zXG4gICAgICAubWFwKChjb2wpID0+IHtcbiAgICAgICAgY29uc3QgdmFsID0gcm93W2NvbC5maWVsZF07XG4gICAgICAgIGNvbnN0IGZvcm1hdHRlZCA9IGNvbC5mb3JtYXR0ZXIgPyBjb2wuZm9ybWF0dGVyKHZhbCwgcm93KSA6IHZhbDtcbiAgICAgICAgY29uc3QgaXNOdW0gPSB0eXBlb2YgZm9ybWF0dGVkID09PSAnbnVtYmVyJyAmJiAhaXNOYU4oZm9ybWF0dGVkKTtcbiAgICAgICAgY29uc3QgdHlwZSA9IGlzTnVtID8gJ051bWJlcicgOiAnU3RyaW5nJztcbiAgICAgICAgcmV0dXJuIGA8Q2VsbCBzczpTdHlsZUlEPVwiJHtzdHlsZUlkfVwiPjxEYXRhIHNzOlR5cGU9XCIke3R5cGV9XCI+JHtlc2NhcGVYbWwoZm9ybWF0dGVkKX08L0RhdGE+PC9DZWxsPmA7XG4gICAgICB9KVxuICAgICAgLmpvaW4oJycpO1xuICAgIHhtbFJvd3MucHVzaChgICAgICAgPFJvdyBzczpIZWlnaHQ9XCIxN1wiPiR7Y2VsbHN9PC9Sb3c+YCk7XG4gIH0pO1xuXG4gIHJldHVybiBgPD94bWwgdmVyc2lvbj1cIjEuMFwiIGVuY29kaW5nPVwiVVRGLThcIj8+XG48P21zby1hcHBsaWNhdGlvbiBwcm9naWQ9XCJFeGNlbC5TaGVldFwiPz5cbjxXb3JrYm9vayB4bWxucz1cInVybjpzY2hlbWFzLW1pY3Jvc29mdC1jb206b2ZmaWNlOnNwcmVhZHNoZWV0XCJcbiB4bWxuczpvPVwidXJuOnNjaGVtYXMtbWljcm9zb2Z0LWNvbTpvZmZpY2U6b2ZmaWNlXCJcbiB4bWxuczp4PVwidXJuOnNjaGVtYXMtbWljcm9zb2Z0LWNvbTpvZmZpY2U6ZXhjZWxcIlxuIHhtbG5zOnNzPVwidXJuOnNjaGVtYXMtbWljcm9zb2Z0LWNvbTpvZmZpY2U6c3ByZWFkc2hlZXRcIj5cbiA8U3R5bGVzPlxuICA8U3R5bGUgc3M6SUQ9XCJEZWZhdWx0XCIgc3M6TmFtZT1cIk5vcm1hbFwiPlxuICAgPEFsaWdubWVudCBzczpWZXJ0aWNhbD1cIkNlbnRlclwiLz5cbiAgIDxGb250IHNzOkZvbnROYW1lPVwiU2Vnb2UgVUlcIiBzczpTaXplPVwiMTBcIiBzczpDb2xvcj1cIiMwRjE3MkFcIi8+XG4gIDwvU3R5bGU+XG4gIDxTdHlsZSBzczpJRD1cIlRpdGxlU3R5bGVcIj5cbiAgIDxBbGlnbm1lbnQgc3M6SG9yaXpvbnRhbD1cIkxlZnRcIiBzczpWZXJ0aWNhbD1cIkNlbnRlclwiLz5cbiAgIDxGb250IHNzOkZvbnROYW1lPVwiU2Vnb2UgVUlcIiBzczpTaXplPVwiMTRcIiBzczpCb2xkPVwiMVwiIHNzOkNvbG9yPVwiIzFFMjkzQlwiLz5cbiAgPC9TdHlsZT5cbiAgPFN0eWxlIHNzOklEPVwiU3ViVGl0bGVTdHlsZVwiPlxuICAgPEFsaWdubWVudCBzczpIb3Jpem9udGFsPVwiTGVmdFwiIHNzOlZlcnRpY2FsPVwiQ2VudGVyXCIvPlxuICAgPEZvbnQgc3M6Rm9udE5hbWU9XCJTZWdvZSBVSVwiIHNzOlNpemU9XCI5XCIgc3M6SXRhbGljPVwiMVwiIHNzOkNvbG9yPVwiIzY0NzQ4QlwiLz5cbiAgPC9TdHlsZT5cbiAgPFN0eWxlIHNzOklEPVwiRmlsdGVyU3R5bGVcIj5cbiAgIDxBbGlnbm1lbnQgc3M6SG9yaXpvbnRhbD1cIkxlZnRcIiBzczpWZXJ0aWNhbD1cIkNlbnRlclwiLz5cbiAgIDxGb250IHNzOkZvbnROYW1lPVwiU2Vnb2UgVUlcIiBzczpTaXplPVwiOVwiIHNzOkJvbGQ9XCIxXCIgc3M6Q29sb3I9XCIjMjU2M0VCXCIvPlxuICAgPEludGVyaW9yIHNzOkNvbG9yPVwiI0VGRjZGRlwiIHNzOlBhdHRlcm49XCJTb2xpZFwiLz5cbiAgPC9TdHlsZT5cbiAgPFN0eWxlIHNzOklEPVwiSGVhZGVyU3R5bGVcIj5cbiAgIDxBbGlnbm1lbnQgc3M6SG9yaXpvbnRhbD1cIkxlZnRcIiBzczpWZXJ0aWNhbD1cIkNlbnRlclwiLz5cbiAgIDxCb3JkZXJzPlxuICAgIDxCb3JkZXIgc3M6UG9zaXRpb249XCJCb3R0b21cIiBzczpMaW5lU3R5bGU9XCJDb250aW51b3VzXCIgc3M6V2VpZ2h0PVwiMVwiIHNzOkNvbG9yPVwiI0NCRDVFMVwiLz5cbiAgIDwvQm9yZGVycz5cbiAgIDxGb250IHNzOkZvbnROYW1lPVwiU2Vnb2UgVUlcIiBzczpTaXplPVwiMTBcIiBzczpCb2xkPVwiMVwiIHNzOkNvbG9yPVwiI0ZGRkZGRlwiLz5cbiAgIDxJbnRlcmlvciBzczpDb2xvcj1cIiMyNTYzRUJcIiBzczpQYXR0ZXJuPVwiU29saWRcIi8+XG4gIDwvU3R5bGU+XG4gIDxTdHlsZSBzczpJRD1cIkRhdGFSb3dFdmVuXCI+XG4gICA8Qm9yZGVycz5cbiAgICA8Qm9yZGVyIHNzOlBvc2l0aW9uPVwiQm90dG9tXCIgc3M6TGluZVN0eWxlPVwiQ29udGludW91c1wiIHNzOldlaWdodD1cIjFcIiBzczpDb2xvcj1cIiNGMUY1RjlcIi8+XG4gICA8L0JvcmRlcnM+XG4gICA8SW50ZXJpb3Igc3M6Q29sb3I9XCIjRkZGRkZGXCIgc3M6UGF0dGVybj1cIlNvbGlkXCIvPlxuICA8L1N0eWxlPlxuICA8U3R5bGUgc3M6SUQ9XCJEYXRhUm93T2RkXCI+XG4gICA8Qm9yZGVycz5cbiAgICA8Qm9yZGVyIHNzOlBvc2l0aW9uPVwiQm90dG9tXCIgc3M6TGluZVN0eWxlPVwiQ29udGludW91c1wiIHNzOldlaWdodD1cIjFcIiBzczpDb2xvcj1cIiNGMUY1RjlcIi8+XG4gICA8L0JvcmRlcnM+XG4gICA8SW50ZXJpb3Igc3M6Q29sb3I9XCIjRjhGQUZDXCIgc3M6UGF0dGVybj1cIlNvbGlkXCIvPlxuICA8L1N0eWxlPlxuIDwvU3R5bGVzPlxuIDxXb3Jrc2hlZXQgc3M6TmFtZT1cIiR7ZXNjYXBlWG1sKHNoZWV0TmFtZSl9XCI+XG4gIDxUYWJsZT5cbiR7Y29sdW1ucy5tYXAoKCkgPT4gJyAgIDxDb2x1bW4gc3M6QXV0b0ZpdFdpZHRoPVwiMVwiIHNzOldpZHRoPVwiMTIwXCIvPicpLmpvaW4oJ1xcbicpfVxuJHt4bWxSb3dzLmpvaW4oJ1xcbicpfVxuICA8L1RhYmxlPlxuIDwvV29ya3NoZWV0PlxuPC9Xb3JrYm9vaz5gO1xufVxuXG4vKipcbiAqIEdlbmVyYXRlcyBhbiBIVE1MIGRvY3VtZW50IHN0cmluZyBmb3JtYXR0ZWQgZm9yIHByaW50aW5nIGFuZCBjbGVhbiBQREYgY29udmVyc2lvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdlbmVyYXRlSHRtbENvbnRlbnQoXG4gIHJvd3M6IFJlY29yZDxzdHJpbmcsIHVua25vd24+W10sXG4gIGNvbHVtbnM6IEV4cG9ydENvbHVtbltdLFxuICB0aXRsZTogc3RyaW5nID0gJ1JlcG9ydCBFeHBvcnQnLFxuICBicmFuZGVkSGVhZGVyPzogQnJhbmRlZEhlYWRlck9wdGlvbnNcbik6IHN0cmluZyB7XG4gIGNvbnN0IGVzY2FwZUh0bWwgPSAodmFsOiB1bmtub3duKTogc3RyaW5nID0+IHtcbiAgICBpZiAodmFsID09PSBudWxsIHx8IHZhbCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gJyc7XG4gICAgcmV0dXJuIFN0cmluZyh2YWwpXG4gICAgICAucmVwbGFjZSgvJi9nLCAnJmFtcDsnKVxuICAgICAgLnJlcGxhY2UoLzwvZywgJyZsdDsnKVxuICAgICAgLnJlcGxhY2UoLz4vZywgJyZndDsnKTtcbiAgfTtcblxuICBjb25zdCBoZWFkZXJIdG1sID0gYnJhbmRlZEhlYWRlclxuICAgID8gYFxuICAgIDxoZWFkZXIgY2xhc3M9XCJycHQtcHJpbnQtaGVhZGVyXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwicnB0LXByaW50LW1ldGFcIj5cbiAgICAgICAgJHtcbiAgICAgICAgICBicmFuZGVkSGVhZGVyLmNvbXBhbnlOYW1lXG4gICAgICAgICAgICA/IGA8aDEgY2xhc3M9XCJycHQtY29tcGFueS10aXRsZVwiPiR7ZXNjYXBlSHRtbChicmFuZGVkSGVhZGVyLmNvbXBhbnlOYW1lKX08L2gxPmBcbiAgICAgICAgICAgIDogJydcbiAgICAgICAgfVxuICAgICAgICA8aDIgY2xhc3M9XCJycHQtcmVwb3J0LXRpdGxlXCI+JHtlc2NhcGVIdG1sKGJyYW5kZWRIZWFkZXIucmVwb3J0VGl0bGUgfHwgdGl0bGUpfTwvaDI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJycHQtbWV0YS1yb3dcIj5cbiAgICAgICAgICAke2JyYW5kZWRIZWFkZXIuYnJhbmNoTmFtZSA/IGA8c3Bhbj48c3Ryb25nPkJyYW5jaDo8L3N0cm9uZz4gJHtlc2NhcGVIdG1sKGJyYW5kZWRIZWFkZXIuYnJhbmNoTmFtZSl9PC9zcGFuPmAgOiAnJ31cbiAgICAgICAgICAke1xuICAgICAgICAgICAgYnJhbmRlZEhlYWRlci5nZW5lcmF0ZWRBdFxuICAgICAgICAgICAgICA/IGA8c3Bhbj48c3Ryb25nPkRhdGU6PC9zdHJvbmc+ICR7ZXNjYXBlSHRtbChcbiAgICAgICAgICAgICAgICAgIGJyYW5kZWRIZWFkZXIuZ2VuZXJhdGVkQXQgaW5zdGFuY2VvZiBEYXRlXG4gICAgICAgICAgICAgICAgICAgID8gYnJhbmRlZEhlYWRlci5nZW5lcmF0ZWRBdC50b0xvY2FsZVN0cmluZygpXG4gICAgICAgICAgICAgICAgICAgIDogYnJhbmRlZEhlYWRlci5nZW5lcmF0ZWRBdFxuICAgICAgICAgICAgICAgICl9PC9zcGFuPmBcbiAgICAgICAgICAgICAgOiAnJ1xuICAgICAgICAgIH1cbiAgICAgICAgICAke2JyYW5kZWRIZWFkZXIuZ2VuZXJhdGVkQnkgPyBgPHNwYW4+PHN0cm9uZz5Vc2VyOjwvc3Ryb25nPiAke2VzY2FwZUh0bWwoYnJhbmRlZEhlYWRlci5nZW5lcmF0ZWRCeSl9PC9zcGFuPmAgOiAnJ31cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICAgICR7XG4gICAgICAgIGJyYW5kZWRIZWFkZXIuYWN0aXZlRmlsdGVyU3VtbWFyeVxuICAgICAgICAgID8gYDxkaXYgY2xhc3M9XCJycHQtZmlsdGVyLWJveFwiPjxzdHJvbmc+QWN0aXZlIEZpbHRlcnM6PC9zdHJvbmc+ICR7ZXNjYXBlSHRtbChcbiAgICAgICAgICAgICAgZm9ybWF0RmlsdGVyU3VtbWFyeShicmFuZGVkSGVhZGVyLmFjdGl2ZUZpbHRlclN1bW1hcnkpXG4gICAgICAgICAgICApfTwvZGl2PmBcbiAgICAgICAgICA6ICcnXG4gICAgICB9XG4gICAgPC9oZWFkZXI+XG4gIGBcbiAgICA6IGA8aDIgY2xhc3M9XCJycHQtcmVwb3J0LXRpdGxlXCI+JHtlc2NhcGVIdG1sKHRpdGxlKX08L2gyPmA7XG5cbiAgY29uc3Qgcm93c0h0bWwgPSByb3dzXG4gICAgLm1hcChcbiAgICAgIChyLCBpZHgpID0+IGBcbiAgICA8dHIgY2xhc3M9XCIke2lkeCAlIDIgPT09IDAgPyAnZXZlbicgOiAnb2RkJ31cIj5cbiAgICAgICR7Y29sdW1uc1xuICAgICAgICAubWFwKChjb2wpID0+IHtcbiAgICAgICAgICBjb25zdCB2YWwgPSByW2NvbC5maWVsZF07XG4gICAgICAgICAgY29uc3QgZm9ybWF0dGVkID0gY29sLmZvcm1hdHRlciA/IGNvbC5mb3JtYXR0ZXIodmFsLCByKSA6IHZhbDtcbiAgICAgICAgICByZXR1cm4gYDx0ZD4ke2VzY2FwZUh0bWwoZm9ybWF0dGVkKX08L3RkPmA7XG4gICAgICAgIH0pXG4gICAgICAgIC5qb2luKCcnKX1cbiAgICA8L3RyPmBcbiAgICApXG4gICAgLmpvaW4oJycpO1xuXG4gIHJldHVybiBgPCFET0NUWVBFIGh0bWw+XG48aHRtbCBsYW5nPVwiZW5cIj5cbjxoZWFkPlxuICA8bWV0YSBjaGFyc2V0PVwidXRmLThcIj5cbiAgPHRpdGxlPiR7ZXNjYXBlSHRtbCh0aXRsZSl9PC90aXRsZT5cbiAgPHN0eWxlPlxuICAgIGJvZHkge1xuICAgICAgZm9udC1mYW1pbHk6IC1hcHBsZS1zeXN0ZW0sIEJsaW5rTWFjU3lzdGVtRm9udCwgXCJTZWdvZSBVSVwiLCBSb2JvdG8sIEhlbHZldGljYSwgQXJpYWwsIHNhbnMtc2VyaWY7XG4gICAgICBtYXJnaW46IDI0cHg7XG4gICAgICBjb2xvcjogIzBmMTcyYTtcbiAgICAgIGJhY2tncm91bmQ6ICNmZmZmZmY7XG4gICAgfVxuICAgIC5ycHQtcHJpbnQtaGVhZGVyIHtcbiAgICAgIGJvcmRlci1ib3R0b206IDJweCBzb2xpZCAjMjU2M2ViO1xuICAgICAgcGFkZGluZy1ib3R0b206IDEycHg7XG4gICAgICBtYXJnaW4tYm90dG9tOiAxNnB4O1xuICAgIH1cbiAgICAucnB0LWNvbXBhbnktdGl0bGUge1xuICAgICAgZm9udC1zaXplOiAxLjI1cmVtO1xuICAgICAgZm9udC13ZWlnaHQ6IDcwMDtcbiAgICAgIGNvbG9yOiAjMWUyOTNiO1xuICAgICAgbWFyZ2luOiAwIDAgNHB4IDA7XG4gICAgfVxuICAgIC5ycHQtcmVwb3J0LXRpdGxlIHtcbiAgICAgIGZvbnQtc2l6ZTogMS4xcmVtO1xuICAgICAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgICAgIGNvbG9yOiAjMjU2M2ViO1xuICAgICAgbWFyZ2luOiAwIDAgNnB4IDA7XG4gICAgfVxuICAgIC5ycHQtbWV0YS1yb3cge1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGdhcDogMTZweDtcbiAgICAgIGZvbnQtc2l6ZTogMC43NXJlbTtcbiAgICAgIGNvbG9yOiAjNjQ3NDhiO1xuICAgIH1cbiAgICAucnB0LWZpbHRlci1ib3gge1xuICAgICAgbWFyZ2luLXRvcDogOHB4O1xuICAgICAgcGFkZGluZzogNnB4IDEwcHg7XG4gICAgICBiYWNrZ3JvdW5kOiAjZWZmNmZmO1xuICAgICAgYm9yZGVyOiAxcHggc29saWQgI2JmZGJmZTtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDRweDtcbiAgICAgIGZvbnQtc2l6ZTogMC43NXJlbTtcbiAgICAgIGNvbG9yOiAjMWU0MGFmO1xuICAgIH1cbiAgICB0YWJsZSB7XG4gICAgICB3aWR0aDogMTAwJTtcbiAgICAgIGJvcmRlci1jb2xsYXBzZTogY29sbGFwc2U7XG4gICAgICBmb250LXNpemU6IDAuOHJlbTtcbiAgICB9XG4gICAgdGgge1xuICAgICAgYmFja2dyb3VuZDogIzI1NjNlYjtcbiAgICAgIGNvbG9yOiAjZmZmZmZmO1xuICAgICAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgICAgIHRleHQtYWxpZ246IGxlZnQ7XG4gICAgICBwYWRkaW5nOiA4cHggMTBweDtcbiAgICAgIGJvcmRlcjogMXB4IHNvbGlkICMxZDRlZDg7XG4gICAgfVxuICAgIHRkIHtcbiAgICAgIHBhZGRpbmc6IDZweCAxMHB4O1xuICAgICAgYm9yZGVyOiAxcHggc29saWQgI2UyZThmMDtcbiAgICB9XG4gICAgdHIuZXZlbiB7XG4gICAgICBiYWNrZ3JvdW5kOiAjZmZmZmZmO1xuICAgIH1cbiAgICB0ci5vZGQge1xuICAgICAgYmFja2dyb3VuZDogI2Y4ZmFmYztcbiAgICB9XG4gICAgQG1lZGlhIHByaW50IHtcbiAgICAgIGJvZHkgeyBtYXJnaW46IDA7IH1cbiAgICAgIHRoIHsgLXdlYmtpdC1wcmludC1jb2xvci1hZGp1c3Q6IGV4YWN0OyBwcmludC1jb2xvci1hZGp1c3Q6IGV4YWN0OyB9XG4gICAgICAucnB0LWZpbHRlci1ib3ggeyAtd2Via2l0LXByaW50LWNvbG9yLWFkanVzdDogZXhhY3Q7IHByaW50LWNvbG9yLWFkanVzdDogZXhhY3Q7IH1cbiAgICB9XG4gIDwvc3R5bGU+XG48L2hlYWQ+XG48Ym9keT5cbiAgJHtoZWFkZXJIdG1sfVxuICA8dGFibGU+XG4gICAgPHRoZWFkPlxuICAgICAgPHRyPlxuICAgICAgICAke2NvbHVtbnMubWFwKChjKSA9PiBgPHRoPiR7ZXNjYXBlSHRtbChjLmhlYWRlcil9PC90aD5gKS5qb2luKCcnKX1cbiAgICAgIDwvdHI+XG4gICAgPC90aGVhZD5cbiAgICA8dGJvZHk+XG4gICAgICAke3Jvd3NIdG1sfVxuICAgIDwvdGJvZHk+XG4gIDwvdGFibGU+XG48L2JvZHk+XG48L2h0bWw+YDtcbn1cblxuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIFJlcG9ydEV4cG9ydFNlcnZpY2Uge1xuICBwcml2YXRlIHJlYWRvbmx5IGRvY3VtZW50ID0gaW5qZWN0KERPQ1VNRU5UKTtcbiAgcHJpdmF0ZSByZWFkb25seSBzZXNzaW9uU2VydmljZSA9IGluamVjdChSZXBvcnRTZXNzaW9uQ29udGV4dFNlcnZpY2UsIHsgb3B0aW9uYWw6IHRydWUgfSk7XG5cbiAgLyoqXG4gICAqIEVucmljaGVzIGJyYW5kZWQgaGVhZGVyIG9wdGlvbnMgd2l0aCBmYWxsYmFjayBzZXNzaW9uIGNvbnRleHQgZGF0YSBpZiBhdmFpbGFibGUuXG4gICAqL1xuICBwcml2YXRlIHJlc29sdmVCcmFuZGVkSGVhZGVyKGhlYWRlcj86IEJyYW5kZWRIZWFkZXJPcHRpb25zKTogQnJhbmRlZEhlYWRlck9wdGlvbnMgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IHNlc3Npb24gPSB0aGlzLnNlc3Npb25TZXJ2aWNlPy5zZXNzaW9uQ29udGV4dCgpID8/IHt9O1xuICAgIGlmICghaGVhZGVyICYmIE9iamVjdC5rZXlzKHNlc3Npb24pLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29tcGFueU5hbWU6XG4gICAgICAgIGhlYWRlcj8uY29tcGFueU5hbWUgfHxcbiAgICAgICAgKHNlc3Npb25bJ2NvbXBhbnlOYW1lJ10gYXMgc3RyaW5nKSB8fFxuICAgICAgICAoc2Vzc2lvblsndGVuYW50TmFtZSddIGFzIHN0cmluZykgfHxcbiAgICAgICAgKHNlc3Npb25bJ2NvbXBhbnknXSBhcyBzdHJpbmcpLFxuICAgICAgYnJhbmNoTmFtZTpcbiAgICAgICAgaGVhZGVyPy5icmFuY2hOYW1lIHx8XG4gICAgICAgIChzZXNzaW9uWydicmFuY2hOYW1lJ10gYXMgc3RyaW5nKSB8fFxuICAgICAgICAoc2Vzc2lvblsnYnJhbmNoQ29kZSddIGFzIHN0cmluZyksXG4gICAgICByZXBvcnRUaXRsZTogaGVhZGVyPy5yZXBvcnRUaXRsZSxcbiAgICAgIGdlbmVyYXRlZEF0OiBoZWFkZXI/LmdlbmVyYXRlZEF0IHx8IG5ldyBEYXRlKCksXG4gICAgICBnZW5lcmF0ZWRCeTpcbiAgICAgICAgaGVhZGVyPy5nZW5lcmF0ZWRCeSB8fFxuICAgICAgICAoc2Vzc2lvblsndXNlck5hbWUnXSBhcyBzdHJpbmcpIHx8XG4gICAgICAgIChzZXNzaW9uWyd1c2VySWQnXSBhcyBzdHJpbmcpLFxuICAgICAgYWN0aXZlRmlsdGVyU3VtbWFyeTogaGVhZGVyPy5hY3RpdmVGaWx0ZXJTdW1tYXJ5LFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGVzIGFuZCB0cmlnZ2VycyBicm93c2VyIGRvd25sb2FkIG9mIGEgQ1NWIGZpbGUuXG4gICAqL1xuICBleHBvcnRDc3Yocm93czogUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXSwgb3B0aW9uczogQ3N2RXhwb3J0T3B0aW9ucyA9IHt9KTogdm9pZCB7XG4gICAgaWYgKCFyb3dzIHx8IHJvd3MubGVuZ3RoID09PSAwKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ1tid2F5cy1yZXBvcnRdIE5vIHJvd3MgdG8gZXhwb3J0Jyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZGVsaW1pdGVyID0gb3B0aW9ucy5kZWxpbWl0ZXIgPz8gJywnO1xuICAgIGNvbnN0IGluY2x1ZGVIZWFkZXIgPSBvcHRpb25zLmluY2x1ZGVIZWFkZXIgIT09IGZhbHNlO1xuICAgIGNvbnN0IGFkZEJvbSA9IG9wdGlvbnMuYWRkQm9tICE9PSBmYWxzZTtcbiAgICBjb25zdCBmaWxlTmFtZSA9IG9wdGlvbnMuZmlsZU5hbWUgfHwgYHJlcG9ydC1leHBvcnQtJHtEYXRlLm5vdygpfS5jc3ZgO1xuICAgIGNvbnN0IGJyYW5kZWRIZWFkZXIgPSB0aGlzLnJlc29sdmVCcmFuZGVkSGVhZGVyKG9wdGlvbnMuYnJhbmRlZEhlYWRlcik7XG5cbiAgICAvLyBJZiBjb2x1bW5zIG5vdCBwcm92aWRlZCwgaW5mZXIgZnJvbSBmaXJzdCByb3cga2V5c1xuICAgIGNvbnN0IGNvbHVtbnM6IEV4cG9ydENvbHVtbltdID1cbiAgICAgIG9wdGlvbnMuY29sdW1ucyAmJiBvcHRpb25zLmNvbHVtbnMubGVuZ3RoID4gMFxuICAgICAgICA/IG9wdGlvbnMuY29sdW1uc1xuICAgICAgICA6IE9iamVjdC5rZXlzKHJvd3NbMF0pLm1hcCgoa2V5KSA9PiAoe1xuICAgICAgICAgICAgZmllbGQ6IGtleSxcbiAgICAgICAgICAgIGhlYWRlcjoga2V5LFxuICAgICAgICAgIH0pKTtcblxuICAgIGNvbnN0IGNzdkNvbnRlbnQgPSBnZW5lcmF0ZUNzdkNvbnRlbnQoXG4gICAgICByb3dzLFxuICAgICAgY29sdW1ucyxcbiAgICAgIGRlbGltaXRlcixcbiAgICAgIGluY2x1ZGVIZWFkZXIsXG4gICAgICBhZGRCb20sXG4gICAgICBicmFuZGVkSGVhZGVyXG4gICAgKTtcbiAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoW2NzdkNvbnRlbnRdLCB7IHR5cGU6ICd0ZXh0L2NzdjtjaGFyc2V0PXV0Zi04OycgfSk7XG4gICAgdGhpcy5kb3dubG9hZEJsb2IoYmxvYiwgZmlsZU5hbWUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdlbmVyYXRlcyBhbmQgdHJpZ2dlcnMgYnJvd3NlciBkb3dubG9hZCBvZiBhbiBFeGNlbCBzcHJlYWRzaGVldCAoLnhscyBTcHJlYWRzaGVldE1MKS5cbiAgICovXG4gIGV4cG9ydEV4Y2VsKHJvd3M6IFJlY29yZDxzdHJpbmcsIHVua25vd24+W10sIG9wdGlvbnM6IEV4Y2VsRXhwb3J0T3B0aW9ucyA9IHt9KTogdm9pZCB7XG4gICAgaWYgKCFyb3dzIHx8IHJvd3MubGVuZ3RoID09PSAwKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ1tid2F5cy1yZXBvcnRdIE5vIHJvd3MgdG8gZXhwb3J0IHRvIEV4Y2VsJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgcmF3TmFtZSA9IG9wdGlvbnMuZmlsZU5hbWUgfHwgYHJlcG9ydC1leHBvcnQtJHtEYXRlLm5vdygpfWA7XG4gICAgY29uc3QgZmlsZU5hbWUgPSByYXdOYW1lLmVuZHNXaXRoKCcueGxzJykgfHwgcmF3TmFtZS5lbmRzV2l0aCgnLnhsc3gnKVxuICAgICAgPyByYXdOYW1lXG4gICAgICA6IGAke3Jhd05hbWV9Lnhsc2A7XG4gICAgY29uc3Qgc2hlZXROYW1lID0gb3B0aW9ucy5zaGVldE5hbWUgfHwgJ1JlcG9ydCBEYXRhJztcbiAgICBjb25zdCBicmFuZGVkSGVhZGVyID0gdGhpcy5yZXNvbHZlQnJhbmRlZEhlYWRlcihvcHRpb25zLmJyYW5kZWRIZWFkZXIpO1xuXG4gICAgY29uc3QgY29sdW1uczogRXhwb3J0Q29sdW1uW10gPVxuICAgICAgb3B0aW9ucy5jb2x1bW5zICYmIG9wdGlvbnMuY29sdW1ucy5sZW5ndGggPiAwXG4gICAgICAgID8gb3B0aW9ucy5jb2x1bW5zXG4gICAgICAgIDogT2JqZWN0LmtleXMocm93c1swXSkubWFwKChrZXkpID0+ICh7XG4gICAgICAgICAgICBmaWVsZDoga2V5LFxuICAgICAgICAgICAgaGVhZGVyOiBrZXksXG4gICAgICAgICAgfSkpO1xuXG4gICAgY29uc3QgeG1sQ29udGVudCA9IGdlbmVyYXRlRXhjZWxYbWwocm93cywgY29sdW1ucywgc2hlZXROYW1lLCBicmFuZGVkSGVhZGVyKTtcbiAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoW3htbENvbnRlbnRdLCB7XG4gICAgICB0eXBlOiAnYXBwbGljYXRpb24vdm5kLm1zLWV4Y2VsO2NoYXJzZXQ9dXRmLTg7JyxcbiAgICB9KTtcbiAgICB0aGlzLmRvd25sb2FkQmxvYihibG9iLCBmaWxlTmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdGVzIGFuZCB0cmlnZ2VycyBicm93c2VyIGRvd25sb2FkIG9mIGEgc3R5bGVkLCBwcmludGFibGUgSFRNTCByZXBvcnQgZmlsZS5cbiAgICovXG4gIGV4cG9ydEh0bWwocm93czogUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXSwgb3B0aW9uczogSHRtbEV4cG9ydE9wdGlvbnMgPSB7fSk6IHZvaWQge1xuICAgIGlmICghcm93cyB8fCByb3dzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgY29uc29sZS53YXJuKCdbYndheXMtcmVwb3J0XSBObyByb3dzIHRvIGV4cG9ydCB0byBIVE1MJyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZmlsZU5hbWUgPSBvcHRpb25zLmZpbGVOYW1lIHx8IGByZXBvcnQtZXhwb3J0LSR7RGF0ZS5ub3coKX0uaHRtbGA7XG4gICAgY29uc3QgdGl0bGUgPSBvcHRpb25zLnRpdGxlIHx8ICdSZXBvcnQgRXhwb3J0JztcbiAgICBjb25zdCBicmFuZGVkSGVhZGVyID0gdGhpcy5yZXNvbHZlQnJhbmRlZEhlYWRlcihvcHRpb25zLmJyYW5kZWRIZWFkZXIpO1xuXG4gICAgY29uc3QgY29sdW1uczogRXhwb3J0Q29sdW1uW10gPVxuICAgICAgb3B0aW9ucy5jb2x1bW5zICYmIG9wdGlvbnMuY29sdW1ucy5sZW5ndGggPiAwXG4gICAgICAgID8gb3B0aW9ucy5jb2x1bW5zXG4gICAgICAgIDogT2JqZWN0LmtleXMocm93c1swXSkubWFwKChrZXkpID0+ICh7XG4gICAgICAgICAgICBmaWVsZDoga2V5LFxuICAgICAgICAgICAgaGVhZGVyOiBrZXksXG4gICAgICAgICAgfSkpO1xuXG4gICAgY29uc3QgaHRtbENvbnRlbnQgPSBnZW5lcmF0ZUh0bWxDb250ZW50KHJvd3MsIGNvbHVtbnMsIHRpdGxlLCBicmFuZGVkSGVhZGVyKTtcbiAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoW2h0bWxDb250ZW50XSwgeyB0eXBlOiAndGV4dC9odG1sO2NoYXJzZXQ9dXRmLTg7JyB9KTtcbiAgICB0aGlzLmRvd25sb2FkQmxvYihibG9iLCBmaWxlTmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogT3BlbnMgYSBwcmludGFibGUgd2luZG93IHdpdGggYnJhbmRlZCBzdHlsaW5nIGFuZCBvcHRpb25hbGx5IGNhbGxzIHdpbmRvdy5wcmludCgpLlxuICAgKi9cbiAgcHJpbnRSZXBvcnQocm93czogUmVjb3JkPHN0cmluZywgdW5rbm93bj5bXSwgb3B0aW9uczogSHRtbEV4cG9ydE9wdGlvbnMgPSB7fSk6IHZvaWQge1xuICAgIGlmICghcm93cyB8fCByb3dzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgY29uc29sZS53YXJuKCdbYndheXMtcmVwb3J0XSBObyByb3dzIHRvIHByaW50Jyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgdGl0bGUgPSBvcHRpb25zLnRpdGxlIHx8ICdSZXBvcnQgUHJpbnQgUHJldmlldyc7XG4gICAgY29uc3QgYnJhbmRlZEhlYWRlciA9IHRoaXMucmVzb2x2ZUJyYW5kZWRIZWFkZXIob3B0aW9ucy5icmFuZGVkSGVhZGVyKTtcbiAgICBjb25zdCBjb2x1bW5zOiBFeHBvcnRDb2x1bW5bXSA9XG4gICAgICBvcHRpb25zLmNvbHVtbnMgJiYgb3B0aW9ucy5jb2x1bW5zLmxlbmd0aCA+IDBcbiAgICAgICAgPyBvcHRpb25zLmNvbHVtbnNcbiAgICAgICAgOiBPYmplY3Qua2V5cyhyb3dzWzBdKS5tYXAoKGtleSkgPT4gKHtcbiAgICAgICAgICAgIGZpZWxkOiBrZXksXG4gICAgICAgICAgICBoZWFkZXI6IGtleSxcbiAgICAgICAgICB9KSk7XG5cbiAgICBjb25zdCBodG1sID0gZ2VuZXJhdGVIdG1sQ29udGVudChyb3dzLCBjb2x1bW5zLCB0aXRsZSwgYnJhbmRlZEhlYWRlcik7XG4gICAgY29uc3Qgd2luID0gd2luZG93Lm9wZW4oJycsICdfYmxhbmsnLCAnd2lkdGg9OTAwLGhlaWdodD03MDAnKTtcbiAgICBpZiAod2luKSB7XG4gICAgICB3aW4uZG9jdW1lbnQub3BlbigpO1xuICAgICAgd2luLmRvY3VtZW50LndyaXRlKGh0bWwpO1xuICAgICAgd2luLmRvY3VtZW50LmNsb3NlKCk7XG4gICAgICBpZiAob3B0aW9ucy5hdXRvUHJpbnQgIT09IGZhbHNlKSB7XG4gICAgICAgIHdpbi5mb2N1cygpO1xuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHdpbi5wcmludCgpLCAyNTApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgYW5kIHRyaWdnZXJzIGJyb3dzZXIgZG93bmxvYWQgb2YgYSBKU09OIGZpbGUuXG4gICAqL1xuICBleHBvcnRKc29uKGRhdGE6IHVua25vd24sIG9wdGlvbnM6IEpzb25FeHBvcnRPcHRpb25zID0ge30pOiB2b2lkIHtcbiAgICBjb25zdCBmaWxlTmFtZSA9IG9wdGlvbnMuZmlsZU5hbWUgfHwgYHJlcG9ydC1leHBvcnQtJHtEYXRlLm5vdygpfS5qc29uYDtcbiAgICBjb25zdCBwcmV0dHkgPSBvcHRpb25zLnByZXR0eSAhPT0gZmFsc2U7XG4gICAgY29uc3QganNvblN0cmluZyA9IHByZXR0eSA/IEpTT04uc3RyaW5naWZ5KGRhdGEsIG51bGwsIDIpIDogSlNPTi5zdHJpbmdpZnkoZGF0YSk7XG5cbiAgICBjb25zdCBibG9iID0gbmV3IEJsb2IoW2pzb25TdHJpbmddLCB7IHR5cGU6ICdhcHBsaWNhdGlvbi9qc29uO2NoYXJzZXQ9dXRmLTg7JyB9KTtcbiAgICB0aGlzLmRvd25sb2FkQmxvYihibG9iLCBmaWxlTmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogU2FmZSBmaWxlIGRvd25sb2FkIHRyaWdnZXIgdmlhIHRlbXBvcmFyeSBhbmNob3IgdGFnLlxuICAgKi9cbiAgcHJpdmF0ZSBkb3dubG9hZEJsb2IoYmxvYjogQmxvYiwgZmlsZU5hbWU6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghdGhpcy5kb2N1bWVudCB8fCAhdGhpcy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgdXJsID0gVVJMLmNyZWF0ZU9iamVjdFVSTChibG9iKTtcbiAgICBjb25zdCBsaW5rID0gdGhpcy5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XG4gICAgbGluay5ocmVmID0gdXJsO1xuICAgIGxpbmsuZG93bmxvYWQgPSBmaWxlTmFtZTtcbiAgICBsaW5rLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG5cbiAgICB0aGlzLmRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQobGluayk7XG4gICAgbGluay5jbGljaygpO1xuXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQobGluayk7XG4gICAgICBVUkwucmV2b2tlT2JqZWN0VVJMKHVybCk7XG4gICAgfSwgMTAwKTtcbiAgfVxufVxuIl19