@banta/sdk 4.6.27 → 4.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/{esm2015/banta-sdk.js → esm2020/banta-sdk.mjs} +0 -0
- package/{esm2015/lib/attachment-scraper.js → esm2020/lib/attachment-scraper.mjs} +0 -0
- package/esm2020/lib/banta/banta.component.mjs +204 -0
- package/esm2020/lib/banta-logo.component.mjs +11 -0
- package/esm2020/lib/banta-sdk.module.mjs +144 -0
- package/esm2020/lib/chat/banta-chat/banta-chat.component.mjs +185 -0
- package/esm2020/lib/chat/chat-message/chat-message.component.mjs +62 -0
- package/esm2020/lib/chat/chat-view/chat-view.component.mjs +170 -0
- package/esm2020/lib/chat/chat.module.mjs +51 -0
- package/{esm2015/lib/chat/index.js → esm2020/lib/chat/index.mjs} +0 -0
- package/esm2020/lib/chat/live-chat-message.component.mjs +80 -0
- package/{esm2015/lib/chat-backend-base.js → esm2020/lib/chat-backend-base.mjs} +0 -0
- package/esm2020/lib/chat-backend.mjs +83 -0
- package/{esm2015/lib/chat-source-base.js → esm2020/lib/chat-source-base.mjs} +0 -0
- package/esm2020/lib/chat-source.mjs +169 -0
- package/esm2020/lib/comments/attachment-button/attachment-button.component.mjs +69 -0
- package/esm2020/lib/comments/attachment-scraper.directive.mjs +107 -0
- package/esm2020/lib/comments/banta-comments/banta-comments.component.mjs +666 -0
- package/esm2020/lib/comments/comment/comment.component.mjs +217 -0
- package/esm2020/lib/comments/comment-field/comment-field.component.mjs +377 -0
- package/esm2020/lib/comments/comment-sort/comment-sort.component.mjs +37 -0
- package/esm2020/lib/comments/comment-view/comment-view.component.mjs +379 -0
- package/esm2020/lib/comments/comments.module.mjs +111 -0
- package/{esm2015/lib/comments/index.js → esm2020/lib/comments/index.mjs} +0 -0
- package/esm2020/lib/comments/live-comment.component.mjs +80 -0
- package/esm2020/lib/comments/reply-send-options.directive.mjs +13 -0
- package/esm2020/lib/common/attachment/attachment.component.mjs +113 -0
- package/esm2020/lib/common/attachments/attachments.component.mjs +72 -0
- package/esm2020/lib/common/common.module.mjs +59 -0
- package/{esm2015/lib/common/index.js → esm2020/lib/common/index.mjs} +0 -0
- package/{esm2015/lib/common/lazy-connection.js → esm2020/lib/common/lazy-connection.mjs} +0 -0
- package/esm2020/lib/common/lightbox/lightbox.component.mjs +31 -0
- package/esm2020/lib/common/markdown-to-html.pipe.mjs +76 -0
- package/esm2020/lib/common/mention-linker.pipe.mjs +35 -0
- package/esm2020/lib/common/timestamp.component.mjs +113 -0
- package/esm2020/lib/common/trust-resource-url.pipe.mjs +22 -0
- package/esm2020/lib/emoji/emoji-selector-button.component.mjs +113 -0
- package/esm2020/lib/emoji/emoji-selector-panel/emoji-selector-panel.component.mjs +88 -0
- package/esm2020/lib/emoji/emoji.module.mjs +55 -0
- package/{esm2015/lib/emoji/emojis.js → esm2020/lib/emoji/emojis.mjs} +0 -0
- package/{esm2015/lib/emoji/index.js → esm2020/lib/emoji/index.mjs} +0 -0
- package/esm2020/lib/giphy-attachments.mjs +16 -0
- package/{esm2015/lib/index.js → esm2020/lib/index.mjs} +0 -0
- package/esm2020/lib/live-message.component.mjs +96 -0
- package/{esm2015/lib/message-menu-item.js → esm2020/lib/message-menu-item.mjs} +0 -0
- package/{esm2015/lib/sdk-options.js → esm2020/lib/sdk-options.mjs} +0 -0
- package/esm2020/lib/tweet-attachments.mjs +13 -0
- package/esm2020/lib/url-attachments.mjs +42 -0
- package/esm2020/lib/youtube-attachments.mjs +22 -0
- package/{esm2015/public-api.js → esm2020/public-api.mjs} +1 -1
- package/fesm2015/{banta-sdk.js → banta-sdk.mjs} +2559 -2239
- package/fesm2015/banta-sdk.mjs.map +1 -0
- package/fesm2020/banta-sdk.mjs +10490 -0
- package/fesm2020/banta-sdk.mjs.map +1 -0
- package/{banta-sdk.d.ts → index.d.ts} +1 -0
- package/lib/banta/banta.component.d.ts +3 -0
- package/lib/banta-logo.component.d.ts +3 -0
- package/lib/banta-sdk.module.d.ts +24 -0
- package/lib/chat/banta-chat/banta-chat.component.d.ts +3 -0
- package/lib/chat/chat-message/chat-message.component.d.ts +3 -0
- package/lib/chat/chat-view/chat-view.component.d.ts +3 -0
- package/lib/chat/chat.module.d.ts +13 -0
- package/lib/chat/live-chat-message.component.d.ts +3 -0
- package/lib/chat-backend.d.ts +3 -0
- package/lib/comments/attachment-button/attachment-button.component.d.ts +3 -0
- package/lib/comments/attachment-scraper.directive.d.ts +3 -0
- package/lib/comments/banta-comments/banta-comments.component.d.ts +3 -0
- package/lib/comments/comment/comment.component.d.ts +3 -0
- package/lib/comments/comment-field/comment-field.component.d.ts +3 -0
- package/lib/comments/comment-sort/comment-sort.component.d.ts +3 -0
- package/lib/comments/comment-view/comment-view.component.d.ts +3 -0
- package/lib/comments/comments.module.d.ts +28 -0
- package/lib/comments/live-comment.component.d.ts +3 -0
- package/lib/comments/reply-send-options.directive.d.ts +3 -0
- package/lib/common/attachment/attachment.component.d.ts +3 -0
- package/lib/common/attachments/attachments.component.d.ts +3 -0
- package/lib/common/common.module.d.ts +15 -0
- package/lib/common/lightbox/lightbox.component.d.ts +3 -0
- package/lib/common/markdown-to-html.pipe.d.ts +3 -0
- package/lib/common/mention-linker.pipe.d.ts +3 -0
- package/lib/common/timestamp.component.d.ts +3 -0
- package/lib/common/trust-resource-url.pipe.d.ts +3 -0
- package/lib/emoji/emoji-selector-button.component.d.ts +3 -0
- package/lib/emoji/emoji-selector-panel/emoji-selector-panel.component.d.ts +3 -0
- package/lib/emoji/emoji.module.d.ts +14 -0
- package/lib/live-message.component.d.ts +3 -0
- package/lib/url-attachments.d.ts +3 -0
- package/package.json +22 -10
- package/banta-sdk.metadata.json +0 -1
- package/bundles/banta-sdk.umd.js +0 -11913
- package/bundles/banta-sdk.umd.js.map +0 -1
- package/esm2015/lib/banta/banta.component.js +0 -200
- package/esm2015/lib/banta-logo.component.js +0 -20
- package/esm2015/lib/banta-sdk.module.js +0 -98
- package/esm2015/lib/chat/banta-chat/banta-chat.component.js +0 -174
- package/esm2015/lib/chat/chat-message/chat-message.component.js +0 -56
- package/esm2015/lib/chat/chat-view/chat-view.component.js +0 -167
- package/esm2015/lib/chat/chat.module.js +0 -32
- package/esm2015/lib/chat/live-chat-message.component.js +0 -71
- package/esm2015/lib/chat-backend.js +0 -92
- package/esm2015/lib/chat-source.js +0 -199
- package/esm2015/lib/comments/attachment-button/attachment-button.component.js +0 -70
- package/esm2015/lib/comments/attachment-scraper.directive.js +0 -109
- package/esm2015/lib/comments/banta-comments/banta-comments.component.js +0 -678
- package/esm2015/lib/comments/comment/comment.component.js +0 -186
- package/esm2015/lib/comments/comment-field/comment-field.component.js +0 -350
- package/esm2015/lib/comments/comment-sort/comment-sort.component.js +0 -34
- package/esm2015/lib/comments/comment-view/comment-view.component.js +0 -364
- package/esm2015/lib/comments/comments.module.js +0 -62
- package/esm2015/lib/comments/live-comment.component.js +0 -71
- package/esm2015/lib/comments/reply-send-options.directive.js +0 -9
- package/esm2015/lib/common/attachment/attachment.component.js +0 -105
- package/esm2015/lib/common/attachments/attachments.component.js +0 -65
- package/esm2015/lib/common/common.module.js +0 -36
- package/esm2015/lib/common/lightbox/lightbox.component.js +0 -30
- package/esm2015/lib/common/markdown-to-html.pipe.js +0 -75
- package/esm2015/lib/common/mention-linker.pipe.js +0 -31
- package/esm2015/lib/common/timestamp.component.js +0 -106
- package/esm2015/lib/common/trust-resource-url.pipe.js +0 -21
- package/esm2015/lib/emoji/emoji-selector-button.component.js +0 -107
- package/esm2015/lib/emoji/emoji-selector-panel/emoji-selector-panel.component.js +0 -86
- package/esm2015/lib/emoji/emoji.module.js +0 -34
- package/esm2015/lib/giphy-attachments.js +0 -20
- package/esm2015/lib/live-message.component.js +0 -74
- package/esm2015/lib/tweet-attachments.js +0 -16
- package/esm2015/lib/url-attachments.js +0 -46
- package/esm2015/lib/youtube-attachments.js +0 -25
- package/fesm2015/banta-sdk.js.map +0 -1
|
@@ -1,678 +0,0 @@
|
|
|
1
|
-
/// <reference types="@types/resize-observer-browser" />
|
|
2
|
-
import { __awaiter } from "tslib";
|
|
3
|
-
import { Component, ContentChild, ElementRef, HostBinding, Input, NgZone, Output, TemplateRef, ViewChild, ViewChildren } from '@angular/core';
|
|
4
|
-
import { CommentsOrder } from '@banta/common';
|
|
5
|
-
import { Subject, Subscription } from 'rxjs';
|
|
6
|
-
import { take } from 'rxjs/operators';
|
|
7
|
-
import { ActivatedRoute } from '@angular/router';
|
|
8
|
-
import { ChatBackendBase } from '../../chat-backend-base';
|
|
9
|
-
import { MatSnackBar } from '@angular/material/snack-bar';
|
|
10
|
-
import { BantaReplySendOptionsDirective } from '../reply-send-options.directive';
|
|
11
|
-
import { CommentViewComponent } from '../comment-view/comment-view.component';
|
|
12
|
-
/**
|
|
13
|
-
* Comments component
|
|
14
|
-
*/
|
|
15
|
-
export class BantaCommentsComponent {
|
|
16
|
-
constructor(backend, elementRef, activatedRoute, matSnackBar, ngZone) {
|
|
17
|
-
this.backend = backend;
|
|
18
|
-
this.elementRef = elementRef;
|
|
19
|
-
this.activatedRoute = activatedRoute;
|
|
20
|
-
this.matSnackBar = matSnackBar;
|
|
21
|
-
this.ngZone = ngZone;
|
|
22
|
-
this.isMobileSized = false;
|
|
23
|
-
this.viewReady = new Promise(r => this.markViewReady = r);
|
|
24
|
-
// Loading Screen
|
|
25
|
-
this._loadingMessage = '';
|
|
26
|
-
this.loadingMessageVisible = false;
|
|
27
|
-
this.loading = true;
|
|
28
|
-
this.showLoadingScreen = false;
|
|
29
|
-
this.customMenuItems = [];
|
|
30
|
-
this._loadingMessageIndex = 0;
|
|
31
|
-
this.maxCommentLength = 1500;
|
|
32
|
-
this.loadingMessages = [
|
|
33
|
-
`Just a second...`,
|
|
34
|
-
`We're definitely working on it.`,
|
|
35
|
-
`There's no need to refresh.`,
|
|
36
|
-
`It's definitely worth the wait!`,
|
|
37
|
-
`This has never happened before.`,
|
|
38
|
-
`We'll keep trying, but it's not looking great.
|
|
39
|
-
Commenting & chat services may be down.
|
|
40
|
-
If you continue to experience issues, please contact support.
|
|
41
|
-
`
|
|
42
|
-
];
|
|
43
|
-
this.useInlineReplies = true;
|
|
44
|
-
this.loaded = new Promise(r => this.markLoaded = r);
|
|
45
|
-
// Properties
|
|
46
|
-
this._signInSelected = new Subject();
|
|
47
|
-
this._permissionDeniedError = new Subject();
|
|
48
|
-
this._editAvatarSelected = new Subject();
|
|
49
|
-
this._upvoted = new Subject();
|
|
50
|
-
this._reported = new Subject();
|
|
51
|
-
this._selected = new Subject();
|
|
52
|
-
this._userSelected = new Subject();
|
|
53
|
-
this._shared = new Subject();
|
|
54
|
-
this._usernameSelected = new Subject();
|
|
55
|
-
this._avatarSelected = new Subject();
|
|
56
|
-
/**
|
|
57
|
-
* Track whether we created this source. If we did not (ie it was passed in from the caller),
|
|
58
|
-
* then we are not responsible for calling close(). If we do own it though, we will call close()
|
|
59
|
-
* when we are done with it.
|
|
60
|
-
*/
|
|
61
|
-
this._sourceIsOwned = false;
|
|
62
|
-
this._subs = new Subscription();
|
|
63
|
-
this._sortOrder = CommentsOrder.NEWEST;
|
|
64
|
-
this.selectedMessageVisible = false;
|
|
65
|
-
// Inputs
|
|
66
|
-
this.signInLabel = 'Sign In';
|
|
67
|
-
this.sendLabel = 'Send';
|
|
68
|
-
this.replyLabel = 'Reply';
|
|
69
|
-
this.sendingLabel = 'Sending';
|
|
70
|
-
this.permissionDeniedLabel = 'Send';
|
|
71
|
-
this.postCommentLabel = 'Post a comment';
|
|
72
|
-
this.postReplyLabel = 'Post a reply';
|
|
73
|
-
this.allowAttachments = true;
|
|
74
|
-
this.maxVisibleMessages = 20;
|
|
75
|
-
this.genericAvatarUrl = `https://gravatar.com/avatar/${Date.now().toString(16)}?s=512&d=robohash`;
|
|
76
|
-
this.participants = [];
|
|
77
|
-
this.hashtags = [
|
|
78
|
-
{ hashtag: 'error', description: 'Cause an error' },
|
|
79
|
-
{ hashtag: 'timeout', description: 'Cause a slow timeout error' },
|
|
80
|
-
{ hashtag: 'slow', description: 'Be slow when this message is posted' },
|
|
81
|
-
];
|
|
82
|
-
this.loadingSharedComment = false;
|
|
83
|
-
this.sharedCommentMissing = false;
|
|
84
|
-
this.sendMessage = (message) => __awaiter(this, void 0, void 0, function* () {
|
|
85
|
-
var _a;
|
|
86
|
-
try {
|
|
87
|
-
const intercept = yield ((_a = this.shouldInterceptMessageSend) === null || _a === void 0 ? void 0 : _a.call(this, message, this.source));
|
|
88
|
-
if (!intercept) {
|
|
89
|
-
yield this.source.send(message);
|
|
90
|
-
}
|
|
91
|
-
if (this.source.sortOrder !== CommentsOrder.NEWEST) {
|
|
92
|
-
this.sortOrder = CommentsOrder.NEWEST;
|
|
93
|
-
}
|
|
94
|
-
return true;
|
|
95
|
-
}
|
|
96
|
-
catch (e) {
|
|
97
|
-
this.handleBackendException(e, 'Could not send: ');
|
|
98
|
-
}
|
|
99
|
-
});
|
|
100
|
-
this.sendReply = (message) => __awaiter(this, void 0, void 0, function* () {
|
|
101
|
-
var _b;
|
|
102
|
-
try {
|
|
103
|
-
const intercept = yield ((_b = this.shouldInterceptMessageSend) === null || _b === void 0 ? void 0 : _b.call(this, message, this.selectedMessageThread));
|
|
104
|
-
if (!intercept) {
|
|
105
|
-
yield this.selectedMessageThread.send(message);
|
|
106
|
-
}
|
|
107
|
-
return true;
|
|
108
|
-
}
|
|
109
|
-
catch (e) {
|
|
110
|
-
this.handleBackendException(e, 'Could not send reply: ');
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
}
|
|
114
|
-
get element() {
|
|
115
|
-
return this.elementRef.nativeElement;
|
|
116
|
-
}
|
|
117
|
-
handleBackendExceptionAsAlert(e, prefix = '') {
|
|
118
|
-
try {
|
|
119
|
-
this.handleBackendException(e, prefix);
|
|
120
|
-
}
|
|
121
|
-
catch (e) {
|
|
122
|
-
alert(e.message);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
handleBackendException(e, prefix = '') {
|
|
126
|
-
let errorMessage = e.message;
|
|
127
|
-
if (errorMessage.startsWith('permission-denied|')) {
|
|
128
|
-
errorMessage = errorMessage.replace(/^permission-denied\|/, '');
|
|
129
|
-
if (errorMessage.startsWith(`app-handle|`)) {
|
|
130
|
-
// If this is an error during authorizeAction on the backend, pass control to the user-provided
|
|
131
|
-
// permission-denied handler.
|
|
132
|
-
this.sendPermissionDenied(errorMessage.replace(/^app-handle\|/, ''));
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
throw new Error(`${prefix}${errorMessage}`);
|
|
137
|
-
}
|
|
138
|
-
// Lifecycle Events / Initialization
|
|
139
|
-
ngOnInit() {
|
|
140
|
-
this._subs.add(this.backend.userChanged.subscribe(user => this.user = user));
|
|
141
|
-
this.startLoading();
|
|
142
|
-
if (typeof window !== 'undefined') {
|
|
143
|
-
let queryString = window.location.search.substring(1);
|
|
144
|
-
let query = queryString.split('&')
|
|
145
|
-
.map(s => s.split('='))
|
|
146
|
-
.reduce((o, [k, v]) => (o[decodeURIComponent(k)] = decodeURIComponent(v), o), {});
|
|
147
|
-
const commentID = query['comment'];
|
|
148
|
-
if (commentID) {
|
|
149
|
-
this.sharedCommentID = commentID;
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
ngAfterViewInit() {
|
|
154
|
-
if (typeof window !== 'undefined') {
|
|
155
|
-
let callback = () => {
|
|
156
|
-
let size = this.elementRef.nativeElement.getBoundingClientRect();
|
|
157
|
-
this.ngZone.run(() => {
|
|
158
|
-
setTimeout(() => {
|
|
159
|
-
this.width = size.width;
|
|
160
|
-
this.height = size.height;
|
|
161
|
-
this.isMobileSized = this.width < 500;
|
|
162
|
-
});
|
|
163
|
-
});
|
|
164
|
-
};
|
|
165
|
-
if (typeof ResizeObserver !== 'undefined') {
|
|
166
|
-
this.resizeObserver = new ResizeObserver(callback);
|
|
167
|
-
this.resizeObserver.observe(this.elementRef.nativeElement);
|
|
168
|
-
}
|
|
169
|
-
else {
|
|
170
|
-
// One check is better than nothing!
|
|
171
|
-
setTimeout(() => {
|
|
172
|
-
this.width = this.elementRef.nativeElement.clientWidth;
|
|
173
|
-
this.height = this.elementRef.nativeElement.clientHeight;
|
|
174
|
-
this.isMobileSized = this.width < 500;
|
|
175
|
-
}, 1000);
|
|
176
|
-
}
|
|
177
|
-
callback();
|
|
178
|
-
}
|
|
179
|
-
this.markViewReady();
|
|
180
|
-
}
|
|
181
|
-
ngOnDestroy() {
|
|
182
|
-
this._subs.unsubscribe();
|
|
183
|
-
if (this.resizeObserver)
|
|
184
|
-
this.resizeObserver.disconnect();
|
|
185
|
-
}
|
|
186
|
-
setSourceFromTopicID(topicID) {
|
|
187
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
188
|
-
if (typeof window === 'undefined')
|
|
189
|
-
return;
|
|
190
|
-
setTimeout(() => __awaiter(this, void 0, void 0, function* () {
|
|
191
|
-
console.log(`[banta-comments] Subscribing to topic source '${topicID}'`);
|
|
192
|
-
this.source = yield this.backend.getSourceForTopic(topicID, { sortOrder: this.sortOrder });
|
|
193
|
-
this._sourceIsOwned = true;
|
|
194
|
-
}));
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
get loadingMessage() {
|
|
198
|
-
return this._loadingMessage;
|
|
199
|
-
}
|
|
200
|
-
set loadingMessage(value) {
|
|
201
|
-
this.loadingMessageVisible = false;
|
|
202
|
-
setTimeout(() => {
|
|
203
|
-
this._loadingMessage = value;
|
|
204
|
-
this._loadingMessage = value;
|
|
205
|
-
setTimeout(() => {
|
|
206
|
-
this.loadingMessageVisible = true;
|
|
207
|
-
});
|
|
208
|
-
}, 500);
|
|
209
|
-
}
|
|
210
|
-
startLoading() {
|
|
211
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
212
|
-
this.loadingStartedAt = this.messageChangedAt = Date.now();
|
|
213
|
-
if (this.updateLoading())
|
|
214
|
-
return;
|
|
215
|
-
yield new Promise(resolve => setTimeout(() => resolve(), 100));
|
|
216
|
-
if (this.updateLoading())
|
|
217
|
-
return;
|
|
218
|
-
yield new Promise(resolve => setTimeout(() => resolve(), 250));
|
|
219
|
-
if (this.updateLoading())
|
|
220
|
-
return;
|
|
221
|
-
yield new Promise(resolve => setTimeout(() => resolve(), 500));
|
|
222
|
-
if (this.updateLoading())
|
|
223
|
-
return;
|
|
224
|
-
console.log(`[Banta] Loading is taking a long time! Showing loading screen.`);
|
|
225
|
-
this.showLoadingScreen = true;
|
|
226
|
-
if (typeof window !== 'undefined')
|
|
227
|
-
this._loadingTimer = setInterval(() => this.updateLoading(), 1000);
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
/**
|
|
231
|
-
* Attempts to find the CommentComponent that corresponds to the given ChatMessage.
|
|
232
|
-
* The ChatMessage could be a top-level message in this conversation, or a reply,
|
|
233
|
-
* but note that a CommentComponent will only exist for a reply if the user has
|
|
234
|
-
* the relevant reply thread open.
|
|
235
|
-
* @param message The message to look for
|
|
236
|
-
*/
|
|
237
|
-
getCommentComponentForMessage(message) {
|
|
238
|
-
var _a;
|
|
239
|
-
if (message.parentMessageId)
|
|
240
|
-
return (_a = this.threadView) === null || _a === void 0 ? void 0 : _a.getCommentComponentForMessage(message);
|
|
241
|
-
else
|
|
242
|
-
return this.commentView.getCommentComponentForMessage(message);
|
|
243
|
-
}
|
|
244
|
-
/**
|
|
245
|
-
* Access the CommentViewComponent corresponding to the currently open reply thread.
|
|
246
|
-
* This is not the top level comments, but instead the reply thread that the user has
|
|
247
|
-
* opened (only one set of replies can be open at a time).
|
|
248
|
-
*
|
|
249
|
-
* For details about what CommentViewComponent affords you, see the commentView property.
|
|
250
|
-
*/
|
|
251
|
-
get threadView() {
|
|
252
|
-
return Array.from(this.threadViewQuery).filter(x => x !== this.commentView)[0];
|
|
253
|
-
}
|
|
254
|
-
waitForThreadView() {
|
|
255
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
256
|
-
if (this.threadView)
|
|
257
|
-
return this.threadView;
|
|
258
|
-
yield this.threadViewQuery.changes.pipe(take(1)).toPromise();
|
|
259
|
-
return this.threadView;
|
|
260
|
-
});
|
|
261
|
-
}
|
|
262
|
-
updateLoading() {
|
|
263
|
-
var _a, _b;
|
|
264
|
-
if (((_a = this.source) === null || _a === void 0 ? void 0 : _a.state) && ((_b = this.source) === null || _b === void 0 ? void 0 : _b.state) !== 'connecting') {
|
|
265
|
-
clearInterval(this._loadingTimer);
|
|
266
|
-
this.loadingMessage = `Here we go!`;
|
|
267
|
-
setTimeout(() => {
|
|
268
|
-
this.loading = false;
|
|
269
|
-
this.markLoaded();
|
|
270
|
-
}, 750);
|
|
271
|
-
return true;
|
|
272
|
-
}
|
|
273
|
-
let messageSwitchTime = 5 * 1000;
|
|
274
|
-
if (this.messageChangedAt + messageSwitchTime < Date.now()) {
|
|
275
|
-
if (this.loadingMessages[this._loadingMessageIndex]) {
|
|
276
|
-
this.loadingMessage = this.loadingMessages[this._loadingMessageIndex++];
|
|
277
|
-
this.messageChangedAt = Date.now();
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
return false;
|
|
281
|
-
}
|
|
282
|
-
get source() { return this._source; }
|
|
283
|
-
set source(value) {
|
|
284
|
-
var _a;
|
|
285
|
-
if (this._source && this._sourceIsOwned) {
|
|
286
|
-
this._source.close();
|
|
287
|
-
(_a = this._sourceSubscription) === null || _a === void 0 ? void 0 : _a.unsubscribe();
|
|
288
|
-
this._source = null;
|
|
289
|
-
this.participants = [];
|
|
290
|
-
}
|
|
291
|
-
this._source = value;
|
|
292
|
-
this._sourceIsOwned = false; // Assume we don't own this source.
|
|
293
|
-
this._sourceSubscription = new Subscription();
|
|
294
|
-
if (value) {
|
|
295
|
-
if (this.sharedCommentID) {
|
|
296
|
-
this.navigateToSharedComment(this.sharedCommentID);
|
|
297
|
-
this.lastSharedCommentID = this.sharedCommentID;
|
|
298
|
-
this.sharedCommentID = null;
|
|
299
|
-
}
|
|
300
|
-
this._source.messages.forEach(m => this.addParticipant(m));
|
|
301
|
-
this._sourceSubscription.add(this._source.messageReceived.subscribe(m => this.addParticipant(m)));
|
|
302
|
-
this._sourceSubscription.add(this._source.messageSent.subscribe(m => this.addParticipant(m)));
|
|
303
|
-
this._sourceSubscription.add(this._source.messageObserved.subscribe(m => this.addParticipant(m)));
|
|
304
|
-
this._sourceSubscription.add(this._source.messageUpdated.subscribe(msg => {
|
|
305
|
-
var _a;
|
|
306
|
-
console.log(`comments received message: `, msg);
|
|
307
|
-
if (msg.id === ((_a = this.selectedMessage) === null || _a === void 0 ? void 0 : _a.id) && msg.hidden) {
|
|
308
|
-
this.unselectMessage();
|
|
309
|
-
this.matSnackBar.open("The thread you were viewing was removed.", undefined, {
|
|
310
|
-
duration: 2500
|
|
311
|
-
});
|
|
312
|
-
}
|
|
313
|
-
}));
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
get topicID() { return this._topicID; }
|
|
317
|
-
set topicID(value) {
|
|
318
|
-
if (this._topicID !== value) {
|
|
319
|
-
this._topicID = value;
|
|
320
|
-
setTimeout(() => this.setSourceFromTopicID(value));
|
|
321
|
-
}
|
|
322
|
-
}
|
|
323
|
-
// Outputs
|
|
324
|
-
get signInSelected() { return this._signInSelected; }
|
|
325
|
-
get editAvatarSelected() { return this._editAvatarSelected; }
|
|
326
|
-
get permissionDeniedError() { return this._permissionDeniedError; }
|
|
327
|
-
get upvoted() { return this._upvoted.asObservable(); }
|
|
328
|
-
get reported() { return this._reported.asObservable(); }
|
|
329
|
-
get selected() { return this._selected.asObservable(); }
|
|
330
|
-
get userSelected() { return this._userSelected.asObservable(); }
|
|
331
|
-
get usernameSelected() { return this._usernameSelected.asObservable(); }
|
|
332
|
-
get avatarSelected() { return this._avatarSelected.asObservable(); }
|
|
333
|
-
get shared() { return this._shared.asObservable(); }
|
|
334
|
-
get sortOrder() { return this._sortOrder; }
|
|
335
|
-
set sortOrder(value) {
|
|
336
|
-
if (this._sortOrder !== value) {
|
|
337
|
-
this._sortOrder = value;
|
|
338
|
-
setTimeout(() => {
|
|
339
|
-
this.setSourceFromTopicID(this.topicID);
|
|
340
|
-
});
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
// UI Interactions
|
|
344
|
-
scrollToComment(commentId) {
|
|
345
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
346
|
-
if (typeof window === 'undefined')
|
|
347
|
-
return;
|
|
348
|
-
yield this.commentView.waitForAllCommentsToLoad();
|
|
349
|
-
const comment = document.querySelector(`[data-comment-id="${commentId}"]`);
|
|
350
|
-
if (comment) {
|
|
351
|
-
comment.scrollIntoView({
|
|
352
|
-
inline: 'center',
|
|
353
|
-
block: 'center'
|
|
354
|
-
});
|
|
355
|
-
}
|
|
356
|
-
});
|
|
357
|
-
}
|
|
358
|
-
navigateToSharedComment(id) {
|
|
359
|
-
var _a, _b, _c, _d;
|
|
360
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
361
|
-
this.loadingSharedComment = true;
|
|
362
|
-
yield new Promise(r => setTimeout(r, 10));
|
|
363
|
-
this.sharedCommentMissing = false;
|
|
364
|
-
let source = this.source;
|
|
365
|
-
yield source.ready;
|
|
366
|
-
yield this.viewReady;
|
|
367
|
-
yield this.loaded;
|
|
368
|
-
console.log(`Navigating to shared comment with ID '${id}'...`);
|
|
369
|
-
let message;
|
|
370
|
-
try {
|
|
371
|
-
message = yield this.source.get(id);
|
|
372
|
-
}
|
|
373
|
-
catch (e) {
|
|
374
|
-
console.error(`Failed to find comment from URL: ${e.message}`);
|
|
375
|
-
this.sharedCommentMissing = true;
|
|
376
|
-
this.loadingSharedComment = false;
|
|
377
|
-
if (typeof window !== 'undefined') {
|
|
378
|
-
setTimeout(() => {
|
|
379
|
-
let notice = this.element.querySelector('.loading-comment');
|
|
380
|
-
notice.scrollIntoView({
|
|
381
|
-
block: 'center',
|
|
382
|
-
inline: 'center'
|
|
383
|
-
});
|
|
384
|
-
}, 200);
|
|
385
|
-
}
|
|
386
|
-
return;
|
|
387
|
-
}
|
|
388
|
-
(_a = message.transientState) !== null && _a !== void 0 ? _a : (message.transientState = {});
|
|
389
|
-
// If there is a parent message, we should instead focus that and let the
|
|
390
|
-
// scrollToComment and highlight do the work.
|
|
391
|
-
if (message.parentMessageId) {
|
|
392
|
-
let parentMessage = yield this.source.get(message.parentMessageId);
|
|
393
|
-
(_b = parentMessage.transientState) !== null && _b !== void 0 ? _b : (parentMessage.transientState = {});
|
|
394
|
-
// Make sure that this message is loaded and visible to the user
|
|
395
|
-
yield this.commentView.loadMessageInContext(parentMessage);
|
|
396
|
-
let thread = yield this.selectMessage(parentMessage);
|
|
397
|
-
// Need to re-retrieve the message within the new chat source to affect its
|
|
398
|
-
// transient state.
|
|
399
|
-
yield thread.ready;
|
|
400
|
-
// Make sure that this message is loaded and visible to the user
|
|
401
|
-
yield this.waitForThreadView();
|
|
402
|
-
yield this.threadView.loadMessageInContext(message);
|
|
403
|
-
message = yield thread.get(message.id);
|
|
404
|
-
(_c = message.transientState) !== null && _c !== void 0 ? _c : (message.transientState = {});
|
|
405
|
-
message.transientState.highlighted = true;
|
|
406
|
-
console.dir(message);
|
|
407
|
-
yield new Promise(resolve => setTimeout(() => resolve(), 500));
|
|
408
|
-
}
|
|
409
|
-
else {
|
|
410
|
-
// Make sure that this message is loaded and visible to the user
|
|
411
|
-
yield this.commentView.loadMessageInContext(message);
|
|
412
|
-
(_d = message.transientState) !== null && _d !== void 0 ? _d : (message.transientState = {});
|
|
413
|
-
message.transientState.highlighted = true;
|
|
414
|
-
}
|
|
415
|
-
this.loadingSharedComment = false;
|
|
416
|
-
yield this.scrollToComment(id);
|
|
417
|
-
});
|
|
418
|
-
}
|
|
419
|
-
handlePermissionDenied(errorMessage) {
|
|
420
|
-
// This is what other components call when handling permission errors
|
|
421
|
-
if (errorMessage.startsWith(`app-handle|`)) {
|
|
422
|
-
// If this is an error during authorizeAction on the backend, pass control to the user-provided
|
|
423
|
-
// permission-denied handler.
|
|
424
|
-
this.sendPermissionDenied(errorMessage.replace(/^app-handle\|/, ''));
|
|
425
|
-
return;
|
|
426
|
-
}
|
|
427
|
-
alert(errorMessage);
|
|
428
|
-
}
|
|
429
|
-
sendPermissionDenied(message) {
|
|
430
|
-
this._permissionDeniedError.next(message);
|
|
431
|
-
}
|
|
432
|
-
scrollToMessage(message) {
|
|
433
|
-
let el = this.elementRef.nativeElement.querySelector(`[data-comment-id="${message.id}"]`);
|
|
434
|
-
if (!el)
|
|
435
|
-
return;
|
|
436
|
-
el.scrollIntoView({ block: 'center', inline: 'start' });
|
|
437
|
-
}
|
|
438
|
-
addParticipant(message) {
|
|
439
|
-
if (!message || !message.user || !message.user.id)
|
|
440
|
-
return;
|
|
441
|
-
let existing = this.participants.find(x => x.id === message.user.id);
|
|
442
|
-
if (existing)
|
|
443
|
-
return;
|
|
444
|
-
this.participants.push(message.user);
|
|
445
|
-
}
|
|
446
|
-
// Actions
|
|
447
|
-
likeMessage(source, message) {
|
|
448
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
449
|
-
if (!this.user) {
|
|
450
|
-
yield this.showSignIn();
|
|
451
|
-
return;
|
|
452
|
-
}
|
|
453
|
-
this._upvoted.next(message);
|
|
454
|
-
message.transientState.liking = true;
|
|
455
|
-
try {
|
|
456
|
-
yield source.likeMessage(message.id);
|
|
457
|
-
}
|
|
458
|
-
catch (e) {
|
|
459
|
-
this.handleBackendExceptionAsAlert(e, 'Could not like this message: ');
|
|
460
|
-
}
|
|
461
|
-
finally {
|
|
462
|
-
yield new Promise(resolve => setTimeout(() => resolve(), 250));
|
|
463
|
-
message.transientState.liking = false;
|
|
464
|
-
}
|
|
465
|
-
});
|
|
466
|
-
}
|
|
467
|
-
unlikeMessage(source, message) {
|
|
468
|
-
var _a;
|
|
469
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
470
|
-
if (!this.user) {
|
|
471
|
-
yield this.showSignIn();
|
|
472
|
-
return;
|
|
473
|
-
}
|
|
474
|
-
this._upvoted.next(message);
|
|
475
|
-
message.transientState.liking = true;
|
|
476
|
-
if ((_a = message.userState) === null || _a === void 0 ? void 0 : _a.liked)
|
|
477
|
-
message.likes = (message.likes || 0) - 1;
|
|
478
|
-
try {
|
|
479
|
-
yield source.unlikeMessage(message.id);
|
|
480
|
-
}
|
|
481
|
-
catch (e) {
|
|
482
|
-
this.handleBackendExceptionAsAlert(e, 'Failed to unlike this message: ');
|
|
483
|
-
}
|
|
484
|
-
yield new Promise(resolve => setTimeout(() => resolve(), 250));
|
|
485
|
-
message.transientState.liking = false;
|
|
486
|
-
});
|
|
487
|
-
}
|
|
488
|
-
reportMessage(message) {
|
|
489
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
490
|
-
this._reported.next(message);
|
|
491
|
-
});
|
|
492
|
-
}
|
|
493
|
-
unselectMessage() {
|
|
494
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
495
|
-
let message = this.selectedMessage;
|
|
496
|
-
this._selected.next(null);
|
|
497
|
-
this.selectedMessage = null;
|
|
498
|
-
if (this.selectedMessageThread) {
|
|
499
|
-
if (this.selectedMessageThread.close)
|
|
500
|
-
this.selectedMessageThread.close();
|
|
501
|
-
this.selectedMessageThread = null;
|
|
502
|
-
}
|
|
503
|
-
if (message)
|
|
504
|
-
setTimeout(() => this.scrollToMessage(message));
|
|
505
|
-
});
|
|
506
|
-
}
|
|
507
|
-
toggleSelectedMessage(message) {
|
|
508
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
509
|
-
if (this.selectedMessage === message) {
|
|
510
|
-
yield this.unselectMessage();
|
|
511
|
-
}
|
|
512
|
-
else {
|
|
513
|
-
yield this.selectMessage(message);
|
|
514
|
-
}
|
|
515
|
-
});
|
|
516
|
-
}
|
|
517
|
-
selectMessage(message) {
|
|
518
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
519
|
-
if (this.selectedMessage === message) {
|
|
520
|
-
console.log(`[Banta] Thread ${this.topicID}/${message.id} is already open.`);
|
|
521
|
-
return this.selectedMessageThread;
|
|
522
|
-
}
|
|
523
|
-
this._selected.next(message);
|
|
524
|
-
console.log(`[Banta] Opening thread for ${this.topicID}/${message.id}...`);
|
|
525
|
-
let selectedMessageThread = yield this.backend.getSourceForThread(this.topicID, message.id);
|
|
526
|
-
if (!selectedMessageThread) {
|
|
527
|
-
console.warn(`Failed to locate thread for message ${this.topicID}/${message.id}!`);
|
|
528
|
-
return null;
|
|
529
|
-
}
|
|
530
|
-
console.log(`[Banta] Thread opened for ${this.topicID}/${message.id}.`);
|
|
531
|
-
setTimeout(() => this.selectedMessageVisible = true);
|
|
532
|
-
setTimeout(() => __awaiter(this, void 0, void 0, function* () {
|
|
533
|
-
this.selectedMessage = message;
|
|
534
|
-
this.selectedMessageThread = selectedMessageThread;
|
|
535
|
-
}), 250);
|
|
536
|
-
return selectedMessageThread;
|
|
537
|
-
});
|
|
538
|
-
}
|
|
539
|
-
showSignIn() {
|
|
540
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
541
|
-
this._signInSelected.next();
|
|
542
|
-
});
|
|
543
|
-
}
|
|
544
|
-
showEditAvatar() {
|
|
545
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
546
|
-
this._editAvatarSelected.next();
|
|
547
|
-
});
|
|
548
|
-
}
|
|
549
|
-
selectMessageUser(message) {
|
|
550
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
551
|
-
this._userSelected.next(message);
|
|
552
|
-
});
|
|
553
|
-
}
|
|
554
|
-
selectUsername(user) {
|
|
555
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
556
|
-
this._usernameSelected.next(user);
|
|
557
|
-
});
|
|
558
|
-
}
|
|
559
|
-
selectAvatar(user) {
|
|
560
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
561
|
-
this._avatarSelected.next(user);
|
|
562
|
-
});
|
|
563
|
-
}
|
|
564
|
-
shareMessage(message) {
|
|
565
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
566
|
-
this._shared.next(message);
|
|
567
|
-
});
|
|
568
|
-
}
|
|
569
|
-
deleteMessage(message) {
|
|
570
|
-
var _a;
|
|
571
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
572
|
-
if (!this.user) {
|
|
573
|
-
yield this.showSignIn();
|
|
574
|
-
return;
|
|
575
|
-
}
|
|
576
|
-
if (!confirm("Are you sure you want to delete this comment? You cannot undo this action."))
|
|
577
|
-
return;
|
|
578
|
-
try {
|
|
579
|
-
yield this.source.deleteMessage(message.id);
|
|
580
|
-
if (((_a = this.selectedMessage) === null || _a === void 0 ? void 0 : _a.id) === message.id)
|
|
581
|
-
this.unselectMessage();
|
|
582
|
-
}
|
|
583
|
-
catch (e) {
|
|
584
|
-
this.handleBackendExceptionAsAlert(e, `Could not delete message: `);
|
|
585
|
-
}
|
|
586
|
-
});
|
|
587
|
-
}
|
|
588
|
-
editMessage(source, message, newText) {
|
|
589
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
590
|
-
if (!this.user) {
|
|
591
|
-
yield this.showSignIn();
|
|
592
|
-
return;
|
|
593
|
-
}
|
|
594
|
-
try {
|
|
595
|
-
yield source.editMessage(message.id, newText);
|
|
596
|
-
}
|
|
597
|
-
catch (e) {
|
|
598
|
-
this.handleBackendExceptionAsAlert(e, 'Could not edit this message: ');
|
|
599
|
-
return;
|
|
600
|
-
}
|
|
601
|
-
message.message = newText;
|
|
602
|
-
message.transientState.editing = false;
|
|
603
|
-
});
|
|
604
|
-
}
|
|
605
|
-
startEditing(message) {
|
|
606
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
607
|
-
this.selectedMessage.transientState.editing = false;
|
|
608
|
-
message.transientState.editing = true;
|
|
609
|
-
});
|
|
610
|
-
}
|
|
611
|
-
saveEdit(message, text) {
|
|
612
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
613
|
-
if (!this.user) {
|
|
614
|
-
yield this.showSignIn();
|
|
615
|
-
return;
|
|
616
|
-
}
|
|
617
|
-
try {
|
|
618
|
-
yield this.source.editMessage(message.id, text);
|
|
619
|
-
message.transientState.editing = false;
|
|
620
|
-
}
|
|
621
|
-
catch (e) {
|
|
622
|
-
this.handleBackendExceptionAsAlert(e, `Could not edit message: `);
|
|
623
|
-
}
|
|
624
|
-
});
|
|
625
|
-
}
|
|
626
|
-
}
|
|
627
|
-
BantaCommentsComponent.decorators = [
|
|
628
|
-
{ type: Component, args: [{
|
|
629
|
-
selector: 'banta-comments',
|
|
630
|
-
template: "<ng-container *ngIf=\"loading\">\r\n <div class=\"loading-screen\" [class.visible]=\"showLoadingScreen\">\r\n <h1>Loading...</h1>\r\n <div>\r\n <mat-spinner [diameter]=\"300\" [strokeWidth]=\"2\"></mat-spinner>\r\n </div>\r\n\r\n <p class=\"loading-message\" [class.visible]=\"loadingMessageVisible\">{{loadingMessage}}</p>\r\n </div>\r\n</ng-container>\r\n<ng-container *ngIf=\"!loading\">\r\n <div class=\"focused\" [class.visible]=\"selectedMessageVisible\" *ngIf=\"selectedMessage && !useInlineReplies\">\r\n\r\n <div>\r\n <a mat-button href=\"javascript:;\" (click)=\"unselectMessage()\">\r\n <mat-icon>arrow_back</mat-icon>\r\n Latest Comments\r\n </a>\r\n </div>\r\n\r\n <banta-comment\r\n [message]=\"selectedMessage\"\r\n [liking]=\"selectedMessage.transientState.liking\"\r\n [mine]=\"user?.id === selectedMessage.user?.id\"\r\n [permissions]=\"source?.permissions\"\r\n [showReplyAction]=\"false\"\r\n [editing]=\"selectedMessage.transientState.editing\"\r\n [maxLength]=\"maxCommentLength\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n (editStarted)=\"startEditing(selectedMessage)\"\r\n (editEnded)=\"selectedMessage.transientState.editing = false\"\r\n (edited)=\"saveEdit(selectedMessage, $event)\"\r\n (userSelected)=\"selectMessageUser(selectedMessage)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n (usernameSelected)=\"selectUsername($event)\"\r\n (liked)=\"likeMessage(source, selectedMessage)\"\r\n (unliked)=\"unlikeMessage(source, selectedMessage)\"\r\n (reported)=\"reportMessage(selectedMessage)\"\r\n (selected)=\"toggleSelectedMessage(selectedMessage)\"\r\n (shared)=\"shareMessage($event)\"\r\n (deleted)=\"deleteMessage(selectedMessage)\"\r\n ></banta-comment>\r\n\r\n <div class=\"replies\">\r\n\r\n <ng-container *ngIf=\"!selectedMessageThread\">\r\n <div class=\"loading\">\r\n <mat-spinner></mat-spinner>\r\n </div>\r\n </ng-container>\r\n\r\n <ng-container *ngIf=\"selectedMessageThread\">\r\n <banta-comment-view\r\n class=\"replies\"\r\n #threadView\r\n [source]=\"selectedMessageThread\"\r\n [allowReplies]=\"false\"\r\n [fixedHeight]=\"false\"\r\n [showEmptyState]=\"false\"\r\n [newestLast]=\"true\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n (liked)=\"likeMessage(selectedMessageThread, $event)\"\r\n (unliked)=\"unlikeMessage(selectedMessageThread, $event)\"\r\n (messageEdited)=\"editMessage(selectedMessageThread, $event.message, $event.newMessage)\"\r\n (reported)=\"reportMessage($event)\"\r\n (usernameSelected)=\"selectUsername($event)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n (shared)=\"shareMessage($event)\"\r\n (deleted)=\"deleteMessage($event)\"\r\n [customMenuItems]=\"customMenuItems\"\r\n ></banta-comment-view>\r\n\r\n <banta-comment-field\r\n [sendLabel]=\"replyLabel\"\r\n [sendingLabel]=\"sendingLabel\"\r\n [hashtags]=\"hashtags\"\r\n [participants]=\"participants\"\r\n (signInSelected)=\"showSignIn()\"\r\n (editAvatarSelected)=\"showEditAvatar()\"\r\n [source]=\"selectedMessageThread\"\r\n [maxLength]=\"maxCommentLength\"\r\n [canComment]=\"source?.permissions?.canPost\"\r\n [signInLabel]=\"signInLabel\"\r\n [permissionDeniedLabel]=\"source?.permissions?.canPostErrorMessage || permissionDeniedLabel\"\r\n (permissionDeniedError)=\"handlePermissionDenied($event)\"\r\n [shouldInterceptMessageSend]=\"shouldInterceptMessageSend\"\r\n [user]=\"user\"\r\n [label]=\"postReplyLabel\"\r\n [submit]=\"sendReply\"\r\n [allowAttachments]=\"allowAttachments\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"sendReplyOptionsTemplate\"></ng-container>\r\n </banta-comment-field>\r\n </ng-container>\r\n </div>\r\n </div>\r\n\r\n <div class=\"main\" [class.hidden]=\"selectedMessage && !useInlineReplies\">\r\n <banta-comment-field\r\n [source]=\"source\"\r\n [user]=\"user\"\r\n [sendLabel]=\"sendLabel\"\r\n [sendingLabel]=\"sendingLabel\"\r\n [signInLabel]=\"signInLabel\"\r\n [canComment]=\"source?.permissions?.canPost\"\r\n [hashtags]=\"hashtags\"\r\n [participants]=\"participants\"\r\n [label]=\"postCommentLabel\"\r\n [maxLength]=\"maxCommentLength\"\r\n (editAvatarSelected)=\"showEditAvatar()\"\r\n (signInSelected)=\"showSignIn()\"\r\n [permissionDeniedLabel]=\"source?.permissions?.canPostErrorMessage || permissionDeniedLabel\"\r\n (permissionDeniedError)=\"handlePermissionDenied($event)\"\r\n [shouldInterceptMessageSend]=\"shouldInterceptMessageSend\"\r\n [submit]=\"sendMessage\"\r\n [allowAttachments]=\"allowAttachments\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n >\r\n \r\n </banta-comment-field>\r\n\r\n <banta-comment-sort\r\n [(sort)]=\"sortOrder\"></banta-comment-sort>\r\n\r\n <div class=\"loading-comment\" *ngIf=\"loadingSharedComment\">\r\n <h1>Loading the comment you linked to...</h1>\r\n <mat-spinner [diameter]=\"300\" [strokeWidth]=\"2\"></mat-spinner>\r\n <p>\r\n If there are a lot of comments, this might take awhile!\r\n </p>\r\n </div>\r\n <div class=\"loading-comment\" *ngIf=\"!loadingSharedComment && lastSharedCommentID\">\r\n <ng-container *ngIf=\"sharedCommentMissing\">\r\n\r\n <a class=\"close\" mat-icon-button matTooltip=\"Close this notice\" href=\"javascript:;\" (click)=\"lastSharedCommentID = null\">\r\n <mat-icon>close</mat-icon>\r\n </a>\r\n\r\n <h1>\r\n <mat-icon>error</mat-icon>\r\n Uh oh!\r\n </h1>\r\n\r\n <p>The comment you linked to can't be found! It may have been removed.</p>\r\n </ng-container>\r\n <ng-container *ngIf=\"!sharedCommentMissing\">\r\n <a class=\"close\" mat-icon-button matTooltip=\"Close this notice\" href=\"javascript:;\" (click)=\"lastSharedCommentID = null\">\r\n <mat-icon>close</mat-icon>\r\n </a>\r\n <button mat-button (click)=\"navigateToSharedComment(lastSharedCommentID)\">\r\n <mat-icon>move_down</mat-icon> Jump to shared comment\r\n </button>\r\n </ng-container>\r\n </div>\r\n\r\n <banta-comment-view\r\n #commentView\r\n [class.faded]=\"selectedMessage && !useInlineReplies\"\r\n [source]=\"source\"\r\n [fixedHeight]=\"fixedHeight\"\r\n [maxMessages]=\"maxMessages\"\r\n [maxVisibleMessages]=\"maxVisibleMessages\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n [customMenuItems]=\"customMenuItems\"\r\n (userSelected)=\"selectMessageUser($event)\"\r\n (sortOrderChanged)=\"sortOrder = $event\"\r\n (selected)=\"toggleSelectedMessage($event)\"\r\n (liked)=\"likeMessage(source, $event)\"\r\n (unliked)=\"unlikeMessage(source, $event)\"\r\n (messageEdited)=\"editMessage(source, $event.message, $event.newMessage)\"\r\n (reported)=\"reportMessage($event)\"\r\n (usernameSelected)=\"selectUsername($event)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n (shared)=\"shareMessage($event)\"\r\n [selectedMessage]=\"selectedMessage\"\r\n (deleted)=\"deleteMessage($event)\"\r\n >\r\n <div class=\"inline-replies\">\r\n <div class=\"focused\" [class.visible]=\"selectedMessageVisible\" *ngIf=\"selectedMessage\">\r\n <div class=\"replies\">\r\n \r\n <ng-container *ngIf=\"!selectedMessageThread\">\r\n <div class=\"loading\">\r\n <mat-spinner></mat-spinner>\r\n </div>\r\n </ng-container>\r\n \r\n <ng-container *ngIf=\"selectedMessageThread\">\r\n <banta-comment-view\r\n [source]=\"selectedMessageThread\"\r\n [allowReplies]=\"false\"\r\n [fixedHeight]=\"false\"\r\n [showEmptyState]=\"false\"\r\n [newestLast]=\"true\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n (liked)=\"likeMessage(selectedMessageThread, $event)\"\r\n (unliked)=\"unlikeMessage(selectedMessageThread, $event)\"\r\n (messageEdited)=\"editMessage(selectedMessageThread, $event.message, $event.newMessage)\"\r\n (reported)=\"reportMessage($event)\"\r\n (usernameSelected)=\"selectUsername($event)\"\r\n (avatarSelected)=\"selectAvatar($event)\"\r\n (shared)=\"shareMessage($event)\"\r\n (deleted)=\"deleteMessage($event)\"\r\n ></banta-comment-view>\r\n \r\n <banta-comment-field\r\n [sendLabel]=\"replyLabel\"\r\n [sendingLabel]=\"sendingLabel\"\r\n [hashtags]=\"hashtags\"\r\n [participants]=\"participants\"\r\n (signInSelected)=\"showSignIn()\"\r\n [maxLength]=\"maxCommentLength\"\r\n (editAvatarSelected)=\"showEditAvatar()\"\r\n [source]=\"selectedMessageThread\"\r\n [canComment]=\"source?.permissions?.canPost\"\r\n [signInLabel]=\"signInLabel\"\r\n [permissionDeniedLabel]=\"source?.permissions?.canPostErrorMessage || permissionDeniedLabel\"\r\n (permissionDeniedError)=\"handlePermissionDenied($event)\"\r\n [shouldInterceptMessageSend]=\"shouldInterceptMessageSend\"\r\n [user]=\"user\"\r\n [label]=\"postReplyLabel\"\r\n [submit]=\"sendReply\"\r\n [allowAttachments]=\"allowAttachments\"\r\n [genericAvatarUrl]=\"genericAvatarUrl\"\r\n >\r\n <ng-container *ngTemplateOutlet=\"sendReplyOptionsTemplate\"></ng-container>\r\n </banta-comment-field>\r\n </ng-container>\r\n </div>\r\n </div> \r\n </div>\r\n </banta-comment-view>\r\n </div>\r\n</ng-container>\r\n",
|
|
631
|
-
styles: [":host{display:flex;flex-direction:column}@keyframes select-comment{0%{transform:scale(1.15)}to{transform:scale(1)}}.focused{animation-name:select-comment;animation-duration:.4s;animation-fill-mode:both}.focused .replies{margin-top:1em;margin-left:2em;border-left:2px solid #333;padding-left:2em}banta-comment-view{opacity:1;transition:.4s opacity ease-in-out}banta-comment-view.faded{opacity:.25}.loading{display:block;width:-moz-fit-content;width:fit-content;margin:0 auto;min-height:16em}.main.hidden{display:none}.loading-screen{text-align:center;opacity:0;transition:.25s ease-in-out opacity}.loading-screen.visible{opacity:1}.loading-screen h1{font-weight:100}.loading-screen mat-spinner{margin:5em auto}.loading-screen .loading-message{opacity:0;transition:.25s ease-in-out opacity;width:500px;max-width:100%;margin:0 auto}.loading-screen .loading-message.visible{opacity:1}banta-comment-sort{margin:0 0 0 auto;width:-moz-fit-content;width:fit-content;display:block}.inline-replies{margin-left:4em}@media (max-width: 500px){.focused .replies{margin-left:0}.inline-replies{margin-left:1em}.focused .replies{padding-left:.5em}banta-comment-sort{margin:0;width:100%}}:host-context(.banta-mobile) .focused .replies{margin-left:0}:host-context(.banta-mobile) .inline-replies{margin-left:1em}:host-context(.banta-mobile) .focused .replies{padding-left:.5em}:host-context(.banta-mobile) banta-comment-sort{margin:0;width:100%}.loading-comment{z-index:100;border:1px solid #333;background:black;color:#fff;padding:1em;border-radius:4px;text-align:center;position:relative}.loading-comment a.close{position:absolute;top:1em;right:1em}.loading-comment h1{font-weight:100;text-align:center}.loading-comment mat-spinner{margin:0 auto}\n"]
|
|
632
|
-
},] }
|
|
633
|
-
];
|
|
634
|
-
BantaCommentsComponent.ctorParameters = () => [
|
|
635
|
-
{ type: ChatBackendBase },
|
|
636
|
-
{ type: ElementRef },
|
|
637
|
-
{ type: ActivatedRoute },
|
|
638
|
-
{ type: MatSnackBar },
|
|
639
|
-
{ type: NgZone }
|
|
640
|
-
];
|
|
641
|
-
BantaCommentsComponent.propDecorators = {
|
|
642
|
-
isMobileSized: [{ type: HostBinding, args: ['class.banta-mobile',] }],
|
|
643
|
-
sendReplyOptionsTemplate: [{ type: ContentChild, args: [BantaReplySendOptionsDirective, { read: TemplateRef },] }],
|
|
644
|
-
customMenuItems: [{ type: Input }],
|
|
645
|
-
maxCommentLength: [{ type: Input }],
|
|
646
|
-
loadingMessages: [{ type: Input }],
|
|
647
|
-
useInlineReplies: [{ type: Input }],
|
|
648
|
-
commentView: [{ type: ViewChild, args: ['commentView',] }],
|
|
649
|
-
threadViewQuery: [{ type: ViewChildren, args: [CommentViewComponent,] }],
|
|
650
|
-
signInLabel: [{ type: Input }],
|
|
651
|
-
sendLabel: [{ type: Input }],
|
|
652
|
-
replyLabel: [{ type: Input }],
|
|
653
|
-
sendingLabel: [{ type: Input }],
|
|
654
|
-
permissionDeniedLabel: [{ type: Input }],
|
|
655
|
-
postCommentLabel: [{ type: Input }],
|
|
656
|
-
postReplyLabel: [{ type: Input }],
|
|
657
|
-
allowAttachments: [{ type: Input }],
|
|
658
|
-
fixedHeight: [{ type: Input }],
|
|
659
|
-
maxMessages: [{ type: Input }],
|
|
660
|
-
maxVisibleMessages: [{ type: Input }],
|
|
661
|
-
genericAvatarUrl: [{ type: Input }],
|
|
662
|
-
shouldInterceptMessageSend: [{ type: Input }],
|
|
663
|
-
participants: [{ type: Input }],
|
|
664
|
-
source: [{ type: Input }],
|
|
665
|
-
hashtags: [{ type: Input }],
|
|
666
|
-
topicID: [{ type: Input }],
|
|
667
|
-
signInSelected: [{ type: Output }],
|
|
668
|
-
editAvatarSelected: [{ type: Output }],
|
|
669
|
-
permissionDeniedError: [{ type: Output }],
|
|
670
|
-
upvoted: [{ type: Output }],
|
|
671
|
-
reported: [{ type: Output }],
|
|
672
|
-
selected: [{ type: Output }],
|
|
673
|
-
userSelected: [{ type: Output }],
|
|
674
|
-
usernameSelected: [{ type: Output }],
|
|
675
|
-
avatarSelected: [{ type: Output }],
|
|
676
|
-
shared: [{ type: Output }]
|
|
677
|
-
};
|
|
678
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFudGEtY29tbWVudHMuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc2RrL3NyYy9saWIvY29tbWVudHMvYmFudGEtY29tbWVudHMvYmFudGEtY29tbWVudHMuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHdEQUF3RDs7QUFFeEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBYSxXQUFXLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN6SixPQUFPLEVBQXFCLGFBQWEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVqRSxPQUFPLEVBQUUsT0FBTyxFQUFjLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN6RCxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFdEMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUUxRCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDMUQsT0FBTyxFQUFFLDhCQUE4QixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFakYsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sd0NBQXdDLENBQUM7QUFHOUU7O0dBRUc7QUFNSCxNQUFNLE9BQU8sc0JBQXNCO0lBQy9CLFlBQ1ksT0FBd0IsRUFDeEIsVUFBbUMsRUFDbkMsY0FBOEIsRUFDOUIsV0FBd0IsRUFDeEIsTUFBYztRQUpkLFlBQU8sR0FBUCxPQUFPLENBQWlCO1FBQ3hCLGVBQVUsR0FBVixVQUFVLENBQXlCO1FBQ25DLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQUM5QixnQkFBVyxHQUFYLFdBQVcsQ0FBYTtRQUN4QixXQUFNLEdBQU4sTUFBTSxDQUFRO1FBc0YxQixrQkFBYSxHQUFZLEtBQUssQ0FBQztRQU0vQixjQUFTLEdBQUcsSUFBSSxPQUFPLENBQU8sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsYUFBYSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBa0QzRCxpQkFBaUI7UUFDVCxvQkFBZSxHQUFHLEVBQUUsQ0FBQztRQUM3QiwwQkFBcUIsR0FBRyxLQUFLLENBQUM7UUFpQjlCLFlBQU8sR0FBWSxJQUFJLENBQUM7UUFDeEIsc0JBQWlCLEdBQUcsS0FBSyxDQUFDO1FBTWpCLG9CQUFlLEdBQXNCLEVBQUUsQ0FBQztRQW9CekMseUJBQW9CLEdBQUcsQ0FBQyxDQUFDO1FBRXhCLHFCQUFnQixHQUFXLElBQUksQ0FBQztRQUNoQyxvQkFBZSxHQUFhO1lBQ2pDLGtCQUFrQjtZQUNsQixpQ0FBaUM7WUFDakMsNkJBQTZCO1lBQzdCLGlDQUFpQztZQUNqQyxpQ0FBaUM7WUFDakM7OztTQUdDO1NBQ0osQ0FBQztRQUVPLHFCQUFnQixHQUFHLElBQUksQ0FBQztRQW9EakMsV0FBTSxHQUFHLElBQUksT0FBTyxDQUFPLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsR0FBRyxDQUFDLENBQUMsQ0FBQztRQXdCckQsYUFBYTtRQUVMLG9CQUFlLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQUN0QywyQkFBc0IsR0FBRyxJQUFJLE9BQU8sRUFBVSxDQUFDO1FBQy9DLHdCQUFtQixHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7UUFDMUMsYUFBUSxHQUFHLElBQUksT0FBTyxFQUFlLENBQUM7UUFDdEMsY0FBUyxHQUFHLElBQUksT0FBTyxFQUFlLENBQUM7UUFDdkMsY0FBUyxHQUFHLElBQUksT0FBTyxFQUFlLENBQUM7UUFDdkMsa0JBQWEsR0FBRyxJQUFJLE9BQU8sRUFBZSxDQUFDO1FBQzNDLFlBQU8sR0FBRyxJQUFJLE9BQU8sRUFBZSxDQUFDO1FBQ3JDLHNCQUFpQixHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7UUFDeEMsb0JBQWUsR0FBRyxJQUFJLE9BQU8sRUFBUSxDQUFDO1FBRzlDOzs7O1dBSUc7UUFDSyxtQkFBYyxHQUFHLEtBQUssQ0FBQztRQUN2QixVQUFLLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUMzQixlQUFVLEdBQWtCLGFBQWEsQ0FBQyxNQUFNLENBQUM7UUFNekQsMkJBQXNCLEdBQUcsS0FBSyxDQUFDO1FBRS9CLFNBQVM7UUFFQSxnQkFBVyxHQUFHLFNBQVMsQ0FBQztRQUN4QixjQUFTLEdBQUcsTUFBTSxDQUFDO1FBQ25CLGVBQVUsR0FBRyxPQUFPLENBQUM7UUFDckIsaUJBQVksR0FBRyxTQUFTLENBQUM7UUFDekIsMEJBQXFCLEdBQUcsTUFBTSxDQUFDO1FBQy9CLHFCQUFnQixHQUFHLGdCQUFnQixDQUFDO1FBQ3BDLG1CQUFjLEdBQUcsY0FBYyxDQUFDO1FBQ2hDLHFCQUFnQixHQUFHLElBQUksQ0FBQztRQUd4Qix1QkFBa0IsR0FBVyxFQUFFLENBQUM7UUFDaEMscUJBQWdCLEdBQUcsK0JBQStCLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLG1CQUFtQixDQUFDO1FBRzdGLGlCQUFZLEdBQVcsRUFBRSxDQUFDO1FBaURuQyxhQUFRLEdBQWM7WUFDbEIsRUFBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLFdBQVcsRUFBRSxnQkFBZ0IsRUFBQztZQUNqRCxFQUFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLDRCQUE0QixFQUFDO1lBQy9ELEVBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUscUNBQXFDLEVBQUM7U0FDeEUsQ0FBQztRQXFERix5QkFBb0IsR0FBRyxLQUFLLENBQUM7UUFDN0IseUJBQW9CLEdBQUcsS0FBSyxDQUFDO1FBN2F6QixJQUFJLENBQUMsV0FBVyxHQUFHLENBQU8sT0FBb0IsRUFBRSxFQUFFOztZQUM5QyxJQUFJO2dCQUNBLE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQSxNQUFBLElBQUksQ0FBQywwQkFBMEIsK0NBQS9CLElBQUksRUFBOEIsT0FBTyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQSxDQUFDO2dCQUNoRixJQUFJLENBQUMsU0FBUyxFQUFFO29CQUNaLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7aUJBQ25DO2dCQUVELElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEtBQUssYUFBYSxDQUFDLE1BQU0sRUFBRTtvQkFDaEQsSUFBSSxDQUFDLFNBQVMsR0FBRyxhQUFhLENBQUMsTUFBTSxDQUFDO2lCQUN6QztnQkFDRCxPQUFPLElBQUksQ0FBQzthQUNmO1lBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ1IsSUFBSSxDQUFDLHNCQUFzQixDQUFDLENBQUMsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO2FBQ3REO1FBQ0wsQ0FBQyxDQUFBLENBQUE7UUFFRCxJQUFJLENBQUMsU0FBUyxHQUFHLENBQU8sT0FBb0IsRUFBRSxFQUFFOztZQUM1QyxJQUFJO2dCQUNBLE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQSxNQUFBLElBQUksQ0FBQywwQkFBMEIsK0NBQS9CLElBQUksRUFBOEIsT0FBTyxFQUFFLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFBLENBQUM7Z0JBQy9GLElBQUksQ0FBQyxTQUFTLEVBQUU7b0JBQ1osTUFBTSxJQUFJLENBQUMscUJBQXFCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2lCQUNsRDtnQkFDRCxPQUFPLElBQUksQ0FBQzthQUNmO1lBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ1IsSUFBSSxDQUFDLHNCQUFzQixDQUFDLENBQUMsRUFBRSx3QkFBd0IsQ0FBQyxDQUFDO2FBQzVEO1FBQ0wsQ0FBQyxDQUFBLENBQUE7SUFDTCxDQUFDO0lBRUQsSUFBSSxPQUFPO1FBQ1AsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQztJQUN6QyxDQUFDO0lBRU8sNkJBQTZCLENBQUMsQ0FBUSxFQUFFLFNBQWlCLEVBQUU7UUFDL0QsSUFBSTtZQUNBLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLENBQUM7U0FDMUM7UUFBQyxPQUFPLENBQUMsRUFBRTtZQUNSLEtBQUssQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUM7U0FDcEI7SUFDTCxDQUFDO0lBRU8sc0JBQXNCLENBQUMsQ0FBUSxFQUFFLFNBQWlCLEVBQUU7UUFDeEQsSUFBSSxZQUFZLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUU3QixJQUFJLFlBQVksQ0FBQyxVQUFVLENBQUMsb0JBQW9CLENBQUMsRUFBRTtZQUMvQyxZQUFZLEdBQUcsWUFBWSxDQUFDLE9BQU8sQ0FBQyxzQkFBc0IsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUVoRSxJQUFJLFlBQVksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLEVBQUU7Z0JBQ3hDLGdHQUFnRztnQkFDaEcsNkJBQTZCO2dCQUU3QixJQUFJLENBQUMsb0JBQW9CLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxlQUFlLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztnQkFDckUsT0FBTzthQUNWO1NBQ0o7UUFFRCxNQUFNLElBQUksS0FBSyxDQUFDLEdBQUcsTUFBTSxHQUFHLFlBQVksRUFBRSxDQUFDLENBQUM7SUFDaEQsQ0FBQztJQUVELG9DQUFvQztJQUVwQyxRQUFRO1FBQ0osSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQzdFLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUVwQixJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVcsRUFBRTtZQUMvQixJQUFJLFdBQVcsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDdEQsSUFBSSxLQUFLLEdBQUcsV0FBVyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUM7aUJBQzdCLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7aUJBQ3RCLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxrQkFBa0IsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FDcEY7WUFFRCxNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDbkMsSUFBSSxTQUFTLEVBQUU7Z0JBQ1gsSUFBSSxDQUFDLGVBQWUsR0FBRyxTQUFTLENBQUM7YUFDcEM7U0FDSjtJQUNMLENBQUM7SUFlRCxlQUFlO1FBQ1gsSUFBSSxPQUFPLE1BQU0sS0FBSyxXQUFXLEVBQUU7WUFDL0IsSUFBSSxRQUFRLEdBQUcsR0FBRyxFQUFFO2dCQUNoQixJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO2dCQUNqRSxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUU7b0JBQ2pCLFVBQVUsQ0FBQyxHQUFHLEVBQUU7d0JBQ1osSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO3dCQUN4QixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUM7d0JBQzFCLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUM7b0JBQzFDLENBQUMsQ0FBQyxDQUFDO2dCQUNQLENBQUMsQ0FBQyxDQUFBO1lBQ04sQ0FBQyxDQUFDO1lBRUYsSUFBSSxPQUFPLGNBQWMsS0FBSyxXQUFXLEVBQUU7Z0JBQ3ZDLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxjQUFjLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ25ELElBQUksQ0FBQyxjQUFjLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLENBQUM7YUFDOUQ7aUJBQU07Z0JBQ0gsb0NBQW9DO2dCQUNwQyxVQUFVLENBQUMsR0FBRyxFQUFFO29CQUNaLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDO29CQUN2RCxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLFlBQVksQ0FBQztvQkFDekQsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQztnQkFDMUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO2FBQ1o7WUFFRCxRQUFRLEVBQUUsQ0FBQztTQUNkO1FBRUQsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQ3pCLENBQUM7SUFFRCxXQUFXO1FBQ1AsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN6QixJQUFJLElBQUksQ0FBQyxjQUFjO1lBQ25CLElBQUksQ0FBQyxjQUFjLENBQUMsVUFBVSxFQUFFLENBQUM7SUFDekMsQ0FBQztJQUVhLG9CQUFvQixDQUFDLE9BQWU7O1lBQzlDLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVztnQkFDN0IsT0FBTztZQUVYLFVBQVUsQ0FBQyxHQUFTLEVBQUU7Z0JBQ2xCLE9BQU8sQ0FBQyxHQUFHLENBQUMsaURBQWlELE9BQU8sR0FBRyxDQUFDLENBQUM7Z0JBQ3pFLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLGlCQUFpQixDQUFDLE9BQU8sRUFBRSxFQUFFLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQztnQkFDM0YsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLENBQUM7WUFDL0IsQ0FBQyxDQUFBLENBQUMsQ0FBQztRQUNQLENBQUM7S0FBQTtJQU1ELElBQUksY0FBYztRQUNkLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQztJQUNoQyxDQUFDO0lBRUQsSUFBSSxjQUFjLENBQUMsS0FBSztRQUNwQixJQUFJLENBQUMscUJBQXFCLEdBQUcsS0FBSyxDQUFDO1FBQ25DLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDWixJQUFJLENBQUMsZUFBZSxHQUFHLEtBQUssQ0FBQztZQUM3QixJQUFJLENBQUMsZUFBZSxHQUFHLEtBQUssQ0FBQztZQUM3QixVQUFVLENBQUMsR0FBRyxFQUFFO2dCQUNaLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLENBQUM7WUFDdEMsQ0FBQyxDQUFDLENBQUE7UUFDTixDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDWixDQUFDO0lBV2EsWUFBWTs7WUFDdEIsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7WUFFM0QsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFO2dCQUFFLE9BQU87WUFDakMsTUFBTSxJQUFJLE9BQU8sQ0FBTyxPQUFPLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ3JFLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRTtnQkFBRSxPQUFPO1lBQ2pDLE1BQU0sSUFBSSxPQUFPLENBQU8sT0FBTyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUNyRSxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUU7Z0JBQUUsT0FBTztZQUNqQyxNQUFNLElBQUksT0FBTyxDQUFPLE9BQU8sQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLE9BQU8sRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDckUsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFO2dCQUFFLE9BQU87WUFFakMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxnRUFBZ0UsQ0FBQyxDQUFDO1lBQzlFLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUM7WUFDOUIsSUFBSSxPQUFPLE1BQU0sS0FBSyxXQUFXO2dCQUM3QixJQUFJLENBQUMsYUFBYSxHQUFHLFdBQVcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDM0UsQ0FBQztLQUFBO0lBb0NEOzs7Ozs7T0FNRztJQUNILDZCQUE2QixDQUFDLE9BQW9COztRQUM5QyxJQUFJLE9BQU8sQ0FBQyxlQUFlO1lBQ3ZCLE9BQU8sTUFBQSxJQUFJLENBQUMsVUFBVSwwQ0FBRSw2QkFBNkIsQ0FBQyxPQUFPLENBQUMsQ0FBQzs7WUFFL0QsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLDZCQUE2QixDQUFDLE9BQU8sQ0FBQyxDQUFBO0lBQ3RFLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxJQUFJLFVBQVU7UUFDVixPQUFPLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbkYsQ0FBQztJQUVLLGlCQUFpQjs7WUFDbkIsSUFBSSxJQUFJLENBQUMsVUFBVTtnQkFDZixPQUFPLElBQUksQ0FBQyxVQUFVLENBQUM7WUFFM0IsTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDN0QsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDO1FBQzNCLENBQUM7S0FBQTtJQUtPLGFBQWE7O1FBQ2pCLElBQUksQ0FBQSxNQUFBLElBQUksQ0FBQyxNQUFNLDBDQUFFLEtBQUssS0FBSSxDQUFBLE1BQUEsSUFBSSxDQUFDLE1BQU0sMENBQUUsS0FBSyxNQUFLLFlBQVksRUFBRTtZQUMzRCxhQUFhLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ2xDLElBQUksQ0FBQyxjQUFjLEdBQUcsYUFBYSxDQUFDO1lBQ3BDLFVBQVUsQ0FBQyxHQUFHLEVBQUU7Z0JBQ1osSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7Z0JBQ3JCLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUN0QixDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDUixPQUFPLElBQUksQ0FBQztTQUNmO1FBRUQsSUFBSSxpQkFBaUIsR0FBRyxDQUFDLEdBQUMsSUFBSSxDQUFDO1FBQy9CLElBQUksSUFBSSxDQUFDLGdCQUFnQixHQUFHLGlCQUFpQixHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsRUFBRTtZQUN4RCxJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLEVBQUU7Z0JBQ2pELElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQyxDQUFDO2dCQUN4RSxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO2FBQ3RDO1NBQ0o7UUFFRCxPQUFPLEtBQUssQ0FBQztJQUNqQixDQUFDO0lBbURELElBQ0ksTUFBTSxLQUFxQixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO0lBQ3JELElBQUksTUFBTSxDQUFDLEtBQUs7O1FBQ1osSUFBSSxJQUFJLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUU7WUFDckMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNyQixNQUFBLElBQUksQ0FBQyxtQkFBbUIsMENBQUUsV0FBVyxFQUFFLENBQUM7WUFDeEMsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7WUFDcEIsSUFBSSxDQUFDLFlBQVksR0FBRyxFQUFFLENBQUM7U0FDMUI7UUFFRCxJQUFJLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztRQUNyQixJQUFJLENBQUMsY0FBYyxHQUFHLEtBQUssQ0FBQyxDQUFDLG1DQUFtQztRQUNoRSxJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUU5QyxJQUFJLEtBQUssRUFBRTtZQUNQLElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRTtnQkFDdEIsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztnQkFDbkQsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxlQUFlLENBQUM7Z0JBQ2hELElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDO2FBQy9CO1lBRUQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBRTNELElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDbEcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM5RixJQUFJLENBQUMsbUJBQW1CLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2xHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxHQUFHLENBQ3hCLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsRUFBRTs7Z0JBQ3hDLE9BQU8sQ0FBQyxHQUFHLENBQUMsNkJBQTZCLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQ2hELElBQUksR0FBRyxDQUFDLEVBQUUsTUFBSyxNQUFBLElBQUksQ0FBQyxlQUFlLDBDQUFFLEVBQUUsQ0FBQSxJQUFJLEdBQUcsQ0FBQyxNQUFNLEVBQUU7b0JBQ25ELElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztvQkFDdkIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQ2pCLDBDQUEwQyxFQUMxQyxTQUFTLEVBQ1Q7d0JBQ0ksUUFBUSxFQUFFLElBQUk7cUJBQ2pCLENBQ0osQ0FBQTtpQkFDSjtZQUNMLENBQUMsQ0FBQyxDQUNMLENBQUM7U0FFTDtJQUNMLENBQUM7SUFPRCxJQUNJLE9BQU8sS0FBYSxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBQy9DLElBQUksT0FBTyxDQUFDLEtBQUs7UUFDYixJQUFJLElBQUksQ0FBQyxRQUFRLEtBQUssS0FBSyxFQUFFO1lBQ3pCLElBQUksQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDO1lBQ3RCLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztTQUN0RDtJQUNMLENBQUM7SUFFRCxVQUFVO0lBRVYsSUFBYyxjQUFjLEtBQXVCLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUM7SUFDakYsSUFBYyxrQkFBa0IsS0FBSyxPQUFPLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDLENBQUM7SUFDdkUsSUFBYyxxQkFBcUIsS0FBeUIsT0FBTyxJQUFJLENBQUMsc0JBQXNCLENBQUMsQ0FBQyxDQUFDO0lBQ2pHLElBQWMsT0FBTyxLQUFLLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDaEUsSUFBYyxRQUFRLEtBQUssT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNsRSxJQUFjLFFBQVEsS0FBSyxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ2xFLElBQWMsWUFBWSxLQUFLLE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDMUUsSUFBYyxnQkFBZ0IsS0FBSyxPQUFPLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDbEYsSUFBYyxjQUFjLEtBQUssT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLFlBQVksRUFBRSxDQUFDLENBQUMsQ0FBQztJQUM5RSxJQUFjLE1BQU0sS0FBSyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsWUFBWSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRTlELElBQUksU0FBUyxLQUFLLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7SUFDM0MsSUFBSSxTQUFTLENBQUMsS0FBSztRQUNmLElBQUksSUFBSSxDQUFDLFVBQVUsS0FBSyxLQUFLLEVBQUU7WUFDM0IsSUFBSSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUM7WUFDeEIsVUFBVSxDQUFDLEdBQUcsRUFBRTtnQkFDWixJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzVDLENBQUMsQ0FBQyxDQUFDO1NBQ047SUFDTCxDQUFDO0lBS0Qsa0JBQWtCO0lBRVosZUFBZSxDQUFDLFNBQTRCOztZQUM5QyxJQUFJLE9BQU8sTUFBTSxLQUFLLFdBQVc7Z0JBQzdCLE9BQU87WUFFWCxNQUFNLElBQUksQ0FBQyxXQUFXLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztZQUVsRCxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLHFCQUFxQixTQUFTLElBQUksQ0FBQyxDQUFDO1lBQzNFLElBQUksT0FBTyxFQUFFO2dCQUNULE9BQU8sQ0FBQyxjQUFjLENBQUM7b0JBQ25CLE1BQU0sRUFBRSxRQUFRO29CQUNoQixLQUFLLEVBQUUsUUFBUTtpQkFDbEIsQ0FBQyxDQUFDO2FBQ047UUFDTCxDQUFDO0tBQUE7SUFLSyx1QkFBdUIsQ0FBQyxFQUFVOzs7WUFDcEMsSUFBSSxDQUFDLG9CQUFvQixHQUFHLElBQUksQ0FBQztZQUNqQyxNQUFNLElBQUksT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQzFDLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxLQUFLLENBQUM7WUFDbEMsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztZQUV6QixNQUFNLE1BQU0sQ0FBQyxLQUFLLENBQUM7WUFDbkIsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFDO1lBQ3JCLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQztZQUVsQixPQUFPLENBQUMsR0FBRyxDQUFDLHlDQUF5QyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQy9ELElBQUksT0FBb0IsQ0FBQztZQUV6QixJQUFJO2dCQUNBLE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2FBQ3ZDO1lBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ1IsT0FBTyxDQUFDLEtBQUssQ0FBQyxvQ0FBb0MsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7Z0JBQy9ELElBQUksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLENBQUM7Z0JBQ2pDLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxLQUFLLENBQUM7Z0JBRWxDLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFO29CQUMvQixVQUFVLENBQUMsR0FBRyxFQUFFO3dCQUNaLElBQUksTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLGtCQUFrQixDQUFDLENBQUM7d0JBQzVELE1BQU0sQ0FBQyxjQUFjLENBQUM7NEJBQ2xCLEtBQUssRUFBRSxRQUFROzRCQUNmLE1BQU0sRUFBRSxRQUFRO3lCQUNuQixDQUFDLENBQUM7b0JBQ1AsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO2lCQUNYO2dCQUNELE9BQU87YUFDVjtZQUVELE1BQUEsT0FBTyxDQUFDLGNBQWMsb0NBQXRCLE9BQU8sQ0FBQyxjQUFjLEdBQUssRUFBRSxFQUFDO1lBRTlCLDBFQUEwRTtZQUMxRSw2Q0FBNkM7WUFFN0MsSUFBSSxPQUFPLENBQUMsZUFBZSxFQUFFO2dCQUV6QixJQUFJLGFBQWEsR0FBRyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0FBQztnQkFDbkUsTUFBQSxhQUFhLENBQUMsY0FBYyxvQ0FBNUIsYUFBYSxDQUFDLGNBQWMsR0FBSyxFQUFFLEVBQUM7Z0JBRXBDLGdFQUFnRTtnQkFDaEUsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLG9CQUFvQixDQUFDLGFBQWEsQ0FBQyxDQUFDO2dCQUUzRCxJQUFJLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLENBQUM7Z0JBRXJELDJFQUEyRTtnQkFDM0UsbUJBQW1CO2dCQUNuQixNQUFNLE1BQU0sQ0FBQyxLQUFLLENBQUM7Z0JBRW5CLGdFQUFnRTtnQkFDaEUsTUFBTSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztnQkFDL0IsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLG9CQUFvQixDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUVwRCxPQUFPLEdBQUcsTUFBTSxNQUFNLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDdkMsTUFBQSxPQUFPLENBQUMsY0FBYyxvQ0FBdEIsT0FBTyxDQUFDLGNBQWMsR0FBSyxFQUFFLEVBQUM7Z0JBQzlCLE9BQU8sQ0FBQyxjQUFjLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztnQkFDMUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDckIsTUFBTSxJQUFJLE9BQU8sQ0FBTyxPQUFPLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO2FBRXhFO2lCQUFNO2dCQUNILGdFQUFnRTtnQkFDaEUsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLG9CQUFvQixDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUVyRCxNQUFBLE9BQU8sQ0FBQyxjQUFjLG9DQUF0QixPQUFPLENBQUMsY0FBYyxHQUFLLEVBQUUsRUFBQztnQkFDOUIsT0FBTyxDQUFDLGNBQWMsQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO2FBQzdDO1lBRUQsSUFBSSxDQUFDLG9CQUFvQixHQUFHLEtBQUssQ0FBQztZQUNsQyxNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsRUFBRSxDQUFDLENBQUM7O0tBQ2xDO0lBRUQsc0JBQXNCLENBQUMsWUFBb0I7UUFDdkMscUVBQXFFO1FBRXJFLElBQUksWUFBWSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsRUFBRTtZQUN4QyxnR0FBZ0c7WUFDaEcsNkJBQTZCO1lBRTdCLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLGVBQWUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3JFLE9BQU87U0FDVjtRQUVELEtBQUssQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUN4QixDQUFDO0lBRUQsb0JBQW9CLENBQUMsT0FBZTtRQUNoQyxJQUFJLENBQUMsc0JBQXNCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzlDLENBQUM7SUFFRCxlQUFlLENBQUMsT0FBb0I7UUFDaEMsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLHFCQUFxQixPQUFPLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUMxRixJQUFJLENBQUMsRUFBRTtZQUNILE9BQU87UUFDWCxFQUFFLENBQUMsY0FBYyxDQUFDLEVBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFDLENBQUMsQ0FBQztJQUMxRCxDQUFDO0lBRU8sY0FBYyxDQUFDLE9BQW9CO1FBQ3ZDLElBQUksQ0FBQyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQzdDLE9BQU87UUFFWCxJQUFJLFFBQVEsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNyRSxJQUFJLFFBQVE7WUFDUixPQUFPO1FBQ1gsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3pDLENBQUM7SUFFRCxVQUFVO0lBRUosV0FBVyxDQUFDLE1BQXNCLEVBQUUsT0FBb0I7O1lBQzFELElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFO2dCQUNaLE1BQU0sSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO2dCQUN4QixPQUFPO2FBQ1Y7WUFFRCxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUM1QixPQUFPLENBQUMsY0FBYyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7WUFFckMsSUFBSTtnQkFDQSxNQUFNLE1BQU0sQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2FBQ3hDO1lBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ1IsSUFBSSxDQUFDLDZCQUE2QixDQUFDLENBQUMsRUFBRSwrQkFBK0IsQ0FBQyxDQUFDO2FBQzFFO29CQUFTO2dCQUNOLE1BQU0sSUFBSSxPQUFPLENBQU8sT0FBTyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFDckUsT0FBTyxDQUFDLGNBQWMsQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDO2FBQ3pDO1FBQ0wsQ0FBQztLQUFBO0lBRUssYUFBYSxDQUFDLE1BQXNCLEVBQUUsT0FBb0I7OztZQUM1RCxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRTtnQkFDWixNQUFNLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztnQkFDeEIsT0FBTzthQUNWO1lBRUQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDNUIsT0FBTyxDQUFDLGNBQWMsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO1lBRXJDLElBQUksTUFBQSxPQUFPLENBQUMsU0FBUywwQ0FBRSxLQUFLO2dCQUN4QixPQUFPLENBQUMsS0FBSyxHQUFHLENBQUMsT0FBTyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7WUFFN0MsSUFBSTtnQkFDQSxNQUFNLE1BQU0sQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2FBQzFDO1lBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ1IsSUFBSSxDQUFDLDZCQUE2QixDQUFDLENBQUMsRUFBRSxpQ0FBaUMsQ0FBQyxDQUFDO2FBQzVFO1lBRUQsTUFBTSxJQUFJLE9BQU8sQ0FBTyxPQUFPLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxPQUFPLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ3JFLE9BQU8sQ0FBQyxjQUFjLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQzs7S0FDekM7SUFFSyxhQUFhLENBQUMsT0FBb0I7O1lBQ3BDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2pDLENBQUM7S0FBQTtJQUVLLGVBQWU7O1lBQ2pCLElBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUM7WUFFbkMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDMUIsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUM7WUFDNUIsSUFBSSxJQUFJLENBQUMscUJBQXFCLEVBQUU7Z0JBQzVCLElBQUksSUFBSSxDQUFDLHFCQUFxQixDQUFDLEtBQUs7b0JBQ2hDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxLQUFLLEVBQUUsQ0FBQztnQkFDdkMsSUFBSSxDQUFDLHFCQUFxQixHQUFHLElBQUksQ0FBQzthQUNyQztZQUVELElBQUksT0FBTztnQkFDUCxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQ3hELENBQUM7S0FBQTtJQUVLLHFCQUFxQixDQUFDLE9BQW9COztZQUM1QyxJQUFJLElBQUksQ0FBQyxlQUFlLEtBQUssT0FBTyxFQUFFO2dCQUNsQyxNQUFNLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQzthQUNoQztpQkFBTTtnQkFDSCxNQUFNLElBQUksQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7YUFDckM7UUFDTCxDQUFDO0tBQUE7SUFFSyxhQUFhLENBQUMsT0FBb0I7O1lBQ3BDLElBQUksSUFBSSxDQUFDLGVBQWUsS0FBSyxPQUFPLEVBQUU7Z0JBQ2xDLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0JBQWtCLElBQUksQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLEVBQUUsbUJBQW1CLENBQUMsQ0FBQztnQkFDN0UsT0FBTyxJQUFJLENBQUMscUJBQXFCLENBQUM7YUFDckM7WUFFRCxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUU3QixPQUFPLENBQUMsR0FBRyxDQUFDLDhCQUE4QixJQUFJLENBQUMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO1lBQzNFLElBQUkscUJBQXFCLEdBQUcsTUFBTSxJQUFJLENBQUMsT0FBTyxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBRTVGLElBQUksQ0FBQyxxQkFBcUIsRUFBRTtnQkFDeEIsT0FBTyxDQUFDLElBQUksQ0FBQyx1Q0FBdUMsSUFBSSxDQUFDLE9BQU8sSUFBSSxPQUFPLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFDbkYsT0FBTyxJQUFJLENBQUM7YUFDZjtZQUVELE9BQU8sQ0FBQyxHQUFHLENBQUMsNkJBQTZCLElBQUksQ0FBQyxPQUFPLElBQUksT0FBTyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFFeEUsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxzQkFBc0IsR0FBRyxJQUFJLENBQUMsQ0FBQztZQUNyRCxVQUFVLENBQUMsR0FBUyxFQUFFO2dCQUNsQixJQUFJLENBQUMsZUFBZSxHQUFHLE9BQU8sQ0FBQztnQkFDL0IsSUFBSSxDQUFDLHFCQUFxQixHQUFHLHFCQUFxQixDQUFDO1lBQ3ZELENBQUMsQ0FBQSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBRVIsT0FBTyxxQkFBcUIsQ0FBQztRQUNqQyxDQUFDO0tBQUE7SUFFSyxVQUFVOztZQUNaLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDaEMsQ0FBQztLQUFBO0lBRUssY0FBYzs7WUFDaEIsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3BDLENBQUM7S0FBQTtJQUVLLGlCQUFpQixDQUFDLE9BQW9COztZQUN4QyxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNyQyxDQUFDO0tBQUE7SUFFSyxjQUFjLENBQUMsSUFBVTs7WUFDM0IsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN0QyxDQUFDO0tBQUE7SUFFSyxZQUFZLENBQUMsSUFBVTs7WUFDekIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDcEMsQ0FBQztLQUFBO0lBRUssWUFBWSxDQUFDLE9BQW9COztZQUNuQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUMvQixDQUFDO0tBQUE7SUFFSyxhQUFhLENBQUMsT0FBb0I7OztZQUNwQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRTtnQkFDWixNQUFNLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztnQkFDeEIsT0FBTzthQUNWO1lBRUQsSUFBSSxDQUFDLE9BQU8sQ0FBQyw0RUFBNEUsQ0FBQztnQkFDdEYsT0FBTztZQUVYLElBQUk7Z0JBQ0EsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBRTVDLElBQUksQ0FBQSxNQUFBLElBQUksQ0FBQyxlQUFlLDBDQUFFLEVBQUUsTUFBSyxPQUFPLENBQUMsRUFBRTtvQkFDdkMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO2FBRTlCO1lBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ1IsSUFBSSxDQUFDLDZCQUE2QixDQUFDLENBQUMsRUFBRSw0QkFBNEIsQ0FBQyxDQUFDO2FBQ3ZFOztLQUNKO0lBRUssV0FBVyxDQUFDLE1BQXNCLEVBQUUsT0FBb0IsRUFBRSxPQUFlOztZQUMzRSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRTtnQkFDWixNQUFNLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztnQkFDeEIsT0FBTzthQUNWO1lBRUQsSUFBSTtnQkFDQSxNQUFNLE1BQU0sQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLEVBQUUsRUFBRSxPQUFPLENBQUMsQ0FBQzthQUNqRDtZQUFDLE9BQU8sQ0FBQyxFQUFFO2dCQUNSLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDLEVBQUUsK0JBQStCLENBQUMsQ0FBQztnQkFDdkUsT0FBTzthQUNWO1lBRUQsT0FBTyxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7WUFDMUIsT0FBTyxDQUFDLGNBQWMsQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO1FBQzNDLENBQUM7S0FBQTtJQUVLLFlBQVksQ0FBQyxPQUFvQjs7WUFDbkMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxjQUFjLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztZQUNwRCxPQUFPLENBQUMsY0FBYyxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUM7UUFDMUMsQ0FBQztLQUFBO0lBRUssUUFBUSxDQUFDLE9BQW9CLEVBQUUsSUFBWTs7WUFDN0MsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUU7Z0JBQ1osTUFBTSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7Z0JBQ3hCLE9BQU87YUFDVjtZQUVELElBQUk7Z0JBQ0EsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxDQUFDO2dCQUNoRCxPQUFPLENBQUMsY0FBYyxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7YUFDMUM7WUFBQyxPQUFPLENBQUMsRUFBRTtnQkFDUixJQUFJLENBQUMsNkJBQTZCLENBQUMsQ0FBQyxFQUFFLDBCQUEwQixDQUFDLENBQUM7YUFDckU7UUFDTCxDQUFDO0tBQUE7OztZQXZ0QkosU0FBUyxTQUFDO2dCQUNQLFFBQVEsRUFBRSxnQkFBZ0I7Z0JBQzFCLDZqWUFBOEM7O2FBRWpEOzs7WUFmUSxlQUFlO1lBUFUsVUFBVTtZQU1uQyxjQUFjO1lBR2QsV0FBVztZQVQ4QyxNQUFNOzs7NEJBa0huRSxXQUFXLFNBQUMsb0JBQW9CO3VDQUdoQyxZQUFZLFNBQUMsOEJBQThCLEVBQUUsRUFBQyxJQUFJLEVBQUUsV0FBVyxFQUFDOzhCQWdGaEUsS0FBSzsrQkFzQkwsS0FBSzs4QkFDTCxLQUFLOytCQVlMLEtBQUs7MEJBWUwsU0FBUyxTQUFDLGFBQWE7OEJBR3ZCLFlBQVksU0FBQyxvQkFBb0I7MEJBNEZqQyxLQUFLO3dCQUNMLEtBQUs7eUJBQ0wsS0FBSzsyQkFDTCxLQUFLO29DQUNMLEtBQUs7K0JBQ0wsS0FBSzs2QkFDTCxLQUFLOytCQUNMLEtBQUs7MEJBQ0wsS0FBSzswQkFDTCxLQUFLO2lDQUNMLEtBQUs7K0JBQ0wsS0FBSzt5Q0FFTCxLQUFLOzJCQUNMLEtBQUs7cUJBSUwsS0FBSzt1QkE0Q0wsS0FBSztzQkFNTCxLQUFLOzZCQVdMLE1BQU07aUNBQ04sTUFBTTtvQ0FDTixNQUFNO3NCQUNOLE1BQU07dUJBQ04sTUFBTTt1QkFDTixNQUFNOzJCQUNOLE1BQU07K0JBQ04sTUFBTTs2QkFDTixNQUFNO3FCQUNOLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyIvLy8gPHJlZmVyZW5jZSB0eXBlcz1cIkB0eXBlcy9yZXNpemUtb2JzZXJ2ZXItYnJvd3NlclwiIC8+XHJcblxyXG5pbXBvcnQgeyBDb21wb25lbnQsIENvbnRlbnRDaGlsZCwgRWxlbWVudFJlZiwgSG9zdEJpbmRpbmcsIElucHV0LCBOZ1pvbmUsIE91dHB1dCwgUXVlcnlMaXN0LCBUZW1wbGF0ZVJlZiwgVmlld0NoaWxkLCBWaWV3Q2hpbGRyZW4gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgVXNlciwgQ2hhdE1lc3NhZ2UsIENvbW1lbnRzT3JkZXIgfSBmcm9tICdAYmFudGEvY29tbW9uJztcclxuaW1wb3J0IHsgSGFzaFRhZyB9IGZyb20gJy4uL2NvbW1lbnQtZmllbGQvY29tbWVudC1maWVsZC5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBTdWJqZWN0LCBPYnNlcnZhYmxlLCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgdGFrZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuXHJcbmltcG9ydCB7IEFjdGl2YXRlZFJvdXRlIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcclxuaW1wb3J0IHsgQ2hhdEJhY2tlbmRCYXNlIH0gZnJvbSAnLi4vLi4vY2hhdC1iYWNrZW5kLWJhc2UnO1xyXG5pbXBvcnQgeyBDaGF0U291cmNlQmFzZSB9IGZyb20gJy4uLy4uL2NoYXQtc291cmNlLWJhc2UnO1xyXG5pbXBvcnQgeyBNYXRTbmFja0JhciB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3NuYWNrLWJhcic7XHJcbmltcG9ydCB7IEJhbnRhUmVwbHlTZW5kT3B0aW9uc0RpcmVjdGl2ZSB9IGZyb20gJy4uL3JlcGx5LXNlbmQtb3B0aW9ucy5kaXJlY3RpdmUnO1xyXG5pbXBvcnQgeyBNZXNzYWdlTWVudUl0ZW0gfSBmcm9tICcuLi8uLi9tZXNzYWdlLW1lbnUtaXRlbSc7XHJcbmltcG9ydCB7IENvbW1lbnRWaWV3Q29tcG9uZW50IH0gZnJvbSAnLi4vY29tbWVudC12aWV3L2NvbW1lbnQtdmlldy5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBDb21tZW50Q29tcG9uZW50IH0gZnJvbSAnLi4vY29tbWVudC9jb21tZW50LmNvbXBvbmVudCc7XHJcblxyXG4vKipcclxuICogQ29tbWVudHMgY29tcG9uZW50XHJcbiAqL1xyXG5AQ29tcG9uZW50KHtcclxuICAgIHNlbGVjdG9yOiAnYmFudGEtY29tbWVudHMnLFxyXG4gICAgdGVtcGxhdGVVcmw6ICcuL2JhbnRhLWNvbW1lbnRzLmNvbXBvbmVudC5odG1sJyxcclxuICAgIHN0eWxlVXJsczogWycuL2JhbnRhLWNvbW1lbnRzLmNvbXBvbmVudC5zY3NzJ11cclxufSlcclxuZXhwb3J0IGNsYXNzIEJhbnRhQ29tbWVudHNDb21wb25lbnQge1xyXG4gICAgY29uc3RydWN0b3IoXHJcbiAgICAgICAgcHJpdmF0ZSBiYWNrZW5kOiBDaGF0QmFja2VuZEJhc2UsXHJcbiAgICAgICAgcHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PixcclxuICAgICAgICBwcml2YXRlIGFjdGl2YXRlZFJvdXRlOiBBY3RpdmF0ZWRSb3V0ZSxcclxuICAgICAgICBwcml2YXRlIG1hdFNuYWNrQmFyOiBNYXRTbmFja0JhcixcclxuICAgICAgICBwcml2YXRlIG5nWm9uZTogTmdab25lXHJcbiAgICApIHtcclxuICAgICAgICB0aGlzLnNlbmRNZXNzYWdlID0gYXN5bmMgKG1lc3NhZ2U6IENoYXRNZXNzYWdlKSA9PiB7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBpbnRlcmNlcHQgPSBhd2FpdCB0aGlzLnNob3VsZEludGVyY2VwdE1lc3NhZ2VTZW5kPy4obWVzc2FnZSwgdGhpcy5zb3VyY2UpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFpbnRlcmNlcHQpIHtcclxuICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnNvdXJjZS5zZW5kKG1lc3NhZ2UpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnNvdXJjZS5zb3J0T3JkZXIgIT09IENvbW1lbnRzT3JkZXIuTkVXRVNUKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zb3J0T3JkZXIgPSBDb21tZW50c09yZGVyLk5FV0VTVDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZUJhY2tlbmRFeGNlcHRpb24oZSwgJ0NvdWxkIG5vdCBzZW5kOiAnKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5zZW5kUmVwbHkgPSBhc3luYyAobWVzc2FnZTogQ2hhdE1lc3NhZ2UpID0+IHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGludGVyY2VwdCA9IGF3YWl0IHRoaXMuc2hvdWxkSW50ZXJjZXB0TWVzc2FnZVNlbmQ/LihtZXNzYWdlLCB0aGlzLnNlbGVjdGVkTWVzc2FnZVRocmVhZCk7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWludGVyY2VwdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuc2VsZWN0ZWRNZXNzYWdlVGhyZWFkLnNlbmQobWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5oYW5kbGVCYWNrZW5kRXhjZXB0aW9uKGUsICdDb3VsZCBub3Qgc2VuZCByZXBseTogJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IGVsZW1lbnQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50O1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgaGFuZGxlQmFja2VuZEV4Y2VwdGlvbkFzQWxlcnQoZTogRXJyb3IsIHByZWZpeDogc3RyaW5nID0gJycpIHtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICB0aGlzLmhhbmRsZUJhY2tlbmRFeGNlcHRpb24oZSwgcHJlZml4KTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgIGFsZXJ0KGUubWVzc2FnZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgaGFuZGxlQmFja2VuZEV4Y2VwdGlvbihlOiBFcnJvciwgcHJlZml4OiBzdHJpbmcgPSAnJykge1xyXG4gICAgICAgIGxldCBlcnJvck1lc3NhZ2UgPSBlLm1lc3NhZ2U7XHJcblxyXG4gICAgICAgIGlmIChlcnJvck1lc3NhZ2Uuc3RhcnRzV2l0aCgncGVybWlzc2lvbi1kZW5pZWR8JykpIHtcclxuICAgICAgICAgICAgZXJyb3JNZXNzYWdlID0gZXJyb3JNZXNzYWdlLnJlcGxhY2UoL15wZXJtaXNzaW9uLWRlbmllZFxcfC8sICcnKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChlcnJvck1lc3NhZ2Uuc3RhcnRzV2l0aChgYXBwLWhhbmRsZXxgKSkge1xyXG4gICAgICAgICAgICAgICAgLy8gSWYgdGhpcyBpcyBhbiBlcnJvciBkdXJpbmcgYXV0aG9yaXplQWN0aW9uIG9uIHRoZSBiYWNrZW5kLCBwYXNzIGNvbnRyb2wgdG8gdGhlIHVzZXItcHJvdmlkZWQgXHJcbiAgICAgICAgICAgICAgICAvLyBwZXJtaXNzaW9uLWRlbmllZCBoYW5kbGVyLlxyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuc2VuZFBlcm1pc3Npb25EZW5pZWQoZXJyb3JNZXNzYWdlLnJlcGxhY2UoL15hcHAtaGFuZGxlXFx8LywgJycpKTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3ByZWZpeH0ke2Vycm9yTWVzc2FnZX1gKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBMaWZlY3ljbGUgRXZlbnRzIC8gSW5pdGlhbGl6YXRpb25cclxuXHJcbiAgICBuZ09uSW5pdCgpIHtcclxuICAgICAgICB0aGlzLl9zdWJzLmFkZCh0aGlzLmJhY2tlbmQudXNlckNoYW5nZWQuc3Vic2NyaWJlKHVzZXIgPT4gdGhpcy51c2VyID0gdXNlcikpO1xyXG4gICAgICAgIHRoaXMuc3RhcnRMb2FkaW5nKCk7XHJcblxyXG4gICAgICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgICAgICBsZXQgcXVlcnlTdHJpbmcgPSB3aW5kb3cubG9jYXRpb24uc2VhcmNoLnN1YnN0cmluZygxKTtcclxuICAgICAgICAgICAgbGV0IHF1ZXJ5ID0gcXVlcnlTdHJpbmcuc3BsaXQoJyYnKVxyXG4gICAgICAgICAgICAgICAgLm1hcChzID0+IHMuc3BsaXQoJz0nKSlcclxuICAgICAgICAgICAgICAgIC5yZWR1Y2UoKG8sIFtrLCB2XSkgPT4gKG9bZGVjb2RlVVJJQ29tcG9uZW50KGspXSA9IGRlY29kZVVSSUNvbXBvbmVudCh2KSwgbyksIHt9KVxyXG4gICAgICAgICAgICA7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBjb21tZW50SUQgPSBxdWVyeVsnY29tbWVudCddO1xyXG4gICAgICAgICAgICBpZiAoY29tbWVudElEKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNoYXJlZENvbW1lbnRJRCA9IGNvbW1lbnRJRDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHJlc2l6ZU9ic2VydmVyOiBSZXNpemVPYnNlcnZlcjtcclxuICAgIHByaXZhdGUgd2lkdGg6IG51bWJlcjtcclxuICAgIHByaXZhdGUgaGVpZ2h0OiBudW1iZXI7XHJcblxyXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5iYW50YS1tb2JpbGUnKVxyXG4gICAgaXNNb2JpbGVTaXplZDogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAgIEBDb250ZW50Q2hpbGQoQmFudGFSZXBseVNlbmRPcHRpb25zRGlyZWN0aXZlLCB7cmVhZDogVGVtcGxhdGVSZWZ9KSBcclxuICAgIHNlbmRSZXBseU9wdGlvbnNUZW1wbGF0ZTogYW55O1xyXG5cclxuICAgIG1hcmtWaWV3UmVhZHk6ICgpID0+IHZvaWQ7XHJcbiAgICB2aWV3UmVhZHkgPSBuZXcgUHJvbWlzZTx2b2lkPihyID0+IHRoaXMubWFya1ZpZXdSZWFkeSA9IHIpO1xyXG5cclxuICAgIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcclxuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICAgICAgbGV0IGNhbGxiYWNrID0gKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgbGV0IHNpemUgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgICAgICAgICAgICAgIHRoaXMubmdab25lLnJ1bigoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMud2lkdGggPSBzaXplLndpZHRoO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhlaWdodCA9IHNpemUuaGVpZ2h0O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzTW9iaWxlU2l6ZWQgPSB0aGlzLndpZHRoIDwgNTAwO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgUmVzaXplT2JzZXJ2ZXIgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnJlc2l6ZU9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKGNhbGxiYWNrKTtcclxuICAgICAgICAgICAgICAgIHRoaXMucmVzaXplT2JzZXJ2ZXIub2JzZXJ2ZSh0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyBPbmUgY2hlY2sgaXMgYmV0dGVyIHRoYW4gbm90aGluZyFcclxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMud2lkdGggPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5jbGllbnRXaWR0aDtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmhlaWdodCA9IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LmNsaWVudEhlaWdodDtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmlzTW9iaWxlU2l6ZWQgPSB0aGlzLndpZHRoIDwgNTAwO1xyXG4gICAgICAgICAgICAgICAgfSwgMTAwMCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNhbGxiYWNrKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLm1hcmtWaWV3UmVhZHkoKTtcclxuICAgIH1cclxuXHJcbiAgICBuZ09uRGVzdHJveSgpIHtcclxuICAgICAgICB0aGlzLl9zdWJzLnVuc3Vic2NyaWJlKCk7XHJcbiAgICAgICAgaWYgKHRoaXMucmVzaXplT2JzZXJ2ZXIpXHJcbiAgICAgICAgICAgIHRoaXMucmVzaXplT2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgYXN5bmMgc2V0U291cmNlRnJvbVRvcGljSUQodG9waWNJRDogc3RyaW5nKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcblxyXG4gICAgICAgIHNldFRpbWVvdXQoYXN5bmMgKCkgPT4ge1xyXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgW2JhbnRhLWNvbW1lbnRzXSBTdWJzY3JpYmluZyB0byB0b3BpYyBzb3VyY2UgJyR7dG9waWNJRH0nYCk7XHJcbiAgICAgICAgICAgIHRoaXMuc291cmNlID0gYXdhaXQgdGhpcy5iYWNrZW5kLmdldFNvdXJjZUZvclRvcGljKHRvcGljSUQsIHsgc29ydE9yZGVyOiB0aGlzLnNvcnRPcmRlciB9KTtcclxuICAgICAgICAgICAgdGhpcy5fc291cmNlSXNPd25lZCA9IHRydWU7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gTG9hZGluZyBTY3JlZW5cclxuICAgIHByaXZhdGUgX2xvYWRpbmdNZXNzYWdlID0gJyc7XHJcbiAgICBsb2FkaW5nTWVzc2FnZVZpc2libGUgPSBmYWxzZTtcclxuXHJcbiAgICBnZXQgbG9hZGluZ01lc3NhZ2UoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2xvYWRpbmdNZXNzYWdlO1xyXG4gICAgfVxyXG5cclxuICAgIHNldCBsb2FkaW5nTWVzc2FnZSh2YWx1ZSkge1xyXG4gICAgICAgIHRoaXMubG9hZGluZ01lc3NhZ2VWaXNpYmxlID0gZmFsc2U7XHJcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRpbmdNZXNzYWdlID0gdmFsdWU7XHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRpbmdNZXNzYWdlID0gdmFsdWU7XHJcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5sb2FkaW5nTWVzc2FnZVZpc2libGUgPSB0cnVlO1xyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgIH0sIDUwMCk7XHJcbiAgICB9XHJcblxyXG4gICAgbG9hZGluZzogYm9vbGVhbiA9IHRydWU7XHJcbiAgICBzaG93TG9hZGluZ1NjcmVlbiA9IGZhbHNlO1xyXG4gICAgbG9hZGluZ1N0YXJ0ZWRBdDogbnVtYmVyO1xyXG4gICAgbWVzc2FnZUNoYW5nZWRBdDogbnVtYmVyO1xyXG4gICAgc2hhcmVkQ29tbWVudElEOiBzdHJpbmc7XHJcbiAgICBsYXN0U2hhcmVkQ29tbWVudElEOiBzdHJpbmc7XHJcblxyXG4gICAgQElucHV0KCkgY3VzdG9tTWVudUl0ZW1zOiBNZXNzYWdlTWVudUl0ZW1bXSA9IFtdO1xyXG5cclxuICAgIHByaXZhdGUgYXN5bmMgc3RhcnRMb2FkaW5nKCkge1xyXG4gICAgICAgIHRoaXMubG9hZGluZ1N0YXJ0ZWRBdCA9IHRoaXMubWVzc2FnZUNoYW5nZWRBdCA9IERhdGUubm93KCk7XHJcblxyXG4gICAgICAgIGlmICh0aGlzLnVwZGF0ZUxvYWRpbmcoKSkgcmV0dXJuO1xyXG4gICAgICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KHJlc29sdmUgPT4gc2V0VGltZW91dCgoKSA9PiByZXNvbHZlKCksIDEwMCkpO1xyXG4gICAgICAgIGlmICh0aGlzLnVwZGF0ZUxvYWRpbmcoKSkgcmV0dXJuO1xyXG4gICAgICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KHJlc29sdmUgPT4gc2V0VGltZW91dCgoKSA9PiByZXNvbHZlKCksIDI1MCkpO1xyXG4gICAgICAgIGlmICh0aGlzLnVwZGF0ZUxvYWRpbmcoKSkgcmV0dXJuO1xyXG4gICAgICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KHJlc29sdmUgPT4gc2V0VGltZW91dCgoKSA9PiByZXNvbHZlKCksIDUwMCkpO1xyXG4gICAgICAgIGlmICh0aGlzLnVwZGF0ZUxvYWRpbmcoKSkgcmV0dXJuO1xyXG5cclxuICAgICAgICBjb25zb2xlLmxvZyhgW0JhbnRhXSBMb2FkaW5nIGlzIHRha2luZyBhIGxvbmcgdGltZSEgU2hvd2luZyBsb2FkaW5nIHNjcmVlbi5gKTtcclxuICAgICAgICB0aGlzLnNob3dMb2FkaW5nU2NyZWVuID0gdHJ1ZTtcclxuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpXHJcbiAgICAgICAgICAgIHRoaXMuX2xvYWRpbmdUaW1lciA9IHNldEludGVydmFsKCgpID0+IHRoaXMudXBkYXRlTG9hZGluZygpLCAxMDAwKTtcclxuICAgIH1cclxuICAgIFxyXG4gICAgcHJpdmF0ZSBfbG9hZGluZ1RpbWVyO1xyXG4gICAgcHJpdmF0ZSBfbG9hZGluZ01lc3NhZ2VJbmRleCA9IDA7XHJcblxyXG4gICAgQElucHV0KCkgbWF4Q29tbWVudExlbmd0aDogbnVtYmVyID0gMTUwMDtcclxuICAgIEBJbnB1dCgpIGxvYWRpbmdNZXNzYWdlczogc3RyaW5nW10gPSBbXHJcbiAgICAgICAgYEp1c3QgYSBzZWNvbmQuLi5gLFxyXG4gICAgICAgIGBXZSdyZSBkZWZpbml0ZWx5IHdvcmtpbmcgb24gaXQuYCxcclxuICAgICAgICBgVGhlcmUncyBubyBuZWVkIHRvIHJlZnJlc2guYCxcclxuICAgICAgICBgSXQncyBkZWZpbml0ZWx5IHdvcnRoIHRoZSB3YWl0IWAsXHJcbiAgICAgICAgYFRoaXMgaGFzIG5ldmVyIGhhcHBlbmVkIGJlZm9yZS5gLFxyXG4gICAgICAgIGBXZSdsbCBrZWVwIHRyeWluZywgYnV0IGl0J3Mgbm90IGxvb2tpbmcgZ3JlYXQuIFxyXG4gICAgICAgICAgICBDb21tZW50aW5nICYgY2hhdCBzZXJ2aWNlcyBtYXkgYmUgZG93bi4gXHJcbiAgICAgICAgICAgIElmIHlvdSBjb250aW51ZSB0byBleHBlcmllbmNlIGlzc3VlcywgcGxlYXNlIGNvbnRhY3Qgc3VwcG9ydC5cclxuICAgICAgICBgXHJcbiAgICBdO1xyXG5cclxuICAgIEBJbnB1dCgpIHVzZUlubGluZVJlcGxpZXMgPSB0cnVlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWNjZXNzIHRoZSBDb21tZW50Vmlld0NvbXBvbmVudCBmb3IgdGhpcyBCYW50YUNvbW1lbnRzQ29tcG9uZW50LiBcclxuICAgICAqIENvbW1lbnRWaWV3Q29tcG9uZW50IGlzIHJlc3BvbnNpYmxlIGZvciBpbnRlcmFjdGluZyB3aXRoIHRoZSBDaGF0U291cmNlIFxyXG4gICAgICogb2JqZWN0IGFuZCByZW5kZXJpbmcgY29tbWVudHMgYXMgQ29tbWVudENvbXBvbmVudHMuIEl0IGlzIHRoZSBzb3VyY2Ugb2YgXHJcbiAgICAgKiB0cnV0aCBmb3Igd2hpY2ggQ29tbWVudENvbXBvbmVudCBjb3JyZXNwb25kcyB0byB3aGljaCBDaGF0TWVzc2FnZS4gXHJcbiAgICAgKiBcclxuICAgICAqIE5vdGUgdGhhdCB0aGlzIENvbW1lbnRWaWV3Q29tcG9uZW50IGlzIG9ubHkgZm9yIHRoZSB0b3AgbGV2ZWwgY29tbWVudHMuXHJcbiAgICAgKiBSZXBsaWVzIGFyZSBoYW5kbGVkIGJ5IGEgc2VwYXJhdGUgQ29tbWVudFZpZXdDb21wb25lbnQgd2hpY2ggY2FuIGJlIFxyXG4gICAgICogcmV0cmlldmVkIHVzaW5nIHRoZSB0aHJlYWRWaWV3IHByb3BlcnR5LlxyXG4gICAgICovXHJcbiAgICBAVmlld0NoaWxkKCdjb21tZW50VmlldycpXHJcbiAgICBjb21tZW50VmlldzogQ29tbWVudFZpZXdDb21wb25lbnQ7XHJcblxyXG4gICAgQFZpZXdDaGlsZHJlbihDb21tZW50Vmlld0NvbXBvbmVudClcclxuICAgIHRocmVhZFZpZXdRdWVyeTogUXVlcnlMaXN0PENvbW1lbnRWaWV3Q29tcG9uZW50PjtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEF0dGVtcHRzIHRvIGZpbmQgdGhlIENvbW1lbnRDb21wb25lbnQgdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgZ2l2ZW4gQ2hhdE1lc3NhZ2UuXHJcbiAgICAgKiBUaGUgQ2hhdE1lc3NhZ2UgY291bGQgYmUgYSB0b3AtbGV2ZWwgbWVzc2FnZSBpbiB0aGlzIGNvbnZlcnNhdGlvbiwgb3IgYSByZXBseSwgXHJcbiAgICAgKiBidXQgbm90ZSB0aGF0IGEgQ29tbWVudENvbXBvbmVudCB3aWxsIG9ubHkgZXhpc3QgZm9yIGEgcmVwbHkgaWYgdGhlIHVzZXIgaGFzIFxyXG4gICAgICogdGhlIHJlbGV2YW50IHJlcGx5IHRocmVhZCBvcGVuLlxyXG4gICAgICogQHBhcmFtIG1lc3NhZ2UgVGhlIG1lc3NhZ2UgdG8gbG9vayBmb3JcclxuICAgICAqL1xyXG4gICAgZ2V0Q29tbWVudENvbXBvbmVudEZvck1lc3NhZ2UobWVzc2FnZTogQ2hhdE1lc3NhZ2UpOiBDb21tZW50Q29tcG9uZW50IHtcclxuICAgICAgICBpZiAobWVzc2FnZS5wYXJlbnRNZXNzYWdlSWQpXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnRocmVhZFZpZXc/LmdldENvbW1lbnRDb21wb25lbnRGb3JNZXNzYWdlKG1lc3NhZ2UpO1xyXG4gICAgICAgIGVsc2VcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29tbWVudFZpZXcuZ2V0Q29tbWVudENvbXBvbmVudEZvck1lc3NhZ2UobWVzc2FnZSlcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFjY2VzcyB0aGUgQ29tbWVudFZpZXdDb21wb25lbnQgY29ycmVzcG9uZGluZyB0byB0aGUgY3VycmVudGx5IG9wZW4gcmVwbHkgdGhyZWFkLlxyXG4gICAgICogVGhpcyBpcyBub3QgdGhlIHRvcCBsZXZlbCBjb21tZW50cywgYnV0IGluc3RlYWQgdGhlIHJlcGx5IHRocmVhZCB0aGF0IHRoZSB1c2VyIGhhcyBcclxuICAgICAqIG9wZW5lZCAob25seSBvbmUgc2V0IG9mIHJlcGxpZXMgY2FuIGJlIG9wZW4gYXQgYSB0aW1lKS5cclxuICAgICAqIFxyXG4gICAgICogRm9yIGRldGFpbHMgYWJvdXQgd2hhdCBDb21tZW50Vmlld0NvbXBvbmVudCBhZmZvcmRzIHlvdSwgc2VlIHRoZSBjb21tZW50VmlldyBwcm9wZXJ0eS5cclxuICAgICAqL1xyXG4gICAgZ2V0IHRocmVhZFZpZXcoKSB7XHJcbiAgICAgICAgcmV0dXJuIEFycmF5LmZyb20odGhpcy50aHJlYWRWaWV3UXVlcnkpLmZpbHRlcih4ID0+IHggIT09IHRoaXMuY29tbWVudFZpZXcpWzBdO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIHdhaXRGb3JUaHJlYWRWaWV3KCkge1xyXG4gICAgICAgIGlmICh0aGlzLnRocmVhZFZpZXcpXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnRocmVhZFZpZXc7XHJcbiAgICAgICAgXHJcbiAgICAgICAgYXdhaXQgdGhpcy50aHJlYWRWaWV3UXVlcnkuY2hhbmdlcy5waXBlKHRha2UoMSkpLnRvUHJvbWlzZSgpO1xyXG4gICAgICAgIHJldHVybiB0aGlzLnRocmVhZFZpZXc7XHJcbiAgICB9XHJcblxyXG4gICAgbWFya0xvYWRlZDogKCkgPT4gdm9pZDtcclxuICAgIGxvYWRlZCA9IG5ldyBQcm9taXNlPHZvaWQ+KHIgPT4gdGhpcy5tYXJrTG9hZGVkID0gcik7XHJcblxyXG4gICAgcHJpdmF0ZSB1cGRhdGVMb2FkaW5nKCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIGlmICh0aGlzLnNvdXJjZT8uc3RhdGUgJiYgdGhpcy5zb3VyY2U/LnN0YXRlICE9PSAnY29ubmVjdGluZycpIHtcclxuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLl9sb2FkaW5nVGltZXIpO1xyXG4gICAgICAgICAgICB0aGlzLmxvYWRpbmdNZXNzYWdlID0gYEhlcmUgd2UgZ28hYDtcclxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxvYWRpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIHRoaXMubWFya0xvYWRlZCgpO1xyXG4gICAgICAgICAgICB9LCA3NTApO1xyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBtZXNzYWdlU3dpdGNoVGltZSA9IDUqMTAwMDtcclxuICAgICAgICBpZiAodGhpcy5tZXNzYWdlQ2hhbmdlZEF0ICsgbWVzc2FnZVN3aXRjaFRpbWUgPCBEYXRlLm5vdygpKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmxvYWRpbmdNZXNzYWdlc1t0aGlzLl9sb2FkaW5nTWVzc2FnZUluZGV4XSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5sb2FkaW5nTWVzc2FnZSA9IHRoaXMubG9hZGluZ01lc3NhZ2VzW3RoaXMuX2xvYWRpbmdNZXNzYWdlSW5kZXgrK107XHJcbiAgICAgICAgICAgICAgICB0aGlzLm1lc3NhZ2VDaGFuZ2VkQXQgPSBEYXRlLm5vdygpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gUHJvcGVydGllc1xyXG5cclxuICAgIHByaXZhdGUgX3NpZ25JblNlbGVjdGVkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcclxuICAgIHByaXZhdGUgX3Blcm1pc3Npb25EZW5pZWRFcnJvciA9IG5ldyBTdWJqZWN0PHN0cmluZz4oKTtcclxuICAgIHByaXZhdGUgX2VkaXRBdmF0YXJTZWxlY3RlZCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XHJcbiAgICBwcml2YXRlIF91cHZvdGVkID0gbmV3IFN1YmplY3Q8Q2hhdE1lc3NhZ2U+KCk7XHJcbiAgICBwcml2YXRlIF9yZXBvcnRlZCA9IG5ldyBTdWJqZWN0PENoYXRNZXNzYWdlPigpO1xyXG4gICAgcHJpdmF0ZSBfc2VsZWN0ZWQgPSBuZXcgU3ViamVjdDxDaGF0TWVzc2FnZT4oKTtcclxuICAgIHByaXZhdGUgX3VzZXJTZWxlY3RlZCA9IG5ldyBTdWJqZWN0PENoYXRNZXNzYWdlPigpO1xyXG4gICAgcHJpdmF0ZSBfc2hhcmVkID0gbmV3IFN1YmplY3Q8Q2hhdE1lc3NhZ2U+KCk7XHJcbiAgICBwcml2YXRlIF91c2VybmFtZVNlbGVjdGVkID0gbmV3IFN1YmplY3Q8VXNlcj4oKTtcclxuICAgIHByaXZhdGUgX2F2YXRhclNlbGVjdGVkID0gbmV3IFN1YmplY3Q8VXNlcj4oKTtcclxuICAgIHByaXZhdGUgX3NvdXJjZTogQ2hhdFNvdXJjZUJhc2U7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUcmFjayB3aGV0aGVyIHdlIGNyZWF0ZWQgdGhpcyBzb3VyY2UuIElmIHdlIGRpZCBub3QgKGllIGl0IHdhcyBwYXNzZWQgaW4gZnJvbSB0aGUgY2FsbGVyKSxcclxuICAgICAqIHRoZW4gd2UgYXJlIG5vdCByZXNwb25zaWJsZSBmb3IgY2FsbGluZyBjbG9zZSgpLiBJZiB3ZSBkbyBvd24gaXQgdGhvdWdoLCB3ZSB3aWxsIGNhbGwgY2xvc2UoKSBcclxuICAgICAqIHdoZW4gd2UgYXJlIGRvbmUgd2l0aCBpdC5cclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBfc291cmNlSXNPd25lZCA9IGZhbHNlO1xyXG4gICAgcHJpdmF0ZSBfc3VicyA9IG5ldyBTdWJzY3JpcHRpb24oKTtcclxuICAgIHByaXZhdGUgX3NvcnRPcmRlcjogQ29tbWVudHNPcmRlciA9IENvbW1lbnRzT3JkZXIuTkVXRVNUO1xyXG4gICAgcHJpdmF0ZSBfdG9waWNJRDogc3RyaW5nO1xyXG4gICAgXHJcbiAgICB1c2VyOiBVc2VyO1xyXG4gICAgc2VsZWN0ZWRNZXNzYWdlOiBDaGF0TWVzc2FnZTtcclxuICAgIHNlbGVjdGVkTWVzc2FnZVRocmVhZDogQ2hhdFNvdXJjZUJhc2U7XHJcbiAgICBzZWxlY3RlZE1lc3NhZ2VWaXNpYmxlID0gZmFsc2U7XHJcblxyXG4gICAgLy8gSW5wdXRzXHJcblxyXG4gICAgQElucHV0KCkgc2lnbkluTGFiZWwgPSAnU2lnbiBJbic7XHJcbiAgICBASW5wdXQoKSBzZW5kTGFiZWwgPSAnU2VuZCc7XHJcbiAgICBASW5wdXQoKSByZXBseUxhYmVsID0gJ1JlcGx5JztcclxuICAgIEBJbnB1dCgpIHNlbmRpbmdMYWJlbCA9ICdTZW5kaW5nJztcclxuICAgIEBJbnB1dCgpIHBlcm1pc3Npb25EZW5pZWRMYWJlbCA9ICdTZW5kJztcclxuICAgIEBJbnB1dCgpIHBvc3RDb21tZW50TGFiZWwgPSAnUG9zdCBhIGNvbW1lbnQnO1xyXG4gICAgQElucHV0KCkgcG9zdFJlcGx5TGFiZWwgPSAnUG9zdCBhIHJlcGx5JztcclxuICAgIEBJbnB1dCgpIGFsbG93QXR0YWNobWVudHMgPSB0cnVlO1xyXG4gICAgQElucHV0KCkgZml4ZWRIZWlnaHQ6IGJvb2xlYW47XHJcbiAgICBASW5wdXQoKSBtYXhNZXNzYWdlczogbnVtYmVyO1xyXG4gICAgQElucHV0KCkgbWF4VmlzaWJsZU1lc3NhZ2VzOiBudW1iZXIgPSAyMDtcclxuICAgIEBJbnB1dCgpIGdlbmVyaWNBdmF0YXJVcmwgPSBgaHR0cHM6Ly9ncmF2YXRhci5jb20vYXZhdGFyLyR7RGF0ZS5ub3coKS50b1N0cmluZygxNil9P3M9NTEyJmQ9cm9ib2hhc2hgO1xyXG5cclxuICAgIEBJbnB1dCgpIHNob3VsZEludGVyY2VwdE1lc3NhZ2VTZW5kPzogKG1lc3NhZ2U6IENoYXRNZXNzYWdlLCBzb3VyY2U6IENoYXRTb3VyY2VCYXNlKSA9PiBib29sZWFuIHwgUHJvbWlzZTxib29sZWFuPjtcclxuICAgIEBJbnB1dCgpIHBhcnRpY2lwYW50czogVXNlcltdID0gW107XHJcblxyXG4gICAgcHJpdmF0ZSBfc291cmNlU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb247XHJcblxyXG4gICAgQElucHV0KClcclxuICAgIGdldCBzb3VyY2UoKTogQ2hhdFNvdXJjZUJhc2UgeyByZXR1cm4gdGhpcy5fc291cmNlOyB9XHJcbiAgICBzZXQgc291cmNlKHZhbHVlKSB7IFxyXG4gICAgICAgIGlmICh0aGlzLl9zb3VyY2UgJiYgdGhpcy5fc291cmNlSXNPd25lZCkge1xyXG4gICAgICAgICAgICB0aGlzLl9zb3VyY2UuY2xvc2UoKTtcclxuICAgICAgICAgICAgdGhpcy5fc291cmNlU3Vic2NyaXB0aW9uPy51bnN1YnNjcmliZSgpO1xyXG4gICAgICAgICAgICB0aGlzLl9zb3VyY2UgPSBudWxsO1xyXG4gICAgICAgICAgICB0aGlzLnBhcnRpY2lwYW50cyA9IFtdO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGhpcy5fc291cmNlID0gdmFsdWU7XHJcbiAgICAgICAgdGhpcy5fc291cmNlSXNPd25lZCA9IGZhbHNlOyAvLyBBc3N1bWUgd2UgZG9uJ3Qgb3duIHRoaXMgc291cmNlLlxyXG4gICAgICAgIHRoaXMuX3NvdXJjZVN1YnNjcmlwdGlvbiA9IG5ldyBTdWJzY3JpcHRpb24oKTtcclxuICAgICAgICBcclxuICAgICAgICBpZiAodmFsdWUpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuc2hhcmVkQ29tbWVudElEKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm5hdmlnYXRlVG9TaGFyZWRDb21tZW50KHRoaXMuc2hhcmVkQ29tbWVudElEKTtcclxuICAgICAgICAgICAgICAgIHRoaXMubGFzdFNoYXJlZENvbW1lbnRJRCA9IHRoaXMuc2hhcmVkQ29tbWVudElEO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zaGFyZWRDb21tZW50SUQgPSBudWxsO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB0aGlzLl9zb3VyY2UubWVzc2FnZXMuZm9yRWFjaChtID0+IHRoaXMuYWRkUGFydGljaXBhbnQobSkpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5fc291cmNlU3Vic2NyaXB0aW9uLmFkZCh0aGlzLl9zb3VyY2UubWVzc2FnZVJlY2VpdmVkLnN1YnNjcmliZShtID0+IHRoaXMuYWRkUGFydGljaXBhbnQobSkpKTtcclxuICAgICAgICAgICAgdGhpcy5fc291cmNlU3Vic2NyaXB0aW9uLmFkZCh0aGlzLl9zb3VyY2UubWVzc2FnZVNlbnQuc3Vic2NyaWJlKG0gPT4gdGhpcy5hZGRQYXJ0aWNpcGFudChtKSkpO1xyXG4gICAgICAgICAgICB0aGlzLl9zb3VyY2VTdWJzY3JpcHRpb24uYWRkKHRoaXMuX3NvdXJjZS5tZXNzYWdlT2JzZXJ2ZWQuc3Vic2NyaWJlKG0gPT4gdGhpcy5hZGRQYXJ0aWNpcGFudChtKSkpO1xyXG4gICAgICAgICAgICB0aGlzLl9zb3VyY2VTdWJzY3JpcHRpb24uYWRkKFxyXG4gICAgICAgICAgICAgICAgdGhpcy5fc291cmNlLm1lc3NhZ2VVcGRhdGVkLnN1YnNjcmliZShtc2cgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBjb21tZW50cyByZWNlaXZlZCBtZXNzYWdlOiBgLCBtc2cpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChtc2cuaWQgPT09IHRoaXMuc2VsZWN0ZWRNZXNzYWdlPy5pZCAmJiBtc2cuaGlkZGVuKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudW5zZWxlY3RNZXNzYWdlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubWF0U25hY2tCYXIub3BlbihcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiVGhlIHRocmVhZCB5b3Ugd2VyZSB2aWV3aW5nIHdhcyByZW1vdmVkLlwiLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5kZWZpbmVkLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uOiAyNTAwXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIClcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICApO1xyXG5cclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBASW5wdXQoKSBcclxuICAgIGhhc2h0YWdzOiBIYXNoVGFnW10gPSBbXHJcbiAgICAgICAge2hhc2h0YWc6ICdlcnJvcicsIGRlc2NyaXB0aW9uOiAnQ2F1c2UgYW4gZXJyb3InfSxcclxuICAgICAgICB7aGFzaHRhZzogJ3RpbWVvdXQnLCBkZXNjcmlwdGlvbjogJ0NhdXNlIGEgc2xvdyB0aW1lb3V0IGVycm9yJ30sXHJcbiAgICAgICAge2hhc2h0YWc6ICdzbG93JywgZGVzY3JpcHRpb246ICdCZSBzbG93IHdoZW4gdGhpcyBtZXNzYWdlIGlzIHBvc3RlZCd9LFxyXG4gICAgXTtcclxuICAgIEBJbnB1dCgpXHJcbiAgICBnZXQgdG9waWNJRCgpOiBzdHJpbmcgeyByZXR1cm4gdGhpcy5fdG9waWNJRDsgfVxyXG4gICAgc2V0IHRvcGljSUQodmFsdWUpIHtcclxuICAgICAgICBpZiAodGhpcy5fdG9waWNJRCAhPT0gdmFsdWUpIHtcclxuICAgICAgICAgICAgdGhpcy5fdG9waWNJRCA9IHZhbHVlO1xyXG4gICAgICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuc2V0U291cmNlRnJvbVRvcGljSUQodmFsdWUpKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgLy8gT3V0cHV0c1xyXG5cclxuICAgIEBPdXRwdXQoKSBnZXQgc2lnbkluU2VsZWN0ZWQoKTogT2JzZXJ2YWJsZTx2b2lkPiB7IHJldHVybiB0aGlzLl9zaWduSW5TZWxlY3RlZDsgfVxyXG4gICAgQE91dHB1dCgpIGdldCBlZGl0QXZhdGFyU2VsZWN0ZWQoKSB7IHJldHVybiB0aGlzLl9lZGl0QXZhdGFyU2VsZWN0ZWQ7IH1cclxuICAgIEBPdXRwdXQoKSBnZXQgcGVybWlzc2lvbkRlbmllZEVycm9yKCk6IE9ic2VydmFibGU8c3RyaW5nPiB7IHJldHVybiB0aGlzLl9wZXJtaXNzaW9uRGVuaWVkRXJyb3I7IH1cclxuICAgIEBPdXRwdXQoKSBnZXQgdXB2b3RlZCgpIHsgcmV0dXJuIHRoaXMuX3Vwdm90ZWQuYXNPYnNlcnZhYmxlKCk7IH1cclxuICAgIEBPdXRwdXQoKSBnZXQgcmVwb3J0ZWQoKSB7IHJldHVybiB0aGlzLl9yZXBvcnRlZC5hc09ic2VydmFibGUoKTsgfVxyXG4gICAgQE91dHB1dCgpIGdldCBzZWxlY3RlZCgpIHsgcmV0dXJuIHRoaXMuX3NlbGVjdGVkLmFzT2JzZXJ2YWJsZSgpOyB9XHJcbiAgICBAT3V0cHV0KCkgZ2V0IHVzZXJTZWxlY3RlZCgpIHsgcmV0dXJuIHRoaXMuX3VzZXJTZWxlY3RlZC5hc09ic2VydmFibGUoKTsgfVxyXG4gICAgQE91dHB1dCgpIGdldCB1c2VybmFtZVNlbGVjdGVkKCkgeyByZXR1cm4gdGhpcy5fdXNlcm5hbWVTZWxlY3RlZC5hc09ic2VydmFibGUoKTsgfVxyXG4gICAgQE91dHB1dCgpIGdldCBhdmF0YXJTZWxlY3RlZCgpIHsgcmV0dXJuIHRoaXMuX2F2YXRhclNlbGVjdGVkLmFzT2JzZXJ2YWJsZSgpOyB9XHJcbiAgICBAT3V0cHV0KCkgZ2V0IHNoYXJlZCgpIHsgcmV0dXJuIHRoaXMuX3NoYXJlZC5hc09ic2VydmFibGUoKTsgfVxyXG5cclxuICAgIGdldCBzb3J0T3JkZXIoKSB7IHJldHVybiB0aGlzLl9zb3J0T3JkZXI7IH1cclxuICAgIHNldCBzb3J0T3JkZXIodmFsdWUpIHtcclxuICAgICAgICBpZiAodGhpcy5fc29ydE9yZGVyICE9PSB2YWx1ZSkge1xyXG4gICAgICAgICAgICB0aGlzLl9zb3J0T3JkZXIgPSB2YWx1ZTtcclxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNldFNvdXJjZUZyb21Ub3BpY0lEKHRoaXMudG9waWNJRCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBzZW5kTWVzc2FnZTogKG1lc3NhZ2U6IENoYXRNZXNzYWdlKSA9PiB2b2lkO1xyXG4gICAgc2VuZFJlcGx5OiAobWVzc2FnZTogQ2hhdE1lc3NhZ2UpID0+IHZvaWQ7XHJcblxyXG4gICAgLy8gVUkgSW50ZXJhY3Rpb25zXHJcblxyXG4gICAgYXN5bmMgc2Nyb2xsVG9Db21tZW50KGNvbW1lbnRJZDogQ2hhdE1lc3NhZ2VbJ2lkJ10pIHtcclxuICAgICAgICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICBcclxuICAgICAgICBhd2FpdCB0aGlzLmNvbW1lbnRWaWV3LndhaXRGb3JBbGxDb21tZW50c1RvTG9hZCgpO1xyXG5cclxuICAgICAgICBjb25zdCBjb21tZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihgW2RhdGEtY29tbWVudC1pZD1cIiR7Y29tbWVudElkfVwiXWApO1xyXG4gICAgICAgIGlmIChjb21tZW50KSB7XHJcbiAgICAgICAgICAgIGNvbW1lbnQuc2Nyb2xsSW50b1ZpZXcoe1xyXG4gICAgICAgICAgICAgICAgaW5saW5lOiAnY2VudGVyJyxcclxuICAgICAgICAgICAgICAgIGJsb2NrOiAnY2VudGVyJ1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgbG9hZGluZ1NoYXJlZENvbW1lbnQgPSBmYWxzZTtcclxuICAgIHNoYXJlZENvbW1lbnRNaXNzaW5nID0gZmFsc2U7XHJcblxyXG4gICAgYXN5bmMgbmF2aWdhdGVUb1NoYXJlZENvbW1lbnQoaWQ6IHN0cmluZykge1xyXG4gICAgICAgIHRoaXMubG9hZGluZ1NoYXJlZENvbW1lbnQgPSB0cnVlO1xyXG4gICAgICAgIGF3YWl0IG5ldyBQcm9taXNlKHIgPT4gc2V0VGltZW91dChyLCAxMCkpO1xyXG4gICAgICAgIHRoaXMuc2hhcmVkQ29tbWVudE1pc3NpbmcgPSBmYWxzZTtcclxuICAgICAgICBsZXQgc291cmNlID0gdGhpcy5zb3VyY2U7XHJcblxyXG4gICAgICAgIGF3YWl0IHNvdXJjZS5yZWFkeTtcclxuICAgICAgICBhd2FpdCB0aGlzLnZpZXdSZWFkeTtcclxuICAgICAgICBhd2FpdCB0aGlzLmxvYWRlZDtcclxuICAgICAgICBcclxuICAgICAgICBjb25zb2xlLmxvZyhgTmF2aWdhdGluZyB0byBzaGFyZWQgY29tbWVudCB3aXRoIElEICcke2lkfScuLi5gKTtcclxuICAgICAgICBsZXQgbWVzc2FnZTogQ2hhdE1lc3NhZ2U7XHJcbiAgICAgICAgXHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgbWVzc2FnZSA9IGF3YWl0IHRoaXMuc291cmNlLmdldChpZCk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGBGYWlsZWQgdG8gZmluZCBjb21tZW50IGZyb20gVVJMOiAke2UubWVzc2FnZX1gKTtcclxuICAgICAgICAgICAgdGhpcy5zaGFyZWRDb21tZW50TWlzc2luZyA9IHRydWU7XHJcbiAgICAgICAgICAgIHRoaXMubG9hZGluZ1NoYXJlZENvbW1lbnQgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGV0IG5vdGljZSA9IHRoaXMuZWxlbWVudC5xdWVyeVNlbGVjdG9yKCcubG9hZGluZy1jb21tZW50Jyk7XHJcbiAgICAgICAgICAgICAgICAgICAgbm90aWNlLnNjcm9sbEludG9WaWV3KHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYmxvY2s6ICdjZW50ZXInLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmxpbmU6ICdjZW50ZXInXHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9LCAyMDApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIG1lc3NhZ2UudHJhbnNpZW50U3RhdGUgPz89IHt9O1xyXG5cclxuICAgICAgICAvLyBJZiB0aGVyZSBpcyBhIHBhcmVudCBtZXNzYWdlLCB3ZSBzaG91bGQgaW5zdGVhZCBmb2N1cyB0aGF0IGFuZCBsZXQgdGhlIFxyXG4gICAgICAgIC8vIHNjcm9sbFRvQ29tbWVudCBhbmQgaGlnaGxpZ2h0IGRvIHRoZSB3b3JrLlxyXG5cclxuICAgICAgICBpZiAobWVzc2FnZS5wYXJlbnRNZXNzYWdlSWQpIHtcclxuXHJcbiAgICAgICAgICAgIGxldCBwYXJlbnRNZXNzYWdlID0gYXdhaXQgdGhpcy5zb3VyY2UuZ2V0KG1lc3NhZ2UucGFyZW50TWVzc2FnZUlkKTtcclxuICAgICAgICAgICAgcGFyZW50TWVzc2FnZS50cmFuc2llbnRTdGF0ZSA/Pz0ge307XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAvLyBNYWtlIHN1cmUgdGhhdCB0aGlzIG1lc3NhZ2UgaXMgbG9hZGVkIGFuZCB2aXNpYmxlIHRvIHRoZSB1c2VyXHJcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuY29tbWVudFZpZXcubG9hZE1lc3NhZ2VJbkNvbnRleHQocGFyZW50TWVzc2FnZSk7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBsZXQgdGhyZWFkID0gYXdhaXQgdGhpcy5zZWxlY3RNZXNzYWdlKHBhcmVudE1lc3NhZ2UpOyBcclxuXHJcbiAgICAgICAgICAgIC8vIE5lZWQgdG8gcmUtcmV0cmlldmUgdGhlIG1lc3NhZ2Ugd2l0aGluIHRoZSBuZXcgY2hhdCBzb3VyY2UgdG8gYWZmZWN0IGl0c1xyXG4gICAgICAgICAgICAvLyB0cmFuc2llbnQgc3RhdGUuXHJcbiAgICAgICAgICAgIGF3YWl0IHRocmVhZC5yZWFkeTtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHRoaXMgbWVzc2FnZSBpcyBsb2FkZWQgYW5kIHZpc2libGUgdG8gdGhlIHVzZXJcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy53YWl0Rm9yVGhyZWFkVmlldygpO1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnRocmVhZFZpZXcubG9hZE1lc3NhZ2VJbkNvbnRleHQobWVzc2FnZSk7XHJcblxyXG4gICAgICAgICAgICBtZXNzYWdlID0gYXdhaXQgdGhyZWFkLmdldChtZXNzYWdlLmlkKTtcclxuICAgICAgICAgICAgbWVzc2FnZS50cmFuc2llbnRTdGF0ZSA/Pz0ge307XHJcbiAgICAgICAgICAgIG1lc3NhZ2UudHJhbnNpZW50U3RhdGUuaGlnaGxpZ2h0ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICBjb25zb2xlLmRpcihtZXNzYWdlKTtcclxuICAgICAgICAgICAgYXdhaXQgbmV3IFByb21pc2U8dm9pZD4ocmVzb2x2ZSA9PiBzZXRUaW1lb3V0KCgpID0+IHJlc29sdmUoKSwgNTAwKSk7XHJcblxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHRoaXMgbWVzc2FnZSBpcyBsb2FkZWQgYW5kIHZpc2libGUgdG8gdGhlIHVzZXJcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5jb21tZW50Vmlldy5sb2FkTWVzc2FnZUluQ29udGV4dChtZXNzYWdlKTtcclxuXHJcbiAgICAgICAgICAgIG1lc3NhZ2UudHJhbnNpZW50U3RhdGUgPz89IHt9O1xyXG4gICAgICAgICAgICBtZXNzYWdlLnRyYW5zaWVudFN0YXRlLmhpZ2hsaWdodGVkID0gdHJ1ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMubG9hZGluZ1NoYXJlZENvbW1lbnQgPSBmYWxzZTtcclxuICAgICAgICBhd2FpdCB0aGlzLnNjcm9sbFRvQ29tbWVudChpZCk7XHJcbiAgICB9XHJcblxyXG4gICAgaGFuZGxlUGVybWlzc2lvbkRlbmllZChlcnJvck1lc3NhZ2U6IHN0cmluZykge1xyXG4gICAgICAgIC8vIFRoaXMgaXMgd2hhdCBvdGhlciBjb21wb25lbnRzIGNhbGwgd2hlbiBoYW5kbGluZyBwZXJtaXNzaW9uIGVycm9yc1xyXG4gICAgICAgIFxyXG4gICAgICAgIGlmIChlcnJvck1lc3NhZ2Uuc3RhcnRzV2l0aChgYXBwLWhhbmRsZXxgKSkge1xyXG4gICAgICAgICAgICAvLyBJZiB0aGlzIGlzIGFuIGVycm9yIGR1cmluZyBhdXRob3JpemVBY3Rpb24gb24gdGhlIGJhY2tlbmQsIHBhc3MgY29udHJvbCB0byB0aGUgdXNlci1wcm92aWRlZCBcclxuICAgICAgICAgICAgLy8gcGVybWlzc2lvbi1kZW5pZWQgaGFuZGxlci5cclxuXHJcbiAgICAgICAgICAgIHRoaXMuc2VuZFBlcm1pc3Npb25EZW5pZWQoZXJyb3JNZXNzYWdlLnJlcGxhY2UoL15hcHAtaGFuZGxlXFx8LywgJycpKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgYWxlcnQoZXJyb3JNZXNzYWdlKTtcclxuICAgIH1cclxuXHJcbiAgICBzZW5kUGVybWlzc2lvbkRlbmllZChtZXNzYWdlOiBzdHJpbmcpIHtcclxuICAgICAgICB0aGlzLl9wZXJtaXNzaW9uRGVuaWVkRXJyb3IubmV4dChtZXNzYWdlKTtcclxuICAgIH1cclxuXHJcbiAgICBzY3JvbGxUb01lc3NhZ2UobWVzc2FnZTogQ2hhdE1lc3NhZ2UpIHtcclxuICAgICAgICBsZXQgZWwgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKGBbZGF0YS1jb21tZW50LWlkPVwiJHttZXNzYWdlLmlkfVwiXWApO1xyXG4gICAgICAgIGlmICghZWwpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICBlbC5zY3JvbGxJbnRvVmlldyh7YmxvY2s6ICdjZW50ZXInLCBpbmxpbmU6ICdzdGFydCd9KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIGFkZFBhcnRpY2lwYW50KG1lc3NhZ2U6IENoYXRNZXNzYWdlKSB7XHJcbiAgICAgICAgaWYgKCFtZXNzYWdlIHx8ICFtZXNzYWdlLnVzZXIgfHwgIW1lc3NhZ2UudXNlci5pZClcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICBsZXQgZXhpc3RpbmcgPSB0aGlzLnBhcnRpY2lwYW50cy5maW5kKHggPT4geC5pZCA9PT0gbWVzc2FnZS51c2VyLmlkKTtcclxuICAgICAgICBpZiAoZXhpc3RpbmcpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB0aGlzLnBhcnRpY2lwYW50cy5wdXNoKG1lc3NhZ2UudXNlcik7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQWN0aW9uc1xyXG5cclxuICAgIGFzeW5jIGxpa2VNZXNzYWdlKHNvdXJjZTogQ2hhdFNvdXJjZUJhc2UsIG1lc3NhZ2U6IENoYXRNZXNzYWdlKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLnVzZXIpIHtcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5zaG93U2lnbkluKCk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX3Vwdm90ZWQubmV4dChtZXNzYWdlKTtcclxuICAgICAgICBtZXNzYWdlLnRyYW5zaWVudFN0YXRlLmxpa2luZyA9IHRydWU7XHJcbiAgICAgICAgXHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgYXdhaXQgc291cmNlLmxpa2VNZXNzYWdlKG1lc3NhZ2UuaWQpO1xyXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgdGhpcy5oYW5kbGVCYWNrZW5kRXhjZXB0aW9uQXNBbGVydChlLCAnQ291bGQgbm90IGxpa2UgdGhpcyBtZXNzYWdlOiAnKTtcclxuICAgICAgICB9IGZpbmFsbHkge1xyXG4gICAgICAgICAgICBhd2FpdCBuZXcgUHJvbWlzZTx2b2lkPihyZXNvbHZlID0+IHNldFRpbWVvdXQoKCkgPT4gcmVzb2x2ZSgpLCAyNTApKTtcclxuICAgICAgICAgICAgbWVzc2FnZS50cmFuc2llbnRTdGF0ZS5saWtpbmcgPSBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgdW5saWtlTWVzc2FnZShzb3VyY2U6IENoYXRTb3VyY2VCYXNlLCBtZXNzYWdlOiBDaGF0TWVzc2FnZSkge1xyXG4gICAgICAgIGlmICghdGhpcy51c2VyKSB7XHJcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuc2hvd1NpZ25JbigpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLl91cHZvdGVkLm5leHQobWVzc2FnZSk7XHJcbiAgICAgICAgbWVzc2FnZS50cmFuc2llbnRTdGF0ZS5saWtpbmcgPSB0cnVlO1xyXG5cclxuICAgICAgICBpZiAobWVzc2FnZS51c2VyU3RhdGU/Lmxpa2VkKVxyXG4gICAgICAgICAgICBtZXNzYWdlLmxpa2VzID0gKG1lc3NhZ2UubGlrZXMgfHwgMCkgLSAxO1xyXG5cclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBhd2FpdCBzb3VyY2UudW5saWtlTWVzc2FnZShtZXNzYWdlLmlkKTtcclxuICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuaGFuZGxlQmFja2VuZEV4Y2VwdGlvbkFzQWxlcnQoZSwgJ0ZhaWxlZCB0byB1bmxpa2UgdGhpcyBtZXNzYWdlOiAnKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGF3YWl0IG5ldyBQcm9taXNlPHZvaWQ+KHJlc29sdmUgPT4gc2V0VGltZW91dCgoKSA9PiByZXNvbHZlKCksIDI1MCkpO1xyXG4gICAgICAgIG1lc3NhZ2UudHJhbnNpZW50U3RhdGUubGlraW5nID0gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgcmVwb3J0TWVzc2FnZShtZXNzYWdlOiBDaGF0TWVzc2FnZSkge1xyXG4gICAgICAgIHRoaXMuX3JlcG9ydGVkLm5leHQobWVzc2FnZSk7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgdW5zZWxlY3RNZXNzYWdlKCkge1xyXG4gICAgICAgIGxldCBtZXNzYWdlID0gdGhpcy5zZWxlY3RlZE1lc3NhZ2U7XHJcblxyXG4gICAgICAgIHRoaXMuX3NlbGVjdGVkLm5leHQobnVsbCk7XHJcbiAgICAgICAgdGhpcy5zZWxlY3RlZE1lc3NhZ2UgPSBudWxsO1xyXG4gICAgICAgIGlmICh0aGlzLnNlbGVjdGVkTWVzc2FnZVRocmVhZCkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5zZWxlY3RlZE1lc3NhZ2VUaHJlYWQuY2xvc2UpXHJcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkTWVzc2FnZVRocmVhZC5jbG9zZSgpO1xyXG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkTWVzc2FnZVRocmVhZCA9IG51bGw7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAobWVzc2FnZSlcclxuICAgICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLnNjcm9sbFRvTWVzc2FnZShtZXNzYWdlKSk7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgdG9nZ2xlU2VsZWN0ZWRNZXNzYWdlKG1lc3NhZ2U6IENoYXRNZXNzYWdlKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRNZXNzYWdlID09PSBtZXNzYWdlKSB7XHJcbiAgICAgICAgICAgIGF3YWl0IHRoaXMudW5zZWxlY3RNZXNzYWdlKCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5zZWxlY3RNZXNzYWdlKG1lc3NhZ2UpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBzZWxlY3RNZXNzYWdlKG1lc3NhZ2U6IENoYXRNZXNzYWdlKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRNZXNzYWdlID09PSBtZXNzYWdlKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBbQmFudGFdIFRocmVhZCAke3RoaXMudG9waWNJRH0vJHttZXNzYWdlLmlkfSBpcyBhbHJlYWR5IG9wZW4uYCk7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNlbGVjdGVkTWVzc2FnZVRocmVhZDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHRoaXMuX3NlbGVjdGVkLm5leHQobWVzc2FnZSk7XHJcblxyXG4gICAgICAgIGNvbnNvbGUubG9nKGBbQmFudGFdIE9wZW5pbmcgdGhyZWFkIGZvciAke3RoaXMudG9waWNJRH0vJHttZXNzYWdlLmlkfS4uLmApO1xyXG4gICAgICAgIGxldCBzZWxlY3RlZE1lc3NhZ2VUaHJlYWQgPSBhd2FpdCB0aGlzLmJhY2tlbmQuZ2V0U291cmNlRm9yVGhyZWFkKHRoaXMudG9waWNJRCwgbWVzc2FnZS5pZCk7XHJcblxyXG4gICAgICAgIGlmICghc2VsZWN0ZWRNZXNzYWdlVGhyZWFkKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUud2FybihgRmFpbGVkIHRvIGxvY2F0ZSB0aHJlYWQgZm9yIG1lc3NhZ2UgJHt0aGlzLnRvcGljSUR9LyR7bWVzc2FnZS5pZH0hYCk7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc29sZS5sb2coYFtCYW50YV0gVGhyZWFkIG9wZW5lZCBmb3IgJHt0aGlzLnRvcGljSUR9LyR7bWVzc2FnZS5pZH0uYCk7XHJcblxyXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5zZWxlY3RlZE1lc3NhZ2VWaXNpYmxlID0gdHJ1ZSk7XHJcbiAgICAgICAgc2V0VGltZW91dChhc3luYyAoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRNZXNzYWdlID0gbWVzc2FnZTtcclxuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZE1lc3NhZ2VUaHJlYWQgPSBzZWxlY3RlZE1lc3NhZ2VUaHJlYWQ7XHJcbiAgICAgICAgfSwgMjUwKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHNlbGVjdGVkTWVzc2FnZVRocmVhZDtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBzaG93U2lnbkluKCkge1xyXG4gICAgICAgIHRoaXMuX3NpZ25JblNlbGVjdGVkLm5leHQoKTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBzaG93RWRpdEF2YXRhcigpIHtcclxuICAgICAgICB0aGlzLl9lZGl0QXZhdGFyU2VsZWN0ZWQubmV4dCgpO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIHNlbGVjdE1lc3NhZ2VVc2VyKG1lc3NhZ2U6IENoYXRNZXNzYWdlKSB7XHJcbiAgICAgICAgdGhpcy5fdXNlclNlbGVjdGVkLm5leHQobWVzc2FnZSk7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgc2VsZWN0VXNlcm5hbWUodXNlcjogVXNlcikge1xyXG4gICAgICAgIHRoaXMuX3VzZXJuYW1lU2VsZWN0ZWQubmV4dCh1c2VyKTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBzZWxlY3RBdmF0YXIodXNlcjogVXNlcikge1xyXG4gICAgICAgIHRoaXMuX2F2YXRhclNlbGVjdGVkLm5leHQodXNlcik7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgc2hhcmVNZXNzYWdlKG1lc3NhZ2U6IENoYXRNZXNzYWdlKSB7XHJcbiAgICAgICAgdGhpcy5fc2hhcmVkLm5leHQobWVzc2FnZSk7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgZGVsZXRlTWVzc2FnZShtZXNzYWdlOiBDaGF0TWVzc2FnZSkge1xyXG4gICAgICAgIGlmICghdGhpcy51c2VyKSB7XHJcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuc2hvd1NpZ25JbigpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIWNvbmZpcm0oXCJBcmUgeW91IHN1cmUgeW91IHdhbnQgdG8gZGVsZXRlIHRoaXMgY29tbWVudD8gWW91IGNhbm5vdCB1bmRvIHRoaXMgYWN0aW9uLlwiKSlcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnNvdXJjZS5kZWxldGVNZXNzYWdlKG1lc3NhZ2UuaWQpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRNZXNzYWdlPy5pZCA9PT0gbWVzc2FnZS5pZClcclxuICAgICAgICAgICAgICAgIHRoaXMudW5zZWxlY3RNZXNzYWdlKCk7XHJcblxyXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgdGhpcy5oYW5kbGVCYWNrZW5kRXhjZXB0aW9uQXNBbGVydChlLCBgQ291bGQgbm90IGRlbGV0ZSBtZXNzYWdlOiBgKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgZWRpdE1lc3NhZ2Uoc291cmNlOiBDaGF0U291cmNlQmFzZSwgbWVzc2FnZTogQ2hhdE1lc3NhZ2UsIG5ld1RleHQ6IHN0cmluZykge1xyXG4gICAgICAgIGlmICghdGhpcy51c2VyKSB7XHJcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuc2hvd1NpZ25JbigpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBhd2FpdCBzb3VyY2UuZWRpdE1lc3NhZ2UobWVzc2FnZS5pZCwgbmV3VGV4dCk7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICB0aGlzLmhhbmRsZUJhY2tlbmRFeGNlcHRpb25Bc0FsZXJ0KGUsICdDb3VsZCBub3QgZWRpdCB0aGlzIG1lc3NhZ2U6ICcpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBtZXNzYWdlLm1lc3NhZ2UgPSBuZXdUZXh0O1xyXG4gICAgICAgIG1lc3NhZ2UudHJhbnNpZW50U3RhdGUuZWRpdGluZyA9IGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIHN0YXJ0RWRpdGluZyhtZXNzYWdlOiBDaGF0TWVzc2FnZSkge1xyXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRNZXNzYWdlLnRyYW5zaWVudFN0YXRlLmVkaXRpbmcgPSBmYWxzZTtcclxuICAgICAgICBtZXNzYWdlLnRyYW5zaWVudFN0YXRlLmVkaXRpbmcgPSB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIHNhdmVFZGl0KG1lc3NhZ2U6IENoYXRNZXNzYWdlLCB0ZXh0OiBzdHJpbmcpIHtcclxuICAgICAgICBpZiAoIXRoaXMudXNlcikge1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnNob3dTaWduSW4oKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLnNvdXJjZS5lZGl0TWVzc2FnZShtZXNzYWdlLmlkLCB0ZXh0KTtcclxuICAgICAgICAgICAgbWVzc2FnZS50cmFuc2llbnRTdGF0ZS5lZGl0aW5nID0gZmFsc2U7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICB0aGlzLmhhbmRsZUJhY2tlbmRFeGNlcHRpb25Bc0FsZXJ0KGUsIGBDb3VsZCBub3QgZWRpdCBtZXNzYWdlOiBgKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuIl19
|