@ha-bits/bit-email 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,575 @@
1
+ "use strict";
2
+ /**
3
+ * @ha-bits/bit-email
4
+ *
5
+ * Email integration bit for IMAP fetching and SMTP sending.
6
+ * Provides triggers for new emails and actions for sending emails.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.email = void 0;
10
+ const imapflow_1 = require("imapflow");
11
+ /**
12
+ * Fetch emails from IMAP server using imapflow
13
+ */
14
+ async function fetchImapEmails(host, port, user, password, folder = 'INBOX', limit = 10, unreadOnly = true) {
15
+ console.log(`📧 IMAP: Connecting to ${host}:${port} as ${user}...`);
16
+ console.log(`📧 IMAP: Fetching from ${folder}, limit: ${limit}, unreadOnly: ${unreadOnly}`);
17
+ const client = new imapflow_1.ImapFlow({
18
+ host,
19
+ port,
20
+ secure: port === 993,
21
+ auth: {
22
+ user,
23
+ pass: password,
24
+ },
25
+ logger: false,
26
+ });
27
+ const emails = [];
28
+ try {
29
+ await client.connect();
30
+ console.log(`📧 IMAP: Connected successfully`);
31
+ const lock = await client.getMailboxLock(folder);
32
+ try {
33
+ // Build search query
34
+ const searchQuery = unreadOnly ? { seen: false } : 'all';
35
+ // Search for messages
36
+ const searchResult = await client.search(searchQuery, { uid: true });
37
+ const messages = Array.isArray(searchResult) ? searchResult : [];
38
+ if (messages.length === 0) {
39
+ console.log(`📧 IMAP: No messages found matching criteria`);
40
+ return emails;
41
+ }
42
+ // Get the most recent messages up to limit
43
+ const messagesToFetch = messages.slice(-limit).reverse();
44
+ console.log(`📧 IMAP: Found ${messages.length} messages, fetching ${messagesToFetch.length}`);
45
+ // Fetch message details
46
+ for await (const message of client.fetch(messagesToFetch, {
47
+ uid: true,
48
+ envelope: true,
49
+ source: true,
50
+ bodyStructure: true,
51
+ })) {
52
+ const envelope = message.envelope;
53
+ if (!envelope)
54
+ continue;
55
+ // Parse from address
56
+ const fromAddr = envelope.from?.[0];
57
+ const from = fromAddr
58
+ ? (fromAddr.name ? `${fromAddr.name} <${fromAddr.address}>` : fromAddr.address || '')
59
+ : '';
60
+ // Parse to addresses
61
+ const toAddrs = envelope.to || [];
62
+ const to = toAddrs
63
+ .map((addr) => addr.name ? `${addr.name} <${addr.address}>` : addr.address || '')
64
+ .join(', ');
65
+ // Extract body from source
66
+ let body = '';
67
+ if (message.source) {
68
+ const sourceStr = message.source.toString();
69
+ // Simple extraction - find body after headers
70
+ const bodyMatch = sourceStr.split(/\r?\n\r?\n/);
71
+ if (bodyMatch.length > 1) {
72
+ body = bodyMatch.slice(1).join('\n\n');
73
+ }
74
+ }
75
+ // Extract attachments info from bodyStructure
76
+ const attachments = [];
77
+ if (message.bodyStructure) {
78
+ extractAttachments(message.bodyStructure, attachments);
79
+ }
80
+ emails.push({
81
+ id: String(message.uid),
82
+ from,
83
+ to,
84
+ subject: envelope.subject || '',
85
+ body,
86
+ date: envelope.date?.toISOString() || new Date().toISOString(),
87
+ attachments: attachments.length > 0 ? attachments : undefined,
88
+ });
89
+ }
90
+ }
91
+ finally {
92
+ lock.release();
93
+ }
94
+ }
95
+ finally {
96
+ await client.logout();
97
+ console.log(`📧 IMAP: Disconnected`);
98
+ }
99
+ console.log(`📧 IMAP: Fetched ${emails.length} email(s)`);
100
+ return emails;
101
+ }
102
+ /**
103
+ * Recursively extract attachment info from bodyStructure
104
+ */
105
+ function extractAttachments(structure, attachments) {
106
+ if (!structure)
107
+ return;
108
+ // Check if this part is an attachment
109
+ if (structure.disposition === 'attachment' ||
110
+ (structure.disposition === 'inline' && structure.dispositionParameters?.filename)) {
111
+ const filename = structure.dispositionParameters?.filename ||
112
+ structure.parameters?.name ||
113
+ 'attachment';
114
+ attachments.push({
115
+ filename,
116
+ contentType: `${structure.type}/${structure.subtype}`,
117
+ size: structure.size || 0,
118
+ });
119
+ }
120
+ // Recurse into child parts
121
+ if (structure.childNodes && Array.isArray(structure.childNodes)) {
122
+ for (const child of structure.childNodes) {
123
+ extractAttachments(child, attachments);
124
+ }
125
+ }
126
+ }
127
+ /**
128
+ * Simulate SMTP send (in real implementation, use nodemailer or similar)
129
+ */
130
+ async function sendSmtpEmail(host, port, user, password, from, to, subject, body, html, attachments) {
131
+ console.log(`📤 SMTP: Connecting to ${host}:${port} as ${user}...`);
132
+ console.log(`📤 SMTP: Sending from ${from} to ${to}`);
133
+ console.log(`📤 SMTP: Subject: ${subject}`);
134
+ // In production, this would use nodemailer
135
+ // For now, return mock response
136
+ const messageId = `<${Date.now()}.${Math.random().toString(36).substring(7)}@habits.local>`;
137
+ return {
138
+ messageId,
139
+ accepted: [to]
140
+ };
141
+ }
142
+ const emailBit = {
143
+ displayName: 'Email (IMAP/SMTP)',
144
+ description: 'Email integration for fetching (IMAP) and sending (SMTP) emails',
145
+ logoUrl: 'lucide:Mail',
146
+ auth: {
147
+ type: 'CUSTOM',
148
+ displayName: 'Email Credentials',
149
+ description: 'IMAP and SMTP server credentials',
150
+ required: false,
151
+ props: {
152
+ imapHost: { type: 'SHORT_TEXT', displayName: 'IMAP Host', required: false },
153
+ imapPort: { type: 'NUMBER', displayName: 'IMAP Port', required: false, defaultValue: 993 },
154
+ imapUser: { type: 'SHORT_TEXT', displayName: 'IMAP Username', required: false },
155
+ imapPassword: { type: 'SECRET_TEXT', displayName: 'IMAP Password', required: false },
156
+ smtpHost: { type: 'SHORT_TEXT', displayName: 'SMTP Host', required: false },
157
+ smtpPort: { type: 'NUMBER', displayName: 'SMTP Port', required: false, defaultValue: 587 },
158
+ smtpUser: { type: 'SHORT_TEXT', displayName: 'SMTP Username', required: false },
159
+ smtpPassword: { type: 'SECRET_TEXT', displayName: 'SMTP Password', required: false },
160
+ }
161
+ },
162
+ triggers: {
163
+ /**
164
+ * IMAP trigger - fetch new emails
165
+ */
166
+ newEmail: {
167
+ name: 'newEmail',
168
+ displayName: 'New Email (IMAP)',
169
+ description: 'Trigger when new emails arrive in the mailbox',
170
+ type: 'POLLING',
171
+ props: {
172
+ imapHost: {
173
+ type: 'SHORT_TEXT',
174
+ displayName: 'IMAP Host',
175
+ description: 'IMAP server hostname (e.g., imap.gmail.com)',
176
+ required: true,
177
+ },
178
+ imapPort: {
179
+ type: 'NUMBER',
180
+ displayName: 'IMAP Port',
181
+ description: 'IMAP server port (default: 993 for SSL)',
182
+ required: false,
183
+ defaultValue: 993,
184
+ },
185
+ imapUser: {
186
+ type: 'SHORT_TEXT',
187
+ displayName: 'Username',
188
+ description: 'Email address or username',
189
+ required: true,
190
+ },
191
+ imapPassword: {
192
+ type: 'SECRET_TEXT',
193
+ displayName: 'Password',
194
+ description: 'Email password or app-specific password',
195
+ required: true,
196
+ },
197
+ folder: {
198
+ type: 'SHORT_TEXT',
199
+ displayName: 'Folder',
200
+ description: 'Mailbox folder to monitor',
201
+ required: false,
202
+ defaultValue: 'INBOX',
203
+ },
204
+ unreadOnly: {
205
+ type: 'CHECKBOX',
206
+ displayName: 'Unread Only',
207
+ description: 'Only fetch unread emails',
208
+ required: false,
209
+ defaultValue: true,
210
+ },
211
+ limit: {
212
+ type: 'NUMBER',
213
+ displayName: 'Limit',
214
+ description: 'Maximum number of emails to fetch',
215
+ required: false,
216
+ defaultValue: 10,
217
+ },
218
+ },
219
+ async run(context) {
220
+ const { imapHost, imapPort = 993, imapUser, imapPassword, folder = 'INBOX', unreadOnly = true, limit = 10 } = context.propsValue;
221
+ const host = context.auth?.imapHost || imapHost;
222
+ const port = context.auth?.imapPort || imapPort;
223
+ const user = context.auth?.imapUser || imapUser;
224
+ const password = context.auth?.imapPassword || imapPassword;
225
+ if (!host || !user || !password) {
226
+ throw new Error('IMAP credentials are required');
227
+ }
228
+ const emails = await fetchImapEmails(host, Number(port), user, password, String(folder), Number(limit), Boolean(unreadOnly));
229
+ console.log(`📧 IMAP Trigger: Fetched ${emails.length} email(s)`);
230
+ return {
231
+ emails,
232
+ count: emails.length,
233
+ folder,
234
+ timestamp: new Date().toISOString(),
235
+ };
236
+ },
237
+ },
238
+ },
239
+ actions: {
240
+ /**
241
+ * New Email action (for workflow testing - simulates IMAP trigger as action)
242
+ */
243
+ newEmail: {
244
+ name: 'newEmail',
245
+ displayName: 'New Email (IMAP)',
246
+ description: 'Fetch new emails from IMAP mailbox (action version of trigger)',
247
+ props: {
248
+ imapHost: {
249
+ type: 'SHORT_TEXT',
250
+ displayName: 'IMAP Host',
251
+ description: 'IMAP server hostname',
252
+ required: false,
253
+ },
254
+ imapPort: {
255
+ type: 'NUMBER',
256
+ displayName: 'IMAP Port',
257
+ description: 'IMAP server port',
258
+ required: false,
259
+ defaultValue: 993,
260
+ },
261
+ imapUser: {
262
+ type: 'SHORT_TEXT',
263
+ displayName: 'Username',
264
+ description: 'Email address or username',
265
+ required: false,
266
+ },
267
+ imapPassword: {
268
+ type: 'SECRET_TEXT',
269
+ displayName: 'Password',
270
+ description: 'Email password',
271
+ required: false,
272
+ },
273
+ folder: {
274
+ type: 'SHORT_TEXT',
275
+ displayName: 'Folder',
276
+ description: 'Mailbox folder',
277
+ required: false,
278
+ defaultValue: 'INBOX',
279
+ },
280
+ unreadOnly: {
281
+ type: 'CHECKBOX',
282
+ displayName: 'Unread Only',
283
+ description: 'Only fetch unread emails',
284
+ required: false,
285
+ defaultValue: true,
286
+ },
287
+ limit: {
288
+ type: 'NUMBER',
289
+ displayName: 'Limit',
290
+ description: 'Maximum number of emails',
291
+ required: false,
292
+ defaultValue: 10,
293
+ },
294
+ },
295
+ async run(context) {
296
+ const { folder = 'INBOX' } = context.propsValue;
297
+ // Return mock test data for workflow testing
298
+ const mockEmails = [
299
+ {
300
+ id: `email_${Date.now()}`,
301
+ from: 'customer@example.com',
302
+ to: 'support@company.com',
303
+ subject: 'Help with my order #12345',
304
+ body: 'Hi, I placed an order last week and haven\'t received any shipping confirmation. Can you help me track it? Order number is 12345. Thanks!',
305
+ date: new Date().toISOString(),
306
+ },
307
+ {
308
+ id: `email_${Date.now() + 1}`,
309
+ from: 'sales.inquiry@prospect.com',
310
+ to: 'sales@company.com',
311
+ subject: 'Pricing inquiry for enterprise plan',
312
+ body: 'We are interested in your enterprise pricing. Our company has 500+ employees. Please send us a quote.',
313
+ date: new Date(Date.now() - 3600000).toISOString(),
314
+ },
315
+ ];
316
+ console.log(`📧 New Email (Mock): Returning ${mockEmails.length} test emails from ${folder}`);
317
+ return {
318
+ emails: mockEmails,
319
+ count: mockEmails.length,
320
+ folder,
321
+ timestamp: new Date().toISOString(),
322
+ };
323
+ },
324
+ },
325
+ /**
326
+ * Fetch emails from IMAP server
327
+ */
328
+ fetchEmails: {
329
+ name: 'fetchEmails',
330
+ displayName: 'Fetch Emails (IMAP)',
331
+ description: 'Fetch emails from an IMAP mailbox',
332
+ props: {
333
+ imapHost: {
334
+ type: 'SHORT_TEXT',
335
+ displayName: 'IMAP Host',
336
+ description: 'IMAP server hostname',
337
+ required: true,
338
+ },
339
+ imapPort: {
340
+ type: 'NUMBER',
341
+ displayName: 'IMAP Port',
342
+ description: 'IMAP server port',
343
+ required: false,
344
+ defaultValue: 993,
345
+ },
346
+ imapUser: {
347
+ type: 'SHORT_TEXT',
348
+ displayName: 'Username',
349
+ description: 'Email address or username',
350
+ required: true,
351
+ },
352
+ imapPassword: {
353
+ type: 'SECRET_TEXT',
354
+ displayName: 'Password',
355
+ description: 'Email password',
356
+ required: true,
357
+ },
358
+ folder: {
359
+ type: 'SHORT_TEXT',
360
+ displayName: 'Folder',
361
+ description: 'Mailbox folder to fetch from',
362
+ required: false,
363
+ defaultValue: 'INBOX',
364
+ },
365
+ unreadOnly: {
366
+ type: 'CHECKBOX',
367
+ displayName: 'Unread Only',
368
+ description: 'Only fetch unread emails',
369
+ required: false,
370
+ defaultValue: false,
371
+ },
372
+ limit: {
373
+ type: 'NUMBER',
374
+ displayName: 'Limit',
375
+ description: 'Maximum number of emails to fetch',
376
+ required: false,
377
+ defaultValue: 10,
378
+ },
379
+ },
380
+ async run(context) {
381
+ const { imapHost, imapPort = 993, imapUser, imapPassword, folder = 'INBOX', unreadOnly = false, limit = 10 } = context.propsValue;
382
+ const host = context.auth?.imapHost || imapHost;
383
+ const port = context.auth?.imapPort || imapPort;
384
+ const user = context.auth?.imapUser || imapUser;
385
+ const password = context.auth?.imapPassword || imapPassword;
386
+ if (!host || !user || !password) {
387
+ throw new Error('IMAP credentials are required');
388
+ }
389
+ const emails = await fetchImapEmails(host, Number(port), user, password, String(folder), Number(limit), Boolean(unreadOnly));
390
+ console.log(`📧 Fetch Emails: Retrieved ${emails.length} email(s) from ${folder}`);
391
+ return {
392
+ emails,
393
+ count: emails.length,
394
+ folder,
395
+ };
396
+ },
397
+ },
398
+ /**
399
+ * Send email via SMTP
400
+ */
401
+ sendEmail: {
402
+ name: 'sendEmail',
403
+ displayName: 'Send Email (SMTP)',
404
+ description: 'Send an email via SMTP',
405
+ props: {
406
+ smtpHost: {
407
+ type: 'SHORT_TEXT',
408
+ displayName: 'SMTP Host',
409
+ description: 'SMTP server hostname (e.g., smtp.gmail.com)',
410
+ required: true,
411
+ },
412
+ smtpPort: {
413
+ type: 'NUMBER',
414
+ displayName: 'SMTP Port',
415
+ description: 'SMTP server port (587 for TLS, 465 for SSL)',
416
+ required: false,
417
+ defaultValue: 587,
418
+ },
419
+ smtpUser: {
420
+ type: 'SHORT_TEXT',
421
+ displayName: 'Username',
422
+ description: 'SMTP username/email',
423
+ required: true,
424
+ },
425
+ smtpPassword: {
426
+ type: 'SECRET_TEXT',
427
+ displayName: 'Password',
428
+ description: 'SMTP password',
429
+ required: true,
430
+ },
431
+ from: {
432
+ type: 'SHORT_TEXT',
433
+ displayName: 'From',
434
+ description: 'Sender email address',
435
+ required: true,
436
+ },
437
+ to: {
438
+ type: 'SHORT_TEXT',
439
+ displayName: 'To',
440
+ description: 'Recipient email address(es), comma-separated',
441
+ required: true,
442
+ },
443
+ cc: {
444
+ type: 'SHORT_TEXT',
445
+ displayName: 'CC',
446
+ description: 'CC recipients (optional)',
447
+ required: false,
448
+ },
449
+ bcc: {
450
+ type: 'SHORT_TEXT',
451
+ displayName: 'BCC',
452
+ description: 'BCC recipients (optional)',
453
+ required: false,
454
+ },
455
+ subject: {
456
+ type: 'SHORT_TEXT',
457
+ displayName: 'Subject',
458
+ description: 'Email subject line',
459
+ required: true,
460
+ },
461
+ body: {
462
+ type: 'LONG_TEXT',
463
+ displayName: 'Body (Plain Text)',
464
+ description: 'Email body in plain text',
465
+ required: true,
466
+ },
467
+ html: {
468
+ type: 'LONG_TEXT',
469
+ displayName: 'Body (HTML)',
470
+ description: 'Email body in HTML format (optional)',
471
+ required: false,
472
+ },
473
+ replyTo: {
474
+ type: 'SHORT_TEXT',
475
+ displayName: 'Reply-To',
476
+ description: 'Reply-to address (optional)',
477
+ required: false,
478
+ },
479
+ },
480
+ async run(context) {
481
+ const { smtpHost, smtpPort = 587, smtpUser, smtpPassword, from, to, subject, body, html, cc, bcc, replyTo } = context.propsValue;
482
+ const host = context.auth?.smtpHost || smtpHost;
483
+ const port = context.auth?.smtpPort || smtpPort;
484
+ const user = context.auth?.smtpUser || smtpUser;
485
+ const password = context.auth?.smtpPassword || smtpPassword;
486
+ if (!host || !user || !password) {
487
+ throw new Error('SMTP credentials are required');
488
+ }
489
+ if (!from || !to || !subject || !body) {
490
+ throw new Error('From, To, Subject, and Body are required');
491
+ }
492
+ const result = await sendSmtpEmail(host, Number(port), user, password, String(from), String(to), String(subject), String(body), html);
493
+ console.log(`📤 Send Email: Message sent to ${to}`);
494
+ return {
495
+ success: true,
496
+ messageId: result.messageId,
497
+ accepted: result.accepted,
498
+ from,
499
+ to,
500
+ subject,
501
+ timestamp: new Date().toISOString(),
502
+ };
503
+ },
504
+ },
505
+ /**
506
+ * Parse email content
507
+ */
508
+ parseEmail: {
509
+ name: 'parseEmail',
510
+ displayName: 'Parse Email',
511
+ description: 'Extract structured data from email content',
512
+ props: {
513
+ rawEmail: {
514
+ type: 'LONG_TEXT',
515
+ displayName: 'Raw Email',
516
+ description: 'Raw email content or JSON email object',
517
+ required: true,
518
+ },
519
+ extractAttachments: {
520
+ type: 'CHECKBOX',
521
+ displayName: 'Extract Attachments',
522
+ description: 'Include attachment information',
523
+ required: false,
524
+ defaultValue: false,
525
+ },
526
+ },
527
+ async run(context) {
528
+ const { rawEmail, extractAttachments } = context.propsValue;
529
+ let email;
530
+ if (typeof rawEmail === 'string') {
531
+ try {
532
+ email = JSON.parse(rawEmail);
533
+ }
534
+ catch {
535
+ // Parse as raw email text - simplified parsing
536
+ const lines = rawEmail.split('\n');
537
+ email = {
538
+ subject: '',
539
+ from: '',
540
+ to: '',
541
+ body: rawEmail,
542
+ };
543
+ for (const line of lines) {
544
+ if (line.toLowerCase().startsWith('subject:')) {
545
+ email.subject = line.substring(8).trim();
546
+ }
547
+ else if (line.toLowerCase().startsWith('from:')) {
548
+ email.from = line.substring(5).trim();
549
+ }
550
+ else if (line.toLowerCase().startsWith('to:')) {
551
+ email.to = line.substring(3).trim();
552
+ }
553
+ }
554
+ }
555
+ }
556
+ else {
557
+ email = rawEmail;
558
+ }
559
+ console.log(`📧 Parse Email: Extracted from ${email.from || 'unknown'}`);
560
+ return {
561
+ from: email.from || '',
562
+ to: email.to || '',
563
+ subject: email.subject || '',
564
+ body: email.body || email.text || '',
565
+ html: email.html || '',
566
+ date: email.date || new Date().toISOString(),
567
+ attachments: extractAttachments ? (email.attachments || []) : [],
568
+ };
569
+ },
570
+ },
571
+ },
572
+ };
573
+ exports.email = emailBit;
574
+ exports.default = emailBit;
575
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7OztHQUtHOzs7QUFFSCx1Q0FBb0M7QUE4QnBDOztHQUVHO0FBQ0gsS0FBSyxVQUFVLGVBQWUsQ0FDNUIsSUFBWSxFQUNaLElBQVksRUFDWixJQUFZLEVBQ1osUUFBZ0IsRUFDaEIsU0FBaUIsT0FBTyxFQUN4QixRQUFnQixFQUFFLEVBQ2xCLGFBQXNCLElBQUk7SUFFMUIsT0FBTyxDQUFDLEdBQUcsQ0FBQywwQkFBMEIsSUFBSSxJQUFJLElBQUksT0FBTyxJQUFJLEtBQUssQ0FBQyxDQUFDO0lBQ3BFLE9BQU8sQ0FBQyxHQUFHLENBQUMsMEJBQTBCLE1BQU0sWUFBWSxLQUFLLGlCQUFpQixVQUFVLEVBQUUsQ0FBQyxDQUFDO0lBRTVGLE1BQU0sTUFBTSxHQUFHLElBQUksbUJBQVEsQ0FBQztRQUMxQixJQUFJO1FBQ0osSUFBSTtRQUNKLE1BQU0sRUFBRSxJQUFJLEtBQUssR0FBRztRQUNwQixJQUFJLEVBQUU7WUFDSixJQUFJO1lBQ0osSUFBSSxFQUFFLFFBQVE7U0FDZjtRQUNELE1BQU0sRUFBRSxLQUFLO0tBQ2QsQ0FBQyxDQUFDO0lBRUgsTUFBTSxNQUFNLEdBQW1CLEVBQUUsQ0FBQztJQUVsQyxJQUFJLENBQUM7UUFDSCxNQUFNLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUN2QixPQUFPLENBQUMsR0FBRyxDQUFDLGlDQUFpQyxDQUFDLENBQUM7UUFFL0MsTUFBTSxJQUFJLEdBQUcsTUFBTSxNQUFNLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRWpELElBQUksQ0FBQztZQUNILHFCQUFxQjtZQUNyQixNQUFNLFdBQVcsR0FBUSxVQUFVLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7WUFFOUQsc0JBQXNCO1lBQ3RC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b0JBQzVCLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSSxJQUFJLEtBQUssQ0FBQyxJQUFJLElBQUksRUFBRTtvQkFDcEMsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLElBQUksRUFBRTtvQkFDdEIsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLElBQUksSUFBSSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUU7b0JBQzVDLFdBQVcsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsV0FBVyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO2lCQUNqRSxDQUFDO1lBQ0osQ0FBQztTQUNGO0tBQ0Y7Q0FDRixDQUFDO0FBRVcsUUFBQSxLQUFLLEdBQUcsUUFBUSxDQUFDO0FBQzlCLGtCQUFlLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGhhLWJpdHMvYml0LWVtYWlsXG4gKiBcbiAqIEVtYWlsIGludGVncmF0aW9uIGJpdCBmb3IgSU1BUCBmZXRjaGluZyBhbmQgU01UUCBzZW5kaW5nLlxuICogUHJvdmlkZXMgdHJpZ2dlcnMgZm9yIG5ldyBlbWFpbHMgYW5kIGFjdGlvbnMgZm9yIHNlbmRpbmcgZW1haWxzLlxuICovXG5cbmltcG9ydCB7IEltYXBGbG93IH0gZnJvbSAnaW1hcGZsb3cnO1xuXG5pbnRlcmZhY2UgRW1haWxDb250ZXh0IHtcbiAgYXV0aD86IHtcbiAgICBpbWFwSG9zdD86IHN0cmluZztcbiAgICBpbWFwUG9ydD86IG51bWJlcjtcbiAgICBpbWFwVXNlcj86IHN0cmluZztcbiAgICBpbWFwUGFzc3dvcmQ/OiBzdHJpbmc7XG4gICAgc210cEhvc3Q/OiBzdHJpbmc7XG4gICAgc210cFBvcnQ/OiBudW1iZXI7XG4gICAgc210cFVzZXI/OiBzdHJpbmc7XG4gICAgc210cFBhc3N3b3JkPzogc3RyaW5nO1xuICB9O1xuICBwcm9wc1ZhbHVlOiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xufVxuXG5pbnRlcmZhY2UgRW1haWxNZXNzYWdlIHtcbiAgaWQ6IHN0cmluZztcbiAgZnJvbTogc3RyaW5nO1xuICB0bzogc3RyaW5nO1xuICBzdWJqZWN0OiBzdHJpbmc7XG4gIGJvZHk6IHN0cmluZztcbiAgZGF0ZTogc3RyaW5nO1xuICBhdHRhY2htZW50cz86IEFycmF5PHtcbiAgICBmaWxlbmFtZTogc3RyaW5nO1xuICAgIGNvbnRlbnRUeXBlOiBzdHJpbmc7XG4gICAgc2l6ZTogbnVtYmVyO1xuICB9Pjtcbn1cblxuLyoqXG4gKiBGZXRjaCBlbWFpbHMgZnJvbSBJTUFQIHNlcnZlciB1c2luZyBpbWFwZmxvd1xuICovXG5hc3luYyBmdW5jdGlvbiBmZXRjaEltYXBFbWFpbHMoXG4gIGhvc3Q6IHN0cmluZyxcbiAgcG9ydDogbnVtYmVyLFxuICB1c2VyOiBzdHJpbmcsXG4gIHBhc3N3b3JkOiBzdHJpbmcsXG4gIGZvbGRlcjogc3RyaW5nID0gJ0lOQk9YJyxcbiAgbGltaXQ6IG51bWJlciA9IDEwLFxuICB1bnJlYWRPbmx5OiBib29sZWFuID0gdHJ1ZVxuKTogUHJvbWlzZTxFbWFpbE1lc3NhZ2VbXT4ge1xuICBjb25zb2xlLmxvZyhg8J+TpyBJTUFQOiBDb25uZWN0aW5nIHRvICR7aG9zdH06JHtwb3J0fSBhcyAke3VzZXJ9Li4uYCk7XG4gIGNvbnNvbGUubG9nKGDwn5OnIElNQVA6IEZldGNoaW5nIGZyb20gJHtmb2xkZXJ9LCBsaW1pdDogJHtsaW1pdH0sIHVucmVhZE9ubHk6ICR7dW5yZWFkT25seX1gKTtcbiAgXG4gIGNvbnN0IGNsaWVudCA9IG5ldyBJbWFwRmxvdyh7XG4gICAgaG9zdCxcbiAgICBwb3J0LFxuICAgIHNlY3VyZTogcG9ydCA9PT0gOTkzLFxuICAgIGF1dGg6IHtcbiAgICAgIHVzZXIsXG4gICAgICBwYXNzOiBwYXNzd29yZCxcbiAgICB9LFxuICAgIGxvZ2dlcjogZmFsc2UsXG4gIH0pO1xuXG4gIGNvbnN0IGVtYWlsczogRW1haWxNZXNzYWdlW10gPSBbXTtcblxuICB0cnkge1xuICAgIGF3YWl0IGNsaWVudC5jb25uZWN0KCk7XG4gICAgY29uc29sZS5sb2coYPCfk6cgSU1BUDogQ29ubmVjdGVkIHN1Y2Nlc3NmdWxseWApO1xuXG4gICAgY29uc3QgbG9jayA9IGF3YWl0IGNsaWVudC5nZXRNYWlsYm94TG9jayhmb2xkZXIpO1xuICAgIFxuICAgIHRyeSB7XG4gICAgICAvLyBCdWlsZCBzZWFyY2ggcXVlcnlcbiAgICAgIGNvbnN0IHNlYXJjaFF1ZXJ5OiBhbnkgPSB1bnJlYWRPbmx5ID8geyBzZWVuOiBmYWxzZSB9IDogJ2FsbCc7XG4gICAgICBcbiAgICAgIC8vIFNlYXJjaCBmb3IgbWVzc2FnZXNcbiAgICAgIGNvbnN0IHNlYXJjaFJlc3VsdCA9IGF3YWl0IGNsaWVudC5zZWFyY2goc2VhcmNoUXVlcnksIHsgdWlkOiB0cnVlIH0pO1xuICAgICAgY29uc3QgbWVzc2FnZXMgPSBBcnJheS5pc0FycmF5KHNlYXJjaFJlc3VsdCkgPyBzZWFyY2hSZXN1bHQgOiBbXTtcbiAgICAgIFxuICAgICAgaWYgKG1lc3NhZ2VzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICBjb25zb2xlLmxvZyhg8J+TpyBJTUFQOiBObyBtZXNzYWdlcyBmb3VuZCBtYXRjaGluZyBjcml0ZXJpYWApO1xuICAgICAgICByZXR1cm4gZW1haWxzO1xuICAgICAgfVxuXG4gICAgICAvLyBHZXQgdGhlIG1vc3QgcmVjZW50IG1lc3NhZ2VzIHVwIHRvIGxpbWl0XG4gICAgICBjb25zdCBtZXNzYWdlc1RvRmV0Y2ggPSBtZXNzYWdlcy5zbGljZSgtbGltaXQpLnJldmVyc2UoKTtcbiAgICAgIGNvbnNvbGUubG9nKGDwn5OnIElNQVA6IEZvdW5kICR7bWVzc2FnZXMubGVuZ3RofSBtZXNzYWdlcywgZmV0Y2hpbmcgJHttZXNzYWdlc1RvRmV0Y2gubGVuZ3RofWApO1xuXG4gICAgICAvLyBGZXRjaCBtZXNzYWdlIGRldGFpbHNcbiAgICAgIGZvciBhd2FpdCAoY29uc3QgbWVzc2FnZSBvZiBjbGllbnQuZmV0Y2gobWVzc2FnZXNUb0ZldGNoLCB7XG4gICAgICAgIHVpZDogdHJ1ZSxcbiAgICAgICAgZW52ZWxvcGU6IHRydWUsXG4gICAgICAgIHNvdXJjZTogdHJ1ZSxcbiAgICAgICAgYm9keVN0cnVjdHVyZTogdHJ1ZSxcbiAgICAgIH0pKSB7XG4gICAgICAgIGNvbnN0IGVudmVsb3BlID0gbWVzc2FnZS5lbnZlbG9wZTtcbiAgICAgICAgaWYgKCFlbnZlbG9wZSkgY29udGludWU7XG4gICAgICAgIFxuICAgICAgICAvLyBQYXJzZSBmcm9tIGFkZHJlc3NcbiAgICAgICAgY29uc3QgZnJvbUFkZHIgPSBlbnZlbG9wZS5mcm9tPy5bMF07XG4gICAgICAgIGNvbnN0IGZyb20gPSBmcm9tQWRkciBcbiAgICAgICAgICA/IChmcm9tQWRkci5uYW1lID8gYCR7ZnJvbUFkZHIubmFtZX0gPCR7ZnJvbUFkZHIuYWRkcmVzc30+YCA6IGZyb21BZGRyLmFkZHJlc3MgfHwgJycpXG4gICAgICAgICAgOiAnJztcbiAgICAgICAgXG4gICAgICAgIC8vIFBhcnNlIHRvIGFkZHJlc3Nlc1xuICAgICAgICBjb25zdCB0b0FkZHJzID0gZW52ZWxvcGUudG8gfHwgW107XG4gICAgICAgIGNvbnN0IHRvID0gdG9BZGRyc1xuICAgICAgICAgIC5tYXAoKGFkZHI6IGFueSkgPT4gYWRkci5uYW1lID8gYCR7YWRkci5uYW1lfSA8JHthZGRyLmFkZHJlc3N9PmAgOiBhZGRyLmFkZHJlc3MgfHwgJycpXG4gICAgICAgICAgLmpvaW4oJywgJyk7XG5cbiAgICAgICAgLy8gRXh0cmFjdCBib2R5IGZyb20gc291cmNlXG4gICAgICAgIGxldCBib2R5ID0gJyc7XG4gICAgICAgIGlmIChtZXNzYWdlLnNvdXJjZSkge1xuICAgICAgICAgIGNvbnN0IHNvdXJjZVN0ciA9IG1lc3NhZ2Uuc291cmNlLnRvU3RyaW5nKCk7XG4gICAgICAgICAgLy8gU2ltcGxlIGV4dHJhY3Rpb24gLSBmaW5kIGJvZHkgYWZ0ZXIgaGVhZGVyc1xuICAgICAgICAgIGNvbnN0IGJvZHlNYXRjaCA9IHNvdXJjZVN0ci5zcGxpdCgvXFxyP1xcblxccj9cXG4vKTtcbiAgICAgICAgICBpZiAoYm9keU1hdGNoLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgIGJvZHkgPSBib2R5TWF0Y2guc2xpY2UoMSkuam9pbignXFxuXFxuJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gRXh0cmFjdCBhdHRhY2htZW50cyBpbmZvIGZyb20gYm9keVN0cnVjdHVyZVxuICAgICAgICBjb25zdCBhdHRhY2htZW50czogQXJyYXk8eyBmaWxlbmFtZTogc3RyaW5nOyBjb250ZW50VHlwZTogc3RyaW5nOyBzaXplOiBudW1iZXIgfT4gPSBbXTtcbiAgICAgICAgaWYgKG1lc3NhZ2UuYm9keVN0cnVjdHVyZSkge1xuICAgICAgICAgIGV4dHJhY3RBdHRhY2htZW50cyhtZXNzYWdlLmJvZHlTdHJ1Y3R1cmUsIGF0dGFjaG1lbnRzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGVtYWlscy5wdXNoKHtcbiAgICAgICAgICBpZDogU3RyaW5nKG1lc3NhZ2UudWlkKSxcbiAgICAgICAgICBmcm9tLFxuICAgICAgICAgIHRvLFxuICAgICAgICAgIHN1YmplY3Q6IGVudmVsb3BlLnN1YmplY3QgfHwgJycsXG4gICAgICAgICAgYm9keSxcbiAgICAgICAgICBkYXRlOiBlbnZlbG9wZS5kYXRlPy50b0lTT1N0cmluZygpIHx8IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICBhdHRhY2htZW50czogYXR0YWNobWVudHMubGVuZ3RoID4gMCA/IGF0dGFjaG1lbnRzIDogdW5kZWZpbmVkLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGZpbmFsbHkge1xuICAgICAgbG9jay5yZWxlYXNlKCk7XG4gICAgfVxuICB9IGZpbmFsbHkge1xuICAgIGF3YWl0IGNsaWVudC5sb2dvdXQoKTtcbiAgICBjb25zb2xlLmxvZyhg8J+TpyBJTUFQOiBEaXNjb25uZWN0ZWRgKTtcbiAgfVxuXG4gIGNvbnNvbGUubG9nKGDwn5OnIElNQVA6IEZldGNoZWQgJHtlbWFpbHMubGVuZ3RofSBlbWFpbChzKWApO1xuICByZXR1cm4gZW1haWxzO1xufVxuXG4vKipcbiAqIFJlY3Vyc2l2ZWx5IGV4dHJhY3QgYXR0YWNobWVudCBpbmZvIGZyb20gYm9keVN0cnVjdHVyZVxuICovXG5mdW5jdGlvbiBleHRyYWN0QXR0YWNobWVudHMoXG4gIHN0cnVjdHVyZTogYW55LFxuICBhdHRhY2htZW50czogQXJyYXk8eyBmaWxlbmFtZTogc3RyaW5nOyBjb250ZW50VHlwZTogc3RyaW5nOyBzaXplOiBudW1iZXIgfT5cbik6IHZvaWQge1xuICBpZiAoIXN0cnVjdHVyZSkgcmV0dXJuO1xuXG4gIC8vIENoZWNrIGlmIHRoaXMgcGFydCBpcyBhbiBhdHRhY2htZW50XG4gIGlmIChzdHJ1Y3R1cmUuZGlzcG9zaXRpb24gPT09ICdhdHRhY2htZW50JyB8fCBcbiAgICAgIChzdHJ1Y3R1cmUuZGlzcG9zaXRpb24gPT09ICdpbmxpbmUnICYmIHN0cnVjdHVyZS5kaXNwb3NpdGlvblBhcmFtZXRlcnM/LmZpbGVuYW1lKSkge1xuICAgIGNvbnN0IGZpbGVuYW1lID0gc3RydWN0dXJlLmRpc3Bvc2l0aW9uUGFyYW1ldGVycz8uZmlsZW5hbWUgfHwgXG4gICAgICAgICAgICAgICAgICAgICBzdHJ1Y3R1cmUucGFyYW1ldGVycz8ubmFtZSB8fCBcbiAgICAgICAgICAgICAgICAgICAgICdhdHRhY2htZW50JztcbiAgICBhdHRhY2htZW50cy5wdXNoKHtcbiAgICAgIGZpbGVuYW1lLFxuICAgICAgY29udGVudFR5cGU6IGAke3N0cnVjdHVyZS50eXBlfS8ke3N0cnVjdHVyZS5zdWJ0eXBlfWAsXG4gICAgICBzaXplOiBzdHJ1Y3R1cmUuc2l6ZSB8fCAwLFxuICAgIH0pO1xuICB9XG5cbiAgLy8gUmVjdXJzZSBpbnRvIGNoaWxkIHBhcnRzXG4gIGlmIChzdHJ1Y3R1cmUuY2hpbGROb2RlcyAmJiBBcnJheS5pc0FycmF5KHN0cnVjdHVyZS5jaGlsZE5vZGVzKSkge1xuICAgIGZvciAoY29uc3QgY2hpbGQgb2Ygc3RydWN0dXJlLmNoaWxkTm9kZXMpIHtcbiAgICAgIGV4dHJhY3RBdHRhY2htZW50cyhjaGlsZCwgYXR0YWNobWVudHMpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFNpbXVsYXRlIFNNVFAgc2VuZCAoaW4gcmVhbCBpbXBsZW1lbnRhdGlvbiwgdXNlIG5vZGVtYWlsZXIgb3Igc2ltaWxhcilcbiAqL1xuYXN5bmMgZnVuY3Rpb24gc2VuZFNtdHBFbWFpbChcbiAgaG9zdDogc3RyaW5nLFxuICBwb3J0OiBudW1iZXIsXG4gIHVzZXI6IHN0cmluZyxcbiAgcGFzc3dvcmQ6IHN0cmluZyxcbiAgZnJvbTogc3RyaW5nLFxuICB0bzogc3RyaW5nLFxuICBzdWJqZWN0OiBzdHJpbmcsXG4gIGJvZHk6IHN0cmluZyxcbiAgaHRtbD86IHN0cmluZyxcbiAgYXR0YWNobWVudHM/OiBBcnJheTx7IGZpbGVuYW1lOiBzdHJpbmc7IGNvbnRlbnQ6IHN0cmluZyB8IEJ1ZmZlciB9PlxuKTogUHJvbWlzZTx7IG1lc3NhZ2VJZDogc3RyaW5nOyBhY2NlcHRlZDogc3RyaW5nW10gfT4ge1xuICBjb25zb2xlLmxvZyhg8J+TpCBTTVRQOiBDb25uZWN0aW5nIHRvICR7aG9zdH06JHtwb3J0fSBhcyAke3VzZXJ9Li4uYCk7XG4gIGNvbnNvbGUubG9nKGDwn5OkIFNNVFA6IFNlbmRpbmcgZnJvbSAke2Zyb219IHRvICR7dG99YCk7XG4gIGNvbnNvbGUubG9nKGDwn5OkIFNNVFA6IFN1YmplY3Q6ICR7c3ViamVjdH1gKTtcbiAgXG4gIC8vIEluIHByb2R1Y3Rpb24sIHRoaXMgd291bGQgdXNlIG5vZGVtYWlsZXJcbiAgLy8gRm9yIG5vdywgcmV0dXJuIG1vY2sgcmVzcG9uc2VcbiAgY29uc3QgbWVzc2FnZUlkID0gYDwke0RhdGUubm93KCl9LiR7TWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc3Vic3RyaW5nKDcpfUBoYWJpdHMubG9jYWw+YDtcbiAgXG4gIHJldHVybiB7XG4gICAgbWVzc2FnZUlkLFxuICAgIGFjY2VwdGVkOiBbdG9dXG4gIH07XG59XG5cbmNvbnN0IGVtYWlsQml0ID0ge1xuICBkaXNwbGF5TmFtZTogJ0VtYWlsIChJTUFQL1NNVFApJyxcbiAgZGVzY3JpcHRpb246ICdFbWFpbCBpbnRlZ3JhdGlvbiBmb3IgZmV0Y2hpbmcgKElNQVApIGFuZCBzZW5kaW5nIChTTVRQKSBlbWFpbHMnLFxuICBsb2dvVXJsOiAnbHVjaWRlOk1haWwnLFxuICBcbiAgYXV0aDoge1xuICAgIHR5cGU6ICdDVVNUT00nLFxuICAgIGRpc3BsYXlOYW1lOiAnRW1haWwgQ3JlZGVudGlhbHMnLFxuICAgIGRlc2NyaXB0aW9uOiAnSU1BUCBhbmQgU01UUCBzZXJ2ZXIgY3JlZGVudGlhbHMnLFxuICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICBwcm9wczoge1xuICAgICAgaW1hcEhvc3Q6IHsgdHlwZTogJ1NIT1JUX1RFWFQnLCBkaXNwbGF5TmFtZTogJ0lNQVAgSG9zdCcsIHJlcXVpcmVkOiBmYWxzZSB9LFxuICAgICAgaW1hcFBvcnQ6IHsgdHlwZTogJ05VTUJFUicsIGRpc3BsYXlOYW1lOiAnSU1BUCBQb3J0JywgcmVxdWlyZWQ6IGZhbHNlLCBkZWZhdWx0VmFsdWU6IDk5MyB9LFxuICAgICAgaW1hcFVzZXI6IHsgdHlwZTogJ1NIT1JUX1RFWFQnLCBkaXNwbGF5TmFtZTogJ0lNQVAgVXNlcm5hbWUnLCByZXF1aXJlZDogZmFsc2UgfSxcbiAgICAgIGltYXBQYXNzd29yZDogeyB0eXBlOiAnU0VDUkVUX1RFWFQnLCBkaXNwbGF5TmFtZTogJ0lNQVAgUGFzc3dvcmQnLCByZXF1aXJlZDogZmFsc2UgfSxcbiAgICAgIHNtdHBIb3N0OiB7IHR5cGU6ICdTSE9SVF9URVhUJywgZGlzcGxheU5hbWU6ICdTTVRQIEhvc3QnLCByZXF1aXJlZDogZmFsc2UgfSxcbiAgICAgIHNtdHBQb3J0OiB7IHR5cGU6ICdOVU1CRVInLCBkaXNwbGF5TmFtZTogJ1NNVFAgUG9ydCcsIHJlcXVpcmVkOiBmYWxzZSwgZGVmYXVsdFZhbHVlOiA1ODcgfSxcbiAgICAgIHNtdHBVc2VyOiB7IHR5cGU6ICdTSE9SVF9URVhUJywgZGlzcGxheU5hbWU6ICdTTVRQIFVzZXJuYW1lJywgcmVxdWlyZWQ6IGZhbHNlIH0sXG4gICAgICBzbXRwUGFzc3dvcmQ6IHsgdHlwZTogJ1NFQ1JFVF9URVhUJywgZGlzcGxheU5hbWU6ICdTTVRQIFBhc3N3b3JkJywgcmVxdWlyZWQ6IGZhbHNlIH0sXG4gICAgfVxuICB9LFxuICBcbiAgdHJpZ2dlcnM6IHtcbiAgICAvKipcbiAgICAgKiBJTUFQIHRyaWdnZXIgLSBmZXRjaCBuZXcgZW1haWxzXG4gICAgICovXG4gICAgbmV3RW1haWw6IHtcbiAgICAgIG5hbWU6ICduZXdFbWFpbCcsXG4gICAgICBkaXNwbGF5TmFtZTogJ05ldyBFbWFpbCAoSU1BUCknLFxuICAgICAgZGVzY3JpcHRpb246ICdUcmlnZ2VyIHdoZW4gbmV3IGVtYWlscyBhcnJpdmUgaW4gdGhlIG1haWxib3gnLFxuICAgICAgdHlwZTogJ1BPTExJTkcnLFxuICAgICAgcHJvcHM6IHtcbiAgICAgICAgaW1hcEhvc3Q6IHtcbiAgICAgICAgICB0eXBlOiAnU0hPUlRfVEVYVCcsXG4gICAgICAgICAgZGlzcGxheU5hbWU6ICdJTUFQIEhvc3QnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnSU1BUCBzZXJ2ZXIgaG9zdG5hbWUgKGUuZy4sIGltYXAuZ21haWwuY29tKScsXG4gICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICAgIGltYXBQb3J0OiB7XG4gICAgICAgICAgdHlwZTogJ05VTUJFUicsXG4gICAgICAgICAgZGlzcGxheU5hbWU6ICdJTUFQIFBvcnQnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnSU1BUCBzZXJ2ZXIgcG9ydCAoZGVmYXVsdDogOTkzIGZvciBTU0wpJyxcbiAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXG4gICAgICAgICAgZGVmYXVsdFZhbHVlOiA5OTMsXG4gICAgICAgIH0sXG4gICAgICAgIGltYXBVc2VyOiB7XG4gICAgICAgICAgdHlwZTogJ1NIT1JUX1RFWFQnLFxuICAgICAgICAgIGRpc3BsYXlOYW1lOiAnVXNlcm5hbWUnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnRW1haWwgYWRkcmVzcyBvciB1c2VybmFtZScsXG4gICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICAgIGltYXBQYXNzd29yZDoge1xuICAgICAgICAgIHR5cGU6ICdTRUNSRVRfVEVYVCcsXG4gICAgICAgICAgZGlzcGxheU5hbWU6ICdQYXNzd29yZCcsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdFbWFpbCBwYXNzd29yZCBvciBhcHAtc3BlY2lmaWMgcGFzc3dvcmQnLFxuICAgICAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICBmb2xkZXI6IHtcbiAgICAgICAgICB0eXBlOiAnU0hPUlRfVEVYVCcsXG4gICAgICAgICAgZGlzcGxheU5hbWU6ICdGb2xkZXInLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnTWFpbGJveCBmb2xkZXIgdG8gbW9uaXRvcicsXG4gICAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxuICAgICAgICAgIGRlZmF1bHRWYWx1ZTogJ0lOQk9YJyxcbiAgICAgICAgfSxcbiAgICAgICAgdW5yZWFkT25seToge1xuICAgICAgICAgIHR5cGU6ICdDSEVDS0JPWCcsXG4gICAgICAgICAgZGlzcGxheU5hbWU6ICdVbnJlYWQgT25seScsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdPbmx5IGZldGNoIHVucmVhZCBlbWFpbHMnLFxuICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgICAgICBkZWZhdWx0VmFsdWU6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICAgIGxpbWl0OiB7XG4gICAgICAgICAgdHlwZTogJ05VTUJFUicsXG4gICAgICAgICAgZGlzcGxheU5hbWU6ICdMaW1pdCcsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdNYXhpbXVtIG51bWJlciBvZiBlbWFpbHMgdG8gZmV0Y2gnLFxuICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgICAgICBkZWZhdWx0VmFsdWU6IDEwLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGFzeW5jIHJ1bihjb250ZXh0OiBFbWFpbENvbnRleHQpIHtcbiAgICAgICAgY29uc3QgeyBcbiAgICAgICAgICBpbWFwSG9zdCwgaW1hcFBvcnQgPSA5OTMsIGltYXBVc2VyLCBpbWFwUGFzc3dvcmQsXG4gICAgICAgICAgZm9sZGVyID0gJ0lOQk9YJywgdW5yZWFkT25seSA9IHRydWUsIGxpbWl0ID0gMTBcbiAgICAgICAgfSA9IGNvbnRleHQucHJvcHNWYWx1ZTtcbiAgICAgICAgXG4gICAgICAgIGNvbnN0IGhvc3QgPSBjb250ZXh0LmF1dGg/LmltYXBIb3N0IHx8IGltYXBIb3N0O1xuICAgICAgICBjb25zdCBwb3J0ID0gY29udGV4dC5hdXRoPy5pbWFwUG9ydCB8fCBpbWFwUG9ydDtcbiAgICAgICAgY29uc3QgdXNlciA9IGNvbnRleHQuYXV0aD8uaW1hcFVzZXIgfHwgaW1hcFVzZXI7XG4gICAgICAgIGNvbnN0IHBhc3N3b3JkID0gY29udGV4dC5hdXRoPy5pbWFwUGFzc3dvcmQgfHwgaW1hcFBhc3N3b3JkO1xuICAgICAgICBcbiAgICAgICAgaWYgKCFob3N0IHx8ICF1c2VyIHx8ICFwYXNzd29yZCkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSU1BUCBjcmVkZW50aWFscyBhcmUgcmVxdWlyZWQnKTtcbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgY29uc3QgZW1haWxzID0gYXdhaXQgZmV0Y2hJbWFwRW1haWxzKFxuICAgICAgICAgIGhvc3QsIE51bWJlcihwb3J0KSwgdXNlciwgcGFzc3dvcmQsXG4gICAgICAgICAgU3RyaW5nKGZvbGRlciksIE51bWJlcihsaW1pdCksIEJvb2xlYW4odW5yZWFkT25seSlcbiAgICAgICAgKTtcbiAgICAgICAgXG4gICAgICAgIGNvbnNvbGUubG9nKGDwn5OnIElNQVAgVHJpZ2dlcjogRmV0Y2hlZCAke2VtYWlscy5sZW5ndGh9IGVtYWlsKHMpYCk7XG4gICAgICAgIFxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGVtYWlscyxcbiAgICAgICAgICBjb3VudDogZW1haWxzLmxlbmd0aCxcbiAgICAgICAgICBmb2xkZXIsXG4gICAgICAgICAgdGltZXN0YW1wOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICAgIH07XG4gICAgICB9LFxuICAgIH0sXG4gIH0sXG4gIFxuICBhY3Rpb25zOiB7XG4gICAgLyoqXG4gICAgICogTmV3IEVtYWlsIGFjdGlvbiAoZm9yIHdvcmtmbG93IHRlc3RpbmcgLSBzaW11bGF0ZXMgSU1BUCB0cmlnZ2VyIGFzIGFjdGlvbilcbiAgICAgKi9cbiAgICBuZXdFbWFpbDoge1xuICAgICAgbmFtZTogJ25ld0VtYWlsJyxcbiAgICAgIGRpc3BsYXlOYW1lOiAnTmV3IEVtYWlsIChJTUFQKScsXG4gICAgICBkZXNjcmlwdGlvbjogJ0ZldGNoIG5ldyBlbWFpbHMgZnJvbSBJTUFQIG1haWxib3ggKGFjdGlvbiB2ZXJzaW9uIG9mIHRyaWdnZXIpJyxcbiAgICAgIHByb3BzOiB7XG4gICAgICAgIGltYXBIb3N0OiB7XG4gICAgICAgICAgdHlwZTogJ1NIT1JUX1RFWFQnLFxuICAgICAgICAgIGRpc3BsYXlOYW1lOiAnSU1BUCBIb3N0JyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ0lNQVAgc2VydmVyIGhvc3RuYW1lJyxcbiAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICAgIGltYXBQb3J0OiB7XG4gICAgICAgICAgdHlwZTogJ05VTUJFUicsXG4gICAgICAgICAgZGlzcGxheU5hbWU6ICdJTUFQIFBvcnQnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnSU1BUCBzZXJ2ZXIgcG9ydCcsXG4gICAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxuICAgICAgICAgIGRlZmF1bHRWYWx1ZTogOTkzLFxuICAgICAgICB9LFxuICAgICAgICBpbWFwVXNlcjoge1xuICAgICAgICAgIHR5cGU6ICdTSE9SVF9URVhUJyxcbiAgICAgICAgICBkaXNwbGF5TmFtZTogJ1VzZXJuYW1lJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ0VtYWlsIGFkZHJlc3Mgb3IgdXNlcm5hbWUnLFxuICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgICAgfSxcbiAgICAgICAgaW1hcFBhc3N3b3JkOiB7XG4gICAgICAgICAgdHlwZTogJ1NFQ1JFVF9URVhUJyxcbiAgICAgICAgICBkaXNwbGF5TmFtZTogJ1Bhc3N3b3JkJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ0VtYWlsIHBhc3N3b3JkJyxcbiAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICAgIGZvbGRlcjoge1xuICAgICAgICAgIHR5cGU6ICdTSE9SVF9URVhUJyxcbiAgICAgICAgICBkaXNwbGF5TmFtZTogJ0ZvbGRlcicsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdNYWlsYm94IGZvbGRlcicsXG4gICAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxuICAgICAgICAgIGRlZmF1bHRWYWx1ZTogJ0lOQk9YJyxcbiAgICAgICAgfSxcbiAgICAgICAgdW5yZWFkT25seToge1xuICAgICAgICAgIHR5cGU6ICdDSEVDS0JPWCcsXG4gICAgICAgICAgZGlzcGxheU5hbWU6ICdVbnJlYWQgT25seScsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdPbmx5IGZldGNoIHVucmVhZCBlbWFpbHMnLFxuICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgICAgICBkZWZhdWx0VmFsdWU6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICAgIGxpbWl0OiB7XG4gICAgICAgICAgdHlwZTogJ05VTUJFUicsXG4gICAgICAgICAgZGlzcGxheU5hbWU6ICdMaW1pdCcsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdNYXhpbXVtIG51bWJlciBvZiBlbWFpbHMnLFxuICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgICAgICBkZWZhdWx0VmFsdWU6IDEwLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGFzeW5jIHJ1bihjb250ZXh0OiBFbWFpbENvbnRleHQpIHtcbiAgICAgICAgY29uc3QgeyBmb2xkZXIgPSAnSU5CT1gnIH0gPSBjb250ZXh0LnByb3BzVmFsdWU7XG4gICAgICAgIFxuICAgICAgICAvLyBSZXR1cm4gbW9jayB0ZXN0IGRhdGEgZm9yIHdvcmtmbG93IHRlc3RpbmdcbiAgICAgICAgY29uc3QgbW9ja0VtYWlsczogRW1haWxNZXNzYWdlW10gPSBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgaWQ6IGBlbWFpbF8ke0RhdGUubm93KCl9YCxcbiAgICAgICAgICAgIGZyb206ICdjdXN0b21lckBleGFtcGxlLmNvbScsXG4gICAgICAgICAgICB0bzogJ3N1cHBvcnRAY29tcGFueS5jb20nLFxuICAgICAgICAgICAgc3ViamVjdDogJ0hlbHAgd2l0aCBteSBvcmRlciAjMTIzNDUnLFxuICAgICAgICAgICAgYm9keTogJ0hpLCBJIHBsYWNlZCBhbiBvcmRlciBsYXN0IHdlZWsgYW5kIGhhdmVuXFwndCByZWNlaXZlZCBhbnkgc2hpcHBpbmcgY29uZmlybWF0aW9uLiBDYW4geW91IGhlbHAgbWUgdHJhY2sgaXQ/IE9yZGVyIG51bWJlciBpcyAxMjM0NS4gVGhhbmtzIScsXG4gICAgICAgICAgICBkYXRlOiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICAgICAgfSxcbiAgICAgICAgICB7XG4gICAgICAgICAgICBpZDogYGVtYWlsXyR7RGF0ZS5ub3coKSArIDF9YCxcbiAgICAgICAgICAgIGZyb206ICdzYWxlcy5pbnF1aXJ5QHByb3NwZWN0LmNvbScsXG4gICAgICAgICAgICB0bzogJ3NhbGVzQGNvbXBhbnkuY29tJyxcbiAgICAgICAgICAgIHN1YmplY3Q6ICdQcmljaW5nIGlucXVpcnkgZm9yIGVudGVycHJpc2UgcGxhbicsXG4gICAgICAgICAgICBib2R5OiAnV2UgYXJlIGludGVyZXN0ZWQgaW4geW91ciBlbnRlcnByaXNlIHByaWNpbmcuIE91ciBjb21wYW55IGhhcyA1MDArIGVtcGxveWVlcy4gUGxlYXNlIHNlbmQgdXMgYSBxdW90ZS4nLFxuICAgICAgICAgICAgZGF0ZTogbmV3IERhdGUoRGF0ZS5ub3coKSAtIDM2MDAwMDApLnRvSVNPU3RyaW5nKCksXG4gICAgICAgICAgfSxcbiAgICAgICAgXTtcbiAgICAgICAgXG4gICAgICAgIGNvbnNvbGUubG9nKGDwn5OnIE5ldyBFbWFpbCAoTW9jayk6IFJldHVybmluZyAke21vY2tFbWFpbHMubGVuZ3RofSB0ZXN0IGVtYWlscyBmcm9tICR7Zm9sZGVyfWApO1xuICAgICAgICBcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBlbWFpbHM6IG1vY2tFbWFpbHMsXG4gICAgICAgICAgY291bnQ6IG1vY2tFbWFpbHMubGVuZ3RoLFxuICAgICAgICAgIGZvbGRlcixcbiAgICAgICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgfTtcbiAgICAgIH0sXG4gICAgfSxcbiAgICBcbiAgICAvKipcbiAgICAgKiBGZXRjaCBlbWFpbHMgZnJvbSBJTUFQIHNlcnZlclxuICAgICAqL1xuICAgIGZldGNoRW1haWxzOiB7XG4gICAgICBuYW1lOiAnZmV0Y2hFbWFpbHMnLFxuICAgICAgZGlzcGxheU5hbWU6ICdGZXRjaCBFbWFpbHMgKElNQVApJyxcbiAgICAgIGRlc2NyaXB0aW9uOiAnRmV0Y2ggZW1haWxzIGZyb20gYW4gSU1BUCBtYWlsYm94JyxcbiAgICAgIHByb3BzOiB7XG4gICAgICAgIGltYXBIb3N0OiB7XG4gICAgICAgICAgdHlwZTogJ1NIT1JUX1RFWFQnLFxuICAgICAgICAgIGRpc3BsYXlOYW1lOiAnSU1BUCBIb3N0JyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ0lNQVAgc2VydmVyIGhvc3RuYW1lJyxcbiAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgICAgaW1hcFBvcnQ6IHtcbiAgICAgICAgICB0eXBlOiAnTlVNQkVSJyxcbiAgICAgICAgICBkaXNwbGF5TmFtZTogJ0lNQVAgUG9ydCcsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdJTUFQIHNlcnZlciBwb3J0JyxcbiAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXG4gICAgICAgICAgZGVmYXVsdFZhbHVlOiA5OTMsXG4gICAgICAgIH0sXG4gICAgICAgIGltYXBVc2VyOiB7XG4gICAgICAgICAgdHlwZTogJ1NIT1JUX1RFWFQnLFxuICAgICAgICAgIGRpc3BsYXlOYW1lOiAnVXNlcm5hbWUnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnRW1haWwgYWRkcmVzcyBvciB1c2VybmFtZScsXG4gICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICAgIGltYXBQYXNzd29yZDoge1xuICAgICAgICAgIHR5cGU6ICdTRUNSRVRfVEVYVCcsXG4gICAgICAgICAgZGlzcGxheU5hbWU6ICdQYXNzd29yZCcsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdFbWFpbCBwYXNzd29yZCcsXG4gICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICAgIGZvbGRlcjoge1xuICAgICAgICAgIHR5cGU6ICdTSE9SVF9URVhUJyxcbiAgICAgICAgICBkaXNwbGF5TmFtZTogJ0ZvbGRlcicsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdNYWlsYm94IGZvbGRlciB0byBmZXRjaCBmcm9tJyxcbiAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXG4gICAgICAgICAgZGVmYXVsdFZhbHVlOiAnSU5CT1gnLFxuICAgICAgICB9LFxuICAgICAgICB1bnJlYWRPbmx5OiB7XG4gICAgICAgICAgdHlwZTogJ0NIRUNLQk9YJyxcbiAgICAgICAgICBkaXNwbGF5TmFtZTogJ1VucmVhZCBPbmx5JyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ09ubHkgZmV0Y2ggdW5yZWFkIGVtYWlscycsXG4gICAgICAgICAgcmVxdWlyZWQ6IGZhbHNlLFxuICAgICAgICAgIGRlZmF1bHRWYWx1ZTogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICAgIGxpbWl0OiB7XG4gICAgICAgICAgdHlwZTogJ05VTUJFUicsXG4gICAgICAgICAgZGlzcGxheU5hbWU6ICdMaW1pdCcsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdNYXhpbXVtIG51bWJlciBvZiBlbWFpbHMgdG8gZmV0Y2gnLFxuICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgICAgICBkZWZhdWx0VmFsdWU6IDEwLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgIGFzeW5jIHJ1bihjb250ZXh0OiBFbWFpbENvbnRleHQpIHtcbiAgICAgICAgY29uc3QgeyBcbiAgICAgICAgICBpbWFwSG9zdCwgaW1hcFBvcnQgPSA5OTMsIGltYXBVc2VyLCBpbWFwUGFzc3dvcmQsXG4gICAgICAgICAgZm9sZGVyID0gJ0lOQk9YJywgdW5yZWFkT25seSA9IGZhbHNlLCBsaW1pdCA9IDEwXG4gICAgICAgIH0gPSBjb250ZXh0LnByb3BzVmFsdWU7XG4gICAgICAgIFxuICAgICAgICBjb25zdCBob3N0ID0gY29udGV4dC5hdXRoPy5pbWFwSG9zdCB8fCBpbWFwSG9zdDtcbiAgICAgICAgY29uc3QgcG9ydCA9IGNvbnRleHQuYXV0aD8uaW1hcFBvcnQgfHwgaW1hcFBvcnQ7XG4gICAgICAgIGNvbnN0IHVzZXIgPSBjb250ZXh0LmF1dGg/LmltYXBVc2VyIHx8IGltYXBVc2VyO1xuICAgICAgICBjb25zdCBwYXNzd29yZCA9IGNvbnRleHQuYXV0aD8uaW1hcFBhc3N3b3JkIHx8IGltYXBQYXNzd29yZDtcbiAgICAgICAgXG4gICAgICAgIGlmICghaG9zdCB8fCAhdXNlciB8fCAhcGFzc3dvcmQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0lNQVAgY3JlZGVudGlhbHMgYXJlIHJlcXVpcmVkJyk7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIGNvbnN0IGVtYWlscyA9IGF3YWl0IGZldGNoSW1hcEVtYWlscyhcbiAgICAgICAgICBob3N0LCBOdW1iZXIocG9ydCksIHVzZXIsIHBhc3N3b3JkLFxuICAgICAgICAgIFN0cmluZyhmb2xkZXIpLCBOdW1iZXIobGltaXQpLCBCb29sZWFuKHVucmVhZE9ubHkpXG4gICAgICAgICk7XG4gICAgICAgIFxuICAgICAgICBjb25zb2xlLmxvZyhg8J+TpyBGZXRjaCBFbWFpbHM6IFJldHJpZXZlZCAke2VtYWlscy5sZW5ndGh9IGVtYWlsKHMpIGZyb20gJHtmb2xkZXJ9YCk7XG4gICAgICAgIFxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGVtYWlscyxcbiAgICAgICAgICBjb3VudDogZW1haWxzLmxlbmd0aCxcbiAgICAgICAgICBmb2xkZXIsXG4gICAgICAgIH07XG4gICAgICB9LFxuICAgIH0sXG4gICAgXG4gICAgLyoqXG4gICAgICogU2VuZCBlbWFpbCB2aWEgU01UUFxuICAgICAqL1xuICAgIHNlbmRFbWFpbDoge1xuICAgICAgbmFtZTogJ3NlbmRFbWFpbCcsXG4gICAgICBkaXNwbGF5TmFtZTogJ1NlbmQgRW1haWwgKFNNVFApJyxcbiAgICAgIGRlc2NyaXB0aW9uOiAnU2VuZCBhbiBlbWFpbCB2aWEgU01UUCcsXG4gICAgICBwcm9wczoge1xuICAgICAgICBzbXRwSG9zdDoge1xuICAgICAgICAgIHR5cGU6ICdTSE9SVF9URVhUJyxcbiAgICAgICAgICBkaXNwbGF5TmFtZTogJ1NNVFAgSG9zdCcsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdTTVRQIHNlcnZlciBob3N0bmFtZSAoZS5nLiwgc210cC5nbWFpbC5jb20pJyxcbiAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgICAgc210cFBvcnQ6IHtcbiAgICAgICAgICB0eXBlOiAnTlVNQkVSJyxcbiAgICAgICAgICBkaXNwbGF5TmFtZTogJ1NNVFAgUG9ydCcsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdTTVRQIHNlcnZlciBwb3J0ICg1ODcgZm9yIFRMUywgNDY1IGZvciBTU0wpJyxcbiAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXG4gICAgICAgICAgZGVmYXVsdFZhbHVlOiA1ODcsXG4gICAgICAgIH0sXG4gICAgICAgIHNtdHBVc2VyOiB7XG4gICAgICAgICAgdHlwZTogJ1NIT1JUX1RFWFQnLFxuICAgICAgICAgIGRpc3BsYXlOYW1lOiAnVXNlcm5hbWUnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnU01UUCB1c2VybmFtZS9lbWFpbCcsXG4gICAgICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICAgIHNtdHBQYXNzd29yZDoge1xuICAgICAgICAgIHR5cGU6ICdTRUNSRVRfVEVYVCcsXG4gICAgICAgICAgZGlzcGxheU5hbWU6ICdQYXNzd29yZCcsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdTTVRQIHBhc3N3b3JkJyxcbiAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgICAgZnJvbToge1xuICAgICAgICAgIHR5cGU6ICdTSE9SVF9URVhUJyxcbiAgICAgICAgICBkaXNwbGF5TmFtZTogJ0Zyb20nLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnU2VuZGVyIGVtYWlsIGFkZHJlc3MnLFxuICAgICAgICAgIHJlcXVpcmVkOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgICB0bzoge1xuICAgICAgICAgIHR5cGU6ICdTSE9SVF9URVhUJyxcbiAgICAgICAgICBkaXNwbGF5TmFtZTogJ1RvJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ1JlY2lwaWVudCBlbWFpbCBhZGRyZXNzKGVzKSwgY29tbWEtc2VwYXJhdGVkJyxcbiAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgICAgY2M6IHtcbiAgICAgICAgICB0eXBlOiAnU0hPUlRfVEVYVCcsXG4gICAgICAgICAgZGlzcGxheU5hbWU6ICdDQycsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdDQyByZWNpcGllbnRzIChvcHRpb25hbCknLFxuICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgICAgfSxcbiAgICAgICAgYmNjOiB7XG4gICAgICAgICAgdHlwZTogJ1NIT1JUX1RFWFQnLFxuICAgICAgICAgIGRpc3BsYXlOYW1lOiAnQkNDJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ0JDQyByZWNpcGllbnRzIChvcHRpb25hbCknLFxuICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgICAgfSxcbiAgICAgICAgc3ViamVjdDoge1xuICAgICAgICAgIHR5cGU6ICdTSE9SVF9URVhUJyxcbiAgICAgICAgICBkaXNwbGF5TmFtZTogJ1N1YmplY3QnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnRW1haWwgc3ViamVjdCBsaW5lJyxcbiAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgICAgYm9keToge1xuICAgICAgICAgIHR5cGU6ICdMT05HX1RFWFQnLFxuICAgICAgICAgIGRpc3BsYXlOYW1lOiAnQm9keSAoUGxhaW4gVGV4dCknLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnRW1haWwgYm9keSBpbiBwbGFpbiB0ZXh0JyxcbiAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgICAgaHRtbDoge1xuICAgICAgICAgIHR5cGU6ICdMT05HX1RFWFQnLFxuICAgICAgICAgIGRpc3BsYXlOYW1lOiAnQm9keSAoSFRNTCknLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnRW1haWwgYm9keSBpbiBIVE1MIGZvcm1hdCAob3B0aW9uYWwpJyxcbiAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXG4gICAgICAgIH0sXG4gICAgICAgIHJlcGx5VG86IHtcbiAgICAgICAgICB0eXBlOiAnU0hPUlRfVEVYVCcsXG4gICAgICAgICAgZGlzcGxheU5hbWU6ICdSZXBseS1UbycsXG4gICAgICAgICAgZGVzY3JpcHRpb246ICdSZXBseS10byBhZGRyZXNzIChvcHRpb25hbCknLFxuICAgICAgICAgIHJlcXVpcmVkOiBmYWxzZSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBhc3luYyBydW4oY29udGV4dDogRW1haWxDb250ZXh0KSB7XG4gICAgICAgIGNvbnN0IHsgXG4gICAgICAgICAgc210cEhvc3QsIHNtdHBQb3J0ID0gNTg3LCBzbXRwVXNlciwgc210cFBhc3N3b3JkLFxuICAgICAgICAgIGZyb20sIHRvLCBzdWJqZWN0LCBib2R5LCBodG1sLCBjYywgYmNjLCByZXBseVRvXG4gICAgICAgIH0gPSBjb250ZXh0LnByb3BzVmFsdWU7XG4gICAgICAgIFxuICAgICAgICBjb25zdCBob3N0ID0gY29udGV4dC5hdXRoPy5zbXRwSG9zdCB8fCBzbXRwSG9zdDtcbiAgICAgICAgY29uc3QgcG9ydCA9IGNvbnRleHQuYXV0aD8uc210cFBvcnQgfHwgc210cFBvcnQ7XG4gICAgICAgIGNvbnN0IHVzZXIgPSBjb250ZXh0LmF1dGg/LnNtdHBVc2VyIHx8IHNtdHBVc2VyO1xuICAgICAgICBjb25zdCBwYXNzd29yZCA9IGNvbnRleHQuYXV0aD8uc210cFBhc3N3b3JkIHx8IHNtdHBQYXNzd29yZDtcbiAgICAgICAgXG4gICAgICAgIGlmICghaG9zdCB8fCAhdXNlciB8fCAhcGFzc3dvcmQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NNVFAgY3JlZGVudGlhbHMgYXJlIHJlcXVpcmVkJyk7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIGlmICghZnJvbSB8fCAhdG8gfHwgIXN1YmplY3QgfHwgIWJvZHkpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Zyb20sIFRvLCBTdWJqZWN0LCBhbmQgQm9keSBhcmUgcmVxdWlyZWQnKTtcbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc2VuZFNtdHBFbWFpbChcbiAgICAgICAgICBob3N0LCBOdW1iZXIocG9ydCksIHVzZXIsIHBhc3N3b3JkLFxuICAgICAgICAgIFN0cmluZyhmcm9tKSwgU3RyaW5nKHRvKSwgU3RyaW5nKHN1YmplY3QpLCBTdHJpbmcoYm9keSksIGh0bWxcbiAgICAgICAgKTtcbiAgICAgICAgXG4gICAgICAgIGNvbnNvbGUubG9nKGDwn5OkIFNlbmQgRW1haWw6IE1lc3NhZ2Ugc2VudCB0byAke3RvfWApO1xuICAgICAgICBcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzdWNjZXNzOiB0cnVlLFxuICAgICAgICAgIG1lc3NhZ2VJZDogcmVzdWx0Lm1lc3NhZ2VJZCxcbiAgICAgICAgICBhY2NlcHRlZDogcmVzdWx0LmFjY2VwdGVkLFxuICAgICAgICAgIGZyb20sXG4gICAgICAgICAgdG8sXG4gICAgICAgICAgc3ViamVjdCxcbiAgICAgICAgICB0aW1lc3RhbXA6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgfTtcbiAgICAgIH0sXG4gICAgfSxcbiAgICBcbiAgICAvKipcbiAgICAgKiBQYXJzZSBlbWFpbCBjb250ZW50XG4gICAgICovXG4gICAgcGFyc2VFbWFpbDoge1xuICAgICAgbmFtZTogJ3BhcnNlRW1haWwnLFxuICAgICAgZGlzcGxheU5hbWU6ICdQYXJzZSBFbWFpbCcsXG4gICAgICBkZXNjcmlwdGlvbjogJ0V4dHJhY3Qgc3RydWN0dXJlZCBkYXRhIGZyb20gZW1haWwgY29udGVudCcsXG4gICAgICBwcm9wczoge1xuICAgICAgICByYXdFbWFpbDoge1xuICAgICAgICAgIHR5cGU6ICdMT05HX1RFWFQnLFxuICAgICAgICAgIGRpc3BsYXlOYW1lOiAnUmF3IEVtYWlsJyxcbiAgICAgICAgICBkZXNjcmlwdGlvbjogJ1JhdyBlbWFpbCBjb250ZW50IG9yIEpTT04gZW1haWwgb2JqZWN0JyxcbiAgICAgICAgICByZXF1aXJlZDogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgICAgZXh0cmFjdEF0dGFjaG1lbnRzOiB7XG4gICAgICAgICAgdHlwZTogJ0NIRUNLQk9YJyxcbiAgICAgICAgICBkaXNwbGF5TmFtZTogJ0V4dHJhY3QgQXR0YWNobWVudHMnLFxuICAgICAgICAgIGRlc2NyaXB0aW9uOiAnSW5jbHVkZSBhdHRhY2htZW50IGluZm9ybWF0aW9uJyxcbiAgICAgICAgICByZXF1aXJlZDogZmFsc2UsXG4gICAgICAgICAgZGVmYXVsdFZhbHVlOiBmYWxzZSxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICBhc3luYyBydW4oY29udGV4dDogRW1haWxDb250ZXh0KSB7XG4gICAgICAgIGNvbnN0IHsgcmF3RW1haWwsIGV4dHJhY3RBdHRhY2htZW50cyB9ID0gY29udGV4dC5wcm9wc1ZhbHVlO1xuICAgICAgICBcbiAgICAgICAgbGV0IGVtYWlsOiBhbnk7XG4gICAgICAgIGlmICh0eXBlb2YgcmF3RW1haWwgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGVtYWlsID0gSlNPTi5wYXJzZShyYXdFbWFpbCk7XG4gICAgICAgICAgfSBjYXRjaCB7XG4gICAgICAgICAgICAvLyBQYXJzZSBhcyByYXcgZW1haWwgdGV4dCAtIHNpbXBsaWZpZWQgcGFyc2luZ1xuICAgICAgICAgICAgY29uc3QgbGluZXMgPSByYXdFbWFpbC5zcGxpdCgnXFxuJyk7XG4gICAgICAgICAgICBlbWFpbCA9IHtcbiAgICAgICAgICAgICAgc3ViamVjdDogJycsXG4gICAgICAgICAgICAgIGZyb206ICcnLFxuICAgICAgICAgICAgICB0bzogJycsXG4gICAgICAgICAgICAgIGJvZHk6IHJhd0VtYWlsLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGZvciAoY29uc3QgbGluZSBvZiBsaW5lcykge1xuICAgICAgICAgICAgICBpZiAobGluZS50b0xvd2VyQ2FzZSgpLnN0YXJ0c1dpdGgoJ3N1YmplY3Q6JykpIHtcbiAgICAgICAgICAgICAgICBlbWFpbC5zdWJqZWN0ID0gbGluZS5zdWJzdHJpbmcoOCkudHJpbSgpO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKGxpbmUudG9Mb3dlckNhc2UoKS5zdGFydHNXaXRoKCdmcm9tOicpKSB7XG4gICAgICAgICAgICAgICAgZW1haWwuZnJvbSA9IGxpbmUuc3Vic3RyaW5nKDUpLnRyaW0oKTtcbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChsaW5lLnRvTG93ZXJDYXNlKCkuc3RhcnRzV2l0aCgndG86JykpIHtcbiAgICAgICAgICAgICAgICBlbWFpbC50byA9IGxpbmUuc3Vic3RyaW5nKDMpLnRyaW0oKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBlbWFpbCA9IHJhd0VtYWlsO1xuICAgICAgICB9XG4gICAgICAgIFxuICAgICAgICBjb25zb2xlLmxvZyhg8J+TpyBQYXJzZSBFbWFpbDogRXh0cmFjdGVkIGZyb20gJHtlbWFpbC5mcm9tIHx8ICd1bmtub3duJ31gKTtcbiAgICAgICAgXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgZnJvbTogZW1haWwuZnJvbSB8fCAnJyxcbiAgICAgICAgICB0bzogZW1haWwudG8gfHwgJycsXG4gICAgICAgICAgc3ViamVjdDogZW1haWwuc3ViamVjdCB8fCAnJyxcbiAgICAgICAgICBib2R5OiBlbWFpbC5ib2R5IHx8IGVtYWlsLnRleHQgfHwgJycsXG4gICAgICAgICAgaHRtbDogZW1haWwuaHRtbCB8fCAnJyxcbiAgICAgICAgICBkYXRlOiBlbWFpbC5kYXRlIHx8IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSxcbiAgICAgICAgICBhdHRhY2htZW50czogZXh0cmFjdEF0dGFjaG1lbnRzID8gKGVtYWlsLmF0dGFjaG1lbnRzIHx8IFtdKSA6IFtdLFxuICAgICAgICB9O1xuICAgICAgfSxcbiAgICB9LFxuICB9LFxufTtcblxuZXhwb3J0IGNvbnN0IGVtYWlsID0gZW1haWxCaXQ7XG5leHBvcnQgZGVmYXVsdCBlbWFpbEJpdDtcbiJdfQ==