emanate-ai-chat-lib 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,706 @@
1
+ import { Component, Input, Output, EventEmitter } from '@angular/core';
2
+ import { Subject } from 'rxjs';
3
+ import { takeUntil } from 'rxjs/operators';
4
+ import { getIconSet } from '../models/icon-config.interface';
5
+ import * as i0 from "@angular/core";
6
+ import * as i1 from "../services/ai-agent.service";
7
+ import * as i2 from "@angular/platform-browser";
8
+ import * as i3 from "@angular/common";
9
+ import * as i4 from "@angular/forms";
10
+ export class AiChatComponent {
11
+ constructor(aiAgentService, sanitizer) {
12
+ this.aiAgentService = aiAgentService;
13
+ this.sanitizer = sanitizer;
14
+ this.title = 'Chat with Maestro';
15
+ this.placeholder = 'Type your inquiry here... (Press Enter to send, Shift+Enter for new line)';
16
+ this.showDebugInfo = false;
17
+ this.enableImageUpload = false; // Enable/disable image upload button
18
+ this.enableFileUpload = false; // Enable/disable file upload button
19
+ this.iconSet = 'feather'; // Icon set selection
20
+ this.messageReceived = new EventEmitter();
21
+ this.messageSent = new EventEmitter();
22
+ this.fileUploaded = new EventEmitter();
23
+ this.sizeChanged = new EventEmitter();
24
+ this.messages = [];
25
+ this.currentInquiry = '';
26
+ this.authorName = '';
27
+ this.intent = '';
28
+ this.isLoading = false;
29
+ this.configurationStatus = '';
30
+ // Resizing properties
31
+ this.currentSize = 'default';
32
+ this.isFullscreen = false;
33
+ this.isResizing = false;
34
+ this.containerWidth = 800;
35
+ this.containerHeight = 600;
36
+ this.minWidth = 400;
37
+ this.maxWidth = 1400;
38
+ this.minHeight = 400;
39
+ this.maxHeight = window.innerHeight - 100;
40
+ this.startX = 0;
41
+ this.startY = 0;
42
+ this.startWidth = 0;
43
+ this.startHeight = 0;
44
+ // File upload properties
45
+ this.maxFileSize = 10 * 1024 * 1024; // 10MB
46
+ this.allowedImageTypes = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif', 'image/webp'];
47
+ this.allowedFileTypes = ['application/pdf', 'application/msword',
48
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
49
+ 'text/plain', 'text/csv'];
50
+ this.selectedFiles = [];
51
+ // Icon configuration
52
+ this.icons = getIconSet('feather');
53
+ this.sanitizedIcons = {};
54
+ this.destroy$ = new Subject();
55
+ }
56
+ ngOnInit() {
57
+ this.configurationStatus = 'Initializing...';
58
+ console.log('AI Chat Component initialized');
59
+ // Load icon set
60
+ this.icons = getIconSet(this.iconSet, this.customIcons);
61
+ this.sanitizeIcons();
62
+ // Configure API URL and App Key if provided
63
+ if (this.apiUrl || this.appKey) {
64
+ this.aiAgentService.configure({
65
+ apiUrl: this.apiUrl,
66
+ appKey: this.appKey
67
+ });
68
+ }
69
+ try {
70
+ // Load historical messages if provided
71
+ if (this.historicalMessages && this.historicalMessages.length > 0) {
72
+ this.loadHistoricalMessages(this.historicalMessages);
73
+ }
74
+ else {
75
+ this.addWelcomeMessage();
76
+ }
77
+ this.testConfiguration();
78
+ this.loadSavedSize();
79
+ this.applySizePreset(this.currentSize);
80
+ }
81
+ catch (error) {
82
+ console.error('Error during component initialization:', error);
83
+ this.configurationStatus = 'Initialization error';
84
+ }
85
+ }
86
+ ngOnChanges(changes) {
87
+ // Detect when historicalMessages input changes
88
+ if (changes['historicalMessages'] && !changes['historicalMessages'].firstChange) {
89
+ const newMessages = changes['historicalMessages'].currentValue;
90
+ // console.log('Historical messages changed:', newMessages);
91
+ // Clear existing messages and reload
92
+ this.messages = [];
93
+ if (newMessages && newMessages.length > 0) {
94
+ this.loadHistoricalMessages(newMessages);
95
+ }
96
+ else {
97
+ this.addWelcomeMessage();
98
+ }
99
+ }
100
+ // Detect when conversationId changes
101
+ if (changes['conversationId'] && !changes['conversationId'].firstChange) {
102
+ // console.log('Conversation ID changed:', changes['conversationId'].currentValue);
103
+ // Update all existing messages with new conversationId if needed
104
+ this.messages.forEach(msg => {
105
+ if (msg.conversationId !== this.conversationId) {
106
+ msg.conversationId = this.conversationId;
107
+ }
108
+ });
109
+ }
110
+ // Detect when icon set changes
111
+ if (changes['iconSet'] || changes['customIcons']) {
112
+ this.icons = getIconSet(this.iconSet, this.customIcons);
113
+ this.sanitizeIcons();
114
+ }
115
+ }
116
+ ngOnDestroy() {
117
+ this.destroy$.next();
118
+ this.destroy$.complete();
119
+ }
120
+ /**
121
+ * Sanitize icon SVG strings for safe rendering in innerHTML bindings
122
+ */
123
+ sanitizeIcons() {
124
+ this.sanitizedIcons = {};
125
+ Object.keys(this.icons).forEach(key => {
126
+ const svgString = this.icons[key];
127
+ if (svgString) {
128
+ this.sanitizedIcons[key] = this.sanitizer.bypassSecurityTrustHtml(svgString);
129
+ }
130
+ });
131
+ }
132
+ testConfiguration() {
133
+ this.configurationStatus = 'Testing connection...';
134
+ this.aiAgentService.testConfiguration()
135
+ .pipe(takeUntil(this.destroy$))
136
+ .subscribe({
137
+ next: (response) => {
138
+ if (response.success) {
139
+ this.configurationStatus = 'AI Agent is ready';
140
+ }
141
+ else {
142
+ this.configurationStatus = `Configuration error: ${response.error}`;
143
+ }
144
+ },
145
+ error: (errorResponse) => {
146
+ this.configurationStatus = `Connection error: Cannot connect to backend service`;
147
+ console.error('API connection test failed:', errorResponse);
148
+ }
149
+ });
150
+ }
151
+ addWelcomeMessage() {
152
+ const welcomeText = this.welcomeMessage ||
153
+ `<h3>Hello ${this.firstName}!</h3>Hi, I'm Maestro—your AI assistant. I'm here to help with your policy-related inquiries.<br><br>How can I assist you today?`;
154
+ this.messages.push({
155
+ isUser: false,
156
+ content: welcomeText,
157
+ intent: 'welcome',
158
+ timestamp: new Date()
159
+ });
160
+ }
161
+ /**
162
+ * Load and transform historical messages from parent component
163
+ * Accepts messages in the format from your backend/state management
164
+ */
165
+ loadHistoricalMessages(historicalMessages) {
166
+ // console.log('Loading historical messages:', historicalMessages);
167
+ // console.log('Number of messages to load:', historicalMessages.length);
168
+ // Transform your backend format to ChatMessage format
169
+ const transformedMessages = historicalMessages.map((msg) => {
170
+ // Determine if message is from user based on sender or role
171
+ const isUserMessage = this.isUserMessage(msg);
172
+ const transformed = {
173
+ messageId: msg.messageId || msg.id,
174
+ conversationId: msg.conversationId || this.conversationId,
175
+ isUser: isUserMessage,
176
+ content: msg.messageText || msg.message || msg.text || msg.content || '',
177
+ sender: msg.sender || (isUserMessage ? this.userName || 'User' : 'Maestro'),
178
+ intent: msg.intent || '',
179
+ authorName: msg.authorName || msg.sender,
180
+ confidenceScore: msg.confidenceScore || msg.confidence || 0,
181
+ timestamp: msg.timestamp || msg.createdAt
182
+ ? new Date(msg.timestamp || msg.createdAt)
183
+ : new Date(),
184
+ isLoading: false
185
+ };
186
+ // console.log('Transformed message:', transformed);
187
+ return transformed;
188
+ });
189
+ // Sort messages by timestamp to maintain chronological order
190
+ transformedMessages.sort((a, b) => a.timestamp.getTime() - b.timestamp.getTime());
191
+ // console.log('Sorted messages count:', transformedMessages.length);
192
+ // Add welcome message first if no messages or load historical messages
193
+ if (transformedMessages.length === 0) {
194
+ // console.log('No messages to load, adding welcome message');
195
+ this.addWelcomeMessage();
196
+ }
197
+ else {
198
+ // Check if first message is a welcome message, if not add one
199
+ const hasWelcome = transformedMessages.some(msg => msg.intent === 'welcome' || msg.content.includes('Hello'));
200
+ if (!hasWelcome) {
201
+ // console.log('No welcome message found, adding one');
202
+ this.addWelcomeMessage();
203
+ }
204
+ // console.log('Pushing transformed messages to messages array');
205
+ this.messages.push(...transformedMessages);
206
+ }
207
+ // console.log('Total loaded messages in component:', this.messages.length);
208
+ // console.log('Messages array:', this.messages);
209
+ }
210
+ /**
211
+ * Helper method to determine if a message is from the user
212
+ */
213
+ isUserMessage(msg) {
214
+ var _a, _b;
215
+ // Check various properties that might indicate user message
216
+ if (msg.isUser !== undefined)
217
+ return msg.isUser;
218
+ if (msg.role)
219
+ return msg.role.toLowerCase() === 'user';
220
+ if (msg.sender) {
221
+ const sender = msg.sender.toLowerCase();
222
+ return sender === 'user' ||
223
+ sender === ((_a = this.userName) === null || _a === void 0 ? void 0 : _a.toLowerCase()) ||
224
+ sender === ((_b = this.userId) === null || _b === void 0 ? void 0 : _b.toLowerCase()) ||
225
+ sender.includes('user');
226
+ }
227
+ // Default to false (bot message) if can't determine
228
+ return false;
229
+ }
230
+ sendInquiry() {
231
+ if (!this.currentInquiry.trim() || this.isLoading) {
232
+ return;
233
+ }
234
+ const userMessage = {
235
+ messageId: this.generateMessageId(),
236
+ conversationId: this.conversationId,
237
+ isUser: true,
238
+ sender: this.userName || 'User',
239
+ intent: this.intent,
240
+ content: this.currentInquiry,
241
+ timestamp: new Date()
242
+ };
243
+ this.messages.push(userMessage);
244
+ this.messageSent.emit(userMessage);
245
+ // Add loading message
246
+ const loadingMessage = {
247
+ isUser: false,
248
+ intent: '',
249
+ content: 'Processing your inquiry...',
250
+ timestamp: new Date(),
251
+ isLoading: true
252
+ };
253
+ this.messages.push(loadingMessage);
254
+ const inquiry = this.currentInquiry.trim();
255
+ this.currentInquiry = '';
256
+ this.authorName = '';
257
+ this.intent = '';
258
+ this.isLoading = true;
259
+ const request = {
260
+ query: inquiry,
261
+ chatHistory: [],
262
+ userId: this.userId,
263
+ userName: this.userName,
264
+ appSource: this.appSource
265
+ };
266
+ this.aiAgentService.processInquiry(request)
267
+ .pipe(takeUntil(this.destroy$))
268
+ .subscribe({
269
+ next: (response) => {
270
+ this.isLoading = false;
271
+ // Remove loading message
272
+ this.messages = this.messages.filter(msg => !msg.isLoading);
273
+ if (response.answer || (response.contents && response.contents.length > 0)) {
274
+ if (response.answer) {
275
+ const botMessage = {
276
+ messageId: this.generateMessageId(),
277
+ conversationId: this.conversationId,
278
+ isUser: false,
279
+ sender: 'Maestro',
280
+ intent: response.searchIntent || inquiry,
281
+ content: this.formatMessageContent(response.answer),
282
+ authorName: response.contents && response.contents.length > 0 ? response.contents[0].authorName : undefined,
283
+ timestamp: new Date()
284
+ };
285
+ this.messages.push(botMessage);
286
+ this.messageReceived.emit(botMessage);
287
+ }
288
+ else if (response.contents && response.contents.length > 0) {
289
+ // Push each content as a separate message
290
+ response.contents.forEach(contentItem => {
291
+ if (contentItem.content) {
292
+ const botMessage = {
293
+ messageId: this.generateMessageId(),
294
+ conversationId: this.conversationId,
295
+ isUser: false,
296
+ sender: contentItem.authorName || 'Maestro',
297
+ intent: response.searchIntent || inquiry,
298
+ content: this.formatMessageContent(contentItem.content || 'No content available'),
299
+ authorName: contentItem.authorName,
300
+ timestamp: new Date()
301
+ };
302
+ this.messages.push(botMessage);
303
+ this.messageReceived.emit(botMessage);
304
+ }
305
+ });
306
+ }
307
+ }
308
+ else {
309
+ const errorMessage = {
310
+ messageId: this.generateMessageId(),
311
+ conversationId: this.conversationId,
312
+ isUser: false,
313
+ sender: 'Maestro',
314
+ intent: inquiry,
315
+ content: `Sorry, I didn't receive a valid response.`,
316
+ authorName: this.authorName,
317
+ timestamp: new Date()
318
+ };
319
+ this.messages.push(errorMessage);
320
+ this.messageReceived.emit(errorMessage);
321
+ }
322
+ },
323
+ error: (error) => {
324
+ this.isLoading = false;
325
+ // Remove loading message
326
+ this.messages = this.messages.filter(msg => !msg.isLoading);
327
+ const errorMessage = {
328
+ messageId: this.generateMessageId(),
329
+ conversationId: this.conversationId,
330
+ isUser: false,
331
+ sender: 'Maestro',
332
+ intent: inquiry,
333
+ content: 'Sorry, I encountered an error processing your request. Please try again.',
334
+ authorName: this.authorName,
335
+ timestamp: new Date()
336
+ };
337
+ this.messages.push(errorMessage);
338
+ this.messageReceived.emit(errorMessage);
339
+ console.error('Error processing inquiry:', error);
340
+ }
341
+ });
342
+ }
343
+ clearChat() {
344
+ this.messages = [];
345
+ this.addWelcomeMessage();
346
+ }
347
+ onKeyPress(event) {
348
+ if (event.key === 'Enter' && !event.shiftKey) {
349
+ event.preventDefault();
350
+ this.sendInquiry();
351
+ }
352
+ }
353
+ trackByIndex(index) {
354
+ return index;
355
+ }
356
+ getThemeClass() {
357
+ // Default theme if no template design is specified
358
+ if (!this.templateDesign) {
359
+ return 'theme-default';
360
+ }
361
+ // Validate and return theme class
362
+ const validThemes = ['default', 'dark', 'blue', 'green', 'purple', 'minimal', 'corporate', 'red', 'yellow', 'orange'];
363
+ const theme = this.templateDesign.toLowerCase();
364
+ if (validThemes.includes(theme)) {
365
+ return `theme-${theme}`;
366
+ }
367
+ // Fallback to default if invalid theme
368
+ console.warn(`Invalid theme '${this.templateDesign}' provided. Using default theme.`);
369
+ return 'theme-default';
370
+ }
371
+ formatMessageContent(content) {
372
+ if (!content)
373
+ return '';
374
+ // If content already contains HTML tags, return as-is
375
+ if (content.includes('<') && content.includes('>')) {
376
+ return content;
377
+ }
378
+ // Convert newlines to HTML breaks
379
+ let formatted = content.replace(/\n/g, '<br>');
380
+ // Convert escaped newlines to HTML breaks
381
+ formatted = formatted.replace(/\\n/g, '<br>');
382
+ // Convert markdown-style bold to HTML
383
+ formatted = formatted.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');
384
+ // Convert bullet points to HTML lists
385
+ const lines = formatted.split('<br>');
386
+ let inList = false;
387
+ const processedLines = [];
388
+ for (let line of lines) {
389
+ if (line.trim().startsWith('• ')) {
390
+ if (!inList) {
391
+ processedLines.push('<ul>');
392
+ inList = true;
393
+ }
394
+ processedLines.push('<li>' + line.replace(/^• /, '') + '</li>');
395
+ }
396
+ else {
397
+ if (inList) {
398
+ processedLines.push('</ul>');
399
+ inList = false;
400
+ }
401
+ processedLines.push(line);
402
+ }
403
+ }
404
+ if (inList) {
405
+ processedLines.push('</ul>');
406
+ }
407
+ return processedLines.join('<br>').replace(/<br><ul>/g, '<ul>').replace(/<\/ul><br>/g, '</ul>');
408
+ }
409
+ generateSessionId() {
410
+ return 'session_' + Math.random().toString(36).substr(2, 9) + '_' + Date.now();
411
+ }
412
+ generateMessageId() {
413
+ return 'msg_' + Math.random().toString(36).substr(2, 9) + '_' + Date.now();
414
+ }
415
+ getFormattedTime(timestamp) {
416
+ return timestamp.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
417
+ }
418
+ // ============= Resize Methods =============
419
+ startResize(event, direction) {
420
+ event.preventDefault();
421
+ this.isResizing = true;
422
+ this.startX = event.clientX;
423
+ this.startY = event.clientY;
424
+ this.startWidth = this.containerWidth;
425
+ this.startHeight = this.containerHeight;
426
+ const mouseMoveHandler = (e) => this.onResize(e, direction);
427
+ const mouseUpHandler = () => this.stopResize(mouseMoveHandler, mouseUpHandler);
428
+ document.addEventListener('mousemove', mouseMoveHandler);
429
+ document.addEventListener('mouseup', mouseUpHandler);
430
+ }
431
+ onResize(event, direction) {
432
+ if (!this.isResizing)
433
+ return;
434
+ const deltaX = event.clientX - this.startX;
435
+ const deltaY = event.clientY - this.startY;
436
+ if (direction === 'width' || direction === 'both') {
437
+ const newWidth = Math.min(Math.max(this.startWidth + deltaX, this.minWidth), this.maxWidth);
438
+ this.containerWidth = newWidth;
439
+ }
440
+ if (direction === 'both') {
441
+ const newHeight = Math.min(Math.max(this.startHeight + deltaY, this.minHeight), this.maxHeight);
442
+ this.containerHeight = newHeight;
443
+ }
444
+ }
445
+ stopResize(mouseMoveHandler, mouseUpHandler) {
446
+ this.isResizing = false;
447
+ document.removeEventListener('mousemove', mouseMoveHandler);
448
+ document.removeEventListener('mouseup', mouseUpHandler);
449
+ this.saveSizePreference();
450
+ this.emitSizeChange();
451
+ }
452
+ applySizePreset(size) {
453
+ this.currentSize = size;
454
+ switch (size) {
455
+ case 'compact':
456
+ this.containerWidth = 400;
457
+ this.containerHeight = 500;
458
+ this.isFullscreen = false;
459
+ break;
460
+ case 'default':
461
+ this.containerWidth = 800;
462
+ this.containerHeight = 600;
463
+ this.isFullscreen = false;
464
+ break;
465
+ case 'expanded':
466
+ this.containerWidth = 1200;
467
+ this.containerHeight = 800;
468
+ this.isFullscreen = false;
469
+ break;
470
+ case 'fullscreen':
471
+ this.toggleFullscreen();
472
+ return;
473
+ }
474
+ this.saveSizePreference();
475
+ this.emitSizeChange();
476
+ }
477
+ toggleFullscreen() {
478
+ if (!this.isFullscreen) {
479
+ // Entering fullscreen - save current state first
480
+ sessionStorage.setItem('chatbox-previous-size', JSON.stringify({
481
+ width: this.containerWidth,
482
+ height: this.containerHeight,
483
+ size: this.currentSize,
484
+ wasFullscreen: this.isFullscreen
485
+ }));
486
+ this.isFullscreen = true;
487
+ this.currentSize = 'fullscreen';
488
+ }
489
+ else {
490
+ // Exiting fullscreen - restore previous state
491
+ try {
492
+ const previous = sessionStorage.getItem('chatbox-previous-size');
493
+ if (previous) {
494
+ const prevData = JSON.parse(previous);
495
+ this.containerWidth = prevData.width || 800;
496
+ this.containerHeight = prevData.height || 600;
497
+ this.currentSize = prevData.size === 'fullscreen' ? 'default' : prevData.size;
498
+ }
499
+ else {
500
+ this.currentSize = 'default';
501
+ this.containerWidth = 800;
502
+ this.containerHeight = 600;
503
+ }
504
+ }
505
+ catch (error) {
506
+ this.currentSize = 'default';
507
+ this.containerWidth = 800;
508
+ this.containerHeight = 600;
509
+ }
510
+ this.isFullscreen = false;
511
+ }
512
+ this.saveSizePreference();
513
+ this.emitSizeChange();
514
+ }
515
+ saveSizePreference() {
516
+ const sizeData = {
517
+ size: this.currentSize,
518
+ width: this.containerWidth,
519
+ height: this.containerHeight,
520
+ isFullscreen: this.isFullscreen
521
+ };
522
+ try {
523
+ sessionStorage.setItem('chatbox-size-preference', JSON.stringify(sizeData));
524
+ }
525
+ catch (error) {
526
+ console.warn('Failed to save size preference:', error);
527
+ }
528
+ }
529
+ loadSavedSize() {
530
+ try {
531
+ const saved = sessionStorage.getItem('chatbox-size-preference');
532
+ if (saved) {
533
+ const sizeData = JSON.parse(saved);
534
+ this.currentSize = sizeData.size || 'default';
535
+ this.containerWidth = sizeData.width || 800;
536
+ this.containerHeight = sizeData.height || 600;
537
+ this.isFullscreen = sizeData.isFullscreen || false;
538
+ }
539
+ }
540
+ catch (error) {
541
+ console.warn('Failed to load size preference:', error);
542
+ }
543
+ }
544
+ emitSizeChange() {
545
+ this.sizeChanged.emit({
546
+ size: this.currentSize,
547
+ width: this.containerWidth,
548
+ height: this.containerHeight
549
+ });
550
+ }
551
+ getContainerStyle() {
552
+ if (this.isFullscreen) {
553
+ return {
554
+ width: '100vw !important',
555
+ height: '100vh !important',
556
+ maxWidth: '100vw !important',
557
+ maxHeight: '100vh !important',
558
+ position: 'fixed',
559
+ top: '0',
560
+ left: '0',
561
+ right: '0',
562
+ bottom: '0',
563
+ margin: '0',
564
+ zIndex: 99999
565
+ };
566
+ }
567
+ return {
568
+ width: `${this.containerWidth}px`,
569
+ height: `${this.containerHeight}px`,
570
+ maxWidth: `${this.maxWidth}px`
571
+ };
572
+ }
573
+ // ============= File Upload Methods =============
574
+ onImageUpload(event) {
575
+ const input = event.target;
576
+ if (input.files && input.files.length > 0) {
577
+ this.handleFileSelection(Array.from(input.files), 'image');
578
+ }
579
+ }
580
+ onFileUpload(event) {
581
+ const input = event.target;
582
+ if (input.files && input.files.length > 0) {
583
+ this.handleFileSelection(Array.from(input.files), 'file');
584
+ }
585
+ }
586
+ handleFileSelection(files, type) {
587
+ files.forEach(file => {
588
+ // Validate file type
589
+ const allowedTypes = type === 'image' ? this.allowedImageTypes : this.allowedFileTypes;
590
+ if (!allowedTypes.includes(file.type)) {
591
+ console.warn(`File type ${file.type} not allowed`);
592
+ return;
593
+ }
594
+ // Validate file size
595
+ if (file.size > this.maxFileSize) {
596
+ console.warn(`File ${file.name} exceeds maximum size of ${this.maxFileSize / 1024 / 1024}MB`);
597
+ return;
598
+ }
599
+ const reader = new FileReader();
600
+ reader.onload = (e) => {
601
+ var _a;
602
+ const attachment = {
603
+ id: this.generateMessageId(),
604
+ name: file.name,
605
+ type: file.type,
606
+ size: file.size,
607
+ data: ((_a = e.target) === null || _a === void 0 ? void 0 : _a.result) || undefined
608
+ };
609
+ this.selectedFiles.push(attachment);
610
+ this.fileUploaded.emit(attachment);
611
+ };
612
+ if (type === 'image') {
613
+ reader.readAsDataURL(file);
614
+ }
615
+ else {
616
+ reader.readAsArrayBuffer(file);
617
+ }
618
+ });
619
+ }
620
+ removeAttachment(attachmentId) {
621
+ this.selectedFiles = this.selectedFiles.filter(f => f.id !== attachmentId);
622
+ }
623
+ triggerImageUpload() {
624
+ const input = document.getElementById('image-upload-input');
625
+ if (input) {
626
+ input.click();
627
+ }
628
+ }
629
+ triggerFileUpload() {
630
+ const input = document.getElementById('file-upload-input');
631
+ if (input) {
632
+ input.click();
633
+ }
634
+ }
635
+ getFileIcon(fileType) {
636
+ if (fileType.startsWith('image/'))
637
+ return '🖼️';
638
+ if (fileType.includes('pdf'))
639
+ return '📄';
640
+ if (fileType.includes('word') || fileType.includes('document'))
641
+ return '📝';
642
+ if (fileType.includes('text'))
643
+ return '📃';
644
+ return '📎';
645
+ }
646
+ getFileSizeFormatted(bytes) {
647
+ if (bytes < 1024)
648
+ return bytes + ' B';
649
+ if (bytes < 1024 * 1024)
650
+ return (bytes / 1024).toFixed(1) + ' KB';
651
+ return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
652
+ }
653
+ }
654
+ AiChatComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: AiChatComponent, deps: [{ token: i1.AiAgentService }, { token: i2.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component });
655
+ AiChatComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.17", type: AiChatComponent, selector: "emanate-ai-chat", inputs: { title: "title", placeholder: "placeholder", showDebugInfo: "showDebugInfo", apiUrl: "apiUrl", appKey: "appKey", appSource: "appSource", userId: "userId", firstName: "firstName", userName: "userName", templateDesign: "templateDesign", welcomeMessage: "welcomeMessage", historicalMessages: "historicalMessages", conversationId: "conversationId", enableImageUpload: "enableImageUpload", enableFileUpload: "enableFileUpload", iconSet: "iconSet", customIcons: "customIcons" }, outputs: { messageReceived: "messageReceived", messageSent: "messageSent", fileUploaded: "fileUploaded", sizeChanged: "sizeChanged" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"ai-chat-container\" \r\n [ngClass]=\"getThemeClass()\" \r\n [ngStyle]=\"getContainerStyle()\"\r\n [class.fullscreen]=\"isFullscreen\"\r\n [class.resizing]=\"isResizing\">\r\n \r\n <!-- Resize Handles -->\r\n <div class=\"resize-handle resize-handle-right\" \r\n (mousedown)=\"startResize($event, 'width')\"\r\n *ngIf=\"!isFullscreen\"\r\n title=\"Drag to resize width\">\r\n </div>\r\n \r\n <div class=\"resize-handle resize-handle-corner\" \r\n (mousedown)=\"startResize($event, 'both')\"\r\n *ngIf=\"!isFullscreen\"\r\n title=\"Drag to resize\">\r\n </div>\r\n \r\n <!-- Debug Information (only shown when showDebugInfo is true) -->\r\n <div *ngIf=\"showDebugInfo\" class=\"debug-info\">\r\n <h3>DEBUG: AI Chat Component Loaded</h3>\r\n <p>Status: {{ configurationStatus || 'Loading...' }}</p>\r\n <p>Messages count: {{ messages.length || 0 }}</p>\r\n <p>Theme: {{ templateDesign || 'default' }}</p>\r\n <p>Size: {{ currentSize }} ({{ containerWidth }}x{{ containerHeight }})</p>\r\n </div>\r\n\r\n <div class=\"chat-header\">\r\n <div class=\"header-left\">\r\n <h2>{{ title }}</h2>\r\n <!-- Icon-only status indicator -->\r\n <div class=\"status-indicator-icon\" \r\n [ngClass]=\"{'status-ready': configurationStatus === 'AI Agent is ready', \r\n 'status-error': configurationStatus !== 'AI Agent is ready',\r\n 'status-loading': configurationStatus === 'Initializing...' || configurationStatus === 'Testing connection...'}\"\r\n [title]=\"configurationStatus\">\r\n </div>\r\n </div>\r\n \r\n <div class=\"header-controls\">\r\n <!-- Size Preset Buttons -->\r\n <div class=\"size-controls\" *ngIf=\"!isFullscreen\">\r\n <button class=\"control-button size-button\" \r\n (click)=\"applySizePreset('compact')\"\r\n [class.active]=\"currentSize === 'compact'\"\r\n title=\"Compact View\"\r\n attr.aria-label=\"Compact View\">\r\n <span class=\"icon-svg\" [innerHTML]=\"sanitizedIcons.compactView\"></span>\r\n </button>\r\n <button class=\"control-button size-button\" \r\n (click)=\"applySizePreset('default')\"\r\n [class.active]=\"currentSize === 'default'\"\r\n title=\"Default View\"\r\n attr.aria-label=\"Default View\">\r\n <span class=\"icon-svg\" [innerHTML]=\"sanitizedIcons.defaultView\"></span>\r\n </button>\r\n <button class=\"control-button size-button\" \r\n (click)=\"applySizePreset('expanded')\"\r\n [class.active]=\"currentSize === 'expanded'\"\r\n title=\"Expanded View\"\r\n attr.aria-label=\"Expanded View\">\r\n <span class=\"icon-svg\" [innerHTML]=\"sanitizedIcons.expandedView\"></span>\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"chat-messages\" #messagesContainer>\r\n <div *ngFor=\"let message of messages; let i = index; trackBy: trackByIndex\" class=\"message-wrapper\">\r\n <!-- Message -->\r\n <div class=\"message\" \r\n [ngClass]=\"{'user-message': message.isUser, 'ai-message': !message.isUser, 'loading-message': message.isLoading}\">\r\n \r\n <div class=\"message-content\">\r\n <div [innerHTML]=\"message.content\"></div>\r\n <div class=\"message-timestamp\">{{ getFormattedTime(message.timestamp) }}</div>\r\n </div>\r\n \r\n <div class=\"message-avatar\">\r\n <span *ngIf=\"message.isUser\" class=\"avatar-icon\" [innerHTML]=\"sanitizedIcons.userAvatar\"></span>\r\n <span *ngIf=\"!message.isUser && !message.isLoading\" class=\"avatar-icon\" [innerHTML]=\"sanitizedIcons.aiAvatar\"></span>\r\n <span *ngIf=\"message.isLoading\" class=\"avatar-icon loading-spinner\" [innerHTML]=\"sanitizedIcons.loadingAvatar\"></span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <div class=\"chat-input\">\r\n <!-- Attachments Preview -->\r\n <div class=\"attachments-preview\" *ngIf=\"selectedFiles.length > 0\">\r\n <div class=\"attachment-item\" *ngFor=\"let file of selectedFiles\">\r\n <svg class=\"attachment-icon\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <path d=\"M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48\"></path>\r\n </svg>\r\n <span class=\"attachment-name\">{{ file.name }}</span>\r\n <span class=\"attachment-size\">{{ getFileSizeFormatted(file.size) }}</span>\r\n <button class=\"remove-attachment\" (click)=\"removeAttachment(file.id)\" title=\"Remove\" attr.aria-label=\"Remove attachment\">\r\n <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\r\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\r\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\r\n </svg>\r\n </button>\r\n </div>\r\n </div>\r\n \r\n <div class=\"input-container\">\r\n <!-- File Upload Inputs (Hidden) -->\r\n <input type=\"file\" \r\n id=\"image-upload-input\" \r\n accept=\"image/*\" \r\n multiple \r\n (change)=\"onImageUpload($event)\"\r\n style=\"display: none;\"\r\n [disabled]=\"!enableImageUpload\">\r\n \r\n <input type=\"file\" \r\n id=\"file-upload-input\" \r\n accept=\".pdf,.doc,.docx,.txt,.csv\" \r\n multiple \r\n (change)=\"onFileUpload($event)\"\r\n style=\"display: none;\"\r\n [disabled]=\"!enableFileUpload\">\r\n \r\n <!-- Upload Buttons (Conditionally rendered) -->\r\n <div class=\"upload-buttons\" *ngIf=\"enableImageUpload || enableFileUpload\">\r\n <button *ngIf=\"enableImageUpload\" \r\n class=\"upload-button image-upload\" \r\n (click)=\"triggerImageUpload()\"\r\n [disabled]=\"isLoading\"\r\n title=\"Upload Image\"\r\n attr.aria-label=\"Upload Image\">\r\n <span class=\"icon-svg\" [innerHTML]=\"sanitizedIcons.imageUpload\"></span>\r\n </button>\r\n \r\n <button *ngIf=\"enableFileUpload\" \r\n class=\"upload-button file-upload\" \r\n (click)=\"triggerFileUpload()\"\r\n [disabled]=\"isLoading\"\r\n title=\"Attach File\"\r\n attr.aria-label=\"Attach File\">\r\n <span class=\"icon-svg\" [innerHTML]=\"sanitizedIcons.fileUpload\"></span>\r\n </button>\r\n </div>\r\n \r\n <textarea \r\n [(ngModel)]=\"currentInquiry\" \r\n (keypress)=\"onKeyPress($event)\"\r\n [placeholder]=\"placeholder\"\r\n rows=\"2\"\r\n [disabled]=\"isLoading\"\r\n class=\"inquiry-textarea\"\r\n attr.aria-label=\"Type your message\"></textarea>\r\n \r\n <button \r\n (click)=\"sendInquiry()\" \r\n [disabled]=\"!currentInquiry.trim() || isLoading\"\r\n class=\"send-button\"\r\n title=\"Send Message\"\r\n attr.aria-label=\"Send Message\">\r\n <span *ngIf=\"!isLoading\" class=\"icon-svg\" [innerHTML]=\"sanitizedIcons.send\"></span>\r\n <span *ngIf=\"isLoading\" class=\"icon-svg loading-icon\" [innerHTML]=\"sanitizedIcons.sendLoading\"></span>\r\n <span class=\"text\">{{ isLoading ? 'Sending...' : 'Send' }}</span>\r\n </button>\r\n </div>\r\n </div>\r\n</div>", styles: ["@charset \"UTF-8\";.ai-chat-container{display:flex;flex-direction:column;height:100vh;max-width:800px;margin:0 auto;background:#ffffff;border-radius:12px;overflow:hidden;position:relative;transition:all .25s cubic-bezier(.4,0,.2,1);box-shadow:0 2px 8px #00000014,0 4px 16px #0000000a;--icon-primary: #667eea;--icon-secondary: #6b7280;--icon-avatar-user: #667eea;--icon-avatar-ai: #764ba2;--icon-header: #ffffff;--icon-upload: #667eea;--icon-send: #ffffff;--icon-active: #667eea;--icon-disabled: #d1d5db;--icon-hover: #5568d3}.ai-chat-container.fullscreen{position:fixed!important;top:0!important;left:0!important;right:0!important;bottom:0!important;width:100vw!important;height:100vh!important;max-width:100vw!important;max-height:100vh!important;border-radius:0;z-index:99999;margin:0}.ai-chat-container.resizing{-webkit-user-select:none;user-select:none;cursor:nwse-resize;transition:none}.resize-handle{position:absolute;background:rgba(102,126,234,.3);transition:background .2s ease;z-index:10}.resize-handle:hover{background:rgba(102,126,234,.6)}.resize-handle.resize-handle-right{top:0;right:-4px;width:8px;height:100%;cursor:ew-resize}.resize-handle.resize-handle-corner{bottom:-4px;right:-4px;width:20px;height:20px;cursor:nwse-resize;border-radius:0 0 8px}.resize-handle.resize-handle-corner:after{content:\"\\22f0\";position:absolute;bottom:2px;right:2px;font-size:12px;color:#fffc}.debug-info{background:yellow;padding:10px;border:1px solid orange}.debug-info h3{margin:0;font-size:1.2rem}.debug-info p{margin:5px 0}.icon-svg{display:inline-block;width:20px;height:20px;color:var(--icon-secondary)}.icon-svg svg{width:100%;height:100%;stroke-width:2;transition:all .2s ease}.avatar-icon{display:inline-block;width:28px;height:28px}.avatar-icon svg{width:100%;height:100%}.chat-header{background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);color:#fff;padding:1rem 1.25rem;display:flex;justify-content:space-between;align-items:center;grid-gap:1rem;gap:1rem;flex-wrap:wrap;box-shadow:0 2px 4px #0000001a}.chat-header .header-left{display:flex;align-items:center;grid-gap:.75rem;gap:.75rem;flex:1;min-width:200px}.chat-header .header-left h2{margin:0;font-size:1.25rem;font-weight:600;letter-spacing:-.01em}.chat-header .header-controls{display:flex;align-items:center;grid-gap:.5rem;gap:.5rem}.chat-header .header-controls .icon-svg{color:var(--icon-header)}.chat-header .status-indicator-icon{width:10px;height:10px;border-radius:50%;background:rgba(255,255,255,.4);transition:all .3s ease;box-shadow:0 0 0 2px #fff3;cursor:help}.chat-header .status-indicator-icon.status-ready{background:#2ecc71;box-shadow:0 0 0 2px #2ecc714d,0 0 8px #2ecc7166}.chat-header .status-indicator-icon.status-error{background:#e74c3c;box-shadow:0 0 0 2px #e74c3c4d,0 0 8px #e74c3c66}.chat-header .status-indicator-icon.status-loading{background:#f39c12;box-shadow:0 0 0 2px #f39c124d;animation:pulse 1.5s ease-in-out infinite}@keyframes pulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.6;transform:scale(1.1)}}.size-controls{display:flex;grid-gap:.5rem;gap:.5rem;background:transparent;padding:0;border-radius:0;backdrop-filter:none}.control-button{background:transparent;border:none;border-radius:0;width:28px;height:28px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s cubic-bezier(.4,0,.2,1);color:#fff;padding:0}.control-button .icon-svg{width:18px;height:18px;color:var(--icon-header)}.control-button:hover:not(:disabled){opacity:.8;transform:scale(1.1)}.control-button:active:not(:disabled){transform:scale(.95)}.control-button.active{opacity:1;transform:scale(1.15)}.control-button:disabled{opacity:.4;cursor:not-allowed}.fullscreen-button{background:transparent}.fullscreen-button:hover:not(:disabled){opacity:.8;transform:scale(1.1)}.clear-button{background:transparent}.clear-button:hover:not(:disabled){opacity:.8;transform:scale(1.1);color:#fcc}.chat-messages{flex:1;overflow-y:auto;overflow-x:hidden;padding:1.25rem;display:flex;flex-direction:column;grid-gap:.875rem;gap:.875rem;scroll-behavior:smooth;background:#f8f9fa}.chat-messages::-webkit-scrollbar{width:6px}.chat-messages::-webkit-scrollbar-track{background:transparent}.chat-messages::-webkit-scrollbar-thumb{background:rgba(0,0,0,.15);border-radius:3px}.chat-messages::-webkit-scrollbar-thumb:hover{background:rgba(0,0,0,.25)}.message-wrapper{display:flex;flex-direction:column}.message{display:flex;max-width:75%;animation:fadeInSlide .25s cubic-bezier(.4,0,.2,1)}.message.user-message{align-self:flex-end;flex-direction:row-reverse}.message.user-message .message-content{background:linear-gradient(135deg,#667eea,#764ba2);color:#fff;border-radius:18px 18px 4px;box-shadow:0 1px 2px #0000001a}.message.user-message .avatar-icon{color:var(--icon-avatar-user)}.message.ai-message{align-self:flex-start}.message.ai-message .message-content{background:white;color:#1a1a1a;border-radius:18px 18px 18px 4px;border:1px solid #e8e8e8;box-shadow:0 1px 2px #0000000d}.message.ai-message .avatar-icon{color:var(--icon-avatar-ai)}.message.loading-message{opacity:.7}.message.loading-message .message-content{font-style:italic}@keyframes fadeInSlide{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.message-content{padding:.75rem 1rem;margin:0 .5rem;word-wrap:break-word;max-width:100%;line-height:1.5;font-size:.9375rem}.message-timestamp{font-size:.6875rem;opacity:.65;margin-top:.375rem;text-align:right;font-weight:500}.message-avatar{width:36px;height:36px;display:flex;align-items:center;justify-content:center;flex-shrink:0}.message-avatar .avatar-icon{opacity:.9}.loading-spinner{animation:spin 1.2s linear infinite;opacity:.7}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.chat-input{background:white;padding:1rem 1.25rem;border-top:1px solid #e8e8e8;display:flex;flex-direction:column;grid-gap:.75rem;gap:.75rem;box-shadow:0 -2px 8px #0000000a}.input-container{display:flex;grid-gap:.5rem;gap:.5rem;align-items:flex-end}.upload-buttons{display:flex;grid-gap:.5rem;gap:.5rem;flex-direction:column}.upload-button{background:#f5f5f5;border:1px solid #e0e0e0;border-radius:10px;width:42px;height:42px;cursor:pointer;display:flex;align-items:center;justify-content:center;transition:all .2s cubic-bezier(.4,0,.2,1)}.upload-button .icon-svg{width:20px;height:20px;color:var(--icon-upload)}.upload-button:hover:not(:disabled){background:var(--icon-upload);border-color:var(--icon-upload);transform:translateY(-1px);box-shadow:0 2px 8px #667eea40}.upload-button:hover:not(:disabled) .icon-svg{color:#fff}.upload-button:active:not(:disabled){transform:translateY(0)}.upload-button:disabled{opacity:.4;cursor:not-allowed;background:#fafafa}.attachments-preview{display:flex;flex-wrap:wrap;grid-gap:.5rem;gap:.5rem;padding:.75rem;background:#f8f9fa;border-radius:10px;border:1px solid #e8e8e8}.attachment-item{display:flex;align-items:center;grid-gap:.625rem;gap:.625rem;background:white;border:1px solid #e0e0e0;border-radius:8px;padding:.625rem .875rem;font-size:.875rem;transition:all .2s ease}.attachment-item:hover{border-color:#667eea;box-shadow:0 2px 4px #667eea1a}.attachment-item .attachment-icon{width:20px;height:20px;color:#667eea;flex-shrink:0}.attachment-item .attachment-name{font-weight:500;max-width:150px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#1a1a1a}.attachment-item .attachment-size{color:#666;font-size:.75rem;font-weight:500}.attachment-item .remove-attachment{background:transparent;border:none;color:#999;cursor:pointer;padding:.25rem;margin-left:.25rem;transition:all .2s ease;display:flex;align-items:center;justify-content:center;border-radius:4px}.attachment-item .remove-attachment svg{width:16px;height:16px}.attachment-item .remove-attachment:hover{color:#e74c3c;background:rgba(231,76,60,.1)}.inquiry-textarea{flex:1;border:1.5px solid #e0e0e0;border-radius:22px;padding:.875rem 1.125rem;font-family:inherit;font-size:.9375rem;line-height:1.5;resize:none;outline:none;transition:all .2s cubic-bezier(.4,0,.2,1);background:#fafafa}.inquiry-textarea:focus{border-color:#667eea;background:white;box-shadow:0 0 0 3px #667eea14}.inquiry-textarea:disabled{background:#f5f5f5;cursor:not-allowed;opacity:.6}.inquiry-textarea::placeholder{color:#999}.send-button{background:linear-gradient(135deg,#667eea,#764ba2);color:#fff;border:none;border-radius:50px;padding:.875rem 1.75rem;font-size:.9375rem;font-weight:600;cursor:pointer;display:flex;align-items:center;grid-gap:.5rem;gap:.5rem;transition:all .2s cubic-bezier(.4,0,.2,1);min-width:110px;justify-content:center;box-shadow:0 2px 8px #667eea40}.send-button .icon-svg{width:18px;height:18px;color:var(--icon-send)}.send-button .loading-icon{animation:spin 1.2s linear infinite}.send-button:hover:not(:disabled){transform:translateY(-1px);box-shadow:0 4px 16px #667eea66}.send-button:active:not(:disabled){transform:translateY(0)}.send-button:disabled{background:#d0d0d0;cursor:not-allowed;box-shadow:none;opacity:.6}@media (max-width: 768px){.ai-chat-container{max-width:100%;border-radius:0;height:100vh}.ai-chat-container:not(.fullscreen){width:100%!important}.resize-handle{display:none}.size-controls{display:none}.chat-header{padding:.875rem 1rem}.chat-header .header-left h2{font-size:1.125rem}.chat-header .status-indicator-icon{width:8px;height:8px}.control-button{width:36px;height:36px}.control-button .icon-svg{width:18px;height:18px}.message{max-width:85%}.message-content{font-size:.875rem}.upload-buttons{flex-direction:row}.input-container{flex-wrap:wrap}.send-button{min-width:90px;padding:.75rem 1.25rem}.send-button .text{display:none}.chat-input{padding:.875rem 1rem}}@media (max-width: 480px){.chat-header{flex-direction:column;align-items:flex-start;grid-gap:.625rem;gap:.625rem}.chat-header .header-controls{width:100%;justify-content:space-between}.control-button{width:34px;height:34px}.control-button .icon-svg{width:16px;height:16px}.message-content{padding:.625rem .875rem;font-size:.875rem}.attachments-preview{flex-direction:column}.attachment-item{width:100%}.attachment-item .attachment-name{max-width:120px}.send-button{padding:.75rem 1rem;min-width:80px}}.control-button:focus,.upload-button:focus,.send-button:focus,.clear-button:focus{outline:3px solid #667eea;outline-offset:2px}@media (prefers-contrast: high){.control-button,.upload-button,.send-button{border:2px solid currentColor}.message-content{border:2px solid currentColor}}@media (prefers-reduced-motion: reduce){*{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}.theme-dark{background:#2c2c2c;--icon-primary: #818cf8;--icon-secondary: #9ca3af;--icon-avatar-user: #818cf8;--icon-avatar-ai: #a78bfa;--icon-header: #e5e7eb;--icon-upload: #818cf8;--icon-send: #ffffff;--icon-active: #818cf8;--icon-disabled: #4b5563;--icon-hover: #6366f1}.theme-dark .chat-header{background:linear-gradient(135deg,#1a1a1a,#333)}.theme-dark .chat-messages{background:#2c2c2c}.theme-dark .ai-message .message-content{background:#3a3a3a;color:#fff;border-color:#555}.theme-dark .chat-input{background:#3a3a3a;border-color:#555}.theme-dark .inquiry-textarea{background:#2c2c2c;color:#fff;border-color:#555}.theme-dark .inquiry-textarea:focus{border-color:#667eea}.theme-dark .attachments-preview{background:#3a3a3a;border-color:#555}.theme-dark .attachment-item{background:#2c2c2c;border-color:#555;color:#fff}.theme-dark .upload-button{background:rgba(255,255,255,.1);border-color:#fff3}.theme-dark .upload-button:hover:not(:disabled){background:rgba(255,255,255,.2)}.theme-blue{background:#e3f2fd;--icon-primary: #1976d2;--icon-secondary: #546e7a;--icon-avatar-user: #1976d2;--icon-avatar-ai: #0288d1;--icon-header: #ffffff;--icon-upload: #1976d2;--icon-send: #ffffff;--icon-active: #1976d2;--icon-disabled: #b0bec5;--icon-hover: #1565c0}.theme-blue .chat-header{background:linear-gradient(135deg,#1976d2,#42a5f5)}.theme-blue .user-message .message-content{background:linear-gradient(135deg,#1976d2,#42a5f5)}.theme-blue .ai-message .message-content{border-color:#bbdefb}.theme-blue .inquiry-textarea:focus{border-color:#1976d2}.theme-blue .send-button{background:linear-gradient(135deg,#1976d2,#42a5f5)}.theme-blue .upload-button{background:rgba(25,118,210,.1);border-color:#1976d24d}.theme-blue .upload-button:hover:not(:disabled){background:rgba(25,118,210,.2)}.theme-green{background:#e8f5e8;--icon-primary: #388e3c;--icon-secondary: #546e7a;--icon-avatar-user: #388e3c;--icon-avatar-ai: #2e7d32;--icon-header: #ffffff;--icon-upload: #388e3c;--icon-send: #ffffff;--icon-active: #388e3c;--icon-disabled: #b0bec5;--icon-hover: #2e7d32}.theme-green .chat-header{background:linear-gradient(135deg,#388e3c,#66bb6a)}.theme-green .user-message .message-content{background:linear-gradient(135deg,#388e3c,#66bb6a)}.theme-green .ai-message .message-content{border-color:#c8e6c9}.theme-green .inquiry-textarea:focus{border-color:#388e3c}.theme-green .send-button{background:linear-gradient(135deg,#388e3c,#66bb6a)}.theme-green .upload-button{background:rgba(56,142,60,.1);border-color:#388e3c4d}.theme-green .upload-button:hover:not(:disabled){background:rgba(56,142,60,.2)}.theme-purple{background:#f3e5f5;--icon-primary: #7b1fa2;--icon-secondary: #6a1b9a;--icon-avatar-user: #7b1fa2;--icon-avatar-ai: #8e24aa;--icon-header: #ffffff;--icon-upload: #7b1fa2;--icon-send: #ffffff;--icon-active: #7b1fa2;--icon-disabled: #ce93d8;--icon-hover: #6a1b9a}.theme-purple .chat-header{background:linear-gradient(135deg,#7b1fa2,#ab47bc)}.theme-purple .user-message .message-content{background:linear-gradient(135deg,#7b1fa2,#ab47bc)}.theme-purple .ai-message .message-content{border-color:#e1bee7}.theme-purple .inquiry-textarea:focus{border-color:#7b1fa2}.theme-purple .send-button{background:linear-gradient(135deg,#7b1fa2,#ab47bc)}.theme-purple .upload-button{background:rgba(123,31,162,.1);border-color:#7b1fa24d}.theme-purple .upload-button:hover:not(:disabled){background:rgba(123,31,162,.2)}.theme-minimal{background:#fafafa;--icon-primary: #333333;--icon-secondary: #757575;--icon-avatar-user: #424242;--icon-avatar-ai: #616161;--icon-header: #333333;--icon-upload: #424242;--icon-send: #ffffff;--icon-active: #333333;--icon-disabled: #bdbdbd;--icon-hover: #212121}.theme-minimal .chat-header{background:#fff;color:#333;border-bottom:1px solid #e0e0e0}.theme-minimal .user-message .message-content{background:#007bff;color:#fff;border-radius:18px}.theme-minimal .ai-message .message-content{background:#f8f9fa;color:#333;border:1px solid #dee2e6}.theme-minimal .send-button{background:#007bff;border-radius:4px}.theme-minimal .upload-button{background:rgba(0,123,255,.1);border-color:#007bff4d}.theme-minimal .upload-button:hover:not(:disabled){background:rgba(0,123,255,.2)}.theme-corporate{background:#f8f9fa}.theme-corporate .chat-header{background:linear-gradient(135deg,#495057,#6c757d)}.theme-corporate .user-message .message-content{background:#495057}.theme-corporate .ai-message .message-content{background:#fff;border-color:#dee2e6}.theme-corporate .inquiry-textarea:focus{border-color:#495057}.theme-corporate .send-button{background:#495057}.theme-corporate .upload-button{background:rgba(73,80,87,.1);border-color:#4950574d}.theme-corporate .upload-button:hover:not(:disabled){background:rgba(73,80,87,.2)}.theme-red{background:#ffebee}.theme-red .chat-header{background:linear-gradient(135deg,#d32f2f,#f44336)}.theme-red .user-message .message-content{background:linear-gradient(135deg,#d32f2f,#f44336)}.theme-red .ai-message .message-content{border-color:#ffcdd2}.theme-red .inquiry-textarea:focus{border-color:#d32f2f}.theme-red .send-button{background:linear-gradient(135deg,#d32f2f,#f44336)}.theme-red .upload-button{background:rgba(211,47,47,.1);border-color:#d32f2f4d}.theme-red .upload-button:hover:not(:disabled){background:rgba(211,47,47,.2)}.theme-yellow{background:#fffde7}.theme-yellow .chat-header{background:linear-gradient(135deg,#f57f17,#ffb300)}.theme-yellow .user-message .message-content{background:linear-gradient(135deg,#f57f17,#ffb300)}.theme-yellow .ai-message .message-content{border-color:#fff9c4}.theme-yellow .inquiry-textarea:focus{border-color:#f57f17}.theme-yellow .send-button{background:linear-gradient(135deg,#f57f17,#ffb300)}.theme-yellow .upload-button{background:rgba(245,127,23,.1);border-color:#f57f174d}.theme-yellow .upload-button:hover:not(:disabled){background:rgba(245,127,23,.2)}.theme-orange{background:#fff3e0}.theme-orange .chat-header{background:linear-gradient(135deg,#e65100,#ff9800)}.theme-orange .user-message .message-content{background:linear-gradient(135deg,#e65100,#ff9800)}.theme-orange .ai-message .message-content{border-color:#ffe0b2}.theme-orange .inquiry-textarea:focus{border-color:#e65100}.theme-orange .send-button{background:linear-gradient(135deg,#e65100,#ff9800)}.theme-orange .upload-button{background:rgba(230,81,0,.1);border-color:#e651004d}.theme-orange .upload-button:hover:not(:disabled){background:rgba(230,81,0,.2)}\n"], directives: [{ type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i3.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i4.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i4.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] });
656
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: AiChatComponent, decorators: [{
657
+ type: Component,
658
+ args: [{
659
+ selector: 'emanate-ai-chat',
660
+ templateUrl: './ai-chat.component.html',
661
+ styleUrls: ['./ai-chat.component.scss']
662
+ }]
663
+ }], ctorParameters: function () { return [{ type: i1.AiAgentService }, { type: i2.DomSanitizer }]; }, propDecorators: { title: [{
664
+ type: Input
665
+ }], placeholder: [{
666
+ type: Input
667
+ }], showDebugInfo: [{
668
+ type: Input
669
+ }], apiUrl: [{
670
+ type: Input
671
+ }], appKey: [{
672
+ type: Input
673
+ }], appSource: [{
674
+ type: Input
675
+ }], userId: [{
676
+ type: Input
677
+ }], firstName: [{
678
+ type: Input
679
+ }], userName: [{
680
+ type: Input
681
+ }], templateDesign: [{
682
+ type: Input
683
+ }], welcomeMessage: [{
684
+ type: Input
685
+ }], historicalMessages: [{
686
+ type: Input
687
+ }], conversationId: [{
688
+ type: Input
689
+ }], enableImageUpload: [{
690
+ type: Input
691
+ }], enableFileUpload: [{
692
+ type: Input
693
+ }], iconSet: [{
694
+ type: Input
695
+ }], customIcons: [{
696
+ type: Input
697
+ }], messageReceived: [{
698
+ type: Output
699
+ }], messageSent: [{
700
+ type: Output
701
+ }], fileUploaded: [{
702
+ type: Output
703
+ }], sizeChanged: [{
704
+ type: Output
705
+ }] } });
706
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWktY2hhdC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9lbWFuYXRlLWFpLWNoYXQtbGliL3NyYy9saWIvY29tcG9uZW50cy9haS1jaGF0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2VtYW5hdGUtYWktY2hhdC1saWIvc3JjL2xpYi9jb21wb25lbnRzL2FpLWNoYXQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBK0MsTUFBTSxlQUFlLENBQUM7QUFFcEgsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMvQixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFM0MsT0FBTyxFQUErQixVQUFVLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQzs7Ozs7O0FBZ0MxRixNQUFNLE9BQU8sZUFBZTtJQTJEMUIsWUFDVSxjQUE4QixFQUM5QixTQUF1QjtRQUR2QixtQkFBYyxHQUFkLGNBQWMsQ0FBZ0I7UUFDOUIsY0FBUyxHQUFULFNBQVMsQ0FBYztRQTVEeEIsVUFBSyxHQUFXLG1CQUFtQixDQUFDO1FBQ3BDLGdCQUFXLEdBQVcsMkVBQTJFLENBQUM7UUFDbEcsa0JBQWEsR0FBWSxLQUFLLENBQUM7UUFXL0Isc0JBQWlCLEdBQVksS0FBSyxDQUFDLENBQUMscUNBQXFDO1FBQ3pFLHFCQUFnQixHQUFZLEtBQUssQ0FBQyxDQUFFLG9DQUFvQztRQUN4RSxZQUFPLEdBQWdCLFNBQVMsQ0FBQyxDQUFHLHFCQUFxQjtRQUV4RCxvQkFBZSxHQUFHLElBQUksWUFBWSxFQUFlLENBQUM7UUFDbEQsZ0JBQVcsR0FBRyxJQUFJLFlBQVksRUFBZSxDQUFDO1FBQzlDLGlCQUFZLEdBQUcsSUFBSSxZQUFZLEVBQWtCLENBQUM7UUFDbEQs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akIsS0FBSztnQkFDRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBQ0csY0FBYztzQkFBdEIsS0FBSztnQkFDRyxrQkFBa0I7c0JBQTFCLEtBQUs7Z0JBQ0csY0FBYztzQkFBdEIsS0FBSztnQkFDRyxpQkFBaUI7c0JBQXpCLEtBQUs7Z0JBQ0csZ0JBQWdCO3NCQUF4QixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNJLGVBQWU7c0JBQXhCLE1BQU07Z0JBQ0csV0FBVztzQkFBcEIsTUFBTTtnQkFDRyxZQUFZO3NCQUFyQixNQUFNO2dCQUNHLFdBQVc7c0JBQXBCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPdXRwdXQsIEV2ZW50RW1pdHRlciwgT25Jbml0LCBPbkRlc3Ryb3ksIE9uQ2hhbmdlcywgU2ltcGxlQ2hhbmdlcyB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBEb21TYW5pdGl6ZXIsIFNhZmVIdG1sIH0gZnJvbSAnQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlcic7XHJcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5pbXBvcnQgeyBBaUFnZW50U2VydmljZSwgQWdlbnRSZXNwb25zZSwgU3VwcG9ydEJvdFJlcXVlc3QsIFN1cHBvcnRCb3RSZXNwb25zZSwgQ2hhdENvbnRlbnQgfSBmcm9tICcuLi9zZXJ2aWNlcy9haS1hZ2VudC5zZXJ2aWNlJztcclxuaW1wb3J0IHsgSWNvblNldFR5cGUsIENoYXRJY29uQ29uZmlnLCBnZXRJY29uU2V0IH0gZnJvbSAnLi4vbW9kZWxzL2ljb24tY29uZmlnLmludGVyZmFjZSc7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIENoYXRNZXNzYWdlIHtcclxuICBtZXNzYWdlSWQ/OiBzdHJpbmc7ICAgICAgICAgICAvLyBVbmlxdWUgbWVzc2FnZSBpZGVudGlmaWVyXHJcbiAgY29udmVyc2F0aW9uSWQ/OiBzdHJpbmc7ICAgICAgIC8vIENvbnZlcnNhdGlvbi9zZXNzaW9uIGlkZW50aWZpZXJcclxuICBpc1VzZXI6IGJvb2xlYW47XHJcbiAgY29udGVudDogc3RyaW5nO1xyXG4gIHNlbmRlcj86IHN0cmluZzsgICAgICAgICAgICAgICAvLyBTZW5kZXIgbmFtZSAobWFwcyB0byB5b3VyICdzZW5kZXInIGZpZWxkKVxyXG4gIGludGVudD86IHN0cmluZztcclxuICBhdXRob3JOYW1lPzogc3RyaW5nO1xyXG4gIGNvbmZpZGVuY2VTY29yZT86IG51bWJlcjsgICAgICAvLyBBSSBjb25maWRlbmNlIHNjb3JlXHJcbiAgdGltZXN0YW1wOiBEYXRlO1xyXG4gIGlzTG9hZGluZz86IGJvb2xlYW47XHJcbiAgYXR0YWNobWVudHM/OiBGaWxlQXR0YWNobWVudFtdOyAvLyBGaWxlL0ltYWdlIGF0dGFjaG1lbnRzXHJcbn1cclxuXHJcbmV4cG9ydCBpbnRlcmZhY2UgRmlsZUF0dGFjaG1lbnQge1xyXG4gIGlkOiBzdHJpbmc7XHJcbiAgbmFtZTogc3RyaW5nO1xyXG4gIHR5cGU6IHN0cmluZztcclxuICBzaXplOiBudW1iZXI7XHJcbiAgdXJsPzogc3RyaW5nO1xyXG4gIGRhdGE/OiBzdHJpbmcgfCBBcnJheUJ1ZmZlcjtcclxufVxyXG5cclxuZXhwb3J0IHR5cGUgQ2hhdFNpemUgPSAnY29tcGFjdCcgfCAnZGVmYXVsdCcgfCAnZXhwYW5kZWQnIHwgJ2Z1bGxzY3JlZW4nO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdlbWFuYXRlLWFpLWNoYXQnLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9haS1jaGF0LmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9haS1jaGF0LmNvbXBvbmVudC5zY3NzJ11cclxufSlcclxuZXhwb3J0IGNsYXNzIEFpQ2hhdENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95LCBPbkNoYW5nZXMge1xyXG4gIEBJbnB1dCgpIHRpdGxlOiBzdHJpbmcgPSAnQ2hhdCB3aXRoIE1hZXN0cm8nO1xyXG4gIEBJbnB1dCgpIHBsYWNlaG9sZGVyOiBzdHJpbmcgPSAnVHlwZSB5b3VyIGlucXVpcnkgaGVyZS4uLiAoUHJlc3MgRW50ZXIgdG8gc2VuZCwgU2hpZnQrRW50ZXIgZm9yIG5ldyBsaW5lKSc7XHJcbiAgQElucHV0KCkgc2hvd0RlYnVnSW5mbzogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBJbnB1dCgpIGFwaVVybD86IHN0cmluZztcclxuICBASW5wdXQoKSBhcHBLZXk/OiBzdHJpbmc7XHJcbiAgQElucHV0KCkgYXBwU291cmNlPzogc3RyaW5nO1xyXG4gIEBJbnB1dCgpIHVzZXJJZD86IHN0cmluZztcclxuICBASW5wdXQoKSBmaXJzdE5hbWU/OiBzdHJpbmc7XHJcbiAgQElucHV0KCkgdXNlck5hbWU/OiBzdHJpbmc7XHJcbiAgQElucHV0KCkgdGVtcGxhdGVEZXNpZ24/OiBzdHJpbmc7XHJcbiAgQElucHV0KCkgd2VsY29tZU1lc3NhZ2U/OiBzdHJpbmc7XHJcbiAgQElucHV0KCkgaGlzdG9yaWNhbE1lc3NhZ2VzPzogYW55W107IC8vIEhpc3RvcmljYWwgbWVzc2FnZXMgZnJvbSBwYXJlbnRcclxuICBASW5wdXQoKSBjb252ZXJzYXRpb25JZD86IHN0cmluZzsgICAgLy8gQ3VycmVudCBjb252ZXJzYXRpb24gSURcclxuICBASW5wdXQoKSBlbmFibGVJbWFnZVVwbG9hZDogYm9vbGVhbiA9IGZhbHNlOyAvLyBFbmFibGUvZGlzYWJsZSBpbWFnZSB1cGxvYWQgYnV0dG9uXHJcbiAgQElucHV0KCkgZW5hYmxlRmlsZVVwbG9hZDogYm9vbGVhbiA9IGZhbHNlOyAgLy8gRW5hYmxlL2Rpc2FibGUgZmlsZSB1cGxvYWQgYnV0dG9uXHJcbiAgQElucHV0KCkgaWNvblNldDogSWNvblNldFR5cGUgPSAnZmVhdGhlcic7ICAgLy8gSWNvbiBzZXQgc2VsZWN0aW9uXHJcbiAgQElucHV0KCkgY3VzdG9tSWNvbnM/OiBQYXJ0aWFsPENoYXRJY29uQ29uZmlnPjsgLy8gQ3VzdG9tIGljb24gb3ZlcnJpZGVzXHJcbiAgQE91dHB1dCgpIG1lc3NhZ2VSZWNlaXZlZCA9IG5ldyBFdmVudEVtaXR0ZXI8Q2hhdE1lc3NhZ2U+KCk7XHJcbiAgQE91dHB1dCgpIG1lc3NhZ2VTZW50ID0gbmV3IEV2ZW50RW1pdHRlcjxDaGF0TWVzc2FnZT4oKTtcclxuICBAT3V0cHV0KCkgZmlsZVVwbG9hZGVkID0gbmV3IEV2ZW50RW1pdHRlcjxGaWxlQXR0YWNobWVudD4oKTtcclxuICBAT3V0cHV0KCkgc2l6ZUNoYW5nZWQgPSBuZXcgRXZlbnRFbWl0dGVyPHsgc2l6ZTogQ2hhdFNpemUsIHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyIH0+KCk7XHJcblxyXG4gIG1lc3NhZ2VzOiBDaGF0TWVzc2FnZVtdID0gW107XHJcbiAgY3VycmVudElucXVpcnkgPSAnJztcclxuICBhdXRob3JOYW1lID0gJyc7XHJcbiAgaW50ZW50ID0gJyc7XHJcbiAgaXNMb2FkaW5nID0gZmFsc2U7XHJcbiAgY29uZmlndXJhdGlvblN0YXR1cyA9ICcnO1xyXG4gIFxyXG4gIC8vIFJlc2l6aW5nIHByb3BlcnRpZXNcclxuICBjdXJyZW50U2l6ZTogQ2hhdFNpemUgPSAnZGVmYXVsdCc7XHJcbiAgaXNGdWxsc2NyZWVuID0gZmFsc2U7XHJcbiAgaXNSZXNpemluZyA9IGZhbHNlO1xyXG4gIGNvbnRhaW5lcldpZHRoID0gODAwO1xyXG4gIGNvbnRhaW5lckhlaWdodCA9IDYwMDtcclxuICBtaW5XaWR0aCA9IDQwMDtcclxuICBtYXhXaWR0aCA9IDE0MDA7XHJcbiAgbWluSGVpZ2h0ID0gNDAwO1xyXG4gIG1heEhlaWdodCA9IHdpbmRvdy5pbm5lckhlaWdodCAtIDEwMDtcclxuICBzdGFydFggPSAwO1xyXG4gIHN0YXJ0WSA9IDA7XHJcbiAgc3RhcnRXaWR0aCA9IDA7XHJcbiAgc3RhcnRIZWlnaHQgPSAwO1xyXG4gIFxyXG4gIC8vIEZpbGUgdXBsb2FkIHByb3BlcnRpZXNcclxuICBtYXhGaWxlU2l6ZSA9IDEwICogMTAyNCAqIDEwMjQ7IC8vIDEwTUJcclxuICBhbGxvd2VkSW1hZ2VUeXBlcyA9IFsnaW1hZ2UvcG5nJywgJ2ltYWdlL2pwZWcnLCAnaW1hZ2UvanBnJywgJ2ltYWdlL2dpZicsICdpbWFnZS93ZWJwJ107XHJcbiAgYWxsb3dlZEZpbGVUeXBlcyA9IFsnYXBwbGljYXRpb24vcGRmJywgJ2FwcGxpY2F0aW9uL21zd29yZCcsIFxyXG4gICAgJ2FwcGxpY2F0aW9uL3ZuZC5vcGVueG1sZm9ybWF0cy1vZmZpY2Vkb2N1bWVudC53b3JkcHJvY2Vzc2luZ21sLmRvY3VtZW50JyxcclxuICAgICd0ZXh0L3BsYWluJywgJ3RleHQvY3N2J107XHJcbiAgc2VsZWN0ZWRGaWxlczogRmlsZUF0dGFjaG1lbnRbXSA9IFtdO1xyXG4gIFxyXG4gIC8vIEljb24gY29uZmlndXJhdGlvblxyXG4gIGljb25zOiBDaGF0SWNvbkNvbmZpZyA9IGdldEljb25TZXQoJ2ZlYXRoZXInKTtcclxuICBzYW5pdGl6ZWRJY29uczogeyBba2V5OiBzdHJpbmddOiBTYWZlSHRtbCB9ID0ge307XHJcbiAgXHJcbiAgcHJpdmF0ZSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJpdmF0ZSBhaUFnZW50U2VydmljZTogQWlBZ2VudFNlcnZpY2UsXHJcbiAgICBwcml2YXRlIHNhbml0aXplcjogRG9tU2FuaXRpemVyXHJcbiAgKSB7fVxyXG5cclxuICBuZ09uSW5pdCgpOiB2b2lkIHtcclxuICAgIHRoaXMuY29uZmlndXJhdGlvblN0YXR1cyA9ICdJbml0aWFsaXppbmcuLi4nO1xyXG4gICAgY29uc29sZS5sb2coJ0FJIENoYXQgQ29tcG9uZW50IGluaXRpYWxpemVkJyk7XHJcbiAgICBcclxuICAgIC8vIExvYWQgaWNvbiBzZXRcclxuICAgIHRoaXMuaWNvbnMgPSBnZXRJY29uU2V0KHRoaXMuaWNvblNldCwgdGhpcy5jdXN0b21JY29ucyk7XHJcbiAgICB0aGlzLnNhbml0aXplSWNvbnMoKTtcclxuICAgIFxyXG4gICAgLy8gQ29uZmlndXJlIEFQSSBVUkwgYW5kIEFwcCBLZXkgaWYgcHJvdmlkZWRcclxuICAgIGlmICh0aGlzLmFwaVVybCB8fCB0aGlzLmFwcEtleSkge1xyXG4gICAgICB0aGlzLmFpQWdlbnRTZXJ2aWNlLmNvbmZpZ3VyZSh7IFxyXG4gICAgICAgIGFwaVVybDogdGhpcy5hcGlVcmwsXHJcbiAgICAgICAgYXBwS2V5OiB0aGlzLmFwcEtleSBcclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBcclxuICAgIHRyeSB7XHJcbiAgICAgIC8vIExvYWQgaGlzdG9yaWNhbCBtZXNzYWdlcyBpZiBwcm92aWRlZFxyXG4gICAgICBpZiAodGhpcy5oaXN0b3JpY2FsTWVzc2FnZXMgJiYgdGhpcy5oaXN0b3JpY2FsTWVzc2FnZXMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIHRoaXMubG9hZEhpc3RvcmljYWxNZXNzYWdlcyh0aGlzLmhpc3RvcmljYWxNZXNzYWdlcyk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5hZGRXZWxjb21lTWVzc2FnZSgpO1xyXG4gICAgICB9XHJcbiAgICAgIFxyXG4gICAgICB0aGlzLnRlc3RDb25maWd1cmF0aW9uKCk7XHJcbiAgICAgIHRoaXMubG9hZFNhdmVkU2l6ZSgpO1xyXG4gICAgICB0aGlzLmFwcGx5U2l6ZVByZXNldCh0aGlzLmN1cnJlbnRTaXplKTtcclxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIGR1cmluZyBjb21wb25lbnQgaW5pdGlhbGl6YXRpb246JywgZXJyb3IpO1xyXG4gICAgICB0aGlzLmNvbmZpZ3VyYXRpb25TdGF0dXMgPSAnSW5pdGlhbGl6YXRpb24gZXJyb3InO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xyXG4gICAgLy8gRGV0ZWN0IHdoZW4gaGlzdG9yaWNhbE1lc3NhZ2VzIGlucHV0IGNoYW5nZXNcclxuICAgIGlmIChjaGFuZ2VzWydoaXN0b3JpY2FsTWVzc2FnZXMnXSAmJiAhY2hhbmdlc1snaGlzdG9yaWNhbE1lc3NhZ2VzJ10uZmlyc3RDaGFuZ2UpIHtcclxuICAgICAgY29uc3QgbmV3TWVzc2FnZXMgPSBjaGFuZ2VzWydoaXN0b3JpY2FsTWVzc2FnZXMnXS5jdXJyZW50VmFsdWU7XHJcbiAgICAgIC8vIGNvbnNvbGUubG9nKCdIaXN0b3JpY2FsIG1lc3NhZ2VzIGNoYW5nZWQ6JywgbmV3TWVzc2FnZXMpO1xyXG4gICAgICBcclxuICAgICAgLy8gQ2xlYXIgZXhpc3RpbmcgbWVzc2FnZXMgYW5kIHJlbG9hZFxyXG4gICAgICB0aGlzLm1lc3NhZ2VzID0gW107XHJcbiAgICAgIFxyXG4gICAgICBpZiAobmV3TWVzc2FnZXMgJiYgbmV3TWVzc2FnZXMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIHRoaXMubG9hZEhpc3RvcmljYWxNZXNzYWdlcyhuZXdNZXNzYWdlcyk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5hZGRXZWxjb21lTWVzc2FnZSgpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBcclxuICAgIC8vIERldGVjdCB3aGVuIGNvbnZlcnNhdGlvbklkIGNoYW5nZXNcclxuICAgIGlmIChjaGFuZ2VzWydjb252ZXJzYXRpb25JZCddICYmICFjaGFuZ2VzWydjb252ZXJzYXRpb25JZCddLmZpcnN0Q2hhbmdlKSB7XHJcbiAgICAgIC8vIGNvbnNvbGUubG9nKCdDb252ZXJzYXRpb24gSUQgY2hhbmdlZDonLCBjaGFuZ2VzWydjb252ZXJzYXRpb25JZCddLmN1cnJlbnRWYWx1ZSk7XHJcbiAgICAgIC8vIFVwZGF0ZSBhbGwgZXhpc3RpbmcgbWVzc2FnZXMgd2l0aCBuZXcgY29udmVyc2F0aW9uSWQgaWYgbmVlZGVkXHJcbiAgICAgIHRoaXMubWVzc2FnZXMuZm9yRWFjaChtc2cgPT4ge1xyXG4gICAgICAgIGlmIChtc2cuY29udmVyc2F0aW9uSWQgIT09IHRoaXMuY29udmVyc2F0aW9uSWQpIHtcclxuICAgICAgICAgIG1zZy5jb252ZXJzYXRpb25JZCA9IHRoaXMuY29udmVyc2F0aW9uSWQ7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICAgIFxyXG4gICAgLy8gRGV0ZWN0IHdoZW4gaWNvbiBzZXQgY2hhbmdlc1xyXG4gICAgaWYgKGNoYW5nZXNbJ2ljb25TZXQnXSB8fCBjaGFuZ2VzWydjdXN0b21JY29ucyddKSB7XHJcbiAgICAgIHRoaXMuaWNvbnMgPSBnZXRJY29uU2V0KHRoaXMuaWNvblNldCwgdGhpcy5jdXN0b21JY29ucyk7XHJcbiAgICAgIHRoaXMuc2FuaXRpemVJY29ucygpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XHJcbiAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcclxuICAgIHRoaXMuZGVzdHJveSQuY29tcGxldGUoKTtcclxuICB9XHJcbiAgXHJcbiAgLyoqXHJcbiAgICogU2FuaXRpemUgaWNvbiBTVkcgc3RyaW5ncyBmb3Igc2FmZSByZW5kZXJpbmcgaW4gaW5uZXJIVE1MIGJpbmRpbmdzXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBzYW5pdGl6ZUljb25zKCk6IHZvaWQge1xyXG4gICAgdGhpcy5zYW5pdGl6ZWRJY29ucyA9IHt9O1xyXG4gICAgT2JqZWN0LmtleXModGhpcy5pY29ucykuZm9yRWFjaChrZXkgPT4ge1xyXG4gICAgICBjb25zdCBzdmdTdHJpbmcgPSB0aGlzLmljb25zW2tleSBhcyBrZXlvZiBDaGF0SWNvbkNvbmZpZ107XHJcbiAgICAgIGlmIChzdmdTdHJpbmcpIHtcclxuICAgICAgICB0aGlzLnNhbml0aXplZEljb25zW2tleV0gPSB0aGlzLnNhbml0aXplci5ieXBhc3NTZWN1cml0eVRydXN0SHRtbChzdmdTdHJpbmcpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHRlc3RDb25maWd1cmF0aW9uKCk6IHZvaWQge1xyXG4gICAgdGhpcy5jb25maWd1cmF0aW9uU3RhdHVzID0gJ1Rlc3RpbmcgY29ubmVjdGlvbi4uLic7XHJcbiAgICBcclxuICAgIHRoaXMuYWlBZ2VudFNlcnZpY2UudGVzdENvbmZpZ3VyYXRpb24oKVxyXG4gICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXHJcbiAgICAgIC5zdWJzY3JpYmUoe1xyXG4gICAgICAgIG5leHQ6IChyZXNwb25zZTogQWdlbnRSZXNwb25zZSkgPT4ge1xyXG4gICAgICAgICAgaWYgKHJlc3BvbnNlLnN1Y2Nlc3MpIHtcclxuICAgICAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uU3RhdHVzID0gJ0FJIEFnZW50IGlzIHJlYWR5JztcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuY29uZmlndXJhdGlvblN0YXR1cyA9IGBDb25maWd1cmF0aW9uIGVycm9yOiAke3Jlc3BvbnNlLmVycm9yfWA7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuICAgICAgICBlcnJvcjogKGVycm9yUmVzcG9uc2U6IGFueSkgPT4ge1xyXG4gICAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uU3RhdHVzID0gYENvbm5lY3Rpb24gZXJyb3I6IENhbm5vdCBjb25uZWN0IHRvIGJhY2tlbmQgc2VydmljZWA7XHJcbiAgICAgICAgICBjb25zb2xlLmVycm9yKCdBUEkgY29ubmVjdGlvbiB0ZXN0IGZhaWxlZDonLCBlcnJvclJlc3BvbnNlKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgYWRkV2VsY29tZU1lc3NhZ2UoKTogdm9pZCB7XHJcbiAgICBjb25zdCB3ZWxjb21lVGV4dCA9IHRoaXMud2VsY29tZU1lc3NhZ2UgfHwgXHJcbiAgICAgIGA8aDM+SGVsbG8gJHt0aGlzLmZpcnN0TmFtZX0hPC9oMz5IaSwgSSdtIE1hZXN0cm/igJR5b3VyIEFJIGFzc2lzdGFudC4gSSdtIGhlcmUgdG8gaGVscCB3aXRoIHlvdXIgcG9saWN5LXJlbGF0ZWQgaW5xdWlyaWVzLjxicj48YnI+SG93IGNhbiBJIGFzc2lzdCB5b3UgdG9kYXk/YDtcclxuICAgIFxyXG4gICAgdGhpcy5tZXNzYWdlcy5wdXNoKHtcclxuICAgICAgaXNVc2VyOiBmYWxzZSxcclxuICAgICAgY29udGVudDogd2VsY29tZVRleHQsIC8vIERvbid0IGZvcm1hdCBIVE1MIGNvbnRlbnQsIHVzZSBpdCBkaXJlY3RseVxyXG4gICAgICBpbnRlbnQ6ICd3ZWxjb21lJyxcclxuICAgICAgdGltZXN0YW1wOiBuZXcgRGF0ZSgpXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIExvYWQgYW5kIHRyYW5zZm9ybSBoaXN0b3JpY2FsIG1lc3NhZ2VzIGZyb20gcGFyZW50IGNvbXBvbmVudFxyXG4gICAqIEFjY2VwdHMgbWVzc2FnZXMgaW4gdGhlIGZvcm1hdCBmcm9tIHlvdXIgYmFja2VuZC9zdGF0ZSBtYW5hZ2VtZW50XHJcbiAgICovXHJcbiAgbG9hZEhpc3RvcmljYWxNZXNzYWdlcyhoaXN0b3JpY2FsTWVzc2FnZXM6IGFueVtdKTogdm9pZCB7XHJcbiAgICAvLyBjb25zb2xlLmxvZygnTG9hZGluZyBoaXN0b3JpY2FsIG1lc3NhZ2VzOicsIGhpc3RvcmljYWxNZXNzYWdlcyk7XHJcbiAgICAvLyBjb25zb2xlLmxvZygnTnVtYmVyIG9mIG1lc3NhZ2VzIHRvIGxvYWQ6JywgaGlzdG9yaWNhbE1lc3NhZ2VzLmxlbmd0aCk7XHJcbiAgICBcclxuICAgIC8vIFRyYW5zZm9ybSB5b3VyIGJhY2tlbmQgZm9ybWF0IHRvIENoYXRNZXNzYWdlIGZvcm1hdFxyXG4gICAgY29uc3QgdHJhbnNmb3JtZWRNZXNzYWdlczogQ2hhdE1lc3NhZ2VbXSA9IGhpc3RvcmljYWxNZXNzYWdlcy5tYXAoKG1zZzogYW55KSA9PiB7XHJcbiAgICAgIC8vIERldGVybWluZSBpZiBtZXNzYWdlIGlzIGZyb20gdXNlciBiYXNlZCBvbiBzZW5kZXIgb3Igcm9sZVxyXG4gICAgICBjb25zdCBpc1VzZXJNZXNzYWdlID0gdGhpcy5pc1VzZXJNZXNzYWdlKG1zZyk7XHJcbiAgICAgIFxyXG4gICAgICBjb25zdCB0cmFuc2Zvcm1lZCA9IHtcclxuICAgICAgICBtZXNzYWdlSWQ6IG1zZy5tZXNzYWdlSWQgfHwgbXNnLmlkLFxyXG4gICAgICAgIGNvbnZlcnNhdGlvbklkOiBtc2cuY29udmVyc2F0aW9uSWQgfHwgdGhpcy5jb252ZXJzYXRpb25JZCxcclxuICAgICAgICBpc1VzZXI6IGlzVXNlck1lc3NhZ2UsXHJcbiAgICAgICAgY29udGVudDogbXNnLm1lc3NhZ2VUZXh0IHx8IG1zZy5tZXNzYWdlIHx8IG1zZy50ZXh0IHx8IG1zZy5jb250ZW50IHx8ICcnLFxyXG4gICAgICAgIHNlbmRlcjogbXNnLnNlbmRlciB8fCAoaXNVc2VyTWVzc2FnZSA/IHRoaXMudXNlck5hbWUgfHwgJ1VzZXInIDogJ01hZXN0cm8nKSxcclxuICAgICAgICBpbnRlbnQ6IG1zZy5pbnRlbnQgfHwgJycsXHJcbiAgICAgICAgYXV0aG9yTmFtZTogbXNnLmF1dGhvck5hbWUgfHwgbXNnLnNlbmRlcixcclxuICAgICAgICBjb25maWRlbmNlU2NvcmU6IG1zZy5jb25maWRlbmNlU2NvcmUgfHwgbXNnLmNvbmZpZGVuY2UgfHwgMCxcclxuICAgICAgICB0aW1lc3RhbXA6IG1zZy50aW1lc3RhbXAgfHwgbXNnLmNyZWF0ZWRBdCBcclxuICAgICAgICAgID8gbmV3IERhdGUobXNnLnRpbWVzdGFtcCB8fCBtc2cuY3JlYXRlZEF0KSBcclxuICAgICAgICAgIDogbmV3IERhdGUoKSxcclxuICAgICAgICBpc0xvYWRpbmc6IGZhbHNlXHJcbiAgICAgIH0gYXMgQ2hhdE1lc3NhZ2U7XHJcbiAgICAgIFxyXG4gICAgICAvLyBjb25zb2xlLmxvZygnVHJhbnNmb3JtZWQgbWVzc2FnZTonLCB0cmFuc2Zvcm1lZCk7XHJcbiAgICAgIHJldHVybiB0cmFuc2Zvcm1lZDtcclxuICAgIH0pO1xyXG4gICAgXHJcbiAgICAvLyBTb3J0IG1lc3NhZ2VzIGJ5IHRpbWVzdGFtcCB0byBtYWludGFpbiBjaHJvbm9sb2dpY2FsIG9yZGVyXHJcbiAgICB0cmFuc2Zvcm1lZE1lc3NhZ2VzLnNvcnQoKGEsIGIpID0+IFxyXG4gICAgICBhLnRpbWVzdGFtcC5nZXRUaW1lKCkgLSBiLnRpbWVzdGFtcC5nZXRUaW1lKClcclxuICAgICk7XHJcbiAgICBcclxuICAgIC8vIGNvbnNvbGUubG9nKCdTb3J0ZWQgbWVzc2FnZXMgY291bnQ6JywgdHJhbnNmb3JtZWRNZXNzYWdlcy5sZW5ndGgpO1xyXG4gICAgXHJcbiAgICAvLyBBZGQgd2VsY29tZSBtZXNzYWdlIGZpcnN0IGlmIG5vIG1lc3NhZ2VzIG9yIGxvYWQgaGlzdG9yaWNhbCBtZXNzYWdlc1xyXG4gICAgaWYgKHRyYW5zZm9ybWVkTWVzc2FnZXMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgIC8vIGNvbnNvbGUubG9nKCdObyBtZXNzYWdlcyB0byBsb2FkLCBhZGRpbmcgd2VsY29tZSBtZXNzYWdlJyk7XHJcbiAgICAgIHRoaXMuYWRkV2VsY29tZU1lc3NhZ2UoKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIC8vIENoZWNrIGlmIGZpcnN0IG1lc3NhZ2UgaXMgYSB3ZWxjb21lIG1lc3NhZ2UsIGlmIG5vdCBhZGQgb25lXHJcbiAgICAgIGNvbnN0IGhhc1dlbGNvbWUgPSB0cmFuc2Zvcm1lZE1lc3NhZ2VzLnNvbWUobXNnID0+IFxyXG4gICAgICAgIG1zZy5pbnRlbnQgPT09ICd3ZWxjb21lJyB8fCBtc2cuY29udGVudC5pbmNsdWRlcygnSGVsbG8nKVxyXG4gICAgICApO1xyXG4gICAgICBcclxuICAgICAgaWYgKCFoYXNXZWxjb21lKSB7XHJcbiAgICAgICAgLy8gY29uc29sZS5sb2coJ05vIHdlbGNvbWUgbWVzc2FnZSBmb3VuZCwgYWRkaW5nIG9uZScpO1xyXG4gICAgICAgIHRoaXMuYWRkV2VsY29tZU1lc3NhZ2UoKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gY29uc29sZS5sb2coJ1B1c2hpbmcgdHJhbnNmb3JtZWQgbWVzc2FnZXMgdG8gbWVzc2FnZXMgYXJyYXknKTtcclxuICAgICAgdGhpcy5tZXNzYWdlcy5wdXNoKC4uLnRyYW5zZm9ybWVkTWVzc2FnZXMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGNvbnNvbGUubG9nKCdUb3RhbCBsb2FkZWQgbWVzc2FnZXMgaW4gY29tcG9uZW50OicsIHRoaXMubWVzc2FnZXMubGVuZ3RoKTtcclxuICAgIC8vIGNvbnNvbGUubG9nKCdNZXNzYWdlcyBhcnJheTonLCB0aGlzLm1lc3NhZ2VzKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEhlbHBlciBtZXRob2QgdG8gZGV0ZXJtaW5lIGlmIGEgbWVzc2FnZSBpcyBmcm9tIHRoZSB1c2VyXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBpc1VzZXJNZXNzYWdlKG1zZzogYW55KTogYm9vbGVhbiB7XHJcbiAgICAvLyBDaGVjayB2YXJpb3VzIHByb3BlcnRpZXMgdGhhdCBtaWdodCBpbmRpY2F0ZSB1c2VyIG1lc3NhZ2VcclxuICAgIGlmIChtc2cuaXNVc2VyICE9PSB1bmRlZmluZWQpIHJldHVybiBtc2cuaXNVc2VyO1xyXG4gICAgaWYgKG1zZy5yb2xlKSByZXR1cm4gbXNnLnJvbGUudG9Mb3dlckNhc2UoKSA9PT0gJ3VzZXInO1xyXG4gICAgaWYgKG1zZy5zZW5kZXIpIHtcclxuICAgICAgY29uc3Qgc2VuZGVyID0gbXNnLnNlbmRlci50b0xvd2VyQ2FzZSgpO1xyXG4gICAgICByZXR1cm4gc2VuZGVyID09PSAndXNlcicgfHwgXHJcbiAgICAgICAgICAgICBzZW5kZXIgPT09IHRoaXMudXNlck5hbWU/LnRvTG93ZXJDYXNlKCkgfHxcclxuICAgICAgICAgICAgIHNlbmRlciA9PT0gdGhpcy51c2VySWQ/LnRvTG93ZXJDYXNlKCkgfHxcclxuICAgICAgICAgICAgIHNlbmRlci5pbmNsdWRlcygndXNlcicpO1xyXG4gICAgfVxyXG4gICAgLy8gRGVmYXVsdCB0byBmYWxzZSAoYm90IG1lc3NhZ2UpIGlmIGNhbid0IGRldGVybWluZVxyXG4gICAgcmV0dXJuIGZhbHNlO1xyXG4gIH1cclxuXHJcbiAgc2VuZElucXVpcnkoKTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMuY3VycmVudElucXVpcnkudHJpbSgpIHx8IHRoaXMuaXNMb2FkaW5nKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCB1c2VyTWVzc2FnZTogQ2hhdE1lc3NhZ2UgPSB7XHJcbiAgICAgIG1lc3NhZ2VJZDogdGhpcy5nZW5lcmF0ZU1lc3NhZ2VJZCgpLFxyXG4gICAgICBjb252ZXJzYXRpb25JZDogdGhpcy5jb252ZXJzYXRpb25JZCxcclxuICAgICAgaXNVc2VyOiB0cnVlLFxyXG4gICAgICBzZW5kZXI6IHRoaXMudXNlck5hbWUgfHwgJ1VzZXInLFxyXG4gICAgICBpbnRlbnQ6IHRoaXMuaW50ZW50LFxyXG4gICAgICBjb250ZW50OiB0aGlzLmN1cnJlbnRJbnF1aXJ5LFxyXG4gICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKClcclxuICAgIH07XHJcbiAgICBcclxuICAgIHRoaXMubWVzc2FnZXMucHVzaCh1c2VyTWVzc2FnZSk7XHJcbiAgICB0aGlzLm1lc3NhZ2VTZW50LmVtaXQodXNlck1lc3NhZ2UpO1xyXG5cclxuICAgIC8vIEFkZCBsb2FkaW5nIG1lc3NhZ2VcclxuICAgIGNvbnN0IGxvYWRpbmdNZXNzYWdlOiBDaGF0TWVzc2FnZSA9IHtcclxuICAgICAgaXNVc2VyOiBmYWxzZSxcclxuICAgICAgaW50ZW50OiAnJyxcclxuICAgICAgY29udGVudDogJ1Byb2Nlc3NpbmcgeW91ciBpbnF1aXJ5Li4uJyxcclxuICAgICAgdGltZXN0YW1wOiBuZXcgRGF0ZSgpLFxyXG4gICAgICBpc0xvYWRpbmc6IHRydWVcclxuICAgIH07XHJcbiAgICB0aGlzLm1lc3NhZ2VzLnB1c2gobG9hZGluZ01lc3NhZ2UpO1xyXG5cclxuICAgIGNvbnN0IGlucXVpcnkgPSB0aGlzLmN1cnJlbnRJbnF1aXJ5LnRyaW0oKTtcclxuICAgIHRoaXMuY3VycmVudElucXVpcnkgPSAnJztcclxuICAgIHRoaXMuYXV0aG9yTmFtZSA9ICcnO1xyXG4gICAgdGhpcy5pbnRlbnQgPSAnJztcclxuICAgIHRoaXMuaXNMb2FkaW5nID0gdHJ1ZTtcclxuXHJcbiAgICBjb25zdCByZXF1ZXN0OiBTdXBwb3J0Qm90UmVxdWVzdCA9IHtcclxuICAgICAgcXVlcnk6IGlucXVpcnksXHJcbiAgICAgIGNoYXRIaXN0b3J5OiBbXSxcclxuICAgICAgdXNlcklkOiB0aGlzLnVzZXJJZCxcclxuICAgICAgdXNlck5hbWU6IHRoaXMudXNlck5hbWUsXHJcbiAgICAgIGFwcFNvdXJjZTogdGhpcy5hcHBTb3VyY2VcclxuICAgIH07XHJcblxyXG4gICAgdGhpcy5haUFnZW50U2VydmljZS5wcm9jZXNzSW5xdWlyeShyZXF1ZXN0KVxyXG4gICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXHJcbiAgICAgIC5zdWJzY3JpYmUoe1xyXG4gICAgICAgIG5leHQ6IChyZXNwb25zZTogU3VwcG9ydEJvdFJlc3BvbnNlKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLmlzTG9hZGluZyA9IGZhbHNlO1xyXG4gICAgICAgICAgXHJcbiAgICAgICAgICAvLyBSZW1vdmUgbG9hZGluZyBtZXNzYWdlXHJcbiAgICAgICAgICB0aGlzLm1lc3NhZ2VzID0gdGhpcy5tZXNzYWdlcy5maWx0ZXIobXNnID0+ICFtc2cuaXNMb2FkaW5nKTtcclxuICAgICAgICAgIFxyXG4gICAgICAgICAgaWYgKHJlc3BvbnNlLmFuc3dlciB8fCAocmVzcG9uc2UuY29udGVudHMgJiYgcmVzcG9uc2UuY29udGVudHMubGVuZ3RoID4gMCkpIHtcclxuICAgICAgICAgICAgaWYgKHJlc3BvbnNlLmFuc3dlcikge1xyXG4gICAgICAgICAgICAgIGNvbnN0IGJvdE1lc3NhZ2U6IENoYXRNZXNzYWdlID0ge1xyXG4gICAgICAgICAgICAgICAgbWVzc2FnZUlkOiB0aGlzLmdlbmVyYXRlTWVzc2FnZUlkKCksXHJcbiAgICAgICAgICAgICAgICBjb252ZXJzYXRpb25JZDogdGhpcy5jb252ZXJzYXRpb25JZCxcclxuICAgICAgICAgICAgICAgIGlzVXNlcjogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICBzZW5kZXI6ICdNYWVzdHJvJyxcclxuICAgICAgICAgICAgICAgIGludGVudDogcmVzcG9uc2Uuc2VhcmNoSW50ZW50IHx8IGlucXVpcnksXHJcbiAgICAgICAgICAgICAgICBjb250ZW50OiB0aGlzLmZvcm1hdE1lc3NhZ2VDb250ZW50KHJlc3BvbnNlLmFuc3dlciksXHJcbiAgICAgICAgICAgICAgICBhdXRob3JOYW1lOiByZXNwb25zZS5jb250ZW50cyAmJiByZXNwb25zZS5jb250ZW50cy5sZW5ndGggPiAwID8gcmVzcG9uc2UuY29udGVudHNbMF0uYXV0aG9yTmFtZSA6IHVuZGVmaW5lZCxcclxuICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogbmV3IERhdGUoKVxyXG4gICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgdGhpcy5tZXNzYWdlcy5wdXNoKGJvdE1lc3NhZ2UpO1xyXG4gICAgICAgICAgICAgIHRoaXMubWVzc2FnZVJlY2VpdmVkLmVtaXQoYm90TWVzc2FnZSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocmVzcG9uc2UuY29udGVudHMgJiYgcmVzcG9uc2UuY29udGVudHMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgIC8vIFB1c2ggZWFjaCBjb250ZW50IGFzIGEgc2VwYXJhdGUgbWVzc2FnZVxyXG4gICAgICAgICAgICAgIHJlc3BvbnNlLmNvbnRlbnRzLmZvckVhY2goY29udGVudEl0ZW0gPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKGNvbnRlbnRJdGVtLmNvbnRlbnQpIHtcclxuICAgICAgICAgICAgICAgICAgY29uc3QgYm90TWVzc2FnZTogQ2hhdE1lc3NhZ2UgPSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZUlkOiB0aGlzLmdlbmVyYXRlTWVzc2FnZUlkKCksXHJcbiAgICAgICAgICAgICAgICAgICAgY29udmVyc2F0aW9uSWQ6IHRoaXMuY29udmVyc2F0aW9uSWQsXHJcbiAgICAgICAgICAgICAgICAgICAgaXNVc2VyOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgICAgICBzZW5kZXI6IGNvbnRlbnRJdGVtLmF1dGhvck5hbWUgfHwgJ01hZXN0cm8nLFxyXG4gICAgICAgICAgICAgICAgICAgIGludGVudDogcmVzcG9uc2Uuc2VhcmNoSW50ZW50IHx8IGlucXVpcnksXHJcbiAgICAgICAgICAgICAgICAgICAgY29udGVudDogdGhpcy5mb3JtYXRNZXNzYWdlQ29udGVudChjb250ZW50SXRlbS5jb250ZW50IHx8ICdObyBjb250ZW50IGF2YWlsYWJsZScpLFxyXG4gICAgICAgICAgICAgICAgICAgIGF1dGhvck5hbWU6IGNvbnRlbnRJdGVtLmF1dGhvck5hbWUsXHJcbiAgICAgICAgICAgICAgICAgICAgdGltZXN0YW1wOiBuZXcgRGF0ZSgpXHJcbiAgICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgICAgICAgIHRoaXMubWVzc2FnZXMucHVzaChib3RNZXNzYWdlKTtcclxuICAgICAgICAgICAgICAgICAgdGhpcy5tZXNzYWdlUmVjZWl2ZWQuZW1pdChib3RNZXNzYWdlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgY29uc3QgZXJyb3JNZXNzYWdlOiBDaGF0TWVzc2FnZSA9IHtcclxuICAgICAgICAgICAgICBtZXNzYWdlSWQ6IHRoaXMuZ2VuZXJhdGVNZXNzYWdlSWQoKSxcclxuICAgICAgICAgICAgICBjb252ZXJzYXRpb25JZDogdGhpcy5jb252ZXJzYXRpb25JZCxcclxuICAgICAgICAgICAgICBpc1VzZXI6IGZhbHNlLFxyXG4gICAgICAgICAgICAgIHNlbmRlcjogJ01hZXN0cm8nLFxyXG4gICAgICAgICAgICAgIGludGVudDogaW5xdWlyeSxcclxuICAgICAgICAgICAgICBjb250ZW50OiBgU29ycnksIEkgZGlkbid0IHJlY2VpdmUgYSB2YWxpZCByZXNwb25zZS5gLFxyXG4gICAgICAgICAgICAgIGF1dGhvck5hbWU6IHRoaXMuYXV0aG9yTmFtZSxcclxuICAgICAgICAgICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKClcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgdGhpcy5tZXNzYWdlcy5wdXNoKGVycm9yTWVzc2FnZSk7XHJcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZVJlY2VpdmVkLmVtaXQoZXJyb3JNZXNzYWdlKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG4gICAgICAgIGVycm9yOiAoZXJyb3IpID0+IHtcclxuICAgICAgICAgIHRoaXMuaXNMb2FkaW5nID0gZmFsc2U7XHJcbiAgICAgICAgICBcclxuICAgICAgICAgIC8vIFJlbW92ZSBsb2FkaW5nIG1lc3NhZ2VcclxuICAgICAgICAgIHRoaXMubWVzc2FnZXMgPSB0aGlzLm1lc3NhZ2VzLmZpbHRlcihtc2cgPT4gIW1zZy5pc0xvYWRpbmcpO1xyXG4gICAgICAgICAgXHJcbiAgICAgICAgICBjb25zdCBlcnJvck1lc3NhZ2U6IENoYXRNZXNzYWdlID0ge1xyXG4gICAgICAgICAgICBtZXNzYWdlSWQ6IHRoaXMuZ2VuZXJhdGVNZXNzYWdlSWQoKSxcclxuICAgICAgICAgICAgY29udmVyc2F0aW9uSWQ6IHRoaXMuY29udmVyc2F0aW9uSWQsXHJcbiAgICAgICAgICAgIGlzVXNlcjogZmFsc2UsXHJcbiAgICAgICAgICAgIHNlbmRlcjogJ01hZXN0cm8nLFxyXG4gICAgICAgICAgICBpbnRlbnQ6IGlucXVpcnksXHJcbiAgICAgICAgICAgIGNvbnRlbnQ6ICdTb3JyeSwgSSBlbmNvdW50ZXJlZCBhbiBlcnJvciBwcm9jZXNzaW5nIHlvdXIgcmVxdWVzdC4gUGxlYXNlIHRyeSBhZ2Fpbi4nLFxyXG4gICAgICAgICAgICBhdXRob3JOYW1lOiB0aGlzLmF1dGhvck5hbWUsXHJcbiAgICAgICAgICAgIHRpbWVzdGFtcDogbmV3IERhdGUoKVxyXG4gICAgICAgICAgfTtcclxuICAgICAgICAgIHRoaXMubWVzc2FnZXMucHVzaChlcnJvck1lc3NhZ2UpO1xyXG4gICAgICAgICAgdGhpcy5tZXNzYWdlUmVjZWl2ZWQuZW1pdChlcnJvck1lc3NhZ2UpO1xyXG4gICAgICAgICAgXHJcbiAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBwcm9jZXNzaW5nIGlucXVpcnk6JywgZXJyb3IpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgfVxyXG5cclxuICBjbGVhckNoYXQoKTogdm9pZCB7XHJcbiAgICB0aGlzLm1lc3NhZ2VzID0gW107XHJcbiAgICB0aGlzLmFkZFdlbGNvbWVNZXNzYWdlKCk7XHJcbiAgfVxyXG5cclxuICBvbktleVByZXNzKGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XHJcbiAgICBpZiAoZXZlbnQua2V5ID09PSAnRW50ZXInICYmICFldmVudC5zaGlmdEtleSkge1xyXG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICB0aGlzLnNlbmRJbnF1aXJ5KCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICB0cmFja0J5SW5kZXgoaW5kZXg6IG51bWJlcik6IG51bWJlciB7XHJcbiAgICByZXR1cm4gaW5kZXg7XHJcbiAgfVxyXG5cclxuICBnZXRUaGVtZUNsYXNzKCk6IHN0cmluZyB7XHJcbiAgICAvLyBEZWZhdWx0IHRoZW1lIGlmIG5vIHRlbXBsYXRlIGRlc2lnbiBpcyBzcGVjaWZpZWRcclxuICAgIGlmICghdGhpcy50ZW1wbGF0ZURlc2lnbikge1xyXG4gICAgICByZXR1cm4gJ3RoZW1lLWRlZmF1bHQnO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFZhbGlkYXRlIGFuZCByZXR1cm4gdGhlbWUgY2xhc3NcclxuICAgIGNvbnN0IHZhbGlkVGhlbWVzID0gWydkZWZhdWx0JywgJ2RhcmsnLCAnYmx1ZScsICdncmVlbicsICdwdXJwbGUnLCAnbWluaW1hbCcsICdjb3Jwb3JhdGUnLCAncmVkJywgJ3llbGxvdycsICdvcmFuZ2UnXTtcclxuICAgIGNvbnN0IHRoZW1lID0gdGhpcy50ZW1wbGF0ZURlc2lnbi50b0xvd2VyQ2FzZSgpO1xyXG4gICAgXHJcbiAgICBpZiAodmFsaWRUaGVtZXMuaW5jbHVkZXModGhlbWUpKSB7XHJcbiAgICAgIHJldHVybiBgdGhlbWUtJHt0aGVtZX1gO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICAvLyBGYWxsYmFjayB0byBkZWZhdWx0IGlmIGludmFsaWQgdGhlbWVcclxuICAgIGNvbnNvbGUud2FybihgSW52YWxpZCB0aGVtZSAnJHt0aGlzLnRlbXBsYXRlRGVzaWdufScgcHJvdmlkZWQuIFVzaW5nIGRlZmF1bHQgdGhlbWUuYCk7XHJcbiAgICByZXR1cm4gJ3RoZW1lLWRlZmF1bHQnO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBmb3JtYXRNZXNzYWdlQ29udGVudChjb250ZW50OiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgaWYgKCFjb250ZW50KSByZXR1cm4gJyc7XHJcbiAgICBcclxuICAgIC8vIElmIGNvbnRlbnQgYWxyZWFkeSBjb250YWlucyBIVE1MIHRhZ3MsIHJldHVybiBhcy1pc1xyXG4gICAgaWYgKGNvbnRlbnQuaW5jbHVkZXMoJzwnKSAmJiBjb250ZW50LmluY2x1ZGVzKCc+JykpIHtcclxuICAgICAgcmV0dXJuIGNvbnRlbnQ7XHJcbiAgICB9XHJcbiAgICBcclxuICAgIC8vIENvbnZlcnQgbmV3bGluZXMgdG8gSFRNTCBicmVha3NcclxuICAgIGxldCBmb3JtYXR0ZWQgPSBjb250ZW50LnJlcGxhY2UoL1xcbi9nLCAnPGJyPicpO1xyXG4gICAgXHJcbiAgICAvLyBDb252ZXJ0IGVzY2FwZWQgbmV3bGluZXMgdG8gSFRNTCBicmVha3NcclxuICAgIGZvcm1hdHRlZCA9IGZvcm1hdHRlZC5yZXBsYWNlKC9cXFxcbi9nLCAnPGJyPicpO1xyXG4gICAgXHJcbiAgICAvLyBDb252ZXJ0IG1hcmtkb3duLXN0eWxlIGJvbGQgdG8gSFRNTFxyXG4gICAgZm9ybWF0dGVkID0gZm9ybWF0dGVkLnJlcGxhY2UoL1xcKlxcKiguKj8pXFwqXFwqL2csICc8c3Ryb25nPiQxPC9zdHJvbmc+Jyk7XHJcbiAgICBcclxuICAgIC8vIENvbnZlcnQgYnVsbGV0IHBvaW50cyB0byBIVE1MIGxpc3RzXHJcbiAgICBjb25zdCBsaW5lcyA9IGZvcm1hdHRlZC5zcGxpdCgnPGJyPicpO1xyXG4gICAgbGV0IGluTGlzdCA9IGZhbHNlO1xyXG4gICAgY29uc3QgcHJvY2Vzc2VkTGluZXM6IHN0cmluZ1tdID0gW107XHJcbiAgICBcclxuICAgIGZvciAobGV0IGxpbmUgb2YgbGluZXMpIHtcclxuICAgICAgaWYgKGxpbmUudHJpbSgpLnN0YXJ0c1dpdGgoJ+KAoiAnKSkge1xyXG4gICAgICAgIGlmICghaW5MaXN0KSB7XHJcbiAgICAgICAgICBwcm9jZXNzZWRMaW5lcy5wdXNoKCc8dWw+Jyk7XHJcbiAgICAgICAgICBpbkxpc3QgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBwcm9jZXNzZWRMaW5lcy5wdXNoKCc8bGk+JyArIGxpbmUucmVwbGFjZSgvXuKAoiAvLCAnJykgKyAnPC9saT4nKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBpZiAoaW5MaXN0KSB7XHJcbiAgICAgICAgICBwcm9jZXNzZWRMaW5lcy5wdXNoKCc8L3VsPicpO1xyXG4gICAgICAgICAgaW5MaXN0ID0gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHByb2Nlc3NlZExpbmVzLnB1c2gobGluZSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIFxyXG4gICAgaWYgKGluTGlzdCkge1xyXG4gICAgICBwcm9jZXNzZWRMaW5lcy5wdXNoKCc8L3VsPicpO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICByZXR1cm4gcHJvY2Vzc2VkTGluZXMuam9pbignPGJyPicpLnJlcGxhY2UoLzxicj48dWw+L2csICc8dWw+JykucmVwbGFjZSgvPFxcL3VsPjxicj4vZywgJzwvdWw+Jyk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdlbmVyYXRlU2Vzc2lvbklkKCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gJ3Nlc3Npb25fJyArIE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnN1YnN0cigyLCA5KSArICdfJyArIERhdGUubm93KCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdlbmVyYXRlTWVzc2FnZUlkKCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gJ21zZ18nICsgTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc3Vic3RyKDIsIDkpICsgJ18nICsgRGF0ZS5ub3coKTtcclxuICB9XHJcblxyXG4gIGdldEZvcm1hdHRlZFRpbWUodGltZXN0YW1wOiBEYXRlKTogc3RyaW5nIHtcclxuICAgIHJldHVybiB0aW1lc3RhbXAudG9Mb2NhbGVUaW1lU3RyaW5nKFtdLCB7IGhvdXI6ICcyLWRpZ2l0JywgbWludXRlOiAnMi1kaWdpdCcgfSk7XHJcbiAgfVxyXG5cclxuICAvLyA9PT09PT09PT09PT09IFJlc2l6ZSBNZXRob2RzID09PT09PT09PT09PT1cclxuICBcclxuICBzdGFydFJlc2l6ZShldmVudDogTW91c2VFdmVudCwgZGlyZWN0aW9uOiAnd2lkdGgnIHwgJ2JvdGgnKTogdm9pZCB7XHJcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgdGhpcy5pc1Jlc2l6aW5nID0gdHJ1ZTtcclxuICAgIHRoaXMuc3RhcnRYID0gZXZlbnQuY2xpZW50WDtcclxuICAgIHRoaXMuc3RhcnRZID0gZXZlbnQuY2xpZW50WTtcclxuICAgIHRoaXMuc3RhcnRXaWR0aCA9IHRoaXMuY29udGFpbmVyV2lkdGg7XHJcbiAgICB0aGlzLnN0YXJ0SGVpZ2h0ID0gdGhpcy5jb250YWluZXJIZWlnaHQ7XHJcbiAgICBcclxuICAgIGNvbnN0IG1vdXNlTW92ZUhhbmRsZXIgPSAoZTogTW91c2VFdmVudCkgPT4gdGhpcy5vblJlc2l6ZShlLCBkaXJlY3Rpb24pO1xyXG4gICAgY29uc3QgbW91c2VVcEhhbmRsZXIgPSAoKSA9PiB0aGlzLnN0b3BSZXNpemUobW91c2VNb3ZlSGFuZGxlciwgbW91c2VVcEhhbmRsZXIpO1xyXG4gICAgXHJcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCBtb3VzZU1vdmVIYW5kbGVyKTtcclxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCBtb3VzZVVwSGFuZGxlcik7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIG9uUmVzaXplKGV2ZW50OiBNb3VzZUV2ZW50LCBkaXJlY3Rpb246ICd3aWR0aCcgfCAnYm90aCcpOiB2b2lkIHtcclxuICAgIGlmICghdGhpcy5pc1Jlc2l6aW5nKSByZXR1cm47XHJcbiAgICBcclxuICAgIGNvbnN0IGRlbHRhWCA9IGV2ZW50LmNsaWVudFggLSB0aGlzLnN0YXJ0WDtcclxuICAgIGNvbnN0IGRlbHRhWSA9IGV2ZW50LmNsaWVudFkgLSB0aGlzLnN0YXJ0WTtcclxuICAgIFxyXG4gICAgaWYgKGRpcmVjdGlvbiA9PT0gJ3dpZHRoJyB8fCBkaXJlY3Rpb24gPT09ICdib3RoJykge1xyXG4gICAgICBjb25zdCBuZXdXaWR0aCA9IE1hdGgubWluKFxyXG4gICAgICAgIE1hdGgubWF4KHRoaXMuc3RhcnRXaWR0aCArIGRlbHRhWCwgdGhpcy5taW5XaWR0aCksXHJcbiAgICAgICAgdGhpcy5tYXhXaWR0aFxyXG4gICAgICApO1xyXG4gICAgICB0aGlzLmNvbnRhaW5lcldpZHRoID0gbmV3V2lkdGg7XHJcbiAgICB9XHJcbiAgICBcclxuICAgIGlmIChkaXJlY3Rpb24gPT09ICdib3RoJykge1xyXG4gICAgICBjb25zdCBuZXdIZWlnaHQgPSBNYXRoLm1pbihcclxuICAgICAgICBNYXRoLm1heCh0aGlzLnN0YXJ0SGVpZ2h0ICsgZGVsdGFZLCB0aGlzLm1pbkhlaWdodCksXHJcbiAgICAgICAgdGhpcy5tYXhIZWlnaHRcclxuICAgICAgKTtcclxuICAgICAgdGhpcy5jb250YWluZXJIZWlnaHQgPSBuZXdIZWlnaHQ7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHN0b3BSZXNpemUobW91c2VNb3ZlSGFuZGxlcjogKGU6IE1vdXNlRXZlbnQpID0+IHZvaWQsIG1vdXNlVXBIYW5kbGVyOiAoKSA9PiB2b2lkKTogdm9pZCB7XHJcbiAgICB0aGlzLmlzUmVzaXppbmcgPSBmYWxzZTtcclxuICAgIGRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlbW92ZScsIG1vdXNlTW92ZUhhbmRsZXIpO1xyXG4gICAgZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIG1vdXNlVXBIYW5kbGVyKTtcclxuICAgIFxyXG4gICAgdGhpcy5zYXZlU2l6ZVByZWZlcmVuY2UoKTtcclxuICAgIHRoaXMuZW1pdFNpemVDaGFuZ2UoKTtcclxuICB9XHJcblxyXG4gIGFwcGx5U2l6ZVByZXNldChzaXplOiBDaGF0U2l6ZSk6IHZvaWQge1xyXG4gICAgdGhpcy5jdXJyZW50U2l6ZSA9IHNpemU7XHJcbiAgICBcclxuICAgIHN3aXRjaCAoc2l6ZSkge1xyXG4gICAgICBjYXNlICdjb21wYWN0JzpcclxuICAgICAgICB0aGlzLmNvbnRhaW5lcldpZHRoID0gNDAwO1xyXG4gICAgICAgIHRoaXMuY29udGFpbmVySGVpZ2h0ID0gNTAwO1xyXG4gICAgICAgIHRoaXMuaXNGdWxsc2NyZWVuID0gZmFsc2U7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIGNhc2UgJ2RlZmF1bHQnOlxyXG4gICAgICAgIHRoaXMuY29udGFpbmVyV2lkdGggPSA4MDA7XHJcbiAgICAgICAgdGhpcy5jb250YWluZXJIZWlnaHQgPSA2MDA7XHJcbiAgICAgICAgdGhpcy5pc0Z1bGxzY3JlZW4gPSBmYWxzZTtcclxuICAgICAgICBicmVhaztcclxuICAgICAgY2FzZSAnZXhwYW5kZWQnOlxyXG4gICAgICAgIHRoaXMuY29udGFpbmVyV2lkdGggPSAxMjAwO1xyXG4gICAgICAgIHRoaXMuY29udGFpbmVySGVpZ2h0ID0gODAwO1xyXG4gICAgICAgIHRoaXMuaXNGdWxsc2NyZWVuID0gZmFsc2U7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIGNhc2UgJ2Z1bGxzY3JlZW4nOlxyXG4gICAgICAgIHRoaXMudG9nZ2xlRnVsbHNjcmVlbigpO1xyXG4gICAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIFxyXG4gICAgdGhpcy5zYXZlU2l6ZVByZWZlcmVuY2UoKTtcclxuICAgIHRoaXMuZW1pdFNpemVDaGFuZ2UoKTtcclxuICB9XHJcblxyXG4gIHRvZ2dsZUZ1bGxzY3JlZW4oKTogdm9pZCB7XHJcbiAgICBpZiAoIXRoaXMuaXNGdWxsc2NyZWVuKSB7XHJcbiAgICAgIC8vIEVudGVyaW5nIGZ1bGxzY3JlZW4gLSBzYXZlIGN1cnJlbnQgc3RhdGUgZmlyc3RcclxuICAgICAgc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbSgnY2hhdGJveC1wcmV2aW91cy1zaXplJywgSlNPTi5zdHJpbmdpZnkoe1xyXG4gICAgICAgIHdpZHRoOiB0aGlzLmNvbnRhaW5lcldpZHRoLFxyXG4gICAgICAgIGhlaWdodDogdGhpcy5jb250YWluZXJIZWlnaHQsXHJcbiAgICAgICAgc2l6ZTogdGhpcy5jdXJyZW50U2l6ZSxcclxuICAgICAgICB3YXNGdWxsc2NyZWVuOiB0aGlzLmlzRnVsbHNjcmVlblxyXG4gICAgICB9KSk7XHJcbiAgICAgIFxyXG4gICAgICB0aGlzLmlzRnVsbHNjcmVlbiA9IHRydWU7XHJcbiAgICAgIHRoaXMuY3VycmVudFNpemUgPSAnZnVsbHNjcmVlbic7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAvLyBFeGl0aW5nIGZ1bGxzY3JlZW4gLSByZXN0b3JlIHByZXZpb3VzIHN0YXRlXHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgY29uc3QgcHJldmlvdXMgPSBzZXNzaW9uU3RvcmFnZS5nZXRJdGVtKCdjaGF0Ym94LXByZXZpb3VzLXNpemUnKTtcclxuICAgICAgICBpZiAocHJldmlvdXMpIHtcclxuICAgICAgICAgIGNvbnN0IHByZXZEYXRhID0gSlNPTi5wYXJzZShwcmV2aW91cyk7XHJcbiAgICAgICAgICB0aGlzLmNvbnRhaW5lcldpZHRoID0gcHJldkRhdGEud2lkdGggfHwgODAwO1xyXG4gICAgICAgICAgdGhpcy5jb250YWluZXJIZWlnaHQgPSBwcmV2RGF0YS5oZWlnaHQgfHwgNjAwO1xyXG4gICAgICAgICAgdGhpcy5jdXJyZW50U2l6ZSA9IHByZXZEYXRhLnNpemUgPT09ICdmdWxsc2NyZWVuJyA/ICdkZWZhdWx0JyA6IHByZXZEYXRhLnNpemU7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRoaXMuY3VycmVudFNpemUgPSAnZGVmYXVsdCc7XHJcbiAgICAgICAgICB0aGlzLmNvbnRhaW5lcldpZHRoID0gODAwO1xyXG4gICAgICAgICAgdGhpcy5jb250YWluZXJIZWlnaHQgPSA2MDA7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICAgIHRoaXMuY3VycmVudFNpemUgPSAnZGVmYXVsdCc7XHJcbiAgICAgICAgdGhpcy5jb250YWluZXJXaWR0aCA9IDgwMDtcclxuICAgICAgICB0aGlzLmNvbnRhaW5lckhlaWdodCA9IDYwMDtcclxuICAgICAgfVxyXG4gICAgICBcclxuICAgICAgdGhpcy5pc0Z1bGxzY3JlZW4gPSBmYWxzZTtcclxuICAgIH1cclxuICAgIFxyXG4gICAgdGhpcy5zYXZlU2l6ZVByZWZlcmVuY2UoKTtcclxuICAgIHRoaXMuZW1pdFNpemVDaGFuZ2UoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgc2F2ZVNpemVQcmVmZXJlbmNlKCk6IHZvaWQge1xyXG4gICAgY29uc3Qgc2l6ZURhdGEgPSB7XHJcbiAgICAgIHNpemU6IHRoaXMuY3VycmVudFNpemUsXHJcbiAgICAgIHdpZHRoOiB0aGlzLmNvbnRhaW5lcldpZHRoLFxyXG4gICAgICBoZWlnaHQ6IHRoaXMuY29udGFpbmVySGVpZ2h0LFxyXG4gICAgICBpc0Z1bGxzY3JlZW46IHRoaXMuaXNGdWxsc2NyZWVuXHJcbiAgICB9O1xyXG4gICAgXHJcbiAgICB0cnkge1xyXG4gICAgICBzZXNzaW9uU3RvcmFnZS5zZXRJdGVtKCdjaGF0Ym94LXNpemUtcHJlZmVyZW5jZScsIEpTT04uc3RyaW5naWZ5KHNpemVEYXRhKSk7XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICBjb25zb2xlLndhcm4oJ0ZhaWxlZCB0byBzYXZlIHNpemUgcHJlZmVyZW5jZTonLCBlcnJvcik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGxvYWRTYXZlZFNpemUoKTogdm9pZCB7XHJcbiAgICB0cnkge1xyXG4gICAgICBjb25zdCBzYXZlZCA9IHNlc3Npb25TdG9yYWdlLmdldEl0ZW0oJ2NoYXRib3gtc2l6ZS1wcmVmZXJlbmNlJyk7XHJcbiAgICAgIGlmIChzYXZlZCkge1xyXG4gICAgICAgIGNvbnN0IHNpemVEYXRhID0gSlNPTi5wYXJzZShzYXZlZCk7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50U2l6ZSA9IHNpemVEYXRhLnNpemUgfHwgJ2RlZmF1bHQnO1xyXG4gICAgICAgIHRoaXMuY29udGFpbmVyV2lkdGggPSBzaXplRGF0YS53aWR0aCB8fCA4MDA7XHJcbiAgICAgICAgdGhpcy5jb250YWluZXJIZWlnaHQgPSBzaXplRGF0YS5oZWlnaHQgfHwgNjAwO1xyXG4gICAgICAgIHRoaXMuaXNGdWxsc2NyZWVuID0gc2l6ZURhdGEuaXNGdWxsc2NyZWVuIHx8IGZhbHNlO1xyXG4gICAgICB9XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICBjb25zb2xlLndhcm4oJ0ZhaWxlZCB0byBsb2FkIHNpemUgcHJlZmVyZW5jZTonLCBlcnJvcik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGVtaXRTaXplQ2hhbmdlKCk6IHZvaWQge1xyXG4gICAgdGhpcy5zaXplQ2hhbmdlZC5lbWl0KHtcclxuICAgICAgc2l6ZTogdGhpcy5jdXJyZW50U2l6ZSxcclxuICAgICAgd2lkdGg6IHRoaXMuY29udGFpbmVyV2lkdGgsXHJcbiAgICAgIGhlaWdodDogdGhpcy5jb250YWluZXJIZWlnaHRcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgZ2V0Q29udGFpbmVyU3R5bGUoKTogYW55IHtcclxuICAgIGlmICh0aGlzLmlzRnVsbHNjcmVlbikge1xyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIHdpZHRoOiAnMTAwdncgIWltcG9ydGFudCcsXHJcbiAgICAgICAgaGVpZ2h0OiAnMTAwdmggIWltcG9ydGFudCcsXHJcbiAgICAgICAgbWF4V2lkdGg6ICcxMDB2dyAhaW1wb3J0YW50JyxcclxuICAgICAgICBtYXhIZWlnaHQ6ICcxMDB2aCAhaW1wb3J0YW50JyxcclxuICAgICAgICBwb3NpdGlvbjogJ2ZpeGVkJyxcclxuICAgICAgICB0b3A6ICcwJyxcclxuICAgICAgICBsZWZ0OiAnMCcsXHJcbiAgICAgICAgcmlnaHQ6ICcwJyxcclxuICAgICAgICBib3R0b206ICcwJyxcclxuICAgICAgICBtYXJnaW46ICcwJyxcclxuICAgICAgICB6SW5kZXg6IDk5OTk5XHJcbiAgICAgIH07XHJcbiAgICB9XHJcbiAgICBcclxuICAgIHJldHVybiB7XHJcbiAgICAgIHdpZHRoOiBgJHt0aGlzLmNvbnRhaW5lcldpZHRofXB4YCxcclxuICAgICAgaGVpZ2h0OiBgJHt0aGlzLmNvbnRhaW5lckhlaWdodH1weGAsXHJcbiAgICAgIG1heFdpZHRoOiBgJHt0aGlzLm1heFdpZHRofXB4YFxyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIC8vID09PT09PT09PT09PT0gRmlsZSBVcGxvYWQgTWV0aG9kcyA9PT09PT09PT09PT09XHJcbiAgXHJcbiAgb25JbWFnZVVwbG9hZChldmVudDogRXZlbnQpOiB2b2lkIHtcclxuICAgIGNvbnN0IGlucHV0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQ7XHJcbiAgICBpZiAoaW5wdXQuZmlsZXMgJiYgaW5wdXQuZmlsZXMubGVuZ3RoID4gMCkge1xyXG4gICAgICB0aGlzLmhhbmRsZUZpbGVTZWxlY3Rpb24oQXJyYXkuZnJvbShpbnB1dC5maWxlcyksICdpbWFnZScpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgb25GaWxlVXBsb2FkKGV2ZW50OiBFdmVudCk6IHZvaWQge1xyXG4gICAgY29uc3QgaW5wdXQgPSBldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudDtcclxuICAgIGlmIChpbnB1dC5maWxlcyAmJiBpbnB1dC5maWxlcy5sZW5ndGggPiAwKSB7XHJcbiAgICAgIHRoaXMuaGFuZGxlRmlsZVNlbGVjdGlvbihBcnJheS5mcm9tKGlucHV0LmZpbGVzKSwgJ2ZpbGUnKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgaGFuZGxlRmlsZVNlbGVjdGlvbihmaWxlczogRmlsZVtdLCB0eXBlOiAnaW1hZ2UnIHwgJ2ZpbGUnKTogdm9pZCB7XHJcbiAgICBmaWxlcy5mb3JFYWNoKGZpbGUgPT4ge1xyXG4gICAgICAvLyBWYWxpZGF0ZSBmaWxlIHR5cGVcclxuICAgICAgY29uc3QgYWxsb3dlZFR5cGVzID0gdHlwZSA9PT0gJ2ltYWdlJyA/IHRoaXMuYWxsb3dlZEltYWdlVHlwZXMgOiB0aGlzLmFsbG93ZWRGaWxlVHlwZXM7XHJcbiAgICAgIGlmICghYWxsb3dlZFR5cGVzLmluY2x1ZGVzKGZpbGUudHlwZSkpIHtcclxuICAgICAgICBjb25zb2xlLndhcm4oYEZpbGUgdHlwZSAke2ZpbGUudHlwZX0gbm90IGFsbG93ZWRgKTtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIFZhbGlkYXRlIGZpbGUgc2l6ZVxyXG4gICAgICBpZiAoZmlsZS5zaXplID4gdGhpcy5tYXhGaWxlU2l6ZSkge1xyXG4gICAgICAgIGNvbnNvbGUud2FybihgRmlsZSAke2ZpbGUubmFtZX0gZXhjZWVkcyBtYXhpbXVtIHNpemUgb2YgJHt0aGlzLm1heEZpbGVTaXplIC8gMTAyNCAvIDEwMjR9TUJgKTtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGNvbnN0IHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XHJcbiAgICAgIHJlYWRlci5vbmxvYWQgPSAoZTogUHJvZ3Jlc3NFdmVudDxGaWxlUmVhZGVyPikgPT4ge1xyXG4gICAgICAgIGNvbnN0IGF0dGFjaG1lbnQ6IEZpbGVBdHRhY2htZW50ID0ge1xyXG4gICAgICAgICAgaWQ6IHRoaXMuZ2VuZXJhdGVNZXNzYWdlSWQoKSxcclxuICAgICAgICAgIG5hbWU6IGZpbGUubmFtZSxcclxuICAgICAgICAgIHR5cGU6IGZpbGUudHlwZSxcclxuICAgICAgICAgIHNpemU6IGZpbGUuc2l6ZSxcclxuICAgICAgICAgIGRhdGE6IGUudGFyZ2V0Py5yZXN1bHQgfHwgdW5kZWZpbmVkXHJcbiAgICAgICAgfTtcclxuICAgICAgICBcclxuICAgICAgICB0aGlzLnNlbGVjdGVkRmlsZXMucHVzaChhdHRhY2htZW50KTtcclxuICAgICAgICB0aGlzLmZpbGVVcGxvYWRlZC5lbWl0KGF0dGFjaG1lbnQpO1xyXG4gICAgICB9O1xyXG4gICAgICBcclxuICAgICAgaWYgKHR5cGUgPT09ICdpbWFnZScpIHtcclxuICAgICAgICByZWFkZXIucmVhZEFzRGF0YVVSTChmaWxlKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICByZWFkZXIucmVhZEFzQXJyYXlCdWZmZXIoZmlsZSk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcmVtb3ZlQXR0YWNobWVudChhdHRhY2htZW50SWQ6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgdGhpcy5zZWxlY3RlZEZpbGVzID0gdGhpcy5zZWxlY3RlZEZpbGVzLmZpbHRlcihmID0+IGYuaWQgIT09IGF0dGFjaG1lbnRJZCk7XHJcbiAgfVxyXG5cclxuICB0cmlnZ2VySW1hZ2VVcGxvYWQoKTogdm9pZCB7XHJcbiAgICBjb25zdCBpbnB1dCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdpbWFnZS11cGxvYWQtaW5wdXQnKSBhcyBIVE1MSW5wdXRFbGVtZW50O1xyXG4gICAgaWYgKGlucHV0KSB7XHJcbiAgICAgIGlucHV0LmNsaWNrKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICB0cmlnZ2VyRmlsZVVwbG9hZCgpOiB2b2lkIHtcclxuICAgIGNvbnN0IGlucHV0ID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ2ZpbGUtdXBsb2FkLWlucHV0JykgYXMgSFRNTElucHV0RWxlbWVudDtcclxuICAgIGlmIChpbnB1dCkge1xyXG4gICAgICBpbnB1dC5jbGljaygpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZ2V0RmlsZUljb24oZmlsZVR5cGU6IHN0cmluZyk6IHN0cmluZyB7XHJcbiAgICBpZiAoZmlsZVR5cGUuc3RhcnRzV2l0aCgnaW1hZ2UvJykpIHJldHVybiAn8J+WvO+4jyc7XHJcbiAgICBpZiAoZmlsZVR5cGUuaW5jbHVkZXMoJ3BkZicpKSByZXR1cm4gJ/Cfk4QnO1xyXG4gICAgaWYgKGZpbGVUeXBlLmluY2x1ZGVzKCd3b3JkJykgfHwgZmlsZVR5cGUuaW5jbHVkZXMoJ2RvY3VtZW50JykpIHJldHVybiAn8J+TnSc7XHJcbiAgICBpZiAoZmlsZVR5cGUuaW5jbHVkZXMoJ3RleHQnKSkgcmV0dXJuICfwn5ODJztcclxuICAgIHJldHVybiAn8J+Tjic7XHJcbiAgfVxyXG5cclxuICBnZXRGaWxlU2l6ZUZvcm1hdHRlZChieXRlczogbnVtYmVyKTogc3RyaW5nIHtcclxuICAgIGlmIChieXRlcyA8IDEwMjQpIHJldHVybiBieXRlcyArICcgQic7XHJcbiAgICBpZiAoYnl0ZXMgPCAxMDI0ICogMTAyNCkgcmV0dXJuIChieXRlcyAvIDEwMjQpLnRvRml4ZWQoMSkgKyAnIEtCJztcclxuICAgIHJldHVybiAoYnl0ZXMgLyAoMTAyNCAqIDEwMjQpKS50b0ZpeGVkKDEpICsgJyBNQic7XHJcbiAgfVxyXG59IiwiPGRpdiBjbGFzcz1cImFpLWNoYXQtY29udGFpbmVyXCIgXHJcbiAgICAgW25nQ2xhc3NdPVwiZ2V0VGhlbWVDbGFzcygpXCIgXHJcbiAgICAgW25nU3R5bGVdPVwiZ2V0Q29udGFpbmVyU3R5bGUoKVwiXHJcbiAgICAgW2NsYXNzLmZ1bGxzY3JlZW5dPVwiaXNGdWxsc2NyZWVuXCJcclxuICAgICBbY2xhc3MucmVzaXppbmddPVwiaXNSZXNpemluZ1wiPlxyXG4gIFxyXG4gIDwhLS0gUmVzaXplIEhhbmRsZXMgLS0+XHJcbiAgPGRpdiBjbGFzcz1cInJlc2l6ZS1oYW5kbGUgcmVzaXplLWhhbmRsZS1yaWdodFwiIFxyXG4gICAgICAgKG1vdXNlZG93bik9XCJzdGFydFJlc2l6ZSgkZXZlbnQsICd3aWR0aCcpXCJcclxuICAgICAgICpuZ0lmPVwiIWlzRnVsbHNjcmVlblwiXHJcbiAgICAgICB0aXRsZT1cIkRyYWcgdG8gcmVzaXplIHdpZHRoXCI+XHJcbiAgPC9kaXY+XHJcbiAgXHJcbiAgPGRpdiBjbGFzcz1cInJlc2l6ZS1oYW5kbGUgcmVzaXplLWhhbmRsZS1jb3JuZXJcIiBcclxuICAgICAgIChtb3VzZWRvd24pPVwic3RhcnRSZXNpemUoJGV2ZW50LCAnYm90aCcpXCJcclxuICAgICAgICpuZ0lmPVwiIWlzRnVsbHNjcmVlblwiXHJcbiAgICAgICB0aXRsZT1cIkRyYWcgdG8gcmVzaXplXCI+XHJcbiAgPC9kaXY+XHJcbiAgXHJcbiAgPCEtLSBEZWJ1ZyBJbmZvcm1hdGlvbiAob25seSBzaG93biB3aGVuIHNob3dEZWJ1Z0luZm8gaXMgdHJ1ZSkgLS0+XHJcbiAgPGRpdiAqbmdJZj1cInNob3dEZWJ1Z0luZm9cIiBjbGFzcz1cImRlYnVnLWluZm9cIj5cclxuICAgIDxoMz5ERUJVRzogQUkgQ2hhdCBDb21wb25lbnQgTG9hZGVkPC9oMz5cclxuICAgIDxwPlN0YXR1czoge3sgY29uZmlndXJhdGlvblN0YXR1cyB8fCAnTG9hZGluZy4uLicgfX08L3A+XHJcbiAgICA8cD5NZXNzYWdlcyBjb3VudDoge3sgbWVzc2FnZXMubGVuZ3RoIHx8IDAgfX08L3A+XHJcbiAgICA8cD5UaGVtZToge3sgdGVtcGxhdGVEZXNpZ24gfHwgJ2RlZmF1bHQnIH19PC9wPlxyXG4gICAgPHA+U2l6ZToge3sgY3VycmVudFNpemUgfX0gKHt7IGNvbnRhaW5lcldpZHRoIH19eHt7IGNvbnRhaW5lckhlaWdodCB9fSk8L3A+XHJcbiAgPC9kaXY+XHJcblxyXG4gIDxkaXYgY2xhc3M9XCJjaGF0LWhlYWRlclwiPlxyXG4gICAgPGRpdiBjbGFzcz1cImhlYWRlci1sZWZ0XCI+XHJcbiAgICAgIDxoMj57eyB0aXRsZSB9fTwvaDI+XHJcbiAgICAgIDwhLS0gSWNvbi1vbmx5IHN0YXR1cyBpbmRpY2F0b3IgLS0+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJzdGF0dXMtaW5kaWNhdG9yLWljb25cIiBcclxuICAgICAgICAgICBbbmdDbGFzc109XCJ7J3N0YXR1cy1yZWFkeSc6IGNvbmZpZ3VyYXRpb25TdGF0dXMgPT09ICdBSSBBZ2VudCBpcyByZWFkeScsIFxyXG4gICAgICAgICAgICAgICAgICAgICAgJ3N0YXR1cy1lcnJvcic6IGNvbmZpZ3VyYXRpb25TdGF0dXMgIT09ICdBSSBBZ2VudCBpcyByZWFkeScsXHJcbiAgICAgICAgICAgICAgICAgICAgICAnc3RhdHVzLWxvYWRpbmcnOiBjb25maWd1cmF0aW9uU3RhdHVzID09PSAnSW5pdGlhbGl6aW5nLi4uJyB8fCBjb25maWd1cmF0aW9uU3RhdHVzID09PSAnVGVzdGluZyBjb25uZWN0aW9uLi4uJ31cIlxyXG4gICAgICAgICAgIFt0aXRsZV09XCJjb25maWd1cmF0aW9uU3RhdHVzXCI+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbiAgICBcclxuICAgIDxkaXYgY2xhc3M9XCJoZWFkZXItY29udHJvbHNcIj5cclxuICAgICAgPCEtLSBTaXplIFByZXNldCBCdXR0b25zIC0tPlxyXG4gICAgICA8ZGl2IGNsYXNzPVwic2l6ZS1jb250cm9sc1wiICpuZ0lmPVwiIWlzRnVsbHNjcmVlblwiPlxyXG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJjb250cm9sLWJ1dHRvbiBzaXplLWJ1dHRvblwiIFxyXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cImFwcGx5U2l6ZVByZXNldCgnY29tcGFjdCcpXCJcclxuICAgICAgICAgICAgICAgIFtjbGFzcy5hY3RpdmVdPVwiY3VycmVudFNpemUgPT09ICdjb21wYWN0J1wiXHJcbiAgICAgICAgICAgICAgICB0aXRsZT1cIkNvbXBhY3QgVmlld1wiXHJcbiAgICAgICAgICAgICAgICBhdHRyLmFyaWEtbGFiZWw9XCJDb21wYWN0IFZpZXdcIj5cclxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaWNvbi1zdmdcIiBbaW5uZXJIVE1MXT1cInNhbml0aXplZEljb25zLmNvbXBhY3RWaWV3XCI+PC9zcGFuPlxyXG4gICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJjb250cm9sLWJ1dHRvbiBzaXplLWJ1dHRvblwiIFxyXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cImFwcGx5U2l6ZVByZXNldCgnZGVmYXVsdCcpXCJcclxuICAgICAgICAgICAgICAgIFtjbGFzcy5hY3RpdmVdPVwiY3VycmVudFNpemUgPT09ICdkZWZhdWx0J1wiXHJcbiAgICAgICAgICAgICAgICB0aXRsZT1cIkRlZmF1bHQgVmlld1wiXHJcbiAgICAgICAgICAgICAgICBhdHRyLmFyaWEtbGFiZWw9XCJEZWZhdWx0IFZpZXdcIj5cclxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaWNvbi1zdmdcIiBbaW5uZXJIVE1MXT1cInNhbml0aXplZEljb25zLmRlZmF1bHRWaWV3XCI+PC9zcGFuPlxyXG4gICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgIDxidXR0b24gY2xhc3M9XCJjb250cm9sLWJ1dHRvbiBzaXplLWJ1dHRvblwiIFxyXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cImFwcGx5U2l6ZVByZXNldCgnZXhwYW5kZWQnKVwiXHJcbiAgICAgICAgICAgICAgICBbY2xhc3MuYWN0aXZlXT1cImN1cnJlbnRTaXplID09PSAnZXhwYW5kZWQnXCJcclxuICAgICAgICAgICAgICAgIHRpdGxlPVwiRXhwYW5kZWQgVmlld1wiXHJcbiAgICAgICAgICAgICAgICBhdHRyLmFyaWEtbGFiZWw9XCJFeHBhbmRlZCBWaWV3XCI+XHJcbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImljb24tc3ZnXCIgW2lubmVySFRNTF09XCJzYW5pdGl6ZWRJY29ucy5leHBhbmRlZFZpZXdcIj48L3NwYW4+XHJcbiAgICAgICAgPC9idXR0b24+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbiAgPC9kaXY+XHJcblxyXG4gIDxkaXYgY2xhc3M9XCJjaGF0LW1lc3NhZ2VzXCIgI21lc3NhZ2VzQ29udGFpbmVyPlxyXG4gICAgPGRpdiAqbmdGb3I9XCJsZXQgbWVzc2FnZSBvZiBtZXNzYWdlczsgbGV0IGkgPSBpbmRleDsgdHJhY2tCeTogdHJhY2tCeUluZGV4XCIgY2xhc3M9XCJtZXNzYWdlLXdyYXBwZXJcIj5cclxuICAgICAgPCEtLSBNZXNzYWdlIC0tPlxyXG4gICAgICA8ZGl2IGNsYXNzPVwibWVzc2FnZVwiIFxyXG4gICAgICAgICAgIFtuZ0NsYXNzXT1cInsndXNlci1tZXNzYWdlJzogbWVzc2FnZS5pc1VzZXIsICdhaS1tZXNzYWdlJzogIW1lc3NhZ2UuaXNVc2VyLCAnbG9hZGluZy1tZXNzYWdlJzogbWVzc2FnZS5pc0xvYWRpbmd9XCI+XHJcbiAgICAgICAgXHJcbiAgICAgICAgPGRpdiBjbGFzcz1cIm1lc3NhZ2UtY29udGVudFwiPlxyXG4gICAgICAgICAgPGRpdiBbaW5uZXJIVE1MXT1cIm1lc3NhZ2UuY29udGVudFwiPjwvZGl2PlxyXG4gICAgICAgICAgPGRpdiBjbGFzcz1cIm1lc3NhZ2UtdGltZXN0YW1wXCI+e3sgZ2V0Rm9ybWF0dGVkVGltZShtZXNzYWdlLnRpbWVzdGFtcCkgfX08L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgICBcclxuICAgICAgICA8ZGl2IGNsYXNzPVwibWVzc2FnZS1hdmF0YXJcIj5cclxuICAgICAgICAgIDxzcGFuICpuZ0lmPVwibWVzc2FnZS5pc1VzZXJcIiBjbGFzcz1cImF2YXRhci1pY29uXCIgW2lubmVySFRNTF09XCJzYW5pdGl6ZWRJY29ucy51c2VyQXZhdGFyXCI+PC9zcGFuPlxyXG4gICAgICAgICAgPHNwYW4gKm5nSWY9XCIhbWVzc2FnZS5pc1VzZXIgJiYgIW1lc3NhZ2UuaXNMb2FkaW5nXCIgY2xhc3M9XCJhdmF0YXItaWNvblwiIFtpbm5lckhUTUxdPVwic2FuaXRpemVkSWNvbnMuYWlBdmF0YXJcIj48L3NwYW4+XHJcbiAgICAgICAgICA8c3BhbiAqbmdJZj1cIm1lc3NhZ2UuaXNMb2FkaW5nXCIgY2xhc3M9XCJhdmF0YXItaWNvbiBsb2FkaW5nLXNwaW5uZXJcIiBbaW5uZXJIVE1MXT1cInNhbml0aXplZEljb25zLmxvYWRpbmdBdmF0YXJcIj48L3NwYW4+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbiAgPC9kaXY+XHJcblxyXG4gIDxkaXYgY2xhc3M9XCJjaGF0LWlucHV0XCI+XHJcbiAgICA8IS0tIEF0dGFjaG1lbnRzIFByZXZpZXcgLS0+XHJcbiAgICA8ZGl2IGNsYXNzPVwiYXR0YWNobWVudHMtcHJldmlld1wiICpuZ0lmPVwic2VsZWN0ZWRGaWxlcy5sZW5ndGggPiAwXCI+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJhdHRhY2htZW50LWl0ZW1cIiAqbmdGb3I9XCJsZXQgZmlsZSBvZiBzZWxlY3RlZEZpbGVzXCI+XHJcbiAgICAgICAgPHN2ZyBjbGFzcz1cImF0dGFjaG1lbnQtaWNvblwiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjJcIj5cclxuICAgICAgICAgIDxwYXRoIGQ9XCJNMjEuNDQgMTEuMDVsLTkuMTkgOS4xOWE2IDYgMCAwIDEtOC40OS04LjQ5bDkuMTktOS4xOWE0IDQgMCAwIDEgNS42NiA1LjY2bC05LjIgOS4xOWEyIDIgMCAwIDEtMi44My0yLjgzbDguNDktOC40OFwiPjwvcGF0aD5cclxuICAgICAgICA8L3N2Zz5cclxuICAgICAgICA8c3BhbiBjbGFzcz1cImF0dGFjaG1lbnQtbmFtZVwiPnt7IGZpbGUubmFtZSB9fTwvc3Bhbj5cclxuICAgICAgICA8c3BhbiBjbGFzcz1cImF0dGFjaG1lbnQtc2l6ZVwiPnt7IGdldEZpbGVTaXplRm9ybWF0dGVkKGZpbGUuc2l6ZSkgfX08L3NwYW4+XHJcbiAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInJlbW92ZS1hdHRhY2htZW50XCIgKGNsaWNrKT1cInJlbW92ZUF0dGFjaG1lbnQoZmlsZS5pZClcIiB0aXRsZT1cIlJlbW92ZVwiIGF0dHIuYXJpYS1sYWJlbD1cIlJlbW92ZSBhdHRhY2htZW50XCI+XHJcbiAgICAgICAgICA8c3ZnIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjJcIj5cclxuICAgICAgICAgICAgPGxpbmUgeDE9XCIxOFwiIHkxPVwiNlwiIHgyPVwiNlwiIHkyPVwiMThcIj48L2xpbmU+XHJcbiAgICAgICAgICAgIDxsaW5lIHgxPVwiNlwiIHkxPVwiNlwiIHgyPVwiMThcIiB5Mj1cIjE4XCI+PC9saW5lPlxyXG4gICAgICAgICAgPC9zdmc+XHJcbiAgICAgICAgPC9idXR0b24+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcbiAgICBcclxuICAgIDxkaXYgY2xhc3M9XCJpbnB1dC1jb250YWluZXJcIj5cclxuICAgICAgPCEtLSBGaWxlIFVwbG9hZCBJbnB1dHMgKEhpZGRlbikgLS0+XHJcbiAgICAgIDxpbnB1dCB0eXBlPVwiZmlsZVwiIFxyXG4gICAgICAgICAgICAgaWQ9XCJpbWFnZS11cGxvYWQtaW5wdXRcIiBcclxuICAgICAgICAgICAgIGFjY2VwdD1cImltYWdlLypcIiBcclxuICAgICAgICAgICAgIG11bHRpcGxlIFxyXG4gICAgICAgICAgICAgKGNoYW5nZSk9XCJvbkltYWdlVXBsb2FkKCRldmVudClcIlxyXG4gICAgICAgICAgICAgc3R5bGU9XCJkaXNwbGF5OiBub25lO1wiXHJcbiAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiIWVuYWJsZUltYWdlVXBsb2FkXCI+XHJcbiAgICAgIFxyXG4gICAgICA8aW5wdXQgdHlwZT1cImZpbGVcIiBcclxuICAgICAgICAgICAgIGlkPVwiZmlsZS11cGxvYWQtaW5wdXRcIiBcclxuICAgICAgICAgICAgIGFjY2VwdD1cIi5wZGYsLmRvYywuZG9jeCwudHh0LC5jc3ZcIiBcclxuICAgICAgICAgICAgIG11bHRpcGxlIFxyXG4gICAgICAgICAgICAgKGNoYW5nZSk9XCJvbkZpbGVVcGxvYWQoJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICBzdHlsZT1cImRpc3BsYXk6IG5vbmU7XCJcclxuICAgICAgICAgICAgIFtkaXNhYmxlZF09XCIhZW5hYmxlRmlsZVVwbG9hZFwiPlxyXG4gICAgICBcclxuICAgICAgPCEtLSBVcGxvYWQgQnV0dG9ucyAoQ29uZGl0aW9uYWxseSByZW5kZXJlZCkgLS0+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJ1cGxvYWQtYnV0dG9uc1wiICpuZ0lmPVwiZW5hYmxlSW1hZ2VVcGxvYWQgfHwgZW5hYmxlRmlsZVVwbG9hZFwiPlxyXG4gICAgICAgIDxidXR0b24gKm5nSWY9XCJlbmFibGVJbWFnZVVwbG9hZFwiIFxyXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJ1cGxvYWQtYnV0dG9uIGltYWdlLXVwbG9hZFwiIFxyXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cInRyaWdnZXJJbWFnZVVwbG9hZCgpXCJcclxuICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJpc0xvYWRpbmdcIlxyXG4gICAgICAgICAgICAgICAgdGl0bGU9XCJVcGxvYWQgSW1hZ2VcIlxyXG4gICAgICAgICAgICAgICAgYXR0ci5hcmlhLWxhYmVsPVwiVXBsb2FkIEltYWdlXCI+XHJcbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImljb24tc3ZnXCIgW2lubmVySFRNTF09XCJzYW5pdGl6ZWRJY29ucy5pbWFnZVVwbG9hZFwiPjwvc3Bhbj5cclxuICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICBcclxuICAgICAgICA8YnV0dG9uICpuZ0lmPVwiZW5hYmxlRmlsZVVwbG9hZFwiIFxyXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJ1cGxvYWQtYnV0dG9uIGZpbGUtdXBsb2FkXCIgXHJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwidHJpZ2dlckZpbGVVcGxvYWQoKVwiXHJcbiAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiaXNMb2FkaW5nXCJcclxuICAgICAgICAgICAgICAgIHRpdGxlPVwiQXR0YWNoIEZpbGVcIlxyXG4gICAgICAgICAgICAgICAgYXR0ci5hcmlhLWxhYmVsPVwiQXR0YWNoIEZpbGVcIj5cclxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaWNvbi1zdmdcIiBbaW5uZXJIVE1MXT1cInNhbml0aXplZEljb25zLmZpbGVVcGxvYWRcIj48L3NwYW4+XHJcbiAgICAgICAgPC9idXR0b24+XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgICBcclxuICAgICAgPHRleHRhcmVhIFxyXG4gICAgICAgIFsobmdNb2RlbCldPVwiY3VycmVudElucXVpcnlcIiBcclxuICAgICAgICAoa2V5cHJlc3MpPVwib25LZXlQcmVzcygkZXZlbnQpXCJcclxuICAgICAgICBbcGxhY2Vob2xkZXJdPVwicGxhY2Vob2xkZXJcIlxyXG4gICAgICAgIHJvd3M9XCIyXCJcclxuICAgICAgICBbZGlzYWJsZWRdPVwiaXNMb2FkaW5nXCJcclxuICAgICAgICBjbGFzcz1cImlucXVpcnktdGV4dGFyZWFcIlxyXG4gICAgICAgIGF0dHIuYXJpYS1sYWJlbD1cIlR5cGUgeW91ciBtZXNzYWdlXCI+PC90ZXh0YXJlYT5cclxuICAgICAgXHJcbiAgICAgIDxidXR0b24gXHJcbiAgICAgICAgKGNsaWNrKT1cInNlbmRJbnF1aXJ5KClcIiBcclxuICAgICAgICBbZGlzYWJsZWRdPVwiIWN1cnJlbnRJbnF1aXJ5LnRyaW0oKSB8fCBpc0xvYWRpbmdcIlxyXG4gICAgICAgIGNsYXNzPVwic2VuZC1idXR0b25cIlxyXG4gICAgICAgIHRpdGxlPVwiU2VuZCBNZXNzYWdlXCJcclxuICAgICAgICBhdHRyLmFyaWEtbGFiZWw9XCJTZW5kIE1lc3NhZ2VcIj5cclxuICAgICAgICA8c3BhbiAqbmdJZj1cIiFpc0xvYWRpbmdcIiBjbGFzcz1cImljb24tc3ZnXCIgW2lubmVySFRNTF09XCJzYW5pdGl6ZWRJY29ucy5zZW5kXCI+PC9zcGFuPlxyXG4gICAgICAgIDxzcGFuICpuZ0lmPVwiaXNMb2FkaW5nXCIgY2xhc3M9XCJpY29uLXN2ZyBsb2FkaW5nLWljb25cIiBbaW5uZXJIVE1MXT1cInNhbml0aXplZEljb25zLnNlbmRMb2FkaW5nXCI+PC9zcGFuPlxyXG4gICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dFwiPnt7IGlzTG9hZGluZyA/ICdTZW5kaW5nLi4uJyA6ICdTZW5kJyB9fTwvc3Bhbj5cclxuICAgICAgPC9idXR0b24+XHJcbiAgICA8L2Rpdj5cclxuICA8L2Rpdj5cclxuPC9kaXY+Il19