cloud-ide-admin 1.0.0

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 (36) hide show
  1. package/README.md +24 -0
  2. package/esm2022/cloud-ide-admin.mjs +5 -0
  3. package/esm2022/lib/admin-module/entity/create/cide-adm-entity.component.mjs +834 -0
  4. package/esm2022/lib/admin-module/entity/create/cide-adm-entity.service.mjs +79 -0
  5. package/esm2022/lib/admin-module/entity/create/country-select.service.mjs +33 -0
  6. package/esm2022/lib/admin-module/entity/create/currency-select.service.mjs +48 -0
  7. package/esm2022/lib/admin-module/entity/create/general-master-select.service.mjs +44 -0
  8. package/esm2022/lib/admin-module/entity/create/pin-code-select.service.mjs +60 -0
  9. package/esm2022/lib/admin-module/entity/create/user-select.service.mjs +58 -0
  10. package/esm2022/lib/admin-module/entity/list/cide-adm-entity-list.component.mjs +600 -0
  11. package/esm2022/lib/admin-module/entity/list/cide-adm-entity-list.service.mjs +52 -0
  12. package/esm2022/lib/admin-module/home/home-wrapper/cide-adm-home-wrapper.component.mjs +21 -0
  13. package/esm2022/lib/cide-adm-admin.component.mjs +29 -0
  14. package/esm2022/lib/cide-adm-admin.service.mjs +14 -0
  15. package/esm2022/lib/cloud-ide-admin.routes.mjs +38 -0
  16. package/esm2022/public-api.mjs +10 -0
  17. package/fesm2022/cloud-ide-admin-cide-adm-home-wrapper.component-Cu0sr3ST.mjs +24 -0
  18. package/fesm2022/cloud-ide-admin-cide-adm-home-wrapper.component-Cu0sr3ST.mjs.map +1 -0
  19. package/fesm2022/cloud-ide-admin.mjs +1867 -0
  20. package/fesm2022/cloud-ide-admin.mjs.map +1 -0
  21. package/index.d.ts +5 -0
  22. package/lib/admin-module/entity/create/cide-adm-entity.component.d.ts +73 -0
  23. package/lib/admin-module/entity/create/cide-adm-entity.service.d.ts +39 -0
  24. package/lib/admin-module/entity/create/country-select.service.d.ts +13 -0
  25. package/lib/admin-module/entity/create/currency-select.service.d.ts +19 -0
  26. package/lib/admin-module/entity/create/general-master-select.service.d.ts +24 -0
  27. package/lib/admin-module/entity/create/pin-code-select.service.d.ts +31 -0
  28. package/lib/admin-module/entity/create/user-select.service.d.ts +31 -0
  29. package/lib/admin-module/entity/list/cide-adm-entity-list.component.d.ts +94 -0
  30. package/lib/admin-module/entity/list/cide-adm-entity-list.service.d.ts +25 -0
  31. package/lib/admin-module/home/home-wrapper/cide-adm-home-wrapper.component.d.ts +9 -0
  32. package/lib/cide-adm-admin.component.d.ts +9 -0
  33. package/lib/cide-adm-admin.service.d.ts +6 -0
  34. package/lib/cloud-ide-admin.routes.d.ts +2 -0
  35. package/package.json +25 -0
  36. package/public-api.d.ts +6 -0
