@banta/sdk 4.9.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{esm2020 → esm2022}/banta-sdk.mjs +4 -4
- package/{esm2020 → esm2022}/lib/attachment-scraper.mjs +1 -1
- package/esm2022/lib/banta/banta.component.mjs +204 -0
- package/{esm2020 → esm2022}/lib/banta-logo.component.mjs +11 -11
- package/esm2022/lib/banta-sdk.module.mjs +143 -0
- package/esm2022/lib/chat/banta-chat/banta-chat.component.mjs +187 -0
- package/esm2022/lib/chat/chat-message/chat-message.component.mjs +62 -0
- package/esm2022/lib/chat/chat-view/chat-view.component.mjs +170 -0
- package/{esm2020 → esm2022}/lib/chat/chat.module.mjs +51 -51
- package/{esm2020 → esm2022}/lib/chat/index.mjs +5 -5
- package/esm2022/lib/chat/live-chat-message.component.mjs +80 -0
- package/{esm2020 → esm2022}/lib/chat-backend-base.mjs +30 -30
- package/esm2022/lib/chat-backend.mjs +163 -0
- package/{esm2020 → esm2022}/lib/chat-source-base.mjs +1 -1
- package/esm2022/lib/chat-source.mjs +233 -0
- package/esm2022/lib/comments/attachment-button/attachment-button.component.mjs +76 -0
- package/esm2022/lib/comments/attachment-scraper.directive.mjs +107 -0
- package/esm2022/lib/comments/banta-comments/banta-comments.component.mjs +739 -0
- package/esm2022/lib/comments/comment/comment.component.mjs +175 -0
- package/esm2022/lib/comments/comment-field/comment-field.component.mjs +401 -0
- package/esm2022/lib/comments/comment-sort/comment-sort.component.mjs +37 -0
- package/esm2022/lib/comments/comment-view/comment-view.component.mjs +470 -0
- package/esm2022/lib/comments/comments.module.mjs +111 -0
- package/{esm2020 → esm2022}/lib/comments/index.mjs +10 -10
- package/esm2022/lib/comments/live-comment.component.mjs +80 -0
- package/{esm2020 → esm2022}/lib/comments/reply-send-options.directive.mjs +13 -13
- package/esm2022/lib/common/attachment/attachment.component.mjs +112 -0
- package/{esm2020 → esm2022}/lib/common/attachments/attachments.component.mjs +75 -75
- package/{esm2020 → esm2022}/lib/common/common.module.mjs +68 -68
- package/{esm2020 → esm2022}/lib/common/index.mjs +10 -10
- package/{esm2020 → esm2022}/lib/common/lazy-connection.mjs +14 -14
- package/esm2022/lib/common/lightbox/lightbox.component.mjs +31 -0
- package/esm2022/lib/common/markdown-to-html.pipe.mjs +89 -0
- package/esm2022/lib/common/mention-linker.pipe.mjs +35 -0
- package/esm2022/lib/common/timer-pool.service.mjs +83 -0
- package/esm2022/lib/common/timestamp.component.mjs +123 -0
- package/{esm2020 → esm2022}/lib/common/trust-resource-url.pipe.mjs +22 -22
- package/esm2022/lib/emoji/emoji-selector-button.component.mjs +115 -0
- package/esm2022/lib/emoji/emoji-selector-panel/emoji-selector-panel.component.mjs +98 -0
- package/{esm2020 → esm2022}/lib/emoji/emoji.module.mjs +55 -55
- package/{esm2020 → esm2022}/lib/emoji/emojis.mjs +6507 -6507
- package/{esm2020 → esm2022}/lib/emoji/index.mjs +4 -4
- package/esm2022/lib/giphy-attachments.mjs +16 -0
- package/{esm2020 → esm2022}/lib/index.mjs +19 -19
- package/{esm2020 → esm2022}/lib/live-message.component.mjs +61 -61
- package/{esm2020 → esm2022}/lib/message-menu-item.mjs +1 -1
- package/{esm2020 → esm2022}/lib/sdk-options.mjs +1 -1
- package/esm2022/lib/static-chat-source.mjs +71 -0
- package/esm2022/lib/tweet-attachments.mjs +13 -0
- package/esm2022/lib/url-attachments.mjs +42 -0
- package/esm2022/lib/youtube-attachments.mjs +29 -0
- package/{esm2020 → esm2022}/public-api.mjs +4 -4
- package/{fesm2020 → fesm2022}/banta-sdk.mjs +10753 -10754
- package/fesm2022/banta-sdk.mjs.map +1 -0
- package/index.d.ts +5 -5
- package/lib/attachment-scraper.d.ts +15 -15
- package/lib/banta/banta.component.d.ts +58 -58
- package/lib/banta-logo.component.d.ts +5 -5
- package/lib/banta-sdk.module.d.ts +31 -31
- package/lib/chat/banta-chat/banta-chat.component.d.ts +70 -70
- package/lib/chat/chat-message/chat-message.component.d.ts +21 -21
- package/lib/chat/chat-view/chat-view.component.d.ts +52 -52
- package/lib/chat/chat.module.d.ts +15 -15
- package/lib/chat/index.d.ts +5 -5
- package/lib/chat/live-chat-message.component.d.ts +23 -23
- package/lib/chat-backend-base.d.ts +36 -36
- package/lib/chat-backend.d.ts +55 -55
- package/lib/chat-source-base.d.ts +44 -44
- package/lib/chat-source.d.ts +65 -65
- package/lib/comments/attachment-button/attachment-button.component.d.ts +17 -17
- package/lib/comments/attachment-scraper.directive.d.ts +21 -21
- package/lib/comments/banta-comments/banta-comments.component.d.ts +196 -196
- package/lib/comments/comment/comment.component.d.ts +72 -72
- package/lib/comments/comment-field/comment-field.component.d.ts +89 -89
- package/lib/comments/comment-sort/comment-sort.component.d.ts +12 -12
- package/lib/comments/comment-view/comment-view.component.d.ts +121 -121
- package/lib/comments/comments.module.d.ts +30 -30
- package/lib/comments/index.d.ts +10 -10
- package/lib/comments/live-comment.component.d.ts +23 -23
- package/lib/comments/reply-send-options.directive.d.ts +5 -5
- package/lib/common/attachment/attachment.component.d.ts +33 -33
- package/lib/common/attachments/attachments.component.d.ts +26 -26
- package/lib/common/common.module.d.ts +19 -19
- package/lib/common/index.d.ts +10 -10
- package/lib/common/lazy-connection.d.ts +6 -6
- package/lib/common/lightbox/lightbox.component.d.ts +14 -14
- package/lib/common/markdown-to-html.pipe.d.ts +15 -15
- package/lib/common/mention-linker.pipe.d.ts +13 -13
- package/lib/common/timer-pool.service.d.ts +15 -15
- package/lib/common/timestamp.component.d.ts +19 -19
- package/lib/common/trust-resource-url.pipe.d.ts +10 -10
- package/lib/emoji/emoji-selector-button.component.d.ts +30 -30
- package/lib/emoji/emoji-selector-panel/emoji-selector-panel.component.d.ts +26 -26
- package/lib/emoji/emoji.module.d.ts +16 -16
- package/lib/emoji/emojis.d.ts +6507 -6507
- package/lib/emoji/index.d.ts +4 -4
- package/lib/giphy-attachments.d.ts +5 -5
- package/lib/index.d.ts +19 -19
- package/lib/live-message.component.d.ts +22 -22
- package/lib/message-menu-item.d.ts +6 -6
- package/lib/sdk-options.d.ts +5 -5
- package/lib/static-chat-source.d.ts +42 -42
- package/lib/tweet-attachments.d.ts +5 -5
- package/lib/url-attachments.d.ts +14 -14
- package/lib/youtube-attachments.d.ts +5 -5
- package/package.json +15 -21
- package/public-api.d.ts +1 -1
- package/esm2020/lib/banta/banta.component.mjs +0 -204
- package/esm2020/lib/banta-sdk.module.mjs +0 -143
- package/esm2020/lib/chat/banta-chat/banta-chat.component.mjs +0 -187
- package/esm2020/lib/chat/chat-message/chat-message.component.mjs +0 -62
- package/esm2020/lib/chat/chat-view/chat-view.component.mjs +0 -170
- package/esm2020/lib/chat/live-chat-message.component.mjs +0 -80
- package/esm2020/lib/chat-backend.mjs +0 -163
- package/esm2020/lib/chat-source.mjs +0 -233
- package/esm2020/lib/comments/attachment-button/attachment-button.component.mjs +0 -76
- package/esm2020/lib/comments/attachment-scraper.directive.mjs +0 -107
- package/esm2020/lib/comments/banta-comments/banta-comments.component.mjs +0 -740
- package/esm2020/lib/comments/comment/comment.component.mjs +0 -175
- package/esm2020/lib/comments/comment-field/comment-field.component.mjs +0 -401
- package/esm2020/lib/comments/comment-sort/comment-sort.component.mjs +0 -37
- package/esm2020/lib/comments/comment-view/comment-view.component.mjs +0 -470
- package/esm2020/lib/comments/comments.module.mjs +0 -111
- package/esm2020/lib/comments/live-comment.component.mjs +0 -80
- package/esm2020/lib/common/attachment/attachment.component.mjs +0 -112
- package/esm2020/lib/common/lightbox/lightbox.component.mjs +0 -31
- package/esm2020/lib/common/markdown-to-html.pipe.mjs +0 -89
- package/esm2020/lib/common/mention-linker.pipe.mjs +0 -35
- package/esm2020/lib/common/timer-pool.service.mjs +0 -83
- package/esm2020/lib/common/timestamp.component.mjs +0 -123
- package/esm2020/lib/emoji/emoji-selector-button.component.mjs +0 -116
- package/esm2020/lib/emoji/emoji-selector-panel/emoji-selector-panel.component.mjs +0 -98
- package/esm2020/lib/giphy-attachments.mjs +0 -16
- package/esm2020/lib/static-chat-source.mjs +0 -71
- package/esm2020/lib/tweet-attachments.mjs +0 -13
- package/esm2020/lib/url-attachments.mjs +0 -42
- package/esm2020/lib/youtube-attachments.mjs +0 -29
- package/fesm2015/banta-sdk.mjs +0 -11181
- package/fesm2015/banta-sdk.mjs.map +0 -1
- package/fesm2020/banta-sdk.mjs.map +0 -1
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
import { __decorate } from "tslib";
|
|
2
|
+
import { BehaviorSubject, Subject, Subscription } from "rxjs";
|
|
3
|
+
import { RpcEvent, SocketRPC } from "@banta/common";
|
|
4
|
+
import { v4 as uuid } from "uuid";
|
|
5
|
+
export class ChatSource extends SocketRPC {
|
|
6
|
+
constructor(backend, identifier, parentIdentifier, options) {
|
|
7
|
+
super();
|
|
8
|
+
this.backend = backend;
|
|
9
|
+
this.identifier = identifier;
|
|
10
|
+
this.parentIdentifier = parentIdentifier;
|
|
11
|
+
this.subscription = new Subscription();
|
|
12
|
+
this.readonly = false;
|
|
13
|
+
this.canLoadMore = true;
|
|
14
|
+
this._state = 'connecting';
|
|
15
|
+
this._connectionStateChanged = new Subject();
|
|
16
|
+
this._connectionStateChanged$ = this._connectionStateChanged.asObservable();
|
|
17
|
+
this.wasRestored = false;
|
|
18
|
+
this.subscribeAttempt = 0;
|
|
19
|
+
this._signInState = 'signed-out';
|
|
20
|
+
this._signInStateChanged = new BehaviorSubject(this._signInState);
|
|
21
|
+
this._signInStateChanged$ = this._signInStateChanged.asObservable();
|
|
22
|
+
this.messageMap = new Map();
|
|
23
|
+
this._messageReceived = new Subject();
|
|
24
|
+
this._messageUpdated = new Subject();
|
|
25
|
+
this._messageSent = new Subject();
|
|
26
|
+
this._messageObserved = new Subject();
|
|
27
|
+
this.messages = [];
|
|
28
|
+
this.options = options ?? {};
|
|
29
|
+
this.ready = new Promise(resolve => this.markReady = resolve);
|
|
30
|
+
}
|
|
31
|
+
get sortOrder() {
|
|
32
|
+
return this.options?.sortOrder;
|
|
33
|
+
}
|
|
34
|
+
get filterMode() {
|
|
35
|
+
return this.options?.filterMode;
|
|
36
|
+
}
|
|
37
|
+
get state() {
|
|
38
|
+
return this._state;
|
|
39
|
+
}
|
|
40
|
+
set state(value) {
|
|
41
|
+
this._state = value;
|
|
42
|
+
setTimeout(() => this._connectionStateChanged.next(this._state));
|
|
43
|
+
}
|
|
44
|
+
get connectionStateChanged() { return this._connectionStateChanged$; }
|
|
45
|
+
async bind(socket) {
|
|
46
|
+
super.bind(socket);
|
|
47
|
+
this.subscription.add(this.backend.userChanged.subscribe(() => this.authenticate()));
|
|
48
|
+
socket.addEventListener('open', async () => {
|
|
49
|
+
console.log(`[Banta/${this.identifier}] Socket is open`);
|
|
50
|
+
});
|
|
51
|
+
socket.addEventListener('error', async () => {
|
|
52
|
+
console.log(`[Banta/${this.identifier}] Socket error`);
|
|
53
|
+
});
|
|
54
|
+
socket.addEventListener('lost', async () => {
|
|
55
|
+
this.state = 'lost';
|
|
56
|
+
});
|
|
57
|
+
socket.addEventListener('restore', async () => {
|
|
58
|
+
this.wasRestored = true;
|
|
59
|
+
await this.authenticate();
|
|
60
|
+
await this.subscribeToTopic();
|
|
61
|
+
});
|
|
62
|
+
try {
|
|
63
|
+
await this.subscribeToTopic();
|
|
64
|
+
}
|
|
65
|
+
catch (e) {
|
|
66
|
+
console.error(`[Banta/ChatSource] Error during initial subscribeToTopic: ${e.message}`);
|
|
67
|
+
}
|
|
68
|
+
return this;
|
|
69
|
+
}
|
|
70
|
+
mapOrUpdateMessages(messages) {
|
|
71
|
+
return messages.map(message => this.mapOrUpdateMessage(message));
|
|
72
|
+
}
|
|
73
|
+
mapOrUpdateMessage(message) {
|
|
74
|
+
let existingMessage = this.messageMap.get(message.id);
|
|
75
|
+
if (existingMessage) {
|
|
76
|
+
message = Object.assign(existingMessage, message);
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
this.messageMap.set(message.id, message);
|
|
80
|
+
this._messageObserved.next(message);
|
|
81
|
+
}
|
|
82
|
+
return message;
|
|
83
|
+
}
|
|
84
|
+
async getExistingMessages() {
|
|
85
|
+
try {
|
|
86
|
+
let messages = await this.idempotentPeer.getExistingMessages(this.options.initialMessageCount ?? 20);
|
|
87
|
+
messages = this.mapOrUpdateMessages(messages);
|
|
88
|
+
return messages;
|
|
89
|
+
}
|
|
90
|
+
catch (e) {
|
|
91
|
+
console.error(`[Banta/${this.identifier}] Error occurred while trying to get existing messages:`);
|
|
92
|
+
console.error(e);
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
async ensureConnection(errorMessage) {
|
|
97
|
+
// let reason = `Connection to chat services is not currently available.`;
|
|
98
|
+
// if (this.state !== 'connected' && this.state !== 'restored') {
|
|
99
|
+
// if (errorMessage)
|
|
100
|
+
// throw new Error(`${errorMessage}: ${reason}`);
|
|
101
|
+
// else
|
|
102
|
+
// throw new Error(`${reason}`);
|
|
103
|
+
// }
|
|
104
|
+
}
|
|
105
|
+
async editMessage(messageId, text) {
|
|
106
|
+
await this.ensureConnection();
|
|
107
|
+
await this.peer.editMessage(messageId, text);
|
|
108
|
+
}
|
|
109
|
+
get errorState() {
|
|
110
|
+
return this._errorState;
|
|
111
|
+
}
|
|
112
|
+
async subscribeToTopic() {
|
|
113
|
+
try {
|
|
114
|
+
await this.immediatePeer.subscribe(this.identifier, this.parentIdentifier, this.options.sortOrder, this.options.filterMode);
|
|
115
|
+
this.subscribeAttempt = 0;
|
|
116
|
+
this._errorState = undefined;
|
|
117
|
+
this.state = this.wasRestored ? 'restored' : 'connected';
|
|
118
|
+
this.markReady();
|
|
119
|
+
}
|
|
120
|
+
catch (e) {
|
|
121
|
+
console.error(`[Banta/${this.identifier}] Error while subscribing to topic`);
|
|
122
|
+
console.error(e);
|
|
123
|
+
this.state = 'lost';
|
|
124
|
+
this._errorState = 'server-issue';
|
|
125
|
+
this.subscribeAttempt += 1;
|
|
126
|
+
let delay = Math.min(30 * 1000, (3 * 1000 * this.subscribeAttempt) * (1 + Math.random()));
|
|
127
|
+
console.error(`[Banta/${this.identifier}] Waiting ${delay}ms before attempting to reconnect...`);
|
|
128
|
+
setTimeout(() => {
|
|
129
|
+
if (this.state === 'lost') {
|
|
130
|
+
console.info(`Attempting reconnection after error in subscribeToTopic...`);
|
|
131
|
+
this.reconnect();
|
|
132
|
+
}
|
|
133
|
+
}, delay);
|
|
134
|
+
throw e;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
get signInState() { return this._signInState; }
|
|
138
|
+
get signInStateChanged() { return this._signInStateChanged$; }
|
|
139
|
+
setSignInState(state) {
|
|
140
|
+
this._signInState = state;
|
|
141
|
+
this._signInStateChanged.next(state);
|
|
142
|
+
}
|
|
143
|
+
async authenticate() {
|
|
144
|
+
this.setSignInState('signing-in');
|
|
145
|
+
if (this.backend.user) {
|
|
146
|
+
try {
|
|
147
|
+
// console.log(`Artificial delay...`);
|
|
148
|
+
// await new Promise(r => setTimeout(r, 30_000));
|
|
149
|
+
// console.log(`Artificial delay complete...`);
|
|
150
|
+
await this.immediatePeer.authenticate(this.backend.user?.token);
|
|
151
|
+
this.setSignInState('signed-in');
|
|
152
|
+
}
|
|
153
|
+
catch (e) {
|
|
154
|
+
console.error(`[Banta] Could not authenticate:`);
|
|
155
|
+
console.error(e);
|
|
156
|
+
this.setSignInState('signed-out');
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
close() {
|
|
161
|
+
super.close();
|
|
162
|
+
this.subscription.unsubscribe();
|
|
163
|
+
}
|
|
164
|
+
onPermissions(permissions) {
|
|
165
|
+
window.bantaPermissionsDebug = permissions;
|
|
166
|
+
this.permissions = permissions;
|
|
167
|
+
}
|
|
168
|
+
onChatMessage(message) {
|
|
169
|
+
if (this.messageMap.has(message.id)) {
|
|
170
|
+
return this.mapOrUpdateMessage(message);
|
|
171
|
+
}
|
|
172
|
+
else if (!message.hidden) {
|
|
173
|
+
// Only process non-hidden messages through here.
|
|
174
|
+
// Hidden messages may be sent to us when they become hidden (ie moderation is occurring).
|
|
175
|
+
// But if we never had the message to begin with, we should discard it.
|
|
176
|
+
this.messageMap.set(message.id, message);
|
|
177
|
+
this._messageReceived.next(message);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
get messageReceived() { return this._messageReceived.asObservable(); }
|
|
181
|
+
get messageUpdated() { return this._messageUpdated.asObservable(); }
|
|
182
|
+
get messageSent() { return this._messageSent.asObservable(); }
|
|
183
|
+
get messageObserved() { return this._messageObserved.asObservable(); }
|
|
184
|
+
async send(message) {
|
|
185
|
+
await this.ensureConnection();
|
|
186
|
+
message.id ??= uuid();
|
|
187
|
+
return await this.idempotentPeer.sendMessage(message);
|
|
188
|
+
}
|
|
189
|
+
async loadAfter(message, count) {
|
|
190
|
+
if (!message)
|
|
191
|
+
return;
|
|
192
|
+
if (!message.pagingCursor)
|
|
193
|
+
return [];
|
|
194
|
+
return this.mapOrUpdateMessages(await this.idempotentPeer.loadAfter(Number(message.pagingCursor), count));
|
|
195
|
+
}
|
|
196
|
+
async get(id) {
|
|
197
|
+
if (this.messageMap.has(id))
|
|
198
|
+
return this.messageMap.get(id);
|
|
199
|
+
await this.ensureConnection(`Could not get message`);
|
|
200
|
+
let message = await this.idempotentPeer.getMessage(id);
|
|
201
|
+
if (this.messageMap.has(id)) {
|
|
202
|
+
let existingMessage = this.messageMap.get(id);
|
|
203
|
+
Object.assign(existingMessage, message);
|
|
204
|
+
message = existingMessage;
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
this.messageMap.set(id, message);
|
|
208
|
+
}
|
|
209
|
+
return message;
|
|
210
|
+
}
|
|
211
|
+
async getCount() {
|
|
212
|
+
return await this.idempotentPeer.getCount();
|
|
213
|
+
}
|
|
214
|
+
async likeMessage(messageId) {
|
|
215
|
+
await this.ensureConnection();
|
|
216
|
+
return await this.idempotentPeer.likeMessage(messageId);
|
|
217
|
+
}
|
|
218
|
+
async unlikeMessage(messageId) {
|
|
219
|
+
await this.ensureConnection();
|
|
220
|
+
return await this.idempotentPeer.unlikeMessage(messageId);
|
|
221
|
+
}
|
|
222
|
+
async deleteMessage(messageId) {
|
|
223
|
+
await this.ensureConnection();
|
|
224
|
+
return await this.idempotentPeer.deleteMessage(messageId);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
__decorate([
|
|
228
|
+
RpcEvent()
|
|
229
|
+
], ChatSource.prototype, "onPermissions", null);
|
|
230
|
+
__decorate([
|
|
231
|
+
RpcEvent()
|
|
232
|
+
], ChatSource.prototype, "onChatMessage", null);
|
|
233
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhdC1zb3VyY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9zZGsvc3JjL2xpYi9jaGF0LXNvdXJjZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQ0EsT0FBTyxFQUFFLGVBQWUsRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzlELE9BQU8sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBR3BELE9BQU8sRUFBRSxFQUFFLElBQUksSUFBSSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBS2xDLE1BQU0sT0FBTyxVQUFXLFNBQVEsU0FBUztJQUNyQyxZQUNhLE9BQW9CLEVBQ3BCLFVBQWtCLEVBQ2xCLGdCQUF3QixFQUNqQyxPQUEwQjtRQUUxQixLQUFLLEVBQUUsQ0FBQztRQUxDLFlBQU8sR0FBUCxPQUFPLENBQWE7UUFDcEIsZUFBVSxHQUFWLFVBQVUsQ0FBUTtRQUNsQixxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQVE7UUFTN0IsaUJBQVksR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBRzFDLGFBQVEsR0FBRyxLQUFLLENBQUM7UUFDakIsZ0JBQVcsR0FBRyxJQUFJLENBQUM7UUFLWCxXQUFNLEdBQXFELFlBQVksQ0FBQztRQW1CeEUsNEJBQXVCLEdBQUcsSUFBSSxPQUFPLEVBQW9ELENBQUM7UUFDMUYsNkJBQXdCLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLFlBQVksRUFBRSxDQUFDO1FBR3ZFLGdCQUFXLEdBQUcsS0FBSyxDQUFDO1FBNkVwQixxQkFBZ0IsR0FBRyxDQUFDLENBQUM7UUFxQ3JCLGlCQUFZLEdBQWdCLFlBQVksQ0FBQztRQUN6Qyx3QkFBbUIsR0FBRyxJQUFJLGVBQWUsQ0FBYyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDMUUseUJBQW9CLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFlBQVksRUFBRSxDQUFDO1FB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QUlWO0FBR0Q7SUFEQyxRQUFRLEVBQUU7K0NBV1YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGF0TWVzc2FnZSwgQ2hhdFBlcm1pc3Npb25zLCBDb21tZW50c09yZGVyLCBEdXJhYmxlU29ja2V0LCBVc2VyIH0gZnJvbSBcIkBiYW50YS9jb21tb25cIjtcclxuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBTdWJqZWN0LCBTdWJzY3JpcHRpb24gfSBmcm9tIFwicnhqc1wiO1xyXG5pbXBvcnQgeyBScGNFdmVudCwgU29ja2V0UlBDIH0gZnJvbSBcIkBiYW50YS9jb21tb25cIjtcclxuaW1wb3J0IHsgQ2hhdFNvdXJjZUJhc2UgfSBmcm9tIFwiLi9jaGF0LXNvdXJjZS1iYXNlXCI7XHJcbmltcG9ydCB7IENoYXRCYWNrZW5kIH0gZnJvbSBcIi4vY2hhdC1iYWNrZW5kXCI7XHJcbmltcG9ydCB7IHY0IGFzIHV1aWQgfSBmcm9tIFwidXVpZFwiO1xyXG5pbXBvcnQgeyBDaGF0U291cmNlT3B0aW9ucyB9IGZyb20gXCIuL2NoYXQtYmFja2VuZC1iYXNlXCI7XHJcblxyXG5leHBvcnQgdHlwZSBTaWduSW5TdGF0ZSA9ICdzaWduZWQtb3V0JyB8ICdzaWduZWQtaW4nIHwgJ3NpZ25pbmctaW4nO1xyXG5cclxuZXhwb3J0IGNsYXNzIENoYXRTb3VyY2UgZXh0ZW5kcyBTb2NrZXRSUEMgaW1wbGVtZW50cyBDaGF0U291cmNlQmFzZSB7XHJcbiAgICBjb25zdHJ1Y3RvcihcclxuICAgICAgICByZWFkb25seSBiYWNrZW5kOiBDaGF0QmFja2VuZCxcclxuICAgICAgICByZWFkb25seSBpZGVudGlmaWVyOiBzdHJpbmcsXHJcbiAgICAgICAgcmVhZG9ubHkgcGFyZW50SWRlbnRpZmllcjogc3RyaW5nLFxyXG4gICAgICAgIG9wdGlvbnM6IENoYXRTb3VyY2VPcHRpb25zXHJcbiAgICApIHtcclxuICAgICAgICBzdXBlcigpO1xyXG4gICAgICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnMgPz8ge307XHJcbiAgICAgICAgdGhpcy5yZWFkeSA9IG5ldyBQcm9taXNlPHZvaWQ+KHJlc29sdmUgPT4gdGhpcy5tYXJrUmVhZHkgPSByZXNvbHZlKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIG9wdGlvbnM6IENoYXRTb3VyY2VPcHRpb25zO1xyXG4gICAgcHJpdmF0ZSBzdWJzY3JpcHRpb24gPSBuZXcgU3Vic2NyaXB0aW9uKCk7XHJcbiAgICBwcml2YXRlIG1hcmtSZWFkeTogKCkgPT4gdm9pZDtcclxuXHJcbiAgICByZWFkb25seSA9IGZhbHNlO1xyXG4gICAgY2FuTG9hZE1vcmUgPSB0cnVlO1xyXG5cclxuICAgIHJlYWR5OiBQcm9taXNlPHZvaWQ+O1xyXG5cclxuICAgIHBlcm1pc3Npb25zOiBDaGF0UGVybWlzc2lvbnM7XHJcbiAgICBwcml2YXRlIF9zdGF0ZTogJ2Nvbm5lY3RlZCcgfCAnY29ubmVjdGluZycgfCAnbG9zdCcgfCAncmVzdG9yZWQnID0gJ2Nvbm5lY3RpbmcnO1xyXG5cclxuICAgIGdldCBzb3J0T3JkZXIoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucz8uc29ydE9yZGVyO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBmaWx0ZXJNb2RlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLm9wdGlvbnM/LmZpbHRlck1vZGU7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHN0YXRlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9zdGF0ZTtcclxuICAgIH1cclxuXHJcbiAgICBzZXQgc3RhdGUodmFsdWUpIHtcclxuICAgICAgICB0aGlzLl9zdGF0ZSA9IHZhbHVlO1xyXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5fY29ubmVjdGlvblN0YXRlQ2hhbmdlZC5uZXh0KHRoaXMuX3N0YXRlKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfY29ubmVjdGlvblN0YXRlQ2hhbmdlZCA9IG5ldyBTdWJqZWN0PCdjb25uZWN0ZWQnIHwgJ2Nvbm5lY3RpbmcnIHwgJ2xvc3QnIHwgJ3Jlc3RvcmVkJz4oKTtcclxuICAgIHByaXZhdGUgX2Nvbm5lY3Rpb25TdGF0ZUNoYW5nZWQkID0gdGhpcy5fY29ubmVjdGlvblN0YXRlQ2hhbmdlZC5hc09ic2VydmFibGUoKTtcclxuICAgIGdldCBjb25uZWN0aW9uU3RhdGVDaGFuZ2VkKCkgeyByZXR1cm4gdGhpcy5fY29ubmVjdGlvblN0YXRlQ2hhbmdlZCQ7IH1cclxuXHJcbiAgICBwcml2YXRlIHdhc1Jlc3RvcmVkID0gZmFsc2U7XHJcblxyXG4gICAgYXN5bmMgYmluZChzb2NrZXQ6IER1cmFibGVTb2NrZXQpOiBQcm9taXNlPHRoaXM+IHtcclxuICAgICAgICBzdXBlci5iaW5kKHNvY2tldCk7XHJcblxyXG4gICAgICAgIHRoaXMuc3Vic2NyaXB0aW9uLmFkZCh0aGlzLmJhY2tlbmQudXNlckNoYW5nZWQuc3Vic2NyaWJlKCgpID0+IHRoaXMuYXV0aGVudGljYXRlKCkpKTtcclxuXHJcbiAgICAgICAgc29ja2V0LmFkZEV2ZW50TGlzdGVuZXIoJ29wZW4nLCBhc3luYyAoKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBbQmFudGEvJHt0aGlzLmlkZW50aWZpZXJ9XSBTb2NrZXQgaXMgb3BlbmApO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBzb2NrZXQuYWRkRXZlbnRMaXN0ZW5lcignZXJyb3InLCBhc3luYyAoKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBbQmFudGEvJHt0aGlzLmlkZW50aWZpZXJ9XSBTb2NrZXQgZXJyb3JgKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgc29ja2V0LmFkZEV2ZW50TGlzdGVuZXIoJ2xvc3QnLCBhc3luYyAoKSA9PiB7XHJcbiAgICAgICAgICAgIHRoaXMuc3RhdGUgPSAnbG9zdCc7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHNvY2tldC5hZGRFdmVudExpc3RlbmVyKCdyZXN0b3JlJywgYXN5bmMgKCkgPT4ge1xyXG4gICAgICAgICAgICB0aGlzLndhc1Jlc3RvcmVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5hdXRoZW50aWNhdGUoKTtcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5zdWJzY3JpYmVUb1RvcGljKCk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGF3YWl0IHRoaXMuc3Vic2NyaWJlVG9Ub3BpYygpO1xyXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgY29uc29sZS5lcnJvcihgW0JhbnRhL0NoYXRTb3VyY2VdIEVycm9yIGR1cmluZyBpbml0aWFsIHN1YnNjcmliZVRvVG9waWM6ICR7ZS5tZXNzYWdlfWApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIG1hcE9yVXBkYXRlTWVzc2FnZXMobWVzc2FnZXM6IENoYXRNZXNzYWdlW10pOiBDaGF0TWVzc2FnZVtdIHtcclxuICAgICAgICByZXR1cm4gbWVzc2FnZXMubWFwKG1lc3NhZ2UgPT4gdGhpcy5tYXBPclVwZGF0ZU1lc3NhZ2UobWVzc2FnZSkpO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgbWFwT3JVcGRhdGVNZXNzYWdlKG1lc3NhZ2U6IENoYXRNZXNzYWdlKTogQ2hhdE1lc3NhZ2Uge1xyXG4gICAgICAgIGxldCBleGlzdGluZ01lc3NhZ2UgPSB0aGlzLm1lc3NhZ2VNYXAuZ2V0KG1lc3NhZ2UuaWQpO1xyXG4gICAgICAgIGlmIChleGlzdGluZ01lc3NhZ2UpIHtcclxuICAgICAgICAgICAgbWVzc2FnZSA9IE9iamVjdC5hc3NpZ24oZXhpc3RpbmdNZXNzYWdlLCBtZXNzYWdlKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2VNYXAuc2V0KG1lc3NhZ2UuaWQsIG1lc3NhZ2UpO1xyXG4gICAgICAgICAgICB0aGlzLl9tZXNzYWdlT2JzZXJ2ZWQubmV4dChtZXNzYWdlKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBtZXNzYWdlO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGdldEV4aXN0aW5nTWVzc2FnZXMoKTogUHJvbWlzZTxDaGF0TWVzc2FnZVtdPiB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgbGV0IG1lc3NhZ2VzID0gYXdhaXQgdGhpcy5pZGVtcG90ZW50UGVlci5nZXRFeGlzdGluZ01lc3NhZ2VzKHRoaXMub3B0aW9ucy5pbml0aWFsTWVzc2FnZUNvdW50ID8/IDIwKTtcclxuICAgICAgICAgICAgbWVzc2FnZXMgPSB0aGlzLm1hcE9yVXBkYXRlTWVzc2FnZXMobWVzc2FnZXMpO1xyXG4gICAgICAgICAgICByZXR1cm4gbWVzc2FnZXM7XHJcbiAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGBbQmFudGEvJHt0aGlzLmlkZW50aWZpZXJ9XSBFcnJvciBvY2N1cnJlZCB3aGlsZSB0cnlpbmcgdG8gZ2V0IGV4aXN0aW5nIG1lc3NhZ2VzOmApO1xyXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xyXG4gICAgICAgICAgICByZXR1cm4gW107XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgYXN5bmMgZW5zdXJlQ29ubmVjdGlvbihlcnJvck1lc3NhZ2U/OiBzdHJpbmcpIHtcclxuICAgICAgICAvLyBsZXQgcmVhc29uID0gYENvbm5lY3Rpb24gdG8gY2hhdCBzZXJ2aWNlcyBpcyBub3QgY3VycmVudGx5IGF2YWlsYWJsZS5gO1xyXG4gICAgICAgIC8vIGlmICh0aGlzLnN0YXRlICE9PSAnY29ubmVjdGVkJyAmJiB0aGlzLnN0YXRlICE9PSAncmVzdG9yZWQnKSB7XHJcbiAgICAgICAgLy8gICAgIGlmIChlcnJvck1lc3NhZ2UpXHJcbiAgICAgICAgLy8gICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7ZXJyb3JNZXNzYWdlfTogJHtyZWFzb259YCk7XHJcbiAgICAgICAgLy8gICAgIGVsc2VcclxuICAgICAgICAvLyAgICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtyZWFzb259YCk7XHJcbiAgICAgICAgLy8gfVxyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGVkaXRNZXNzYWdlKG1lc3NhZ2VJZDogc3RyaW5nLCB0ZXh0OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBhd2FpdCB0aGlzLmVuc3VyZUNvbm5lY3Rpb24oKTtcclxuICAgICAgICBhd2FpdCB0aGlzLnBlZXIuZWRpdE1lc3NhZ2UobWVzc2FnZUlkLCB0ZXh0KTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIHN1YnNjcmliZUF0dGVtcHQgPSAwO1xyXG4gICAgcHJpdmF0ZSBfZXJyb3JTdGF0ZTogc3RyaW5nO1xyXG5cclxuICAgIGdldCBlcnJvclN0YXRlKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9lcnJvclN0YXRlO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIHN1YnNjcmliZVRvVG9waWMoKSB7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5pbW1lZGlhdGVQZWVyLnN1YnNjcmliZSh0aGlzLmlkZW50aWZpZXIsIHRoaXMucGFyZW50SWRlbnRpZmllciwgdGhpcy5vcHRpb25zLnNvcnRPcmRlciwgdGhpcy5vcHRpb25zLmZpbHRlck1vZGUpO1xyXG4gICAgICAgICAgICB0aGlzLnN1YnNjcmliZUF0dGVtcHQgPSAwO1xyXG4gICAgICAgICAgICB0aGlzLl9lcnJvclN0YXRlID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICB0aGlzLnN0YXRlID0gdGhpcy53YXNSZXN0b3JlZCA/ICdyZXN0b3JlZCcgOiAnY29ubmVjdGVkJztcclxuICAgICAgICAgICAgdGhpcy5tYXJrUmVhZHkoKTtcclxuXHJcbiAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGBbQmFudGEvJHt0aGlzLmlkZW50aWZpZXJ9XSBFcnJvciB3aGlsZSBzdWJzY3JpYmluZyB0byB0b3BpY2ApO1xyXG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5zdGF0ZSA9ICdsb3N0JztcclxuICAgICAgICAgICAgdGhpcy5fZXJyb3JTdGF0ZSA9ICdzZXJ2ZXItaXNzdWUnO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5zdWJzY3JpYmVBdHRlbXB0ICs9IDE7XHJcbiAgICAgICAgICAgIGxldCBkZWxheSA9IE1hdGgubWluKDMwKjEwMDAsICgzKjEwMDAgKiB0aGlzLnN1YnNjcmliZUF0dGVtcHQpICogKDEgKyBNYXRoLnJhbmRvbSgpKSk7XHJcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFtCYW50YS8ke3RoaXMuaWRlbnRpZmllcn1dIFdhaXRpbmcgJHtkZWxheX1tcyBiZWZvcmUgYXR0ZW1wdGluZyB0byByZWNvbm5lY3QuLi5gKTtcclxuXHJcbiAgICAgICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUgPT09ICdsb3N0Jykge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuaW5mbyhgQXR0ZW1wdGluZyByZWNvbm5lY3Rpb24gYWZ0ZXIgZXJyb3IgaW4gc3Vic2NyaWJlVG9Ub3BpYy4uLmApO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucmVjb25uZWN0KCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sIGRlbGF5KTtcclxuXHJcbiAgICAgICAgICAgIHRocm93IGU7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgX3NpZ25JblN0YXRlOiBTaWduSW5TdGF0ZSA9ICdzaWduZWQtb3V0JztcclxuICAgIHByaXZhdGUgX3NpZ25JblN0YXRlQ2hhbmdlZCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8U2lnbkluU3RhdGU+KHRoaXMuX3NpZ25JblN0YXRlKTtcclxuICAgIHByaXZhdGUgX3NpZ25JblN0YXRlQ2hhbmdlZCQgPSB0aGlzLl9zaWduSW5TdGF0ZUNoYW5nZWQuYXNPYnNlcnZhYmxlKCk7XHJcblxyXG4gICAgZ2V0IHNpZ25JblN0YXRlKCkgeyByZXR1cm4gdGhpcy5fc2lnbkluU3RhdGU7IH1cclxuICAgIGdldCBzaWduSW5TdGF0ZUNoYW5nZWQoKSB7IHJldHVybiB0aGlzLl9zaWduSW5TdGF0ZUNoYW5nZWQkOyB9XHJcblxyXG4gICAgcHJpdmF0ZSBzZXRTaWduSW5TdGF0ZShzdGF0ZTogU2lnbkluU3RhdGUpIHtcclxuICAgICAgICB0aGlzLl9zaWduSW5TdGF0ZSA9IHN0YXRlO1xyXG4gICAgICAgIHRoaXMuX3NpZ25JblN0YXRlQ2hhbmdlZC5uZXh0KHN0YXRlKTtcclxuICAgIH1cclxuICAgIGFzeW5jIGF1dGhlbnRpY2F0ZSgpIHtcclxuICAgICAgICB0aGlzLnNldFNpZ25JblN0YXRlKCdzaWduaW5nLWluJyk7XHJcbiAgICAgICAgaWYgKHRoaXMuYmFja2VuZC51c2VyKSB7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhgQXJ0aWZpY2lhbCBkZWxheS4uLmApO1xyXG4gICAgICAgICAgICAgICAgLy8gYXdhaXQgbmV3IFByb21pc2UociA9PiBzZXRUaW1lb3V0KHIsIDMwXzAwMCkpO1xyXG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coYEFydGlmaWNpYWwgZGVsYXkgY29tcGxldGUuLi5gKTtcclxuICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuaW1tZWRpYXRlUGVlci5hdXRoZW50aWNhdGUodGhpcy5iYWNrZW5kLnVzZXI/LnRva2VuKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuc2V0U2lnbkluU3RhdGUoJ3NpZ25lZC1pbicpO1xyXG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBbQmFudGFdIENvdWxkIG5vdCBhdXRoZW50aWNhdGU6YCk7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zZXRTaWduSW5TdGF0ZSgnc2lnbmVkLW91dCcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGNsb3NlKCk6IHZvaWQge1xyXG4gICAgICAgIHN1cGVyLmNsb3NlKCk7XHJcbiAgICAgICAgdGhpcy5zdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcclxuICAgIH1cclxuXHJcbiAgICBAUnBjRXZlbnQoKVxyXG4gICAgb25QZXJtaXNzaW9ucyhwZXJtaXNzaW9uczogQ2hhdFBlcm1pc3Npb25zKSB7XHJcbiAgICAgICAgKHdpbmRvdyBhcyBhbnkpLmJhbnRhUGVybWlzc2lvbnNEZWJ1ZyA9IHBlcm1pc3Npb25zO1xyXG4gICAgICAgIHRoaXMucGVybWlzc2lvbnMgPSBwZXJtaXNzaW9ucztcclxuICAgIH1cclxuXHJcbiAgICBAUnBjRXZlbnQoKVxyXG4gICAgb25DaGF0TWVzc2FnZShtZXNzYWdlOiBDaGF0TWVzc2FnZSkge1xyXG4gICAgICAgIGlmICh0aGlzLm1lc3NhZ2VNYXAuaGFzKG1lc3NhZ2UuaWQpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm1hcE9yVXBkYXRlTWVzc2FnZShtZXNzYWdlKTtcclxuICAgICAgICB9IGVsc2UgaWYgKCFtZXNzYWdlLmhpZGRlbikge1xyXG4gICAgICAgICAgICAvLyBPbmx5IHByb2Nlc3Mgbm9uLWhpZGRlbiBtZXNzYWdlcyB0aHJvdWdoIGhlcmUuIFxyXG4gICAgICAgICAgICAvLyBIaWRkZW4gbWVzc2FnZXMgbWF5IGJlIHNlbnQgdG8gdXMgd2hlbiB0aGV5IGJlY29tZSBoaWRkZW4gKGllIG1vZGVyYXRpb24gaXMgb2NjdXJyaW5nKS5cclxuICAgICAgICAgICAgLy8gQnV0IGlmIHdlIG5ldmVyIGhhZCB0aGUgbWVzc2FnZSB0byBiZWdpbiB3aXRoLCB3ZSBzaG91bGQgZGlzY2FyZCBpdC5cclxuICAgICAgICAgICAgdGhpcy5tZXNzYWdlTWFwLnNldChtZXNzYWdlLmlkLCBtZXNzYWdlKTtcclxuICAgICAgICAgICAgdGhpcy5fbWVzc2FnZVJlY2VpdmVkLm5leHQobWVzc2FnZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgbWVzc2FnZU1hcCA9IG5ldyBNYXA8c3RyaW5nLCBDaGF0TWVzc2FnZT4oKTtcclxuICAgIHByaXZhdGUgX21lc3NhZ2VSZWNlaXZlZCA9IG5ldyBTdWJqZWN0PENoYXRNZXNzYWdlPigpO1xyXG4gICAgcHJpdmF0ZSBfbWVzc2FnZVVwZGF0ZWQgPSBuZXcgU3ViamVjdDxDaGF0TWVzc2FnZT4oKTtcclxuICAgIHByaXZhdGUgX21lc3NhZ2VTZW50ID0gbmV3IFN1YmplY3Q8Q2hhdE1lc3NhZ2U+KCk7XHJcbiAgICBwcml2YXRlIF9tZXNzYWdlT2JzZXJ2ZWQgPSBuZXcgU3ViamVjdDxDaGF0TWVzc2FnZT4oKTtcclxuXHJcbiAgICBnZXQgbWVzc2FnZVJlY2VpdmVkKCkgeyByZXR1cm4gdGhpcy5fbWVzc2FnZVJlY2VpdmVkLmFzT2JzZXJ2YWJsZSgpOyB9XHJcbiAgICBnZXQgbWVzc2FnZVVwZGF0ZWQoKSB7IHJldHVybiB0aGlzLl9tZXNzYWdlVXBkYXRlZC5hc09ic2VydmFibGUoKTsgfVxyXG4gICAgZ2V0IG1lc3NhZ2VTZW50KCkgeyByZXR1cm4gdGhpcy5fbWVzc2FnZVNlbnQuYXNPYnNlcnZhYmxlKCk7IH1cclxuICAgIGdldCBtZXNzYWdlT2JzZXJ2ZWQoKSB7IHJldHVybiB0aGlzLl9tZXNzYWdlT2JzZXJ2ZWQuYXNPYnNlcnZhYmxlKCk7IH1cclxuXHJcbiAgICBtZXNzYWdlczogQ2hhdE1lc3NhZ2VbXSA9IFtdO1xyXG5cclxuICAgIGFzeW5jIHNlbmQobWVzc2FnZTogQ2hhdE1lc3NhZ2UpOiBQcm9taXNlPENoYXRNZXNzYWdlPiB7XHJcbiAgICAgICAgYXdhaXQgdGhpcy5lbnN1cmVDb25uZWN0aW9uKCk7XHJcbiAgICAgICAgbWVzc2FnZS5pZCA/Pz0gdXVpZCgpO1xyXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmlkZW1wb3RlbnRQZWVyLnNlbmRNZXNzYWdlKG1lc3NhZ2UpO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGxvYWRBZnRlcihtZXNzYWdlOiBDaGF0TWVzc2FnZSwgY291bnQ6IG51bWJlcik6IFByb21pc2U8Q2hhdE1lc3NhZ2VbXT4ge1xyXG4gICAgICAgIGlmICghbWVzc2FnZSlcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICBpZiAoIW1lc3NhZ2UucGFnaW5nQ3Vyc29yKVxyXG4gICAgICAgICAgICByZXR1cm4gW107XHJcbiAgICAgICAgXHJcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwT3JVcGRhdGVNZXNzYWdlcyhcclxuICAgICAgICAgICAgYXdhaXQgdGhpcy5pZGVtcG90ZW50UGVlci5sb2FkQWZ0ZXIoTnVtYmVyKG1lc3NhZ2UucGFnaW5nQ3Vyc29yKSwgY291bnQpXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyBnZXQoaWQ6IHN0cmluZyk6IFByb21pc2U8Q2hhdE1lc3NhZ2U+IHtcclxuICAgICAgICBpZiAodGhpcy5tZXNzYWdlTWFwLmhhcyhpZCkpXHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm1lc3NhZ2VNYXAuZ2V0KGlkKTtcclxuICAgICAgICBcclxuICAgICAgICBhd2FpdCB0aGlzLmVuc3VyZUNvbm5lY3Rpb24oYENvdWxkIG5vdCBnZXQgbWVzc2FnZWApO1xyXG4gICAgICAgIGxldCBtZXNzYWdlID0gYXdhaXQgdGhpcy5pZGVtcG90ZW50UGVlci5nZXRNZXNzYWdlKGlkKTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMubWVzc2FnZU1hcC5oYXMoaWQpKSB7XHJcbiAgICAgICAgICAgIGxldCBleGlzdGluZ01lc3NhZ2UgPSB0aGlzLm1lc3NhZ2VNYXAuZ2V0KGlkKTtcclxuICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihleGlzdGluZ01lc3NhZ2UsIG1lc3NhZ2UpO1xyXG4gICAgICAgICAgICBtZXNzYWdlID0gZXhpc3RpbmdNZXNzYWdlO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZU1hcC5zZXQoaWQsIG1lc3NhZ2UpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIG1lc3NhZ2U7XHJcbiAgICB9XHJcblxyXG4gICAgYXN5bmMgZ2V0Q291bnQoKTogUHJvbWlzZTxudW1iZXI+IHtcclxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5pZGVtcG90ZW50UGVlci5nZXRDb3VudCgpO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGxpa2VNZXNzYWdlKG1lc3NhZ2VJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgYXdhaXQgdGhpcy5lbnN1cmVDb25uZWN0aW9uKCk7XHJcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuaWRlbXBvdGVudFBlZXIubGlrZU1lc3NhZ2UobWVzc2FnZUlkKTtcclxuICAgIH1cclxuXHJcbiAgICBhc3luYyB1bmxpa2VNZXNzYWdlKG1lc3NhZ2VJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgYXdhaXQgdGhpcy5lbnN1cmVDb25uZWN0aW9uKCk7XHJcbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuaWRlbXBvdGVudFBlZXIudW5saWtlTWVzc2FnZShtZXNzYWdlSWQpO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGRlbGV0ZU1lc3NhZ2UobWVzc2FnZUlkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICBhd2FpdCB0aGlzLmVuc3VyZUNvbm5lY3Rpb24oKTtcclxuICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5pZGVtcG90ZW50UGVlci5kZWxldGVNZXNzYWdlKG1lc3NhZ2VJZCk7XHJcbiAgICB9XHJcblxyXG59Il19
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { Component, Input, Output, ViewChild } from '@angular/core';
|
|
2
|
+
import { Subject } from 'rxjs';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
import * as i1 from "@banta/common";
|
|
5
|
+
import * as i2 from "@angular/material/icon";
|
|
6
|
+
import * as i3 from "@angular/material/button";
|
|
7
|
+
import * as i4 from "@angular/material/tooltip";
|
|
8
|
+
export class AttachmentButtonComponent {
|
|
9
|
+
constructor(cdnProvider) {
|
|
10
|
+
this.cdnProvider = cdnProvider;
|
|
11
|
+
//#region Properties
|
|
12
|
+
this._addedAttachment = new Subject();
|
|
13
|
+
this._attachmentError = new Subject();
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region Inputs
|
|
16
|
+
this.disabled = false;
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region Outputs
|
|
20
|
+
get addedAttachment() { return this._addedAttachment.asObservable(); }
|
|
21
|
+
get attachmentError() { return this._attachmentError.asObservable(); }
|
|
22
|
+
//#endregion
|
|
23
|
+
show() { this.fileInput.nativeElement.click(); }
|
|
24
|
+
async fileChange(event) {
|
|
25
|
+
const element = event.currentTarget;
|
|
26
|
+
if (element.files.length) {
|
|
27
|
+
console.log('[Banta] File Added to comment');
|
|
28
|
+
const file = element.files[0];
|
|
29
|
+
let publicURL;
|
|
30
|
+
let attachment = {
|
|
31
|
+
type: file.type,
|
|
32
|
+
url: undefined,
|
|
33
|
+
transientState: {
|
|
34
|
+
uploading: true,
|
|
35
|
+
error: false,
|
|
36
|
+
errorMessage: undefined
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
this._addedAttachment.next(attachment);
|
|
40
|
+
try {
|
|
41
|
+
publicURL = await this.cdnProvider.uploadImage(file);
|
|
42
|
+
}
|
|
43
|
+
catch (e) {
|
|
44
|
+
attachment.transientState.error = true;
|
|
45
|
+
attachment.transientState.errorMessage = "Failed to upload";
|
|
46
|
+
console.error(`[Banta] Caught an error while uploading image to CDN:`);
|
|
47
|
+
console.error(e);
|
|
48
|
+
alert(e.message);
|
|
49
|
+
this._attachmentError.next(attachment);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
// If no URL was returned, then an error must have occurred. Presumably the CDN
|
|
53
|
+
// provider has conveyed an error to the user.
|
|
54
|
+
if (!publicURL)
|
|
55
|
+
return;
|
|
56
|
+
attachment.url = publicURL;
|
|
57
|
+
attachment.transientState = undefined;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.8", ngImport: i0, type: AttachmentButtonComponent, deps: [{ token: i1.CDNProvider }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
61
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.8", type: AttachmentButtonComponent, selector: "banta-attachment-button", inputs: { disabled: "disabled" }, outputs: { addedAttachment: "addedAttachment", attachmentError: "attachmentError" }, viewQueries: [{ propertyName: "fileInput", first: true, predicate: ["fileUpload"], descendants: true }], ngImport: i0, template: "<button matTooltip=\"Add an image or gif\" #button type=\"button\" mat-icon-button (click)=\"show()\" [disabled]=\"disabled\">\r\n\t<mat-icon>image</mat-icon>\r\n</button>\r\n<input style=\"display: none;\" #fileUpload [multiple]=\"false\" (change)=\"fileChange($event)\" type=\"file\" >", styles: ["button{color:#666}\n"], dependencies: [{ kind: "component", type: i2.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i3.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: i4.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }] }); }
|
|
62
|
+
}
|
|
63
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.8", ngImport: i0, type: AttachmentButtonComponent, decorators: [{
|
|
64
|
+
type: Component,
|
|
65
|
+
args: [{ selector: 'banta-attachment-button', template: "<button matTooltip=\"Add an image or gif\" #button type=\"button\" mat-icon-button (click)=\"show()\" [disabled]=\"disabled\">\r\n\t<mat-icon>image</mat-icon>\r\n</button>\r\n<input style=\"display: none;\" #fileUpload [multiple]=\"false\" (change)=\"fileChange($event)\" type=\"file\" >", styles: ["button{color:#666}\n"] }]
|
|
66
|
+
}], ctorParameters: () => [{ type: i1.CDNProvider }], propDecorators: { disabled: [{
|
|
67
|
+
type: Input
|
|
68
|
+
}], addedAttachment: [{
|
|
69
|
+
type: Output
|
|
70
|
+
}], attachmentError: [{
|
|
71
|
+
type: Output
|
|
72
|
+
}], fileInput: [{
|
|
73
|
+
type: ViewChild,
|
|
74
|
+
args: ['fileUpload', { static: false }]
|
|
75
|
+
}] } });
|
|
76
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXR0YWNobWVudC1idXR0b24uY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc2RrL3NyYy9saWIvY29tbWVudHMvYXR0YWNobWVudC1idXR0b24vYXR0YWNobWVudC1idXR0b24uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc2RrL3NyYy9saWIvY29tbWVudHMvYXR0YWNobWVudC1idXR0b24vYXR0YWNobWVudC1idXR0b24uY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBYyxLQUFLLEVBQUUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVoRixPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDOzs7Ozs7QUFPL0IsTUFBTSxPQUFPLHlCQUF5QjtJQUNsQyxZQUNZLFdBQXdCO1FBQXhCLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBSXBDLG9CQUFvQjtRQUVaLHFCQUFnQixHQUFHLElBQUksT0FBTyxFQUF5QixDQUFDO1FBQ3hELHFCQUFnQixHQUFHLElBQUksT0FBTyxFQUF5QixDQUFDO1FBRWhFLFlBQVk7UUFDWixnQkFBZ0I7UUFFUCxhQUFRLEdBQUcsS0FBSyxDQUFDO0lBVjFCLENBQUM7SUFZRCxZQUFZO0lBQ1osaUJBQWlCO0lBRWpCLElBQWMsZUFBZSxLQUFLLE9BQU8sSUFBSSxDQUFDLGdCQUFnQixDQUFDLFlBQVksRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNoRixJQUFjLGVBQWUsS0FBSyxPQUFPLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFPaEYsWUFBWTtJQUVaLElBQUksS0FBSyxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFFaEQsS0FBSyxDQUFDLFVBQVUsQ0FBQyxLQUFZO1FBQ3pCLE1BQU0sT0FBTyxHQUFJLEtBQUssQ0FBQyxhQUFrQyxDQUFDO1FBQzFELElBQUksT0FBTyxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUN2QixPQUFPLENBQUMsR0FBRyxDQUFDLCtCQUErQixDQUFDLENBQUM7WUFDN0MsTUFBTSxJQUFJLEdBQUcsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM5QixJQUFJLFNBQWlCLENBQUM7WUFFdEIsSUFBSSxVQUFVLEdBQTBCO2dCQUNwQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUk7Z0JBQ2YsR0FBRyxFQUFFLFNBQVM7Z0JBQ2QsY0FBYyxFQUFFO29CQUNaLFNBQVMsRUFBRSxJQUFJO29CQUNmLEtBQUssRUFBRSxLQUFLO29CQUNaLFlBQVksRUFBRSxTQUFTO2lCQUMxQjthQUNKLENBQUE7WUFFRCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBRXZDLElBQUksQ0FBQztnQkFDRCxTQUFTLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUN6RCxDQUFDO1lBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztnQkFDVCxVQUFVLENBQUMsY0FBYyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7Z0JBQ3ZDLFVBQVUsQ0FBQyxjQUFjLENBQUMsWUFBWSxHQUFHLGtCQUFrQixDQUFDO2dCQUU1RCxPQUFPLENBQUMsS0FBSyxDQUFDLHVEQUF1RCxDQUFDLENBQUM7Z0JBQ3ZFLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ2pCLEtBQUssQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBRWpCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7Z0JBQ3ZDLE9BQU87WUFDWCxDQUFDO1lBRUQsK0VBQStFO1lBQy9FLDhDQUE4QztZQUM5QyxJQUFJLENBQUMsU0FBUztnQkFDVixPQUFPO1lBRVgsVUFBVSxDQUFDLEdBQUcsR0FBRyxTQUFTLENBQUM7WUFDM0IsVUFBVSxDQUFDLGNBQWMsR0FBRyxTQUFTLENBQUM7UUFDMUMsQ0FBQztJQUNMLENBQUM7OEdBeEVRLHlCQUF5QjtrR0FBekIseUJBQXlCLCtSQ1R0QyxrU0FHeUc7OzJGRE01Rix5QkFBeUI7a0JBTHJDLFNBQVM7K0JBQ0kseUJBQXlCO2dGQWtCMUIsUUFBUTtzQkFBaEIsS0FBSztnQkFLUSxlQUFlO3NCQUE1QixNQUFNO2dCQUNPLGVBQWU7c0JBQTVCLE1BQU07Z0JBS3FDLFNBQVM7c0JBQXBELFNBQVM7dUJBQUMsWUFBWSxFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRWxlbWVudFJlZiwgSW5wdXQsIE91dHB1dCwgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IENETlByb3ZpZGVyLCBDaGF0TWVzc2FnZUF0dGFjaG1lbnQgfSBmcm9tICdAYmFudGEvY29tbW9uJztcclxuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgICBzZWxlY3RvcjogJ2JhbnRhLWF0dGFjaG1lbnQtYnV0dG9uJyxcclxuICAgIHRlbXBsYXRlVXJsOiAnLi9hdHRhY2htZW50LWJ1dHRvbi5jb21wb25lbnQuaHRtbCcsXHJcbiAgICBzdHlsZVVybHM6IFsnLi9hdHRhY2htZW50LWJ1dHRvbi5jb21wb25lbnQuc2NzcyddXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBBdHRhY2htZW50QnV0dG9uQ29tcG9uZW50IHtcclxuICAgIGNvbnN0cnVjdG9yKFxyXG4gICAgICAgIHByaXZhdGUgY2RuUHJvdmlkZXI6IENETlByb3ZpZGVyLFxyXG4gICAgKSB7XHJcbiAgICB9XHJcblxyXG4gICAgLy8jcmVnaW9uIFByb3BlcnRpZXNcclxuXHJcbiAgICBwcml2YXRlIF9hZGRlZEF0dGFjaG1lbnQgPSBuZXcgU3ViamVjdDxDaGF0TWVzc2FnZUF0dGFjaG1lbnQ+KCk7XHJcbiAgICBwcml2YXRlIF9hdHRhY2htZW50RXJyb3IgPSBuZXcgU3ViamVjdDxDaGF0TWVzc2FnZUF0dGFjaG1lbnQ+KCk7XHJcblxyXG4gICAgLy8jZW5kcmVnaW9uXHJcbiAgICAvLyNyZWdpb24gSW5wdXRzXHJcblxyXG4gICAgQElucHV0KCkgZGlzYWJsZWQgPSBmYWxzZTtcclxuXHJcbiAgICAvLyNlbmRyZWdpb25cclxuICAgIC8vI3JlZ2lvbiBPdXRwdXRzXHJcblxyXG4gICAgQE91dHB1dCgpIGdldCBhZGRlZEF0dGFjaG1lbnQoKSB7IHJldHVybiB0aGlzLl9hZGRlZEF0dGFjaG1lbnQuYXNPYnNlcnZhYmxlKCk7IH1cclxuICAgIEBPdXRwdXQoKSBnZXQgYXR0YWNobWVudEVycm9yKCkgeyByZXR1cm4gdGhpcy5fYXR0YWNobWVudEVycm9yLmFzT2JzZXJ2YWJsZSgpOyB9XHJcblxyXG4gICAgLy8jZW5kcmVnaW9uXHJcbiAgICAvLyNyZWdpb24gVUkgQmluZGluZ3NcclxuXHJcbiAgICBAVmlld0NoaWxkKCdmaWxlVXBsb2FkJywgeyBzdGF0aWM6IGZhbHNlIH0pIGZpbGVJbnB1dDogRWxlbWVudFJlZjxIVE1MSW5wdXRFbGVtZW50PjtcclxuXHJcbiAgICAvLyNlbmRyZWdpb25cclxuXHJcbiAgICBzaG93KCkgeyB0aGlzLmZpbGVJbnB1dC5uYXRpdmVFbGVtZW50LmNsaWNrKCk7IH1cclxuXHJcbiAgICBhc3luYyBmaWxlQ2hhbmdlKGV2ZW50OiBFdmVudCk6IFByb21pc2U8dm9pZD4ge1xyXG4gICAgICAgIGNvbnN0IGVsZW1lbnQgPSAoZXZlbnQuY3VycmVudFRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50KTtcclxuICAgICAgICBpZiAoZWxlbWVudC5maWxlcy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgY29uc29sZS5sb2coJ1tCYW50YV0gRmlsZSBBZGRlZCB0byBjb21tZW50Jyk7XHJcbiAgICAgICAgICAgIGNvbnN0IGZpbGUgPSBlbGVtZW50LmZpbGVzWzBdO1xyXG4gICAgICAgICAgICBsZXQgcHVibGljVVJMOiBzdHJpbmc7XHJcblxyXG4gICAgICAgICAgICBsZXQgYXR0YWNobWVudDogQ2hhdE1lc3NhZ2VBdHRhY2htZW50ID0ge1xyXG4gICAgICAgICAgICAgICAgdHlwZTogZmlsZS50eXBlLFxyXG4gICAgICAgICAgICAgICAgdXJsOiB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgICAgICB0cmFuc2llbnRTdGF0ZToge1xyXG4gICAgICAgICAgICAgICAgICAgIHVwbG9hZGluZzogdHJ1ZSxcclxuICAgICAgICAgICAgICAgICAgICBlcnJvcjogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JNZXNzYWdlOiB1bmRlZmluZWRcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdGhpcy5fYWRkZWRBdHRhY2htZW50Lm5leHQoYXR0YWNobWVudCk7XHJcblxyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgcHVibGljVVJMID0gYXdhaXQgdGhpcy5jZG5Qcm92aWRlci51cGxvYWRJbWFnZShmaWxlKTtcclxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgYXR0YWNobWVudC50cmFuc2llbnRTdGF0ZS5lcnJvciA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBhdHRhY2htZW50LnRyYW5zaWVudFN0YXRlLmVycm9yTWVzc2FnZSA9IFwiRmFpbGVkIHRvIHVwbG9hZFwiO1xyXG5cclxuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFtCYW50YV0gQ2F1Z2h0IGFuIGVycm9yIHdoaWxlIHVwbG9hZGluZyBpbWFnZSB0byBDRE46YCk7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xyXG4gICAgICAgICAgICAgICAgYWxlcnQoZS5tZXNzYWdlKTtcclxuXHJcbiAgICAgICAgICAgICAgICB0aGlzLl9hdHRhY2htZW50RXJyb3IubmV4dChhdHRhY2htZW50KTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gSWYgbm8gVVJMIHdhcyByZXR1cm5lZCwgdGhlbiBhbiBlcnJvciBtdXN0IGhhdmUgb2NjdXJyZWQuIFByZXN1bWFibHkgdGhlIENETlxyXG4gICAgICAgICAgICAvLyBwcm92aWRlciBoYXMgY29udmV5ZWQgYW4gZXJyb3IgdG8gdGhlIHVzZXIuXHJcbiAgICAgICAgICAgIGlmICghcHVibGljVVJMKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG5cclxuICAgICAgICAgICAgYXR0YWNobWVudC51cmwgPSBwdWJsaWNVUkw7XHJcbiAgICAgICAgICAgIGF0dGFjaG1lbnQudHJhbnNpZW50U3RhdGUgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59IiwiPGJ1dHRvbiBtYXRUb29sdGlwPVwiQWRkIGFuIGltYWdlIG9yIGdpZlwiICNidXR0b24gdHlwZT1cImJ1dHRvblwiIG1hdC1pY29uLWJ1dHRvbiAoY2xpY2spPVwic2hvdygpXCIgW2Rpc2FibGVkXT1cImRpc2FibGVkXCI+XHJcblx0PG1hdC1pY29uPmltYWdlPC9tYXQtaWNvbj5cclxuPC9idXR0b24+XHJcbjxpbnB1dCBzdHlsZT1cImRpc3BsYXk6IG5vbmU7XCIgI2ZpbGVVcGxvYWQgW211bHRpcGxlXT1cImZhbHNlXCIgIChjaGFuZ2UpPVwiZmlsZUNoYW5nZSgkZXZlbnQpXCIgdHlwZT1cImZpbGVcIiA+Il19
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { Directive, Input, Output } from "@angular/core";
|
|
2
|
+
import { Subject } from "rxjs";
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
import * as i1 from "../chat-backend-base";
|
|
5
|
+
export class AttachmentScraperDirective {
|
|
6
|
+
constructor(elementRef, chatBackend) {
|
|
7
|
+
this.elementRef = elementRef;
|
|
8
|
+
this.chatBackend = chatBackend;
|
|
9
|
+
this.attachments = [];
|
|
10
|
+
this.attachmentsChange = new Subject();
|
|
11
|
+
this.scrapeDebounce = 1500;
|
|
12
|
+
this.fragments = new Map();
|
|
13
|
+
}
|
|
14
|
+
ngOnInit() {
|
|
15
|
+
if (typeof window === 'undefined')
|
|
16
|
+
return;
|
|
17
|
+
this.element.addEventListener('keydown', () => {
|
|
18
|
+
clearTimeout(this.scrapeTimeout);
|
|
19
|
+
this.scrapeTimeout = setTimeout(() => this.scrape(), this.scrapeDebounce);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
get element() {
|
|
23
|
+
return this.elementRef?.nativeElement;
|
|
24
|
+
}
|
|
25
|
+
get text() {
|
|
26
|
+
return this.element.value;
|
|
27
|
+
}
|
|
28
|
+
scrape() {
|
|
29
|
+
let message = {
|
|
30
|
+
likes: 0,
|
|
31
|
+
message: this.text,
|
|
32
|
+
sentAt: undefined,
|
|
33
|
+
user: null,
|
|
34
|
+
attachments: this.attachments
|
|
35
|
+
};
|
|
36
|
+
let foundFragments = [];
|
|
37
|
+
for (let scraper of this.chatBackend.attachmentScrapers) {
|
|
38
|
+
let fragments = scraper.findFragments(message);
|
|
39
|
+
if (!fragments) {
|
|
40
|
+
console.error(`Attachment fragment scraper ${scraper.constructor.name} is implemented incorrectly: Returned null instead of array`);
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
for (let fragment of fragments) {
|
|
44
|
+
foundFragments.push(fragment.text);
|
|
45
|
+
if (!this.fragments.has(fragment.text)) {
|
|
46
|
+
console.log(`Scraped new fragment:`);
|
|
47
|
+
console.dir(fragment);
|
|
48
|
+
this.fragments.set(fragment.text, {
|
|
49
|
+
fragment,
|
|
50
|
+
resolution: undefined
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
// Remove fragments that are no longer in the message.
|
|
56
|
+
let removedFragments = [];
|
|
57
|
+
for (let [key] of this.fragments) {
|
|
58
|
+
if (!foundFragments.includes(key))
|
|
59
|
+
removedFragments.push(key);
|
|
60
|
+
}
|
|
61
|
+
for (let removedFragment of removedFragments) {
|
|
62
|
+
console.log(`Removed fragment: ${removedFragment}`);
|
|
63
|
+
this.fragments.delete(removedFragment);
|
|
64
|
+
}
|
|
65
|
+
// Process any fragments that are not yet resolved (or being
|
|
66
|
+
// resolved)
|
|
67
|
+
for (let [key, state] of this.fragments) {
|
|
68
|
+
if (state.resolution)
|
|
69
|
+
continue;
|
|
70
|
+
state.resolution = new Promise(async (resolve, reject) => {
|
|
71
|
+
console.log(`Resolving fragment ${key}`);
|
|
72
|
+
for (let resolver of this.chatBackend.attachmentResolvers) {
|
|
73
|
+
console.log(`- Trying resolver ${resolver.constructor.name}...`);
|
|
74
|
+
try {
|
|
75
|
+
let attachment = await resolver.resolveFragment(message, state.fragment);
|
|
76
|
+
if (attachment) {
|
|
77
|
+
console.log(`Resolved fragment ${key} into attachment:`);
|
|
78
|
+
console.dir(attachment);
|
|
79
|
+
this.attachments.push(attachment);
|
|
80
|
+
this.attachmentsChange.next(this.attachments.slice());
|
|
81
|
+
resolve(attachment);
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch (e) {
|
|
86
|
+
console.error(`Caught error during attachment resolver ${resolver.constructor.name}:`);
|
|
87
|
+
console.error(e);
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.8", ngImport: i0, type: AttachmentScraperDirective, deps: [{ token: i0.ElementRef }, { token: i1.ChatBackendBase }], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
95
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.8", type: AttachmentScraperDirective, selector: "[attachmentScraper]", inputs: { attachments: "attachments" }, outputs: { attachmentsChange: "attachmentsChange" }, ngImport: i0 }); }
|
|
96
|
+
}
|
|
97
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.8", ngImport: i0, type: AttachmentScraperDirective, decorators: [{
|
|
98
|
+
type: Directive,
|
|
99
|
+
args: [{
|
|
100
|
+
selector: '[attachmentScraper]'
|
|
101
|
+
}]
|
|
102
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.ChatBackendBase }], propDecorators: { attachments: [{
|
|
103
|
+
type: Input
|
|
104
|
+
}], attachmentsChange: [{
|
|
105
|
+
type: Output
|
|
106
|
+
}] } });
|
|
107
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXR0YWNobWVudC1zY3JhcGVyLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3Nkay9zcmMvbGliL2NvbW1lbnRzL2F0dGFjaG1lbnQtc2NyYXBlci5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBYyxLQUFLLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRXJFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7OztBQVkvQixNQUFNLE9BQU8sMEJBQTBCO0lBQ25DLFlBQ1ksVUFBMkMsRUFDM0MsV0FBNEI7UUFENUIsZUFBVSxHQUFWLFVBQVUsQ0FBaUM7UUFDM0MsZ0JBQVcsR0FBWCxXQUFXLENBQWlCO1FBSS9CLGdCQUFXLEdBQTRCLEVBQUUsQ0FBQztRQUN6QyxzQkFBaUIsR0FBRyxJQUFJLE9BQU8sRUFBMkIsQ0FBQztRQXFCN0QsbUJBQWMsR0FBRyxJQUFJLENBQUM7UUFDdEIsY0FBUyxHQUFHLElBQUksR0FBRyxFQUFtQyxDQUFDO0lBekIvRCxDQUFDO0lBSUQsUUFBUTtRQUNKLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVztZQUM3QixPQUFPO1FBRVgsSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLEVBQUUsR0FBRyxFQUFFO1lBQzFDLFlBQVksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUM7WUFDakMsSUFBSSxDQUFDLGFBQWEsR0FBRyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUM5RSxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRCxJQUFJLE9BQU87UUFDUCxPQUFPLElBQUksQ0FBQyxVQUFVLEVBQUUsYUFBYSxDQUFDO0lBQzFDLENBQUM7SUFFRCxJQUFJLElBQUk7UUFDSixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDO0lBQzlCLENBQUM7SUFNTyxNQUFNO1FBQ1YsSUFBSSxPQUFPLEdBQWdCO1lBQ3ZCLEtBQUssRUFBRSxDQUFDO1lBQ1IsT0FBTyxFQUFFLElBQUksQ0FBQyxJQUFJO1lBQ2xCLE1BQU0sRUFBRSxTQUFTO1lBQ2pCLElBQUksRUFBRSxJQUFJO1lBQ1YsV0FBVyxFQUFFLElBQUksQ0FBQyxXQUFXO1NBQ2hDLENBQUM7UUFFRixJQUFJLGNBQWMsR0FBYSxFQUFFLENBQUM7UUFFbEMsS0FBSyxJQUFJLE9BQU8sSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLGtCQUFrQixFQUFFLENBQUM7WUFDdEQsSUFBSSxTQUFTLEdBQUcsT0FBTyxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUMvQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQ2IsT0FBTyxDQUFDLEtBQUssQ0FBQywrQkFBK0IsT0FBTyxDQUFDLFdBQVcsQ0FBQyxJQUFJLDZEQUE2RCxDQUFDLENBQUM7Z0JBQ3BJLFNBQVM7WUFDYixDQUFDO1lBQ0QsS0FBSyxJQUFJLFFBQVEsSUFBSSxTQUFTLEVBQUUsQ0FBQztnQkFDN0IsY0FBYyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ25DLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztvQkFDckMsT0FBTyxDQUFDLEdBQUcsQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO29CQUNyQyxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO29CQUN0QixJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFO3dCQUM5QixRQUFRO3dCQUNSLFVBQVUsRUFBRSxTQUFTO3FCQUN4QixDQUFDLENBQUM7Z0JBQ1AsQ0FBQztZQUNMLENBQUM7UUFDTCxDQUFDO1FBRUQsc0RBQXNEO1FBQ3RELElBQUksZ0JBQWdCLEdBQWEsRUFBRSxDQUFDO1FBQ3BDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUMvQixJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUM7Z0JBQzdCLGdCQUFnQixDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNuQyxDQUFDO1FBQ0QsS0FBSyxJQUFJLGVBQWUsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO1lBQzNDLE9BQU8sQ0FBQyxHQUFHLENBQUMscUJBQXFCLGVBQWUsRUFBRSxDQUFDLENBQUM7WUFDcEQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDM0MsQ0FBQztRQUVELDZEQUE2RDtRQUM3RCxZQUFZO1FBRVosS0FBSyxJQUFJLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUN0QyxJQUFJLEtBQUssQ0FBQyxVQUFVO2dCQUNoQixTQUFTO1lBRWIsS0FBSyxDQUFDLFVBQVUsR0FBRyxJQUFJLE9BQU8sQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO2dCQUNyRCxPQUFPLENBQUMsR0FBRyxDQUFDLHNCQUFzQixHQUFHLEVBQUUsQ0FBQyxDQUFDO2dCQUN6QyxLQUFLLElBQUksUUFBUSxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsbUJBQW1CLEVBQUUsQ0FBQztvQkFDeEQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxxQkFBcUIsUUFBUSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEtBQUssQ0FBQyxDQUFDO29CQUNqRSxJQUFJLENBQUM7d0JBQ0QsSUFBSSxVQUFVLEdBQUcsTUFBTSxRQUFRLENBQUMsZUFBZSxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7d0JBQ3pFLElBQUksVUFBVSxFQUFFLENBQUM7NEJBQ2IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxxQkFBcUIsR0FBRyxtQkFBbUIsQ0FBQyxDQUFDOzRCQUN6RCxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDOzRCQUN4QixJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQzs0QkFDbEMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7NEJBQ3RELE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQzs0QkFDcEIsTUFBTTt3QkFDVixDQUFDO29CQUNMLENBQUM7b0JBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQzt3QkFDVCxPQUFPLENBQUMsS0FBSyxDQUFDLDJDQUEyQyxRQUFRLENBQUMsV0FBVyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUM7d0JBQ3ZGLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7d0JBQ2pCLFNBQVM7b0JBQ2IsQ0FBQztnQkFDTCxDQUFDO1lBQ0wsQ0FBQyxDQUFDLENBQUM7UUFDUCxDQUFDO0lBQ0wsQ0FBQzs4R0FyR1EsMEJBQTBCO2tHQUExQiwwQkFBMEI7OzJGQUExQiwwQkFBMEI7a0JBSHRDLFNBQVM7bUJBQUM7b0JBQ1AsUUFBUSxFQUFFLHFCQUFxQjtpQkFDbEM7NkdBUVksV0FBVztzQkFBbkIsS0FBSztnQkFDSSxpQkFBaUI7c0JBQTFCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEaXJlY3RpdmUsIEVsZW1lbnRSZWYsIElucHV0LCBPdXRwdXQgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xyXG5pbXBvcnQgeyBDaGF0TWVzc2FnZSwgQ2hhdE1lc3NhZ2VBdHRhY2htZW50IH0gZnJvbSBcIkBiYW50YS9jb21tb25cIjtcclxuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gXCJyeGpzXCI7XHJcbmltcG9ydCB7IEF0dGFjaG1lbnRGcmFnbWVudCB9IGZyb20gXCIuLi9hdHRhY2htZW50LXNjcmFwZXJcIjtcclxuaW1wb3J0IHsgQ2hhdEJhY2tlbmRCYXNlIH0gZnJvbSBcIi4uL2NoYXQtYmFja2VuZC1iYXNlXCI7XHJcblxyXG5pbnRlcmZhY2UgQXR0YWNobWVudEZyYWdtZW50U3RhdGUge1xyXG4gICAgZnJhZ21lbnQ6IEF0dGFjaG1lbnRGcmFnbWVudDtcclxuICAgIHJlc29sdXRpb246IFByb21pc2U8Q2hhdE1lc3NhZ2VBdHRhY2htZW50PjtcclxufVxyXG5cclxuQERpcmVjdGl2ZSh7XHJcbiAgICBzZWxlY3RvcjogJ1thdHRhY2htZW50U2NyYXBlcl0nXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBBdHRhY2htZW50U2NyYXBlckRpcmVjdGl2ZSB7XHJcbiAgICBjb25zdHJ1Y3RvcihcclxuICAgICAgICBwcml2YXRlIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWY8SFRNTFRleHRBcmVhRWxlbWVudD4sXHJcbiAgICAgICAgcHJpdmF0ZSBjaGF0QmFja2VuZDogQ2hhdEJhY2tlbmRCYXNlXHJcbiAgICApIHtcclxuICAgIH1cclxuXHJcbiAgICBASW5wdXQoKSBhdHRhY2htZW50czogQ2hhdE1lc3NhZ2VBdHRhY2htZW50W10gPSBbXTtcclxuICAgIEBPdXRwdXQoKSBhdHRhY2htZW50c0NoYW5nZSA9IG5ldyBTdWJqZWN0PENoYXRNZXNzYWdlQXR0YWNobWVudFtdPigpO1xyXG4gICAgbmdPbkluaXQoKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3cgPT09ICd1bmRlZmluZWQnKVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgXHJcbiAgICAgICAgdGhpcy5lbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCAoKSA9PiB7XHJcbiAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aGlzLnNjcmFwZVRpbWVvdXQpO1xyXG4gICAgICAgICAgICB0aGlzLnNjcmFwZVRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHRoaXMuc2NyYXBlKCksIHRoaXMuc2NyYXBlRGVib3VuY2UpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGdldCBlbGVtZW50KCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnRSZWY/Lm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0IHRleHQoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZWxlbWVudC52YWx1ZTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgcHJpdmF0ZSBzY3JhcGVUaW1lb3V0O1xyXG4gICAgcHJpdmF0ZSBzY3JhcGVEZWJvdW5jZSA9IDE1MDA7XHJcbiAgICBwcml2YXRlIGZyYWdtZW50cyA9IG5ldyBNYXA8c3RyaW5nLCBBdHRhY2htZW50RnJhZ21lbnRTdGF0ZT4oKTtcclxuICAgIHByaXZhdGUgc2NyYXBlKCkge1xyXG4gICAgICAgIGxldCBtZXNzYWdlOiBDaGF0TWVzc2FnZSA9IHtcclxuICAgICAgICAgICAgbGlrZXM6IDAsXHJcbiAgICAgICAgICAgIG1lc3NhZ2U6IHRoaXMudGV4dCxcclxuICAgICAgICAgICAgc2VudEF0OiB1bmRlZmluZWQsXHJcbiAgICAgICAgICAgIHVzZXI6IG51bGwsXHJcbiAgICAgICAgICAgIGF0dGFjaG1lbnRzOiB0aGlzLmF0dGFjaG1lbnRzXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgbGV0IGZvdW5kRnJhZ21lbnRzOiBzdHJpbmdbXSA9IFtdO1xyXG5cclxuICAgICAgICBmb3IgKGxldCBzY3JhcGVyIG9mIHRoaXMuY2hhdEJhY2tlbmQuYXR0YWNobWVudFNjcmFwZXJzKSB7XHJcbiAgICAgICAgICAgIGxldCBmcmFnbWVudHMgPSBzY3JhcGVyLmZpbmRGcmFnbWVudHMobWVzc2FnZSk7XHJcbiAgICAgICAgICAgIGlmICghZnJhZ21lbnRzKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBBdHRhY2htZW50IGZyYWdtZW50IHNjcmFwZXIgJHtzY3JhcGVyLmNvbnN0cnVjdG9yLm5hbWV9IGlzIGltcGxlbWVudGVkIGluY29ycmVjdGx5OiBSZXR1cm5lZCBudWxsIGluc3RlYWQgb2YgYXJyYXlgKTtcclxuICAgICAgICAgICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGZvciAobGV0IGZyYWdtZW50IG9mIGZyYWdtZW50cykge1xyXG4gICAgICAgICAgICAgICAgZm91bmRGcmFnbWVudHMucHVzaChmcmFnbWVudC50ZXh0KTtcclxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5mcmFnbWVudHMuaGFzKGZyYWdtZW50LnRleHQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coYFNjcmFwZWQgbmV3IGZyYWdtZW50OmApO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGlyKGZyYWdtZW50KTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZyYWdtZW50cy5zZXQoZnJhZ21lbnQudGV4dCwge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmcmFnbWVudCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzb2x1dGlvbjogdW5kZWZpbmVkXHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIFJlbW92ZSBmcmFnbWVudHMgdGhhdCBhcmUgbm8gbG9uZ2VyIGluIHRoZSBtZXNzYWdlLlxyXG4gICAgICAgIGxldCByZW1vdmVkRnJhZ21lbnRzOiBzdHJpbmdbXSA9IFtdO1xyXG4gICAgICAgIGZvciAobGV0IFtrZXldIG9mIHRoaXMuZnJhZ21lbnRzKSB7XHJcbiAgICAgICAgICAgIGlmICghZm91bmRGcmFnbWVudHMuaW5jbHVkZXMoa2V5KSlcclxuICAgICAgICAgICAgICAgIHJlbW92ZWRGcmFnbWVudHMucHVzaChrZXkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmb3IgKGxldCByZW1vdmVkRnJhZ21lbnQgb2YgcmVtb3ZlZEZyYWdtZW50cykge1xyXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhgUmVtb3ZlZCBmcmFnbWVudDogJHtyZW1vdmVkRnJhZ21lbnR9YCk7XHJcbiAgICAgICAgICAgIHRoaXMuZnJhZ21lbnRzLmRlbGV0ZShyZW1vdmVkRnJhZ21lbnQpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gUHJvY2VzcyBhbnkgZnJhZ21lbnRzIHRoYXQgYXJlIG5vdCB5ZXQgcmVzb2x2ZWQgKG9yIGJlaW5nIFxyXG4gICAgICAgIC8vIHJlc29sdmVkKVxyXG5cclxuICAgICAgICBmb3IgKGxldCBba2V5LCBzdGF0ZV0gb2YgdGhpcy5mcmFnbWVudHMpIHtcclxuICAgICAgICAgICAgaWYgKHN0YXRlLnJlc29sdXRpb24pXHJcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuXHJcbiAgICAgICAgICAgIHN0YXRlLnJlc29sdXRpb24gPSBuZXcgUHJvbWlzZShhc3luYyAocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhgUmVzb2x2aW5nIGZyYWdtZW50ICR7a2V5fWApO1xyXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgcmVzb2x2ZXIgb2YgdGhpcy5jaGF0QmFja2VuZC5hdHRhY2htZW50UmVzb2x2ZXJzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coYC0gVHJ5aW5nIHJlc29sdmVyICR7cmVzb2x2ZXIuY29uc3RydWN0b3IubmFtZX0uLi5gKTtcclxuICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgYXR0YWNobWVudCA9IGF3YWl0IHJlc29sdmVyLnJlc29sdmVGcmFnbWVudChtZXNzYWdlLCBzdGF0ZS5mcmFnbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChhdHRhY2htZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhgUmVzb2x2ZWQgZnJhZ21lbnQgJHtrZXl9IGludG8gYXR0YWNobWVudDpgKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZGlyKGF0dGFjaG1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hdHRhY2htZW50cy5wdXNoKGF0dGFjaG1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5hdHRhY2htZW50c0NoYW5nZS5uZXh0KHRoaXMuYXR0YWNobWVudHMuc2xpY2UoKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXNvbHZlKGF0dGFjaG1lbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYENhdWdodCBlcnJvciBkdXJpbmcgYXR0YWNobWVudCByZXNvbHZlciAke3Jlc29sdmVyLmNvbnN0cnVjdG9yLm5hbWV9OmApO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbn0iXX0=
|