@jubbio/core 1.3.1 → 1.3.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/Client.d.ts +157 -0
- package/dist/cjs/Client.js +640 -0
- package/dist/cjs/builders/ActionRowBuilder.d.ts +53 -0
- package/dist/cjs/builders/ActionRowBuilder.js +68 -0
- package/dist/cjs/builders/ButtonBuilder.d.ts +77 -0
- package/dist/cjs/builders/ButtonBuilder.js +96 -0
- package/dist/cjs/builders/EmbedBuilder.d.ts +157 -0
- package/dist/cjs/builders/EmbedBuilder.js +208 -0
- package/dist/cjs/builders/ModalBuilder.d.ts +122 -0
- package/dist/cjs/builders/ModalBuilder.js +162 -0
- package/dist/cjs/builders/SelectMenuBuilder.d.ts +123 -0
- package/dist/cjs/builders/SelectMenuBuilder.js +165 -0
- package/dist/cjs/builders/SlashCommandBuilder.d.ts +197 -0
- package/dist/cjs/builders/SlashCommandBuilder.js +324 -0
- package/dist/cjs/builders/index.d.ts +9 -0
- package/dist/cjs/builders/index.js +26 -0
- package/dist/cjs/enums.d.ts +191 -0
- package/dist/cjs/enums.js +211 -0
- package/dist/cjs/index.d.ts +25 -0
- package/dist/cjs/index.js +130 -0
- package/dist/cjs/managers/BaseManager.d.ts +69 -0
- package/dist/cjs/managers/BaseManager.js +106 -0
- package/dist/cjs/managers/ChannelManager.d.ts +95 -0
- package/dist/cjs/managers/ChannelManager.js +205 -0
- package/dist/cjs/managers/GuildMemberManager.d.ts +74 -0
- package/dist/cjs/managers/GuildMemberManager.js +157 -0
- package/dist/cjs/managers/RoleManager.d.ts +84 -0
- package/dist/cjs/managers/RoleManager.js +207 -0
- package/dist/cjs/managers/index.d.ts +7 -0
- package/dist/cjs/managers/index.js +24 -0
- package/dist/cjs/rest/REST.d.ts +527 -0
- package/dist/cjs/rest/REST.js +904 -0
- package/dist/cjs/rest/index.d.ts +1 -0
- package/dist/cjs/rest/index.js +18 -0
- package/dist/cjs/sharding/ShardingManager.d.ts +179 -0
- package/dist/cjs/sharding/ShardingManager.js +375 -0
- package/dist/cjs/sharding/index.d.ts +4 -0
- package/dist/cjs/sharding/index.js +21 -0
- package/dist/cjs/structures/Channel.d.ts +122 -0
- package/dist/cjs/structures/Channel.js +240 -0
- package/dist/cjs/structures/Collection.d.ts +53 -0
- package/dist/cjs/structures/Collection.js +115 -0
- package/dist/cjs/structures/Guild.d.ts +59 -0
- package/dist/cjs/structures/Guild.js +94 -0
- package/dist/cjs/structures/GuildMember.d.ts +174 -0
- package/dist/cjs/structures/GuildMember.js +311 -0
- package/dist/cjs/structures/Interaction.d.ts +245 -0
- package/dist/cjs/structures/Interaction.js +450 -0
- package/dist/cjs/structures/Message.d.ts +98 -0
- package/dist/cjs/structures/Message.js +195 -0
- package/dist/cjs/structures/User.d.ts +37 -0
- package/dist/cjs/structures/User.js +65 -0
- package/dist/cjs/structures/index.d.ts +7 -0
- package/dist/cjs/structures/index.js +25 -0
- package/dist/cjs/structures.d.ts +1 -0
- package/dist/cjs/structures.js +19 -0
- package/dist/cjs/types.d.ts +255 -0
- package/dist/cjs/types.js +3 -0
- package/dist/cjs/utils/BitField.d.ts +66 -0
- package/dist/cjs/utils/BitField.js +138 -0
- package/dist/cjs/utils/Collection.d.ts +116 -0
- package/dist/cjs/utils/Collection.js +265 -0
- package/dist/cjs/utils/Collector.d.ts +152 -0
- package/dist/cjs/utils/Collector.js +314 -0
- package/dist/cjs/utils/DataResolver.d.ts +61 -0
- package/dist/cjs/utils/DataResolver.js +146 -0
- package/dist/cjs/utils/Formatters.d.ts +145 -0
- package/dist/cjs/utils/Formatters.js +213 -0
- package/dist/cjs/utils/IntentsBitField.d.ts +85 -0
- package/dist/cjs/utils/IntentsBitField.js +99 -0
- package/dist/cjs/utils/Partials.d.ts +104 -0
- package/dist/cjs/utils/Partials.js +148 -0
- package/dist/cjs/utils/PermissionsBitField.d.ts +118 -0
- package/dist/cjs/utils/PermissionsBitField.js +145 -0
- package/dist/cjs/utils/SnowflakeUtil.d.ts +63 -0
- package/dist/cjs/utils/SnowflakeUtil.js +93 -0
- package/dist/cjs/utils/Sweepers.d.ts +119 -0
- package/dist/cjs/utils/Sweepers.js +249 -0
- package/dist/cjs/utils/index.d.ts +13 -0
- package/dist/cjs/utils/index.js +30 -0
- package/dist/esm/Client.js +634 -0
- package/dist/esm/builders/ActionRowBuilder.js +64 -0
- package/dist/esm/builders/ButtonBuilder.js +92 -0
- package/dist/esm/builders/EmbedBuilder.js +204 -0
- package/dist/esm/builders/ModalBuilder.js +157 -0
- package/dist/esm/builders/SelectMenuBuilder.js +161 -0
- package/dist/esm/builders/SlashCommandBuilder.js +311 -0
- package/dist/esm/builders/index.js +10 -0
- package/dist/esm/enums.js +208 -0
- package/dist/esm/index.js +34 -0
- package/dist/esm/managers/BaseManager.js +100 -0
- package/dist/esm/managers/ChannelManager.js +200 -0
- package/dist/esm/managers/GuildMemberManager.js +153 -0
- package/dist/esm/managers/RoleManager.js +203 -0
- package/dist/esm/managers/index.js +8 -0
- package/dist/esm/rest/REST.js +900 -0
- package/dist/esm/rest/index.js +2 -0
- package/dist/esm/sharding/ShardingManager.js +366 -0
- package/dist/esm/sharding/index.js +5 -0
- package/dist/esm/structures/Channel.js +232 -0
- package/dist/esm/structures/Collection.js +111 -0
- package/dist/esm/structures/Guild.js +90 -0
- package/dist/esm/structures/GuildMember.js +306 -0
- package/dist/esm/structures/Interaction.js +438 -0
- package/dist/esm/structures/Message.js +191 -0
- package/dist/esm/structures/User.js +61 -0
- package/dist/esm/structures/index.js +9 -0
- package/dist/esm/structures.js +3 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/utils/BitField.js +134 -0
- package/dist/esm/utils/Collection.js +261 -0
- package/dist/esm/utils/Collector.js +305 -0
- package/dist/esm/utils/DataResolver.js +142 -0
- package/dist/esm/utils/Formatters.js +191 -0
- package/dist/esm/utils/IntentsBitField.js +93 -0
- package/dist/esm/utils/Partials.js +137 -0
- package/dist/esm/utils/PermissionsBitField.js +141 -0
- package/dist/esm/utils/SnowflakeUtil.js +89 -0
- package/dist/esm/utils/Sweepers.js +245 -0
- package/dist/esm/utils/index.js +14 -0
- package/package.json +14 -4
|
@@ -0,0 +1,634 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
import WebSocket from 'ws';
|
|
3
|
+
import { GatewayOpcodes, GatewayIntentBits } from './enums';
|
|
4
|
+
import { Collection } from './structures/Collection';
|
|
5
|
+
import { User } from './structures/User';
|
|
6
|
+
import { Guild } from './structures/Guild';
|
|
7
|
+
import { Message } from './structures/Message';
|
|
8
|
+
import { createInteraction } from './structures/Interaction';
|
|
9
|
+
import { REST } from './rest/REST';
|
|
10
|
+
/**
|
|
11
|
+
* Main client class
|
|
12
|
+
*/
|
|
13
|
+
export class Client extends EventEmitter {
|
|
14
|
+
/** Client options */
|
|
15
|
+
options;
|
|
16
|
+
/** REST API client */
|
|
17
|
+
rest;
|
|
18
|
+
/** The bot user */
|
|
19
|
+
user = null;
|
|
20
|
+
/** Application ID */
|
|
21
|
+
applicationId = null;
|
|
22
|
+
/** Cached guilds */
|
|
23
|
+
guilds = new Collection();
|
|
24
|
+
/** Cached channels */
|
|
25
|
+
channels = new Collection();
|
|
26
|
+
/** Cached users */
|
|
27
|
+
users = new Collection();
|
|
28
|
+
/** Voice adapter management */
|
|
29
|
+
voice;
|
|
30
|
+
/** WebSocket connection */
|
|
31
|
+
ws = null;
|
|
32
|
+
/** Bot token */
|
|
33
|
+
token = '';
|
|
34
|
+
/** Session ID */
|
|
35
|
+
sessionId = null;
|
|
36
|
+
/** Sequence number */
|
|
37
|
+
sequence = null;
|
|
38
|
+
/** Heartbeat interval */
|
|
39
|
+
heartbeatInterval = null;
|
|
40
|
+
/** Gateway URL */
|
|
41
|
+
gatewayUrl;
|
|
42
|
+
/** Voice state update handlers (for voice adapters) */
|
|
43
|
+
voiceStateHandlers = new Map();
|
|
44
|
+
voiceServerHandlers = new Map();
|
|
45
|
+
/** Whether the client is currently in the login flow */
|
|
46
|
+
_loginState = 'idle';
|
|
47
|
+
/** Reconnect attempt counter */
|
|
48
|
+
_reconnectAttempts = 0;
|
|
49
|
+
/** Maximum reconnect attempts before giving up */
|
|
50
|
+
_maxReconnectAttempts = 5;
|
|
51
|
+
constructor(options) {
|
|
52
|
+
super();
|
|
53
|
+
this.options = options;
|
|
54
|
+
this.gatewayUrl = options.gatewayUrl || 'wss://realtime.jubbio.com/ws/bot';
|
|
55
|
+
this.rest = new REST(options.apiUrl);
|
|
56
|
+
// Initialize voice adapter system
|
|
57
|
+
this.voice = {
|
|
58
|
+
adapters: new Map()
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Calculate intents value
|
|
63
|
+
*/
|
|
64
|
+
getIntentsValue() {
|
|
65
|
+
if (typeof this.options.intents === 'number') {
|
|
66
|
+
return this.options.intents;
|
|
67
|
+
}
|
|
68
|
+
return this.options.intents.reduce((acc, intent) => acc | intent, 0);
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Gateway close code descriptions
|
|
72
|
+
*/
|
|
73
|
+
static CLOSE_CODES = {
|
|
74
|
+
4000: { message: 'Bilinmeyen hata (Unknown error)', reconnectable: true },
|
|
75
|
+
4001: { message: 'Bilinmeyen opcode gönderildi (Unknown opcode)', reconnectable: true },
|
|
76
|
+
4002: { message: 'Geçersiz payload gönderildi (Decode error)', reconnectable: true },
|
|
77
|
+
4003: { message: 'Henüz kimlik doğrulaması yapılmadı (Not authenticated)', reconnectable: true },
|
|
78
|
+
4004: { message: 'Geçersiz bot token\'ı (Authentication failed)', reconnectable: false },
|
|
79
|
+
4005: { message: 'Zaten kimlik doğrulaması yapılmış (Already authenticated)', reconnectable: true },
|
|
80
|
+
4007: { message: 'Geçersiz sequence numarası (Invalid seq)', reconnectable: true },
|
|
81
|
+
4008: { message: 'Rate limit aşıldı (Rate limited)', reconnectable: true },
|
|
82
|
+
4009: { message: 'Oturum zaman aşımına uğradı (Session timed out)', reconnectable: true },
|
|
83
|
+
4010: { message: 'Geçersiz shard yapılandırması (Invalid shard)', reconnectable: false },
|
|
84
|
+
4011: { message: 'Sharding gerekli (Sharding required)', reconnectable: false },
|
|
85
|
+
4014: { message: 'İzin verilmeyen intent\'ler istendi (Disallowed intents)', reconnectable: false },
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* Login to the gateway
|
|
89
|
+
*/
|
|
90
|
+
async login(token) {
|
|
91
|
+
if (!token || typeof token !== 'string') {
|
|
92
|
+
throw new Error('Geçerli bir bot token\'ı sağlanmalıdır. Örnek: client.login(process.env.BOT_TOKEN)');
|
|
93
|
+
}
|
|
94
|
+
this.token = token.replace(/^Bot\s+/i, '');
|
|
95
|
+
this.rest.setToken(this.token);
|
|
96
|
+
this._loginState = 'connecting';
|
|
97
|
+
this._reconnectAttempts = 0;
|
|
98
|
+
return new Promise((resolve, reject) => {
|
|
99
|
+
const cleanup = () => {
|
|
100
|
+
clearTimeout(timeout);
|
|
101
|
+
this.removeListener('ready', onReady);
|
|
102
|
+
this.removeListener('error', onError);
|
|
103
|
+
this.removeListener('gatewayClose', onGatewayClose);
|
|
104
|
+
};
|
|
105
|
+
const timeout = setTimeout(() => {
|
|
106
|
+
cleanup();
|
|
107
|
+
this._loginState = 'idle';
|
|
108
|
+
reject(new Error('Gateway\'e bağlanılamadı: 30 saniye içinde READY event\'i alınamadı. ' +
|
|
109
|
+
'Olası sebepler: gateway sunucusu erişilemez, token geçersiz veya ağ sorunu.'));
|
|
110
|
+
}, 30000);
|
|
111
|
+
const onReady = () => {
|
|
112
|
+
cleanup();
|
|
113
|
+
this._loginState = 'ready';
|
|
114
|
+
this._reconnectAttempts = 0;
|
|
115
|
+
resolve(this.token);
|
|
116
|
+
};
|
|
117
|
+
const onError = (error) => {
|
|
118
|
+
cleanup();
|
|
119
|
+
this._loginState = 'idle';
|
|
120
|
+
reject(error);
|
|
121
|
+
};
|
|
122
|
+
const onGatewayClose = (code, reason) => {
|
|
123
|
+
const info = Client.CLOSE_CODES[code];
|
|
124
|
+
if (info && !info.reconnectable) {
|
|
125
|
+
cleanup();
|
|
126
|
+
this._loginState = 'idle';
|
|
127
|
+
reject(new Error(`Gateway bağlantısı reddedildi [${code}]: ${info.message}${reason ? ' - ' + reason : ''}`));
|
|
128
|
+
}
|
|
129
|
+
// Reconnectable codes: login promise stays alive, connect() will retry
|
|
130
|
+
};
|
|
131
|
+
this.once('ready', onReady);
|
|
132
|
+
this.once('error', onError);
|
|
133
|
+
this.on('gatewayClose', onGatewayClose);
|
|
134
|
+
this.connect();
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Connect to the gateway
|
|
139
|
+
*/
|
|
140
|
+
connect() {
|
|
141
|
+
this.ws = new WebSocket(this.gatewayUrl);
|
|
142
|
+
this.ws.on('open', () => {
|
|
143
|
+
this.emit('debug', 'WebSocket bağlantısı açıldı');
|
|
144
|
+
this._reconnectAttempts = 0;
|
|
145
|
+
});
|
|
146
|
+
this.ws.on('message', (data) => {
|
|
147
|
+
this.handleMessage(data.toString());
|
|
148
|
+
});
|
|
149
|
+
this.ws.on('close', (code, reason) => {
|
|
150
|
+
const reasonStr = reason?.toString() || '';
|
|
151
|
+
const info = Client.CLOSE_CODES[code];
|
|
152
|
+
if (info) {
|
|
153
|
+
this.emit('debug', `Gateway bağlantısı kapandı [${code}]: ${info.message}${reasonStr ? ' - ' + reasonStr : ''}`);
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
this.emit('debug', `WebSocket kapandı: ${code} - ${reasonStr}`);
|
|
157
|
+
}
|
|
158
|
+
this.cleanup();
|
|
159
|
+
// Emit gatewayClose so login() can handle non-reconnectable codes
|
|
160
|
+
this.emit('gatewayClose', code, reasonStr);
|
|
161
|
+
// Non-reconnectable codes: don't retry
|
|
162
|
+
if (info && !info.reconnectable) {
|
|
163
|
+
this.emit('debug', `Kod ${code} yeniden bağlanılamaz, bağlantı sonlandırılıyor.`);
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
// Normal close: don't retry
|
|
167
|
+
if (code === 1000) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
// Reconnectable: retry with backoff
|
|
171
|
+
this._reconnectAttempts++;
|
|
172
|
+
if (this._reconnectAttempts > this._maxReconnectAttempts) {
|
|
173
|
+
this.emit('debug', `Maksimum yeniden bağlanma denemesi aşıldı (${this._maxReconnectAttempts})`);
|
|
174
|
+
this.emit('error', new Error(`Gateway bağlantısı ${this._maxReconnectAttempts} denemeden sonra kurulamadı. Son kapanma kodu: ${code}`));
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
const delay = Math.min(1000 * Math.pow(2, this._reconnectAttempts - 1), 30000);
|
|
178
|
+
this.emit('debug', `Yeniden bağlanılıyor (deneme ${this._reconnectAttempts}/${this._maxReconnectAttempts}), ${delay}ms sonra...`);
|
|
179
|
+
setTimeout(() => this.connect(), delay);
|
|
180
|
+
});
|
|
181
|
+
this.ws.on('error', (error) => {
|
|
182
|
+
this.emit('debug', `WebSocket hatası: ${error.message}`);
|
|
183
|
+
this.emit('error', error);
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Handle incoming gateway message
|
|
188
|
+
*/
|
|
189
|
+
handleMessage(data) {
|
|
190
|
+
// Handle multiple messages in one frame
|
|
191
|
+
const messages = data.split('\n').filter(m => m.trim());
|
|
192
|
+
for (const msg of messages) {
|
|
193
|
+
try {
|
|
194
|
+
const payload = JSON.parse(msg);
|
|
195
|
+
this.handlePayload(payload);
|
|
196
|
+
}
|
|
197
|
+
catch (e) {
|
|
198
|
+
this.emit('debug', `Failed to parse message: ${msg}`);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Handle gateway payload
|
|
204
|
+
*/
|
|
205
|
+
handlePayload(payload) {
|
|
206
|
+
if (payload.s) {
|
|
207
|
+
this.sequence = payload.s;
|
|
208
|
+
}
|
|
209
|
+
switch (payload.op) {
|
|
210
|
+
case GatewayOpcodes.Hello:
|
|
211
|
+
this.handleHello(payload.d);
|
|
212
|
+
break;
|
|
213
|
+
case GatewayOpcodes.Dispatch:
|
|
214
|
+
this.handleDispatch(payload.t, payload.d);
|
|
215
|
+
break;
|
|
216
|
+
case GatewayOpcodes.HeartbeatAck:
|
|
217
|
+
this.emit('debug', 'Heartbeat acknowledged');
|
|
218
|
+
break;
|
|
219
|
+
case GatewayOpcodes.InvalidSession:
|
|
220
|
+
this.emit('debug', 'Geçersiz oturum, yeniden kimlik doğrulanıyor...');
|
|
221
|
+
// InvalidSession may carry error data from sendError()
|
|
222
|
+
if (payload.d && typeof payload.d === 'object' && payload.d.code && payload.d.message) {
|
|
223
|
+
this.emit('debug', `Sunucu hatası [${payload.d.code}]: ${payload.d.message}`);
|
|
224
|
+
const info = Client.CLOSE_CODES[payload.d.code];
|
|
225
|
+
if (info && !info.reconnectable) {
|
|
226
|
+
this.emit('error', new Error(`Gateway hatası [${payload.d.code}]: ${info.message}`));
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
setTimeout(() => this.identify(), 5000);
|
|
231
|
+
break;
|
|
232
|
+
case GatewayOpcodes.Reconnect:
|
|
233
|
+
this.emit('debug', 'Reconnect requested');
|
|
234
|
+
this.ws?.close();
|
|
235
|
+
setTimeout(() => this.connect(), 1000);
|
|
236
|
+
break;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Handle Hello payload
|
|
241
|
+
*/
|
|
242
|
+
handleHello(data) {
|
|
243
|
+
this.emit('debug', `Received Hello, heartbeat interval: ${data.heartbeat_interval}ms`);
|
|
244
|
+
this.startHeartbeat(data.heartbeat_interval);
|
|
245
|
+
this.identify();
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Handle Dispatch events
|
|
249
|
+
*/
|
|
250
|
+
handleDispatch(eventType, data) {
|
|
251
|
+
this.emit('debug', `Dispatch: ${eventType}`);
|
|
252
|
+
switch (eventType) {
|
|
253
|
+
case 'READY':
|
|
254
|
+
this.handleReady(data);
|
|
255
|
+
break;
|
|
256
|
+
case 'GUILD_CREATE':
|
|
257
|
+
this.handleGuildCreate(data);
|
|
258
|
+
break;
|
|
259
|
+
case 'GUILD_UPDATE':
|
|
260
|
+
this.handleGuildUpdate(data);
|
|
261
|
+
break;
|
|
262
|
+
case 'GUILD_DELETE':
|
|
263
|
+
this.handleGuildDelete(data);
|
|
264
|
+
break;
|
|
265
|
+
case 'MESSAGE_CREATE':
|
|
266
|
+
this.handleMessageCreate(data);
|
|
267
|
+
break;
|
|
268
|
+
case 'MESSAGE_UPDATE':
|
|
269
|
+
this.emit('messageUpdate', data);
|
|
270
|
+
break;
|
|
271
|
+
case 'MESSAGE_DELETE':
|
|
272
|
+
this.emit('messageDelete', data);
|
|
273
|
+
break;
|
|
274
|
+
case 'MESSAGE_DELETE_BULK':
|
|
275
|
+
this.emit('messageDeleteBulk', data);
|
|
276
|
+
break;
|
|
277
|
+
case 'CHANNEL_CREATE': {
|
|
278
|
+
// Update guild channel cache
|
|
279
|
+
const guildId = data.guild_id;
|
|
280
|
+
const channelId = data.id || data.channel_id;
|
|
281
|
+
if (guildId && channelId) {
|
|
282
|
+
const guild = this.guilds.get(guildId);
|
|
283
|
+
if (guild) {
|
|
284
|
+
guild.channels.set(channelId, data);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
this.emit('channelCreate', data);
|
|
288
|
+
break;
|
|
289
|
+
}
|
|
290
|
+
case 'CHANNEL_UPDATE': {
|
|
291
|
+
const guildId = data.guild_id;
|
|
292
|
+
const channelId = data.id || data.channel_id;
|
|
293
|
+
if (guildId && channelId) {
|
|
294
|
+
const guild = this.guilds.get(guildId);
|
|
295
|
+
if (guild) {
|
|
296
|
+
guild.channels.set(channelId, data);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
this.emit('channelUpdate', data);
|
|
300
|
+
break;
|
|
301
|
+
}
|
|
302
|
+
case 'CHANNEL_DELETE': {
|
|
303
|
+
const guildId = data.guild_id;
|
|
304
|
+
const channelId = data.id || data.channel_id;
|
|
305
|
+
if (guildId && channelId) {
|
|
306
|
+
const guild = this.guilds.get(guildId);
|
|
307
|
+
if (guild) {
|
|
308
|
+
guild.channels.delete(channelId);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
this.emit('channelDelete', data);
|
|
312
|
+
break;
|
|
313
|
+
}
|
|
314
|
+
case 'GUILD_MEMBER_ADD': {
|
|
315
|
+
const guild = this.guilds.get(String(data.guild_id));
|
|
316
|
+
if (guild && data.user) {
|
|
317
|
+
const member = guild._addMember(data);
|
|
318
|
+
this.emit('guildMemberAdd', member);
|
|
319
|
+
}
|
|
320
|
+
else {
|
|
321
|
+
this.emit('guildMemberAdd', data);
|
|
322
|
+
}
|
|
323
|
+
break;
|
|
324
|
+
}
|
|
325
|
+
case 'GUILD_MEMBER_UPDATE': {
|
|
326
|
+
const guild = this.guilds.get(String(data.guild_id));
|
|
327
|
+
const rawUserId = data.user?.id || data.user_id;
|
|
328
|
+
if (guild && rawUserId) {
|
|
329
|
+
const existing = guild.members.get(String(rawUserId));
|
|
330
|
+
if (existing) {
|
|
331
|
+
existing._patch(data);
|
|
332
|
+
this.emit('guildMemberUpdate', existing);
|
|
333
|
+
}
|
|
334
|
+
else {
|
|
335
|
+
this.emit('guildMemberUpdate', data);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
this.emit('guildMemberUpdate', data);
|
|
340
|
+
}
|
|
341
|
+
break;
|
|
342
|
+
}
|
|
343
|
+
case 'GUILD_MEMBER_REMOVE': {
|
|
344
|
+
const guild = this.guilds.get(String(data.guild_id));
|
|
345
|
+
const rawUserId = data.user?.id || data.user_id;
|
|
346
|
+
if (guild && rawUserId) {
|
|
347
|
+
const userId = String(rawUserId);
|
|
348
|
+
const member = guild.members.get(userId);
|
|
349
|
+
guild.members.delete(userId);
|
|
350
|
+
this.emit('guildMemberRemove', member || data);
|
|
351
|
+
}
|
|
352
|
+
else {
|
|
353
|
+
this.emit('guildMemberRemove', data);
|
|
354
|
+
}
|
|
355
|
+
break;
|
|
356
|
+
}
|
|
357
|
+
case 'GUILD_ROLE_CREATE':
|
|
358
|
+
this.emit('roleCreate', data);
|
|
359
|
+
break;
|
|
360
|
+
case 'GUILD_ROLE_UPDATE':
|
|
361
|
+
this.emit('roleUpdate', data);
|
|
362
|
+
break;
|
|
363
|
+
case 'GUILD_ROLE_DELETE':
|
|
364
|
+
this.emit('roleDelete', data);
|
|
365
|
+
break;
|
|
366
|
+
case 'GUILD_BAN_ADD':
|
|
367
|
+
this.emit('guildBanAdd', data);
|
|
368
|
+
break;
|
|
369
|
+
case 'GUILD_BAN_REMOVE':
|
|
370
|
+
this.emit('guildBanRemove', data);
|
|
371
|
+
break;
|
|
372
|
+
case 'INVITE_CREATE':
|
|
373
|
+
this.emit('inviteCreate', data);
|
|
374
|
+
break;
|
|
375
|
+
case 'INVITE_DELETE':
|
|
376
|
+
this.emit('inviteDelete', data);
|
|
377
|
+
break;
|
|
378
|
+
case 'TYPING_START':
|
|
379
|
+
this.emit('typingStart', data);
|
|
380
|
+
break;
|
|
381
|
+
case 'PRESENCE_UPDATE':
|
|
382
|
+
this.emit('presenceUpdate', data);
|
|
383
|
+
break;
|
|
384
|
+
case 'INTERACTION_CREATE':
|
|
385
|
+
this.handleInteractionCreate(data);
|
|
386
|
+
break;
|
|
387
|
+
case 'VOICE_STATE_UPDATE':
|
|
388
|
+
this.handleVoiceStateUpdate(data);
|
|
389
|
+
break;
|
|
390
|
+
case 'VOICE_SERVER_UPDATE':
|
|
391
|
+
this.handleVoiceServerUpdate(data);
|
|
392
|
+
break;
|
|
393
|
+
default:
|
|
394
|
+
// Emit raw event for unhandled types
|
|
395
|
+
this.emit('raw', { t: eventType, d: data });
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Handle Ready event
|
|
400
|
+
*/
|
|
401
|
+
handleReady(data) {
|
|
402
|
+
this.sessionId = data.session_id;
|
|
403
|
+
this.user = new User(data.user);
|
|
404
|
+
// Handle both string and number application IDs
|
|
405
|
+
this.applicationId = data.application?.id ? String(data.application.id) : null;
|
|
406
|
+
if (this.applicationId) {
|
|
407
|
+
this.rest.setApplicationId(this.applicationId);
|
|
408
|
+
}
|
|
409
|
+
// Cache guilds (as unavailable initially)
|
|
410
|
+
if (data.guilds) {
|
|
411
|
+
for (const guild of data.guilds) {
|
|
412
|
+
this.guilds.set(String(guild.id), new Guild(this, guild));
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
// Setup voice adapters for each guild
|
|
416
|
+
this.setupVoiceAdapters();
|
|
417
|
+
console.log(`✅ Bot hazır! User: ${this.user.username} (${this.user.id}), App: ${this.applicationId}`);
|
|
418
|
+
this.emit('ready', this);
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Setup voice adapters for all guilds
|
|
422
|
+
*/
|
|
423
|
+
setupVoiceAdapters() {
|
|
424
|
+
for (const [guildId] of this.guilds) {
|
|
425
|
+
this.createVoiceAdapter(guildId);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Create a voice adapter for a guild
|
|
430
|
+
*/
|
|
431
|
+
createVoiceAdapter(guildId) {
|
|
432
|
+
const adapter = (methods) => {
|
|
433
|
+
// Store handlers for this guild
|
|
434
|
+
this.voiceStateHandlers.set(guildId, methods.onVoiceStateUpdate);
|
|
435
|
+
this.voiceServerHandlers.set(guildId, methods.onVoiceServerUpdate);
|
|
436
|
+
return {
|
|
437
|
+
sendPayload: (payload) => {
|
|
438
|
+
if (this.ws?.readyState === WebSocket.OPEN) {
|
|
439
|
+
this.ws.send(JSON.stringify(payload));
|
|
440
|
+
return true;
|
|
441
|
+
}
|
|
442
|
+
return false;
|
|
443
|
+
},
|
|
444
|
+
destroy: () => {
|
|
445
|
+
this.voiceStateHandlers.delete(guildId);
|
|
446
|
+
this.voiceServerHandlers.delete(guildId);
|
|
447
|
+
}
|
|
448
|
+
};
|
|
449
|
+
};
|
|
450
|
+
this.voice.adapters.set(guildId, adapter);
|
|
451
|
+
}
|
|
452
|
+
/**
|
|
453
|
+
* Handle Guild Create event
|
|
454
|
+
*/
|
|
455
|
+
handleGuildCreate(data) {
|
|
456
|
+
let guild = this.guilds.get(data.id);
|
|
457
|
+
if (guild) {
|
|
458
|
+
guild._patch(data);
|
|
459
|
+
}
|
|
460
|
+
else {
|
|
461
|
+
guild = new Guild(this, data);
|
|
462
|
+
this.guilds.set(data.id, guild);
|
|
463
|
+
this.createVoiceAdapter(data.id);
|
|
464
|
+
}
|
|
465
|
+
this.emit('guildCreate', guild);
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* Handle Guild Update event
|
|
469
|
+
*/
|
|
470
|
+
handleGuildUpdate(data) {
|
|
471
|
+
const guild = this.guilds.get(data.id);
|
|
472
|
+
if (guild) {
|
|
473
|
+
guild._patch(data);
|
|
474
|
+
this.emit('guildUpdate', guild);
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
/**
|
|
478
|
+
* Handle Guild Delete event
|
|
479
|
+
*/
|
|
480
|
+
handleGuildDelete(data) {
|
|
481
|
+
const guild = this.guilds.get(data.id);
|
|
482
|
+
if (guild) {
|
|
483
|
+
this.guilds.delete(data.id);
|
|
484
|
+
this.voice.adapters.delete(data.id);
|
|
485
|
+
this.emit('guildDelete', guild);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Handle Message Create event
|
|
490
|
+
*/
|
|
491
|
+
handleMessageCreate(data) {
|
|
492
|
+
// Backend sends user_id separately, map it to author.id for compatibility
|
|
493
|
+
if (data.user_id && data.author && !data.author.id) {
|
|
494
|
+
data.author.id = data.user_id;
|
|
495
|
+
}
|
|
496
|
+
// Cache the author
|
|
497
|
+
if (data.author) {
|
|
498
|
+
const user = new User(data.author);
|
|
499
|
+
this.users.set(user.id, user);
|
|
500
|
+
// Also cache in REST for mention resolution
|
|
501
|
+
this.rest.cacheUser(data.author);
|
|
502
|
+
}
|
|
503
|
+
const message = new Message(this, data);
|
|
504
|
+
// Mark message as from bot if author ID matches the bot's own user ID
|
|
505
|
+
if (this.user && String(message.author.id) === String(this.user.id)) {
|
|
506
|
+
message.author.bot = true;
|
|
507
|
+
}
|
|
508
|
+
// Resolve guild member if in a guild
|
|
509
|
+
if (message.guildId) {
|
|
510
|
+
const guild = this.guilds.get(message.guildId);
|
|
511
|
+
const memberData = data.member;
|
|
512
|
+
if (memberData && guild) {
|
|
513
|
+
// Gateway sent member data with the message — cache it
|
|
514
|
+
memberData.user = data.author;
|
|
515
|
+
const member = guild._addMember(memberData);
|
|
516
|
+
message.member = member;
|
|
517
|
+
}
|
|
518
|
+
else if (memberData) {
|
|
519
|
+
// No guild in cache but member data exists
|
|
520
|
+
memberData.user = data.author;
|
|
521
|
+
const resolvedGuild = { id: message.guildId, ownerId: null };
|
|
522
|
+
message.member = new (require('./structures/GuildMember').GuildMember)(this, resolvedGuild, memberData);
|
|
523
|
+
}
|
|
524
|
+
else if (guild) {
|
|
525
|
+
// Try cache
|
|
526
|
+
const cached = guild.members?.get(String(message.author.id));
|
|
527
|
+
if (cached?.permissions?.has) {
|
|
528
|
+
message.member = cached;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
this.emit('messageCreate', message);
|
|
533
|
+
}
|
|
534
|
+
/**
|
|
535
|
+
* Handle Interaction Create event
|
|
536
|
+
*/
|
|
537
|
+
handleInteractionCreate(data) {
|
|
538
|
+
console.log('[DEBUG] handleInteractionCreate called with:', JSON.stringify(data, null, 2));
|
|
539
|
+
// Cache the user
|
|
540
|
+
const userData = data.member?.user || data.user;
|
|
541
|
+
if (userData) {
|
|
542
|
+
const user = new User(userData);
|
|
543
|
+
this.users.set(user.id, user);
|
|
544
|
+
this.rest.cacheUser(userData);
|
|
545
|
+
}
|
|
546
|
+
const interaction = createInteraction(this, data);
|
|
547
|
+
console.log('[DEBUG] Created interaction type:', interaction.constructor.name, 'customId:', interaction.customId);
|
|
548
|
+
this.emit('interactionCreate', interaction);
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* Handle Voice State Update event
|
|
552
|
+
*/
|
|
553
|
+
handleVoiceStateUpdate(data) {
|
|
554
|
+
const guildId = data.guild_id;
|
|
555
|
+
// Forward to voice adapter if exists
|
|
556
|
+
const handler = this.voiceStateHandlers.get(guildId);
|
|
557
|
+
if (handler) {
|
|
558
|
+
handler(data);
|
|
559
|
+
}
|
|
560
|
+
this.emit('voiceStateUpdate', data);
|
|
561
|
+
}
|
|
562
|
+
/**
|
|
563
|
+
* Handle Voice Server Update event
|
|
564
|
+
*/
|
|
565
|
+
handleVoiceServerUpdate(data) {
|
|
566
|
+
const guildId = data.guild_id;
|
|
567
|
+
// Forward to voice adapter if exists
|
|
568
|
+
const handler = this.voiceServerHandlers.get(guildId);
|
|
569
|
+
if (handler) {
|
|
570
|
+
handler({
|
|
571
|
+
token: data.token,
|
|
572
|
+
endpoint: data.endpoint,
|
|
573
|
+
room: data.room
|
|
574
|
+
});
|
|
575
|
+
}
|
|
576
|
+
this.emit('voiceServerUpdate', data);
|
|
577
|
+
}
|
|
578
|
+
/**
|
|
579
|
+
* Send Identify payload
|
|
580
|
+
*/
|
|
581
|
+
identify() {
|
|
582
|
+
const payload = {
|
|
583
|
+
op: GatewayOpcodes.Identify,
|
|
584
|
+
d: {
|
|
585
|
+
token: `Bot ${this.token}`,
|
|
586
|
+
intents: this.getIntentsValue(),
|
|
587
|
+
shard: this.options.shards || [0, 1]
|
|
588
|
+
}
|
|
589
|
+
};
|
|
590
|
+
this.send(payload);
|
|
591
|
+
}
|
|
592
|
+
/**
|
|
593
|
+
* Start heartbeat
|
|
594
|
+
*/
|
|
595
|
+
startHeartbeat(interval) {
|
|
596
|
+
this.heartbeatInterval = setInterval(() => {
|
|
597
|
+
this.send({
|
|
598
|
+
op: GatewayOpcodes.Heartbeat,
|
|
599
|
+
d: this.sequence
|
|
600
|
+
});
|
|
601
|
+
}, interval);
|
|
602
|
+
}
|
|
603
|
+
/**
|
|
604
|
+
* Send payload to gateway
|
|
605
|
+
*/
|
|
606
|
+
send(payload) {
|
|
607
|
+
if (this.ws?.readyState === WebSocket.OPEN) {
|
|
608
|
+
this.ws.send(JSON.stringify(payload));
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
/**
|
|
612
|
+
* Cleanup on disconnect
|
|
613
|
+
*/
|
|
614
|
+
cleanup() {
|
|
615
|
+
if (this.heartbeatInterval) {
|
|
616
|
+
clearInterval(this.heartbeatInterval);
|
|
617
|
+
this.heartbeatInterval = null;
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
/**
|
|
621
|
+
* Destroy the client
|
|
622
|
+
*/
|
|
623
|
+
destroy() {
|
|
624
|
+
this._loginState = 'idle';
|
|
625
|
+
this._reconnectAttempts = this._maxReconnectAttempts + 1; // Prevent reconnect
|
|
626
|
+
this.cleanup();
|
|
627
|
+
this.ws?.close(1000);
|
|
628
|
+
this.ws = null;
|
|
629
|
+
this.removeAllListeners();
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
// Re-export for convenience
|
|
633
|
+
export { GatewayIntentBits };
|
|
634
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL0NsaWVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBQ3RDLE9BQU8sU0FBUyxNQUFNLElBQUksQ0FBQztBQVkzQixPQUFPLEVBQUUsY0FBYyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sU0FBUyxDQUFDO0FBQzVELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDekMsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUMvQyxPQUFPLEVBQUUsaUJBQWlCLEVBQWUsTUFBTSwwQkFBMEIsQ0FBQztBQUUxRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBY25DOztHQUVHO0FBQ0gsTUFBTSxPQUFPLE1BQU8sU0FBUSxZQUFZO0lBQ3RDLHFCQUFxQjtJQUNMLE9BQU8sQ0FBZ0I7SUFFdkMsc0JBQXNCO0lBQ04sSUFBSSxDQUFPO0lBRTNCLG1CQUFtQjtJQUNaLElBQUksR0FBZ0IsSUFBSSxDQUFDO0lBRWhDLHFCQUFxQjtJQUNkLGFBQWEsR0FBa0IsSUFBSSxDQUFDO0lBRTNDLG9CQUFvQjtJQUNiLE1BQU0sR0FBOEIsSUFBSSxVQUFVLEVBQUUsQ0FBQztJQUU1RCxzQkFBc0I7SUFDZixRQUFRLEdBQW9DLElBQUksVUFBVSxFQUFFLENBQUM7SUFFcEUsbUJBQW1CO0lBQ1osS0FBSyxHQUE2QixJQUFJLFVBQVUsRUFBRSxDQUFDO0lBRTFELCtCQUErQjtJQUN4QixLQUFLLENBRVY7SUFFRiwyQkFBMkI7SUFDbkIsRUFBRSxHQUFxQixJQUFJLENBQUM7SUFFcEMsZ0JBQWdCO0lBQ1IsS0FB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aUIsQ0FBQyxDQUFDO1lBQ3RDLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUM7UUFDaEMsQ0FBQztJQUNILENBQUM7SUFFRDs7T0FFRztJQUNILE9BQU87UUFDTCxJQUFJLENBQUMsV0FBVyxHQUFHLE1BQU0sQ0FBQztRQUMxQixJQUFJLENBQUMsa0JBQWtCLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixHQUFHLENBQUMsQ0FBQyxDQUFDLG9CQUFvQjtRQUM5RSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDZixJQUFJLENBQUMsRUFBRSxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNyQixJQUFJLENBQUMsRUFBRSxHQUFHLElBQUksQ0FBQztRQUNmLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO0lBQzVCLENBQUM7O0FBR0gsNEJBQTRCO0FBQzVCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRXZlbnRFbWl0dGVyIH0gZnJvbSAnZXZlbnRzJztcclxuaW1wb3J0IFdlYlNvY2tldCBmcm9tICd3cyc7XHJcbmltcG9ydCB7IFxyXG4gIENsaWVudE9wdGlvbnMsIFxyXG4gIEdhdGV3YXlQYXlsb2FkLCBcclxuICBSZWFkeUV2ZW50RGF0YSxcclxuICBBUElHdWlsZCxcclxuICBBUElJbnRlcmFjdGlvbixcclxuICBBUElNZXNzYWdlLFxyXG4gIEFQSVZvaWNlU2VydmVyVXBkYXRlLFxyXG4gIEFQSUNoYW5uZWwsXHJcbiAgQVBJVXNlclxyXG59IGZyb20gJy4vdHlwZXMnO1xyXG5pbXBvcnQgeyBHYXRld2F5T3Bjb2RlcywgR2F0ZXdheUludGVudEJpdHMgfSBmcm9tICcuL2VudW1zJztcclxuaW1wb3J0IHsgQ29sbGVjdGlvbiB9IGZyb20gJy4vc3RydWN0dXJlcy9Db2xsZWN0aW9uJztcclxuaW1wb3J0IHsgVXNlciB9IGZyb20gJy4vc3RydWN0dXJlcy9Vc2VyJztcclxuaW1wb3J0IHsgR3VpbGQgfSBmcm9tICcuL3N0cnVjdHVyZXMvR3VpbGQnO1xyXG5pbXBvcnQgeyBNZXNzYWdlIH0gZnJvbSAnLi9zdHJ1Y3R1cmVzL01lc3NhZ2UnO1xyXG5pbXBvcnQgeyBjcmVhdGVJbnRlcmFjdGlvbiwgSW50ZXJhY3Rpb24gfSBmcm9tICcuL3N0cnVjdHVyZXMvSW50ZXJhY3Rpb24nO1xyXG5pbXBvcnQgeyBCYXNlQ2hhbm5lbCwgY3JlYXRlQ2hhbm5lbCB9IGZyb20gJy4vc3RydWN0dXJlcy9DaGFubmVsJztcclxuaW1wb3J0IHsgUkVTVCB9IGZyb20gJy4vcmVzdC9SRVNUJztcclxuXHJcbi8qKlxyXG4gKiBWb2ljZSBhZGFwdGVyIGNyZWF0b3IgdHlwZSBmb3IgQGp1YmJpby92b2ljZSBjb21wYXRpYmlsaXR5XHJcbiAqL1xyXG50eXBlIFZvaWNlQWRhcHRlckNyZWF0b3IgPSAobWV0aG9kczoge1xyXG4gIG9uVm9pY2VTZXJ2ZXJVcGRhdGUoZGF0YTogYW55KTogdm9pZDtcclxuICBvblZvaWNlU3RhdGVVcGRhdGUoZGF0YTogYW55KTogdm9pZDtcclxuICBkZXN0cm95KCk6IHZvaWQ7XHJcbn0pID0+IHtcclxuICBzZW5kUGF5bG9hZChwYXlsb2FkOiBhbnkpOiBib29sZWFuO1xyXG4gIGRlc3Ryb3koKTogdm9pZDtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBNYWluIGNsaWVudCBjbGFzc1xyXG4gKi9cclxuZXhwb3J0IGNsYXNzIENsaWVudCBleHRlbmRzIEV2ZW50RW1pdHRlciB7XHJcbiAgLyoqIENsaWVudCBvcHRpb25zICovXHJcbiAgcHVibGljIHJlYWRvbmx5IG9wdGlvbnM6IENsaWVudE9wdGlvbnM7XHJcbiAgXHJcbiAgLyoqIFJFU1QgQVBJIGNsaWVudCAqL1xyXG4gIHB1YmxpYyByZWFkb25seSByZXN0OiBSRVNUO1xyXG4gIFxyXG4gIC8qKiBUaGUgYm90IHVzZXIgKi9cclxuICBwdWJsaWMgdXNlcjogVXNlciB8IG51bGwgPSBudWxsO1xyXG4gIFxyXG4gIC8qKiBBcHBsaWNhdGlvbiBJRCAqL1xyXG4gIHB1YmxpYyBhcHBsaWNhdGlvbklkOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcclxuICBcclxuICAvKiogQ2FjaGVkIGd1aWxkcyAqL1xyXG4gIHB1YmxpYyBndWlsZHM6IENvbGxlY3Rpb248c3RyaW5nLCBHdWlsZD4gPSBuZXcgQ29sbGVjdGlvbigpO1xyXG4gIFxyXG4gIC8qKiBDYWNoZWQgY2hhbm5lbHMgKi9cclxuICBwdWJsaWMgY2hhbm5lbHM6IENvbGxlY3Rpb248c3RyaW5nLCBCYXNlQ2hhbm5lbD4gPSBuZXcgQ29sbGVjdGlvbigpO1xyXG4gIFxyXG4gIC8qKiBDYWNoZWQgdXNlcnMgKi9cclxuICBwdWJsaWMgdXNlcnM6IENvbGxlY3Rpb248c3RyaW5nLCBVc2VyPiA9IG5ldyBDb2xsZWN0aW9uKCk7XHJcbiAgXHJcbiAgLyoqIFZvaWNlIGFkYXB0ZXIgbWFuYWdlbWVudCAqL1xyXG4gIHB1YmxpYyB2b2ljZToge1xyXG4gICAgYWRhcHRlcnM6IE1hcDxzdHJpbmcsIFZvaWNlQWRhcHRlckNyZWF0b3I+O1xyXG4gIH07XHJcbiAgXHJcbiAgLyoqIFdlYlNvY2tldCBjb25uZWN0aW9uICovXHJcbiAgcHJpdmF0ZSB3czogV2ViU29ja2V0IHwgbnVsbCA9IG51bGw7XHJcbiAgXHJcbiAgLyoqIEJvdCB0b2tlbiAqL1xyXG4gIHByaXZhdGUgdG9rZW46IHN0cmluZyA9ICcnO1xyXG4gIFxyXG4gIC8qKiBTZXNzaW9uIElEICovXHJcbiAgcHJpdmF0ZSBzZXNzaW9uSWQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xyXG4gIFxyXG4gIC8qKiBTZXF1ZW5jZSBudW1iZXIgKi9cclxuICBwcml2YXRlIHNlcXVlbmNlOiBudW1iZXIgfCBudWxsID0gbnVsbDtcclxuICBcclxuICAvKiogSGVhcnRiZWF0IGludGVydmFsICovXHJcbiAgcHJpdmF0ZSBoZWFydGJlYXRJbnRlcnZhbDogTm9kZUpTLlRpbWVvdXQgfCBudWxsID0gbnVsbDtcclxuICBcclxuICAvKiogR2F0ZXdheSBVUkwgKi9cclxuICBwcml2YXRlIGdhdGV3YXlVcmw6IHN0cmluZztcclxuICBcclxuICAvKiogVm9pY2Ugc3RhdGUgdXBkYXRlIGhhbmRsZXJzIChmb3Igdm9pY2UgYWRhcHRlcnMpICovXHJcbiAgcHJpdmF0ZSB2b2ljZVN0YXRlSGFuZGxlcnM6IE1hcDxzdHJpbmcsIChkYXRhOiBhbnkpID0+IHZvaWQ+ID0gbmV3IE1hcCgpO1xyXG4gIHByaXZhdGUgdm9pY2VTZXJ2ZXJIYW5kbGVyczogTWFwPHN0cmluZywgKGRhdGE6IGFueSkgPT4gdm9pZD4gPSBuZXcgTWFwKCk7XHJcblxyXG4gIC8qKiBXaGV0aGVyIHRoZSBjbGllbnQgaXMgY3VycmVudGx5IGluIHRoZSBsb2dpbiBmbG93ICovXHJcbiAgcHJpdmF0ZSBfbG9naW5TdGF0ZTogJ2lkbGUnIHwgJ2Nvbm5lY3RpbmcnIHwgJ3JlYWR5JyA9ICdpZGxlJztcclxuXHJcbiAgLyoqIFJlY29ubmVjdCBhdHRlbXB0IGNvdW50ZXIgKi9cclxuICBwcml2YXRlIF9yZWNvbm5lY3RBdHRlbXB0czogbnVtYmVyID0gMDtcclxuXHJcbiAgLyoqIE1heGltdW0gcmVjb25uZWN0IGF0dGVtcHRzIGJlZm9yZSBnaXZpbmcgdXAgKi9cclxuICBwcml2YXRlIHJlYWRvbmx5IF9tYXhSZWNvbm5lY3RBdHRlbXB0czogbnVtYmVyID0gNTtcclxuXHJcbiAgY29uc3RydWN0b3Iob3B0aW9uczogQ2xpZW50T3B0aW9ucykge1xyXG4gICAgc3VwZXIoKTtcclxuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnM7XHJcbiAgICB0aGlzLmdhdGV3YXlVcmwgPSBvcHRpb25zLmdhdGV3YXlVcmwgfHwgJ3dzczovL3JlYWx0aW1lLmp1YmJpby5jb20vd3MvYm90JztcclxuICAgIHRoaXMucmVzdCA9IG5ldyBSRVNUKG9wdGlvbnMuYXBpVXJsKTtcclxuICAgIFxyXG4gICAgLy8gSW5pdGlhbGl6ZSB2b2ljZSBhZGFwdGVyIHN5c3RlbVxyXG4gICAgdGhpcy52b2ljZSA9IHtcclxuICAgICAgYWRhcHRlcnM6IG5ldyBNYXAoKVxyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENhbGN1bGF0ZSBpbnRlbnRzIHZhbHVlXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBnZXRJbnRlbnRzVmFsdWUoKTogbnVtYmVyIHtcclxuICAgIGlmICh0eXBlb2YgdGhpcy5vcHRpb25zLmludGVudHMgPT09ICdudW1iZXInKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLm9wdGlvbnMuaW50ZW50cztcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzLm9wdGlvbnMuaW50ZW50cy5yZWR1Y2UoKGFjYywgaW50ZW50KSA9PiBhY2MgfCBpbnRlbnQsIDApO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2F0ZXdheSBjbG9zZSBjb2RlIGRlc2NyaXB0aW9uc1xyXG4gICAqL1xyXG4gIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IENMT1NFX0NPREVTOiBSZWNvcmQ8bnVtYmVyLCB7IG1lc3NhZ2U6IHN0cmluZzsgcmVjb25uZWN0YWJsZTogYm9vbGVhbiB9PiA9IHtcclxuICAgIDQwMDA6IHsgbWVzc2FnZTogJ0JpbGlubWV5ZW4gaGF0YSAoVW5rbm93biBlcnJvciknLCByZWNvbm5lY3RhYmxlOiB0cnVlIH0sXHJcbiAgICA0MDAxOiB7IG1lc3NhZ2U6ICdCaWxpbm1leWVuIG9wY29kZSBnw7ZuZGVyaWxkaSAoVW5rbm93biBvcGNvZGUpJywgcmVjb25uZWN0YWJsZTogdHJ1ZSB9LFxyXG4gICAgNDAwMjogeyBtZXNzYWdlOiAnR2XDp2Vyc2l6IHBheWxvYWQgZ8O2bmRlcmlsZGkgKERlY29kZSBlcnJvciknLCByZWNvbm5lY3RhYmxlOiB0cnVlIH0sXHJcbiAgICA0MDAzOiB7IG1lc3NhZ2U6ICdIZW7DvHoga2ltbGlrIGRvxJ9ydWxhbWFzxLEgeWFwxLFsbWFkxLEgKE5vdCBhdXRoZW50aWNhdGVkKScsIHJlY29ubmVjdGFibGU6IHRydWUgfSxcclxuICAgIDQwMDQ6IHsgbWVzc2FnZTogJ0dlw6dlcnNpeiBib3QgdG9rZW5cXCfEsSAoQXV0aGVudGljYXRpb24gZmFpbGVkKScsIHJlY29ubmVjdGFibGU6IGZhbHNlIH0sXHJcbiAgICA0MDA1OiB7IG1lc3NhZ2U6ICdaYXRlbiBraW1saWsgZG/En3J1bGFtYXPEsSB5YXDEsWxtxLHFnyAoQWxyZWFkeSBhdXRoZW50aWNhdGVkKScsIHJlY29ubmVjdGFibGU6IHRydWUgfSxcclxuICAgIDQwMDc6IHsgbWVzc2FnZTogJ0dlw6dlcnNpeiBzZXF1ZW5jZSBudW1hcmFzxLEgKEludmFsaWQgc2VxKScsIHJlY29ubmVjdGFibGU6IHRydWUgfSxcclxuICAgIDQwMDg6IHsgbWVzc2FnZTogJ1JhdGUgbGltaXQgYcWfxLFsZMSxIChSYXRlIGxpbWl0ZWQpJywgcmVjb25uZWN0YWJsZTogdHJ1ZSB9LFxyXG4gICAgNDAwOTogeyBtZXNzYWdlOiAnT3R1cnVtIHphbWFuIGHFn8SxbcSxbmEgdcSfcmFkxLEgKFNlc3Npb24gdGltZWQgb3V0KScsIHJlY29ubmVjdGFibGU6IHRydWUgfSxcclxuICAgIDQwMTA6IHsgbWVzc2FnZTogJ0dlw6dlcnNpeiBzaGFyZCB5YXDEsWxhbmTEsXJtYXPEsSAoSW52YWxpZCBzaGFyZCknLCByZWNvbm5lY3RhYmxlOiBmYWxzZSB9LFxyXG4gICAgNDAxMTogeyBtZXNzYWdlOiAnU2hhcmRpbmcgZ2VyZWtsaSAoU2hhcmRpbmcgcmVxdWlyZWQpJywgcmVjb25uZWN0YWJsZTogZmFsc2UgfSxcclxuICAgIDQwMTQ6IHsgbWVzc2FnZTogJ8SwemluIHZlcmlsbWV5ZW4gaW50ZW50XFwnbGVyIGlzdGVuZGkgKERpc2FsbG93ZWQgaW50ZW50cyknLCByZWNvbm5lY3RhYmxlOiBmYWxzZSB9LFxyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIExvZ2luIHRvIHRoZSBnYXRld2F5XHJcbiAgICovXHJcbiAgYXN5bmMgbG9naW4odG9rZW46IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XHJcbiAgICBpZiAoIXRva2VuIHx8IHR5cGVvZiB0b2tlbiAhPT0gJ3N0cmluZycpIHtcclxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxyXG4gICAgICAgICdHZcOnZXJsaSBiaXIgYm90IHRva2VuXFwnxLEgc2HEn2xhbm1hbMSxZMSxci4gw5ZybmVrOiBjbGllbnQubG9naW4ocHJvY2Vzcy5lbnYuQk9UX1RPS0VOKSdcclxuICAgICAgKTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnRva2VuID0gdG9rZW4ucmVwbGFjZSgvXkJvdFxccysvaSwgJycpO1xyXG4gICAgdGhpcy5yZXN0LnNldFRva2VuKHRoaXMudG9rZW4pO1xyXG4gICAgdGhpcy5fbG9naW5TdGF0ZSA9ICdjb25uZWN0aW5nJztcclxuICAgIHRoaXMuX3JlY29ubmVjdEF0dGVtcHRzID0gMDtcclxuXHJcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xyXG4gICAgICBjb25zdCBjbGVhbnVwID0gKCkgPT4ge1xyXG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcclxuICAgICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKCdyZWFkeScsIG9uUmVhZHkpO1xyXG4gICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25FcnJvcik7XHJcbiAgICAgICAgdGhpcy5yZW1vdmVMaXN0ZW5lcignZ2F0ZXdheUNsb3NlJywgb25HYXRld2F5Q2xvc2UpO1xyXG4gICAgICB9O1xyXG5cclxuICAgICAgY29uc3QgdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICAgIGNsZWFudXAoKTtcclxuICAgICAgICB0aGlzLl9sb2dpblN0YXRlID0gJ2lkbGUnO1xyXG4gICAgICAgIHJlamVjdChuZXcgRXJyb3IoXHJcbiAgICAgICAgICAnR2F0ZXdheVxcJ2UgYmHEn2xhbsSxbGFtYWTEsTogMzAgc2FuaXllIGnDp2luZGUgUkVBRFkgZXZlbnRcXCdpIGFsxLFuYW1hZMSxLiAnICtcclxuICAgICAgICAgICdPbGFzxLEgc2ViZXBsZXI6IGdhdGV3YXkgc3VudWN1c3UgZXJpxZ9pbGVtZXosIHRva2VuIGdlw6dlcnNpeiB2ZXlhIGHEnyBzb3J1bnUuJ1xyXG4gICAgICAgICkpO1xyXG4gICAgICB9LCAzMDAwMCk7XHJcblxyXG4gICAgICBjb25zdCBvblJlYWR5ID0gKCkgPT4ge1xyXG4gICAgICAgIGNsZWFudXAoKTtcclxuICAgICAgICB0aGlzLl9sb2dpblN0YXRlID0gJ3JlYWR5JztcclxuICAgICAgICB0aGlzLl9yZWNvbm5lY3RBdHRlbXB0cyA9IDA7XHJcbiAgICAgICAgcmVzb2x2ZSh0aGlzLnRva2VuKTtcclxuICAgICAgfTtcclxuXHJcbiAgICAgIGNvbnN0IG9uRXJyb3IgPSAoZXJyb3I6IEVycm9yKSA9PiB7XHJcbiAgICAgICAgY2xlYW51cCgpO1xyXG4gICAgICAgIHRoaXMuX2xvZ2luU3RhdGUgPSAnaWRsZSc7XHJcbiAgICAgICAgcmVqZWN0KGVycm9yKTtcclxuICAgICAgfTtcclxuXHJcbiAgICAgIGNvbnN0IG9uR2F0ZXdheUNsb3NlID0gKGNvZGU6IG51bWJlciwgcmVhc29uOiBzdHJpbmcpID0+IHtcclxuICAgICAgICBjb25zdCBpbmZvID0gQ2xpZW50LkNMT1NFX0NPREVTW2NvZGVdO1xyXG4gICAgICAgIGlmIChpbmZvICYmICFpbmZvLnJlY29ubmVjdGFibGUpIHtcclxuICAgICAgICAgIGNsZWFudXAoKTtcclxuICAgICAgICAgIHRoaXMuX2xvZ2luU3RhdGUgPSAnaWRsZSc7XHJcbiAgICAgICAgICByZWplY3QobmV3IEVycm9yKGBHYXRld2F5IGJhxJ9sYW50xLFzxLEgcmVkZGVkaWxkaSBbJHtjb2RlfV06ICR7aW5mby5tZXNzYWdlfSR7cmVhc29uID8gJyAtICcgKyByZWFzb24gOiAnJ31gKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIFJlY29ubmVjdGFibGUgY29kZXM6IGxvZ2luIHByb21pc2Ugc3RheXMgYWxpdmUsIGNvbm5lY3QoKSB3aWxsIHJldHJ5XHJcbiAgICAgIH07XHJcblxyXG4gICAgICB0aGlzLm9uY2UoJ3JlYWR5Jywgb25SZWFkeSk7XHJcbiAgICAgIHRoaXMub25jZSgnZXJyb3InLCBvbkVycm9yKTtcclxuICAgICAgdGhpcy5vbignZ2F0ZXdheUNsb3NlJywgb25HYXRld2F5Q2xvc2UpO1xyXG5cclxuICAgICAgdGhpcy5jb25uZWN0KCk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENvbm5lY3QgdG8gdGhlIGdhdGV3YXlcclxuICAgKi9cclxuICBwcml2YXRlIGNvbm5lY3QoKTogdm9pZCB7XHJcbiAgICB0aGlzLndzID0gbmV3IFdlYlNvY2tldCh0aGlzLmdhdGV3YXlVcmwpO1xyXG4gICAgXHJcbiAgICB0aGlzLndzLm9uKCdvcGVuJywgKCkgPT4ge1xyXG4gICAgICB0aGlzLmVtaXQoJ2RlYnVnJywgJ1dlYlNvY2tldCBiYcSfbGFudMSxc8SxIGHDp8SxbGTEsScpO1xyXG4gICAgICB0aGlzLl9yZWNvbm5lY3RBdHRlbXB0cyA9IDA7XHJcbiAgICB9KTtcclxuICAgIFxyXG4gICAgdGhpcy53cy5vbignbWVzc2FnZScsIChkYXRhKSA9PiB7XHJcbiAgICAgIHRoaXMuaGFuZGxlTWVzc2FnZShkYXRhLnRvU3RyaW5nKCkpO1xyXG4gICAgfSk7XHJcbiAgICBcclxuICAgIHRoaXMud3Mub24oJ2Nsb3NlJywgKGNvZGUsIHJlYXNvbikgPT4ge1xyXG4gICAgICBjb25zdCByZWFzb25TdHIgPSByZWFzb24/LnRvU3RyaW5nKCkgfHwgJyc7XHJcbiAgICAgIGNvbnN0IGluZm8gPSBDbGllbnQuQ0xPU0VfQ09ERVNbY29kZV07XHJcbiAgICAgIFxyXG4gICAgICBpZiAoaW5mbykge1xyXG4gICAgICAgIHRoaXMuZW1pdCgnZGVidWcnLCBgR2F0ZXdheSBiYcSfbGFudMSxc8SxIGthcGFuZMSxIFske2NvZGV9XTogJHtpbmZvLm1lc3NhZ2V9JHtyZWFzb25TdHIgPyAnIC0gJyArIHJlYXNvblN0ciA6ICcnfWApO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuZW1pdCgnZGVidWcnLCBgV2ViU29ja2V0IGthcGFuZMSxOiAke2NvZGV9IC0gJHtyZWFzb25TdHJ9YCk7XHJcbiAgICAgIH1cclxuICAgICAgXHJcbiAgICAgIHRoaXMuY2xlYW51cCgpO1xyXG5cclxuICAgICAgLy8gRW1pdCBnYXRld2F5Q2xvc2Ugc28gbG9naW4oKSBjYW4gaGFuZGxlIG5vbi1yZWNvbm5lY3RhYmxlIGNvZGVzXHJcbiAgICAgIHRoaXMuZW1pdCgnZ2F0ZXdheUNsb3NlJywgY29kZSwgcmVhc29uU3RyKTtcclxuXHJcbiAgICAgIC8vIE5vbi1yZWNvbm5lY3RhYmxlIGNvZGVzOiBkb24ndCByZXRyeVxyXG4gICAgICBpZiAoaW5mbyAmJiAhaW5mby5yZWNvbm5lY3RhYmxlKSB7XHJcbiAgICAgICAgdGhpcy5lbWl0KCdkZWJ1ZycsIGBLb2QgJHtjb2RlfSB5ZW5pZGVuIGJhxJ9sYW7EsWxhbWF6LCBiYcSfbGFudMSxIHNvbmxhbmTEsXLEsWzEsXlvci5gKTtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIE5vcm1hbCBjbG9zZTogZG9uJ3QgcmV0cnlcclxuICAgICAgaWYgKGNvZGUgPT09IDEwMDApIHtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIFJlY29ubmVjdGFibGU6IHJldHJ5IHdpdGggYmFja29mZlxyXG4gICAgICB0aGlzLl9yZWNvbm5lY3RBdHRlbXB0cysrO1xyXG4gICAgICBpZiAodGhpcy5fcmVjb25uZWN0QXR0ZW1wdHMgPiB0aGlzLl9tYXhSZWNvbm5lY3RBdHRlbXB0cykge1xyXG4gICAgICAgIHRoaXMuZW1pdCgnZGVidWcnLCBgTWFrc2ltdW0geWVuaWRlbiBiYcSfbGFubWEgZGVuZW1lc2kgYcWfxLFsZMSxICgke3RoaXMuX21heFJlY29ubmVjdEF0dGVtcHRzfSlgKTtcclxuICAgICAgICB0aGlzLmVtaXQoJ2Vycm9yJywgbmV3IEVycm9yKFxyXG4gICAgICAgICAgYEdhdGV3YXkgYmHEn2xhbnTEsXPEsSAke3RoaXMuX21heFJlY29ubmVjdEF0dGVtcHRzfSBkZW5lbWVkZW4gc29ucmEga3VydWxhbWFkxLEuIFNvbiBrYXBhbm1hIGtvZHU6ICR7Y29kZX1gXHJcbiAgICAgICAgKSk7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBjb25zdCBkZWxheSA9IE1hdGgubWluKDEwMDAgKiBNYXRoLnBvdygyLCB0aGlzLl9yZWNvbm5lY3RBdHRlbXB0cyAtIDEpLCAzMDAwMCk7XHJcbiAgICAgIHRoaXMuZW1pdCgnZGVidWcnLCBgWWVuaWRlbiBiYcSfbGFuxLFsxLF5b3IgKGRlbmVtZSAke3RoaXMuX3JlY29ubmVjdEF0dGVtcHRzfS8ke3RoaXMuX21heFJlY29ubmVjdEF0dGVtcHRzfSksICR7ZGVsYXl9bXMgc29ucmEuLi5gKTtcclxuICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLmNvbm5lY3QoKSwgZGVsYXkpO1xyXG4gICAgfSk7XHJcbiAgICBcclxuICAgIHRoaXMud3Mub24oJ2Vycm9yJywgKGVycm9yKSA9PiB7XHJcbiAgICAgIHRoaXMuZW1pdCgnZGVidWcnLCBgV2ViU29ja2V0IGhhdGFzxLE6ICR7ZXJyb3IubWVzc2FnZX1gKTtcclxuICAgICAgdGhpcy5lbWl0KCdlcnJvcicsIGVycm9yKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSGFuZGxlIGluY29taW5nIGdhdGV3YXkgbWVzc2FnZVxyXG4gICAqL1xyXG4gIHByaXZhdGUgaGFuZGxlTWVzc2FnZShkYXRhOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIC8vIEhhbmRsZSBtdWx0aXBsZSBtZXNzYWdlcyBpbiBvbmUgZnJhbWVcclxuICAgIGNvbnN0IG1lc3NhZ2VzID0gZGF0YS5zcGxpdCgnXFxuJykuZmlsdGVyKG0gPT4gbS50cmltKCkpO1xyXG4gICAgXHJcbiAgICBmb3IgKGNvbnN0IG1zZyBvZiBtZXNzYWdlcykge1xyXG4gICAgICB0cnkge1xyXG4gICAgICAgIGNvbnN0IHBheWxvYWQ6IEdhdGV3YXlQYXlsb2FkID0gSlNPTi5wYXJzZShtc2cpO1xyXG4gICAgICAgIHRoaXMuaGFuZGxlUGF5bG9hZChwYXlsb2FkKTtcclxuICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgIHRoaXMuZW1pdCgnZGVidWcnLCBgRmFpbGVkIHRvIHBhcnNlIG1lc3NhZ2U6ICR7bXNnfWApO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIYW5kbGUgZ2F0ZXdheSBwYXlsb2FkXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBoYW5kbGVQYXlsb2FkKHBheWxvYWQ6IEdhdGV3YXlQYXlsb2FkKTogdm9pZCB7XHJcbiAgICBpZiAocGF5bG9hZC5zKSB7XHJcbiAgICAgIHRoaXMuc2VxdWVuY2UgPSBwYXlsb2FkLnM7XHJcbiAgICB9XHJcblxyXG4gICAgc3dpdGNoIChwYXlsb2FkLm9wKSB7XHJcbiAgICAgIGNhc2UgR2F0ZXdheU9wY29kZXMuSGVsbG86XHJcbiAgICAgICAgdGhpcy5oYW5kbGVIZWxsbyhwYXlsb2FkLmQpO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICAgIFxyXG4gICAgICBjYXNlIEdhdGV3YXlPcGNvZGVzLkRpc3BhdGNoOlxyXG4gICAgICAgIHRoaXMuaGFuZGxlRGlzcGF0Y2gocGF5bG9hZC50ISwgcGF5bG9hZC5kKTtcclxuICAgICAgICBicmVhaztcclxuICAgICAgICBcclxuICAgICAgY2FzZSBHYXRld2F5T3Bjb2Rlcy5IZWFydGJlYXRBY2s6XHJcbiAgICAgICAgdGhpcy5lbWl0KCdkZWJ1ZycsICdIZWFydGJlYXQgYWNrbm93bGVkZ2VkJyk7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgXHJcbiAgICAgIGNhc2UgR2F0ZXdheU9wY29kZXMuSW52YWxpZFNlc3Npb246XHJcbiAgICAgICAgdGhpcy5lbWl0KCdkZWJ1ZycsICdHZcOnZXJzaXogb3R1cnVtLCB5ZW5pZGVuIGtpbWxpayBkb8SfcnVsYW7EsXlvci4uLicpO1xyXG4gICAgICAgIC8vIEludmFsaWRTZXNzaW9uIG1heSBjYXJyeSBlcnJvciBkYXRhIGZyb20gc2VuZEVycm9yKClcclxuICAgICAgICBpZiAocGF5bG9hZC5kICYmIHR5cGVvZiBwYXlsb2FkLmQgPT09ICdvYmplY3QnICYmIHBheWxvYWQuZC5jb2RlICYmIHBheWxvYWQuZC5tZXNzYWdlKSB7XHJcbiAgICAgICAgICB0aGlzLmVtaXQoJ2RlYnVnJywgYFN1bnVjdSBoYXRhc8SxIFske3BheWxvYWQuZC5jb2RlfV06ICR7cGF5bG9hZC5kLm1lc3NhZ2V9YCk7XHJcbiAgICAgICAgICBjb25zdCBpbmZvID0gQ2xpZW50LkNMT1NFX0NPREVTW3BheWxvYWQuZC5jb2RlXTtcclxuICAgICAgICAgIGlmIChpbmZvICYmICFpbmZvLnJlY29ubmVjdGFibGUpIHtcclxuICAgICAgICAgICAgdGhpcy5lbWl0KCdlcnJvcicsIG5ldyBFcnJvcihgR2F0ZXdheSBoYXRhc8SxIFske3BheWxvYWQuZC5jb2RlfV06ICR7aW5mby5tZXNzYWdlfWApKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBzZXRUaW1lb3V0KCgpID0+IHRoaXMuaWRlbnRpZnkoKSwgNTAwMCk7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgXHJcbiAgICAgIGNhc2UgR2F0ZXdheU9wY29kZXMuUmVjb25uZWN0OlxyXG4gICAgICAgIHRoaXMuZW1pdCgnZGVidWcnLCAnUmVjb25uZWN0IHJlcXVlc3RlZCcpO1xyXG4gICAgICAgIHRoaXMud3M/LmNsb3NlKCk7XHJcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLmNvbm5lY3QoKSwgMTAwMCk7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIYW5kbGUgSGVsbG8gcGF5bG9hZFxyXG4gICAqL1xyXG4gIHByaXZhdGUgaGFuZGxlSGVsbG8oZGF0YTogeyBoZWFydGJlYXRfaW50ZXJ2YWw6IG51bWJlciB9KTogdm9pZCB7XHJcbiAgICB0aGlzLmVtaXQoJ2RlYnVnJywgYFJlY2VpdmVkIEhlbGxvLCBoZWFydGJlYXQgaW50ZXJ2YWw6ICR7ZGF0YS5oZWFydGJlYXRfaW50ZXJ2YWx9bXNgKTtcclxuICAgIHRoaXMuc3RhcnRIZWFydGJlYXQoZGF0YS5oZWFydGJlYXRfaW50ZXJ2YWwpO1xyXG4gICAgdGhpcy5pZGVudGlmeSgpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSGFuZGxlIERpc3BhdGNoIGV2ZW50c1xyXG4gICAqL1xyXG4gIHByaXZhdGUgaGFuZGxlRGlzcGF0Y2goZXZlbnRUeXBlOiBzdHJpbmcsIGRhdGE6IGFueSk6IHZvaWQge1xyXG4gICAgdGhpcy5lbWl0KCdkZWJ1ZycsIGBEaXNwYXRjaDogJHtldmVudFR5cGV9YCk7XHJcbiAgICBcclxuICAgIHN3aXRjaCAoZXZlbnRUeXBlKSB7XHJcbiAgICAgIGNhc2UgJ1JFQURZJzpcclxuICAgICAgICB0aGlzLmhhbmRsZVJlYWR5KGRhdGEpO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICAgIFxyXG4gICAgICBjYXNlICdHVUlMRF9DUkVBVEUnOlxyXG4gICAgICAgIHRoaXMuaGFuZGxlR3VpbGRDcmVhdGUoZGF0YSk7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgXHJcbiAgICAgIGNhc2UgJ0dVSUxEX1VQREFURSc6XHJcbiAgICAgICAgdGhpcy5oYW5kbGVHdWlsZFVwZGF0ZShkYXRhKTtcclxuICAgICAgICBicmVhaztcclxuICAgICAgICBcclxuICAgICAgY2FzZSAnR1VJTERfREVMRVRFJzpcclxuICAgICAgICB0aGlzLmhhbmRsZUd1aWxkRGVsZXRlKGRhdGEpO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICAgIFxyXG4gICAgICBjYXNlICdNRVNTQUdFX0NSRUFURSc6XHJcbiAgICAgICAgdGhpcy5oYW5kbGVNZXNzYWdlQ3JlYXRlKGRhdGEpO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICAgIFxyXG4gICAgICBjYXNlICdNRVNTQUdFX1VQREFURSc6XHJcbiAgICAgICAgdGhpcy5lbWl0KCdtZXNzYWdlVXBkYXRlJywgZGF0YSk7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgXHJcbiAgICAgIGNhc2UgJ01FU1NBR0VfREVMRVRFJzpcclxuICAgICAgICB0aGlzLmVtaXQoJ21lc3NhZ2VEZWxldGUnLCBkYXRhKTtcclxuICAgICAgICBicmVhaztcclxuICAgICAgICBcclxuICAgICAgY2FzZSAnTUVTU0FHRV9ERUxFVEVfQlVMSyc6XHJcbiAgICAgICAgdGhpcy5lbWl0KCdtZXNzYWdlRGVsZXRlQnVsaycsIGRhdGEpO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICAgIFxyXG4gICAgICBjYXNlICdDSEFOTkVMX0NSRUFURSc6IHtcclxuICAgICAgICAvLyBVcGRhdGUgZ3VpbGQgY2hhbm5lbCBjYWNoZVxyXG4gICAgICAgIGNvbnN0IGd1aWxkSWQgPSBkYXRhLmd1aWxkX2lkO1xyXG4gICAgICAgIGNvbnN0IGNoYW5uZWxJZCA9IGRhdGEuaWQgfHwgZGF0YS5jaGFubmVsX2lkO1xyXG4gICAgICAgIGlmIChndWlsZElkICYmIGNoYW5uZWxJZCkge1xyXG4gICAgICAgICAgY29uc3QgZ3VpbGQgPSB0aGlzLmd1aWxkcy5nZXQoZ3VpbGRJZCk7XHJcbiAgICAgICAgICBpZiAoZ3VpbGQpIHtcclxuICAgICAgICAgICAgZ3VpbGQuY2hhbm5lbHMuc2V0KGNoYW5uZWxJZCwgZGF0YSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuZW1pdCgnY2hhbm5lbENyZWF0ZScsIGRhdGEpO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgIGNhc2UgJ0NIQU5ORUxfVVBEQVRFJzoge1xyXG4gICAgICAgIGNvbnN0IGd1aWxkSWQgPSBkYXRhLmd1aWxkX2lkO1xyXG4gICAgICAgIGNvbnN0IGNoYW5uZWxJZCA9IGRhdGEuaWQgfHwgZGF0YS5jaGFubmVsX2lkO1xyXG4gICAgICAgIGlmIChndWlsZElkICYmIGNoYW5uZWxJZCkge1xyXG4gICAgICAgICAgY29uc3QgZ3VpbGQgPSB0aGlzLmd1aWxkcy5nZXQoZ3VpbGRJZCk7XHJcbiAgICAgICAgICBpZiAoZ3VpbGQpIHtcclxuICAgICAgICAgICAgZ3VpbGQuY2hhbm5lbHMuc2V0KGNoYW5uZWxJZCwgZGF0YSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuZW1pdCgnY2hhbm5lbFVwZGF0ZScsIGRhdGEpO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgIGNhc2UgJ0NIQU5ORUxfREVMRVRFJzoge1xyXG4gICAgICAgIGNvbnN0IGd1aWxkSWQgPSBkYXRhLmd1aWxkX2lkO1xyXG4gICAgICAgIGNvbnN0IGNoYW5uZWxJZCA9IGRhdGEuaWQgfHwgZGF0YS5jaGFubmVsX2lkO1xyXG4gICAgICAgIGlmIChndWlsZElkICYmIGNoYW5uZWxJZCkge1xyXG4gICAgICAgICAgY29uc3QgZ3VpbGQgPSB0aGlzLmd1aWxkcy5nZXQoZ3VpbGRJZCk7XHJcbiAgICAgICAgICBpZiAoZ3VpbGQpIHtcclxuICAgICAgICAgICAgZ3VpbGQuY2hhbm5lbHMuZGVsZXRlKGNoYW5uZWxJZCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuZW1pdCgnY2hhbm5lbERlbGV0ZScsIGRhdGEpO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcbiAgICAgICAgXHJcbiAgICAgIGNhc2UgJ0dVSUxEX01FTUJFUl9BREQnOiB7XHJcbiAgICAgICAgY29uc3QgZ3VpbGQgPSB0aGlzLmd1aWxkcy5nZXQoU3RyaW5nKGRhdGEuZ3VpbGRfaWQpKTtcclxuICAgICAgICBpZiAoZ3VpbGQgJiYgZGF0YS51c2VyKSB7XHJcbiAgICAgICAgICBjb25zdCBtZW1iZXIgPSBndWlsZC5fYWRkTWVtYmVyKGRhdGEpO1xyXG4gICAgICAgICAgdGhpcy5lbWl0KCdndWlsZE1lbWJlckFkZCcsIG1lbWJlcik7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRoaXMuZW1pdCgnZ3VpbGRNZW1iZXJBZGQnLCBkYXRhKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgY2FzZSAnR1VJTERfTUVNQkVSX1VQREFURSc6IHtcclxuICAgICAgICBjb25zdCBndWlsZCA9IHRoaXMuZ3VpbGRzLmdldChTdHJpbmcoZGF0YS5ndWlsZF9pZCkpO1xyXG4gICAgICAgIGNvbnN0IHJhd1VzZXJJZCA9IGRhdGEudXNlcj8uaWQgfHwgZGF0YS51c2VyX2lkO1xyXG4gICAgICAgIGlmIChndWlsZCAmJiByYXdVc2VySWQpIHtcclxuICAgICAgICAgIGNvbnN0IGV4aXN0aW5nID0gZ3VpbGQubWVtYmVycy5nZXQoU3RyaW5nKHJhd1VzZXJJZCkpO1xyXG4gICAgICAgICAgaWYgKGV4aXN0aW5nKSB7XHJcbiAgICAgICAgICAgIGV4aXN0aW5nLl9wYXRjaChkYXRhKTtcclxuICAgICAgICAgICAgdGhpcy5lbWl0KCdndWlsZE1lbWJlclVwZGF0ZScsIGV4aXN0aW5nKTtcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnZ3VpbGRNZW1iZXJVcGRhdGUnLCBkYXRhKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdGhpcy5lbWl0KCdndWlsZE1lbWJlclVwZGF0ZScsIGRhdGEpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBicmVhaztcclxuICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgICBjYXNlICdHVUlMRF9NRU1CRVJfUkVNT1ZFJzoge1xyXG4gICAgICAgIGNvbnN0IGd1aWxkID0gdGhpcy5ndWlsZHMuZ2V0KFN0cmluZyhkYXRhLmd1aWxkX2lkKSk7XHJcbiAgICAgICAgY29uc3QgcmF3VXNlcklkID0gZGF0YS51c2VyPy5pZCB8fCBkYXRhLnVzZXJfaWQ7XHJcbiAgICAgICAgaWYgKGd1aWxkICYmIHJhd1VzZXJJZCkge1xyXG4gICAgICAgICAgY29uc3QgdXNlcklkID0gU3RyaW5nKHJhd1VzZXJJZCk7XHJcbiAgICAgICAgICBjb25zdCBtZW1iZXIgPSBndWlsZC5tZW1iZXJzLmdldCh1c2VySWQpO1xyXG4gICAgICAgICAgZ3VpbGQubWVtYmVycy5kZWxldGUodXNlcklkKTtcclxuICAgICAgICAgIHRoaXMuZW1pdCgnZ3VpbGRNZW1iZXJSZW1vdmUnLCBtZW1iZXIgfHwgZGF0YSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRoaXMuZW1pdCgnZ3VpbGRNZW1iZXJSZW1vdmUnLCBkYXRhKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgIH1cclxuICAgICAgICBcclxuICAgICAgY2FzZSAnR1VJTERfUk9MRV9DUkVBVEUnOlxyXG4gICAgICAgIHRoaXMuZW1pdCgncm9sZUNyZWF0ZScsIGRhdGEpO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICAgIFxyXG4gICAgICBjYXNlICdHVUlMRF9ST0xFX1VQREFURSc6XHJcbiAgICAgICAgdGhpcy5lbWl0KCdyb2xlVXBkYXRlJywgZGF0YSk7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgXHJcbiAgICAgIGNhc2UgJ0dVSUxEX1JPTEVfREVMRVRFJzpcclxuICAgICAgICB0aGlzLmVtaXQoJ3JvbGVEZWxldGUnLCBkYXRhKTtcclxuICAgICAgICBicmVhaztcclxuICAgICAgICBcclxuICAgICAgY2FzZSAnR1VJTERfQkFOX0FERCc6XHJcbiAgICAgICAgdGhpcy5lbWl0KCdndWlsZEJhbkFkZCcsIGRhdGEpO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICAgIFxyXG4gICAgICBjYXNlICdHVUlMRF9CQU5fUkVNT1ZFJzpcclxuICAgICAgICB0aGlzLmVtaXQoJ2d1aWxkQmFuUmVtb3ZlJywgZGF0YSk7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgXHJcbiAgICAgIGNhc2UgJ0lOVklURV9DUkVBVEUnOlxyXG4gICAgICAgIHRoaXMuZW1pdCgnaW52aXRlQ3JlYXRlJywgZGF0YSk7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgXHJcbiAgICAgIGNhc2UgJ0lOVklURV9ERUxFVEUnOlxyXG4gICAgICAgIHRoaXMuZW1pdCgnaW52aXRlRGVsZXRlJywgZGF0YSk7XHJcbiAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgXHJcbiAgICAgIGNhc2UgJ1RZUElOR19TVEFSVCc6XHJcbiAgICAgICAgdGhpcy5lbWl0KCd0eXBpbmdTdGFydCcsIGRhdGEpO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICAgIFxyXG4gICAgICBjYXNlICdQUkVTRU5DRV9VUERBVEUnOlxyXG4gICAgICAgIHRoaXMuZW1pdCgncHJlc2VuY2VVcGRhdGUnLCBkYXRhKTtcclxuICAgICAgICBicmVhaztcclxuICAgICAgICBcclxuICAgICAgY2FzZSAnSU5URVJBQ1RJT05fQ1JFQVRFJzpcclxuICAgICAgICB0aGlzLmhhbmRsZUludGVyYWN0aW9uQ3JlYXRlKGRhdGEpO1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICAgIFxyXG4gICAgICBjYXNlICdWT0lDRV9TVEFURV9VUERBVEUnOlxyXG4gICAgICAgIHRoaXMuaGFuZGxlVm9pY2VTdGF0ZVVwZGF0ZShkYXRhKTtcclxuICAgICAgICBicmVhaztcclxuICAgICAgICBcclxuICAgICAgY2FzZSAnVk9JQ0VfU0VSVkVSX1VQREFURSc6XHJcbiAgICAgICAgdGhpcy5oYW5kbGVWb2ljZVNlcnZlclVwZGF0ZShkYXRhKTtcclxuICAgICAgICBicmVhaztcclxuICAgICAgICBcclxuICAgICAgZGVmYXVsdDpcclxuICAgICAgICAvLyBFbWl0IHJhdyBldmVudCBmb3IgdW5oYW5kbGVkIHR5cGVzXHJcbiAgICAgICAgdGhpcy5lbWl0KCdyYXcnLCB7IHQ6IGV2ZW50VHlwZSwgZDogZGF0YSB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEhhbmRsZSBSZWFkeSBldmVudFxyXG4gICAqL1xyXG4gIHByaXZhdGUgaGFuZGxlUmVhZHkoZGF0YTogUmVhZHlFdmVudERhdGEpOiB2b2lkIHtcclxuICAgIHRoaXMuc2Vzc2lvbklkID0gZGF0YS5zZXNzaW9uX2lkO1xyXG4gICAgdGhpcy51c2VyID0gbmV3IFVzZXIoZGF0YS51c2VyKTtcclxuICAgIC8vIEhhbmRsZSBib3RoIHN0cmluZyBhbmQgbnVtYmVyIGFwcGxpY2F0aW9uIElEc1xyXG4gICAgdGhpcy5hcHBsaWNhdGlvbklkID0gZGF0YS5hcHBsaWNhdGlvbj8uaWQgPyBTdHJpbmcoZGF0YS5hcHBsaWNhdGlvbi5pZCkgOiBudWxsO1xyXG4gICAgaWYgKHRoaXMuYXBwbGljYXRpb25JZCkge1xyXG4gICAgICB0aGlzLnJlc3Quc2V0QXBwbGljYXRpb25JZCh0aGlzLmFwcGxpY2F0aW9uSWQpO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICAvLyBDYWNoZSBndWlsZHMgKGFzIHVuYXZhaWxhYmxlIGluaXRpYWxseSlcclxuICAgIGlmIChkYXRhLmd1aWxkcykge1xyXG4gICAgICBmb3IgKGNvbnN0IGd1aWxkIG9mIGRhdGEuZ3VpbGRzKSB7XHJcbiAgICAgICAgdGhpcy5ndWlsZHMuc2V0KFN0cmluZyhndWlsZC5pZCksIG5ldyBHdWlsZCh0aGlzLCBndWlsZCkpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICBcclxuICAgIC8vIFNldHVwIHZvaWNlIGFkYXB0ZXJzIGZvciBlYWNoIGd1aWxkXHJcbiAgICB0aGlzLnNldHVwVm9pY2VBZGFwdGVycygpO1xyXG4gICAgXHJcbiAgICBjb25zb2xlLmxvZyhg4pyFIEJvdCBoYXrEsXIhIFVzZXI6ICR7dGhpcy51c2VyLnVzZXJuYW1lfSAoJHt0aGlzLnVzZXIuaWR9KSwgQXBwOiAke3RoaXMuYXBwbGljYXRpb25JZH1gKTtcclxuICAgIHRoaXMuZW1pdCgncmVhZHknLCB0aGlzKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFNldHVwIHZvaWNlIGFkYXB0ZXJzIGZvciBhbGwgZ3VpbGRzXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBzZXR1cFZvaWNlQWRhcHRlcnMoKTogdm9pZCB7XHJcbiAgICBmb3IgKGNvbnN0IFtndWlsZElkXSBvZiB0aGlzLmd1aWxkcykge1xyXG4gICAgICB0aGlzLmNyZWF0ZVZvaWNlQWRhcHRlcihndWlsZElkKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENyZWF0ZSBhIHZvaWNlIGFkYXB0ZXIgZm9yIGEgZ3VpbGRcclxuICAgKi9cclxuICBwcml2YXRlIGNyZWF0ZVZvaWNlQWRhcHRlcihndWlsZElkOiBzdHJpbmcpOiB2b2lkIHtcclxuICAgIGNvbnN0IGFkYXB0ZXI6IFZvaWNlQWRhcHRlckNyZWF0b3IgPSAobWV0aG9kcykgPT4ge1xyXG4gICAgICAvLyBTdG9yZSBoYW5kbGVycyBmb3IgdGhpcyBndWlsZFxyXG4gICAgICB0aGlzLnZvaWNlU3RhdGVIYW5kbGVycy5zZXQoZ3VpbGRJZCwgbWV0aG9kcy5vblZvaWNlU3RhdGVVcGRhdGUpO1xyXG4gICAgICB0aGlzLnZvaWNlU2VydmVySGFuZGxlcnMuc2V0KGd1aWxkSWQsIG1ldGhvZHMub25Wb2ljZVNlcnZlclVwZGF0ZSk7XHJcbiAgICAgIFxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIHNlbmRQYXlsb2FkOiAocGF5bG9hZCkgPT4ge1xyXG4gICAgICAgICAgaWYgKHRoaXMud3M/LnJlYWR5U3RhdGUgPT09IFdlYlNvY2tldC5PUEVOKSB7XHJcbiAgICAgICAgICAgIHRoaXMud3Muc2VuZChKU09OLnN0cmluZ2lmeShwYXlsb2FkKSk7XHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZGVzdHJveTogKCkgPT4ge1xyXG4gICAgICAgICAgdGhpcy52b2ljZVN0YXRlSGFuZGxlcnMuZGVsZXRlKGd1aWxkSWQpO1xyXG4gICAgICAgICAgdGhpcy52b2ljZVNlcnZlckhhbmRsZXJzLmRlbGV0ZShndWlsZElkKTtcclxuICAgICAgICB9XHJcbiAgICAgIH07XHJcbiAgICB9O1xyXG4gICAgXHJcbiAgICB0aGlzLnZvaWNlLmFkYXB0ZXJzLnNldChndWlsZElkLCBhZGFwdGVyKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEhhbmRsZSBHdWlsZCBDcmVhdGUgZXZlbnRcclxuICAgKi9cclxuICBwcml2YXRlIGhhbmRsZUd1aWxkQ3JlYXRlKGRhdGE6IEFQSUd1aWxkKTogdm9pZCB7XHJcbiAgICBsZXQgZ3VpbGQgPSB0aGlzLmd1aWxkcy5nZXQoZGF0YS5pZCk7XHJcbiAgICBcclxuICAgIGlmIChndWlsZCkge1xyXG4gICAgICBndWlsZC5fcGF0Y2goZGF0YSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBndWlsZCA9IG5ldyBHdWlsZCh0aGlzLCBkYXRhKTtcclxuICAgICAgdGhpcy5ndWlsZHMuc2V0KGRhdGEuaWQsIGd1aWxkKTtcclxuICAgICAgdGhpcy5jcmVhdGVWb2ljZUFkYXB0ZXIoZGF0YS5pZCk7XHJcbiAgICB9XHJcbiAgICBcclxuICAgIHRoaXMuZW1pdCgnZ3VpbGRDcmVhdGUnLCBndWlsZCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIYW5kbGUgR3VpbGQgVXBkYXRlIGV2ZW50XHJcbiAgICovXHJcbiAgcHJpdmF0ZSBoYW5kbGVHdWlsZFVwZGF0ZShkYXRhOiBBUElHdWlsZCk6IHZvaWQge1xyXG4gICAgY29uc3QgZ3VpbGQgPSB0aGlzLmd1aWxkcy5nZXQoZGF0YS5pZCk7XHJcbiAgICBpZiAoZ3VpbGQpIHtcclxuICAgICAgZ3VpbGQuX3BhdGNoKGRhdGEpO1xyXG4gICAgICB0aGlzLmVtaXQoJ2d1aWxkVXBkYXRlJywgZ3VpbGQpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSGFuZGxlIEd1aWxkIERlbGV0ZSBldmVudFxyXG4gICAqL1xyXG4gIHByaXZhdGUgaGFuZGxlR3VpbGREZWxldGUoZGF0YTogeyBpZDogc3RyaW5nIH0pOiB2b2lkIHtcclxuICAgIGNvbnN0IGd1aWxkID0gdGhpcy5ndWlsZHMuZ2V0KGRhdGEuaWQpO1xyXG4gICAgaWYgKGd1aWxkKSB7XHJcbiAgICAgIHRoaXMuZ3VpbGRzLmRlbGV0ZShkYXRhLmlkKTtcclxuICAgICAgdGhpcy52b2ljZS5hZGFwdGVycy5kZWxldGUoZGF0YS5pZCk7XHJcbiAgICAgIHRoaXMuZW1pdCgnZ3VpbGREZWxldGUnLCBndWlsZCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIYW5kbGUgTWVzc2FnZSBDcmVhdGUgZXZlbnRcclxuICAgKi9cclxuICBwcml2YXRlIGhhbmRsZU1lc3NhZ2VDcmVhdGUoZGF0YTogQVBJTWVzc2FnZSk6IHZvaWQge1xyXG4gICAgLy8gQmFja2VuZCBzZW5kcyB1c2VyX2lkIHNlcGFyYXRlbHksIG1hcCBpdCB0byBhdXRob3IuaWQgZm9yIGNvbXBhdGliaWxpdHlcclxuICAgIGlmIChkYXRhLnVzZXJfaWQgJiYgZGF0YS5hdXRob3IgJiYgIWRhdGEuYXV0aG9yLmlkKSB7XHJcbiAgICAgIChkYXRhLmF1dGhvciBhcyBhbnkpLmlkID0gZGF0YS51c2VyX2lkO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICAvLyBDYWNoZSB0aGUgYXV0aG9yXHJcbiAgICBpZiAoZGF0YS5hdXRob3IpIHtcclxuICAgICAgY29uc3QgdXNlciA9IG5ldyBVc2VyKGRhdGEuYXV0aG9yKTtcclxuICAgICAgdGhpcy51c2Vycy5zZXQodXNlci5pZCwgdXNlcik7XHJcbiAgICAgIC8vIEFsc28gY2FjaGUgaW4gUkVTVCBmb3IgbWVudGlvbiByZXNvbHV0aW9uXHJcbiAgICAgIHRoaXMucmVzdC5jYWNoZVVzZXIoZGF0YS5hdXRob3IpO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICBjb25zdCBtZXNzYWdlID0gbmV3IE1lc3NhZ2UodGhpcywgZGF0YSk7XHJcblxyXG4gICAgLy8gTWFyayBtZXNzYWdlIGFzIGZyb20gYm90IGlmIGF1dGhvciBJRCBtYXRjaGVzIHRoZSBib3QncyBvd24gdXNlciBJRFxyXG4gICAgaWYgKHRoaXMudXNlciAmJiBTdHJpbmcobWVzc2FnZS5hdXRob3IuaWQpID09PSBTdHJpbmcodGhpcy51c2VyLmlkKSkge1xyXG4gICAgICAobWVzc2FnZS5hdXRob3IgYXMgYW55KS5ib3QgPSB0cnVlO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFJlc29sdmUgZ3VpbGQgbWVtYmVyIGlmIGluIGEgZ3VpbGRcclxuICAgIGlmIChtZXNzYWdlLmd1aWxkSWQpIHtcclxuICAgICAgY29uc3QgZ3VpbGQgPSB0aGlzLmd1aWxkcy5nZXQobWVzc2FnZS5ndWlsZElkKTtcclxuICAgICAgY29uc3QgbWVtYmVyRGF0YSA9IChkYXRhIGFzIGFueSkubWVtYmVyO1xyXG4gICAgICBpZiAobWVtYmVyRGF0YSAmJiBndWlsZCkge1xyXG4gICAgICAgIC8vIEdhdGV3YXkgc2VudCBtZW1iZXIgZGF0YSB3aXRoIHRoZSBtZXNzYWdlIOKAlCBjYWNoZSBpdFxyXG4gICAgICAgIG1lbWJlckRhdGEudXNlciA9IGRhdGEuYXV0aG9yO1xyXG4gICAgICAgIGNvbnN0IG1lbWJlciA9IGd1aWxkLl9hZGRNZW1iZXIobWVtYmVyRGF0YSk7XHJcbiAgICAgICAgbWVzc2FnZS5tZW1iZXIgPSBtZW1iZXI7XHJcbiAgICAgIH0gZWxzZSBpZiAobWVtYmVyRGF0YSkge1xyXG4gICAgICAgIC8vIE5vIGd1aWxkIGluIGNhY2hlIGJ1dCBtZW1iZXIgZGF0YSBleGlzdHNcclxuICAgICAgICBtZW1iZXJEYXRhLnVzZXIgPSBkYXRhLmF1dGhvcjtcclxuICAgICAgICBjb25zdCByZXNvbHZlZEd1aWxkID0geyBpZDogbWVzc2FnZS5ndWlsZElkLCBvd25lcklkOiBudWxsIH0gYXMgYW55O1xyXG4gICAgICAgIG1lc3NhZ2UubWVtYmVyID0gbmV3IChyZXF1aXJlKCcuL3N0cnVjdHVyZXMvR3VpbGRNZW1iZXInKS5HdWlsZE1lbWJlcikodGhpcywgcmVzb2x2ZWRHdWlsZCwgbWVtYmVyRGF0YSk7XHJcbiAgICAgIH0gZWxzZSBpZiAoZ3VpbGQpIHtcclxuICAgICAgICAvLyBUcnkgY2FjaGVcclxuICAgICAgICBjb25zdCBjYWNoZWQgPSBndWlsZC5tZW1iZXJzPy5nZXQoU3RyaW5nKG1lc3NhZ2UuYXV0aG9yLmlkKSk7XHJcbiAgICAgICAgaWYgKGNhY2hlZD8ucGVybWlzc2lvbnM/Lmhhcykge1xyXG4gICAgICAgICAgbWVzc2FnZS5tZW1iZXIgPSBjYWNoZWQ7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5lbWl0KCdtZXNzYWdlQ3JlYXRlJywgbWVzc2FnZSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIYW5kbGUgSW50ZXJhY3Rpb24gQ3JlYXRlIGV2ZW50XHJcbiAgICovXHJcbiAgcHJpdmF0ZSBoYW5kbGVJbnRlcmFjdGlvbkNyZWF0ZShkYXRhOiBBUElJbnRlcmFjdGlvbik6IHZvaWQge1xyXG4gICAgY29uc29sZS5sb2coJ1tERUJVR10gaGFuZGxlSW50ZXJhY3Rpb25DcmVhdGUgY2FsbGVkIHdpdGg6JywgSlNPTi5zdHJpbmdpZnkoZGF0YSwgbnVsbCwgMikpO1xyXG4gICAgXHJcbiAgICAvLyBDYWNoZSB0aGUgdXNlclxyXG4gICAgY29uc3QgdXNlckRhdGEgPSBkYXRhLm1lbWJlcj8udXNlciB8fCBkYXRhLnVzZXI7XHJcbiAgICBpZiAodXNlckRhdGEpIHtcclxuICAgICAgY29uc3QgdXNlciA9IG5ldyBVc2VyKHVzZXJEYXRhKTtcclxuICAgICAgdGhpcy51c2Vycy5zZXQodXNlci5pZCwgdXNlcik7XHJcbiAgICAgIHRoaXMucmVzdC5jYWNoZVVzZXIodXNlckRhdGEpO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICBjb25zdCBpbnRlcmFjdGlvbiA9IGNyZWF0ZUludGVyYWN0aW9uKHRoaXMsIGRhdGEpO1xyXG4gICAgY29uc29sZS5sb2coJ1tERUJVR10gQ3JlYXRlZCBpbnRlcmFjdGlvbiB0eXBlOicsIGludGVyYWN0aW9uLmNvbnN0cnVjdG9yLm5hbWUsICdjdXN0b21JZDonLCAoaW50ZXJhY3Rpb24gYXMgYW55KS5jdXN0b21JZCk7XHJcbiAgICB0aGlzLmVtaXQoJ2ludGVyYWN0aW9uQ3JlYXRlJywgaW50ZXJhY3Rpb24pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSGFuZGxlIFZvaWNlIFN0YXRlIFVwZGF0ZSBldmVudFxyXG4gICAqL1xyXG4gIHByaXZhdGUgaGFuZGxlVm9pY2VTdGF0ZVVwZGF0ZShkYXRhOiBhbnkpOiB2b2lkIHtcclxuICAgIGNvbnN0IGd1aWxkSWQgPSBkYXRhLmd1aWxkX2lkO1xyXG4gICAgXHJcbiAgICAvLyBGb3J3YXJkIHRvIHZvaWNlIGFkYXB0ZXIgaWYgZXhpc3RzXHJcbiAgICBjb25zdCBoYW5kbGVyID0gdGhpcy52b2ljZVN0YXRlSGFuZGxlcnMuZ2V0KGd1aWxkSWQpO1xyXG4gICAgaWYgKGhhbmRsZXIpIHtcclxuICAgICAgaGFuZGxlcihkYXRhKTtcclxuICAgIH1cclxuICAgIFxyXG4gICAgdGhpcy5lbWl0KCd2b2ljZVN0YXRlVXBkYXRlJywgZGF0YSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIYW5kbGUgVm9pY2UgU2VydmVyIFVwZGF0ZSBldmVudFxyXG4gICAqL1xyXG4gIHByaXZhdGUgaGFuZGxlVm9pY2VTZXJ2ZXJVcGRhdGUoZGF0YTogQVBJVm9pY2VTZXJ2ZXJVcGRhdGUpOiB2b2lkIHtcclxuICAgIGNvbnN0IGd1aWxkSWQgPSBkYXRhLmd1aWxkX2lkO1xyXG4gICAgXHJcbiAgICAvLyBGb3J3YXJkIHRvIHZvaWNlIGFkYXB0ZXIgaWYgZXhpc3RzXHJcbiAgICBjb25zdCBoYW5kbGVyID0gdGhpcy52b2ljZVNlcnZlckhhbmRsZXJzLmdldChndWlsZElkKTtcclxuICAgIGlmIChoYW5kbGVyKSB7XHJcbiAgICAgIGhhbmRsZXIoe1xyXG4gICAgICAgIHRva2VuOiBkYXRhLnRva2VuLFxyXG4gICAgICAgIGVuZHBvaW50OiBkYXRhLmVuZHBvaW50LFxyXG4gICAgICAgIHJvb206IGRhdGEucm9vbVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuICAgIFxyXG4gICAgdGhpcy5lbWl0KCd2b2ljZVNlcnZlclVwZGF0ZScsIGRhdGEpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU2VuZCBJZGVudGlmeSBwYXlsb2FkXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBpZGVudGlmeSgpOiB2b2lkIHtcclxuICAgIGNvbnN0IHBheWxvYWQ6IEdhdGV3YXlQYXlsb2FkID0ge1xyXG4gICAgICBvcDogR2F0ZXdheU9wY29kZXMuSWRlbnRpZnksXHJcbiAgICAgIGQ6IHtcclxuICAgICAgICB0b2tlbjogYEJvdCAke3RoaXMudG9rZW59YCxcclxuICAgICAgICBpbnRlbnRzOiB0aGlzLmdldEludGVudHNWYWx1ZSgpLFxyXG4gICAgICAgIHNoYXJkOiB0aGlzLm9wdGlvbnMuc2hhcmRzIHx8IFswLCAxXVxyXG4gICAgICB9XHJcbiAgICB9O1xyXG4gICAgXHJcbiAgICB0aGlzLnNlbmQocGF5bG9hZCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTdGFydCBoZWFydGJlYXRcclxuICAgKi9cclxuICBwcml2YXRlIHN0YXJ0SGVhcnRiZWF0KGludGVydmFsOiBudW1iZXIpOiB2b2lkIHtcclxuICAgIHRoaXMuaGVhcnRiZWF0SW50ZXJ2YWwgPSBzZXRJbnRlcnZhbCgoKSA9PiB7XHJcbiAgICAgIHRoaXMuc2VuZCh7XHJcbiAgICAgICAgb3A6IEdhdGV3YXlPcGNvZGVzLkhlYXJ0YmVhdCxcclxuICAgICAgICBkOiB0aGlzLnNlcXVlbmNlXHJcbiAgICAgIH0pO1xyXG4gICAgfSwgaW50ZXJ2YWwpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU2VuZCBwYXlsb2FkIHRvIGdhdGV3YXlcclxuICAgKi9cclxuICBwcml2YXRlIHNlbmQocGF5bG9hZDogR2F0ZXdheVBheWxvYWQpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLndzPy5yZWFkeVN0YXRlID09PSBXZWJTb2NrZXQuT1BFTikge1xyXG4gICAgICB0aGlzLndzLnNlbmQoSlNPTi5zdHJpbmdpZnkocGF5bG9hZCkpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2xlYW51cCBvbiBkaXNjb25uZWN0XHJcbiAgICovXHJcbiAgcHJpdmF0ZSBjbGVhbnVwKCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuaGVhcnRiZWF0SW50ZXJ2YWwpIHtcclxuICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLmhlYXJ0YmVhdEludGVydmFsKTtcclxuICAgICAgdGhpcy5oZWFydGJlYXRJbnRlcnZhbCA9IG51bGw7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBEZXN0cm95IHRoZSBjbGllbnRcclxuICAgKi9cclxuICBkZXN0cm95KCk6IHZvaWQge1xyXG4gICAgdGhpcy5fbG9naW5TdGF0ZSA9ICdpZGxlJztcclxuICAgIHRoaXMuX3JlY29ubmVjdEF0dGVtcHRzID0gdGhpcy5fbWF4UmVjb25uZWN0QXR0ZW1wdHMgKyAxOyAvLyBQcmV2ZW50IHJlY29ubmVjdFxyXG4gICAgdGhpcy5jbGVhbnVwKCk7XHJcbiAgICB0aGlzLndzPy5jbG9zZSgxMDAwKTtcclxuICAgIHRoaXMud3MgPSBudWxsO1xyXG4gICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoKTtcclxuICB9XHJcbn1cclxuXHJcbi8vIFJlLWV4cG9ydCBmb3IgY29udmVuaWVuY2VcclxuZXhwb3J0IHsgR2F0ZXdheUludGVudEJpdHMgfTtcclxuIl19
|