@@ -0,0 +1,600 @@
1
+ import { Component, signal, inject, ViewChild } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { FormsModule } from '@angular/forms';
4
+ import { Router } from '@angular/router';
5
+ import { CideInputComponent, CideIconComponent, TooltipDirective } from 'cloud-ide-element';
6
+ import { CideEleButtonComponent, CideSelectComponent } from 'cloud-ide-element';
7
+ import { CideEleDataGridComponent } from 'cloud-ide-element';
8
+ import { CideAdmEntityListService } from './cide-adm-entity-list.service';
9
+ import { generateStringFromObject } from 'cloud-ide-lms-model';
10
+ import * as i0 from "@angular/core";
11
+ import * as i1 from "@angular/forms";
12
+ export class CideAdmEntityListComponent {
13
+ constructor() {
14
+ // Modern dependency injection using inject()
15
+ this.router = inject(Router); // Made public for template access
16
+ this.entityService = inject(CideAdmEntityListService);
17
+ // State management using Angular Signals
18
+ this.entities = signal([]);
19
+ this.loading = signal(false);
20
+ this.error = signal(null);
21
+ this.searchQuery = signal('');
22
+ this.currentPage = signal(1);
23
+ this.pageSize = signal(10);
24
+ this.totalItems = signal(0);
25
+ this.selectedEntityType = signal('');
26
+ // Pagination calculations
27
+ this.totalPages = signal(0);
28
+ this.hasNextPage = signal(false);
29
+ this.hasPreviousPage = signal(false);
30
+ this.jumpToPage = 1;
31
+ this.loadStartTime = 0;
32
+ // Filter options
33
+ this.entityTypeOptions = signal([
34
+ { value: '', label: 'All Entity Types' },
35
+ { value: 'school', label: 'School' },
36
+ { value: 'college', label: 'College' },
37
+ { value: 'university', label: 'University' },
38
+ { value: 'institute', label: 'Institute' }
39
+ ]);
40
+ // Grid configuration signal
41
+ this.gridConfig = signal({
42
+ id: 'entity-list-grid',
43
+ title: '',
44
+ subtitle: '',
45
+ columns: [
46
+ {
47
+ key: 'details',
48
+ header: 'Entity Details',
49
+ type: 'custom',
50
+ width: 'lg',
51
+ truncate: true,
52
+ align: 'left',
53
+ renderer: 'entityDetailsRenderer'
54
+ },
55
+ {
56
+ key: 'contact',
57
+ header: 'Contact Information',
58
+ type: 'custom',
59
+ width: 'lg',
60
+ truncate: true,
61
+ align: 'left',
62
+ renderer: 'contactInfoRenderer'
63
+ },
64
+ {
65
+ key: 'syen_isactive',
66
+ header: 'Status',
67
+ type: 'status',
68
+ width: 'md',
69
+ truncate: false,
70
+ align: 'center',
71
+ statusConfig: {
72
+ activeValue: true,
73
+ activeLabel: 'Active',
74
+ inactiveLabel: 'Inactive',
75
+ activeClass: 'tw-bg-green-100 tw-text-green-800',
76
+ inactiveClass: 'tw-bg-red-100 tw-text-red-800'
77
+ }
78
+ },
79
+ {
80
+ key: 'syen_entity_type_gmst',
81
+ header: 'Entity Type',
82
+ type: 'text',
83
+ width: 'md',
84
+ truncate: false,
85
+ align: 'center'
86
+ },
87
+ {
88
+ key: 'actions',
89
+ header: 'Actions',
90
+ type: 'actions',
91
+ width: 'md',
92
+ truncate: false,
93
+ align: 'right',
94
+ actions: [
95
+ {
96
+ key: 'edit',
97
+ label: 'Edit',
98
+ icon: 'pencil',
99
+ variant: 'outline',
100
+ tooltip: 'Edit entity',
101
+ onClick: 'onEditEntity'
102
+ },
103
+ {
104
+ key: 'delete',
105
+ label: 'Delete',
106
+ icon: 'trash',
107
+ variant: 'danger',
108
+ tooltip: 'Delete entity',
109
+ onClick: 'onDeleteEntity'
110
+ }
111
+ ]
112
+ }
113
+ ],
114
+ data: [],
115
+ trackBy: '_id',
116
+ pagination: {
117
+ enabled: true,
118
+ pageSize: 10,
119
+ pageSizeOptions: [10, 25, 50, 100],
120
+ showQuickJump: true,
121
+ showPageInfo: true,
122
+ showRefresh: true
123
+ },
124
+ search: {
125
+ enabled: true,
126
+ placeholder: 'Search entities...',
127
+ searchableColumns: ['syen_name', 'syen_entity_code', 'syen_corporate_email'],
128
+ debounceMs: 300
129
+ },
130
+ loading: {
131
+ useDefer: true,
132
+ skeletonRows: 5,
133
+ showOverlay: false
134
+ },
135
+ responsive: true,
136
+ striped: false,
137
+ bordered: true,
138
+ compact: false,
139
+ fullHeight: true,
140
+ onRowClick: 'onEntityRowClick',
141
+ onRefresh: 'onEntityRefresh',
142
+ tree: {
143
+ enabled: true,
144
+ primaryKey: '_id',
145
+ foreignKey: 'syen_parent_entity_id',
146
+ childrenKey: 'children',
147
+ levelKey: 'level',
148
+ expandedKey: 'isExpanded',
149
+ hasChildrenKey: 'hasChildren'
150
+ }
151
+ });
152
+ // Custom renderers for complex columns
153
+ this.customRenderers = {
154
+ entityDetailsRenderer: (value, row) => {
155
+ const entityCode = row.syen_entity_code || 'N/A';
156
+ const entityName = row.syen_name || 'Unknown Entity';
157
+ return `
158
+ <div class="tw-flex tw-items-center tw-space-x-3">
159
+ <div class="tw-flex-shrink-0 tw-w-10 tw-h-10 tw-bg-blue-100 tw-rounded-full tw-flex tw-items-center tw-justify-center">
160
+ <span class="tw-text-blue-600 tw-font-semibold tw-text-sm">
161
+ ${entityCode.substring(0, 2).toUpperCase()}
162
+ </span>
163
+ </div>
164
+ <div class="tw-flex-1 tw-min-w-0">
165
+ <p class="tw-text-sm tw-font-medium tw-text-gray-900 tw-truncate" title="${entityName}">
166
+ ${entityName}
167
+ </p>
168
+ <p class="tw-text-sm tw-text-gray-500 tw-truncate" title="${entityCode}">
169
+ Code: ${entityCode}
170
+ </p>
171
+ </div>
172
+ </div>
173
+ `;
174
+ },
175
+ contactInfoRenderer: (value, row) => {
176
+ const contactPerson = row.syen_corporate_contact_person_user || 'N/A';
177
+ const email = row.syen_corporate_email || 'N/A';
178
+ const phone = row.syen_corporate_phone ? String(row.syen_corporate_phone) : 'N/A';
179
+ return `
180
+ <div class="tw-space-y-1">
181
+ <p class="tw-text-sm tw-text-gray-900 tw-truncate tw-flex tw-items-center" title="${contactPerson}">
182
+ <svg class="tw-flex-shrink-0 tw-w-4 tw-h-4 tw-text-gray-400 tw-mr-2" fill="currentColor" viewBox="0 0 20 20">
183
+ <path d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z"/>
184
+ </svg>
185
+ <span class="tw-truncate">${contactPerson}</span>
186
+ </p>
187
+ <p class="tw-text-sm tw-text-gray-600 tw-truncate tw-flex tw-items-center" title="${email}">
188
+ <svg class="tw-flex-shrink-0 tw-w-4 tw-h-4 tw-text-gray-400 tw-mr-2" fill="currentColor" viewBox="0 0 20 20">
189
+ <path d="M2.003 5.884L10 9.882l7.997-3.998A2 2 0 0016 4H4a2 2 0 00-1.997 1.884z"/>
190
+ <path d="M18 8.118l-8 4-8-4V14a2 2 0 002 2h12a2 2 0 002-2V8.118z"/>
191
+ </svg>
192
+ <span class="tw-truncate">${email}</span>
193
+ </p>
194
+ <p class="tw-text-sm tw-text-gray-600 tw-truncate tw-flex tw-items-center" title="${phone}">
195
+ <svg class="tw-flex-shrink-0 tw-w-4 tw-h-4 tw-text-gray-400 tw-mr-2" fill="currentColor" viewBox="0 0 20 20">
196
+ <path d="M2 3a1 1 0 011-1h2.153a1 1 0 01.986.836l.74 4.435a1 1 0 01-.54 1.06l-1.548.773a11.037 11.037 0 006.105 6.105l.774-1.548a1 1 0 011.059-.54l4.435.74a1 1 0 01.836.986V17a1 1 0 01-1 1h-2C7.82 18 2 12.18 2 5V3z"/>
197
+ </svg>
198
+ <span class="tw-truncate">${phone}</span>
199
+ </p>
200
+ </div>
201
+ `;
202
+ }
203
+ };
204
+ // Action handlers
205
+ this.actionHandlers = {
206
+ onEditEntity: (entity) => {
207
+ const query = generateStringFromObject({
208
+ syen_id: entity._id
209
+ });
210
+ this.router.navigate(['control-panel', 'entity-create', query]);
211
+ },
212
+ onDeleteEntity: (entity) => {
213
+ const entityName = entity.syen_name || 'this entity';
214
+ if (confirm(`Are you sure you want to delete ${entityName}?`)) {
215
+ this.onDeleteEntityConfirmed(entity._id || '');
216
+ }
217
+ }
218
+ };
219
+ }
220
+ // Getter and setter for ngModel compatibility
221
+ get selectedEntityTypeValue() {
222
+ return this.selectedEntityType();
223
+ }
224
+ set selectedEntityTypeValue(value) {
225
+ this.selectedEntityType.set(value);
226
+ }
227
+ ngOnInit() {
228
+ console.log('🔧 ENTITY LIST: Component initializing');
229
+ this.updatePaginationState();
230
+ // Set initial loading state to false to allow grid to render
231
+ this.loading.set(false);
232
+ // Load entities from API
233
+ this.loadEntities();
234
+ }
235
+ // Grid event handler
236
+ onGridEvent(event) {
237
+ console.log('📡 GRID EVENT: Received grid event:', event.type, event);
238
+ switch (event.type) {
239
+ case 'rowClick':
240
+ this.onEntityRowClick(event.data);
241
+ break;
242
+ case 'refresh':
243
+ this.onEntityRefresh();
244
+ break;
245
+ case 'search':
246
+ this.onEntitySearch(event.data);
247
+ break;
248
+ case 'pageChange':
249
+ this.onEntityPageChange(event.data);
250
+ break;
251
+ default:
252
+ console.log('Unhandled grid event:', event.type);
253
+ }
254
+ }
255
+ // Event handlers for grid events
256
+ onEntityRowClick(entity) {
257
+ console.log('Entity row clicked:', entity);
258
+ this.router.navigate(['admin', 'entity', 'view', entity._id]);
259
+ }
260
+ onEntityRefresh() {
261
+ console.log('Refreshing entities...');
262
+ this.loadEntities(true);
263
+ }
264
+ onEntitySearch(query) {
265
+ console.log('Search entities:', query);
266
+ this.searchQuery.set(query);
267
+ // The grid handles the actual filtering
268
+ }
269
+ onEntityPageChange(page) {
270
+ console.log('Page changed to:', page);
271
+ this.currentPage.set(page);
272
+ // Reload data for the new page
273
+ this.loadEntities(false);
274
+ }
275
+ onDeleteEntityConfirmed(entityId) {
276
+ // In a real app, you'd call the API to delete
277
+ console.log('Deleting entity:', entityId);
278
+ // For now, just reload the entities
279
+ this.loadEntities(true);
280
+ }
281
+ // Update grid data method
282
+ updateGridData(entities) {
283
+ console.log('📊 GRID UPDATE: Updating grid with', entities.length, 'entities');
284
+ console.log('📊 GRID UPDATE: Sample entity data:', entities[0] || 'No entities');
285
+ // Set the entities signal
286
+ this.entities.set(entities);
287
+ // Update grid configuration with new data and ensure loading is false
288
+ this.gridConfig.update(config => ({
289
+ ...config,
290
+ data: entities
291
+ }));
292
+ // Ensure loading states are cleared
293
+ this.loading.set(false);
294
+ // Clear page change loading state in the grid component
295
+ if (this.gridComponent) {
296
+ this.gridComponent.clearPageChangeLoading();
297
+ }
298
+ console.log('📊 GRID UPDATE: Grid config updated successfully');
299
+ console.log('📊 GRID UPDATE: Current grid data length:', this.gridConfig().data.length);
300
+ console.log('📊 GRID UPDATE: Loading state:', this.loading());
301
+ console.log('📊 GRID UPDATE: Full grid config for debugging:', JSON.stringify(this.gridConfig(), null, 2));
302
+ }
303
+ loadEntities(isRefresh = false) {
304
+ if (isRefresh) {
305
+ console.log('🔄 ENTITY LIST: Refreshing entities');
306
+ // Set the grid's refresh state to true
307
+ if (this.gridComponent) {
308
+ this.gridComponent.setRefreshing(true);
309
+ }
310
+ }
311
+ else {
312
+ this.loading.set(true);
313
+ console.log('🔍 ENTITY LIST: Loading entities from API');
314
+ }
315
+ this.error.set(null);
316
+ this.loadStartTime = Date.now();
317
+ this.entityService.getAllEntities().subscribe({
318
+ next: (response) => {
319
+ console.log('✅ ENTITY LIST: API response received:', response);
320
+ // Process the response data
321
+ if (response?.data) {
322
+ // Handle both array and single object responses
323
+ const entitiesData = Array.isArray(response.data) ? response.data : [response.data];
324
+ console.log('📋 ENTITY LIST: Processed entities data:', entitiesData.length, 'entities');
325
+ if (entitiesData.length > 0) {
326
+ console.log('📊 ENTITY LIST: First entity sample:', entitiesData[0]);
327
+ this.updateGridData(entitiesData);
328
+ this.totalItems.set(entitiesData.length);
329
+ }
330
+ else {
331
+ console.log('📊 ENTITY LIST: No entities returned, showing test data');
332
+ this.loadTestData();
333
+ }
334
+ }
335
+ else {
336
+ console.warn('⚠️ ENTITY LIST: No data in API response, loading test data');
337
+ this.loadTestData();
338
+ }
339
+ this.updatePaginationState();
340
+ this.loading.set(false);
341
+ // Clear page change loading state in the grid component
342
+ if (this.gridComponent) {
343
+ this.gridComponent.clearPageChangeLoading();
344
+ }
345
+ // Set the grid's refresh state to false when done
346
+ if (isRefresh && this.gridComponent) {
347
+ this.gridComponent.setRefreshing(false);
348
+ }
349
+ },
350
+ error: (err) => {
351
+ console.error('❌ ENTITY LIST: API error:', err);
352
+ console.log('🧪 ENTITY LIST: API failed, loading test data for demonstration');
353
+ // Load test data when API fails
354
+ this.loadTestData();
355
+ this.error.set('API unavailable. Showing sample data.');
356
+ this.loading.set(false);
357
+ // Clear page change loading state in the grid component
358
+ if (this.gridComponent) {
359
+ this.gridComponent.clearPageChangeLoading();
360
+ }
361
+ // Set the grid's refresh state to false when done
362
+ if (isRefresh && this.gridComponent) {
363
+ this.gridComponent.setRefreshing(false);
364
+ }
365
+ }
366
+ });
367
+ }
368
+ loadTestData() {
369
+ console.log('🧪 ENTITY LIST: Loading test data');
370
+ const testData = [
371
+ {
372
+ _id: 'test-1',
373
+ syen_name: 'Test University',
374
+ syen_entity_code: 'TEST001',
375
+ syen_corporate_email: 'test@university.com',
376
+ syen_corporate_contact_person_user: 'John Doe',
377
+ syen_corporate_phone: 9876543210, // Now a number
378
+ syen_isactive: true,
379
+ syen_entity_type_gmst: 'university',
380
+ children: []
381
+ },
382
+ {
383
+ _id: 'test-2',
384
+ syen_name: 'Sample College',
385
+ syen_entity_code: 'SAMP002',
386
+ syen_corporate_email: 'info@samplecollege.edu',
387
+ syen_corporate_contact_person_user: 'Jane Smith',
388
+ syen_corporate_phone: 9876543211,
389
+ syen_isactive: false,
390
+ syen_entity_type_gmst: 'college',
391
+ children: []
392
+ },
393
+ {
394
+ _id: 'test-3',
395
+ syen_name: 'Global Institute of Technology',
396
+ syen_entity_code: 'GIT003',
397
+ syen_corporate_email: 'admin@git.edu',
398
+ syen_corporate_contact_person_user: 'Bob Johnson',
399
+ syen_corporate_phone: 9876543212,
400
+ syen_isactive: true,
401
+ syen_entity_type_gmst: 'institute',
402
+ children: []
403
+ }
404
+ ];
405
+ console.log('🧪 ENTITY LIST: Test data prepared:', testData);
406
+ this.updateGridData(testData);
407
+ this.totalItems.set(testData.length);
408
+ }
409
+ updatePaginationState() {
410
+ const total = Math.ceil(this.totalItems() / this.pageSize());
411
+ this.totalPages.set(total);
412
+ this.hasNextPage.set(this.currentPage() < total);
413
+ this.hasPreviousPage.set(this.currentPage() > 1);
414
+ }
415
+ onSearch() {
416
+ this.currentPage.set(1);
417
+ this.loadEntities();
418
+ }
419
+ onFilterChange() {
420
+ this.currentPage.set(1);
421
+ this.loadEntities();
422
+ }
423
+ onPageChange(page) {
424
+ if (parseInt(page) >= 1 && parseInt(page) <= this.totalPages()) {
425
+ this.currentPage.set(parseInt(page));
426
+ this.loadEntities();
427
+ }
428
+ }
429
+ onPageSizeChange() {
430
+ this.currentPage.set(1);
431
+ this.loadEntities();
432
+ }
433
+ onRefresh() {
434
+ this.loadEntities(true); // Pass true for refresh
435
+ }
436
+ onAddEntity() {
437
+ // Navigate to entity create form
438
+ this.router.navigate(['/control-panel/entity-create']);
439
+ }
440
+ onEditEntity(entity) {
441
+ // TODO: Implement edit functionality - navigate to edit form with entity ID
442
+ this.router.navigate(['/control-panel/entity-create'], {
443
+ queryParams: { id: entity._id, mode: 'edit' }
444
+ });
445
+ console.log('Edit entity:', entity);
446
+ }
447
+ onViewEntity(entity) {
448
+ // TODO: Implement view functionality
449
+ console.log('View entity:', entity);
450
+ }
451
+ onDeleteEntity(entity) {
452
+ if (confirm(`Are you sure you want to delete "${entity.syen_name}"?`)) {
453
+ // TODO: Implement delete functionality
454
+ console.log('Delete entity:', entity);
455
+ }
456
+ }
457
+ getStatusClass(isActive) {
458
+ return isActive
459
+ ? 'tw-bg-green-100 tw-text-green-800'
460
+ : 'tw-bg-red-100 tw-text-red-800';
461
+ }
462
+ getStatusText(isActive) {
463
+ return isActive ? 'Active' : 'Inactive';
464
+ }
465
+ formatDate(date) {
466
+ if (!date)
467
+ return 'N/A';
468
+ return new Date(date).toLocaleDateString();
469
+ }
470
+ // Pagination helper methods
471
+ getPageNumbers() {
472
+ const total = this.totalPages();
473
+ const current = this.currentPage();
474
+ const delta = 2; // Number of pages to show on each side of current page
475
+ const pages = [];
476
+ const start = Math.max(1, current - delta);
477
+ const end = Math.min(total, current + delta);
478
+ for (let i = start; i <= end; i++) {
479
+ pages.push(i);
480
+ }
481
+ return pages;
482
+ }
483
+ getItemRangeText() {
484
+ const start = (this.currentPage() - 1) * this.pageSize() + 1;
485
+ const end = Math.min(this.currentPage() * this.pageSize(), this.totalItems());
486
+ const total = this.totalItems();
487
+ return `${start}-${end} of ${total}`;
488
+ }
489
+ trackByEntityId(index, entity) {
490
+ return entity?._id || '';
491
+ }
492
+ // ===== Enhanced Pagination Methods =====
493
+ /**
494
+ * Get enhanced page numbers with ellipsis for better navigation
495
+ */
496
+ getEnhancedPageNumbers() {
497
+ const total = this.totalPages();
498
+ const current = this.currentPage();
499
+ const pages = [];
500
+ if (total <= 7) {
501
+ // Show all pages if 7 or fewer
502
+ for (let i = 1; i <= total; i++) {
503
+ pages.push(i);
504
+ }
505
+ }
506
+ else {
507
+ // Always show first page
508
+ pages.push(1);
509
+ if (current <= 4) {
510
+ // Current page is near the beginning
511
+ for (let i = 2; i <= 5; i++) {
512
+ pages.push(i);
513
+ }
514
+ pages.push('...');
515
+ pages.push(total);
516
+ }
517
+ else if (current >= total - 3) {
518
+ // Current page is near the end
519
+ pages.push('...');
520
+ for (let i = total - 4; i <= total; i++) {
521
+ pages.push(i);
522
+ }
523
+ }
524
+ else {
525
+ // Current page is in the middle
526
+ pages.push('...');
527
+ for (let i = current - 1; i <= current + 1; i++) {
528
+ pages.push(i);
529
+ }
530
+ pages.push('...');
531
+ pages.push(total);
532
+ }
533
+ }
534
+ return pages;
535
+ }
536
+ /**
537
+ * Calculate progress percentage based on current position
538
+ */
539
+ getProgressPercentage() {
540
+ if (this.totalPages() === 0)
541
+ return 0;
542
+ return Math.round((this.currentPage() / this.totalPages()) * 100);
543
+ }
544
+ /**
545
+ * Jump to specific page functionality
546
+ */
547
+ onJumpToPage() {
548
+ if (this.jumpToPage >= 1 && this.jumpToPage <= this.totalPages()) {
549
+ this.onPageChange(this.jumpToPage);
550
+ }
551
+ }
552
+ /**
553
+ * Get simulated load time for performance display
554
+ */
555
+ getLoadTime() {
556
+ return this.loadStartTime > 0 ? Date.now() - this.loadStartTime : 0;
557
+ }
558
+ /**
559
+ * Get total data size for display
560
+ */
561
+ getTotalDataSize() {
562
+ return this.totalItems();
563
+ }
564
+ /**
565
+ * Export current page entities
566
+ */
567
+ onExportCurrentPage() {
568
+ const currentPageEntities = this.entities();
569
+ console.log('Exporting current page:', currentPageEntities);
570
+ // TODO: Implement actual export functionality
571
+ alert(`Exporting ${currentPageEntities.length} entities from current page`);
572
+ }
573
+ /**
574
+ * Export all entities
575
+ */
576
+ onExportAll() {
577
+ console.log('Exporting all entities');
578
+ // TODO: Implement actual export functionality
579
+ alert(`Exporting all ${this.totalItems()} entities`);
580
+ }
581
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: CideAdmEntityListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
582
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.7", type: CideAdmEntityListComponent, isStandalone: true, selector: "cide-adm-entity-list", viewQueries: [{ propertyName: "gridComponent", first: true, predicate: CideEleDataGridComponent, descendants: true }], ngImport: i0, template: "<!-- Entity List Container -->\n<div class=\"entity-list-container tw-bg-white tw-shadow-lg tw-rounded-lg tw-overflow-hidden\">\n \n <!-- Header Section with Filters -->\n <div class=\"tw-px-6 tw-py-4 tw-border-b tw-border-gray-200 tw-bg-gray-50\">\n <div class=\"tw-flex tw-flex-col sm:tw-flex-row tw-justify-between tw-items-start sm:tw-items-center tw-space-y-4 sm:tw-space-y-0\">\n \n <!-- Title -->\n <div class=\"tw-flex tw-items-center tw-space-x-3\">\n <cide-ele-icon class=\"tw-text-blue-600\">apartment</cide-ele-icon>\n <div>\n <h5 class=\"tw-text-md tw-font-semibold tw-text-gray-900\">Entity Management</h5>\n <p class=\"tw-text-sm tw-text-gray-600\">Manage and view all entities in the system</p>\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"tw-flex tw-items-center tw-space-x-3\">\n <!-- Entity Type Filter -->\n <div class=\"tw-flex tw-items-center tw-space-x-2\">\n <label for=\"entityTypeFilter\" class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Type:</label>\n <cide-ele-select\n id=\"entityTypeFilter\"\n [options]=\"entityTypeOptions()\"\n [(ngModel)]=\"selectedEntityTypeValue\"\n (ngModelChange)=\"loadEntities()\"\n class=\"tw-min-w-40\">\n </cide-ele-select>\n </div>\n\n <!-- Add Entity Button -->\n <button\n cideEleButton\n variant=\"primary\"\n size=\"sm\"\n (click)=\"router.navigate(['control-panel', 'entity-create'])\"\n class=\"tw-whitespace-nowrap tw-flex tw-items-center tw-gap-2\">\n <cide-ele-icon size=\"xs\" class=\"tw-w-6 tw-h-5\">add</cide-ele-icon>\n Add Entity\n </button>\n </div>\n </div>\n\n <!-- Error Message -->\n @if (error()) {\n <div class=\"tw-mt-4 tw-p-4 tw-bg-red-50 tw-border tw-border-red-200 tw-rounded-md\">\n <div class=\"tw-flex\">\n <cide-ele-icon name=\"exclamation-triangle\" class=\"tw-text-red-400\"></cide-ele-icon>\n <div class=\"tw-ml-3\">\n <h3 class=\"tw-text-sm tw-font-medium tw-text-red-800\">Error</h3>\n <p class=\"tw-text-sm tw-text-red-700 tw-mt-1\">{{ error() }}</p>\n </div>\n </div>\n </div>\n }\n </div>\n\n <!-- Data Grid Component -->\n <cide-ele-data-grid\n [config]=\"gridConfig()\"\n [customRenderers]=\"customRenderers\"\n [actionHandlers]=\"actionHandlers\"\n (gridEvent)=\"onGridEvent($event)\">\n </cide-ele-data-grid>\n\n</div>", styles: [".entity-list-container table tr{transition:background-color .15s ease}.entity-list-container table th{font-weight:600;letter-spacing:.025em}.entity-list-container table td{vertical-align:top}.entity-list-container .tw-text-red-600:hover{background-color:theme(\"colors.red.50\")}.entity-list-container .tw-animate-spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.entity-list-container .tw-overflow-x-auto{scrollbar-width:thin;scrollbar-color:theme(\"colors.gray.300\") theme(\"colors.gray.100\")}.entity-list-container .tw-overflow-x-auto::-webkit-scrollbar{height:8px}.entity-list-container .tw-overflow-x-auto::-webkit-scrollbar-track{background:theme(\"colors.gray.100\");border-radius:4px}.entity-list-container .tw-overflow-x-auto::-webkit-scrollbar-thumb{background:theme(\"colors.gray.300\");border-radius:4px}.entity-list-container .tw-overflow-x-auto::-webkit-scrollbar-thumb:hover{background:theme(\"colors.gray.400\")}@media (max-width: 768px){.entity-list-container .tw-px-6{padding-left:theme(\"spacing.4\");padding-right:theme(\"spacing.4\")}}\n", ":host{height:100%;display:flex;flex-direction:column}.entity-list-container{height:100%;display:flex;flex-direction:column;overflow:hidden}.tw-overflow-auto{flex:1;min-height:0}cide-ele-data-grid{flex:1;min-height:0;display:flex;flex-direction:column}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: CideIconComponent, selector: "cide-ele-icon", inputs: ["size", "type", "toolTip"] }, { kind: "component", type: CideEleButtonComponent, selector: "button[cideEleButton], a[cideEleButton]", inputs: ["label", "variant", "size", "type", "shape", "elevation", "disabled", "id", "loading", "fullWidth", "leftIcon", "rightIcon", "customClass", "tooltip", "ariaLabel", "testId", "routerLink", "routerExtras", "preventDoubleClick", "animated"], outputs: ["btnClick", "doubleClick"] }, { kind: "component", type: CideSelectComponent, selector: "cide-ele-select", inputs: ["label", "labelHide", "placeholder", "helperText", "errorText", "required", "disabled", "id", "ngModel", "size", "fill", "labelPlacement", "labelDir", "leadingIcon", "trailingIcon", "clearInput", "options", "multiple", "searchable", "showSearchInput", "loading"], outputs: ["ngModelChange", "change", "searchChange"] }, { kind: "component", type: CideEleDataGridComponent, selector: "cide-ele-data-grid", inputs: ["config", "customRenderers", "templateRenderers", "customFormatters", "actionHandlers", "serverSidePagination", "totalServerItems", "currentServerPage", "currentServerPageSize", "dragDropEnabled"], outputs: ["gridEvent"] }] }); }
583
+ }
584
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImport: i0, type: CideAdmEntityListComponent, decorators: [{
585
+ type: Component,
586
+ args: [{ selector: 'cide-adm-entity-list', standalone: true, imports: [
587
+ CommonModule,
588
+ FormsModule,
589
+ CideInputComponent,
590
+ CideIconComponent,
591
+ CideEleButtonComponent,
592
+ CideSelectComponent,
593
+ TooltipDirective,
594
+ CideEleDataGridComponent
595
+ ], template: "<!-- Entity List Container -->\n<div class=\"entity-list-container tw-bg-white tw-shadow-lg tw-rounded-lg tw-overflow-hidden\">\n \n <!-- Header Section with Filters -->\n <div class=\"tw-px-6 tw-py-4 tw-border-b tw-border-gray-200 tw-bg-gray-50\">\n <div class=\"tw-flex tw-flex-col sm:tw-flex-row tw-justify-between tw-items-start sm:tw-items-center tw-space-y-4 sm:tw-space-y-0\">\n \n <!-- Title -->\n <div class=\"tw-flex tw-items-center tw-space-x-3\">\n <cide-ele-icon class=\"tw-text-blue-600\">apartment</cide-ele-icon>\n <div>\n <h5 class=\"tw-text-md tw-font-semibold tw-text-gray-900\">Entity Management</h5>\n <p class=\"tw-text-sm tw-text-gray-600\">Manage and view all entities in the system</p>\n </div>\n </div>\n\n <!-- Actions -->\n <div class=\"tw-flex tw-items-center tw-space-x-3\">\n <!-- Entity Type Filter -->\n <div class=\"tw-flex tw-items-center tw-space-x-2\">\n <label for=\"entityTypeFilter\" class=\"tw-text-sm tw-font-medium tw-text-gray-700\">Type:</label>\n <cide-ele-select\n id=\"entityTypeFilter\"\n [options]=\"entityTypeOptions()\"\n [(ngModel)]=\"selectedEntityTypeValue\"\n (ngModelChange)=\"loadEntities()\"\n class=\"tw-min-w-40\">\n </cide-ele-select>\n </div>\n\n <!-- Add Entity Button -->\n <button\n cideEleButton\n variant=\"primary\"\n size=\"sm\"\n (click)=\"router.navigate(['control-panel', 'entity-create'])\"\n class=\"tw-whitespace-nowrap tw-flex tw-items-center tw-gap-2\">\n <cide-ele-icon size=\"xs\" class=\"tw-w-6 tw-h-5\">add</cide-ele-icon>\n Add Entity\n </button>\n </div>\n </div>\n\n <!-- Error Message -->\n @if (error()) {\n <div class=\"tw-mt-4 tw-p-4 tw-bg-red-50 tw-border tw-border-red-200 tw-rounded-md\">\n <div class=\"tw-flex\">\n <cide-ele-icon name=\"exclamation-triangle\" class=\"tw-text-red-400\"></cide-ele-icon>\n <div class=\"tw-ml-3\">\n <h3 class=\"tw-text-sm tw-font-medium tw-text-red-800\">Error</h3>\n <p class=\"tw-text-sm tw-text-red-700 tw-mt-1\">{{ error() }}</p>\n </div>\n </div>\n </div>\n }\n </div>\n\n <!-- Data Grid Component -->\n <cide-ele-data-grid\n [config]=\"gridConfig()\"\n [customRenderers]=\"customRenderers\"\n [actionHandlers]=\"actionHandlers\"\n (gridEvent)=\"onGridEvent($event)\">\n </cide-ele-data-grid>\n\n</div>", styles: [".entity-list-container table tr{transition:background-color .15s ease}.entity-list-container table th{font-weight:600;letter-spacing:.025em}.entity-list-container table td{vertical-align:top}.entity-list-container .tw-text-red-600:hover{background-color:theme(\"colors.red.50\")}.entity-list-container .tw-animate-spin{animation:spin 1s linear infinite}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.entity-list-container .tw-overflow-x-auto{scrollbar-width:thin;scrollbar-color:theme(\"colors.gray.300\") theme(\"colors.gray.100\")}.entity-list-container .tw-overflow-x-auto::-webkit-scrollbar{height:8px}.entity-list-container .tw-overflow-x-auto::-webkit-scrollbar-track{background:theme(\"colors.gray.100\");border-radius:4px}.entity-list-container .tw-overflow-x-auto::-webkit-scrollbar-thumb{background:theme(\"colors.gray.300\");border-radius:4px}.entity-list-container .tw-overflow-x-auto::-webkit-scrollbar-thumb:hover{background:theme(\"colors.gray.400\")}@media (max-width: 768px){.entity-list-container .tw-px-6{padding-left:theme(\"spacing.4\");padding-right:theme(\"spacing.4\")}}\n", ":host{height:100%;display:flex;flex-direction:column}.entity-list-container{height:100%;display:flex;flex-direction:column;overflow:hidden}.tw-overflow-auto{flex:1;min-height:0}cide-ele-data-grid{flex:1;min-height:0;display:flex;flex-direction:column}\n"] }]
596
+ }], propDecorators: { gridComponent: [{
597
+ type: ViewChild,
598
+ args: [CideEleDataGridComponent]
599
+ }] } });
600
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2lkZS1hZG0tZW50aXR5LWxpc3QuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY2xvdWQtaWRlLWFkbWluL3NyYy9saWIvYWRtaW4tbW9kdWxlL2VudGl0eS9saXN0L2NpZGUtYWRtLWVudGl0eS1saXN0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Nsb3VkLWlkZS1hZG1pbi9zcmMvbGliL2FkbWluLW1vZHVsZS9lbnRpdHkvbGlzdC9jaWRlLWFkbS1lbnRpdHktbGlzdC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBVSxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzdFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ3pDLE9BQU8sRUFDTCxrQkFBa0IsRUFDbEIsaUJBQWlCLEVBQ2pCLGdCQUFnQixFQUNqQixNQUFNLG1CQUFtQixDQUFDO0FBQzNCLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2hGLE9BQU8sRUFBRSx3QkFBd0IsRUFBK0IsTUFBTSxtQkFBbUIsQ0FBQztBQUMxRixPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUMxRSxPQUFPLEVBQWdELHdCQUF3QixFQUFFLE1BQU0scUJBQXFCLENBQUM7OztBQTZDN0csTUFBTSxPQUFPLDBCQUEwQjtJQTFDdkM7UUEyQ0UsNkNBQTZDO1FBQzdDLFdBQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBRSxrQ0FB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IHNpZ25hbCwgT25Jbml0LCBpbmplY3QsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcbmltcG9ydCB7XG4gIENpZGVJbnB1dENvbXBvbmVudCxcbiAgQ2lkZUljb25Db21wb25lbnQsXG4gIFRvb2x0aXBEaXJlY3RpdmVcbn0gZnJvbSAnY2xvdWQtaWRlLWVsZW1lbnQnO1xuaW1wb3J0IHsgQ2lkZUVsZUJ1dHRvbkNvbXBvbmVudCwgQ2lkZVNlbGVjdENvbXBvbmVudCB9IGZyb20gJ2Nsb3VkLWlkZS1lbGVtZW50JztcbmltcG9ydCB7IENpZGVFbGVEYXRhR3JpZENvbXBvbmVudCAsR3JpZENvbmZpZ3VyYXRpb24sIEdyaWRFdmVudH0gZnJvbSAnY2xvdWQtaWRlLWVsZW1lbnQnO1xuaW1wb3J0IHsgQ2lkZUFkbUVudGl0eUxpc3RTZXJ2aWNlIH0gZnJvbSAnLi9jaWRlLWFkbS1lbnRpdHktbGlzdC5zZXJ2aWNlJztcbmltcG9ydCB7IGVudGl0eUNvbnRyb2xsZXJSZXNwb25zZSwgZW50aXR5UmVzcG9uc2VEYXRhLCBnZW5lcmF0ZVN0cmluZ0Zyb21PYmplY3QgfSBmcm9tICdjbG91ZC1pZGUtbG1zLW1vZGVsJztcblxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjaWRlLWFkbS1lbnRpdHktbGlzdCcsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBDb21tb25Nb2R1bGUsXG4gICAgRm9ybXNNb2R1bGUsXG4gICAgQ2lkZUlucHV0Q29tcG9uZW50LFxuICAgIENpZGVJY29uQ29tcG9uZW50LFxuICAgIENpZGVFbGVCdXR0b25Db21wb25lbnQsXG4gICAgQ2lkZVNlbGVjdENvbXBvbmVudCxcbiAgICBUb29sdGlwRGlyZWN0aXZlLFxuICAgIENpZGVFbGVEYXRhR3JpZENvbXBvbmVudFxuICBdLFxuICB0ZW1wbGF0ZVVybDogJy4vY2lkZS1hZG0tZW50aXR5LWxpc3QuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybDogJy4vY2lkZS1hZG0tZW50aXR5LWxpc3QuY29tcG9uZW50LnNjc3MnLFxuICBzdHlsZXM6IFtgXG4gICAgOmhvc3Qge1xuICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgfVxuICAgIFxuICAgIC5lbnRpdHktbGlzdC1jb250YWluZXIge1xuICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICBvdmVyZmxvdzogaGlkZGVuO1xuICAgIH1cbiAgICBcbiAgICAudHctb3ZlcmZsb3ctYXV0byB7XG4gICAgICBmbGV4OiAxO1xuICAgICAgbWluLWhlaWdodDogMDtcbiAgICB9XG4gICAgXG4gICAgY2lkZS1lbGUtZGF0YS1ncmlkIHtcbiAgICAgIGZsZXg6IDE7XG4gICAgICBtaW4taGVpZ2h0OiAwO1xuICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgfVxuICBgXVxufSlcbmV4cG9ydCBjbGFzcyBDaWRlQWRtRW50aXR5TGlzdENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIC8vIE1vZGVybiBkZXBlbmRlbmN5IGluamVjdGlvbiB1c2luZyBpbmplY3QoKVxuICByb3V0ZXIgPSBpbmplY3QoUm91dGVyKTsgIC8vIE1hZGUgcHVibGljIGZvciB0ZW1wbGF0ZSBhY2Nlc3NcbiAgcHJpdmF0ZSBlbnRpdHlTZXJ2aWNlID0gaW5qZWN0KENpZGVBZG1FbnRpdHlMaXN0U2VydmljZSk7XG5cbiAgLy8gVmlld0NoaWxkIHJlZmVyZW5jZSB0byB0aGUgZ3JpZCBjb21wb25lbnRcbiAgQFZpZXdDaGlsZChDaWRlRWxlRGF0YUdyaWRDb21wb25lbnQpIGdyaWRDb21wb25lbnQhOiBDaWRlRWxlRGF0YUdyaWRDb21wb25lbnQ8ZW50aXR5UmVzcG9uc2VEYXRhPjtcblxuICAvLyBTdGF0ZSBtYW5hZ2VtZW50IHVzaW5nIEFuZ3VsYXIgU2lnbmFsc1xuICBlbnRpdGllcyA9IHNpZ25hbDxlbnRpdHlSZXNwb25zZURhdGFbXT4oW10pO1xuICBsb2FkaW5nID0gc2lnbmFsKGZhbHNlKTtcbiAgZXJyb3IgPSBzaWduYWw8c3RyaW5nIHwgbnVsbD4obnVsbCk7XG4gIHNlYXJjaFF1ZXJ5ID0gc2lnbmFsKCcnKTtcbiAgY3VycmVudFBhZ2UgPSBzaWduYWwoMSk7XG4gIHBhZ2VTaXplID0gc2lnbmFsKDEwKTtcbiAgdG90YWxJdGVtcyA9IHNpZ25hbCgwKTtcbiAgc2VsZWN0ZWRFbnRpdHlUeXBlID0gc2lnbmFsKCcnKTtcblxuICAvLyBHZXR0ZXIgYW5kIHNldHRlciBmb3IgbmdNb2RlbCBjb21wYXRpYmlsaXR5XG4gIGdldCBzZWxlY3RlZEVudGl0eVR5cGVWYWx1ZSgpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnNlbGVjdGVkRW50aXR5VHlwZSgpO1xuICB9XG5cbiAgc2V0IHNlbGVjdGVkRW50aXR5VHlwZVZhbHVlKHZhbHVlOiBzdHJpbmcpIHtcbiAgICB0aGlzLnNlbGVjdGVkRW50aXR5VHlwZS5zZXQodmFsdWUpO1xuICB9XG5cbiAgLy8gUGFnaW5hdGlvbiBjYWxjdWxhdGlvbnNcbiAgdG90YWxQYWdlcyA9IHNpZ25hbCgwKTtcbiAgaGFzTmV4dFBhZ2UgPSBzaWduYWwoZmFsc2UpO1xuICBoYXNQcmV2aW91c1BhZ2UgPSBzaWduYWwoZmFsc2UpO1xuICBqdW1wVG9QYWdlOiBudW1iZXIgPSAxO1xuICBsb2FkU3RhcnRUaW1lOiBudW1iZXIgPSAwO1xuXG4gIC8vIEZpbHRlciBvcHRpb25zXG4gIGVudGl0eVR5cGVPcHRpb25zID0gc2lnbmFsKFtcbiAgICB7IHZhbHVlOiAnJywgbGFiZWw6ICdBbGwgRW50aXR5IFR5cGVzJyB9LFxuICAgIHsgdmFsdWU6ICdzY2hvb2wnLCBsYWJlbDogJ1NjaG9vbCcgfSxcbiAgICB7IHZhbHVlOiAnY29sbGVnZScsIGxhYmVsOiAnQ29sbGVnZScgfSxcbiAgICB7IHZhbHVlOiAndW5pdmVyc2l0eScsIGxhYmVsOiAnVW5pdmVyc2l0eScgfSxcbiAgICB7IHZhbHVlOiAnaW5zdGl0dXRlJywgbGFiZWw6ICdJbnN0aXR1dGUnIH1cbiAgXSk7XG5cbiAgLy8gR3JpZCBjb25maWd1cmF0aW9uIHNpZ25hbFxuICBncmlkQ29uZmlnID0gc2lnbmFsPEdyaWRDb25maWd1cmF0aW9uPGVudGl0eVJlc3BvbnNlRGF0YT4+KHtcbiAgICBpZDogJ2VudGl0eS1saXN0LWdyaWQnLFxuICAgIHRpdGxlOiAnJyxcbiAgICBzdWJ0aXRsZTogJycsXG4gICAgY29sdW1uczogW1xuICAgICAge1xuICAgICAgICBrZXk6ICdkZXRhaWxzJyxcbiAgICAgICAgaGVhZGVyOiAnRW50aXR5IERldGFpbHMnLFxuICAgICAgICB0eXBlOiAnY3VzdG9tJyxcbiAgICAgICAgd2lkdGg6ICdsZycsXG4gICAgICAgIHRydW5jYXRlOiB0cnVlLFxuICAgICAgICBhbGlnbjogJ2xlZnQnLFxuICAgICAgICByZW5kZXJlcjogJ2VudGl0eURldGFpbHNSZW5kZXJlcidcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGtleTogJ2NvbnRhY3QnLFxuICAgICAgICBoZWFkZXI6ICdDb250YWN0IEluZm9ybWF0aW9uJyxcbiAgICAgICAgdHlwZTogJ2N1c3RvbScsXG4gICAgICAgIHdpZHRoOiAnbGcnLFxuICAgICAgICB0cnVuY2F0ZTogdHJ1ZSxcbiAgICAgICAgYWxpZ246ICdsZWZ0JyxcbiAgICAgICAgcmVuZGVyZXI6ICdjb250YWN0SW5mb1JlbmRlcmVyJ1xuICAgICAgfSxcbiAgICAgIHtcbiAgICAgICAga2V5OiAnc3llbl9pc2FjdGl2ZScsXG4gICAgICAgIGhlYWRlcjogJ1N0YXR1cycsXG4gICAgICAgIHR5cGU6ICdzdGF0dXMnLFxuICAgICAgICB3aWR0aDogJ21kJyxcbiAgICAgICAgdHJ1bmNhdGU6IGZhbHNlLFxuICAgICAgICBhbGlnbjogJ2NlbnRlcicsXG4gICAgICAgIHN0YXR1c0NvbmZpZzoge1xuICAgICAgICAgIGFjdGl2ZVZhbHVlOiB0cnVlLFxuICAgICAgICAgIGFjdGl2ZUxhYmVsOiAnQWN0aXZlJyxcbiAgICAgICAgICBpbmFjdGl2ZUxhYmVsOiAnSW5hY3RpdmUnLFxuICAgICAgICAgIGFjdGl2ZUNsYXNzOiAndHctYmctZ3JlZW4tMTAwIHR3LXRleHQtZ3JlZW4tODAwJyxcbiAgICAgICAgICBpbmFjdGl2ZUNsYXNzOiAndHctYmctcmVkLTEwMCB0dy10ZXh0LXJlZC04MDAnXG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGtleTogJ3N5ZW5fZW50aXR5X3R5cGVfZ21zdCcsXG4gICAgICAgIGhlYWRlcjogJ0VudGl0eSBUeXBlJyxcbiAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICB3aWR0aDogJ21kJyxcbiAgICAgICAgdHJ1bmNhdGU6IGZhbHNlLFxuICAgICAgICBhbGlnbjogJ2NlbnRlcidcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIGtleTogJ2FjdGlvbnMnLFxuICAgICAgICBoZWFkZXI6ICdBY3Rpb25zJyxcbiAgICAgICAgdHlwZTogJ2FjdGlvbnMnLFxuICAgICAgICB3aWR0aDogJ21kJyxcbiAgICAgICAgdHJ1bmNhdGU6IGZhbHNlLFxuICAgICAgICBhbGlnbjogJ3JpZ2h0JyxcbiAgICAgICAgYWN0aW9uczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIGtleTogJ2VkaXQnLFxuICAgICAgICAgICAgbGFiZWw6ICdFZGl0JyxcbiAgICAgICAgICAgIGljb246ICdwZW5jaWwnLFxuICAgICAgICAgICAgdmFyaWFudDogJ291dGxpbmUnLFxuICAgICAgICAgICAgdG9vbHRpcDogJ0VkaXQgZW50aXR5JyxcbiAgICAgICAgICAgIG9uQ2xpY2s6ICdvbkVkaXRFbnRpdHknXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBrZXk6ICdkZWxldGUnLFxuICAgICAgICAgICAgbGFiZWw6ICdEZWxldGUnLFxuICAgICAgICAgICAgaWNvbjogJ3RyYXNoJyxcbiAgICAgICAgICAgIHZhcmlhbnQ6ICdkYW5nZXInLFxuICAgICAgICAgICAgdG9vbHRpcDogJ0RlbGV0ZSBlbnRpdHknLFxuICAgICAgICAgICAgb25DbGljazogJ29uRGVsZXRlRW50aXR5J1xuICAgICAgICAgIH1cbiAgICAgICAgXVxuICAgICAgfVxuICAgIF0sXG4gICAgZGF0YTogW10sXG4gICAgdHJhY2tCeTogJ19pZCcsXG4gICAgcGFnaW5hdGlvbjoge1xuICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgIHBhZ2VTaXplOiAxMCxcbiAgICAgIHBhZ2VTaXplT3B0aW9uczogWzEwLCAyNSwgNTAsIDEwMF0sXG4gICAgICBzaG93UXVpY2tKdW1wOiB0cnVlLFxuICAgICAgc2hvd1BhZ2VJbmZvOiB0cnVlLFxuICAgICAgc2hvd1JlZnJlc2g6IHRydWVcbiAgICB9LFxuICAgIHNlYXJjaDoge1xuICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgIHBsYWNlaG9sZGVyOiAnU2VhcmNoIGVudGl0aWVzLi4uJyxcbiAgICAgIHNlYXJjaGFibGVDb2x1bW5zOiBbJ3N5ZW5fbmFtZScsICdzeWVuX2VudGl0eV9jb2RlJywgJ3N5ZW5fY29ycG9yYXRlX2VtYWlsJ10sXG4gICAgICBkZWJvdW5jZU1zOiAzMDBcbiAgICB9LFxuICAgIGxvYWRpbmc6IHtcbiAgICAgIHVzZURlZmVyOiB0cnVlLFxuICAgICAgc2tlbGV0b25Sb3dzOiA1LFxuICAgICAgc2hvd092ZXJsYXk6IGZhbHNlXG4gICAgfSxcbiAgICByZXNwb25zaXZlOiB0cnVlLFxuICAgIHN0cmlwZWQ6IGZhbHNlLFxuICAgIGJvcmRlcmVkOiB0cnVlLFxuICAgIGNvbXBhY3Q6IGZhbHNlLFxuICAgIGZ1bGxIZWlnaHQ6IHRydWUsXG4gICAgb25Sb3dDbGljazogJ29uRW50aXR5Um93Q2xpY2snLFxuICAgIG9uUmVmcmVzaDogJ29uRW50aXR5UmVmcmVzaCcsXG4gICAgdHJlZToge1xuICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgIHByaW1hcnlLZXk6ICdfaWQnLFxuICAgICAgZm9yZWlnbktleTogJ3N5ZW5fcGFyZW50X2VudGl0eV9pZCcsXG4gICAgICBjaGlsZHJlbktleTogJ2NoaWxkcmVuJyxcbiAgICAgIGxldmVsS2V5OiAnbGV2ZWwnLFxuICAgICAgZXhwYW5kZWRLZXk6ICdpc0V4cGFuZGVkJyxcbiAgICAgIGhhc0NoaWxkcmVuS2V5OiAnaGFzQ2hpbGRyZW4nXG4gICAgfVxuICB9KTtcblxuICAvLyBDdXN0b20gcmVuZGVyZXJzIGZvciBjb21wbGV4IGNvbHVtbnNcbiAgY3VzdG9tUmVuZGVyZXJzID0ge1xuICAgIGVudGl0eURldGFpbHNSZW5kZXJlcjogKHZhbHVlOiB1bmtub3duLCByb3c6IGVudGl0eVJlc3BvbnNlRGF0YSk6IHN0cmluZyA9PiB7XG4gICAgICBjb25zdCBlbnRpdHlDb2RlID0gcm93LnN5ZW5fZW50aXR5X2NvZGUgfHwgJ04vQSc7XG4gICAgICBjb25zdCBlbnRpdHlOYW1lID0gcm93LnN5ZW5fbmFtZSB8fCAnVW5rbm93biBFbnRpdHknO1xuXG4gICAgICByZXR1cm4gYFxuICAgICAgICA8ZGl2IGNsYXNzPVwidHctZmxleCB0dy1pdGVtcy1jZW50ZXIgdHctc3BhY2UteC0zXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInR3LWZsZXgtc2hyaW5rLTAgdHctdy0xMCB0dy1oLTEwIHR3LWJnLWJsdWUtMTAwIHR3LXJvdW5kZWQtZnVsbCB0dy1mbGV4IHR3LWl0ZW1zLWNlbnRlciB0dy1qdXN0aWZ5LWNlbnRlclwiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0dy10ZXh0LWJsdWUtNjAwIHR3LWZvbnQtc2VtaWJvbGQgdHctdGV4dC1zbVwiPlxuICAgICAgICAgICAgICAke2VudGl0eUNvZGUuc3Vic3RyaW5nKDAsIDIpLnRvVXBwZXJDYXNlKCl9XG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInR3LWZsZXgtMSB0dy1taW4tdy0wXCI+XG4gICAgICAgICAgICA8cCBjbGFzcz1cInR3LXRleHQtc20gdHctZm9udC1tZWRpdW0gdHctdGV4dC1ncmF5LTkwMCB0dy10cnVuY2F0ZVwiIHRpdGxlPVwiJHtlbnRpdHlOYW1lfVwiPlxuICAgICAgICAgICAgICAke2VudGl0eU5hbWV9XG4gICAgICAgICAgICA8L3A+XG4gICAgICAgICAgICA8cCBjbGFzcz1cInR3LXRleHQtc20gdHctdGV4dC1ncmF5LTUwMCB0dy10cnVuY2F0ZVwiIHRpdGxlPVwiJHtlbnRpdHlDb2RlfVwiPlxuICAgICAgICAgICAgICBDb2RlOiAke2VudGl0eUNvZGV9XG4gICAgICAgICAgICA8L3A+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgYDtcbiAgICB9LFxuXG4gICAgY29udGFjdEluZm9SZW5kZXJlcjogKHZhbHVlOiB1bmtub3duLCByb3c6IGVudGl0eVJlc3BvbnNlRGF0YSk6IHN0cmluZyA9PiB7XG4gICAgICBjb25zdCBjb250YWN0UGVyc29uID0gcm93LnN5ZW5fY29ycG9yYXRlX2NvbnRhY3RfcGVyc29uX3VzZXIgfHwgJ04vQSc7XG4gICAgICBjb25zdCBlbWFpbCA9IHJvdy5zeWVuX2NvcnBvcmF0ZV9lbWFpbCB8fCAnTi9BJztcbiAgICAgIGNvbnN0IHBob25lID0gcm93LnN5ZW5fY29ycG9yYXRlX3Bob25lID8gU3RyaW5nKHJvdy5zeWVuX2NvcnBvcmF0ZV9waG9uZSkgOiAnTi9BJztcblxuICAgICAgcmV0dXJuIGBcbiAgICAgICAgPGRpdiBjbGFzcz1cInR3LXNwYWNlLXktMVwiPlxuICAgICAgICAgIDxwIGNsYXNzPVwidHctdGV4dC1zbSB0dy10ZXh0LWdyYXktOTAwIHR3LXRydW5jYXRlIHR3LWZsZXggdHctaXRlbXMtY2VudGVyXCIgdGl0bGU9XCIke2NvbnRhY3RQZXJzb259XCI+XG4gICAgICAgICAgICA8c3ZnIGNsYXNzPVwidHctZmxleC1zaHJpbmstMCB0dy13LTQgdHctaC00IHR3LXRleHQtZ3JheS00MDAgdHctbXItMlwiIGZpbGw9XCJjdXJyZW50Q29sb3JcIiB2aWV3Qm94PVwiMCAwIDIwIDIwXCI+XG4gICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMTAgOWEzIDMgMCAxMDAtNiAzIDMgMCAwMDAgNnptLTcgOWE3IDcgMCAxMTE0IDBIM3pcIi8+XG4gICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwidHctdHJ1bmNhdGVcIj4ke2NvbnRhY3RQZXJzb259PC9zcGFuPlxuICAgICAgICAgIDwvcD5cbiAgICAgICAgICA8cCBjbGFzcz1cInR3LXRleHQtc20gdHctdGV4dC1ncmF5LTYwMCB0dy10cnVuY2F0ZSB0dy1mbGV4IHR3LWl0ZW1zLWNlbnRlclwiIHRpdGxlPVwiJHtlbWFpbH1cIj5cbiAgICAgICAgICAgIDxzdmcgY2xhc3M9XCJ0dy1mbGV4LXNocmluay0wIHR3LXctNCB0dy1oLTQgdHctdGV4dC1ncmF5LTQwMCB0dy1tci0yXCIgZmlsbD1cImN1cnJlbnRDb2xvclwiIHZpZXdCb3g9XCIwIDAgMjAgMjBcIj5cbiAgICAgICAgICAgICAgPHBhdGggZD1cIk0yLjAwMyA1Ljg4NEwxMCA5Ljg4Mmw3Ljk5Ny0zLjk5OEEyIDIgMCAwMDE2IDRINGEyIDIgMCAwMC0xLjk5NyAxLjg4NHpcIi8+XG4gICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMTggOC4xMThsLTggNC04LTRWMTRhMiAyIDAgMDAyIDJoMTJhMiAyIDAgMDAyLTJWOC4xMTh6XCIvPlxuICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInR3LXRydW5jYXRlXCI+JHtlbWFpbH08L3NwYW4+XG4gICAgICAgICAgPC9wPlxuICAgICAgICAgIDxwIGNsYXNzPVwidHctdGV4dC1zbSB0dy10ZXh0LWdyYXktNjAwIHR3LXRydW5jYXRlIHR3LWZsZXggdHctaXRlbXMtY2VudGVyXCIgdGl0bGU9XCIke3Bob25lfVwiPlxuICAgICAgICAgICAgPHN2ZyBjbGFzcz1cInR3LWZsZXgtc2hyaW5rLTAgdHctdy00IHR3LWgtNCB0dy10ZXh0LWdyYXktNDAwIHR3LW1yLTJcIiBmaWxsPVwiY3VycmVudENvbG9yXCIgdmlld0JveD1cIjAgMCAyMCAyMFwiPlxuICAgICAgICAgICAgICA8cGF0aCBkPVwiTTIgM2ExIDEgMCAwMTEtMWgyLjE1M2ExIDEgMCAwMS45ODYuODM2bC43NCA0LjQzNWExIDEgMCAwMS0uNTQgMS4wNmwtMS41NDguNzczYTExLjAzNyAxMS4wMzcgMCAwMDYuMTA1IDYuMTA1bC43NzQtMS41NDhhMSAxIDAgMDExLjA1OS0uNTRsNC40MzUuNzRhMSAxIDAgMDEuODM2Ljk4NlYxN2ExIDEgMCAwMS0xIDFoLTJDNy44MiAxOCAyIDEyLjE4IDIgNVYzelwiLz5cbiAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0dy10cnVuY2F0ZVwiPiR7cGhvbmV9PC9zcGFuPlxuICAgICAgICAgIDwvcD5cbiAgICAgICAgPC9kaXY+XG4gICAgICBgO1xuICAgIH1cbiAgfTtcblxuICAvLyBBY3Rpb24gaGFuZGxlcnNcbiAgYWN0aW9uSGFuZGxlcnMgPSB7XG4gICAgb25FZGl0RW50aXR5OiAoZW50aXR5OiBlbnRpdHlSZXNwb25zZURhdGEpID0+IHtcbiAgICAgIGNvbnN0IHF1ZXJ5OiBzdHJpbmcgPSBnZW5lcmF0ZVN0cmluZ0Zyb21PYmplY3Qoe1xuICAgICAgICBzeWVuX2lkOiBlbnRpdHkuX2lkXG4gICAgICB9KVxuICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoWydjb250cm9sLXBhbmVsJywgJ2VudGl0eS1jcmVhdGUnLCBxdWVyeV0pO1xuICAgIH0sXG5cbiAgICBvbkRlbGV0ZUVudGl0eTogKGVudGl0eTogZW50aXR5UmVzcG9uc2VEYXRhKSA9PiB7XG4gICAgICBjb25zdCBlbnRpdHlOYW1lID0gZW50aXR5LnN5ZW5fbmFtZSB8fCAndGhpcyBlbnRpdHknO1xuICAgICAgaWYgKGNvbmZpcm0oYEFyZSB5b3Ugc3VyZSB5b3Ugd2FudCB0byBkZWxldGUgJHtlbnRpdHlOYW1lfT9gKSkge1xuICAgICAgICB0aGlzLm9uRGVsZXRlRW50aXR5Q29uZmlybWVkKGVudGl0eS5faWQgfHwgJycpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICBuZ09uSW5pdCgpIHtcbiAgICBjb25zb2xlLmxvZygn8J+UpyBFTlRJVFkgTElTVDogQ29tcG9uZW50IGluaXRpYWxpemluZycpO1xuICAgIHRoaXMudXBkYXRlUGFnaW5hdGlvblN0YXRlKCk7XG5cbiAgICAvLyBTZXQgaW5pdGlhbCBsb2FkaW5nIHN0YXRlIHRvIGZhbHNlIHRvIGFsbG93IGdyaWQgdG8gcmVuZGVyXG4gICAgdGhpcy5sb2FkaW5nLnNldChmYWxzZSk7XG5cbiAgICAvLyBMb2FkIGVudGl0aWVzIGZyb20gQVBJXG4gICAgdGhpcy5sb2FkRW50aXRpZXMoKTtcbiAgfVxuXG4gIC8vIEdyaWQgZXZlbnQgaGFuZGxlclxuICBvbkdyaWRFdmVudChldmVudDogR3JpZEV2ZW50PGVudGl0eVJlc3BvbnNlRGF0YT4pIHtcbiAgICBjb25zb2xlLmxvZygn8J+ToSBHUklEIEVWRU5UOiBSZWNlaXZlZCBncmlkIGV2ZW50OicsIGV2ZW50LnR5cGUsIGV2ZW50KTtcblxuICAgIHN3aXRjaCAoZXZlbnQudHlwZSkge1xuICAgICAgY2FzZSAncm93Q2xpY2snOlxuICAgICAgICB0aGlzLm9uRW50aXR5Um93Q2xpY2soZXZlbnQuZGF0YSBhcyBlbnRpdHlSZXNwb25zZURhdGEpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3JlZnJlc2gnOlxuICAgICAgICB0aGlzLm9uRW50aXR5UmVmcmVzaCgpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3NlYXJjaCc6XG4gICAgICAgIHRoaXMub25FbnRpdHlTZWFyY2goZXZlbnQuZGF0YSBhcyBzdHJpbmcpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3BhZ2VDaGFuZ2UnOlxuICAgICAgICB0aGlzLm9uRW50aXR5UGFnZUNoYW5nZShldmVudC5kYXRhIGFzIG51bWJlcik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgY29uc29sZS5sb2coJ1VuaGFuZGxlZCBncmlkIGV2ZW50OicsIGV2ZW50LnR5cGUpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEV2ZW50IGhhbmRsZXJzIGZvciBncmlkIGV2ZW50c1xuICBwcml2YXRlIG9uRW50aXR5Um93Q2xpY2soZW50aXR5OiBlbnRpdHlSZXNwb25zZURhdGEpIHtcbiAgICBjb25zb2xlLmxvZygnRW50aXR5IHJvdyBjbGlja2VkOicsIGVudGl0eSk7XG4gICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoWydhZG1pbicsICdlbnRpdHknLCAndmlldycsIGVudGl0eS5faWRdKTtcbiAgfVxuXG4gIHByaXZhdGUgb25FbnRpdHlSZWZyZXNoKCkge1xuICAgIGNvbnNvbGUubG9nKCdSZWZyZXNoaW5nIGVudGl0aWVzLi4uJyk7XG4gICAgdGhpcy5sb2FkRW50aXRpZXModHJ1ZSk7XG4gIH1cblxuICBwcml2YXRlIG9uRW50aXR5U2VhcmNoKHF1ZXJ5OiBzdHJpbmcpIHtcbiAgICBjb25zb2xlLmxvZygnU2VhcmNoIGVudGl0aWVzOicsIHF1ZXJ5KTtcbiAgICB0aGlzLnNlYXJjaFF1ZXJ5LnNldChxdWVyeSk7XG4gICAgLy8gVGhlIGdyaWQgaGFuZGxlcyB0aGUgYWN0dWFsIGZpbHRlcmluZ1xuICB9XG5cbiAgcHJpdmF0ZSBvbkVudGl0eVBhZ2VDaGFuZ2UocGFnZTogbnVtYmVyKSB7XG4gICAgY29uc29sZS5sb2coJ1BhZ2UgY2hhbmdlZCB0bzonLCBwYWdlKTtcbiAgICB0aGlzLmN1cnJlbnRQYWdlLnNldChwYWdlKTtcbiAgICBcbiAgICAvLyBSZWxvYWQgZGF0YSBmb3IgdGhlIG5ldyBwYWdlXG4gICAgdGhpcy5sb2FkRW50aXRpZXMoZmFsc2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBvbkRlbGV0ZUVudGl0eUNvbmZpcm1lZChlbnRpdHlJZDogc3RyaW5nKSB7XG4gICAgLy8gSW4gYSByZWFsIGFwcCwgeW91J2QgY2FsbCB0aGUgQVBJIHRvIGRlbGV0ZVxuICAgIGNvbnNvbGUubG9nKCdEZWxldGluZyBlbnRpdHk6JywgZW50aXR5SWQpO1xuICAgIC8vIEZvciBub3csIGp1c3QgcmVsb2FkIHRoZSBlbnRpdGllc1xuICAgIHRoaXMubG9hZEVudGl0aWVzKHRydWUpO1xuICB9XG5cbiAgLy8gVXBkYXRlIGdyaWQgZGF0YSBtZXRob2RcbiAgcHJpdmF0ZSB1cGRhdGVHcmlkRGF0YShlbnRpdGllczogZW50aXR5UmVzcG9uc2VEYXRhW10pIHtcbiAgICBjb25zb2xlLmxvZygn8J+TiiBHUklEIFVQREFURTogVXBkYXRpbmcgZ3JpZCB3aXRoJywgZW50aXRpZXMubGVuZ3RoLCAnZW50aXRpZXMnKTtcbiAgICBjb25zb2xlLmxvZygn8J+TiiBHUklEIFVQREFURTogU2FtcGxlIGVudGl0eSBkYXRhOicsIGVudGl0aWVzWzBdIHx8ICdObyBlbnRpdGllcycpO1xuXG4gICAgLy8gU2V0IHRoZSBlbnRpdGllcyBzaWduYWxcbiAgICB0aGlzLmVudGl0aWVzLnNldChlbnRpdGllcyk7XG5cbiAgICAvLyBVcGRhdGUgZ3JpZCBjb25maWd1cmF0aW9uIHdpdGggbmV3IGRhdGEgYW5kIGVuc3VyZSBsb2FkaW5nIGlzIGZhbHNlXG4gICAgdGhpcy5ncmlkQ29uZmlnLnVwZGF0ZShjb25maWcgPT4gKHtcbiAgICAgIC4uLmNvbmZpZyxcbiAgICAgIGRhdGE6IGVudGl0aWVzXG4gICAgfSkpO1xuXG4gICAgLy8gRW5zdXJlIGxvYWRpbmcgc3RhdGVzIGFyZSBjbGVhcmVkXG4gICAgdGhpcy5sb2FkaW5nLnNldChmYWxzZSk7XG4gICAgXG4gICAgLy8gQ2xlYXIgcGFnZSBjaGFuZ2UgbG9hZGluZyBzdGF0ZSBpbiB0aGUgZ3JpZCBjb21wb25lbnRcbiAgICBpZiAodGhpcy5ncmlkQ29tcG9uZW50KSB7XG4gICAgICB0aGlzLmdyaWRDb21wb25lbnQuY2xlYXJQYWdlQ2hhbmdlTG9hZGluZygpO1xuICAgIH1cblxuICAgIGNvbnNvbGUubG9nKCfwn5OKIEdSSUQgVVBEQVRFOiBHcmlkIGNvbmZpZyB1cGRhdGVkIHN1Y2Nlc3NmdWxseScpO1xuICAgIGNvbnNvbGUubG9nKCfwn5OKIEdSSUQgVVBEQVRFOiBDdXJyZW50IGdyaWQgZGF0YSBsZW5ndGg6JywgdGhpcy5ncmlkQ29uZmlnKCkuZGF0YS5sZW5ndGgpO1xuICAgIGNvbnNvbGUubG9nKCfwn5OKIEdSSUQgVVBEQVRFOiBMb2FkaW5nIHN0YXRlOicsIHRoaXMubG9hZGluZygpKTtcbiAgICBjb25zb2xlLmxvZygn8J+TiiBHUklEIFVQREFURTogRnVsbCBncmlkIGNvbmZpZyBmb3IgZGVidWdnaW5nOicsIEpTT04uc3RyaW5naWZ5KHRoaXMuZ3JpZENvbmZpZygpLCBudWxsLCAyKSk7XG4gIH1cblxuICBsb2FkRW50aXRpZXMoaXNSZWZyZXNoOiBib29sZWFuID0gZmFsc2UpIHtcbiAgICBpZiAoaXNSZWZyZXNoKSB7XG4gICAgICBjb25zb2xlLmxvZygn8J+UhCBFTlRJVFkgTElTVDogUmVmcmVzaGluZyBlbnRpdGllcycpO1xuICAgICAgLy8gU2V0IHRoZSBncmlkJ3MgcmVmcmVzaCBzdGF0ZSB0byB0cnVlXG4gICAgICBpZiAodGhpcy5ncmlkQ29tcG9uZW50KSB7XG4gICAgICAgIHRoaXMuZ3JpZENvbXBvbmVudC5zZXRSZWZyZXNoaW5nKHRydWUpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxvYWRpbmcuc2V0KHRydWUpO1xuICAgICAgY29uc29sZS5sb2coJ/CflI0gRU5USVRZIExJU1Q6IExvYWRpbmcgZW50aXRpZXMgZnJvbSBBUEknKTtcbiAgICB9XG4gICAgdGhpcy5lcnJvci5zZXQobnVsbCk7XG4gICAgdGhpcy5sb2FkU3RhcnRUaW1lID0gRGF0ZS5ub3coKTtcblxuICAgIHRoaXMuZW50aXR5U2VydmljZS5nZXRBbGxFbnRpdGllcygpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAocmVzcG9uc2U6IGVudGl0eUNvbnRyb2xsZXJSZXNwb25zZSkgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZygn4pyFIEVOVElUWSBMSVNUOiBBUEkgcmVzcG9uc2UgcmVjZWl2ZWQ6JywgcmVzcG9uc2UpO1xuXG4gICAgICAgIC8vIFByb2Nlc3MgdGhlIHJlc3BvbnNlIGRhdGFcbiAgICAgICAgaWYgKHJlc3BvbnNlPy5kYXRhKSB7XG4gICAgICAgICAgLy8gSGFuZGxlIGJvdGggYXJyYXkgYW5kIHNpbmdsZSBvYmplY3QgcmVzcG9uc2VzXG4gICAgICAgICAgY29uc3QgZW50aXRpZXNEYXRhID0gQXJyYXkuaXNBcnJheShyZXNwb25zZS5kYXRhKSA/IHJlc3BvbnNlLmRhdGEgOiBbcmVzcG9uc2UuZGF0YV07XG4gICAgICAgICAgY29uc29sZS5sb2coJ/Cfk4sgRU5USVRZIExJU1Q6IFByb2Nlc3NlZCBlbnRpdGllcyBkYXRhOicsIGVudGl0aWVzRGF0YS5sZW5ndGgsICdlbnRpdGllcycpO1xuXG4gICAgICAgICAgaWYgKGVudGl0aWVzRGF0YS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygn8J+TiiBFTlRJVFkgTElTVDogRmlyc3QgZW50aXR5IHNhbXBsZTonLCBlbnRpdGllc0RhdGFbMF0pO1xuICAgICAgICAgICAgdGhpcy51cGRhdGVHcmlkRGF0YShlbnRpdGllc0RhdGEpO1xuICAgICAgICAgICAgdGhpcy50b3RhbEl0ZW1zLnNldChlbnRpdGllc0RhdGEubGVuZ3RoKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS5sb2coJ/Cfk4ogRU5USVRZIExJU1Q6IE5vIGVudGl0aWVzIHJldHVybmVkLCBzaG93aW5nIHRlc3QgZGF0YScpO1xuICAgICAgICAgICAgdGhpcy5sb2FkVGVzdERhdGEoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc29sZS53YXJuKCfimqDvuI8gRU5USVRZIExJU1Q6IE5vIGRhdGEgaW4gQVBJIHJlc3BvbnNlLCBsb2FkaW5nIHRlc3QgZGF0YScpO1xuICAgICAgICAgIHRoaXMubG9hZFRlc3REYXRhKCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLnVwZGF0ZVBhZ2luYXRpb25TdGF0ZSgpO1xuICAgICAgICB0aGlzLmxvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgXG4gICAgICAgIC8vIENsZWFyIHBhZ2UgY2hhbmdlIGxvYWRpbmcgc3RhdGUgaW4gdGhlIGdyaWQgY29tcG9uZW50XG4gICAgICAgIGlmICh0aGlzLmdyaWRDb21wb25lbnQpIHtcbiAgICAgICAgICB0aGlzLmdyaWRDb21wb25lbnQuY2xlYXJQYWdlQ2hhbmdlTG9hZGluZygpO1xuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICAvLyBTZXQgdGhlIGdyaWQncyByZWZyZXNoIHN0YXRlIHRvIGZhbHNlIHdoZW4gZG9uZVxuICAgICAgICBpZiAoaXNSZWZyZXNoICYmIHRoaXMuZ3JpZENvbXBvbmVudCkge1xuICAgICAgICAgIHRoaXMuZ3JpZENvbXBvbmVudC5zZXRSZWZyZXNoaW5nKGZhbHNlKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGVycm9yOiAoZXJyKSA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJ+KdjCBFTlRJVFkgTElTVDogQVBJIGVycm9yOicsIGVycik7XG4gICAgICAgIGNvbnNvbGUubG9nKCfwn6eqIEVOVElUWSBMSVNUOiBBUEkgZmFpbGVkLCBsb2FkaW5nIHRlc3QgZGF0YSBmb3IgZGVtb25zdHJhdGlvbicpO1xuXG4gICAgICAgIC8vIExvYWQgdGVzdCBkYXRhIHdoZW4gQVBJIGZhaWxzXG4gICAgICAgIHRoaXMubG9hZFRlc3REYXRhKCk7XG4gICAgICAgIHRoaXMuZXJyb3Iuc2V0KCdBUEkgdW5hdmFpbGFibGUuIFNob3dpbmcgc2FtcGxlIGRhdGEuJyk7XG5cbiAgICAgICAgdGhpcy5sb2FkaW5nLnNldChmYWxzZSk7XG4gICAgICAgIFxuICAgICAgICAvLyBDbGVhciBwYWdlIGNoYW5nZSBsb2FkaW5nIHN0YXRlIGluIHRoZSBncmlkIGNvbXBvbmVudFxuICAgICAgICBpZiAodGhpcy5ncmlkQ29tcG9uZW50KSB7XG4gICAgICAgICAgdGhpcy5ncmlkQ29tcG9uZW50LmNsZWFyUGFnZUNoYW5nZUxvYWRpbmcoKTtcbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgLy8gU2V0IHRoZSBncmlkJ3MgcmVmcmVzaCBzdGF0ZSB0byBmYWxzZSB3aGVuIGRvbmVcbiAgICAgICAgaWYgKGlzUmVmcmVzaCAmJiB0aGlzLmdyaWRDb21wb25lbnQpIHtcbiAgICAgICAgICB0aGlzLmdyaWRDb21wb25lbnQuc2V0UmVmcmVzaGluZyhmYWxzZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgbG9hZFRlc3REYXRhKCkge1xuICAgIGNvbnNvbGUubG9nKCfwn6eqIEVOVElUWSBMSVNUOiBMb2FkaW5nIHRlc3QgZGF0YScpO1xuICAgIGNvbnN0IHRlc3REYXRhOiBlbnRpdHlSZXNwb25zZURhdGFbXSA9IFtcbiAgICAgIHtcbiAgICAgICAgX2lkOiAndGVzdC0xJyxcbiAgICAgICAgc3llbl9uYW1lOiAnVGVzdCBVbml2ZXJzaXR5JyxcbiAgICAgICAgc3llbl9lbnRpdHlfY29kZTogJ1RFU1QwMDEnLFxuICAgICAgICBzeWVuX2NvcnBvcmF0ZV9lbWFpbDogJ3Rlc3RAdW5pdmVyc2l0eS5jb20nLFxuICAgICAgICBzeWVuX2NvcnBvcmF0ZV9jb250YWN0X3BlcnNvbl91c2VyOiAnSm9obiBEb2UnLFxuICAgICAgICBzeWVuX2NvcnBvcmF0ZV9waG9uZTogOTg3NjU0MzIxMCwgIC8vIE5vdyBhIG51bWJlclxuICAgICAgICBzeWVuX2lzYWN0aXZlOiB0cnVlLFxuICAgICAgICBzeWVuX2VudGl0eV90eXBlX2dtc3Q6ICd1bml2ZXJzaXR5JyxcbiAgICAgICAgY2hpbGRyZW46IFtdXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICBfaWQ6ICd0ZXN0LTInLFxuICAgICAgICBzeWVuX25hbWU6ICdTYW1wbGUgQ29sbGVnZScsXG4gICAgICAgIHN5ZW5fZW50aXR5X2NvZGU6ICdTQU1QMDAyJyxcbiAgICAgICAgc3llbl9jb3Jwb3JhdGVfZW1haWw6ICdpbmZvQHNhbXBsZWNvbGxlZ2UuZWR1JyxcbiAgICAgICAgc3llbl9jb3Jwb3JhdGVfY29udGFjdF9wZXJzb25fdXNlcjogJ0phbmUgU21pdGgnLFxuICAgICAgICBzeWVuX2NvcnBvcmF0ZV9waG9uZTogOTg3NjU0MzIxMSxcbiAgICAgICAgc3llbl9pc2FjdGl2ZTogZmFsc2UsXG4gICAgICAgIHN5ZW5fZW50aXR5X3R5cGVfZ21zdDogJ2NvbGxlZ2UnLFxuICAgICAgICBjaGlsZHJlbjogW11cbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIF9pZDogJ3Rlc3QtMycsXG4gICAgICAgIHN5ZW5fbmFtZTogJ0dsb2JhbCBJbnN0aXR1dGUgb2YgVGVjaG5vbG9neScsXG4gICAgICAgIHN5ZW5fZW50aXR5X2NvZGU6ICdHSVQwMDMnLFxuICAgICAgICBzeWVuX2NvcnBvcmF0ZV9lbWFpbDogJ2FkbWluQGdpdC5lZHUnLFxuICAgICAgICBzeWVuX2NvcnBvcmF0ZV9jb250YWN0X3BlcnNvbl91c2VyOiAnQm9iIEpvaG5zb24nLFxuICAgICAgICBzeWVuX2NvcnBvcmF0ZV9waG9uZTogOTg3NjU0MzIxMixcbiAgICAgICAgc3llbl9pc2FjdGl2ZTogdHJ1ZSxcbiAgICAgICAgc3llbl9lbnRpdHlfdHlwZV9nbXN0OiAnaW5zdGl0dXRlJyxcbiAgICAgICAgY2hpbGRyZW46IFtdXG4gICAgICB9XG4gICAgXTtcblxuICAgIGNvbnNvbGUubG9nKCfwn6eqIEVOVElUWSBMSVNUOiBUZXN0IGRhdGEgcHJlcGFyZWQ6JywgdGVzdERhdGEpO1xuICAgIHRoaXMudXBkYXRlR3JpZERhdGEodGVzdERhdGEpO1xuICAgIHRoaXMudG90YWxJdGVtcy5zZXQodGVzdERhdGEubGVuZ3RoKTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlUGFnaW5hdGlvblN0YXRlKCkge1xuICAgIGNvbnN0IHRvdGFsID0gTWF0aC5jZWlsKHRoaXMudG90YWxJdGVtcygpIC8gdGhpcy5wYWdlU2l6ZSgpKTtcbiAgICB0aGlzLnRvdGFsUGFnZXMuc2V0KHRvdGFsKTtcbiAgICB0aGlzLmhhc05leHRQYWdlLnNldCh0aGlzLmN1cnJlbnRQYWdlKCkgPCB0b3RhbCk7XG4gICAgdGhpcy5oYXNQcmV2aW91c1BhZ2Uuc2V0KHRoaXMuY3VycmVudFBhZ2UoKSA+IDEpO1xuICB9XG5cbiAgb25TZWFyY2goKSB7XG4gICAgdGhpcy5jdXJyZW50UGFnZS5zZXQoMSk7XG4gICAgdGhpcy5sb2FkRW50aXRpZXMoKTtcbiAgfVxuXG4gIG9uRmlsdGVyQ2hhbmdlKCkge1xuICAgIHRoaXMuY3VycmVudFBhZ2Uuc2V0KDEpO1xuICAgIHRoaXMubG9hZEVudGl0aWVzKCk7XG4gIH1cblxuICBvblBhZ2VDaGFuZ2UocGFnZTogbnVtYmVyIHwgc3RyaW5nKSB7XG4gICAgaWYgKHBhcnNlSW50KHBhZ2UgYXMgc3RyaW5nKSA+PSAxICYmIHBhcnNlSW50KHBhZ2UgYXMgc3RyaW5nKSA8PSB0aGlzLnRvdGFsUGFnZXMoKSkge1xuICAgICAgdGhpcy5jdXJyZW50UGFnZS5zZXQocGFyc2VJbnQocGFnZSBhcyBzdHJpbmcpKTtcbiAgICAgIHRoaXMubG9hZEVudGl0aWVzKCk7XG4gICAgfVxuICB9XG5cbiAgb25QYWdlU2l6ZUNoYW5nZSgpIHtcbiAgICB0aGlzLmN1cnJlbnRQYWdlLnNldCgxKTtcbiAgICB0aGlzLmxvYWRFbnRpdGllcygpO1xuICB9XG5cbiAgb25SZWZyZXNoKCkge1xuICAgIHRoaXMubG9hZEVudGl0aWVzKHRydWUpOyAvLyBQYXNzIHRydWUgZm9yIHJlZnJlc2hcbiAgfVxuXG4gIG9uQWRkRW50aXR5KCkge1xuICAgIC8vIE5hdmlnYXRlIHRvIGVudGl0eSBjcmVhdGUgZm9ybVxuICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFsnL2NvbnRyb2wtcGFuZWwvZW50aXR5LWNyZWF0ZSddKTtcbiAgfVxuXG4gIG9uRWRpdEVudGl0eShlbnRpdHk6IGVudGl0eVJlc3BvbnNlRGF0YSkge1xuICAgIC8vIFRPRE86IEltcGxlbWVudCBlZGl0IGZ1bmN0aW9uYWxpdHkgLSBuYXZpZ2F0ZSB0byBlZGl0IGZvcm0gd2l0aCBlbnRpdHkgSURcbiAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbJy9jb250cm9sLXBhbmVsL2VudGl0eS1jcmVhdGUnXSwge1xuICAgICAgcXVlcnlQYXJhbXM6IHsgaWQ6IGVudGl0eS5faWQsIG1vZGU6ICdlZGl0JyB9XG4gICAgfSk7XG4gICAgY29uc29sZS5sb2coJ0VkaXQgZW50aXR5OicsIGVudGl0eSk7XG4gIH1cblxuICBvblZpZXdFbnRpdHkoZW50aXR5OiBlbnRpdHlSZXNwb25zZURhdGEpIHtcbiAgICAvLyBUT0RPOiBJbXBsZW1lbnQgdmlldyBmdW5jdGlvbmFsaXR5XG4gICAgY29uc29sZS5sb2coJ1ZpZXcgZW50aXR5OicsIGVudGl0eSk7XG4gIH1cblxuICBvbkRlbGV0ZUVudGl0eShlbnRpdHk6IGVudGl0eVJlc3BvbnNlRGF0YSkge1xuICAgIGlmIChjb25maXJtKGBBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gZGVsZXRlIFwiJHtlbnRpdHkuc3llbl9uYW1lfVwiP2ApKSB7XG4gICAgICAvLyBUT0RPOiBJbXBsZW1lbnQgZGVsZXRlIGZ1bmN0aW9uYWxpdHlcbiAgICAgIGNvbnNvbGUubG9nKCdEZWxldGUgZW50aXR5OicsIGVudGl0eSk7XG4gICAgfVxuICB9XG5cbiAgZ2V0U3RhdHVzQ2xhc3MoaXNBY3RpdmU6IGJvb2xlYW4pOiBzdHJpbmcge1xuICAgIHJldHVybiBpc0FjdGl2ZVxuICAgICAgPyAndHctYmctZ3JlZW4tMTAwIHR3LXRleHQtZ3JlZW4tODAwJ1xuICAgICAgOiAndHctYmctcmVkLTEwMCB0dy10ZXh0LXJlZC04MDAnO1xuICB9XG5cbiAgZ2V0U3RhdHVzVGV4dChpc0FjdGl2ZTogYm9vbGVhbik6IHN0cmluZyB7XG4gICAgcmV0dXJuIGlzQWN0aXZlID8gJ0FjdGl2ZScgOiAnSW5hY3RpdmUnO1xuICB9XG5cbiAgZm9ybWF0RGF0ZShkYXRlOiBEYXRlIHwgc3RyaW5nIHwgdW5kZWZpbmVkKTogc3RyaW5nIHtcbiAgICBpZiAoIWRhdGUpIHJldHVybiAnTi9BJztcbiAgICByZXR1cm4gbmV3IERhdGUoZGF0ZSkudG9Mb2NhbGVEYXRlU3RyaW5nKCk7XG4gIH1cblxuICAvLyBQYWdpbmF0aW9uIGhlbHBlciBtZXRob2RzXG4gIGdldFBhZ2VOdW1iZXJzKCk6IG51bWJlcltdIHtcbiAgICBjb25zdCB0b3RhbCA9IHRoaXMudG90YWxQYWdlcygpO1xuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLmN1cnJlbnRQYWdlKCk7XG4gICAgY29uc3QgZGVsdGEgPSAyOyAvLyBOdW1iZXIgb2YgcGFnZXMgdG8gc2hvdyBvbiBlYWNoIHNpZGUgb2YgY3VycmVudCBwYWdlXG5cbiAgICBjb25zdCBwYWdlczogbnVtYmVyW10gPSBbXTtcbiAgICBjb25zdCBzdGFydCA9IE1hdGgubWF4KDEsIGN1cnJlbnQgLSBkZWx0YSk7XG4gICAgY29uc3QgZW5kID0gTWF0aC5taW4odG90YWwsIGN1cnJlbnQgKyBkZWx0YSk7XG5cbiAgICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPD0gZW5kOyBpKyspIHtcbiAgICAgIHBhZ2VzLnB1c2goaSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhZ2VzO1xuICB9XG5cbiAgZ2V0SXRlbVJhbmdlVGV4dCgpOiBzdHJpbmcge1xuICAgIGNvbnN0IHN0YXJ0ID0gKHRoaXMuY3VycmVudFBhZ2UoKSAtIDEpICogdGhpcy5wYWdlU2l6ZSgpICsgMTtcbiAgICBjb25zdCBlbmQgPSBNYXRoLm1pbih0aGlzLmN1cnJlbnRQYWdlKCkgKiB0aGlzLnBhZ2VTaXplKCksIHRoaXMudG90YWxJdGVtcygpKTtcbiAgICBjb25zdCB0b3RhbCA9IHRoaXMudG90YWxJdGVtcygpO1xuXG4gICAgcmV0dXJuIGAke3N0YXJ0fS0ke2VuZH0gb2YgJHt0b3RhbH1gO1xuICB9XG5cbiAgdHJhY2tCeUVudGl0eUlkKGluZGV4OiBudW1iZXIsIGVudGl0eTogZW50aXR5UmVzcG9uc2VEYXRhKTogc3RyaW5nIHtcbiAgICByZXR1cm4gZW50aXR5Py5faWQgfHwgJyc7XG4gIH1cblxuICAvLyA9PT09PSBFbmhhbmNlZCBQYWdpbmF0aW9uIE1ldGhvZHMgPT09PT1cblxuICAvKipcbiAgICogR2V0IGVuaGFuY2VkIHBhZ2UgbnVtYmVycyB3aXRoIGVsbGlwc2lzIGZvciBiZXR0ZXIgbmF2aWdhdGlvblxuICAgKi9cbiAgZ2V0RW5oYW5jZWRQYWdlTnVtYmVycygpOiAobnVtYmVyIHwgc3RyaW5nKVtdIHtcbiAgICBjb25zdCB0b3RhbCA9IHRoaXMudG90YWxQYWdlcygpO1xuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLmN1cnJlbnRQYWdlKCk7XG4gICAgY29uc3QgcGFnZXM6IChudW1iZXIgfCBzdHJpbmcpW10gPSBbXTtcblxuICAgIGlmICh0b3RhbCA8PSA3KSB7XG4gICAgICAvLyBTaG93IGFsbCBwYWdlcyBpZiA3IG9yIGZld2VyXG4gICAgICBmb3IgKGxldCBpID0gMTsgaSA8PSB0b3RhbDsgaSsrKSB7XG4gICAgICAgIHBhZ2VzLnB1c2goaSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIEFsd2F5cyBzaG93IGZpcnN0IHBhZ2VcbiAgICAgIHBhZ2VzLnB1c2goMSk7XG5cbiAgICAgIGlmIChjdXJyZW50IDw9IDQpIHtcbiAgICAgICAgLy8gQ3VycmVudCBwYWdlIGlzIG5lYXIgdGhlIGJlZ2lubmluZ1xuICAgICAgICBmb3IgKGxldCBpID0gMjsgaSA8PSA1OyBpKyspIHtcbiAgICAgICAgICBwYWdlcy5wdXNoKGkpO1xuICAgICAgICB9XG4gICAgICAgIHBhZ2VzLnB1c2goJy4uLicpO1xuICAgICAgICBwYWdlcy5wdXNoKHRvdGFsKTtcbiAgICAgIH0gZWxzZSBpZiAoY3VycmVudCA+PSB0b3RhbCAtIDMpIHtcbiAgICAgICAgLy8gQ3VycmVudCBwYWdlIGlzIG5lYXIgdGhlIGVuZFxuICAgICAgICBwYWdlcy5wdXNoKCcuLi4nKTtcbiAgICAgICAgZm9yIChsZXQgaSA9IHRvdGFsIC0gNDsgaSA8PSB0b3RhbDsgaSsrKSB7XG4gICAgICAgICAgcGFnZXMucHVzaChpKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQ3VycmVudCBwYWdlIGlzIGluIHRoZSBtaWRkbGVcbiAgICAgICAgcGFnZXMucHVzaCgnLi4uJyk7XG4gICAgICAgIGZvciAobGV0IGkgPSBjdXJyZW50IC0gMTsgaSA8PSBjdXJyZW50ICsgMTsgaSsrKSB7XG4gICAgICAgICAgcGFnZXMucHVzaChpKTtcbiAgICAgICAgfVxuICAgICAgICBwYWdlcy5wdXNoKCcuLi4nKTtcbiAgICAgICAgcGFnZXMucHVzaCh0b3RhbCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHBhZ2VzO1xuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZSBwcm9ncmVzcyBwZXJjZW50YWdlIGJhc2VkIG9uIGN1cnJlbnQgcG9zaXRpb25cbiAgICovXG4gIGdldFByb2dyZXNzUGVyY2VudGFnZSgpOiBudW1iZXIge1xuICAgIGlmICh0aGlzLnRvdGFsUGFnZXMoKSA9PT0gMCkgcmV0dXJuIDA7XG4gICAgcmV0dXJuIE1hdGgucm91bmQoKHRoaXMuY3VycmVudFBhZ2UoKSAvIHRoaXMudG90YWxQYWdlcygpKSAqIDEwMCk7XG4gIH1cblxuICAvKipcbiAgICogSnVtcCB0byBzcGVjaWZpYyBwYWdlIGZ1bmN0aW9uYWxpdHlcbiAgICovXG4gIG9uSnVtcFRvUGFnZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5qdW1wVG9QYWdlID49IDEgJiYgdGhpcy5qdW1wVG9QYWdlIDw9IHRoaXMudG90YWxQYWdlcygpKSB7XG4gICAgICB0aGlzLm9uUGFnZUNoYW5nZSh0aGlzLmp1bXBUb1BhZ2UpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgc2ltdWxhdGVkIGxvYWQgdGltZSBmb3IgcGVyZm9ybWFuY2UgZGlzcGxheVxuICAgKi9cbiAgZ2V0TG9hZFRpbWUoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5sb2FkU3RhcnRUaW1lID4gMCA/IERhdGUubm93KCkgLSB0aGlzLmxvYWRTdGFydFRpbWUgOiAwO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCB0b3RhbCBkYXRhIHNpemUgZm9yIGRpc3BsYXlcbiAgICovXG4gIGdldFRvdGFsRGF0YVNpemUoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy50b3RhbEl0ZW1zKCk7XG4gIH1cblxuICAvKipcbiAgICogRXhwb3J0IGN1cnJlbnQgcGFnZSBlbnRpdGllc1xuICAgKi9cbiAgb25FeHBvcnRDdXJyZW50UGFnZSgpOiB2b2lkIHtcbiAgICBjb25zdCBjdXJyZW50UGFnZUVudGl0aWVzID0gdGhpcy5lbnRpdGllcygpO1xuICAgIGNvbnNvbGUubG9nKCdFeHBvcnRpbmcgY3VycmVudCBwYWdlOicsIGN1cnJlbnRQYWdlRW50aXRpZXMpO1xuICAgIC8vIFRPRE86IEltcGxlbWVudCBhY3R1YWwgZXhwb3J0IGZ1bmN0aW9uYWxpdHlcbiAgICBhbGVydChgRXhwb3J0aW5nICR7Y3VycmVudFBhZ2VFbnRpdGllcy5sZW5ndGh9IGVudGl0aWVzIGZyb20gY3VycmVudCBwYWdlYCk7XG4gIH1cblxuICAvKipcbiAgICogRXhwb3J0IGFsbCBlbnRpdGllc1xuICAgKi9cbiAgb25FeHBvcnRBbGwoKTogdm9pZCB7XG4gICAgY29uc29sZS5sb2coJ0V4cG9ydGluZyBhbGwgZW50aXRpZXMnKTtcbiAgICAvLyBUT0RPOiBJbXBsZW1lbnQgYWN0dWFsIGV4cG9ydCBmdW5jdGlvbmFsaXR5XG4gICAgYWxlcnQoYEV4cG9ydGluZyBhbGwgJHt0aGlzLnRvdGFsSXRlbXMoKX0gZW50aXRpZXNgKTtcbiAgfVxufSAiLCI8IS0tIEVudGl0eSBMaXN0IENvbnRhaW5lciAtLT5cbjxkaXYgY2xhc3M9XCJlbnRpdHktbGlzdC1jb250YWluZXIgdHctYmctd2hpdGUgdHctc2hhZG93LWxnIHR3LXJvdW5kZWQtbGcgdHctb3ZlcmZsb3ctaGlkZGVuXCI+XG4gIFxuICA8IS0tIEhlYWRlciBTZWN0aW9uIHdpdGggRmlsdGVycyAtLT5cbiAgPGRpdiBjbGFzcz1cInR3LXB4LTYgdHctcHktNCB0dy1ib3JkZXItYiB0dy1ib3JkZXItZ3JheS0yMDAgdHctYmctZ3JheS01MFwiPlxuICAgIDxkaXYgY2xhc3M9XCJ0dy1mbGV4IHR3LWZsZXgtY29sIHNtOnR3LWZsZXgtcm93IHR3LWp1c3RpZnktYmV0d2VlbiB0dy1pdGVtcy1zdGFydCBzbTp0dy1pdGVtcy1jZW50ZXIgdHctc3BhY2UteS00IHNtOnR3LXNwYWNlLXktMFwiPlxuICAgICAgXG4gICAgICA8IS0tIFRpdGxlIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cInR3LWZsZXggdHctaXRlbXMtY2VudGVyIHR3LXNwYWNlLXgtM1wiPlxuICAgICAgICA8Y2lkZS1lbGUtaWNvbiBjbGFzcz1cInR3LXRleHQtYmx1ZS02MDBcIj5hcGFydG1lbnQ8L2NpZGUtZWxlLWljb24+XG4gICAgICAgIDxkaXY+XG4gICAgICAgICAgPGg1IGNsYXNzPVwidHctdGV4dC1tZCB0dy1mb250LXNlbWlib2xkIHR3LXRleHQtZ3JheS05MDBcIj5FbnRpdHkgTWFuYWdlbWVudDwvaDU+XG4gICAgICAgICAgPHAgY2xhc3M9XCJ0dy10ZXh0LXNtIHR3LXRleHQtZ3JheS02MDBcIj5NYW5hZ2UgYW5kIHZpZXcgYWxsIGVudGl0aWVzIGluIHRoZSBzeXN0ZW08L3A+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gQWN0aW9ucyAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJ0dy1mbGV4IHR3LWl0ZW1zLWNlbnRlciB0dy1zcGFjZS14LTNcIj5cbiAgICAgICAgPCEtLSBFbnRpdHkgVHlwZSBGaWx0ZXIgLS0+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0dy1mbGV4IHR3LWl0ZW1zLWNlbnRlciB0dy1zcGFjZS14LTJcIj5cbiAgICAgICAgICA8bGFiZWwgZm9yPVwiZW50aXR5VHlwZUZpbHRlclwiIGNsYXNzPVwidHctdGV4dC1zbSB0dy1mb250LW1lZGl1bSB0dy10ZXh0LWdyYXktNzAwXCI+VHlwZTo8L2xhYmVsPlxuICAgICAgICAgIDxjaWRlLWVsZS1zZWxlY3RcbiAgICAgICAgICAgIGlkPVwiZW50aXR5VHlwZUZpbHRlclwiXG4gICAgICAgICAgICBbb3B0aW9uc109XCJlbnRpdHlUeXBlT3B0aW9ucygpXCJcbiAgICAgICAgICAgIFsobmdNb2RlbCldPVwic2VsZWN0ZWRFbnRpdHlUeXBlVmFsdWVcIlxuICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwibG9hZEVudGl0aWVzKClcIlxuICAgICAgICAgICAgY2xhc3M9XCJ0dy1taW4tdy00MFwiPlxuICAgICAgICAgIDwvY2lkZS1lbGUtc2VsZWN0PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8IS0tIEFkZCBFbnRpdHkgQnV0dG9uIC0tPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgY2lkZUVsZUJ1dHRvblxuICAgICAgICAgIHZhcmlhbnQ9XCJwcmltYXJ5XCJcbiAgICAgICAgICBzaXplPVwic21cIlxuICAgICAgICAgIChjbGljayk9XCJyb3V0ZXIubmF2aWdhdGUoWydjb250cm9sLXBhbmVsJywgJ2VudGl0eS1jcmVhdGUnXSlcIlxuICAgICAgICAgIGNsYXNzPVwidHctd2hpdGVzcGFjZS1ub3dyYXAgdHctZmxleCB0dy1pdGVtcy1jZW50ZXIgdHctZ2FwLTJcIj5cbiAgICAgICAgICA8Y2lkZS1lbGUtaWNvbiBzaXplPVwieHNcIiBjbGFzcz1cInR3LXctNiB0dy1oLTVcIj5hZGQ8L2NpZGUtZWxlLWljb24+XG4gICAgICAgICAgQWRkIEVudGl0eVxuICAgICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG5cbiAgPCEtLSBFcnJvciBNZXNzYWdlIC0tPlxuICAgIEBpZiAoZXJyb3IoKSkge1xuICAgICAgPGRpdiBjbGFzcz1cInR3LW10LTQgdHctcC00IHR3LWJnLXJlZC01MCB0dy1ib3JkZXIgdHctYm9yZGVyLXJlZC0yMDAgdHctcm91bmRlZC1tZFwiPlxuICAgIDxkaXYgY2xhc3M9XCJ0dy1mbGV4XCI+XG4gICAgICAgICAgPGNpZGUtZWxlLWljb24gbmFtZT1cImV4Y2xhbWF0aW9uLXRyaWFuZ2xlXCIgY2xhc3M9XCJ0dy10ZXh0LXJlZC00MDBcIj48L2NpZGUtZWxlLWljb24+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInR3LW1sLTNcIj5cbiAgICAgICAgICAgIDxoMyBjbGFzcz1cInR3LXRleHQtc20gdHctZm9udC1tZWRpdW0gdHctdGV4dC1yZWQtODAwXCI+RXJyb3I8L2gzPlxuICAgICAgICAgICAgPHAgY2xhc3M9XCJ0dy10ZXh0LXNtIHR3LXRleHQtcmVkLTcwMCB0dy1tdC0xXCI+e3sgZXJyb3IoKSB9fTwvcD5cbiAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIH1cbiAgPC9kaXY+XG5cbiAgPCEtLSBEYXRhIEdyaWQgQ29tcG9uZW50IC0tPlxuICA8Y2lkZS1lbGUtZGF0YS1ncmlkXG4gICAgW2NvbmZpZ109XCJncmlkQ29uZmlnKClcIlxuICAgIFtjdXN0b21SZW5kZXJlcnNdPVwiY3VzdG9tUmVuZGVyZXJzXCJcbiAgICBbYWN0aW9uSGFuZGxlcnNdPVwiYWN0aW9uSGFuZGxlcnNcIlxuICAgIChncmlkRXZlbnQpPVwib25HcmlkRXZlbnQoJGV2ZW50KVwiPlxuICA8L2NpZGUtZWxlLWRhdGEtZ3JpZD5cblxuPC9kaXY+Il19