@ukwhatn/wikidot 4.0.2 → 4.0.4

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.
@@ -1,980 +0,0 @@
1
- import {
2
- User
3
- } from "./index-kka6e8cb.js";
4
- import {
5
- LoginRequiredError,
6
- NoElementError,
7
- UnexpectedError,
8
- __legacyDecorateClassTS,
9
- fromPromise,
10
- wdErrAsync
11
- } from "./index-7dqqxq7x.js";
12
-
13
- // src/module/forum/forum-category.ts
14
- import * as cheerio3 from "cheerio";
15
-
16
- // src/common/decorators.ts
17
- function getClientRef(obj) {
18
- if (obj.client)
19
- return obj.client;
20
- if (obj.site?.client)
21
- return obj.site.client;
22
- if (obj.thread?.site?.client)
23
- return obj.thread.site.client;
24
- return null;
25
- }
26
- function RequireLogin(target, _context) {
27
- return function(...args) {
28
- const clientRef = getClientRef(this);
29
- if (!clientRef) {
30
- return wdErrAsync(new LoginRequiredError("Client reference not found"));
31
- }
32
- const loginResult = clientRef.requireLogin();
33
- if (loginResult.isErr()) {
34
- return fromPromise(Promise.reject(loginResult.error), () => new LoginRequiredError("Login required"));
35
- }
36
- return target.call(this, ...args);
37
- };
38
- }
39
-
40
- // src/module/forum/forum-thread.ts
41
- import * as cheerio2 from "cheerio";
42
-
43
- // src/common/logger.ts
44
- var LOG_LEVEL_PRIORITY = {
45
- debug: 0,
46
- info: 1,
47
- warn: 2,
48
- error: 3
49
- };
50
- var nullHandler = () => {};
51
- var consoleHandler = (level, name, message, ...args) => {
52
- const timestamp = new Date().toISOString();
53
- const formattedMessage = `${timestamp} [${name}/${level.toUpperCase()}] ${message}`;
54
- switch (level) {
55
- case "debug":
56
- console.debug(formattedMessage, ...args);
57
- break;
58
- case "info":
59
- console.info(formattedMessage, ...args);
60
- break;
61
- case "warn":
62
- console.warn(formattedMessage, ...args);
63
- break;
64
- case "error":
65
- console.error(formattedMessage, ...args);
66
- break;
67
- }
68
- };
69
-
70
- class Logger {
71
- name;
72
- handler;
73
- level;
74
- constructor(name, handler = nullHandler, level = "warn") {
75
- this.name = name;
76
- this.handler = handler;
77
- this.level = level;
78
- }
79
- setHandler(handler) {
80
- this.handler = handler;
81
- }
82
- setLevel(level) {
83
- this.level = level;
84
- }
85
- shouldLog(level) {
86
- return LOG_LEVEL_PRIORITY[level] >= LOG_LEVEL_PRIORITY[this.level];
87
- }
88
- log(level, message, ...args) {
89
- if (this.shouldLog(level)) {
90
- this.handler(level, this.name, message, ...args);
91
- }
92
- }
93
- debug(message, ...args) {
94
- this.log("debug", message, ...args);
95
- }
96
- info(message, ...args) {
97
- this.log("info", message, ...args);
98
- }
99
- warn(message, ...args) {
100
- this.log("warn", message, ...args);
101
- }
102
- error(message, ...args) {
103
- this.log("error", message, ...args);
104
- }
105
- }
106
- function getLogger(name = "wikidot") {
107
- return new Logger(name);
108
- }
109
- function setupConsoleHandler(logger, level = "warn") {
110
- logger.setHandler(consoleHandler);
111
- logger.setLevel(level);
112
- }
113
- var logger = getLogger();
114
-
115
- // src/module/user/anonymous-user.ts
116
- class AnonymousUser {
117
- client;
118
- id = 0;
119
- name = "Anonymous";
120
- unixName = "anonymous";
121
- avatarUrl = null;
122
- ip;
123
- userType = "anonymous";
124
- constructor(client, ip) {
125
- this.client = client;
126
- this.ip = ip;
127
- }
128
- isUser() {
129
- return false;
130
- }
131
- isDeletedUser() {
132
- return false;
133
- }
134
- isAnonymousUser() {
135
- return true;
136
- }
137
- isGuestUser() {
138
- return false;
139
- }
140
- isWikidotUser() {
141
- return false;
142
- }
143
- toString() {
144
- return `AnonymousUser(name=${this.name}, unixName=${this.unixName}, ip=${this.ip})`;
145
- }
146
- }
147
- // src/module/user/deleted-user.ts
148
- class DeletedUser {
149
- client;
150
- id;
151
- name = "account deleted";
152
- unixName = "account_deleted";
153
- avatarUrl = null;
154
- ip = null;
155
- userType = "deleted";
156
- constructor(client, id) {
157
- this.client = client;
158
- this.id = id;
159
- }
160
- isUser() {
161
- return false;
162
- }
163
- isDeletedUser() {
164
- return true;
165
- }
166
- isAnonymousUser() {
167
- return false;
168
- }
169
- isGuestUser() {
170
- return false;
171
- }
172
- isWikidotUser() {
173
- return false;
174
- }
175
- toString() {
176
- return `DeletedUser(id=${this.id}, name=${this.name}, unixName=${this.unixName})`;
177
- }
178
- }
179
- // src/module/user/guest-user.ts
180
- class GuestUser {
181
- client;
182
- id = 0;
183
- name;
184
- unixName = null;
185
- avatarUrl;
186
- ip = null;
187
- userType = "guest";
188
- constructor(client, name, avatarUrl = null) {
189
- this.client = client;
190
- this.name = name;
191
- this.avatarUrl = avatarUrl;
192
- }
193
- isUser() {
194
- return false;
195
- }
196
- isDeletedUser() {
197
- return false;
198
- }
199
- isAnonymousUser() {
200
- return false;
201
- }
202
- isGuestUser() {
203
- return true;
204
- }
205
- isWikidotUser() {
206
- return false;
207
- }
208
- toString() {
209
- return `GuestUser(name=${this.name})`;
210
- }
211
- }
212
- // src/module/user/wikidot-user.ts
213
- class WikidotUser {
214
- client;
215
- id = 0;
216
- name = "Wikidot";
217
- unixName = "wikidot";
218
- avatarUrl = null;
219
- ip = null;
220
- userType = "wikidot";
221
- constructor(client) {
222
- this.client = client;
223
- }
224
- isUser() {
225
- return false;
226
- }
227
- isDeletedUser() {
228
- return false;
229
- }
230
- isAnonymousUser() {
231
- return false;
232
- }
233
- isGuestUser() {
234
- return false;
235
- }
236
- isWikidotUser() {
237
- return true;
238
- }
239
- toString() {
240
- return `WikidotUser(name=${this.name}, unixName=${this.unixName})`;
241
- }
242
- }
243
- // src/util/parser/user.ts
244
- function parseUser(client, elem) {
245
- const classAttr = elem.attr("class") ?? "";
246
- const classes = classAttr.split(/\s+/);
247
- if (classes.includes("deleted")) {
248
- const dataId = elem.attr("data-id");
249
- const userId2 = dataId ? Number.parseInt(dataId, 10) : 0;
250
- return new DeletedUser(client, userId2);
251
- }
252
- const text = elem.text().trim();
253
- if (text === "(user deleted)") {
254
- return new DeletedUser(client, 0);
255
- }
256
- if (classes.includes("anonymous")) {
257
- const ipElem = elem.find("span.ip");
258
- if (ipElem.length > 0) {
259
- const ip = ipElem.text().replace(/[()]/g, "").trim();
260
- return new AnonymousUser(client, ip);
261
- }
262
- return new AnonymousUser(client, "");
263
- }
264
- const imgElem = elem.find("img");
265
- if (imgElem.length > 0) {
266
- const src = imgElem.attr("src") ?? "";
267
- if (src.includes("gravatar.com")) {
268
- const guestName = text.split(" ")[0] ?? "Guest";
269
- return new GuestUser(client, guestName, src);
270
- }
271
- }
272
- if (text === "Wikidot") {
273
- return new WikidotUser(client);
274
- }
275
- const links = elem.find("a");
276
- if (links.length === 0) {
277
- return new DeletedUser(client, 0);
278
- }
279
- const userLink = links.last();
280
- const userName = userLink.text().trim();
281
- const href = userLink.attr("href") ?? "";
282
- const onclick = userLink.attr("onclick") ?? "";
283
- const unixName = href.replace(/^.*\/user:info\//, "").replace(/\/$/, "");
284
- const userIdMatch = onclick.match(/userInfo\((\d+)\)/);
285
- const userId = userIdMatch?.[1] ? Number.parseInt(userIdMatch[1], 10) : 0;
286
- const avatarUrl = userId > 0 ? `http://www.wikidot.com/avatar.php?userid=${userId}` : undefined;
287
- return new User(client, {
288
- id: userId,
289
- name: userName,
290
- unixName,
291
- avatarUrl
292
- });
293
- }
294
- function parseOdate(elem) {
295
- const classAttr = elem.attr("class") ?? "";
296
- const timeMatch = classAttr.match(/time_(\d+)/);
297
- if (timeMatch?.[1]) {
298
- const unixTime = Number.parseInt(timeMatch[1], 10);
299
- return new Date(unixTime * 1000);
300
- }
301
- const text = elem.text().trim();
302
- const parsed = Date.parse(text);
303
- if (!Number.isNaN(parsed)) {
304
- return new Date(parsed);
305
- }
306
- logger.warn(`Failed to parse odate element: class="${classAttr}", text="${text}"`);
307
- return null;
308
- }
309
- // src/module/forum/forum-post.ts
310
- import * as cheerio from "cheerio";
311
- class ForumPost {
312
- thread;
313
- id;
314
- title;
315
- text;
316
- element;
317
- createdBy;
318
- createdAt;
319
- editedBy;
320
- editedAt;
321
- _parentId;
322
- _source = null;
323
- constructor(data) {
324
- this.thread = data.thread;
325
- this.id = data.id;
326
- this.title = data.title;
327
- this.text = data.text;
328
- this.element = data.element;
329
- this.createdBy = data.createdBy;
330
- this.createdAt = data.createdAt;
331
- this.editedBy = data.editedBy ?? null;
332
- this.editedAt = data.editedAt ?? null;
333
- this._parentId = data.parentId ?? null;
334
- }
335
- get parentId() {
336
- return this._parentId;
337
- }
338
- getSource() {
339
- if (this._source !== null) {
340
- return fromPromise(Promise.resolve(this._source), (e) => new UnexpectedError(String(e)));
341
- }
342
- return fromPromise((async () => {
343
- const result = await this.thread.site.amcRequest([
344
- {
345
- moduleName: "forum/sub/ForumEditPostFormModule",
346
- threadId: this.thread.id,
347
- postId: this.id
348
- }
349
- ]);
350
- if (result.isErr()) {
351
- throw result.error;
352
- }
353
- const response = result.value[0];
354
- if (!response) {
355
- throw new NoElementError("Empty response");
356
- }
357
- const $ = cheerio.load(String(response.body ?? ""));
358
- const sourceElem = $("textarea[name='source']");
359
- if (sourceElem.length === 0) {
360
- throw new NoElementError("Source textarea not found");
361
- }
362
- this._source = sourceElem.text();
363
- return this._source;
364
- })(), (error) => {
365
- if (error instanceof NoElementError)
366
- return error;
367
- return new UnexpectedError(`Failed to get post source: ${String(error)}`);
368
- });
369
- }
370
- edit(source, title) {
371
- return fromPromise((async () => {
372
- const formResult = await this.thread.site.amcRequest([
373
- {
374
- moduleName: "forum/sub/ForumEditPostFormModule",
375
- threadId: this.thread.id,
376
- postId: this.id
377
- }
378
- ]);
379
- if (formResult.isErr()) {
380
- throw formResult.error;
381
- }
382
- const formResponse = formResult.value[0];
383
- if (!formResponse) {
384
- throw new NoElementError("Empty form response");
385
- }
386
- const $ = cheerio.load(String(formResponse.body ?? ""));
387
- const revisionInput = $("input[name='currentRevisionId']");
388
- if (revisionInput.length === 0) {
389
- throw new NoElementError("Current revision ID input not found");
390
- }
391
- const revisionValue = revisionInput.val();
392
- const currentRevisionId = Number.parseInt(String(revisionValue ?? ""), 10);
393
- if (Number.isNaN(currentRevisionId)) {
394
- throw new NoElementError("Invalid revision ID value");
395
- }
396
- const editResult = await this.thread.site.amcRequest([
397
- {
398
- action: "ForumAction",
399
- event: "saveEditPost",
400
- moduleName: "Empty",
401
- postId: this.id,
402
- currentRevisionId,
403
- title: title ?? this.title,
404
- source
405
- }
406
- ]);
407
- if (editResult.isErr()) {
408
- throw editResult.error;
409
- }
410
- if (title !== undefined) {
411
- this.title = title;
412
- }
413
- this._source = source;
414
- })(), (error) => {
415
- if (error instanceof NoElementError || error instanceof LoginRequiredError) {
416
- return error;
417
- }
418
- return new UnexpectedError(`Failed to edit post: ${String(error)}`);
419
- });
420
- }
421
- toString() {
422
- return `ForumPost(id=${this.id}, title=${this.title})`;
423
- }
424
- }
425
- __legacyDecorateClassTS([
426
- RequireLogin
427
- ], ForumPost.prototype, "edit", null);
428
-
429
- class ForumPostCollection extends Array {
430
- thread;
431
- constructor(thread, posts) {
432
- super();
433
- this.thread = thread;
434
- if (posts) {
435
- this.push(...posts);
436
- }
437
- }
438
- findById(id) {
439
- return this.find((post) => post.id === id);
440
- }
441
- static _parse(thread, $) {
442
- const posts = [];
443
- $("div.post").each((_i, postElem) => {
444
- const $post = $(postElem);
445
- const postIdAttr = $post.attr("id");
446
- if (!postIdAttr)
447
- return;
448
- const postId = Number.parseInt(postIdAttr.replace("post-", ""), 10);
449
- if (Number.isNaN(postId))
450
- return;
451
- let parentId = null;
452
- const $parentContainer = $post.parent();
453
- if ($parentContainer.length > 0) {
454
- const $grandparent = $parentContainer.parent();
455
- if ($grandparent.length > 0 && $grandparent[0]?.name !== "body") {
456
- const grandparentClasses = $grandparent.attr("class") ?? "";
457
- if (grandparentClasses.includes("post-container")) {
458
- const $parentPost = $grandparent.find("> div.post");
459
- if ($parentPost.length > 0) {
460
- const parentPostIdAttr = $parentPost.attr("id");
461
- if (parentPostIdAttr) {
462
- parentId = Number.parseInt(parentPostIdAttr.replace("post-", ""), 10);
463
- }
464
- }
465
- }
466
- }
467
- }
468
- const $wrapper = $post.find("div.long");
469
- if ($wrapper.length === 0)
470
- return;
471
- const $head = $wrapper.find("div.head");
472
- if ($head.length === 0)
473
- return;
474
- const $title = $head.find("div.title");
475
- const title = $title.text().trim();
476
- const $content = $wrapper.find("div.content");
477
- const text = $content.html() ?? "";
478
- const $info = $head.find("div.info");
479
- if ($info.length === 0)
480
- return;
481
- const $userElem = $info.find("span.printuser");
482
- if ($userElem.length === 0)
483
- return;
484
- const createdBy = parseUser(thread.site.client, $userElem);
485
- const $odateElem = $info.find("span.odate");
486
- if ($odateElem.length === 0)
487
- return;
488
- const createdAt = parseOdate($odateElem) ?? new Date;
489
- let editedBy = null;
490
- let editedAt = null;
491
- const $changes = $wrapper.find("div.changes");
492
- if ($changes.length > 0) {
493
- const $editUserElem = $changes.find("span.printuser");
494
- const $editOdateElem = $changes.find("span.odate");
495
- if ($editUserElem.length > 0 && $editOdateElem.length > 0) {
496
- editedBy = parseUser(thread.site.client, $editUserElem);
497
- editedAt = parseOdate($editOdateElem);
498
- }
499
- }
500
- posts.push(new ForumPost({
501
- thread,
502
- id: postId,
503
- title,
504
- text,
505
- element: postElem,
506
- createdBy,
507
- createdAt,
508
- editedBy,
509
- editedAt,
510
- parentId
511
- }));
512
- });
513
- return posts;
514
- }
515
- static acquireAllInThread(thread) {
516
- return fromPromise((async () => {
517
- const posts = [];
518
- const firstResult = await thread.site.amcRequest([
519
- {
520
- moduleName: "forum/ForumViewThreadPostsModule",
521
- pageNo: "1",
522
- t: String(thread.id)
523
- }
524
- ]);
525
- if (firstResult.isErr()) {
526
- throw firstResult.error;
527
- }
528
- const firstResponse = firstResult.value[0];
529
- if (!firstResponse) {
530
- throw new NoElementError("Empty response");
531
- }
532
- const firstBody = String(firstResponse.body ?? "");
533
- const $first = cheerio.load(firstBody);
534
- posts.push(...ForumPostCollection._parse(thread, $first));
535
- const $pager = $first("div.pager");
536
- if ($pager.length === 0) {
537
- return new ForumPostCollection(thread, posts);
538
- }
539
- const $pagerTargets = $pager.find("span.target");
540
- if ($pagerTargets.length < 2) {
541
- return new ForumPostCollection(thread, posts);
542
- }
543
- const lastPageText = $pagerTargets.eq($pagerTargets.length - 2).text().trim();
544
- const lastPage = Number.parseInt(lastPageText, 10);
545
- if (Number.isNaN(lastPage) || lastPage <= 1) {
546
- return new ForumPostCollection(thread, posts);
547
- }
548
- const bodies = [];
549
- for (let page = 2;page <= lastPage; page++) {
550
- bodies.push({
551
- moduleName: "forum/ForumViewThreadPostsModule",
552
- pageNo: String(page),
553
- t: String(thread.id)
554
- });
555
- }
556
- const additionalResults = await thread.site.amcRequest(bodies);
557
- if (additionalResults.isErr()) {
558
- throw additionalResults.error;
559
- }
560
- for (const response of additionalResults.value) {
561
- const body = String(response?.body ?? "");
562
- const $ = cheerio.load(body);
563
- posts.push(...ForumPostCollection._parse(thread, $));
564
- }
565
- return new ForumPostCollection(thread, posts);
566
- })(), (error) => {
567
- if (error instanceof NoElementError)
568
- return error;
569
- return new UnexpectedError(`Failed to acquire posts: ${String(error)}`);
570
- });
571
- }
572
- }
573
-
574
- // src/module/forum/forum-thread.ts
575
- class ForumThread {
576
- site;
577
- id;
578
- title;
579
- description;
580
- createdBy;
581
- createdAt;
582
- postCount;
583
- category;
584
- _posts = null;
585
- constructor(data) {
586
- this.site = data.site;
587
- this.id = data.id;
588
- this.title = data.title;
589
- this.description = data.description;
590
- this.createdBy = data.createdBy;
591
- this.createdAt = data.createdAt;
592
- this.postCount = data.postCount;
593
- this.category = data.category ?? null;
594
- }
595
- getUrl() {
596
- return `${this.site.getBaseUrl()}/forum/t-${this.id}/`;
597
- }
598
- getPosts() {
599
- if (this._posts !== null) {
600
- return fromPromise(Promise.resolve(this._posts), (e) => new UnexpectedError(String(e)));
601
- }
602
- return ForumPostCollection.acquireAllInThread(this);
603
- }
604
- reply(source, title = "", parentPostId = null) {
605
- return fromPromise((async () => {
606
- const result = await this.site.amcRequest([
607
- {
608
- threadId: String(this.id),
609
- parentId: parentPostId !== null ? String(parentPostId) : "",
610
- title,
611
- source,
612
- action: "ForumAction",
613
- event: "savePost",
614
- moduleName: "Empty"
615
- }
616
- ]);
617
- if (result.isErr()) {
618
- throw result.error;
619
- }
620
- this._posts = null;
621
- this.postCount += 1;
622
- return this;
623
- })(), (error) => new UnexpectedError(`Failed to reply: ${String(error)}`));
624
- }
625
- toString() {
626
- return `ForumThread(id=${this.id}, title=${this.title})`;
627
- }
628
- static getFromId(site, threadId, category = null) {
629
- return fromPromise((async () => {
630
- const result = await ForumThreadCollection.acquireFromThreadIds(site, [threadId], category);
631
- if (result.isErr()) {
632
- throw result.error;
633
- }
634
- const thread = result.value[0];
635
- if (!thread) {
636
- throw new NoElementError(`Thread not found: ${threadId}`);
637
- }
638
- return thread;
639
- })(), (error) => {
640
- if (error instanceof NoElementError)
641
- return error;
642
- return new UnexpectedError(`Failed to get thread: ${String(error)}`);
643
- });
644
- }
645
- }
646
- __legacyDecorateClassTS([
647
- RequireLogin
648
- ], ForumThread.prototype, "reply", null);
649
-
650
- class ForumThreadCollection extends Array {
651
- site;
652
- constructor(site, threads) {
653
- super();
654
- this.site = site;
655
- if (threads) {
656
- this.push(...threads);
657
- }
658
- }
659
- findById(id) {
660
- return this.find((thread) => thread.id === id);
661
- }
662
- static acquireAllInCategory(category) {
663
- return fromPromise((async () => {
664
- const threads = [];
665
- const firstResult = await category.site.amcRequest([
666
- {
667
- p: 1,
668
- c: category.id,
669
- moduleName: "forum/ForumViewCategoryModule"
670
- }
671
- ]);
672
- if (firstResult.isErr()) {
673
- throw firstResult.error;
674
- }
675
- const firstResponse = firstResult.value[0];
676
- if (!firstResponse) {
677
- throw new NoElementError("Empty response");
678
- }
679
- const firstBody = String(firstResponse.body ?? "");
680
- const $first = cheerio2.load(firstBody);
681
- $first("table.table tr.head~tr").each((_i, elem) => {
682
- const $row = $first(elem);
683
- const titleElem = $row.find("div.title a");
684
- const href = titleElem.attr("href") ?? "";
685
- const threadIdMatch = href.match(/t-(\d+)/);
686
- if (!threadIdMatch?.[1])
687
- return;
688
- const threadId = Number.parseInt(threadIdMatch[1], 10);
689
- const title = titleElem.text().trim();
690
- const description = $row.find("div.description").text().trim();
691
- const postCount = Number.parseInt($row.find("td.posts").text().trim(), 10) || 0;
692
- const $userElem = $row.find("td.started span.printuser");
693
- const $odateElem = $row.find("td.started span.odate");
694
- const createdBy = $userElem.length > 0 ? parseUser(category.site.client, $userElem) : null;
695
- const createdAt = $odateElem.length > 0 ? parseOdate($odateElem) ?? new Date : new Date;
696
- threads.push(new ForumThread({
697
- site: category.site,
698
- id: threadId,
699
- title,
700
- description,
701
- createdBy,
702
- createdAt,
703
- postCount,
704
- category
705
- }));
706
- });
707
- const pager = $first("div.pager");
708
- if (pager.length === 0) {
709
- return new ForumThreadCollection(category.site, threads);
710
- }
711
- const pagerLinks = pager.find("a");
712
- if (pagerLinks.length < 2) {
713
- return new ForumThreadCollection(category.site, threads);
714
- }
715
- const lastPageLink = pagerLinks[pagerLinks.length - 2];
716
- const lastPageText = lastPageLink ? $first(lastPageLink).text().trim() : "1";
717
- const lastPage = Number.parseInt(lastPageText, 10) || 1;
718
- if (lastPage <= 1) {
719
- return new ForumThreadCollection(category.site, threads);
720
- }
721
- const bodies = [];
722
- for (let page = 2;page <= lastPage; page++) {
723
- bodies.push({
724
- p: page,
725
- c: category.id,
726
- moduleName: "forum/ForumViewCategoryModule"
727
- });
728
- }
729
- const additionalResults = await category.site.amcRequest(bodies);
730
- if (additionalResults.isErr()) {
731
- throw additionalResults.error;
732
- }
733
- for (const response of additionalResults.value) {
734
- const body = String(response?.body ?? "");
735
- const $ = cheerio2.load(body);
736
- $("table.table tr.head~tr").each((_i, elem) => {
737
- const $row = $(elem);
738
- const titleElem = $row.find("div.title a");
739
- const href = titleElem.attr("href") ?? "";
740
- const threadIdMatch = href.match(/t-(\d+)/);
741
- if (!threadIdMatch?.[1])
742
- return;
743
- const threadId = Number.parseInt(threadIdMatch[1], 10);
744
- const title = titleElem.text().trim();
745
- const description = $row.find("div.description").text().trim();
746
- const postCount = Number.parseInt($row.find("td.posts").text().trim(), 10) || 0;
747
- const $userElem = $row.find("td.started span.printuser");
748
- const $odateElem = $row.find("td.started span.odate");
749
- const createdBy = $userElem.length > 0 ? parseUser(category.site.client, $userElem) : null;
750
- const createdAt = $odateElem.length > 0 ? parseOdate($odateElem) ?? new Date : new Date;
751
- threads.push(new ForumThread({
752
- site: category.site,
753
- id: threadId,
754
- title,
755
- description,
756
- createdBy,
757
- createdAt,
758
- postCount,
759
- category
760
- }));
761
- });
762
- }
763
- return new ForumThreadCollection(category.site, threads);
764
- })(), (error) => {
765
- if (error instanceof NoElementError)
766
- return error;
767
- return new UnexpectedError(`Failed to acquire threads: ${String(error)}`);
768
- });
769
- }
770
- static fromId(site, threadId) {
771
- return fromPromise((async () => {
772
- const result = await ForumThreadCollection.acquireFromThreadIds(site, [threadId]);
773
- if (result.isErr()) {
774
- throw result.error;
775
- }
776
- const thread = result.value[0];
777
- if (!thread) {
778
- throw new NoElementError(`Thread not found: ${threadId}`);
779
- }
780
- return thread;
781
- })(), (error) => {
782
- if (error instanceof NoElementError)
783
- return error;
784
- return new UnexpectedError(`Failed to get thread: ${String(error)}`);
785
- });
786
- }
787
- static acquireFromThreadIds(site, threadIds, category = null) {
788
- return fromPromise((async () => {
789
- const result = await site.amcRequest(threadIds.map((threadId) => ({
790
- t: threadId,
791
- moduleName: "forum/ForumViewThreadModule"
792
- })));
793
- if (result.isErr()) {
794
- throw result.error;
795
- }
796
- const threads = [];
797
- for (let i = 0;i < threadIds.length; i++) {
798
- const response = result.value[i];
799
- const threadId = threadIds[i];
800
- if (!response || !threadId)
801
- continue;
802
- const body = String(response.body ?? "");
803
- const $ = cheerio2.load(body);
804
- const bcElem = $("div.forum-breadcrumbs");
805
- if (bcElem.length === 0) {
806
- throw new NoElementError("Breadcrumbs not found");
807
- }
808
- const bcParts = bcElem.text().split("»");
809
- const title = bcParts.length > 0 ? bcParts[bcParts.length - 1]?.trim() ?? "" : "";
810
- const descBlockElem = $("div.description-block");
811
- const description = descBlockElem.text().trim();
812
- const postCountMatch = $("div.statistics").text().match(/(\d+)/);
813
- const postCount = postCountMatch?.[1] ? Number.parseInt(postCountMatch[1], 10) : 0;
814
- threads.push(new ForumThread({
815
- site,
816
- id: threadId,
817
- title,
818
- description,
819
- createdBy: null,
820
- createdAt: new Date,
821
- postCount,
822
- category
823
- }));
824
- }
825
- return new ForumThreadCollection(site, threads);
826
- })(), (error) => {
827
- if (error instanceof NoElementError)
828
- return error;
829
- return new UnexpectedError(`Failed to acquire threads: ${String(error)}`);
830
- });
831
- }
832
- }
833
-
834
- // src/module/forum/forum-category.ts
835
- class ForumCategory {
836
- site;
837
- id;
838
- title;
839
- description;
840
- threadsCount;
841
- postsCount;
842
- _threads = null;
843
- constructor(data) {
844
- this.site = data.site;
845
- this.id = data.id;
846
- this.title = data.title;
847
- this.description = data.description;
848
- this.threadsCount = data.threadsCount;
849
- this.postsCount = data.postsCount;
850
- }
851
- getThreads() {
852
- if (this._threads !== null) {
853
- return fromPromise(Promise.resolve(this._threads), (e) => new UnexpectedError(String(e)));
854
- }
855
- return fromPromise((async () => {
856
- const result = await ForumThreadCollection.acquireAllInCategory(this);
857
- if (result.isErr()) {
858
- throw result.error;
859
- }
860
- this._threads = result.value;
861
- return this._threads;
862
- })(), (error) => new UnexpectedError(`Failed to get threads: ${String(error)}`));
863
- }
864
- reloadThreads() {
865
- this._threads = null;
866
- return this.getThreads();
867
- }
868
- createThread(title, description, source) {
869
- return fromPromise((async () => {
870
- const result = await this.site.amcRequest([
871
- {
872
- moduleName: "Empty",
873
- action: "ForumAction",
874
- event: "newThread",
875
- category_id: this.id,
876
- title,
877
- description,
878
- source
879
- }
880
- ]);
881
- if (result.isErr()) {
882
- throw result.error;
883
- }
884
- const response = result.value[0];
885
- if (!response || typeof response.threadId !== "number") {
886
- throw new NoElementError("Thread ID not found in response");
887
- }
888
- const threadId = response.threadId;
889
- const threadResult = await ForumThread.getFromId(this.site, threadId, this);
890
- if (threadResult.isErr()) {
891
- throw threadResult.error;
892
- }
893
- return threadResult.value;
894
- })(), (error) => {
895
- if (error instanceof NoElementError || error instanceof LoginRequiredError) {
896
- return error;
897
- }
898
- return new UnexpectedError(`Failed to create thread: ${String(error)}`);
899
- });
900
- }
901
- toString() {
902
- return `ForumCategory(id=${this.id}, title=${this.title})`;
903
- }
904
- }
905
- __legacyDecorateClassTS([
906
- RequireLogin
907
- ], ForumCategory.prototype, "createThread", null);
908
-
909
- class ForumCategoryCollection extends Array {
910
- site;
911
- constructor(site, categories) {
912
- super();
913
- this.site = site;
914
- if (categories) {
915
- this.push(...categories);
916
- }
917
- }
918
- findById(id) {
919
- return this.find((category) => category.id === id);
920
- }
921
- static acquireAll(site) {
922
- return fromPromise((async () => {
923
- const result = await site.amcRequest([
924
- {
925
- moduleName: "forum/ForumStartModule",
926
- hidden: "true"
927
- }
928
- ]);
929
- if (result.isErr()) {
930
- throw result.error;
931
- }
932
- const response = result.value[0];
933
- if (!response) {
934
- throw new NoElementError("Empty response");
935
- }
936
- const body = String(response.body ?? "");
937
- const $ = cheerio3.load(body);
938
- const categories = [];
939
- $("table tr.head~tr").each((_i, row) => {
940
- const $row = $(row);
941
- const nameElem = $row.find("td.name");
942
- const nameLinkElem = nameElem.find("a");
943
- const href = nameLinkElem.attr("href") ?? "";
944
- const categoryIdMatch = href.match(/c-(\d+)/);
945
- if (!categoryIdMatch?.[1])
946
- return;
947
- const categoryId = Number.parseInt(categoryIdMatch[1], 10);
948
- const title = nameLinkElem.text().trim();
949
- const description = nameElem.find("div.description").text().trim();
950
- const threadsCount = Number.parseInt($row.find("td.threads").text().trim(), 10) || 0;
951
- const postsCount = Number.parseInt($row.find("td.posts").text().trim(), 10) || 0;
952
- categories.push(new ForumCategory({
953
- site,
954
- id: categoryId,
955
- title,
956
- description,
957
- threadsCount,
958
- postsCount
959
- }));
960
- });
961
- return new ForumCategoryCollection(site, categories);
962
- })(), (error) => {
963
- if (error instanceof NoElementError)
964
- return error;
965
- return new UnexpectedError(`Failed to acquire categories: ${String(error)}`);
966
- });
967
- }
968
- }
969
- export {
970
- ForumThreadCollection,
971
- ForumThread,
972
- ForumPostCollection,
973
- ForumPost,
974
- ForumCategoryCollection,
975
- ForumCategory
976
- };
977
- export { nullHandler, consoleHandler, Logger, getLogger, setupConsoleHandler, logger, AnonymousUser, DeletedUser, GuestUser, WikidotUser, parseUser, parseOdate, RequireLogin, ForumPost, ForumPostCollection, ForumThread, ForumThreadCollection, ForumCategory, ForumCategoryCollection };
978
-
979
- //# debugId=B1748EA576F96A3164756E2164756E21
980
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL21vZHVsZS9mb3J1bS9mb3J1bS1jYXRlZ29yeS50cyIsICJzcmMvY29tbW9uL2RlY29yYXRvcnMudHMiLCAic3JjL21vZHVsZS9mb3J1bS9mb3J1bS10aHJlYWQudHMiLCAic3JjL2NvbW1vbi9sb2dnZXIudHMiLCAic3JjL21vZHVsZS91c2VyL2Fub255bW91cy11c2VyLnRzIiwgInNyYy9tb2R1bGUvdXNlci9kZWxldGVkLXVzZXIudHMiLCAic3JjL21vZHVsZS91c2VyL2d1ZXN0LXVzZXIudHMiLCAic3JjL21vZHVsZS91c2VyL3dpa2lkb3QtdXNlci50cyIsICJzcmMvdXRpbC9wYXJzZXIvdXNlci50cyIsICJzcmMvbW9kdWxlL2ZvcnVtL2ZvcnVtLXBvc3QudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbCiAgICAiaW1wb3J0ICogYXMgY2hlZXJpbyBmcm9tICdjaGVlcmlvJztcbmltcG9ydCB7IFJlcXVpcmVMb2dpbiB9IGZyb20gJy4uLy4uL2NvbW1vbi9kZWNvcmF0b3JzJztcbmltcG9ydCB7IExvZ2luUmVxdWlyZWRFcnJvciwgTm9FbGVtZW50RXJyb3IsIFVuZXhwZWN0ZWRFcnJvciB9IGZyb20gJy4uLy4uL2NvbW1vbi9lcnJvcnMnO1xuaW1wb3J0IHsgZnJvbVByb21pc2UsIHR5cGUgV2lraWRvdFJlc3VsdEFzeW5jIH0gZnJvbSAnLi4vLi4vY29tbW9uL3R5cGVzJztcbmltcG9ydCB0eXBlIHsgU2l0ZSB9IGZyb20gJy4uL3NpdGUnO1xuaW1wb3J0IHsgRm9ydW1UaHJlYWQsIEZvcnVtVGhyZWFkQ29sbGVjdGlvbiB9IGZyb20gJy4vZm9ydW0tdGhyZWFkJztcblxuLyoqXG4gKiDjg5Xjgqnjg7zjg6njg6Djgqvjg4bjgrTjg6rjg4fjg7zjgr9cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBGb3J1bUNhdGVnb3J5RGF0YSB7XG4gIHNpdGU6IFNpdGU7XG4gIGlkOiBudW1iZXI7XG4gIHRpdGxlOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIHRocmVhZHNDb3VudDogbnVtYmVyO1xuICBwb3N0c0NvdW50OiBudW1iZXI7XG59XG5cbi8qKlxuICog44OV44Kp44O844Op44Og44Kr44OG44K044OqXG4gKi9cbmV4cG9ydCBjbGFzcyBGb3J1bUNhdGVnb3J5IHtcbiAgcHVibGljIHJlYWRvbmx5IHNpdGU6IFNpdGU7XG4gIHB1YmxpYyByZWFkb25seSBpZDogbnVtYmVyO1xuICBwdWJsaWMgcmVhZG9ubHkgdGl0bGU6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSB0aHJlYWRzQ291bnQ6IG51bWJlcjtcbiAgcHVibGljIHJlYWRvbmx5IHBvc3RzQ291bnQ6IG51bWJlcjtcbiAgcHJpdmF0ZSBfdGhyZWFkczogRm9ydW1UaHJlYWRDb2xsZWN0aW9uIHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IoZGF0YTogRm9ydW1DYXRlZ29yeURhdGEpIHtcbiAgICB0aGlzLnNpdGUgPSBkYXRhLnNpdGU7XG4gICAgdGhpcy5pZCA9IGRhdGEuaWQ7XG4gICAgdGhpcy50aXRsZSA9IGRhdGEudGl0bGU7XG4gICAgdGhpcy5kZXNjcmlwdGlvbiA9IGRhdGEuZGVzY3JpcHRpb247XG4gICAgdGhpcy50aHJlYWRzQ291bnQgPSBkYXRhLnRocmVhZHNDb3VudDtcbiAgICB0aGlzLnBvc3RzQ291bnQgPSBkYXRhLnBvc3RzQ291bnQ7XG4gIH1cblxuICAvKipcbiAgICog44K544Os44OD44OJ5LiA6Kan44KS5Y+W5b6XXG4gICAqL1xuICBnZXRUaHJlYWRzKCk6IFdpa2lkb3RSZXN1bHRBc3luYzxGb3J1bVRocmVhZENvbGxlY3Rpb24+IHtcbiAgICBpZiAodGhpcy5fdGhyZWFkcyAhPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIGZyb21Qcm9taXNlKFByb21pc2UucmVzb2x2ZSh0aGlzLl90aHJlYWRzKSwgKGUpID0+IG5ldyBVbmV4cGVjdGVkRXJyb3IoU3RyaW5nKGUpKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgRm9ydW1UaHJlYWRDb2xsZWN0aW9uLmFjcXVpcmVBbGxJbkNhdGVnb3J5KHRoaXMpO1xuICAgICAgICBpZiAocmVzdWx0LmlzRXJyKCkpIHtcbiAgICAgICAgICB0aHJvdyByZXN1bHQuZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fdGhyZWFkcyA9IHJlc3VsdC52YWx1ZTtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3RocmVhZHM7XG4gICAgICB9KSgpLFxuICAgICAgKGVycm9yKSA9PiBuZXcgVW5leHBlY3RlZEVycm9yKGBGYWlsZWQgdG8gZ2V0IHRocmVhZHM6ICR7U3RyaW5nKGVycm9yKX1gKVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICog44K544Os44OD44OJ5LiA6Kan44KS5YaN5Y+W5b6XXG4gICAqL1xuICByZWxvYWRUaHJlYWRzKCk6IFdpa2lkb3RSZXN1bHRBc3luYzxGb3J1bVRocmVhZENvbGxlY3Rpb24+IHtcbiAgICB0aGlzLl90aHJlYWRzID0gbnVsbDtcbiAgICByZXR1cm4gdGhpcy5nZXRUaHJlYWRzKCk7XG4gIH1cblxuICAvKipcbiAgICog44K544Os44OD44OJ44KS5L2c5oiQXG4gICAqL1xuICBAUmVxdWlyZUxvZ2luXG4gIGNyZWF0ZVRocmVhZChcbiAgICB0aXRsZTogc3RyaW5nLFxuICAgIGRlc2NyaXB0aW9uOiBzdHJpbmcsXG4gICAgc291cmNlOiBzdHJpbmdcbiAgKTogV2lraWRvdFJlc3VsdEFzeW5jPEZvcnVtVGhyZWFkPiB7XG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5zaXRlLmFtY1JlcXVlc3QoW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG1vZHVsZU5hbWU6ICdFbXB0eScsXG4gICAgICAgICAgICBhY3Rpb246ICdGb3J1bUFjdGlvbicsXG4gICAgICAgICAgICBldmVudDogJ25ld1RocmVhZCcsXG4gICAgICAgICAgICBjYXRlZ29yeV9pZDogdGhpcy5pZCxcbiAgICAgICAgICAgIHRpdGxlLFxuICAgICAgICAgICAgZGVzY3JpcHRpb24sXG4gICAgICAgICAgICBzb3VyY2UsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG5cbiAgICAgICAgaWYgKHJlc3VsdC5pc0VycigpKSB7XG4gICAgICAgICAgdGhyb3cgcmVzdWx0LmVycm9yO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSByZXN1bHQudmFsdWVbMF07XG4gICAgICAgIGlmICghcmVzcG9uc2UgfHwgdHlwZW9mIHJlc3BvbnNlLnRocmVhZElkICE9PSAnbnVtYmVyJykge1xuICAgICAgICAgIHRocm93IG5ldyBOb0VsZW1lbnRFcnJvcignVGhyZWFkIElEIG5vdCBmb3VuZCBpbiByZXNwb25zZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdGhyZWFkSWQgPSByZXNwb25zZS50aHJlYWRJZCBhcyBudW1iZXI7XG4gICAgICAgIGNvbnN0IHRocmVhZFJlc3VsdCA9IGF3YWl0IEZvcnVtVGhyZWFkLmdldEZyb21JZCh0aGlzLnNpdGUsIHRocmVhZElkLCB0aGlzKTtcbiAgICAgICAgaWYgKHRocmVhZFJlc3VsdC5pc0VycigpKSB7XG4gICAgICAgICAgdGhyb3cgdGhyZWFkUmVzdWx0LmVycm9yO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aHJlYWRSZXN1bHQudmFsdWU7XG4gICAgICB9KSgpLFxuICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIE5vRWxlbWVudEVycm9yIHx8IGVycm9yIGluc3RhbmNlb2YgTG9naW5SZXF1aXJlZEVycm9yKSB7XG4gICAgICAgICAgcmV0dXJuIGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgVW5leHBlY3RlZEVycm9yKGBGYWlsZWQgdG8gY3JlYXRlIHRocmVhZDogJHtTdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIHJldHVybiBgRm9ydW1DYXRlZ29yeShpZD0ke3RoaXMuaWR9LCB0aXRsZT0ke3RoaXMudGl0bGV9KWA7XG4gIH1cbn1cblxuLyoqXG4gKiDjg5Xjgqnjg7zjg6njg6Djgqvjg4bjgrTjg6rjgrPjg6zjgq/jgrfjg6fjg7NcbiAqL1xuZXhwb3J0IGNsYXNzIEZvcnVtQ2F0ZWdvcnlDb2xsZWN0aW9uIGV4dGVuZHMgQXJyYXk8Rm9ydW1DYXRlZ29yeT4ge1xuICBwdWJsaWMgcmVhZG9ubHkgc2l0ZTogU2l0ZTtcblxuICBjb25zdHJ1Y3RvcihzaXRlOiBTaXRlLCBjYXRlZ29yaWVzPzogRm9ydW1DYXRlZ29yeVtdKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLnNpdGUgPSBzaXRlO1xuICAgIGlmIChjYXRlZ29yaWVzKSB7XG4gICAgICB0aGlzLnB1c2goLi4uY2F0ZWdvcmllcyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIElE44Gn5qSc57SiXG4gICAqL1xuICBmaW5kQnlJZChpZDogbnVtYmVyKTogRm9ydW1DYXRlZ29yeSB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuZmluZCgoY2F0ZWdvcnkpID0+IGNhdGVnb3J5LmlkID09PSBpZCk7XG4gIH1cblxuICAvKipcbiAgICog44K144Kk44OI44Gu5YWo44Kr44OG44K044Oq44KS5Y+W5b6XXG4gICAqL1xuICBzdGF0aWMgYWNxdWlyZUFsbChzaXRlOiBTaXRlKTogV2lraWRvdFJlc3VsdEFzeW5jPEZvcnVtQ2F0ZWdvcnlDb2xsZWN0aW9uPiB7XG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgc2l0ZS5hbWNSZXF1ZXN0KFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBtb2R1bGVOYW1lOiAnZm9ydW0vRm9ydW1TdGFydE1vZHVsZScsXG4gICAgICAgICAgICBoaWRkZW46ICd0cnVlJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdKTtcblxuICAgICAgICBpZiAocmVzdWx0LmlzRXJyKCkpIHtcbiAgICAgICAgICB0aHJvdyByZXN1bHQuZXJyb3I7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXNwb25zZSA9IHJlc3VsdC52YWx1ZVswXTtcbiAgICAgICAgaWYgKCFyZXNwb25zZSkge1xuICAgICAgICAgIHRocm93IG5ldyBOb0VsZW1lbnRFcnJvcignRW1wdHkgcmVzcG9uc2UnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGJvZHkgPSBTdHJpbmcocmVzcG9uc2UuYm9keSA/PyAnJyk7XG4gICAgICAgIGNvbnN0ICQgPSBjaGVlcmlvLmxvYWQoYm9keSk7XG5cbiAgICAgICAgY29uc3QgY2F0ZWdvcmllczogRm9ydW1DYXRlZ29yeVtdID0gW107XG5cbiAgICAgICAgJCgndGFibGUgdHIuaGVhZH50cicpLmVhY2goKF9pLCByb3cpID0+IHtcbiAgICAgICAgICBjb25zdCAkcm93ID0gJChyb3cpO1xuICAgICAgICAgIGNvbnN0IG5hbWVFbGVtID0gJHJvdy5maW5kKCd0ZC5uYW1lJyk7XG4gICAgICAgICAgY29uc3QgbmFtZUxpbmtFbGVtID0gbmFtZUVsZW0uZmluZCgnYScpO1xuICAgICAgICAgIGNvbnN0IGhyZWYgPSBuYW1lTGlua0VsZW0uYXR0cignaHJlZicpID8/ICcnO1xuXG4gICAgICAgICAgY29uc3QgY2F0ZWdvcnlJZE1hdGNoID0gaHJlZi5tYXRjaCgvYy0oXFxkKykvKTtcbiAgICAgICAgICBpZiAoIWNhdGVnb3J5SWRNYXRjaD8uWzFdKSByZXR1cm47XG5cbiAgICAgICAgICBjb25zdCBjYXRlZ29yeUlkID0gTnVtYmVyLnBhcnNlSW50KGNhdGVnb3J5SWRNYXRjaFsxXSwgMTApO1xuICAgICAgICAgIGNvbnN0IHRpdGxlID0gbmFtZUxpbmtFbGVtLnRleHQoKS50cmltKCk7XG4gICAgICAgICAgY29uc3QgZGVzY3JpcHRpb24gPSBuYW1lRWxlbS5maW5kKCdkaXYuZGVzY3JpcHRpb24nKS50ZXh0KCkudHJpbSgpO1xuICAgICAgICAgIGNvbnN0IHRocmVhZHNDb3VudCA9IE51bWJlci5wYXJzZUludCgkcm93LmZpbmQoJ3RkLnRocmVhZHMnKS50ZXh0KCkudHJpbSgpLCAxMCkgfHwgMDtcbiAgICAgICAgICBjb25zdCBwb3N0c0NvdW50ID0gTnVtYmVyLnBhcnNlSW50KCRyb3cuZmluZCgndGQucG9zdHMnKS50ZXh0KCkudHJpbSgpLCAxMCkgfHwgMDtcblxuICAgICAgICAgIGNhdGVnb3JpZXMucHVzaChcbiAgICAgICAgICAgIG5ldyBGb3J1bUNhdGVnb3J5KHtcbiAgICAgICAgICAgICAgc2l0ZSxcbiAgICAgICAgICAgICAgaWQ6IGNhdGVnb3J5SWQsXG4gICAgICAgICAgICAgIHRpdGxlLFxuICAgICAgICAgICAgICBkZXNjcmlwdGlvbixcbiAgICAgICAgICAgICAgdGhyZWFkc0NvdW50LFxuICAgICAgICAgICAgICBwb3N0c0NvdW50LFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICApO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gbmV3IEZvcnVtQ2F0ZWdvcnlDb2xsZWN0aW9uKHNpdGUsIGNhdGVnb3JpZXMpO1xuICAgICAgfSkoKSxcbiAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBOb0VsZW1lbnRFcnJvcikgcmV0dXJuIGVycm9yO1xuICAgICAgICByZXR1cm4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgRmFpbGVkIHRvIGFjcXVpcmUgY2F0ZWdvcmllczogJHtTdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfVxuICAgICk7XG4gIH1cbn1cbiIsCiAgICAiLyoqXG4gKiDjg4fjgrPjg6zjg7zjgr/jg6bjg7zjg4bjgqPjg6rjg4bjgqNcbiAqL1xuXG5pbXBvcnQgeyBMb2dpblJlcXVpcmVkRXJyb3IgfSBmcm9tICcuL2Vycm9ycyc7XG5pbXBvcnQgeyBmcm9tUHJvbWlzZSwgdHlwZSBXaWtpZG90UmVzdWx0QXN5bmMsIHdkRXJyQXN5bmMgfSBmcm9tICcuL3R5cGVzJztcblxuLyoqXG4gKiDjgq/jg6njgqTjgqLjg7Pjg4jlj4LnhafjgpLmjIHjgaTjgqrjg5bjgrjjgqfjgq/jg4jjga7lnotcbiAqL1xuaW50ZXJmYWNlIEhhc0NsaWVudCB7XG4gIGNsaWVudD86IHsgcmVxdWlyZUxvZ2luKCk6IHsgaXNFcnIoKTogYm9vbGVhbjsgZXJyb3I/OiBFcnJvciB9IH07XG4gIHNpdGU/OiB7IGNsaWVudDogeyByZXF1aXJlTG9naW4oKTogeyBpc0VycigpOiBib29sZWFuOyBlcnJvcj86IEVycm9yIH0gfSB9O1xuICB0aHJlYWQ/OiB7IHNpdGU6IHsgY2xpZW50OiB7IHJlcXVpcmVMb2dpbigpOiB7IGlzRXJyKCk6IGJvb2xlYW47IGVycm9yPzogRXJyb3IgfSB9IH0gfTtcbn1cblxuLyoqXG4gKiDjgqrjg5bjgrjjgqfjgq/jg4jjgYvjgonjgq/jg6njgqTjgqLjg7Pjg4jlj4LnhafjgpLlj5blvpfjgZnjgotcbiAqL1xuZnVuY3Rpb24gZ2V0Q2xpZW50UmVmKFxuICBvYmo6IEhhc0NsaWVudFxuKTogeyByZXF1aXJlTG9naW4oKTogeyBpc0VycigpOiBib29sZWFuOyBlcnJvcj86IEVycm9yIH0gfSB8IG51bGwge1xuICBpZiAob2JqLmNsaWVudCkgcmV0dXJuIG9iai5jbGllbnQ7XG4gIGlmIChvYmouc2l0ZT8uY2xpZW50KSByZXR1cm4gb2JqLnNpdGUuY2xpZW50O1xuICBpZiAob2JqLnRocmVhZD8uc2l0ZT8uY2xpZW50KSByZXR1cm4gb2JqLnRocmVhZC5zaXRlLmNsaWVudDtcbiAgcmV0dXJuIG51bGw7XG59XG5cbi8qKlxuICog44Ot44Kw44Kk44Oz5b+F6aCI44Oh44K944OD44OJ44OH44Kz44Os44O844K/XG4gKlxuICog44GT44Gu44OH44Kz44Os44O844K/44KS6YGp55So44GX44Gf44Oh44K944OD44OJ44Gv44CB5a6f6KGM5YmN44Gr44Ot44Kw44Kk44Oz54q25oWL44KS44OB44Kn44OD44Kv44GZ44KL44CCXG4gKiDjg63jgrDjgqTjg7PjgZfjgabjgYTjgarjgYTloLTlkIjjga8gTG9naW5SZXF1aXJlZEVycm9yIOOCkui/lOOBmeOAglxuICpcbiAqIEBleGFtcGxlXG4gKiBjbGFzcyBQYWdlIHtcbiAqICAgQFJlcXVpcmVMb2dpblxuICogICBkZXN0cm95KCk6IFdpa2lkb3RSZXN1bHRBc3luYzx2b2lkPiB7XG4gKiAgICAgcmV0dXJuIGZyb21Qcm9taXNlKGFzeW5jICgpID0+IHsgLi4uIH0sIChlKSA9PiBuZXcgVW5leHBlY3RlZEVycm9yKC4uLikpO1xuICogICB9XG4gKiB9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBSZXF1aXJlTG9naW48XG4gIFRoaXMgZXh0ZW5kcyBIYXNDbGllbnQsXG4gIEFyZ3MgZXh0ZW5kcyB1bmtub3duW10sXG4gIFJldHVybiBleHRlbmRzIFdpa2lkb3RSZXN1bHRBc3luYzx1bmtub3duPixcbj4oXG4gIHRhcmdldDogKHRoaXM6IFRoaXMsIC4uLmFyZ3M6IEFyZ3MpID0+IFJldHVybixcbiAgX2NvbnRleHQ6IENsYXNzTWV0aG9kRGVjb3JhdG9yQ29udGV4dDxUaGlzLCAodGhpczogVGhpcywgLi4uYXJnczogQXJncykgPT4gUmV0dXJuPlxuKTogKHRoaXM6IFRoaXMsIC4uLmFyZ3M6IEFyZ3MpID0+IFJldHVybiB7XG4gIHJldHVybiBmdW5jdGlvbiAodGhpczogVGhpcywgLi4uYXJnczogQXJncyk6IFJldHVybiB7XG4gICAgY29uc3QgY2xpZW50UmVmID0gZ2V0Q2xpZW50UmVmKHRoaXMpO1xuICAgIGlmICghY2xpZW50UmVmKSB7XG4gICAgICByZXR1cm4gd2RFcnJBc3luYyhuZXcgTG9naW5SZXF1aXJlZEVycm9yKCdDbGllbnQgcmVmZXJlbmNlIG5vdCBmb3VuZCcpKSBhcyB1bmtub3duIGFzIFJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBsb2dpblJlc3VsdCA9IGNsaWVudFJlZi5yZXF1aXJlTG9naW4oKTtcbiAgICBpZiAobG9naW5SZXN1bHQuaXNFcnIoKSkge1xuICAgICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgICBQcm9taXNlLnJlamVjdChsb2dpblJlc3VsdC5lcnJvciksXG4gICAgICAgICgpID0+IG5ldyBMb2dpblJlcXVpcmVkRXJyb3IoJ0xvZ2luIHJlcXVpcmVkJylcbiAgICAgICkgYXMgdW5rbm93biBhcyBSZXR1cm47XG4gICAgfVxuXG4gICAgcmV0dXJuIHRhcmdldC5jYWxsKHRoaXMsIC4uLmFyZ3MpO1xuICB9O1xufVxuIiwKICAgICJpbXBvcnQgdHlwZSB7IENoZWVyaW8gfSBmcm9tICdjaGVlcmlvJztcbmltcG9ydCAqIGFzIGNoZWVyaW8gZnJvbSAnY2hlZXJpbyc7XG5pbXBvcnQgdHlwZSB7IEFueU5vZGUgfSBmcm9tICdkb21oYW5kbGVyJztcbmltcG9ydCB7IFJlcXVpcmVMb2dpbiB9IGZyb20gJy4uLy4uL2NvbW1vbi9kZWNvcmF0b3JzJztcbmltcG9ydCB7IE5vRWxlbWVudEVycm9yLCBVbmV4cGVjdGVkRXJyb3IgfSBmcm9tICcuLi8uLi9jb21tb24vZXJyb3JzJztcbmltcG9ydCB7IGZyb21Qcm9taXNlLCB0eXBlIFdpa2lkb3RSZXN1bHRBc3luYyB9IGZyb20gJy4uLy4uL2NvbW1vbi90eXBlcyc7XG5pbXBvcnQgeyBwYXJzZU9kYXRlLCBwYXJzZVVzZXIgfSBmcm9tICcuLi8uLi91dGlsL3BhcnNlcic7XG5pbXBvcnQgdHlwZSB7IFNpdGUgfSBmcm9tICcuLi9zaXRlJztcbmltcG9ydCB0eXBlIHsgQWJzdHJhY3RVc2VyIH0gZnJvbSAnLi4vdXNlcic7XG5pbXBvcnQgdHlwZSB7IEZvcnVtQ2F0ZWdvcnkgfSBmcm9tICcuL2ZvcnVtLWNhdGVnb3J5JztcbmltcG9ydCB7IEZvcnVtUG9zdENvbGxlY3Rpb24gfSBmcm9tICcuL2ZvcnVtLXBvc3QnO1xuXG4vKipcbiAqIOODleOCqeODvOODqeODoOOCueODrOODg+ODieODh+ODvOOCv1xuICovXG5leHBvcnQgaW50ZXJmYWNlIEZvcnVtVGhyZWFkRGF0YSB7XG4gIHNpdGU6IFNpdGU7XG4gIGlkOiBudW1iZXI7XG4gIHRpdGxlOiBzdHJpbmc7XG4gIGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIGNyZWF0ZWRCeTogQWJzdHJhY3RVc2VyIHwgbnVsbDtcbiAgY3JlYXRlZEF0OiBEYXRlO1xuICBwb3N0Q291bnQ6IG51bWJlcjtcbiAgY2F0ZWdvcnk/OiBGb3J1bUNhdGVnb3J5IHwgbnVsbDtcbn1cblxuLyoqXG4gKiDjg5Xjgqnjg7zjg6njg6Djgrnjg6zjg4Pjg4lcbiAqL1xuZXhwb3J0IGNsYXNzIEZvcnVtVGhyZWFkIHtcbiAgcHVibGljIHJlYWRvbmx5IHNpdGU6IFNpdGU7XG4gIHB1YmxpYyByZWFkb25seSBpZDogbnVtYmVyO1xuICBwdWJsaWMgcmVhZG9ubHkgdGl0bGU6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IGRlc2NyaXB0aW9uOiBzdHJpbmc7XG4gIHB1YmxpYyByZWFkb25seSBjcmVhdGVkQnk6IEFic3RyYWN0VXNlciB8IG51bGw7XG4gIHB1YmxpYyByZWFkb25seSBjcmVhdGVkQXQ6IERhdGU7XG4gIHB1YmxpYyBwb3N0Q291bnQ6IG51bWJlcjtcbiAgcHVibGljIHJlYWRvbmx5IGNhdGVnb3J5OiBGb3J1bUNhdGVnb3J5IHwgbnVsbDtcbiAgcHJpdmF0ZSBfcG9zdHM6IEZvcnVtUG9zdENvbGxlY3Rpb24gfCBudWxsID0gbnVsbDtcblxuICBjb25zdHJ1Y3RvcihkYXRhOiBGb3J1bVRocmVhZERhdGEpIHtcbiAgICB0aGlzLnNpdGUgPSBkYXRhLnNpdGU7XG4gICAgdGhpcy5pZCA9IGRhdGEuaWQ7XG4gICAgdGhpcy50aXRsZSA9IGRhdGEudGl0bGU7XG4gICAgdGhpcy5kZXNjcmlwdGlvbiA9IGRhdGEuZGVzY3JpcHRpb247XG4gICAgdGhpcy5jcmVhdGVkQnkgPSBkYXRhLmNyZWF0ZWRCeTtcbiAgICB0aGlzLmNyZWF0ZWRBdCA9IGRhdGEuY3JlYXRlZEF0O1xuICAgIHRoaXMucG9zdENvdW50ID0gZGF0YS5wb3N0Q291bnQ7XG4gICAgdGhpcy5jYXRlZ29yeSA9IGRhdGEuY2F0ZWdvcnkgPz8gbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiDjgrnjg6zjg4Pjg4lVUkxcbiAgICovXG4gIGdldFVybCgpOiBzdHJpbmcge1xuICAgIHJldHVybiBgJHt0aGlzLnNpdGUuZ2V0QmFzZVVybCgpfS9mb3J1bS90LSR7dGhpcy5pZH0vYDtcbiAgfVxuXG4gIC8qKlxuICAgKiDmipXnqL/kuIDopqfjgpLlj5blvpdcbiAgICovXG4gIGdldFBvc3RzKCk6IFdpa2lkb3RSZXN1bHRBc3luYzxGb3J1bVBvc3RDb2xsZWN0aW9uPiB7XG4gICAgaWYgKHRoaXMuX3Bvc3RzICE9PSBudWxsKSB7XG4gICAgICByZXR1cm4gZnJvbVByb21pc2UoUHJvbWlzZS5yZXNvbHZlKHRoaXMuX3Bvc3RzKSwgKGUpID0+IG5ldyBVbmV4cGVjdGVkRXJyb3IoU3RyaW5nKGUpKSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIEZvcnVtUG9zdENvbGxlY3Rpb24uYWNxdWlyZUFsbEluVGhyZWFkKHRoaXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIOOCueODrOODg+ODieOBq+i/lOS/oVxuICAgKi9cbiAgQFJlcXVpcmVMb2dpblxuICByZXBseShcbiAgICBzb3VyY2U6IHN0cmluZyxcbiAgICB0aXRsZSA9ICcnLFxuICAgIHBhcmVudFBvc3RJZDogbnVtYmVyIHwgbnVsbCA9IG51bGxcbiAgKTogV2lraWRvdFJlc3VsdEFzeW5jPEZvcnVtVGhyZWFkPiB7XG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgdGhpcy5zaXRlLmFtY1JlcXVlc3QoW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHRocmVhZElkOiBTdHJpbmcodGhpcy5pZCksXG4gICAgICAgICAgICBwYXJlbnRJZDogcGFyZW50UG9zdElkICE9PSBudWxsID8gU3RyaW5nKHBhcmVudFBvc3RJZCkgOiAnJyxcbiAgICAgICAgICAgIHRpdGxlLFxuICAgICAgICAgICAgc291cmNlLFxuICAgICAgICAgICAgYWN0aW9uOiAnRm9ydW1BY3Rpb24nLFxuICAgICAgICAgICAgZXZlbnQ6ICdzYXZlUG9zdCcsXG4gICAgICAgICAgICBtb2R1bGVOYW1lOiAnRW1wdHknLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0pO1xuICAgICAgICBpZiAocmVzdWx0LmlzRXJyKCkpIHtcbiAgICAgICAgICB0aHJvdyByZXN1bHQuZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fcG9zdHMgPSBudWxsO1xuICAgICAgICB0aGlzLnBvc3RDb3VudCArPSAxO1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgIH0pKCksXG4gICAgICAoZXJyb3IpID0+IG5ldyBVbmV4cGVjdGVkRXJyb3IoYEZhaWxlZCB0byByZXBseTogJHtTdHJpbmcoZXJyb3IpfWApXG4gICAgKTtcbiAgfVxuXG4gIHRvU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGBGb3J1bVRocmVhZChpZD0ke3RoaXMuaWR9LCB0aXRsZT0ke3RoaXMudGl0bGV9KWA7XG4gIH1cblxuICAvKipcbiAgICogSUTjgYvjgonjgrnjg6zjg4Pjg4njgpLlj5blvpdcbiAgICovXG4gIHN0YXRpYyBnZXRGcm9tSWQoXG4gICAgc2l0ZTogU2l0ZSxcbiAgICB0aHJlYWRJZDogbnVtYmVyLFxuICAgIGNhdGVnb3J5OiBGb3J1bUNhdGVnb3J5IHwgbnVsbCA9IG51bGxcbiAgKTogV2lraWRvdFJlc3VsdEFzeW5jPEZvcnVtVGhyZWFkPiB7XG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgRm9ydW1UaHJlYWRDb2xsZWN0aW9uLmFjcXVpcmVGcm9tVGhyZWFkSWRzKHNpdGUsIFt0aHJlYWRJZF0sIGNhdGVnb3J5KTtcbiAgICAgICAgaWYgKHJlc3VsdC5pc0VycigpKSB7XG4gICAgICAgICAgdGhyb3cgcmVzdWx0LmVycm9yO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHRocmVhZCA9IHJlc3VsdC52YWx1ZVswXTtcbiAgICAgICAgaWYgKCF0aHJlYWQpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgTm9FbGVtZW50RXJyb3IoYFRocmVhZCBub3QgZm91bmQ6ICR7dGhyZWFkSWR9YCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRocmVhZDtcbiAgICAgIH0pKCksXG4gICAgICAoZXJyb3IpID0+IHtcbiAgICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgTm9FbGVtZW50RXJyb3IpIHJldHVybiBlcnJvcjtcbiAgICAgICAgcmV0dXJuIG5ldyBVbmV4cGVjdGVkRXJyb3IoYEZhaWxlZCB0byBnZXQgdGhyZWFkOiAke1N0cmluZyhlcnJvcil9YCk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxufVxuXG4vKipcbiAqIOODleOCqeODvOODqeODoOOCueODrOODg+ODieOCs+ODrOOCr+OCt+ODp+ODs1xuICovXG5leHBvcnQgY2xhc3MgRm9ydW1UaHJlYWRDb2xsZWN0aW9uIGV4dGVuZHMgQXJyYXk8Rm9ydW1UaHJlYWQ+IHtcbiAgcHVibGljIHJlYWRvbmx5IHNpdGU6IFNpdGU7XG5cbiAgY29uc3RydWN0b3Ioc2l0ZTogU2l0ZSwgdGhyZWFkcz86IEZvcnVtVGhyZWFkW10pIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuc2l0ZSA9IHNpdGU7XG4gICAgaWYgKHRocmVhZHMpIHtcbiAgICAgIHRoaXMucHVzaCguLi50aHJlYWRzKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSUTjgafmpJzntKJcbiAgICovXG4gIGZpbmRCeUlkKGlkOiBudW1iZXIpOiBGb3J1bVRocmVhZCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuZmluZCgodGhyZWFkKSA9PiB0aHJlYWQuaWQgPT09IGlkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDjgqvjg4bjgrTjg6rlhoXjga7lhajjgrnjg6zjg4Pjg4njgpLlj5blvpdcbiAgICovXG4gIHN0YXRpYyBhY3F1aXJlQWxsSW5DYXRlZ29yeShjYXRlZ29yeTogRm9ydW1DYXRlZ29yeSk6IFdpa2lkb3RSZXN1bHRBc3luYzxGb3J1bVRocmVhZENvbGxlY3Rpb24+IHtcbiAgICByZXR1cm4gZnJvbVByb21pc2UoXG4gICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCB0aHJlYWRzOiBGb3J1bVRocmVhZFtdID0gW107XG5cbiAgICAgICAgY29uc3QgZmlyc3RSZXN1bHQgPSBhd2FpdCBjYXRlZ29yeS5zaXRlLmFtY1JlcXVlc3QoW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHA6IDEsXG4gICAgICAgICAgICBjOiBjYXRlZ29yeS5pZCxcbiAgICAgICAgICAgIG1vZHVsZU5hbWU6ICdmb3J1bS9Gb3J1bVZpZXdDYXRlZ29yeU1vZHVsZScsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG5cbiAgICAgICAgaWYgKGZpcnN0UmVzdWx0LmlzRXJyKCkpIHtcbiAgICAgICAgICB0aHJvdyBmaXJzdFJlc3VsdC5lcnJvcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGZpcnN0UmVzcG9uc2UgPSBmaXJzdFJlc3VsdC52YWx1ZVswXTtcbiAgICAgICAgaWYgKCFmaXJzdFJlc3BvbnNlKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IE5vRWxlbWVudEVycm9yKCdFbXB0eSByZXNwb25zZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZmlyc3RCb2R5ID0gU3RyaW5nKGZpcnN0UmVzcG9uc2UuYm9keSA/PyAnJyk7XG4gICAgICAgIGNvbnN0ICRmaXJzdCA9IGNoZWVyaW8ubG9hZChmaXJzdEJvZHkpO1xuXG4gICAgICAgICRmaXJzdCgndGFibGUudGFibGUgdHIuaGVhZH50cicpLmVhY2goKF9pLCBlbGVtKSA9PiB7XG4gICAgICAgICAgY29uc3QgJHJvdyA9ICRmaXJzdChlbGVtKTtcbiAgICAgICAgICBjb25zdCB0aXRsZUVsZW0gPSAkcm93LmZpbmQoJ2Rpdi50aXRsZSBhJyk7XG4gICAgICAgICAgY29uc3QgaHJlZiA9IHRpdGxlRWxlbS5hdHRyKCdocmVmJykgPz8gJyc7XG4gICAgICAgICAgY29uc3QgdGhyZWFkSWRNYXRjaCA9IGhyZWYubWF0Y2goL3QtKFxcZCspLyk7XG4gICAgICAgICAgaWYgKCF0aHJlYWRJZE1hdGNoPy5bMV0pIHJldHVybjtcblxuICAgICAgICAgIGNvbnN0IHRocmVhZElkID0gTnVtYmVyLnBhcnNlSW50KHRocmVhZElkTWF0Y2hbMV0sIDEwKTtcbiAgICAgICAgICBjb25zdCB0aXRsZSA9IHRpdGxlRWxlbS50ZXh0KCkudHJpbSgpO1xuICAgICAgICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gJHJvdy5maW5kKCdkaXYuZGVzY3JpcHRpb24nKS50ZXh0KCkudHJpbSgpO1xuICAgICAgICAgIGNvbnN0IHBvc3RDb3VudCA9IE51bWJlci5wYXJzZUludCgkcm93LmZpbmQoJ3RkLnBvc3RzJykudGV4dCgpLnRyaW0oKSwgMTApIHx8IDA7XG5cbiAgICAgICAgICAvLyDjg6bjg7zjgrbjg7zjgajml6XmmYLjga7jg5Hjg7zjgrlcbiAgICAgICAgICBjb25zdCAkdXNlckVsZW0gPSAkcm93LmZpbmQoJ3RkLnN0YXJ0ZWQgc3Bhbi5wcmludHVzZXInKTtcbiAgICAgICAgICBjb25zdCAkb2RhdGVFbGVtID0gJHJvdy5maW5kKCd0ZC5zdGFydGVkIHNwYW4ub2RhdGUnKTtcblxuICAgICAgICAgIGNvbnN0IGNyZWF0ZWRCeSA9XG4gICAgICAgICAgICAkdXNlckVsZW0ubGVuZ3RoID4gMFxuICAgICAgICAgICAgICA/IHBhcnNlVXNlcihjYXRlZ29yeS5zaXRlLmNsaWVudCwgJHVzZXJFbGVtIGFzIENoZWVyaW88QW55Tm9kZT4pXG4gICAgICAgICAgICAgIDogbnVsbDtcbiAgICAgICAgICBjb25zdCBjcmVhdGVkQXQgPVxuICAgICAgICAgICAgJG9kYXRlRWxlbS5sZW5ndGggPiAwXG4gICAgICAgICAgICAgID8gKHBhcnNlT2RhdGUoJG9kYXRlRWxlbSBhcyBDaGVlcmlvPEFueU5vZGU+KSA/PyBuZXcgRGF0ZSgpKVxuICAgICAgICAgICAgICA6IG5ldyBEYXRlKCk7XG5cbiAgICAgICAgICB0aHJlYWRzLnB1c2goXG4gICAgICAgICAgICBuZXcgRm9ydW1UaHJlYWQoe1xuICAgICAgICAgICAgICBzaXRlOiBjYXRlZ29yeS5zaXRlLFxuICAgICAgICAgICAgICBpZDogdGhyZWFkSWQsXG4gICAgICAgICAgICAgIHRpdGxlLFxuICAgICAgICAgICAgICBkZXNjcmlwdGlvbixcbiAgICAgICAgICAgICAgY3JlYXRlZEJ5LFxuICAgICAgICAgICAgICBjcmVhdGVkQXQsXG4gICAgICAgICAgICAgIHBvc3RDb3VudCxcbiAgICAgICAgICAgICAgY2F0ZWdvcnksXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIC8vIENoZWNrIHBhZ2luYXRpb25cbiAgICAgICAgY29uc3QgcGFnZXIgPSAkZmlyc3QoJ2Rpdi5wYWdlcicpO1xuICAgICAgICBpZiAocGFnZXIubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBGb3J1bVRocmVhZENvbGxlY3Rpb24oY2F0ZWdvcnkuc2l0ZSwgdGhyZWFkcyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwYWdlckxpbmtzID0gcGFnZXIuZmluZCgnYScpO1xuICAgICAgICBpZiAocGFnZXJMaW5rcy5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBGb3J1bVRocmVhZENvbGxlY3Rpb24oY2F0ZWdvcnkuc2l0ZSwgdGhyZWFkcyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBsYXN0UGFnZUxpbmsgPSBwYWdlckxpbmtzW3BhZ2VyTGlua3MubGVuZ3RoIC0gMl07XG4gICAgICAgIGNvbnN0IGxhc3RQYWdlVGV4dCA9IGxhc3RQYWdlTGluayA/ICRmaXJzdChsYXN0UGFnZUxpbmspLnRleHQoKS50cmltKCkgOiAnMSc7XG4gICAgICAgIGNvbnN0IGxhc3RQYWdlID0gTnVtYmVyLnBhcnNlSW50KGxhc3RQYWdlVGV4dCwgMTApIHx8IDE7XG5cbiAgICAgICAgaWYgKGxhc3RQYWdlIDw9IDEpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IEZvcnVtVGhyZWFkQ29sbGVjdGlvbihjYXRlZ29yeS5zaXRlLCB0aHJlYWRzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEZldGNoIHJlbWFpbmluZyBwYWdlc1xuICAgICAgICBjb25zdCBib2RpZXM6IHsgcDogbnVtYmVyOyBjOiBudW1iZXI7IG1vZHVsZU5hbWU6IHN0cmluZyB9W10gPSBbXTtcbiAgICAgICAgZm9yIChsZXQgcGFnZSA9IDI7IHBhZ2UgPD0gbGFzdFBhZ2U7IHBhZ2UrKykge1xuICAgICAgICAgIGJvZGllcy5wdXNoKHtcbiAgICAgICAgICAgIHA6IHBhZ2UsXG4gICAgICAgICAgICBjOiBjYXRlZ29yeS5pZCxcbiAgICAgICAgICAgIG1vZHVsZU5hbWU6ICdmb3J1bS9Gb3J1bVZpZXdDYXRlZ29yeU1vZHVsZScsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBhZGRpdGlvbmFsUmVzdWx0cyA9IGF3YWl0IGNhdGVnb3J5LnNpdGUuYW1jUmVxdWVzdChib2RpZXMpO1xuICAgICAgICBpZiAoYWRkaXRpb25hbFJlc3VsdHMuaXNFcnIoKSkge1xuICAgICAgICAgIHRocm93IGFkZGl0aW9uYWxSZXN1bHRzLmVycm9yO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChjb25zdCByZXNwb25zZSBvZiBhZGRpdGlvbmFsUmVzdWx0cy52YWx1ZSkge1xuICAgICAgICAgIGNvbnN0IGJvZHkgPSBTdHJpbmcocmVzcG9uc2U/LmJvZHkgPz8gJycpO1xuICAgICAgICAgIGNvbnN0ICQgPSBjaGVlcmlvLmxvYWQoYm9keSk7XG5cbiAgICAgICAgICAkKCd0YWJsZS50YWJsZSB0ci5oZWFkfnRyJykuZWFjaCgoX2ksIGVsZW0pID0+IHtcbiAgICAgICAgICAgIGNvbnN0ICRyb3cgPSAkKGVsZW0pO1xuICAgICAgICAgICAgY29uc3QgdGl0bGVFbGVtID0gJHJvdy5maW5kKCdkaXYudGl0bGUgYScpO1xuICAgICAgICAgICAgY29uc3QgaHJlZiA9IHRpdGxlRWxlbS5hdHRyKCdocmVmJykgPz8gJyc7XG4gICAgICAgICAgICBjb25zdCB0aHJlYWRJZE1hdGNoID0gaHJlZi5tYXRjaCgvdC0oXFxkKykvKTtcbiAgICAgICAgICAgIGlmICghdGhyZWFkSWRNYXRjaD8uWzFdKSByZXR1cm47XG5cbiAgICAgICAgICAgIGNvbnN0IHRocmVhZElkID0gTnVtYmVyLnBhcnNlSW50KHRocmVhZElkTWF0Y2hbMV0sIDEwKTtcbiAgICAgICAgICAgIGNvbnN0IHRpdGxlID0gdGl0bGVFbGVtLnRleHQoKS50cmltKCk7XG4gICAgICAgICAgICBjb25zdCBkZXNjcmlwdGlvbiA9ICRyb3cuZmluZCgnZGl2LmRlc2NyaXB0aW9uJykudGV4dCgpLnRyaW0oKTtcbiAgICAgICAgICAgIGNvbnN0IHBvc3RDb3VudCA9IE51bWJlci5wYXJzZUludCgkcm93LmZpbmQoJ3RkLnBvc3RzJykudGV4dCgpLnRyaW0oKSwgMTApIHx8IDA7XG5cbiAgICAgICAgICAgIC8vIOODpuODvOOCtuODvOOBqOaXpeaZguOBruODkeODvOOCuVxuICAgICAgICAgICAgY29uc3QgJHVzZXJFbGVtID0gJHJvdy5maW5kKCd0ZC5zdGFydGVkIHNwYW4ucHJpbnR1c2VyJyk7XG4gICAgICAgICAgICBjb25zdCAkb2RhdGVFbGVtID0gJHJvdy5maW5kKCd0ZC5zdGFydGVkIHNwYW4ub2RhdGUnKTtcblxuICAgICAgICAgICAgY29uc3QgY3JlYXRlZEJ5ID1cbiAgICAgICAgICAgICAgJHVzZXJFbGVtLmxlbmd0aCA+IDBcbiAgICAgICAgICAgICAgICA/IHBhcnNlVXNlcihjYXRlZ29yeS5zaXRlLmNsaWVudCwgJHVzZXJFbGVtIGFzIENoZWVyaW88QW55Tm9kZT4pXG4gICAgICAgICAgICAgICAgOiBudWxsO1xuICAgICAgICAgICAgY29uc3QgY3JlYXRlZEF0ID1cbiAgICAgICAgICAgICAgJG9kYXRlRWxlbS5sZW5ndGggPiAwXG4gICAgICAgICAgICAgICAgPyAocGFyc2VPZGF0ZSgkb2RhdGVFbGVtIGFzIENoZWVyaW88QW55Tm9kZT4pID8/IG5ldyBEYXRlKCkpXG4gICAgICAgICAgICAgICAgOiBuZXcgRGF0ZSgpO1xuXG4gICAgICAgICAgICB0aHJlYWRzLnB1c2goXG4gICAgICAgICAgICAgIG5ldyBGb3J1bVRocmVhZCh7XG4gICAgICAgICAgICAgICAgc2l0ZTogY2F0ZWdvcnkuc2l0ZSxcbiAgICAgICAgICAgICAgICBpZDogdGhyZWFkSWQsXG4gICAgICAgICAgICAgICAgdGl0bGUsXG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb24sXG4gICAgICAgICAgICAgICAgY3JlYXRlZEJ5LFxuICAgICAgICAgICAgICAgIGNyZWF0ZWRBdCxcbiAgICAgICAgICAgICAgICBwb3N0Q291bnQsXG4gICAgICAgICAgICAgICAgY2F0ZWdvcnksXG4gICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICApO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBGb3J1bVRocmVhZENvbGxlY3Rpb24oY2F0ZWdvcnkuc2l0ZSwgdGhyZWFkcyk7XG4gICAgICB9KSgpLFxuICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIE5vRWxlbWVudEVycm9yKSByZXR1cm4gZXJyb3I7XG4gICAgICAgIHJldHVybiBuZXcgVW5leHBlY3RlZEVycm9yKGBGYWlsZWQgdG8gYWNxdWlyZSB0aHJlYWRzOiAke1N0cmluZyhlcnJvcil9YCk7XG4gICAgICB9XG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiDjgrnjg6zjg4Pjg4lJROOBi+OCieWNmOS4gOOBruOCueODrOODg+ODieOCkuWPluW+l1xuICAgKiBAcGFyYW0gc2l0ZSAtIOOCteOCpOODiFxuICAgKiBAcGFyYW0gdGhyZWFkSWQgLSDjgrnjg6zjg4Pjg4lJRFxuICAgKi9cbiAgc3RhdGljIGZyb21JZChzaXRlOiBTaXRlLCB0aHJlYWRJZDogbnVtYmVyKTogV2lraWRvdFJlc3VsdEFzeW5jPEZvcnVtVGhyZWFkPiB7XG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgRm9ydW1UaHJlYWRDb2xsZWN0aW9uLmFjcXVpcmVGcm9tVGhyZWFkSWRzKHNpdGUsIFt0aHJlYWRJZF0pO1xuICAgICAgICBpZiAocmVzdWx0LmlzRXJyKCkpIHtcbiAgICAgICAgICB0aHJvdyByZXN1bHQuZXJyb3I7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdGhyZWFkID0gcmVzdWx0LnZhbHVlWzBdO1xuICAgICAgICBpZiAoIXRocmVhZCkge1xuICAgICAgICAgIHRocm93IG5ldyBOb0VsZW1lbnRFcnJvcihgVGhyZWFkIG5vdCBmb3VuZDogJHt0aHJlYWRJZH1gKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGhyZWFkO1xuICAgICAgfSkoKSxcbiAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBOb0VsZW1lbnRFcnJvcikgcmV0dXJuIGVycm9yO1xuICAgICAgICByZXR1cm4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgRmFpbGVkIHRvIGdldCB0aHJlYWQ6ICR7U3RyaW5nKGVycm9yKX1gKTtcbiAgICAgIH1cbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIOOCueODrOODg+ODiUlE44GL44KJ44K544Os44OD44OJ44KS5Y+W5b6XXG4gICAqL1xuICBzdGF0aWMgYWNxdWlyZUZyb21UaHJlYWRJZHMoXG4gICAgc2l0ZTogU2l0ZSxcbiAgICB0aHJlYWRJZHM6IG51bWJlcltdLFxuICAgIGNhdGVnb3J5OiBGb3J1bUNhdGVnb3J5IHwgbnVsbCA9IG51bGxcbiAgKTogV2lraWRvdFJlc3VsdEFzeW5jPEZvcnVtVGhyZWFkQ29sbGVjdGlvbj4ge1xuICAgIHJldHVybiBmcm9tUHJvbWlzZShcbiAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHNpdGUuYW1jUmVxdWVzdChcbiAgICAgICAgICB0aHJlYWRJZHMubWFwKCh0aHJlYWRJZCkgPT4gKHtcbiAgICAgICAgICAgIHQ6IHRocmVhZElkLFxuICAgICAgICAgICAgbW9kdWxlTmFtZTogJ2ZvcnVtL0ZvcnVtVmlld1RocmVhZE1vZHVsZScsXG4gICAgICAgICAgfSkpXG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKHJlc3VsdC5pc0VycigpKSB7XG4gICAgICAgICAgdGhyb3cgcmVzdWx0LmVycm9yO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdGhyZWFkczogRm9ydW1UaHJlYWRbXSA9IFtdO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhyZWFkSWRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgY29uc3QgcmVzcG9uc2UgPSByZXN1bHQudmFsdWVbaV07XG4gICAgICAgICAgY29uc3QgdGhyZWFkSWQgPSB0aHJlYWRJZHNbaV07XG4gICAgICAgICAgaWYgKCFyZXNwb25zZSB8fCAhdGhyZWFkSWQpIGNvbnRpbnVlO1xuXG4gICAgICAgICAgY29uc3QgYm9keSA9IFN0cmluZyhyZXNwb25zZS5ib2R5ID8/ICcnKTtcbiAgICAgICAgICBjb25zdCAkID0gY2hlZXJpby5sb2FkKGJvZHkpO1xuXG4gICAgICAgICAgLy8gUGFyc2UgdGhyZWFkIGluZm8gZnJvbSBwYWdlXG4gICAgICAgICAgY29uc3QgYmNFbGVtID0gJCgnZGl2LmZvcnVtLWJyZWFkY3J1bWJzJyk7XG4gICAgICAgICAgaWYgKGJjRWxlbS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBOb0VsZW1lbnRFcnJvcignQnJlYWRjcnVtYnMgbm90IGZvdW5kJyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGNvbnN0IGJjUGFydHMgPSBiY0VsZW0udGV4dCgpLnNwbGl0KCfCuycpO1xuICAgICAgICAgIGNvbnN0IHRpdGxlID0gYmNQYXJ0cy5sZW5ndGggPiAwID8gKGJjUGFydHNbYmNQYXJ0cy5sZW5ndGggLSAxXT8udHJpbSgpID8/ICcnKSA6ICcnO1xuXG4gICAgICAgICAgY29uc3QgZGVzY0Jsb2NrRWxlbSA9ICQoJ2Rpdi5kZXNjcmlwdGlvbi1ibG9jaycpO1xuICAgICAgICAgIGNvbnN0IGRlc2NyaXB0aW9uID0gZGVzY0Jsb2NrRWxlbS50ZXh0KCkudHJpbSgpO1xuXG4gICAgICAgICAgY29uc3QgcG9zdENvdW50TWF0Y2ggPSAkKCdkaXYuc3RhdGlzdGljcycpLnRleHQoKS5tYXRjaCgvKFxcZCspLyk7XG4gICAgICAgICAgY29uc3QgcG9zdENvdW50ID0gcG9zdENvdW50TWF0Y2g/LlsxXSA/IE51bWJlci5wYXJzZUludChwb3N0Q291bnRNYXRjaFsxXSwgMTApIDogMDtcblxuICAgICAgICAgIHRocmVhZHMucHVzaChcbiAgICAgICAgICAgIG5ldyBGb3J1bVRocmVhZCh7XG4gICAgICAgICAgICAgIHNpdGUsXG4gICAgICAgICAgICAgIGlkOiB0aHJlYWRJZCxcbiAgICAgICAgICAgICAgdGl0bGUsXG4gICAgICAgICAgICAgIGRlc2NyaXB0aW9uLFxuICAgICAgICAgICAgICBjcmVhdGVkQnk6IG51bGwsXG4gICAgICAgICAgICAgIGNyZWF0ZWRBdDogbmV3IERhdGUoKSxcbiAgICAgICAgICAgICAgcG9zdENvdW50LFxuICAgICAgICAgICAgICBjYXRlZ29yeSxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBuZXcgRm9ydW1UaHJlYWRDb2xsZWN0aW9uKHNpdGUsIHRocmVhZHMpO1xuICAgICAgfSkoKSxcbiAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBOb0VsZW1lbnRFcnJvcikgcmV0dXJuIGVycm9yO1xuICAgICAgICByZXR1cm4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgRmFpbGVkIHRvIGFjcXVpcmUgdGhyZWFkczogJHtTdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfVxuICAgICk7XG4gIH1cbn1cbiIsCiAgICAiLyoqXG4gKiDjg63jgq7jg7PjgrDmqZ/og73jgpLmj5DkvpvjgZnjgovjg6Ljgrjjg6Xjg7zjg6tcbiAqXG4gKiDjgZPjga7jg6Ljgrjjg6Xjg7zjg6vjga/jgIHjg6njgqTjg5bjg6njg6rlhajkvZPjgafkvb/nlKjjgZXjgozjgovjg63jgqzjg7zjgpLoqK3lrprjgZfjgIHmj5DkvpvjgZnjgovjgIJcbiAqIOODh+ODleOCqeODq+ODiOOBp+OBr+WHuuWKm+OCkuihjOOCj+OBmuOAgeOCouODl+ODquOCseODvOOCt+ODp+ODs+WBtOOBp+OBruODreOCsOWItuW+oeOCkuWPr+iDveOBq+OBmeOCi+OAglxuICovXG5cbi8qKlxuICog44Ot44Kw44Os44OZ44OrXG4gKi9cbmV4cG9ydCB0eXBlIExvZ0xldmVsID0gJ2RlYnVnJyB8ICdpbmZvJyB8ICd3YXJuJyB8ICdlcnJvcic7XG5cbi8qKlxuICog44Ot44Kw44Os44OZ44Or44Gu5YSq5YWI5bqm77yI5pWw5YCk44GM5aSn44GN44GE44G744Gp6YeN6KaB77yJXG4gKi9cbmNvbnN0IExPR19MRVZFTF9QUklPUklUWTogUmVjb3JkPExvZ0xldmVsLCBudW1iZXI+ID0ge1xuICBkZWJ1ZzogMCxcbiAgaW5mbzogMSxcbiAgd2FybjogMixcbiAgZXJyb3I6IDMsXG59O1xuXG4vKipcbiAqIOODreOCrOODvOODj+ODs+ODieODqeODvFxuICovXG5leHBvcnQgdHlwZSBMb2dIYW5kbGVyID0gKFxuICBsZXZlbDogTG9nTGV2ZWwsXG4gIG5hbWU6IHN0cmluZyxcbiAgbWVzc2FnZTogc3RyaW5nLFxuICAuLi5hcmdzOiB1bmtub3duW11cbikgPT4gdm9pZDtcblxuLyoqXG4gKiBOdWxsSGFuZGxlcjog5L2V44KC5Ye65Yqb44GX44Gq44GE77yI44OH44OV44Kp44Or44OI77yJXG4gKi9cbmV4cG9ydCBjb25zdCBudWxsSGFuZGxlcjogTG9nSGFuZGxlciA9ICgpID0+IHtcbiAgLy8g5L2V44KC44GX44Gq44GEXG59O1xuXG4vKipcbiAqIENvbnNvbGVIYW5kbGVyOiDjgrPjg7Pjgr3jg7zjg6vjgavlh7rlipvjgZnjgotcbiAqL1xuZXhwb3J0IGNvbnN0IGNvbnNvbGVIYW5kbGVyOiBMb2dIYW5kbGVyID0gKFxuICBsZXZlbDogTG9nTGV2ZWwsXG4gIG5hbWU6IHN0cmluZyxcbiAgbWVzc2FnZTogc3RyaW5nLFxuICAuLi5hcmdzOiB1bmtub3duW11cbikgPT4ge1xuICBjb25zdCB0aW1lc3RhbXAgPSBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCk7XG4gIGNvbnN0IGZvcm1hdHRlZE1lc3NhZ2UgPSBgJHt0aW1lc3RhbXB9IFske25hbWV9LyR7bGV2ZWwudG9VcHBlckNhc2UoKX1dICR7bWVzc2FnZX1gO1xuXG4gIHN3aXRjaCAobGV2ZWwpIHtcbiAgICBjYXNlICdkZWJ1Zyc6XG4gICAgICBjb25zb2xlLmRlYnVnKGZvcm1hdHRlZE1lc3NhZ2UsIC4uLmFyZ3MpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnaW5mbyc6XG4gICAgICBjb25zb2xlLmluZm8oZm9ybWF0dGVkTWVzc2FnZSwgLi4uYXJncyk7XG4gICAgICBicmVhaztcbiAgICBjYXNlICd3YXJuJzpcbiAgICAgIGNvbnNvbGUud2Fybihmb3JtYXR0ZWRNZXNzYWdlLCAuLi5hcmdzKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2Vycm9yJzpcbiAgICAgIGNvbnNvbGUuZXJyb3IoZm9ybWF0dGVkTWVzc2FnZSwgLi4uYXJncyk7XG4gICAgICBicmVhaztcbiAgfVxufTtcblxuLyoqXG4gKiDjg63jgqzjg7zjgq/jg6njgrlcbiAqL1xuZXhwb3J0IGNsYXNzIExvZ2dlciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuICBwcml2YXRlIGhhbmRsZXI6IExvZ0hhbmRsZXI7XG4gIHByaXZhdGUgbGV2ZWw6IExvZ0xldmVsO1xuXG4gIGNvbnN0cnVjdG9yKG5hbWU6IHN0cmluZywgaGFuZGxlcjogTG9nSGFuZGxlciA9IG51bGxIYW5kbGVyLCBsZXZlbDogTG9nTGV2ZWwgPSAnd2FybicpIHtcbiAgICB0aGlzLm5hbWUgPSBuYW1lO1xuICAgIHRoaXMuaGFuZGxlciA9IGhhbmRsZXI7XG4gICAgdGhpcy5sZXZlbCA9IGxldmVsO1xuICB9XG5cbiAgLyoqXG4gICAqIOODj+ODs+ODieODqeODvOOCkuioreWumlxuICAgKi9cbiAgc2V0SGFuZGxlcihoYW5kbGVyOiBMb2dIYW5kbGVyKTogdm9pZCB7XG4gICAgdGhpcy5oYW5kbGVyID0gaGFuZGxlcjtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg63jgrDjg6zjg5njg6vjgpLoqK3lrppcbiAgICovXG4gIHNldExldmVsKGxldmVsOiBMb2dMZXZlbCk6IHZvaWQge1xuICAgIHRoaXMubGV2ZWwgPSBsZXZlbDtcbiAgfVxuXG4gIC8qKlxuICAgKiDmjIflrprjg6zjg5njg6vjgYzjg63jgrDlh7rlipvlr77osaHjgYvjganjgYbjgYtcbiAgICovXG4gIHByaXZhdGUgc2hvdWxkTG9nKGxldmVsOiBMb2dMZXZlbCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBMT0dfTEVWRUxfUFJJT1JJVFlbbGV2ZWxdID49IExPR19MRVZFTF9QUklPUklUWVt0aGlzLmxldmVsXTtcbiAgfVxuXG4gIC8qKlxuICAgKiDjg63jgrDlh7rliptcbiAgICovXG4gIHByaXZhdGUgbG9nKGxldmVsOiBMb2dMZXZlbCwgbWVzc2FnZTogc3RyaW5nLCAuLi5hcmdzOiB1bmtub3duW10pOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zaG91bGRMb2cobGV2ZWwpKSB7XG4gICAgICB0aGlzLmhhbmRsZXIobGV2ZWwsIHRoaXMubmFtZSwgbWVzc2FnZSwgLi4uYXJncyk7XG4gICAgfVxuICB9XG5cbiAgZGVidWcobWVzc2FnZTogc3RyaW5nLCAuLi5hcmdzOiB1bmtub3duW10pOiB2b2lkIHtcbiAgICB0aGlzLmxvZygnZGVidWcnLCBtZXNzYWdlLCAuLi5hcmdzKTtcbiAgfVxuXG4gIGluZm8obWVzc2FnZTogc3RyaW5nLCAuLi5hcmdzOiB1bmtub3duW10pOiB2b2lkIHtcbiAgICB0aGlzLmxvZygnaW5mbycsIG1lc3NhZ2UsIC4uLmFyZ3MpO1xuICB9XG5cbiAgd2FybihtZXNzYWdlOiBzdHJpbmcsIC4uLmFyZ3M6IHVua25vd25bXSk6IHZvaWQge1xuICAgIHRoaXMubG9nKCd3YXJuJywgbWVzc2FnZSwgLi4uYXJncyk7XG4gIH1cblxuICBlcnJvcihtZXNzYWdlOiBzdHJpbmcsIC4uLmFyZ3M6IHVua25vd25bXSk6IHZvaWQge1xuICAgIHRoaXMubG9nKCdlcnJvcicsIG1lc3NhZ2UsIC4uLmFyZ3MpO1xuICB9XG59XG5cbi8qKlxuICog44Ot44Ks44O844KS5Y+W5b6XXG4gKiBAcGFyYW0gbmFtZSAtIOODreOCrOODvOWQje+8iOODh+ODleOCqeODq+ODiDogXCJ3aWtpZG90XCLvvIlcbiAqIEByZXR1cm5zIOODreOCrOODvOOCpOODs+OCueOCv+ODs+OCuVxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0TG9nZ2VyKG5hbWUgPSAnd2lraWRvdCcpOiBMb2dnZXIge1xuICByZXR1cm4gbmV3IExvZ2dlcihuYW1lKTtcbn1cblxuLyoqXG4gKiDjgrPjg7Pjgr3jg7zjg6vlh7rlipvnlKjjg4/jg7Pjg4njg6njgpLoqK3lrppcbiAqIEBwYXJhbSBsb2dnZXIgLSDoqK3lrprjgZnjgovjg63jgqzjg7xcbiAqIEBwYXJhbSBsZXZlbCAtIOODreOCsOODrOODmeODq++8iOODh+ODleOCqeODq+ODiDogXCJ3YXJuXCLvvIlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldHVwQ29uc29sZUhhbmRsZXIobG9nZ2VyOiBMb2dnZXIsIGxldmVsOiBMb2dMZXZlbCA9ICd3YXJuJyk6IHZvaWQge1xuICBsb2dnZXIuc2V0SGFuZGxlcihjb25zb2xlSGFuZGxlcik7XG4gIGxvZ2dlci5zZXRMZXZlbChsZXZlbCk7XG59XG5cbi8qKlxuICog44OR44OD44Kx44O844K45YWo5L2T44Gn5L2/55So44GV44KM44KL44OH44OV44Kp44Or44OI44Ot44Ks44O8XG4gKi9cbmV4cG9ydCBjb25zdCBsb2dnZXI6IExvZ2dlciA9IGdldExvZ2dlcigpO1xuIiwKICAgICJpbXBvcnQgdHlwZSB7IENsaWVudFJlZiB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB0eXBlIHsgQWJzdHJhY3RVc2VyLCBVc2VyVHlwZSB9IGZyb20gJy4vYWJzdHJhY3QtdXNlcic7XG5cbi8qKlxuICog5Yy/5ZCN44Om44O844K244O8XG4gKi9cbmV4cG9ydCBjbGFzcyBBbm9ueW1vdXNVc2VyIGltcGxlbWVudHMgQWJzdHJhY3RVc2VyIHtcbiAgcHVibGljIHJlYWRvbmx5IGNsaWVudDogQ2xpZW50UmVmO1xuXG4gIC8qKiDjg6bjg7zjgrbjg7xJRO+8iOWMv+WQjeOBrzDvvIkgKi9cbiAgcHVibGljIHJlYWRvbmx5IGlkOiBudW1iZXIgPSAwO1xuXG4gIC8qKiDjg6bjg7zjgrbjg7zlkI3vvIjljL/lkI3jga9cIkFub255bW91c1wi77yJICovXG4gIHB1YmxpYyByZWFkb25seSBuYW1lOiBzdHJpbmcgPSAnQW5vbnltb3VzJztcblxuICAvKiogVU5JWOW9ouW8j+OBruODpuODvOOCtuODvOWQjSAqL1xuICBwdWJsaWMgcmVhZG9ubHkgdW5peE5hbWU6IHN0cmluZyA9ICdhbm9ueW1vdXMnO1xuXG4gIC8qKiDjgqLjg5Djgr/jg7xVUkzvvIjljL/lkI3jga9udWxs77yJICovXG4gIHB1YmxpYyByZWFkb25seSBhdmF0YXJVcmw6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiBJUOOCouODieODrOOCuSAqL1xuICBwdWJsaWMgcmVhZG9ubHkgaXA6IHN0cmluZztcblxuICAvKiog44Om44O844K244O856iu5YilICovXG4gIHB1YmxpYyByZWFkb25seSB1c2VyVHlwZTogVXNlclR5cGUgPSAnYW5vbnltb3VzJztcblxuICBjb25zdHJ1Y3RvcihjbGllbnQ6IENsaWVudFJlZiwgaXA6IHN0cmluZykge1xuICAgIHRoaXMuY2xpZW50ID0gY2xpZW50O1xuICAgIHRoaXMuaXAgPSBpcDtcbiAgfVxuXG4gIC8vIEFic3RyYWN0VXNlcuWun+ijhVxuICBpc1VzZXIoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlzRGVsZXRlZFVzZXIoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlzQW5vbnltb3VzVXNlcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpc0d1ZXN0VXNlcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaXNXaWtpZG90VXNlcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIHJldHVybiBgQW5vbnltb3VzVXNlcihuYW1lPSR7dGhpcy5uYW1lfSwgdW5peE5hbWU9JHt0aGlzLnVuaXhOYW1lfSwgaXA9JHt0aGlzLmlwfSlgO1xuICB9XG59XG4iLAogICAgImltcG9ydCB0eXBlIHsgQ2xpZW50UmVmIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHR5cGUgeyBBYnN0cmFjdFVzZXIsIFVzZXJUeXBlIH0gZnJvbSAnLi9hYnN0cmFjdC11c2VyJztcblxuLyoqXG4gKiDliYrpmaTmuIjjgb/jg6bjg7zjgrbjg7xcbiAqL1xuZXhwb3J0IGNsYXNzIERlbGV0ZWRVc2VyIGltcGxlbWVudHMgQWJzdHJhY3RVc2VyIHtcbiAgcHVibGljIHJlYWRvbmx5IGNsaWVudDogQ2xpZW50UmVmO1xuXG4gIC8qKiDliYrpmaTmuIjjgb/jg6bjg7zjgrbjg7xJRCAqL1xuICBwdWJsaWMgcmVhZG9ubHkgaWQ6IG51bWJlcjtcblxuICAvKiog44Om44O844K244O85ZCN77yI5YmK6Zmk5riI44G/44GvXCJhY2NvdW50IGRlbGV0ZWRcIu+8iSAqL1xuICBwdWJsaWMgcmVhZG9ubHkgbmFtZTogc3RyaW5nID0gJ2FjY291bnQgZGVsZXRlZCc7XG5cbiAgLyoqIFVOSVjlvaLlvI/jga7jg6bjg7zjgrbjg7zlkI0gKi9cbiAgcHVibGljIHJlYWRvbmx5IHVuaXhOYW1lOiBzdHJpbmcgPSAnYWNjb3VudF9kZWxldGVkJztcblxuICAvKiog44Ki44OQ44K/44O8VVJM77yI5YmK6Zmk5riI44G/44GvbnVsbO+8iSAqL1xuICBwdWJsaWMgcmVhZG9ubHkgYXZhdGFyVXJsOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxuICAvKiogSVDjgqLjg4njg6zjgrnvvIjliYrpmaTmuIjjgb/jga9udWxs77yJICovXG4gIHB1YmxpYyByZWFkb25seSBpcDogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqIOODpuODvOOCtuODvOeoruWIpSAqL1xuICBwdWJsaWMgcmVhZG9ubHkgdXNlclR5cGU6IFVzZXJUeXBlID0gJ2RlbGV0ZWQnO1xuXG4gIGNvbnN0cnVjdG9yKGNsaWVudDogQ2xpZW50UmVmLCBpZDogbnVtYmVyKSB7XG4gICAgdGhpcy5jbGllbnQgPSBjbGllbnQ7XG4gICAgdGhpcy5pZCA9IGlkO1xuICB9XG5cbiAgLy8gQWJzdHJhY3RVc2Vy5a6f6KOFXG4gIGlzVXNlcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaXNEZWxldGVkVXNlcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICBpc0Fub255bW91c1VzZXIoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlzR3Vlc3RVc2VyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpc1dpa2lkb3RVc2VyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHRvU3RyaW5nKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGBEZWxldGVkVXNlcihpZD0ke3RoaXMuaWR9LCBuYW1lPSR7dGhpcy5uYW1lfSwgdW5peE5hbWU9JHt0aGlzLnVuaXhOYW1lfSlgO1xuICB9XG59XG4iLAogICAgImltcG9ydCB0eXBlIHsgQ2xpZW50UmVmIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHR5cGUgeyBBYnN0cmFjdFVzZXIsIFVzZXJUeXBlIH0gZnJvbSAnLi9hYnN0cmFjdC11c2VyJztcblxuLyoqXG4gKiDjgrLjgrnjg4jjg6bjg7zjgrbjg7xcbiAqL1xuZXhwb3J0IGNsYXNzIEd1ZXN0VXNlciBpbXBsZW1lbnRzIEFic3RyYWN0VXNlciB7XG4gIHB1YmxpYyByZWFkb25seSBjbGllbnQ6IENsaWVudFJlZjtcblxuICAvKiog44Om44O844K244O8SUTvvIjjgrLjgrnjg4jjga8w77yJICovXG4gIHB1YmxpYyByZWFkb25seSBpZDogbnVtYmVyID0gMDtcblxuICAvKiog44Ky44K544OI5ZCNICovXG4gIHB1YmxpYyByZWFkb25seSBuYW1lOiBzdHJpbmc7XG5cbiAgLyoqIFVOSVjlvaLlvI/jga7jg6bjg7zjgrbjg7zlkI3vvIjjgrLjgrnjg4jjga9udWxs77yJICovXG4gIHB1YmxpYyByZWFkb25seSB1bml4TmFtZTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqIOOCouODkOOCv+ODvFVSTO+8iEdyYXZhdGFy44Gu5aC05ZCI44GC44KK77yJICovXG4gIHB1YmxpYyByZWFkb25seSBhdmF0YXJVcmw6IHN0cmluZyB8IG51bGw7XG5cbiAgLyoqIElQ44Ki44OJ44Os44K577yI44Ky44K544OI44GvbnVsbO+8iSAqL1xuICBwdWJsaWMgcmVhZG9ubHkgaXA6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiDjg6bjg7zjgrbjg7znqK7liKUgKi9cbiAgcHVibGljIHJlYWRvbmx5IHVzZXJUeXBlOiBVc2VyVHlwZSA9ICdndWVzdCc7XG5cbiAgY29uc3RydWN0b3IoY2xpZW50OiBDbGllbnRSZWYsIG5hbWU6IHN0cmluZywgYXZhdGFyVXJsOiBzdHJpbmcgfCBudWxsID0gbnVsbCkge1xuICAgIHRoaXMuY2xpZW50ID0gY2xpZW50O1xuICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gICAgdGhpcy5hdmF0YXJVcmwgPSBhdmF0YXJVcmw7XG4gIH1cblxuICAvLyBBYnN0cmFjdFVzZXLlrp/oo4VcbiAgaXNVc2VyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpc0RlbGV0ZWRVc2VyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICBpc0Fub255bW91c1VzZXIoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlzR3Vlc3RVc2VyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGlzV2lraWRvdFVzZXIoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgdG9TdHJpbmcoKTogc3RyaW5nIHtcbiAgICByZXR1cm4gYEd1ZXN0VXNlcihuYW1lPSR7dGhpcy5uYW1lfSlgO1xuICB9XG59XG4iLAogICAgImltcG9ydCB0eXBlIHsgQ2xpZW50UmVmIH0gZnJvbSAnLi4vdHlwZXMnO1xuaW1wb3J0IHR5cGUgeyBBYnN0cmFjdFVzZXIsIFVzZXJUeXBlIH0gZnJvbSAnLi9hYnN0cmFjdC11c2VyJztcblxuLyoqXG4gKiBXaWtpZG9044K344K544OG44Og44Om44O844K244O8XG4gKi9cbmV4cG9ydCBjbGFzcyBXaWtpZG90VXNlciBpbXBsZW1lbnRzIEFic3RyYWN0VXNlciB7XG4gIHB1YmxpYyByZWFkb25seSBjbGllbnQ6IENsaWVudFJlZjtcblxuICAvKiog44Om44O844K244O8SUTvvIhXaWtpZG9044K344K544OG44Og44GvMO+8iSAqL1xuICBwdWJsaWMgcmVhZG9ubHkgaWQ6IG51bWJlciA9IDA7XG5cbiAgLyoqIOODpuODvOOCtuODvOWQjSAqL1xuICBwdWJsaWMgcmVhZG9ubHkgbmFtZTogc3RyaW5nID0gJ1dpa2lkb3QnO1xuXG4gIC8qKiBVTklY5b2i5byP44Gu44Om44O844K244O85ZCNICovXG4gIHB1YmxpYyByZWFkb25seSB1bml4TmFtZTogc3RyaW5nID0gJ3dpa2lkb3QnO1xuXG4gIC8qKiDjgqLjg5Djgr/jg7xVUkzvvIjjgrfjgrnjg4bjg6Djg6bjg7zjgrbjg7zjga9udWxs77yJICovXG4gIHB1YmxpYyByZWFkb25seSBhdmF0YXJVcmw6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiBJUOOCouODieODrOOCue+8iOOCt+OCueODhuODoOODpuODvOOCtuODvOOBr251bGzvvIkgKi9cbiAgcHVibGljIHJlYWRvbmx5IGlwOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxuICAvKiog44Om44O844K244O856iu5YilICovXG4gIHB1YmxpYyByZWFkb25seSB1c2VyVHlwZTogVXNlclR5cGUgPSAnd2lraWRvdCc7XG5cbiAgY29uc3RydWN0b3IoY2xpZW50OiBDbGllbnRSZWYpIHtcbiAgICB0aGlzLmNsaWVudCA9IGNsaWVudDtcbiAgfVxuXG4gIC8vIEFic3RyYWN0VXNlcuWun+ijhVxuICBpc1VzZXIoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlzRGVsZXRlZFVzZXIoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlzQW5vbnltb3VzVXNlcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaXNHdWVzdFVzZXIoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlzV2lraWRvdFVzZXIoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIHJldHVybiBgV2lraWRvdFVzZXIobmFtZT0ke3RoaXMubmFtZX0sIHVuaXhOYW1lPSR7dGhpcy51bml4TmFtZX0pYDtcbiAgfVxufVxuIiwKICAgICJpbXBvcnQgdHlwZSAqIGFzIGNoZWVyaW8gZnJvbSAnY2hlZXJpbyc7XG5pbXBvcnQgdHlwZSB7IEFueU5vZGUgfSBmcm9tICdkb21oYW5kbGVyJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uLy4uL2NvbW1vbi9sb2dnZXInO1xuaW1wb3J0IHR5cGUgeyBDbGllbnRSZWYgfSBmcm9tICcuLi8uLi9tb2R1bGUvdHlwZXMnO1xuaW1wb3J0IHR5cGUgeyBBYnN0cmFjdFVzZXIgfSBmcm9tICcuLi8uLi9tb2R1bGUvdXNlcic7XG5pbXBvcnQgeyBBbm9ueW1vdXNVc2VyLCBEZWxldGVkVXNlciwgR3Vlc3RVc2VyLCBVc2VyLCBXaWtpZG90VXNlciB9IGZyb20gJy4uLy4uL21vZHVsZS91c2VyJztcblxuLyoqXG4gKiBwcmludHVzZXLopoHntKDjgpLjg5Hjg7zjgrnjgZfjgIHjg6bjg7zjgrbjg7zjgqrjg5bjgrjjgqfjgq/jg4jjgpLov5TjgZlcbiAqXG4gKiBAcGFyYW0gY2xpZW50IC0gV2lraWRvdOOCr+ODqeOCpOOCouODs+ODiFxuICogQHBhcmFtIGVsZW0gLSDjg5Hjg7zjgrnlr77osaHjga7opoHntKDvvIhwcmludHVzZXLjgq/jg6njgrnjgYzjgaTjgYTjgZ/opoHntKDvvIlcbiAqIEByZXR1cm5zIOODkeODvOOCueOBleOCjOOBpuW+l+OCieOCjOOBn+ODpuODvOOCtuODvOOCquODluOCuOOCp+OCr+ODiFxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VVc2VyKGNsaWVudDogQ2xpZW50UmVmLCBlbGVtOiBjaGVlcmlvLkNoZWVyaW88QW55Tm9kZT4pOiBBYnN0cmFjdFVzZXIge1xuICBjb25zdCBjbGFzc0F0dHIgPSBlbGVtLmF0dHIoJ2NsYXNzJykgPz8gJyc7XG4gIGNvbnN0IGNsYXNzZXMgPSBjbGFzc0F0dHIuc3BsaXQoL1xccysvKTtcblxuICAvLyDliYrpmaTmuIjjgb/jg6bjg7zjgrbjg7zliKTlrppcbiAgaWYgKGNsYXNzZXMuaW5jbHVkZXMoJ2RlbGV0ZWQnKSkge1xuICAgIGNvbnN0IGRhdGFJZCA9IGVsZW0uYXR0cignZGF0YS1pZCcpO1xuICAgIGNvbnN0IHVzZXJJZCA9IGRhdGFJZCA/IE51bWJlci5wYXJzZUludChkYXRhSWQsIDEwKSA6IDA7XG4gICAgcmV0dXJuIG5ldyBEZWxldGVkVXNlcihjbGllbnQsIHVzZXJJZCk7XG4gIH1cblxuICAvLyDjg4bjgq3jgrnjg4jjgYwgXCIodXNlciBkZWxldGVkKVwiIOOBruWgtOWQiFxuICBjb25zdCB0ZXh0ID0gZWxlbS50ZXh0KCkudHJpbSgpO1xuICBpZiAodGV4dCA9PT0gJyh1c2VyIGRlbGV0ZWQpJykge1xuICAgIHJldHVybiBuZXcgRGVsZXRlZFVzZXIoY2xpZW50LCAwKTtcbiAgfVxuXG4gIC8vIOWMv+WQjeODpuODvOOCtuODvOWIpOWumlxuICBpZiAoY2xhc3Nlcy5pbmNsdWRlcygnYW5vbnltb3VzJykpIHtcbiAgICBjb25zdCBpcEVsZW0gPSBlbGVtLmZpbmQoJ3NwYW4uaXAnKTtcbiAgICBpZiAoaXBFbGVtLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGlwID0gaXBFbGVtLnRleHQoKS5yZXBsYWNlKC9bKCldL2csICcnKS50cmltKCk7XG4gICAgICByZXR1cm4gbmV3IEFub255bW91c1VzZXIoY2xpZW50LCBpcCk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgQW5vbnltb3VzVXNlcihjbGllbnQsICcnKTtcbiAgfVxuXG4gIC8vIOOCsuOCueODiOODpuODvOOCtuODvOWIpOWumu+8iEdyYXZhdGFy44Ki44OQ44K/44O844KS5oyB44Gk77yJXG4gIGNvbnN0IGltZ0VsZW0gPSBlbGVtLmZpbmQoJ2ltZycpO1xuICBpZiAoaW1nRWxlbS5sZW5ndGggPiAwKSB7XG4gICAgY29uc3Qgc3JjID0gaW1nRWxlbS5hdHRyKCdzcmMnKSA/PyAnJztcbiAgICBpZiAoc3JjLmluY2x1ZGVzKCdncmF2YXRhci5jb20nKSkge1xuICAgICAgY29uc3QgZ3Vlc3ROYW1lID0gdGV4dC5zcGxpdCgnICcpWzBdID8/ICdHdWVzdCc7XG4gICAgICByZXR1cm4gbmV3IEd1ZXN0VXNlcihjbGllbnQsIGd1ZXN0TmFtZSwgc3JjKTtcbiAgICB9XG4gIH1cblxuICAvLyBXaWtpZG9044K344K544OG44Og44Om44O844K244O85Yik5a6aXG4gIGlmICh0ZXh0ID09PSAnV2lraWRvdCcpIHtcbiAgICByZXR1cm4gbmV3IFdpa2lkb3RVc2VyKGNsaWVudCk7XG4gIH1cblxuICAvLyDpgJrluLjjg6bjg7zjgrbjg7xcbiAgY29uc3QgbGlua3MgPSBlbGVtLmZpbmQoJ2EnKTtcbiAgaWYgKGxpbmtzLmxlbmd0aCA9PT0gMCkge1xuICAgIC8vIOODquODs+OCr+OBjOOBquOBhOWgtOWQiOOBr0RlbGV0ZWRVc2Vy44Go44GX44Gm5omx44GGXG4gICAgcmV0dXJuIG5ldyBEZWxldGVkVXNlcihjbGllbnQsIDApO1xuICB9XG5cbiAgLy8g5pyA5b6M44Gu44Oq44Oz44Kv44GM44Om44O844K244O844Oq44Oz44KvXG4gIGNvbnN0IHVzZXJMaW5rID0gbGlua3MubGFzdCgpO1xuICBjb25zdCB1c2VyTmFtZSA9IHVzZXJMaW5rLnRleHQoKS50cmltKCk7XG4gIGNvbnN0IGhyZWYgPSB1c2VyTGluay5hdHRyKCdocmVmJykgPz8gJyc7XG4gIGNvbnN0IG9uY2xpY2sgPSB1c2VyTGluay5hdHRyKCdvbmNsaWNrJykgPz8gJyc7XG5cbiAgLy8gdW5peF9uYW1l44KSaHJlZuOBi+OCieaKveWHulxuICBjb25zdCB1bml4TmFtZSA9IGhyZWYucmVwbGFjZSgvXi4qXFwvdXNlcjppbmZvXFwvLywgJycpLnJlcGxhY2UoL1xcLyQvLCAnJyk7XG5cbiAgLy8gdXNlcl9pZOOCkm9uY2xpY2vjgYvjgonmir3lh7pcbiAgLy8g44OR44K/44O844OzOiBcIldJS0lET1QucGFnZS5saXN0ZW5lcnMudXNlckluZm8oMTIzNDU2KTsgcmV0dXJuIGZhbHNlO1wiXG4gIGNvbnN0IHVzZXJJZE1hdGNoID0gb25jbGljay5tYXRjaCgvdXNlckluZm9cXCgoXFxkKylcXCkvKTtcbiAgY29uc3QgdXNlcklkID0gdXNlcklkTWF0Y2g/LlsxXSA/IE51bWJlci5wYXJzZUludCh1c2VySWRNYXRjaFsxXSwgMTApIDogMDtcblxuICAvLyDjgqLjg5Djgr/jg7xVUkzjgpLnlJ/miJBcbiAgY29uc3QgYXZhdGFyVXJsID0gdXNlcklkID4gMCA/IGBodHRwOi8vd3d3Lndpa2lkb3QuY29tL2F2YXRhci5waHA/dXNlcmlkPSR7dXNlcklkfWAgOiB1bmRlZmluZWQ7XG5cbiAgcmV0dXJuIG5ldyBVc2VyKGNsaWVudCwge1xuICAgIGlkOiB1c2VySWQsXG4gICAgbmFtZTogdXNlck5hbWUsXG4gICAgdW5peE5hbWUsXG4gICAgYXZhdGFyVXJsLFxuICB9KTtcbn1cblxuLyoqXG4gKiBvZGF0Zeimgee0oOOBi+OCieaXpeaZguOCkuODkeODvOOCueOBmeOCi1xuICpcbiAqIEBwYXJhbSBlbGVtIC0g44OR44O844K55a++6LGh44Gu6KaB57Sg77yIb2RhdGXopoHntKDvvIlcbiAqIEByZXR1cm5zIOODkeODvOOCueOBleOCjOOBn0RhdGXjgIHjg5Hjg7zjgrnlpLHmlZfmmYLjga9udWxsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZU9kYXRlKGVsZW06IGNoZWVyaW8uQ2hlZXJpbzxBbnlOb2RlPik6IERhdGUgfCBudWxsIHtcbiAgY29uc3QgY2xhc3NBdHRyID0gZWxlbS5hdHRyKCdjbGFzcycpID8/ICcnO1xuXG4gIC8vIOOCr+ODqeOCueOBi+OCiSBVbml4IOOCv+OCpOODoOOCueOCv+ODs+ODl+OCkuaKveWHulxuICAvLyDjg5Hjgr/jg7zjg7M6IFwib2RhdGUgdGltZV8xMjM0NTY3ODkwIGZvcm1hdF8uLi5cIiDjga7jgojjgYbjgarlvaLlvI9cbiAgY29uc3QgdGltZU1hdGNoID0gY2xhc3NBdHRyLm1hdGNoKC90aW1lXyhcXGQrKS8pO1xuICBpZiAodGltZU1hdGNoPy5bMV0pIHtcbiAgICBjb25zdCB1bml4VGltZSA9IE51bWJlci5wYXJzZUludCh0aW1lTWF0Y2hbMV0sIDEwKTtcbiAgICByZXR1cm4gbmV3IERhdGUodW5peFRpbWUgKiAxMDAwKTtcbiAgfVxuXG4gIC8vIOODleOCqeODvOODq+ODkOODg+OCrzog44OG44Kt44K544OI44GL44KJ44OR44O844K5XG4gIGNvbnN0IHRleHQgPSBlbGVtLnRleHQoKS50cmltKCk7XG4gIGNvbnN0IHBhcnNlZCA9IERhdGUucGFyc2UodGV4dCk7XG4gIGlmICghTnVtYmVyLmlzTmFOKHBhcnNlZCkpIHtcbiAgICByZXR1cm4gbmV3IERhdGUocGFyc2VkKTtcbiAgfVxuXG4gIC8vIOODkeODvOOCueOBp+OBjeOBquOBhOWgtOWQiOOBr251bGzjgpLov5TljbTjgZfjgIHorablkYrjgpLjg63jgrDlh7rliptcbiAgbG9nZ2VyLndhcm4oYEZhaWxlZCB0byBwYXJzZSBvZGF0ZSBlbGVtZW50OiBjbGFzcz1cIiR7Y2xhc3NBdHRyfVwiLCB0ZXh0PVwiJHt0ZXh0fVwiYCk7XG4gIHJldHVybiBudWxsO1xufVxuIiwKICAgICJpbXBvcnQgdHlwZSB7IENoZWVyaW8sIENoZWVyaW9BUEkgfSBmcm9tICdjaGVlcmlvJztcbmltcG9ydCAqIGFzIGNoZWVyaW8gZnJvbSAnY2hlZXJpbyc7XG5pbXBvcnQgdHlwZSB7IEFueU5vZGUsIEVsZW1lbnQgfSBmcm9tICdkb21oYW5kbGVyJztcbmltcG9ydCB7IFJlcXVpcmVMb2dpbiB9IGZyb20gJy4uLy4uL2NvbW1vbi9kZWNvcmF0b3JzJztcbmltcG9ydCB7IExvZ2luUmVxdWlyZWRFcnJvciwgTm9FbGVtZW50RXJyb3IsIFVuZXhwZWN0ZWRFcnJvciB9IGZyb20gJy4uLy4uL2NvbW1vbi9lcnJvcnMnO1xuaW1wb3J0IHsgZnJvbVByb21pc2UsIHR5cGUgV2lraWRvdFJlc3VsdEFzeW5jIH0gZnJvbSAnLi4vLi4vY29tbW9uL3R5cGVzJztcbmltcG9ydCB7IHBhcnNlT2RhdGUsIHBhcnNlVXNlciB9IGZyb20gJy4uLy4uL3V0aWwvcGFyc2VyJztcbmltcG9ydCB0eXBlIHsgQ2xpZW50IH0gZnJvbSAnLi4vY2xpZW50JztcbmltcG9ydCB0eXBlIHsgRm9ydW1UaHJlYWRSZWYgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQgdHlwZSB7IEFic3RyYWN0VXNlciB9IGZyb20gJy4uL3VzZXInO1xuXG4vKipcbiAqIOODleOCqeODvOODqeODoOaKleeov+ODh+ODvOOCv1xuICovXG5leHBvcnQgaW50ZXJmYWNlIEZvcnVtUG9zdERhdGEge1xuICB0aHJlYWQ6IEZvcnVtVGhyZWFkUmVmO1xuICBpZDogbnVtYmVyO1xuICB0aXRsZTogc3RyaW5nO1xuICB0ZXh0OiBzdHJpbmc7XG4gIGVsZW1lbnQ6IEVsZW1lbnQ7XG4gIGNyZWF0ZWRCeTogQWJzdHJhY3RVc2VyO1xuICBjcmVhdGVkQXQ6IERhdGU7XG4gIGVkaXRlZEJ5PzogQWJzdHJhY3RVc2VyIHwgbnVsbDtcbiAgZWRpdGVkQXQ/OiBEYXRlIHwgbnVsbDtcbiAgcGFyZW50SWQ/OiBudW1iZXIgfCBudWxsO1xufVxuXG4vKipcbiAqIOODleOCqeODvOODqeODoOaKleeov1xuICovXG5leHBvcnQgY2xhc3MgRm9ydW1Qb3N0IHtcbiAgcHVibGljIHJlYWRvbmx5IHRocmVhZDogRm9ydW1UaHJlYWRSZWY7XG4gIHB1YmxpYyByZWFkb25seSBpZDogbnVtYmVyO1xuICBwdWJsaWMgdGl0bGU6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IHRleHQ6IHN0cmluZztcbiAgcHVibGljIHJlYWRvbmx5IGVsZW1lbnQ6IEVsZW1lbnQ7XG4gIHB1YmxpYyByZWFkb25seSBjcmVhdGVkQnk6IEFic3RyYWN0VXNlcjtcbiAgcHVibGljIHJlYWRvbmx5IGNyZWF0ZWRBdDogRGF0ZTtcbiAgcHVibGljIHJlYWRvbmx5IGVkaXRlZEJ5OiBBYnN0cmFjdFVzZXIgfCBudWxsO1xuICBwdWJsaWMgcmVhZG9ubHkgZWRpdGVkQXQ6IERhdGUgfCBudWxsO1xuICBwcml2YXRlIF9wYXJlbnRJZDogbnVtYmVyIHwgbnVsbDtcbiAgcHJpdmF0ZSBfc291cmNlOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxuICBjb25zdHJ1Y3RvcihkYXRhOiBGb3J1bVBvc3REYXRhKSB7XG4gICAgdGhpcy50aHJlYWQgPSBkYXRhLnRocmVhZDtcbiAgICB0aGlzLmlkID0gZGF0YS5pZDtcbiAgICB0aGlzLnRpdGxlID0gZGF0YS50aXRsZTtcbiAgICB0aGlzLnRleHQgPSBkYXRhLnRleHQ7XG4gICAgdGhpcy5lbGVtZW50ID0gZGF0YS5lbGVtZW50O1xuICAgIHRoaXMuY3JlYXRlZEJ5ID0gZGF0YS5jcmVhdGVkQnk7XG4gICAgdGhpcy5jcmVhdGVkQXQgPSBkYXRhLmNyZWF0ZWRBdDtcbiAgICB0aGlzLmVkaXRlZEJ5ID0gZGF0YS5lZGl0ZWRCeSA/PyBudWxsO1xuICAgIHRoaXMuZWRpdGVkQXQgPSBkYXRhLmVkaXRlZEF0ID8/IG51bGw7XG4gICAgdGhpcy5fcGFyZW50SWQgPSBkYXRhLnBhcmVudElkID8/IG51bGw7XG4gIH1cblxuICAvKipcbiAgICog6Kaq5oqV56i/SURcbiAgICovXG4gIGdldCBwYXJlbnRJZCgpOiBudW1iZXIgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5fcGFyZW50SWQ7XG4gIH1cblxuICAvKipcbiAgICog44K944O844K544Kz44O844OJ77yIV2lraWRvdOiomOazle+8ieOCkuWPluW+l1xuICAgKi9cbiAgZ2V0U291cmNlKCk6IFdpa2lkb3RSZXN1bHRBc3luYzxzdHJpbmc+IHtcbiAgICBpZiAodGhpcy5fc291cmNlICE9PSBudWxsKSB7XG4gICAgICByZXR1cm4gZnJvbVByb21pc2UoUHJvbWlzZS5yZXNvbHZlKHRoaXMuX3NvdXJjZSksIChlKSA9PiBuZXcgVW5leHBlY3RlZEVycm9yKFN0cmluZyhlKSkpO1xuICAgIH1cblxuICAgIHJldHVybiBmcm9tUHJvbWlzZShcbiAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMudGhyZWFkLnNpdGUuYW1jUmVxdWVzdChbXG4gICAgICAgICAge1xuICAgICAgICAgICAgbW9kdWxlTmFtZTogJ2ZvcnVtL3N1Yi9Gb3J1bUVkaXRQb3N0Rm9ybU1vZHVsZScsXG4gICAgICAgICAgICB0aHJlYWRJZDogdGhpcy50aHJlYWQuaWQsXG4gICAgICAgICAgICBwb3N0SWQ6IHRoaXMuaWQsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG5cbiAgICAgICAgaWYgKHJlc3VsdC5pc0VycigpKSB7XG4gICAgICAgICAgdGhyb3cgcmVzdWx0LmVycm9yO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgcmVzcG9uc2UgPSByZXN1bHQudmFsdWVbMF07XG4gICAgICAgIGlmICghcmVzcG9uc2UpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgTm9FbGVtZW50RXJyb3IoJ0VtcHR5IHJlc3BvbnNlJyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCAkID0gY2hlZXJpby5sb2FkKFN0cmluZyhyZXNwb25zZS5ib2R5ID8/ICcnKSk7XG4gICAgICAgIGNvbnN0IHNvdXJjZUVsZW0gPSAkKFwidGV4dGFyZWFbbmFtZT0nc291cmNlJ11cIik7XG4gICAgICAgIGlmIChzb3VyY2VFbGVtLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgIHRocm93IG5ldyBOb0VsZW1lbnRFcnJvcignU291cmNlIHRleHRhcmVhIG5vdCBmb3VuZCcpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3NvdXJjZSA9IHNvdXJjZUVsZW0udGV4dCgpO1xuICAgICAgICByZXR1cm4gdGhpcy5fc291cmNlO1xuICAgICAgfSkoKSxcbiAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBOb0VsZW1lbnRFcnJvcikgcmV0dXJuIGVycm9yO1xuICAgICAgICByZXR1cm4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgRmFpbGVkIHRvIGdldCBwb3N0IHNvdXJjZTogJHtTdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICog5oqV56i/44KS57eo6ZuG44GZ44KLXG4gICAqIEBwYXJhbSBzb3VyY2UgLSDmlrDjgZfjgYTjgr3jg7zjgrnvvIhXaWtpZG906KiY5rOV77yJXG4gICAqIEBwYXJhbSB0aXRsZSAtIOaWsOOBl+OBhOOCv+OCpOODiOODq++8iOecgeeVpeaZguOBr+ePvuWcqOOBruOCv+OCpOODiOODq+OCkue2reaMge+8iVxuICAgKi9cbiAgQFJlcXVpcmVMb2dpblxuICBlZGl0KHNvdXJjZTogc3RyaW5nLCB0aXRsZT86IHN0cmluZyk6IFdpa2lkb3RSZXN1bHRBc3luYzx2b2lkPiB7XG4gICAgcmV0dXJuIGZyb21Qcm9taXNlKFxuICAgICAgKGFzeW5jICgpID0+IHtcbiAgICAgICAgLy8g54++5Zyo44Gu44Oq44OT44K444On44OzSUTjgpLlj5blvpdcbiAgICAgICAgY29uc3QgZm9ybVJlc3VsdCA9IGF3YWl0IHRoaXMudGhyZWFkLnNpdGUuYW1jUmVxdWVzdChbXG4gICAgICAgICAge1xuICAgICAgICAgICAgbW9kdWxlTmFtZTogJ2ZvcnVtL3N1Yi9Gb3J1bUVkaXRQb3N0Rm9ybU1vZHVsZScsXG4gICAgICAgICAgICB0aHJlYWRJZDogdGhpcy50aHJlYWQuaWQsXG4gICAgICAgICAgICBwb3N0SWQ6IHRoaXMuaWQsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG5cbiAgICAgICAgaWYgKGZvcm1SZXN1bHQuaXNFcnIoKSkge1xuICAgICAgICAgIHRocm93IGZvcm1SZXN1bHQuZXJyb3I7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmb3JtUmVzcG9uc2UgPSBmb3JtUmVzdWx0LnZhbHVlWzBdO1xuICAgICAgICBpZiAoIWZvcm1SZXNwb25zZSkge1xuICAgICAgICAgIHRocm93IG5ldyBOb0VsZW1lbnRFcnJvcignRW1wdHkgZm9ybSByZXNwb25zZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgJCA9IGNoZWVyaW8ubG9hZChTdHJpbmcoZm9ybVJlc3BvbnNlLmJvZHkgPz8gJycpKTtcbiAgICAgICAgY29uc3QgcmV2aXNpb25JbnB1dCA9ICQoXCJpbnB1dFtuYW1lPSdjdXJyZW50UmV2aXNpb25JZCddXCIpO1xuICAgICAgICBpZiAocmV2aXNpb25JbnB1dC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aHJvdyBuZXcgTm9FbGVtZW50RXJyb3IoJ0N1cnJlbnQgcmV2aXNpb24gSUQgaW5wdXQgbm90IGZvdW5kJyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCByZXZpc2lvblZhbHVlID0gcmV2aXNpb25JbnB1dC52YWwoKTtcbiAgICAgICAgY29uc3QgY3VycmVudFJldmlzaW9uSWQgPSBOdW1iZXIucGFyc2VJbnQoU3RyaW5nKHJldmlzaW9uVmFsdWUgPz8gJycpLCAxMCk7XG4gICAgICAgIGlmIChOdW1iZXIuaXNOYU4oY3VycmVudFJldmlzaW9uSWQpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IE5vRWxlbWVudEVycm9yKCdJbnZhbGlkIHJldmlzaW9uIElEIHZhbHVlJyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyDnt6jpm4bjgpLkv53lrZhcbiAgICAgICAgY29uc3QgZWRpdFJlc3VsdCA9IGF3YWl0IHRoaXMudGhyZWFkLnNpdGUuYW1jUmVxdWVzdChbXG4gICAgICAgICAge1xuICAgICAgICAgICAgYWN0aW9uOiAnRm9ydW1BY3Rpb24nLFxuICAgICAgICAgICAgZXZlbnQ6ICdzYXZlRWRpdFBvc3QnLFxuICAgICAgICAgICAgbW9kdWxlTmFtZTogJ0VtcHR5JyxcbiAgICAgICAgICAgIHBvc3RJZDogdGhpcy5pZCxcbiAgICAgICAgICAgIGN1cnJlbnRSZXZpc2lvbklkLFxuICAgICAgICAgICAgdGl0bGU6IHRpdGxlID8/IHRoaXMudGl0bGUsXG4gICAgICAgICAgICBzb3VyY2UsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG5cbiAgICAgICAgaWYgKGVkaXRSZXN1bHQuaXNFcnIoKSkge1xuICAgICAgICAgIHRocm93IGVkaXRSZXN1bHQuZXJyb3I7XG4gICAgICAgIH1cblxuICAgICAgICAvLyDjg63jg7zjgqvjg6vnirbmhYvjgpLmm7TmlrBcbiAgICAgICAgaWYgKHRpdGxlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aGlzLnRpdGxlID0gdGl0bGU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fc291cmNlID0gc291cmNlO1xuICAgICAgfSkoKSxcbiAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBOb0VsZW1lbnRFcnJvciB8fCBlcnJvciBpbnN0YW5jZW9mIExvZ2luUmVxdWlyZWRFcnJvcikge1xuICAgICAgICAgIHJldHVybiBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFVuZXhwZWN0ZWRFcnJvcihgRmFpbGVkIHRvIGVkaXQgcG9zdDogJHtTdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICB0b1N0cmluZygpOiBzdHJpbmcge1xuICAgIHJldHVybiBgRm9ydW1Qb3N0KGlkPSR7dGhpcy5pZH0sIHRpdGxlPSR7dGhpcy50aXRsZX0pYDtcbiAgfVxufVxuXG4vKipcbiAqIOODleOCqeODvOODqeODoOaKleeov+OCs+ODrOOCr+OCt+ODp+ODs1xuICovXG5leHBvcnQgY2xhc3MgRm9ydW1Qb3N0Q29sbGVjdGlvbiBleHRlbmRzIEFycmF5PEZvcnVtUG9zdD4ge1xuICBwdWJsaWMgcmVhZG9ubHkgdGhyZWFkOiBGb3J1bVRocmVhZFJlZjtcblxuICBjb25zdHJ1Y3Rvcih0aHJlYWQ6IEZvcnVtVGhyZWFkUmVmLCBwb3N0cz86IEZvcnVtUG9zdFtdKSB7XG4gICAgc3VwZXIoKTtcbiAgICB0aGlzLnRocmVhZCA9IHRocmVhZDtcbiAgICBpZiAocG9zdHMpIHtcbiAgICAgIHRoaXMucHVzaCguLi5wb3N0cyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIElE44Gn5qSc57SiXG4gICAqIEBwYXJhbSBpZCAtIOaKleeov0lEXG4gICAqIEByZXR1cm5zIOaKleeov++8iOWtmOWcqOOBl+OBquOBhOWgtOWQiOOBr3VuZGVmaW5lZO+8iVxuICAgKi9cbiAgZmluZEJ5SWQoaWQ6IG51bWJlcik6IEZvcnVtUG9zdCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuZmluZCgocG9zdCkgPT4gcG9zdC5pZCA9PT0gaWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhUTUzjgYvjgonmipXnqL/jgpLjg5Hjg7zjgrnjgZnjgovvvIjlhoXpg6jjg6Hjgr3jg4Pjg4nvvIlcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIF9wYXJzZSh0aHJlYWQ6IEZvcnVtVGhyZWFkUmVmLCAkOiBDaGVlcmlvQVBJKTogRm9ydW1Qb3N0W10ge1xuICAgIGNvbnN0IHBvc3RzOiBGb3J1bVBvc3RbXSA9IFtdO1xuXG4gICAgJCgnZGl2LnBvc3QnKS5lYWNoKChfaSwgcG9zdEVsZW0pID0+IHtcbiAgICAgIGNvbnN0ICRwb3N0ID0gJChwb3N0RWxlbSk7XG4gICAgICBjb25zdCBwb3N0SWRBdHRyID0gJHBvc3QuYXR0cignaWQnKTtcbiAgICAgIGlmICghcG9zdElkQXR0cikgcmV0dXJuO1xuXG4gICAgICBjb25zdCBwb3N0SWQgPSBOdW1iZXIucGFyc2VJbnQocG9zdElkQXR0ci5yZXBsYWNlKCdwb3N0LScsICcnKSwgMTApO1xuICAgICAgaWYgKE51bWJlci5pc05hTihwb3N0SWQpKSByZXR1cm47XG5cbiAgICAgIC8vIOimquaKleeov0lE44Gu5Y+W5b6XXG4gICAgICBsZXQgcGFyZW50SWQ6IG51bWJlciB8IG51bGwgPSBudWxsO1xuICAgICAgY29uc3QgJHBhcmVudENvbnRhaW5lciA9ICRwb3N0LnBhcmVudCgpO1xuICAgICAgaWYgKCRwYXJlbnRDb250YWluZXIubGVuZ3RoID4gMCkge1xuICAgICAgICBjb25zdCAkZ3JhbmRwYXJlbnQgPSAkcGFyZW50Q29udGFpbmVyLnBhcmVudCgpO1xuICAgICAgICBpZiAoJGdyYW5kcGFyZW50Lmxlbmd0aCA+IDAgJiYgJGdyYW5kcGFyZW50WzBdPy5uYW1lICE9PSAnYm9keScpIHtcbiAgICAgICAgICBjb25zdCBncmFuZHBhcmVudENsYXNzZXMgPSAkZ3JhbmRwYXJlbnQuYXR0cignY2xhc3MnKSA/PyAnJztcbiAgICAgICAgICBpZiAoZ3JhbmRwYXJlbnRDbGFzc2VzLmluY2x1ZGVzKCdwb3N0LWNvbnRhaW5lcicpKSB7XG4gICAgICAgICAgICBjb25zdCAkcGFyZW50UG9zdCA9ICRncmFuZHBhcmVudC5maW5kKCc+IGRpdi5wb3N0Jyk7XG4gICAgICAgICAgICBpZiAoJHBhcmVudFBvc3QubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICBjb25zdCBwYXJlbnRQb3N0SWRBdHRyID0gJHBhcmVudFBvc3QuYXR0cignaWQnKTtcbiAgICAgICAgICAgICAgaWYgKHBhcmVudFBvc3RJZEF0dHIpIHtcbiAgICAgICAgICAgICAgICBwYXJlbnRJZCA9IE51bWJlci5wYXJzZUludChwYXJlbnRQb3N0SWRBdHRyLnJlcGxhY2UoJ3Bvc3QtJywgJycpLCAxMCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8g44K/44Kk44OI44Or44Go5pys5paH44Gu5Y+W5b6XXG4gICAgICBjb25zdCAkd3JhcHBlciA9ICRwb3N0LmZpbmQoJ2Rpdi5sb25nJyk7XG4gICAgICBpZiAoJHdyYXBwZXIubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgICAgIGNvbnN0ICRoZWFkID0gJHdyYXBwZXIuZmluZCgnZGl2LmhlYWQnKTtcbiAgICAgIGlmICgkaGVhZC5sZW5ndGggPT09IDApIHJldHVybjtcblxuICAgICAgY29uc3QgJHRpdGxlID0gJGhlYWQuZmluZCgnZGl2LnRpdGxlJyk7XG4gICAgICBjb25zdCB0aXRsZSA9ICR0aXRsZS50ZXh0KCkudHJpbSgpO1xuXG4gICAgICBjb25zdCAkY29udGVudCA9ICR3cmFwcGVyLmZpbmQoJ2Rpdi5jb250ZW50Jyk7XG4gICAgICBjb25zdCB0ZXh0ID0gJGNvbnRlbnQuaHRtbCgpID8/ICcnO1xuXG4gICAgICAvLyDmipXnqL/ogIXjgajml6XmmYJcbiAgICAgIGNvbnN0ICRpbmZvID0gJGhlYWQuZmluZCgnZGl2LmluZm8nKTtcbiAgICAgIGlmICgkaW5mby5sZW5ndGggPT09IDApIHJldHVybjtcblxuICAgICAgY29uc3QgJHVzZXJFbGVtID0gJGluZm8uZmluZCgnc3Bhbi5wcmludHVzZXInKTtcbiAgICAgIGlmICgkdXNlckVsZW0ubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgICAgIGNvbnN0IGNyZWF0ZWRCeSA9IHBhcnNlVXNlcih0aHJlYWQuc2l0ZS5jbGllbnQgYXMgQ2xpZW50LCAkdXNlckVsZW0gYXMgQ2hlZXJpbzxBbnlOb2RlPik7XG5cbiAgICAgIGNvbnN0ICRvZGF0ZUVsZW0gPSAkaW5mby5maW5kKCdzcGFuLm9kYXRlJyk7XG4gICAgICBpZiAoJG9kYXRlRWxlbS5sZW5ndGggPT09IDApIHJldHVybjtcblxuICAgICAgY29uc3QgY3JlYXRlZEF0ID0gcGFyc2VPZGF0ZSgkb2RhdGVFbGVtIGFzIENoZWVyaW88QW55Tm9kZT4pID8/IG5ldyBEYXRlKCk7XG5cbiAgICAgIC8vIOe3qOmbhuaDheWgse+8iOWtmOWcqOOBmeOCi+WgtOWQiO+8iVxuICAgICAgbGV0IGVkaXRlZEJ5OiBBYnN0cmFjdFVzZXIgfCBudWxsID0gbnVsbDtcbiAgICAgIGxldCBlZGl0ZWRBdDogRGF0ZSB8IG51bGwgPSBudWxsO1xuICAgICAgY29uc3QgJGNoYW5nZXMgPSAkd3JhcHBlci5maW5kKCdkaXYuY2hhbmdlcycpO1xuICAgICAgaWYgKCRjaGFuZ2VzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgY29uc3QgJGVkaXRVc2VyRWxlbSA9ICRjaGFuZ2VzLmZpbmQoJ3NwYW4ucHJpbnR1c2VyJyk7XG4gICAgICAgIGNvbnN0ICRlZGl0T2RhdGVFbGVtID0gJGNoYW5nZXMuZmluZCgnc3Bhbi5vZGF0ZScpO1xuICAgICAgICBpZiAoJGVkaXRVc2VyRWxlbS5sZW5ndGggPiAwICYmICRlZGl0T2RhdGVFbGVtLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICBlZGl0ZWRCeSA9IHBhcnNlVXNlcih0aHJlYWQuc2l0ZS5jbGllbnQgYXMgQ2xpZW50LCAkZWRpdFVzZXJFbGVtIGFzIENoZWVyaW88QW55Tm9kZT4pO1xuICAgICAgICAgIGVkaXRlZEF0ID0gcGFyc2VPZGF0ZSgkZWRpdE9kYXRlRWxlbSBhcyBDaGVlcmlvPEFueU5vZGU+KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBwb3N0cy5wdXNoKFxuICAgICAgICBuZXcgRm9ydW1Qb3N0KHtcbiAgICAgICAgICB0aHJlYWQsXG4gICAgICAgICAgaWQ6IHBvc3RJZCxcbiAgICAgICAgICB0aXRsZSxcbiAgICAgICAgICB0ZXh0LFxuICAgICAgICAgIGVsZW1lbnQ6IHBvc3RFbGVtIGFzIEVsZW1lbnQsXG4gICAgICAgICAgY3JlYXRlZEJ5LFxuICAgICAgICAgIGNyZWF0ZWRBdCxcbiAgICAgICAgICBlZGl0ZWRCeSxcbiAgICAgICAgICBlZGl0ZWRBdCxcbiAgICAgICAgICBwYXJlbnRJZCxcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gcG9zdHM7XG4gIH1cblxuICAvKipcbiAgICog44K544Os44OD44OJ5YaF44Gu5YWo5oqV56i/44KS5Y+W5b6XXG4gICAqL1xuICBzdGF0aWMgYWNxdWlyZUFsbEluVGhyZWFkKHRocmVhZDogRm9ydW1UaHJlYWRSZWYpOiBXaWtpZG90UmVzdWx0QXN5bmM8Rm9ydW1Qb3N0Q29sbGVjdGlvbj4ge1xuICAgIHJldHVybiBmcm9tUHJvbWlzZShcbiAgICAgIChhc3luYyAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBvc3RzOiBGb3J1bVBvc3RbXSA9IFtdO1xuXG4gICAgICAgIGNvbnN0IGZpcnN0UmVzdWx0ID0gYXdhaXQgdGhyZWFkLnNpdGUuYW1jUmVxdWVzdChbXG4gICAgICAgICAge1xuICAgICAgICAgICAgbW9kdWxlTmFtZTogJ2ZvcnVtL0ZvcnVtVmlld1RocmVhZFBvc3RzTW9kdWxlJyxcbiAgICAgICAgICAgIHBhZ2VObzogJzEnLFxuICAgICAgICAgICAgdDogU3RyaW5nKHRocmVhZC5pZCksXG4gICAgICAgICAgfSxcbiAgICAgICAgXSk7XG5cbiAgICAgICAgaWYgKGZpcnN0UmVzdWx0LmlzRXJyKCkpIHtcbiAgICAgICAgICB0aHJvdyBmaXJzdFJlc3VsdC5lcnJvcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGZpcnN0UmVzcG9uc2UgPSBmaXJzdFJlc3VsdC52YWx1ZVswXTtcbiAgICAgICAgaWYgKCFmaXJzdFJlc3BvbnNlKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IE5vRWxlbWVudEVycm9yKCdFbXB0eSByZXNwb25zZScpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZmlyc3RCb2R5ID0gU3RyaW5nKGZpcnN0UmVzcG9uc2UuYm9keSA/PyAnJyk7XG4gICAgICAgIGNvbnN0ICRmaXJzdCA9IGNoZWVyaW8ubG9hZChmaXJzdEJvZHkpO1xuXG4gICAgICAgIHBvc3RzLnB1c2goLi4uRm9ydW1Qb3N0Q29sbGVjdGlvbi5fcGFyc2UodGhyZWFkLCAkZmlyc3QpKTtcblxuICAgICAgICAvLyDjg5rjg7zjgrjjg43jg7zjgrfjg6fjg7Pnorroqo1cbiAgICAgICAgY29uc3QgJHBhZ2VyID0gJGZpcnN0KCdkaXYucGFnZXInKTtcbiAgICAgICAgaWYgKCRwYWdlci5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICByZXR1cm4gbmV3IEZvcnVtUG9zdENvbGxlY3Rpb24odGhyZWFkLCBwb3N0cyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCAkcGFnZXJUYXJnZXRzID0gJHBhZ2VyLmZpbmQoJ3NwYW4udGFyZ2V0Jyk7XG4gICAgICAgIGlmICgkcGFnZXJUYXJnZXRzLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgICByZXR1cm4gbmV3IEZvcnVtUG9zdENvbGxlY3Rpb24odGhyZWFkLCBwb3N0cyk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyDmnIDlvozjgYvjgoky55Wq55uu44Gu44Oa44O844K444Oq44Oz44Kv44GL44KJ5pyA57WC44Oa44O844K455Wq5Y+344KS5Y+W5b6XXG4gICAgICAgIGNvbnN0IGxhc3RQYWdlVGV4dCA9ICRwYWdlclRhcmdldHNcbiAgICAgICAgICAuZXEoJHBhZ2VyVGFyZ2V0cy5sZW5ndGggLSAyKVxuICAgICAgICAgIC50ZXh0KClcbiAgICAgICAgICAudHJpbSgpO1xuICAgICAgICBjb25zdCBsYXN0UGFnZSA9IE51bWJlci5wYXJzZUludChsYXN0UGFnZVRleHQsIDEwKTtcbiAgICAgICAgaWYgKE51bWJlci5pc05hTihsYXN0UGFnZSkgfHwgbGFzdFBhZ2UgPD0gMSkge1xuICAgICAgICAgIHJldHVybiBuZXcgRm9ydW1Qb3N0Q29sbGVjdGlvbih0aHJlYWQsIHBvc3RzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIOaui+OCiuOBruODmuODvOOCuOOCkuWPluW+l1xuICAgICAgICBjb25zdCBib2RpZXM6IHsgbW9kdWxlTmFtZTogc3RyaW5nOyBwYWdlTm86IHN0cmluZzsgdDogc3RyaW5nIH1bXSA9IFtdO1xuICAgICAgICBmb3IgKGxldCBwYWdlID0gMjsgcGFnZSA8PSBsYXN0UGFnZTsgcGFnZSsrKSB7XG4gICAgICAgICAgYm9kaWVzLnB1c2goe1xuICAgICAgICAgICAgbW9kdWxlTmFtZTogJ2ZvcnVtL0ZvcnVtVmlld1RocmVhZFBvc3RzTW9kdWxlJyxcbiAgICAgICAgICAgIHBhZ2VObzogU3RyaW5nKHBhZ2UpLFxuICAgICAgICAgICAgdDogU3RyaW5nKHRocmVhZC5pZCksXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBhZGRpdGlvbmFsUmVzdWx0cyA9IGF3YWl0IHRocmVhZC5zaXRlLmFtY1JlcXVlc3QoYm9kaWVzKTtcbiAgICAgICAgaWYgKGFkZGl0aW9uYWxSZXN1bHRzLmlzRXJyKCkpIHtcbiAgICAgICAgICB0aHJvdyBhZGRpdGlvbmFsUmVzdWx0cy5lcnJvcjtcbiAgICAgICAgfVxuXG4gICAgICAgIGZvciAoY29uc3QgcmVzcG9uc2Ugb2YgYWRkaXRpb25hbFJlc3VsdHMudmFsdWUpIHtcbiAgICAgICAgICBjb25zdCBib2R5ID0gU3RyaW5nKHJlc3BvbnNlPy5ib2R5ID8/ICcnKTtcbiAgICAgICAgICBjb25zdCAkID0gY2hlZXJpby5sb2FkKGJvZHkpO1xuICAgICAgICAgIHBvc3RzLnB1c2goLi4uRm9ydW1Qb3N0Q29sbGVjdGlvbi5fcGFyc2UodGhyZWFkLCAkKSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gbmV3IEZvcnVtUG9zdENvbGxlY3Rpb24odGhyZWFkLCBwb3N0cyk7XG4gICAgICB9KSgpLFxuICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIE5vRWxlbWVudEVycm9yKSByZXR1cm4gZXJyb3I7XG4gICAgICAgIHJldHVybiBuZXcgVW5leHBlY3RlZEVycm9yKGBGYWlsZWQgdG8gYWNxdWlyZSBwb3N0czogJHtTdHJpbmcoZXJyb3IpfWApO1xuICAgICAgfVxuICAgICk7XG4gIH1cbn1cbiIKICBdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7QUFBQTs7O0FDbUJBLFNBQVMsWUFBWSxDQUNuQixLQUNnRTtBQUFBLEVBQ2hFLElBQUksSUFBSTtBQUFBLElBQVEsT0FBTyxJQUFJO0FBQUEsRUFDM0IsSUFBSSxJQUFJLE1BQU07QUFBQSxJQUFRLE9BQU8sSUFBSSxLQUFLO0FBQUEsRUFDdEMsSUFBSSxJQUFJLFFBQVEsTUFBTTtBQUFBLElBQVEsT0FBTyxJQUFJLE9BQU8sS0FBSztBQUFB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LFlBQVk7QUFBQSxNQUNYLE1BQU0sU0FBUyxNQUFNLEtBQUssV0FBVztBQUFBLFFBQ25DO0FBQUEsVUFDRSxZQUFZO0FBQUEsVUFDWixRQUFRO0FBQUEsUUFDVjtBQUFBLE1BQ0YsQ0FBQztBQUFBLE1BRUQsSUFBSSxPQUFPLE1BQU0sR0FBRztBQUFBLFFBQ2xCLE1BQU0sT0FBTztBQUFBLE1BQ2Y7QUFBQSxNQUVBLE1BQU0sV0FBVyxPQUFPLE1BQU07QUFBQSxNQUM5QixJQUFJLENBQUMsVUFBVTtBQUFBLFFBQ2IsTUFBTSxJQUFJLGVBQWUsZ0JBQWdCO0FBQUEsTUFDM0M7QUFBQSxNQUVBLE1BQU0sT0FBTyxPQUFPLFNBQVMsUUFBUSxFQUFFO0FBQUEsTUFDdkMsTUFBTSxJQUFZLGNBQUssSUFBSTtBQUFBLE1BRTNCLE1BQU0sYUFBOEIsQ0FBQztBQUFBLE1BRXJDLEVBQUUsa0JBQWtCLEVBQUUsS0FBSyxDQUFDLElBQUksUUFBUTtBQUFBLFFBQ3RDLE1BQU0sT0FBTyxFQUFFLEdBQUc7QUFBQSxRQUNsQixNQUFNLFdBQVcsS0FBSyxLQUFLLFNBQVM7QUFBQSxRQUNwQyxNQUFNLGVBQWUsU0FBUyxLQUFLLEdBQUc7QUFBQSxRQUN0QyxNQUFNLE9BQU8sYUFBYSxLQUFLLE1BQU0sS0FBSztBQUFBLFFBRTFDLE1BQU0sa0JBQWtCLEtBQUssTUFBTSxTQUFTO0FBQUEsUUFDNUMsSUFBSSxDQUFDLGtCQUFrQjtBQUFBLFVBQUk7QUFBQSxRQUUzQixNQUFNLGFBQWEsT0FBTyxTQUFTLGdCQUFnQixJQUFJLEVBQUU7QUFBQSxRQUN6RCxNQUFNLFFBQVEsYUFBYSxLQUFLLEVBQUUsS0FBSztBQUFBLFFBQ3ZDLE1BQU0sY0FBYyxTQUFTLEtBQUssaUJBQWlCLEVBQUUsS0FBSyxFQUFFLEtBQUs7QUFBQSxRQUNqRSxNQUFNLGVBQWUsT0FBTyxTQUFTLEtBQUssS0FBSyxZQUFZLEVBQUUsS0FBSyxFQUFFLEtBQUssR0FBRyxFQUFFLEtBQUs7QUFBQSxRQUNuRixNQUFNLGFBQWEsT0FBTyxTQUFTLEtBQUssS0FBSyxVQUFVLEVBQUUsS0FBSyxFQUFFLEtBQUssR0FBRyxFQUFFLEtBQUs7QUFBQSxRQUUvRSxXQUFXLEtBQ1QsSUFBSSxjQUFjO0FBQUEsVUFDaEI7QUFBQSxVQUNBLElBQUk7QUFBQSxVQUNKO0FBQUEsVUFDQTtBQUFBLFVBQ0E7QUFBQSxVQUNBO0FBQUEsUUFDRixDQUFDLENBQ0g7QUFBQSxPQUNEO0FBQUEsTUFFRCxPQUFPLElBQUksd0JBQXdCLE1BQU0sVUFBVTtBQUFBLE9BQ2xELEdBQ0gsQ0FBQyxVQUFVO0FBQUEsTUFDVCxJQUFJLGlCQUFpQjtBQUFBLFFBQWdCLE9BQU87QUFBQSxNQUM1QyxPQUFPLElBQUksZ0JBQWdCLGlDQUFpQyxPQUFPLEtBQUssR0FBRztBQUFBLEtBRS9FO0FBQUE7QUFFSjsiLAogICJkZWJ1Z0lkIjogIkIxNzQ4RUE1NzZGOTZBMzE2NDc1NkUyMTY0NzU2RTIxIiwKICAibmFtZXMiOiBbXQp9