@modelprofile.com/browser-runtime 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/.smartconfig.json +34 -0
  2. package/changelog.md +11 -0
  3. package/dist_ts/00_commitinfo_data.d.ts +8 -0
  4. package/dist_ts/00_commitinfo_data.js +9 -0
  5. package/dist_ts/actions.d.ts +3 -0
  6. package/dist_ts/actions.js +215 -0
  7. package/dist_ts/classes.artifactstore.d.ts +38 -0
  8. package/dist_ts/classes.artifactstore.js +344 -0
  9. package/dist_ts/classes.egressproxy.d.ts +67 -0
  10. package/dist_ts/classes.egressproxy.js +830 -0
  11. package/dist_ts/classes.flexprovider.d.ts +9 -0
  12. package/dist_ts/classes.flexprovider.js +117 -0
  13. package/dist_ts/classes.framed.d.ts +52 -0
  14. package/dist_ts/classes.framed.js +557 -0
  15. package/dist_ts/classes.runtime.d.ts +202 -0
  16. package/dist_ts/classes.runtime.js +1667 -0
  17. package/dist_ts/confinement.d.ts +2 -0
  18. package/dist_ts/confinement.js +63 -0
  19. package/dist_ts/errors.d.ts +7 -0
  20. package/dist_ts/errors.js +40 -0
  21. package/dist_ts/index.d.ts +11 -0
  22. package/dist_ts/index.js +9 -0
  23. package/dist_ts/interfaces.d.ts +287 -0
  24. package/dist_ts/interfaces.js +2 -0
  25. package/dist_ts/internal.testing.d.ts +9 -0
  26. package/dist_ts/internal.testing.js +2 -0
  27. package/dist_ts/mcp.d.ts +4 -0
  28. package/dist_ts/mcp.js +196 -0
  29. package/dist_ts/plugins.d.ts +20 -0
  30. package/dist_ts/plugins.js +24 -0
  31. package/dist_ts/utils.d.ts +25 -0
  32. package/dist_ts/utils.js +143 -0
  33. package/license.md +21 -0
  34. package/package.json +59 -0
  35. package/readme.hints.md +35 -0
  36. package/readme.md +181 -0
  37. package/ts/00_commitinfo_data.ts +8 -0
  38. package/ts/actions.ts +241 -0
  39. package/ts/classes.artifactstore.ts +432 -0
  40. package/ts/classes.egressproxy.ts +1005 -0
  41. package/ts/classes.flexprovider.ts +134 -0
  42. package/ts/classes.framed.ts +649 -0
  43. package/ts/classes.runtime.ts +2135 -0
  44. package/ts/confinement.ts +90 -0
  45. package/ts/errors.ts +63 -0
  46. package/ts/index.ts +52 -0
  47. package/ts/interfaces.ts +375 -0
  48. package/ts/internal.testing.ts +18 -0
  49. package/ts/mcp.ts +230 -0
  50. package/ts/plugins.ts +28 -0
  51. package/ts/utils.ts +188 -0
@@ -0,0 +1,830 @@
1
+ import * as plugins from './plugins.js';
2
+ import { BrowserRuntimeError } from './errors.js';
3
+ import { randomId, validateBoundedString, validateInteger, validateOptionalInteger, waitBounded, } from './utils.js';
4
+ const hopByHopHeaders = new Set([
5
+ 'connection',
6
+ 'keep-alive',
7
+ 'proxy-authenticate',
8
+ 'proxy-authorization',
9
+ 'proxy-connection',
10
+ 'te',
11
+ 'trailer',
12
+ 'transfer-encoding',
13
+ 'upgrade',
14
+ ]);
15
+ export class BrowserEgressProxy {
16
+ projectId;
17
+ allowedPorts;
18
+ maxConnections;
19
+ maxActiveRequests;
20
+ maxHeaderBytes;
21
+ connectTimeoutMs;
22
+ idleTimeoutMs;
23
+ tunnelLifetimeMs;
24
+ requestTimeoutMs;
25
+ maxRequestBytes;
26
+ maxResponseBytes;
27
+ maxTunnelBytes;
28
+ resolver;
29
+ connector;
30
+ username = randomId(18);
31
+ password = randomId(32);
32
+ expectedAuthorization;
33
+ clientSockets = new Set();
34
+ upstreamSockets = new Set();
35
+ activeOperations = new Set();
36
+ server;
37
+ listenPort;
38
+ startPromise;
39
+ stopPromise;
40
+ lifecycleState = 'stopped';
41
+ lifecycleController = new AbortController();
42
+ ordinaryRequests = 0;
43
+ upgradeRequests = 0;
44
+ connectRequests = 0;
45
+ rejectedRequests = 0;
46
+ constructor(options) {
47
+ this.projectId = validateBoundedString(options.projectId, 'projectId', 1, 128);
48
+ const ports = options.allowedPorts ?? [80, 443];
49
+ if (!Array.isArray(ports) || ports.length < 1 || ports.length > 32) {
50
+ throw new BrowserRuntimeError('INVALID_INPUT', 'allowedPorts must contain 1 to 32 ports');
51
+ }
52
+ this.allowedPorts = new Set(ports.map((port) => validateInteger(port, 'allowedPort', 1, 65535)));
53
+ if (this.allowedPorts.size !== ports.length) {
54
+ throw new BrowserRuntimeError('INVALID_INPUT', 'allowedPorts must not contain duplicates');
55
+ }
56
+ this.maxConnections = validateOptionalInteger(options.maxConnections, 'maxConnections', 1, 1024, 128);
57
+ this.maxActiveRequests = validateOptionalInteger(options.maxActiveRequests, 'maxActiveRequests', 1, 1024, this.maxConnections);
58
+ this.maxHeaderBytes = validateOptionalInteger(options.maxHeaderBytes, 'maxHeaderBytes', 1024, 128 * 1024, 32 * 1024);
59
+ this.connectTimeoutMs = validateOptionalInteger(options.connectTimeoutMs, 'connectTimeoutMs', 100, 60_000, 10_000);
60
+ this.idleTimeoutMs = validateOptionalInteger(options.idleTimeoutMs, 'idleTimeoutMs', 1000, 10 * 60_000, 60_000);
61
+ this.tunnelLifetimeMs = validateOptionalInteger(options.tunnelLifetimeMs, 'tunnelLifetimeMs', 1000, 60 * 60_000, 10 * 60_000);
62
+ this.requestTimeoutMs = validateOptionalInteger(options.requestTimeoutMs, 'requestTimeoutMs', 1000, 60 * 60_000, Math.min(this.tunnelLifetimeMs, 5 * 60_000));
63
+ this.maxRequestBytes = validateOptionalInteger(options.maxRequestBytes, 'maxRequestBytes', 1024, 256 * 1024 * 1024, 16 * 1024 * 1024);
64
+ this.maxResponseBytes = validateOptionalInteger(options.maxResponseBytes, 'maxResponseBytes', 1024, 1024 * 1024 * 1024, 64 * 1024 * 1024);
65
+ this.maxTunnelBytes = validateOptionalInteger(options.maxTunnelBytes, 'maxTunnelBytes', 1024, 2 * 1024 * 1024 * 1024, 256 * 1024 * 1024);
66
+ this.resolver = options.resolver ?? (async (hostname, lookupOptions) => (plugins.dns.promises.lookup(hostname, {
67
+ all: lookupOptions.all,
68
+ verbatim: lookupOptions.verbatim,
69
+ })));
70
+ this.connector = options.connector ?? ((connectionOptions) => plugins.net.connect({
71
+ host: connectionOptions.address,
72
+ family: connectionOptions.family,
73
+ port: connectionOptions.port,
74
+ }));
75
+ this.expectedAuthorization = plugins.Buffer.from(`Basic ${plugins.Buffer.from(`${this.username}:${this.password}`, 'utf8').toString('base64')}`, 'utf8');
76
+ }
77
+ get credentials() {
78
+ return { username: this.username, password: this.password };
79
+ }
80
+ get port() {
81
+ if (this.listenPort === undefined)
82
+ throw new BrowserRuntimeError('NOT_RUNNING');
83
+ return this.listenPort;
84
+ }
85
+ get project() {
86
+ return this.projectId;
87
+ }
88
+ get allowedTargetPorts() {
89
+ return [...this.allowedPorts];
90
+ }
91
+ getStats() {
92
+ return {
93
+ ordinaryRequests: this.ordinaryRequests,
94
+ upgradeRequests: this.upgradeRequests,
95
+ connectRequests: this.connectRequests,
96
+ rejectedRequests: this.rejectedRequests,
97
+ activeConnections: this.clientSockets.size,
98
+ };
99
+ }
100
+ start() {
101
+ if (this.lifecycleState === 'running')
102
+ return Promise.resolve();
103
+ if (this.startPromise)
104
+ return this.startPromise;
105
+ if (this.stopPromise)
106
+ return this.stopPromise.then(() => this.start());
107
+ this.stopPromise = undefined;
108
+ this.lifecycleState = 'starting';
109
+ this.lifecycleController = new AbortController();
110
+ this.startPromise = this.startInternal().then(() => {
111
+ if (this.lifecycleState !== 'starting')
112
+ throw new BrowserRuntimeError('ABORTED');
113
+ this.lifecycleState = 'running';
114
+ }).catch((error) => {
115
+ if (this.lifecycleState === 'starting')
116
+ this.lifecycleState = 'stopped';
117
+ throw error;
118
+ }).finally(() => {
119
+ this.startPromise = undefined;
120
+ });
121
+ return this.startPromise;
122
+ }
123
+ stop() {
124
+ if (this.stopPromise)
125
+ return this.stopPromise;
126
+ if (this.lifecycleState === 'stopped' && !this.server && !this.startPromise) {
127
+ return Promise.resolve();
128
+ }
129
+ this.lifecycleState = 'stopping';
130
+ this.lifecycleController.abort(new BrowserRuntimeError('ABORTED'));
131
+ const startup = this.startPromise;
132
+ this.stopPromise = (async () => {
133
+ await startup?.catch(() => undefined);
134
+ await this.stopInternal();
135
+ this.lifecycleState = 'stopped';
136
+ })().finally(() => {
137
+ this.stopPromise = undefined;
138
+ });
139
+ return this.stopPromise;
140
+ }
141
+ async startInternal() {
142
+ const server = plugins.http.createServer({ maxHeaderSize: this.maxHeaderBytes }, (request, response) => {
143
+ if (!this.admit()) {
144
+ this.rejectedRequests += 1;
145
+ this.sendSafeFailure(response, 503);
146
+ return;
147
+ }
148
+ this.track(this.handleHttpRequest(request, response));
149
+ });
150
+ this.server = server;
151
+ server.on('connection', (socket) => {
152
+ if (this.clientSockets.size >= this.maxConnections) {
153
+ socket.destroy();
154
+ return;
155
+ }
156
+ this.clientSockets.add(socket);
157
+ socket.on('error', () => socket.destroy());
158
+ socket.setTimeout(this.idleTimeoutMs, () => socket.destroy());
159
+ socket.once('close', () => this.clientSockets.delete(socket));
160
+ });
161
+ server.on('connect', (request, socket, head) => {
162
+ if (!this.admit()) {
163
+ this.rejectedRequests += 1;
164
+ this.rejectRawSocket(socket, 502, false);
165
+ return;
166
+ }
167
+ this.track(this.handleConnect(request, socket, head));
168
+ });
169
+ server.on('upgrade', (request, socket, head) => {
170
+ if (!this.admit()) {
171
+ this.rejectedRequests += 1;
172
+ this.rejectRawSocket(socket, 502, false);
173
+ return;
174
+ }
175
+ this.track(this.handleUpgrade(request, socket, head));
176
+ });
177
+ server.on('clientError', (_error, socket) => {
178
+ this.rejectedRequests += 1;
179
+ if (socket.writable) {
180
+ socket.end('HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n');
181
+ }
182
+ else {
183
+ socket.destroy();
184
+ }
185
+ });
186
+ server.on('error', () => {
187
+ if (this.lifecycleState === 'running')
188
+ void this.stop().catch(() => undefined);
189
+ });
190
+ server.headersTimeout = this.requestTimeoutMs;
191
+ server.requestTimeout = this.requestTimeoutMs;
192
+ server.maxRequestsPerSocket = this.maxActiveRequests;
193
+ await new Promise((resolve, reject) => {
194
+ const onError = (error) => {
195
+ server.off('listening', onListening);
196
+ reject(error);
197
+ };
198
+ const onListening = () => {
199
+ server.off('error', onError);
200
+ resolve();
201
+ };
202
+ server.once('error', onError);
203
+ server.once('listening', onListening);
204
+ server.listen(0, '127.0.0.1');
205
+ });
206
+ const address = server.address();
207
+ if (!address || typeof address === 'string' || address.address !== '127.0.0.1') {
208
+ await this.stopInternal();
209
+ throw new BrowserRuntimeError('FENCED', 'proxy did not bind to IPv4 loopback');
210
+ }
211
+ this.listenPort = address.port;
212
+ }
213
+ async stopInternal() {
214
+ const server = this.server;
215
+ this.listenPort = undefined;
216
+ for (const socket of this.clientSockets)
217
+ socket.destroy();
218
+ for (const socket of this.upstreamSockets)
219
+ socket.destroy();
220
+ if (server) {
221
+ await new Promise((resolve, reject) => {
222
+ server.close((error) => {
223
+ if (error && error.code !== 'ERR_SERVER_NOT_RUNNING') {
224
+ reject(error);
225
+ }
226
+ else {
227
+ resolve();
228
+ }
229
+ });
230
+ });
231
+ }
232
+ const settled = await waitBounded(Promise.allSettled([...this.activeOperations]).then(() => undefined), this.requestTimeoutMs);
233
+ if (!settled.settled)
234
+ throw new BrowserRuntimeError('TIMEOUT');
235
+ this.server = undefined;
236
+ this.startPromise = undefined;
237
+ }
238
+ track(operation) {
239
+ const observed = operation.catch(() => undefined).finally(() => {
240
+ this.activeOperations.delete(observed);
241
+ });
242
+ this.activeOperations.add(observed);
243
+ }
244
+ admit() {
245
+ return this.lifecycleState !== 'stopping'
246
+ && this.activeOperations.size < this.maxActiveRequests;
247
+ }
248
+ async handleHttpRequest(request, response) {
249
+ this.ordinaryRequests += 1;
250
+ if (!this.authorize(request)) {
251
+ this.sendProxyAuthenticationRequired(response);
252
+ return;
253
+ }
254
+ request.pause();
255
+ let upstreamRequest;
256
+ let upstreamSocket;
257
+ let upstreamResponse;
258
+ let agent;
259
+ const operation = this.createOperationSignal();
260
+ const abort = () => operation.controller.abort(new BrowserRuntimeError('ABORTED'));
261
+ request.once('aborted', abort);
262
+ request.socket.once('close', abort);
263
+ response.once('close', () => {
264
+ if (!response.writableFinished)
265
+ abort();
266
+ });
267
+ try {
268
+ const contentLength = Number(request.headers['content-length']);
269
+ if (Number.isFinite(contentLength)
270
+ && contentLength > this.maxRequestBytes)
271
+ throw new BrowserRuntimeError('QUOTA_EXCEEDED');
272
+ const target = await this.resolveAbsoluteTarget(request.url, false, operation.signal);
273
+ operation.signal.throwIfAborted();
274
+ upstreamSocket = this.openUpstream(target, operation.signal);
275
+ await this.waitForConnect(upstreamSocket, operation.signal);
276
+ const headers = this.sanitizeHeaders(request.headers);
277
+ headers.host = target.hostHeader;
278
+ agent = new plugins.http.Agent({ keepAlive: false });
279
+ agent.createConnection = () => upstreamSocket;
280
+ upstreamRequest = plugins.http.request({
281
+ method: request.method,
282
+ host: target.address,
283
+ family: target.family,
284
+ port: target.port,
285
+ path: target.path,
286
+ headers,
287
+ agent,
288
+ maxHeaderSize: this.maxHeaderBytes,
289
+ });
290
+ const onAbort = () => {
291
+ upstreamRequest?.destroy(operation.signal.reason);
292
+ upstreamResponse?.destroy(operation.signal.reason);
293
+ upstreamSocket?.destroy(operation.signal.reason);
294
+ };
295
+ operation.signal.addEventListener('abort', onAbort, { once: true });
296
+ let requestBytes = 0;
297
+ request.on('data', (chunk) => {
298
+ requestBytes += chunk.byteLength;
299
+ if (requestBytes > this.maxRequestBytes) {
300
+ operation.controller.abort(new BrowserRuntimeError('QUOTA_EXCEEDED'));
301
+ }
302
+ });
303
+ const upstreamResponsePromise = new Promise((resolve, reject) => {
304
+ upstreamRequest.once('response', resolve);
305
+ upstreamRequest.once('error', reject);
306
+ });
307
+ request.pipe(upstreamRequest);
308
+ upstreamResponse = await this.raceAbort(upstreamResponsePromise, operation.signal);
309
+ const responseLength = Number(upstreamResponse.headers['content-length']);
310
+ if (Number.isFinite(responseLength) && responseLength > this.maxResponseBytes) {
311
+ throw new BrowserRuntimeError('QUOTA_EXCEEDED');
312
+ }
313
+ const responseHeaders = this.sanitizeHeaders(upstreamResponse.headers);
314
+ response.writeHead(upstreamResponse.statusCode ?? 502, responseHeaders);
315
+ let responseBytes = 0;
316
+ upstreamResponse.on('data', (chunk) => {
317
+ responseBytes += chunk.byteLength;
318
+ if (responseBytes > this.maxResponseBytes) {
319
+ operation.controller.abort(new BrowserRuntimeError('QUOTA_EXCEEDED'));
320
+ }
321
+ });
322
+ upstreamResponse.once('aborted', abort);
323
+ const responseFailure = new Promise((_resolve, reject) => {
324
+ upstreamResponse.once('error', reject);
325
+ });
326
+ upstreamResponse.pipe(response);
327
+ await Promise.race([this.waitForResponseCompletion(response), responseFailure]);
328
+ operation.signal.throwIfAborted();
329
+ }
330
+ catch {
331
+ this.rejectedRequests += 1;
332
+ upstreamRequest?.destroy();
333
+ upstreamSocket?.destroy();
334
+ if (!response.headersSent)
335
+ this.sendSafeFailure(response, 502);
336
+ else
337
+ response.destroy();
338
+ }
339
+ finally {
340
+ operation.dispose();
341
+ request.off('aborted', abort);
342
+ request.socket.off('close', abort);
343
+ upstreamResponse?.destroy();
344
+ upstreamRequest?.destroy();
345
+ upstreamSocket?.destroy();
346
+ agent?.destroy();
347
+ }
348
+ }
349
+ async handleConnect(request, clientSocket, head) {
350
+ this.connectRequests += 1;
351
+ if (!this.authorize(request)) {
352
+ this.rejectRawSocket(clientSocket, 407, true);
353
+ return;
354
+ }
355
+ clientSocket.pause();
356
+ const operation = this.createOperationSignal();
357
+ const abort = () => operation.controller.abort(new BrowserRuntimeError('ABORTED'));
358
+ clientSocket.once('close', abort);
359
+ let upstream;
360
+ try {
361
+ if (head.byteLength > this.maxTunnelBytes)
362
+ throw new BrowserRuntimeError('QUOTA_EXCEEDED');
363
+ const target = await this.resolveAuthority(request.url, operation.signal);
364
+ upstream = this.openUpstream(target, operation.signal);
365
+ await this.waitForConnect(upstream, operation.signal);
366
+ operation.signal.throwIfAborted();
367
+ clientSocket.write('HTTP/1.1 200 Connection Established\r\n\r\n');
368
+ await this.pipeTunnel(clientSocket, upstream, {
369
+ toUpstream: head,
370
+ toClient: plugins.Buffer.alloc(0),
371
+ }, operation.signal);
372
+ }
373
+ catch {
374
+ this.rejectedRequests += 1;
375
+ upstream?.destroy();
376
+ this.rejectRawSocket(clientSocket, 502, false);
377
+ }
378
+ finally {
379
+ operation.dispose();
380
+ clientSocket.off('close', abort);
381
+ }
382
+ }
383
+ async handleUpgrade(request, clientSocket, head) {
384
+ this.upgradeRequests += 1;
385
+ if (!this.authorize(request)) {
386
+ this.rejectRawSocket(clientSocket, 407, true);
387
+ return;
388
+ }
389
+ clientSocket.pause();
390
+ const operation = this.createOperationSignal();
391
+ const abort = () => operation.controller.abort(new BrowserRuntimeError('ABORTED'));
392
+ clientSocket.once('close', abort);
393
+ let upstream;
394
+ try {
395
+ if (request.method !== 'GET'
396
+ || String(request.headers.upgrade).toLowerCase() !== 'websocket'
397
+ || !String(request.headers.connection).toLowerCase().split(',')
398
+ .map((value) => value.trim()).includes('upgrade'))
399
+ throw new BrowserRuntimeError('EGRESS_DENIED');
400
+ const webSocketKey = validateBoundedString(request.headers['sec-websocket-key'], 'sec-websocket-key', 20, 32);
401
+ if (request.headers['sec-websocket-version'] !== '13'
402
+ || !/^[A-Za-z0-9+/]{22}==$/.test(webSocketKey)
403
+ || plugins.Buffer.from(webSocketKey, 'base64').toString('base64') !== webSocketKey)
404
+ throw new BrowserRuntimeError('EGRESS_DENIED');
405
+ const expectedAccept = plugins.crypto
406
+ .createHash('sha1')
407
+ .update(`${webSocketKey}258EAFA5-E914-47DA-95CA-C5AB0DC85B11`, 'ascii')
408
+ .digest('base64');
409
+ if (head.byteLength > this.maxTunnelBytes)
410
+ throw new BrowserRuntimeError('QUOTA_EXCEEDED');
411
+ const target = await this.resolveAbsoluteTarget(request.url, true, operation.signal);
412
+ upstream = this.openUpstream(target, operation.signal);
413
+ await this.waitForConnect(upstream, operation.signal);
414
+ const headers = this.sanitizeHeaders(request.headers);
415
+ headers.host = target.hostHeader;
416
+ headers.connection = 'Upgrade';
417
+ headers.upgrade = 'websocket';
418
+ const headerLines = Object.entries(headers).flatMap(([name, value]) => (Array.isArray(value)
419
+ ? value.map((entry) => `${name}: ${entry}`)
420
+ : value === undefined
421
+ ? []
422
+ : [`${name}: ${value}`]));
423
+ upstream.write(`${request.method ?? 'GET'} ${target.path} HTTP/1.1\r\n${headerLines.join('\r\n')}\r\n\r\n`);
424
+ const handshake = await this.readWebSocketHandshake(upstream, operation.signal, expectedAccept);
425
+ clientSocket.write(handshake.header);
426
+ await this.pipeTunnel(clientSocket, upstream, { toUpstream: head, toClient: handshake.remaining }, operation.signal);
427
+ }
428
+ catch {
429
+ this.rejectedRequests += 1;
430
+ upstream?.destroy();
431
+ this.rejectRawSocket(clientSocket, 502, false);
432
+ }
433
+ finally {
434
+ operation.dispose();
435
+ clientSocket.off('close', abort);
436
+ }
437
+ }
438
+ authorize(request) {
439
+ const value = request.headers['proxy-authorization'];
440
+ if (typeof value !== 'string') {
441
+ this.rejectedRequests += 1;
442
+ return false;
443
+ }
444
+ const supplied = plugins.Buffer.from(value, 'utf8');
445
+ const accepted = supplied.byteLength === this.expectedAuthorization.byteLength
446
+ && plugins.crypto.timingSafeEqual(supplied, this.expectedAuthorization);
447
+ if (!accepted)
448
+ this.rejectedRequests += 1;
449
+ return accepted;
450
+ }
451
+ sendProxyAuthenticationRequired(response) {
452
+ response.writeHead(407, {
453
+ connection: 'close',
454
+ 'content-length': '0',
455
+ 'proxy-authenticate': 'Basic realm="browser-runtime"',
456
+ });
457
+ response.end();
458
+ }
459
+ sendSafeFailure(response, status) {
460
+ response.writeHead(status, { connection: 'close', 'content-length': '0' });
461
+ response.end();
462
+ }
463
+ rejectRawSocket(socket, status, authenticate) {
464
+ if (!socket.writable) {
465
+ socket.destroy();
466
+ return;
467
+ }
468
+ const statusText = status === 407 ? 'Proxy Authentication Required' : 'Bad Gateway';
469
+ const challenge = authenticate
470
+ ? 'Proxy-Authenticate: Basic realm="browser-runtime"\r\n'
471
+ : '';
472
+ socket.end(`HTTP/1.1 ${status} ${statusText}\r\n${challenge}Connection: close\r\nContent-Length: 0\r\n\r\n`);
473
+ }
474
+ sanitizeHeaders(headers) {
475
+ const connectionTokens = new Set((typeof headers.connection === 'string' ? headers.connection : '')
476
+ .split(',')
477
+ .map((token) => token.trim().toLowerCase())
478
+ .filter(Boolean));
479
+ const result = {};
480
+ for (const [name, value] of Object.entries(headers)) {
481
+ const normalizedName = name.toLowerCase();
482
+ if (hopByHopHeaders.has(normalizedName) || connectionTokens.has(normalizedName))
483
+ continue;
484
+ result[normalizedName] = value;
485
+ }
486
+ return result;
487
+ }
488
+ async resolveAbsoluteTarget(rawUrl, upgrade, signal) {
489
+ if (!rawUrl || plugins.Buffer.byteLength(rawUrl, 'utf8') > 8192) {
490
+ throw new BrowserRuntimeError('EGRESS_DENIED');
491
+ }
492
+ let parsed;
493
+ try {
494
+ parsed = new URL(rawUrl);
495
+ }
496
+ catch {
497
+ throw new BrowserRuntimeError('EGRESS_DENIED');
498
+ }
499
+ const allowedProtocols = upgrade ? new Set(['http:', 'ws:']) : new Set(['http:']);
500
+ if (!allowedProtocols.has(parsed.protocol)
501
+ || parsed.username
502
+ || parsed.password
503
+ || parsed.hash) {
504
+ throw new BrowserRuntimeError('EGRESS_DENIED');
505
+ }
506
+ const hostname = this.canonicalizeHostname(parsed.hostname);
507
+ const port = parsed.port
508
+ ? validateInteger(Number(parsed.port), 'target port', 1, 65535)
509
+ : 80;
510
+ const resolved = await this.resolveHost(hostname, port, signal);
511
+ return {
512
+ ...resolved,
513
+ path: `${parsed.pathname || '/'}${parsed.search}`,
514
+ hostHeader: parsed.host,
515
+ };
516
+ }
517
+ async resolveAuthority(rawAuthority, signal) {
518
+ if (!rawAuthority
519
+ || rawAuthority.length > 512
520
+ || /[\/?#@]/.test(rawAuthority)) {
521
+ throw new BrowserRuntimeError('EGRESS_DENIED');
522
+ }
523
+ let hostnameValue;
524
+ let portValue;
525
+ if (rawAuthority.startsWith('[')) {
526
+ const closingBracket = rawAuthority.indexOf(']');
527
+ if (closingBracket < 2 || rawAuthority[closingBracket + 1] !== ':') {
528
+ throw new BrowserRuntimeError('EGRESS_DENIED');
529
+ }
530
+ hostnameValue = rawAuthority.slice(1, closingBracket);
531
+ portValue = rawAuthority.slice(closingBracket + 2);
532
+ }
533
+ else {
534
+ const separator = rawAuthority.lastIndexOf(':');
535
+ if (separator < 1 || rawAuthority.indexOf(':') !== separator) {
536
+ throw new BrowserRuntimeError('EGRESS_DENIED');
537
+ }
538
+ hostnameValue = rawAuthority.slice(0, separator);
539
+ portValue = rawAuthority.slice(separator + 1);
540
+ }
541
+ if (!/^\d{1,5}$/.test(portValue))
542
+ throw new BrowserRuntimeError('EGRESS_DENIED');
543
+ const hostname = this.canonicalizeHostname(hostnameValue);
544
+ const port = validateInteger(Number(portValue), 'target port', 1, 65535);
545
+ const resolved = await this.resolveHost(hostname, port, signal);
546
+ return { ...resolved, path: '', hostHeader: rawAuthority };
547
+ }
548
+ canonicalizeHostname(hostnameArg) {
549
+ const unbracketed = hostnameArg.startsWith('[') && hostnameArg.endsWith(']')
550
+ ? hostnameArg.slice(1, -1)
551
+ : hostnameArg;
552
+ if (!unbracketed || unbracketed.length > 253 || unbracketed.includes('%')) {
553
+ throw new BrowserRuntimeError('EGRESS_DENIED');
554
+ }
555
+ if (plugins.ipaddr.isValid(unbracketed)) {
556
+ return plugins.ipaddr.parse(unbracketed).toNormalizedString();
557
+ }
558
+ const withoutTrailingDot = unbracketed.endsWith('.') ? unbracketed.slice(0, -1) : unbracketed;
559
+ const ascii = plugins.url.domainToASCII(withoutTrailingDot).toLowerCase();
560
+ if (!ascii
561
+ || ascii.length > 253
562
+ || !ascii.includes('.')
563
+ || ascii.split('.').some((label) => (label.length < 1
564
+ || label.length > 63
565
+ || !/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(label)))) {
566
+ throw new BrowserRuntimeError('EGRESS_DENIED');
567
+ }
568
+ return ascii;
569
+ }
570
+ async resolveHost(hostname, port, signal) {
571
+ if (!this.allowedPorts.has(port)) {
572
+ throw new BrowserRuntimeError('EGRESS_DENIED');
573
+ }
574
+ const answers = plugins.ipaddr.isValid(hostname)
575
+ ? [{ address: hostname, family: plugins.ipaddr.parse(hostname).kind() === 'ipv4' ? 4 : 6 }]
576
+ : await this.raceAbort(this.resolver(hostname, { all: true, verbatim: true, signal }), signal);
577
+ signal.throwIfAborted();
578
+ if (!Array.isArray(answers) || answers.length < 1 || answers.length > 64) {
579
+ throw new BrowserRuntimeError('EGRESS_DENIED');
580
+ }
581
+ const validated = answers.map((answer) => {
582
+ if (!answer
583
+ || (answer.family !== 4 && answer.family !== 6)
584
+ || typeof answer.address !== 'string'
585
+ || answer.address.includes('%')
586
+ || !plugins.ipaddr.isValid(answer.address)) {
587
+ throw new BrowserRuntimeError('EGRESS_DENIED');
588
+ }
589
+ const parsed = plugins.ipaddr.parse(answer.address);
590
+ if ((parsed.kind() === 'ipv6'
591
+ && parsed.isIPv4MappedAddress())
592
+ || parsed.range() !== 'unicast'
593
+ || (parsed.kind() === 'ipv6'
594
+ && !parsed.match(plugins.ipaddr.parse('2000::'), 3))) {
595
+ throw new BrowserRuntimeError('EGRESS_DENIED');
596
+ }
597
+ const family = parsed.kind() === 'ipv4' ? 4 : 6;
598
+ if (family !== answer.family)
599
+ throw new BrowserRuntimeError('EGRESS_DENIED');
600
+ return { address: parsed.toNormalizedString(), family };
601
+ });
602
+ return { ...validated[0], hostname, port };
603
+ }
604
+ openUpstream(target, signal) {
605
+ const options = {
606
+ address: target.address,
607
+ family: target.family,
608
+ port: target.port,
609
+ hostname: target.hostname,
610
+ signal,
611
+ };
612
+ const socket = this.connector(options);
613
+ if (!(socket instanceof plugins.net.Socket)) {
614
+ throw new BrowserRuntimeError('EGRESS_DENIED');
615
+ }
616
+ this.upstreamSockets.add(socket);
617
+ socket.on('error', () => socket.destroy());
618
+ socket.setTimeout(this.idleTimeoutMs, () => socket.destroy());
619
+ socket.once('close', () => this.upstreamSockets.delete(socket));
620
+ if (signal.aborted)
621
+ socket.destroy(signal.reason);
622
+ else
623
+ signal.addEventListener('abort', () => socket.destroy(signal.reason), { once: true });
624
+ return socket;
625
+ }
626
+ async waitForConnect(socket, signal) {
627
+ if (!socket.connecting
628
+ && !socket.pending
629
+ && !socket.destroyed
630
+ && socket.remoteAddress)
631
+ return;
632
+ if (!socket.connecting || socket.destroyed)
633
+ throw new BrowserRuntimeError('EGRESS_DENIED');
634
+ await new Promise((resolve, reject) => {
635
+ const timer = setTimeout(() => {
636
+ cleanup();
637
+ socket.destroy();
638
+ reject(new BrowserRuntimeError('TIMEOUT'));
639
+ }, this.connectTimeoutMs);
640
+ timer.unref();
641
+ const cleanup = () => {
642
+ clearTimeout(timer);
643
+ socket.off('connect', onConnect);
644
+ socket.off('error', onError);
645
+ socket.off('close', onClose);
646
+ signal.removeEventListener('abort', onAbort);
647
+ };
648
+ const onConnect = () => {
649
+ cleanup();
650
+ resolve();
651
+ };
652
+ const onError = () => {
653
+ cleanup();
654
+ reject(new BrowserRuntimeError('EGRESS_DENIED'));
655
+ };
656
+ const onClose = () => {
657
+ cleanup();
658
+ reject(new BrowserRuntimeError('EGRESS_DENIED'));
659
+ };
660
+ const onAbort = () => {
661
+ cleanup();
662
+ socket.destroy(signal.reason);
663
+ reject(signal.reason);
664
+ };
665
+ socket.once('connect', onConnect);
666
+ socket.once('error', onError);
667
+ socket.once('close', onClose);
668
+ signal.addEventListener('abort', onAbort, { once: true });
669
+ });
670
+ }
671
+ async pipeTunnel(clientSocket, upstream, initial, signal) {
672
+ let transferred = initial.toUpstream.byteLength + initial.toClient.byteLength;
673
+ if (transferred > this.maxTunnelBytes)
674
+ throw new BrowserRuntimeError('QUOTA_EXCEEDED');
675
+ const lifetimeTimer = setTimeout(() => {
676
+ clientSocket.destroy();
677
+ upstream.destroy();
678
+ }, this.tunnelLifetimeMs);
679
+ lifetimeTimer.unref();
680
+ const count = (chunk) => {
681
+ transferred += chunk.byteLength;
682
+ if (transferred > this.maxTunnelBytes) {
683
+ clientSocket.destroy();
684
+ upstream.destroy();
685
+ }
686
+ };
687
+ clientSocket.on('data', count);
688
+ upstream.on('data', count);
689
+ const onAbort = () => {
690
+ clientSocket.destroy(signal.reason);
691
+ upstream.destroy(signal.reason);
692
+ };
693
+ signal.addEventListener('abort', onAbort, { once: true });
694
+ if (initial.toUpstream.byteLength > 0)
695
+ upstream.write(initial.toUpstream);
696
+ if (initial.toClient.byteLength > 0)
697
+ clientSocket.write(initial.toClient);
698
+ clientSocket.pipe(upstream);
699
+ upstream.pipe(clientSocket);
700
+ clientSocket.resume();
701
+ await Promise.race([
702
+ new Promise((resolve) => clientSocket.once('close', resolve)),
703
+ new Promise((resolve) => upstream.once('close', resolve)),
704
+ ]);
705
+ clearTimeout(lifetimeTimer);
706
+ clientSocket.off('data', count);
707
+ upstream.off('data', count);
708
+ signal.removeEventListener('abort', onAbort);
709
+ clientSocket.destroy();
710
+ upstream.destroy();
711
+ }
712
+ async readWebSocketHandshake(upstream, signal, expectedAccept) {
713
+ const data = await new Promise((resolve, reject) => {
714
+ let buffered = plugins.Buffer.alloc(0);
715
+ const cleanup = () => {
716
+ upstream.off('data', onData);
717
+ upstream.off('error', onError);
718
+ upstream.off('close', onClose);
719
+ signal.removeEventListener('abort', onAbort);
720
+ };
721
+ const onData = (chunk) => {
722
+ buffered = plugins.Buffer.concat([buffered, chunk]);
723
+ const boundary = buffered.indexOf('\r\n\r\n');
724
+ if (boundary < 0 && buffered.byteLength > this.maxHeaderBytes) {
725
+ cleanup();
726
+ reject(new BrowserRuntimeError('QUOTA_EXCEEDED'));
727
+ return;
728
+ }
729
+ if (boundary < 0)
730
+ return;
731
+ if (boundary + 4 > this.maxHeaderBytes) {
732
+ cleanup();
733
+ reject(new BrowserRuntimeError('QUOTA_EXCEEDED'));
734
+ return;
735
+ }
736
+ cleanup();
737
+ resolve(buffered);
738
+ };
739
+ const onError = () => {
740
+ cleanup();
741
+ reject(new BrowserRuntimeError('EGRESS_DENIED'));
742
+ };
743
+ const onClose = () => {
744
+ cleanup();
745
+ reject(new BrowserRuntimeError('EGRESS_DENIED'));
746
+ };
747
+ const onAbort = () => {
748
+ cleanup();
749
+ reject(signal.reason);
750
+ };
751
+ upstream.on('data', onData);
752
+ upstream.once('error', onError);
753
+ upstream.once('close', onClose);
754
+ signal.addEventListener('abort', onAbort, { once: true });
755
+ });
756
+ const boundary = data.indexOf('\r\n\r\n');
757
+ const header = data.subarray(0, boundary + 4);
758
+ const statusLine = header.subarray(0, header.indexOf('\r\n')).toString('latin1');
759
+ if (!/^HTTP\/1\.[01] 101(?: |$)/.test(statusLine)) {
760
+ throw new BrowserRuntimeError('EGRESS_DENIED');
761
+ }
762
+ const headerLines = header.toString('latin1').split('\r\n').slice(1, -2);
763
+ const headers = new Map();
764
+ for (const headerLine of headerLines) {
765
+ const separator = headerLine.indexOf(':');
766
+ if (separator < 1)
767
+ throw new BrowserRuntimeError('EGRESS_DENIED');
768
+ const name = headerLine.slice(0, separator).trim().toLowerCase();
769
+ const value = headerLine.slice(separator + 1).trim();
770
+ const values = headers.get(name) ?? [];
771
+ values.push(value);
772
+ headers.set(name, values);
773
+ }
774
+ const connectionTokens = (headers.get('connection') ?? [])
775
+ .flatMap((value) => value.split(','))
776
+ .map((value) => value.trim().toLowerCase());
777
+ if (!connectionTokens.includes('upgrade')
778
+ || headers.get('upgrade')?.length !== 1
779
+ || headers.get('upgrade')?.[0]?.toLowerCase() !== 'websocket'
780
+ || headers.get('sec-websocket-accept')?.length !== 1
781
+ || headers.get('sec-websocket-accept')?.[0] !== expectedAccept)
782
+ throw new BrowserRuntimeError('EGRESS_DENIED');
783
+ return { header, remaining: data.subarray(boundary + 4) };
784
+ }
785
+ createOperationSignal() {
786
+ const controller = new AbortController();
787
+ const timeoutController = new AbortController();
788
+ const timeout = setTimeout(() => {
789
+ timeoutController.abort(new BrowserRuntimeError('TIMEOUT'));
790
+ }, this.requestTimeoutMs);
791
+ timeout.unref();
792
+ return {
793
+ controller,
794
+ signal: AbortSignal.any([
795
+ controller.signal,
796
+ timeoutController.signal,
797
+ this.lifecycleController.signal,
798
+ ]),
799
+ dispose: () => clearTimeout(timeout),
800
+ };
801
+ }
802
+ async raceAbort(promise, signal) {
803
+ signal.throwIfAborted();
804
+ let onAbort;
805
+ const aborted = new Promise((_resolve, reject) => {
806
+ onAbort = () => reject(signal.reason);
807
+ signal.addEventListener('abort', onAbort, { once: true });
808
+ });
809
+ try {
810
+ return await Promise.race([promise, aborted]);
811
+ }
812
+ finally {
813
+ signal.removeEventListener('abort', onAbort);
814
+ }
815
+ }
816
+ async waitForResponseCompletion(response) {
817
+ if (response.writableFinished || response.destroyed)
818
+ return;
819
+ await new Promise((resolve) => {
820
+ const settle = () => {
821
+ response.off('finish', settle);
822
+ response.off('close', settle);
823
+ resolve();
824
+ };
825
+ response.once('finish', settle);
826
+ response.once('close', settle);
827
+ });
828
+ }
829
+ }
830
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5lZ3Jlc3Nwcm94eS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMuZWdyZXNzcHJveHkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFReEMsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ2xELE9BQU8sRUFDTCxRQUFRLEVBQ1IscUJBQXFCLEVBQ3JCLGVBQWUsRUFDZix1QkFBdUIsRUFDdkIsV0FBVyxHQUNaLE1BQU0sWUFBWSxDQUFDO0FBV3BCLE1BQU0sZUFBZSxHQUFHLElBQUksR0FBRyxDQUFDO0lBQzlCLFlBQVk7SUFDWixZQUFZO0lBQ1osb0JBQW9CO0lBQ3BCLHFCQUFxQjtJQUNyQixrQkFBa0I7SUFDbEIsSUFBSTtJQUNKLFNBQVM7SUFDVCxtQkFBbUI7SUFDbkIsU0FBUztDQUNWLENBQUMsQ0FBQztBQUVILE1BQU0sT0FBTyxrQkFBa0I7SUFDWixTQUFTLENBQVM7SUFDbEIsWUFBWSxDQUFzQjtJQUNsQyxjQUFjLENBQVM7SUFDdkIsaUJBQWlCLENBQVM7SUFDMUIsY0FBYyxDQUFTO0lBQ3ZCLGdCQUFnQixDQUFTO0lBQ3pCLGFBQWEsQ0FBUztJQUN0QixnQkFBZ0IsQ0FBUztJQUN6QixnQkFBZ0IsQ0FBUztJQUN6QixlQUFlLENBQVM7SUFDeEIsZ0JBQWdCLENBQVM7SUFDekIsY0FBYyxDQUFTO0lBQ3ZCLFFBQVEsQ0FBc0I7SUFDOUIsU0FBUyxDQUEwQjtJQUNuQyxRQUFRLEdBQUcsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ3hCLFFBQVEsR0FBRyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDeEIscUJBQXFCLENBQWlCO0lBQ3RDLGFBQWEsR0FBRyxJQUFJLEdBQUcsRUFBc0IsQ0FBQztJQUM5QyxlQUFlLEdBQUcsSUFBSSxHQUFHLEVBQXNCLENBQUM7SUFDaEQsZ0JBQWdCLEdBQUcsSUFBSSxHQUFHLEVBQWlCLENBQUM7SUFDckQsTUFBTSxDQUF1QjtJQUM3QixVQUFVLENBQVU7SUFDcEIsWUFBWSxDQUFpQjtJQUM3QixXQUFXLENBQWlCO0lBQzVCLGNBQWMsR0FBb0QsU0FBUyxDQUFDO0lBQzVFLG1CQUFtQixHQUFHLElBQUksZUFBZSxFQUFFLENBQUM7SUFDNUMsZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDO0lBQ3JCLGVBQWUsR0FBRyxDQUFDLENBQUM7SUFDcEIsZUFBZSxHQUFHLENBQUMsQ0FBQztJQUNwQixnQkFBZ0IsR0FBRyxDQUFDLENBQUM7SUFFN0IsWUFBWSxPQUFtQztRQUM3QyxJQUFJLENBQUMsU0FBUyxHQUFHLHFCQUFxQixDQUFDLE9BQU8sQ0FBQyxTQUFTLEVBQUUsV0FBVyxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUMvRSxNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsWUFBWSxJQUFJLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ2hELElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLEtBQUssQ0FBQyxNQUFNLEdBQUcsRUFBRSxFQUFFLENBQUM7WUFDbkUsTUFBTSxJQUFJLG1CQUFtQixDQUFDLGVBQWUsRUFBRSx5Q0FBeUMsQ0FBQyxDQUFDO1FBQzVGLENBQUM7UUFDRCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLGVBQWUsQ0FBQyxJQUFJLEVBQUUsYUFBYSxFQUFFLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDakcsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksS0FBSyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDNUMsTUFBTSxJQUFJLG1CQUFtQixDQUFDLGVBQWUsRUFBRSwwQ0FBMEMsQ0FBQyxDQUFDO1FBQzdGLENBQUM7UUFDRCxJQUFJLENBQUMsY0FBYyxHQUFHLHVCQUF1QixDQUMzQyxPQUFPLENBQUMsY0FBYyxFQUN0QixnQkFBZ0IsRUFDaEIsQ0FBQyxFQUNELElBQUksRUFDSixHQUFHLENBQ0osQ0FBQztRQUNGLElBQUksQ0FBQyxpQkFBaUIsR0FBRyx1QkFBdUIsQ0FDOUMsT0FBTyxDQUFDLGlCQUFpQixFQUN6QixtQkFBbUIsRUFDbkIsQ0FBQyxFQUNELElBQUksRUFDSixJQUFJLENBQUMsY0FBYyxDQUNwQixDQUFDO1FBQ0YsSUFBSSxDQUFDLGNBQWMsR0FBRyx1QkFBdUIsQ0FDM0MsT0FBTyxDQUFDLGNBQWMsRUFDdEIsZ0JBQWdCLEVBQ2hCLElBQUksRUFDSixHQUFHLEdBQUcsSUFBSSxFQUNWLEVBQUUsR0FBRyxJQUFJLENBQ1YsQ0FBQztRQUNGLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyx1QkFBdUIsQ0FDN0MsT0FBTyxDQUFDLGdCQUFnQixFQUN4QixrQkFBa0IsRUFDbEIsR0FBRyxFQUNILE1BQU0sRUFDTixNQUFNLENBQ1AsQ0FBQztRQUNGLElBQUksQ0FBQyxhQUFhLEdBQUcsdUJBQXVCLENBQzFDLE9BQU8sQ0FBQyxhQUFhLEVBQ3JCLGVBQWUsRUFDZixJQUFJLEVBQ0osRUFBRSxHQUFHLE1BQU0sRUFDWCxNQUFNLENBQ1AsQ0FBQztRQUNGLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyx1QkFBdUIsQ0FDN0MsT0FBTyxDQUFDLGdCQUFnQixFQUN4QixrQkFBa0IsRUFDbEIsSUFBSSxFQUNKLEVBQUUsR0FBRyxNQUFNLEVBQ1gsRUFBRSxHQUFHLE1BQU0sQ0FDWixDQUFDO1FBQ0YsSUFBSSxDQUFDLGdCQUFnQixHQUFHLHVCQUF1QixDQUM3QyxPQUFPLENBQUMsZ0JBQWdCLEVBQ3hCLGtCQUFrQixFQUNsQixJQUFJLEVBQ0osRUFBRSxHQUFHLE1BQU0sRUFDWCxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQzVDLENBQUM7UUFDRixJQUFJLENBQUMsZUFBZSxHQUFHLHVCQUF1QixDQUM1QyxPQUFPLENBQUMsZUFBZSxFQUN2QixpQkFBaUIsRUFDakIsSUFBSSxFQUNKLEdBQUcsR0FBRyxJQUFJLEdBQUcsSUFBSSxFQUNqQixFQUFFLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FDakIsQ0FBQztRQUNGLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyx1QkFBdUIsQ0FDN0MsT0FBTyxDQUFDLGdCQUFnQixFQUN4QixrQkFBa0IsRUFDbEIsSUFBSSxFQUNKLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxFQUNsQixFQUFFLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FDakIsQ0FBQztRQUNGLElBQUksQ0FBQyxjQUFjLEdBQUcsdUJBQXVCLENBQzNDLE9BQU8sQ0FBQyxjQUFjLEVBQ3RCLGdCQUFnQixFQUNoQixJQUFJLEVBQ0osQ0FBQyxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxFQUN0QixHQUFHLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FDbEIsQ0FBQztRQUNGLElBQUksQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLFFBQVEsSUFBSSxDQUFDLEtBQUssRUFBRSxRQUFRLEVBQUUsYUFBYSxFQUFFLEVBQUUsQ0FBQyxDQUN0RSxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsUUFBUSxFQUFFO1lBQ3BDLEdBQUcsRUFBRSxhQUFhLENBQUMsR0FBRztZQUN0QixRQUFRLEVBQUUsYUFBYSxDQUFDLFFBQVE7U0FDakMsQ0FBQyxDQUNILENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxTQUFTLEdBQUcsT0FBTyxDQUFDLFNBQVMsSUFBSSxDQUFDLENBQUMsaUJBQWlCLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDO1lBQ2hGLElBQUksRUFBRSxpQkFBaUIsQ0FBQyxPQUFPO1lBQy9CLE1BQU0sRUFBRSxpQkFBaUIsQ0FBQyxNQUFNO1lBQ2hDLElBQUksRUFBRSxpQkFBaUIsQ0FBQyxJQUFJO1NBQzdCLENBQUMsQ0FBQyxDQUFDO1FBQ0osSUFBSSxDQUFDLHFCQUFxQixHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUM5QyxTQUFTLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxFQUFFLEVBQzlGLE1BQU0sQ0FDUCxDQUFDO0lBQ0osQ0FBQztJQUVELElBQVcsV0FBVztRQUNwQixPQUFPLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUM5RCxDQUFDO0lBRUQsSUFBVyxJQUFJO1FBQ2IsSUFBSSxJQUFJLENBQUMsVUFBVSxLQUFLLFNBQVM7WUFBRSxNQUFNLElBQUksbUJBQW1CLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDaEYsT0FBTyxJQUFJLENBQUMsVUFBVSxDQUFDO0lBQ3pCLENBQUM7SUFFRCxJQUFXLE9BQU87UUFDaEIsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO0lBQ3hCLENBQUM7SUFFRCxJQUFXLGtCQUFrQjtRQUMzQixPQUFPLENBQUMsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7SUFDaEMsQ0FBQztJQUVNLFFBQVE7UUFDYixPQUFPO1lBQ0wsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLGdCQUFnQjtZQUN2QyxlQUFlLEVBQUUsSUFBSSxDQUFDLGVBQWU7WUFDckMsZUFBZSxFQUFFLElBQUksQ0FBQyxlQUFlO1lBQ3JDLGdCQUFnQixFQUFFLElBQUksQ0FBQyxnQkFBZ0I7WUFDdkMsaUJBQWlCLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJO1NBQzNDLENBQUM7SUFDSixDQUFDO0lBRU0sS0FBSztRQUNWLElBQUksSUFBSSxDQUFDLGNBQWMsS0FBSyxTQUFTO1lBQUUsT0FBTyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDaEUsSUFBSSxJQUFJLENBQUMsWUFBWTtZQUFFLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQztRQUNoRCxJQUFJLElBQUksQ0FBQyxXQUFXO1lBQUUsT0FBTyxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUN2RSxJQUFJLENBQUMsV0FBVyxHQUFHLFNBQVMsQ0FBQztRQUM3QixJQUFJLENBQUMsY0FBYyxHQUFHLFVBQVUsQ0FBQztRQUNqQyxJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxlQUFlLEVBQUUsQ0FBQztRQUNqRCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFO1lBQ2pELElBQUksSUFBSSxDQUFDLGNBQWMsS0FBSyxVQUFVO2dCQUFFLE1BQU0sSUFBSSxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUNqRixJQUFJLENBQUMsY0FBYyxHQUFHLFNBQVMsQ0FBQztRQUNsQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtZQUNqQixJQUFJLElBQUksQ0FBQyxjQUFjLEtBQUssVUFBVTtnQkFBRSxJQUFJLENBQUMsY0FBYyxHQUFHLFNBQVMsQ0FBQztZQUN4RSxNQUFNLEtBQUssQ0FBQztRQUNkLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUU7WUFDZCxJQUFJLENBQUMsWUFBWSxHQUFHLFNBQVMsQ0FBQztRQUNoQyxDQUFDLENBQUMsQ0FBQztRQUNILE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQztJQUMzQixDQUFDO0lBRU0sSUFBSTtRQUNULElBQUksSUFBSSxDQUFDLFdBQVc7WUFBRSxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUM7UUFDOUMsSUFBSSxJQUFJLENBQUMsY0FBYyxLQUFLLFNBQVMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDNUUsT0FBTyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDM0IsQ0FBQztRQUNELElBQUksQ0FBQyxjQUFjLEdBQUcsVUFBVSxDQUFDO1FBQ2pDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLENBQUMsSUFBSSxtQkFBbUIsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQ25FLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUM7UUFDbEMsSUFBSSxDQUFDLFdBQVcsR0FBRyxDQUFDLEtBQUssSUFBSSxFQUFFO1lBQzdCLE1BQU0sT0FBTyxFQUFFLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUN0QyxNQUFNLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUMxQixJQUFJLENBQUMsY0FBYyxHQUFHLFNBQVMsQ0FBQztRQUNsQyxDQUFDLENBQUMsRUFBRSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUU7WUFDaEIsSUFBSSxDQUFDLFdBQVcsR0FBRyxTQUFTLENBQUM7UUFDL0IsQ0FBQyxDQUFDLENBQUM7UUFDSCxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUM7SUFDMUIsQ0FBQztJQUVPLEtBQUssQ0FBQyxhQUFhO1FBQ3pCLE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUN0QyxFQUFFLGFBQWEsRUFBRSxJQUFJLENBQUMsY0FBYyxFQUFFLEVBQ3RDLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxFQUFFO1lBQ3BCLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQztnQkFDbEIsSUFBSSxDQUFDLGdCQUFnQixJQUFJLENBQUMsQ0FBQztnQkFDM0IsSUFBSSxDQUFDLGVBQWUsQ0FBQyxRQUFRLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQ3BDLE9BQU87WUFDVCxDQUFDO1lBQ0QsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsT0FBTyxFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFDeEQsQ0FBQyxDQUNGLENBQUM7UUFDRixJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixNQUFNLENBQUMsRUFBRSxDQUFDLFlBQVksRUFBRSxDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQ2pDLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUNuRCxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ2pCLE9BQU87WUFDVCxDQUFDO1lBQ0QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDL0IsTUFBTSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFDM0MsTUFBTSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDO1lBQzlELE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDaEUsQ0FBQyxDQUFDLENBQUM7UUFDSCxNQUFNLENBQUMsRUFBRSxDQUFDLFNBQVMsRUFBRSxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLEVBQUU7WUFDN0MsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDO2dCQUNsQixJQUFJLENBQUMsZ0JBQWdCLElBQUksQ0FBQyxDQUFDO2dCQUMzQixJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sRUFBRSxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUM7Z0JBQ3pDLE9BQU87WUFDVCxDQUFDO1lBQ0QsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUN4RCxDQUFDLENBQUMsQ0FBQztRQUNILE1BQU0sQ0FBQyxFQUFFLENBQUMsU0FBUyxFQUFFLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsRUFBRTtZQUM3QyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUM7Z0JBQ2xCLElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxDQUFDLENBQUM7Z0JBQzNCLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQztnQkFDekMsT0FBTztZQUNULENBQUM7WUFDRCxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ3hELENBQUMsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxDQUFDLEVBQUUsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLEVBQUU7WUFDMUMsSUFBSSxDQUFDLGdCQUFnQixJQUFJLENBQUMsQ0FBQztZQUMzQixJQUFJLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDcEIsTUFBTSxDQUFDLEdBQUcsQ0FBQyx1REFBdUQsQ0FBQyxDQUFDO1lBQ3RFLENBQUM7aUJBQU0sQ0FBQztnQkFDTixNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDbkIsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFO1lBQ3RCLElBQUksSUFBSSxDQUFDLGNBQWMsS0FBSyxTQUFTO2dCQUFFLEtBQUssSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNqRixDQUFDLENBQUMsQ0FBQztRQUNILE1BQU0sQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDO1FBQzlDLE1BQU0sQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDO1FBQzlDLE1BQU0sQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUM7UUFDckQsTUFBTSxJQUFJLE9BQU8sQ0FBTyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsRUFBRTtZQUMxQyxNQUFNLE9BQU8sR0FBRyxDQUFDLEtBQVksRUFBUSxFQUFFO2dCQUNyQyxNQUFNLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxXQUFXLENBQUMsQ0FBQztnQkFDckMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2hCLENBQUMsQ0FBQztZQUNGLE1BQU0sV0FBVyxHQUFHLEdBQVMsRUFBRTtnQkFDN0IsTUFBTSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7Z0JBQzdCLE9BQU8sRUFBRSxDQUFDO1lBQ1osQ0FBQyxDQUFDO1lBQ0YsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDOUIsTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsV0FBVyxDQUFDLENBQUM7WUFDdEMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDaEMsQ0FBQyxDQUFDLENBQUM7UUFDSCxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDakMsSUFBSSxDQUFDLE9BQU8sSUFBSSxPQUFPLE9BQU8sS0FBSyxRQUFRLElBQUksT0FBTyxDQUFDLE9BQU8sS0FBSyxXQUFXLEVBQUUsQ0FBQztZQUMvRSxNQUFNLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUMxQixNQUFNLElBQUksbUJBQW1CLENBQUMsUUFBUSxFQUFFLHFDQUFxQyxDQUFDLENBQUM7UUFDakYsQ0FBQztRQUNELElBQUksQ0FBQyxVQUFVLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQztJQUNqQyxDQUFDO0lBRU8sS0FBSyxDQUFDLFlBQVk7UUFDeEIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUMzQixJQUFJLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQztRQUM1QixLQUFLLE1BQU0sTUFBTSxJQUFJLElBQUksQ0FBQyxhQUFhO1lBQUUsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQzFELEtBQUssTUFBTSxNQUFNLElBQUksSUFBSSxDQUFDLGVBQWU7WUFBRSxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDNUQsSUFBSSxNQUFNLEVBQUUsQ0FBQztZQUNYLE1BQU0sSUFBSSxPQUFPLENBQU8sQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7Z0JBQzFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRTtvQkFDckIsSUFBSSxLQUFLLElBQUssS0FBK0IsQ0FBQyxJQUFJLEtBQUssd0JBQXdCLEVBQUUsQ0FBQzt3QkFDaEYsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUNoQixDQUFDO3lCQUFNLENBQUM7d0JBQ04sT0FBTyxFQUFFLENBQUM7b0JBQ1osQ0FBQztnQkFDSCxDQUFDLENBQUMsQ0FBQztZQUNMLENBQUMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUNELE1BQU0sT0FBTyxHQUFHLE1BQU0sV0FBVyxDQUMvQixPQUFPLENBQUMsVUFBVSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsRUFDcEUsSUFBSSxDQUFDLGdCQUFnQixDQUN0QixDQUFDO1FBQ0YsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPO1lBQUUsTUFBTSxJQUFJLG1CQUFtQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQy9ELElBQUksQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDO1FBQ3hCLElBQUksQ0FBQyxZQUFZLEdBQUcsU0FBUyxDQUFDO0lBQ2hDLENBQUM7SUFFTyxLQUFLLENBQUMsU0FBd0I7UUFDcEMsTUFBTSxRQUFRLEdBQUcsU0FBUyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFO1lBQzdELElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDekMsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3RDLENBQUM7SUFFTyxLQUFLO1FBQ1gsT0FBTyxJQUFJLENBQUMsY0FBYyxLQUFLLFVBQVU7ZUFDcEMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUM7SUFDM0QsQ0FBQztJQUVPLEtBQUssQ0FBQyxpQkFBaUIsQ0FDN0IsT0FBcUMsRUFDckMsUUFBcUM7UUFFckMsSUFBSSxDQUFDLGdCQUFnQixJQUFJLENBQUMsQ0FBQztRQUMzQixJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQzdCLElBQUksQ0FBQywrQkFBK0IsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUMvQyxPQUFPO1FBQ1QsQ0FBQztRQUNELE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNoQixJQUFJLGVBQXVELENBQUM7UUFDNUQsSUFBSSxjQUE4QyxDQUFDO1FBQ25ELElBQUksZ0JBQTBELENBQUM7UUFDL0QsSUFBSSxLQUFxQyxDQUFDO1FBQzFDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQy9DLE1BQU0sS0FBSyxHQUFHLEdBQVMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLElBQUksbUJBQW1CLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztRQUN6RixPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQztRQUMvQixPQUFPLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDcEMsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFO1lBQzFCLElBQUksQ0FBQyxRQUFRLENBQUMsZ0JBQWdCO2dCQUFFLEtBQUssRUFBRSxDQUFDO1FBQzFDLENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDO1lBQ0gsTUFBTSxhQUFhLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDO1lBQ2hFLElBQ0UsTUFBTSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUM7bUJBQzNCLGFBQWEsR0FBRyxJQUFJLENBQUMsZUFBZTtnQkFDdkMsTUFBTSxJQUFJLG1CQUFtQixDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDbEQsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMscUJBQXFCLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3RGLFNBQVMsQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDbEMsY0FBYyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUM3RCxNQUFNLElBQUksQ0FBQyxjQUFjLENBQUMsY0FBYyxFQUFFLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUM1RCxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUN0RCxPQUFPLENBQUMsSUFBSSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUM7WUFDakMsS0FBSyxHQUFHLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztZQUNyRCxLQUFLLENBQUMsZ0JBQWdCLEdBQUcsR0FBRyxFQUFFLENBQUMsY0FBZSxDQUFDO1lBQy9DLGVBQWUsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztnQkFDckMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNO2dCQUN0QixJQUFJLEVBQUUsTUFBTSxDQUFDLE9BQU87Z0JBQ3BCLE1BQU0sRUFBRSxNQUFNLENBQUMsTUFBTTtnQkFDckIsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJO2dCQUNqQixJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUk7Z0JBQ2pCLE9BQU87Z0JBQ1AsS0FBSztnQkFDTCxhQUFhLEVBQUUsSUFBSSxDQUFDLGNBQWM7YUFDbkMsQ0FBQyxDQUFDO1lBQ0gsTUFBTSxPQUFPLEdBQUcsR0FBUyxFQUFFO2dCQUN6QixlQUFlLEVBQUUsT0FBTyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQ2xELGdCQUFnQixFQUFFLE9BQU8sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUNuRCxjQUFjLEVBQUUsT0FBTyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDbkQsQ0FBQyxDQUFDO1lBQ0YsU0FBUyxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7WUFDcEUsSUFBSSxZQUFZLEdBQUcsQ0FBQyxDQUFDO1lBQ3JCLE9BQU8sQ0FBQyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUMsS0FBcUIsRUFBRSxFQUFFO2dCQUMzQyxZQUFZLElBQUksS0FBSyxDQUFDLFVBQVUsQ0FBQztnQkFDakMsSUFBSSxZQUFZLEdBQUcsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO29CQUN4QyxTQUFTLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxJQUFJLG1CQUFtQixDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQztnQkFDeEUsQ0FBQztZQUNILENBQUMsQ0FBQyxDQUFDO1lBQ0gsTUFBTSx1QkFBdUIsR0FBRyxJQUFJLE9BQU8sQ0FBK0IsQ0FBQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEVBQUU7Z0JBQzVGLGVBQWdCLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFDM0MsZUFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ3pDLENBQUMsQ0FBQyxDQUFDO1lBQ0gsT0FBTyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUM5QixnQkFBZ0IsR0FBRyxNQUFNLElBQUksQ0FBQyxTQUFTLENBQUMsdUJBQXVCLEVBQUUsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ25GLE1BQU0sY0FBYyxHQUFHLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDO1lBQzFFLElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsSUFBSSxjQUFjLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7Z0JBQzlFLE1BQU0sSUFBSSxtQkFBbUIsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ2xELENBQUM7WUFDRCxNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3ZFLFFBQVEsQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxJQUFJLEdBQUcsRUFBRSxlQUFlLENBQUMsQ0FBQztZQUN4RSxJQUFJLGFBQWEsR0FBRyxDQUFDLENBQUM7WUFDdEIsZ0JBQWdCLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLEtBQXFCLEVBQUUsRUFBRTtnQkFDcEQsYUFBYSxJQUFJLEtBQUssQ0FBQyxVQUFVLENBQUM7Z0JBQ2xDLElBQUksYUFBYSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO29CQUMxQyxTQUFTLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxJQUFJLG1CQUFtQixDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQztnQkFDeEUsQ0FBQztZQUNILENBQUMsQ0FBQyxDQUFDO1lBQ0gsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUN4QyxNQUFNLGVBQWUsR0FBRyxJQUFJLE9BQU8sQ0FBUSxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsRUFBRTtnQkFDOUQsZ0JBQWlCLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUMxQyxDQUFDLENBQUMsQ0FBQztZQUNILGdCQUFnQixDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNoQyxNQUFNLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMseUJBQXlCLENBQUMsUUFBUSxDQUFDLEVBQUUsZUFBZSxDQUFDLENBQUMsQ0FBQztZQUNoRixTQUFTLENBQUMsTUFBTSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3BDLENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUCxJQUFJLENBQUMsZ0JBQWdCLElBQUksQ0FBQyxDQUFDO1lBQzNCLGVBQWUsRUFBRSxPQUFPLEVBQUUsQ0FBQztZQUMzQixjQUFjLEVBQUUsT0FBTyxFQUFFLENBQUM7WUFDMUIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxXQUFXO2dCQUFFLElBQUksQ0FBQyxlQUFlLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxDQUFDOztnQkFDMUQsUUFBUSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQzFCLENBQUM7Z0JBQVMsQ0FBQztZQUNULFNBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNwQixPQUFPLENBQUMsR0FBRyxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUM5QixPQUFPLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDbkMsZ0JBQWdCLEVBQUUsT0FBTyxFQUFFLENBQUM7WUFDNUIsZUFBZSxFQUFFLE9BQU8sRUFBRSxDQUFDO1lBQzNCLGNBQWMsRUFBRSxPQUFPLEVBQUUsQ0FBQztZQUMxQixLQUFLLEVBQUUsT0FBTyxFQUFFLENBQUM7UUFDbkIsQ0FBQztJQUNILENBQUM7SUFFTyxLQUFLLENBQUMsYUFBYSxDQUN6QixPQUFxQyxFQUNyQyxZQUFtQyxFQUNuQyxJQUFvQjtRQUVwQixJQUFJLENBQUMsZUFBZSxJQUFJLENBQUMsQ0FBQztRQUMxQixJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQzdCLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUM5QyxPQUFPO1FBQ1QsQ0FBQztRQUNELFlBQVksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNyQixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztRQUMvQyxNQUFNLEtBQUssR0FBRyxHQUFTLEVBQUUsQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxJQUFJLG1CQUFtQixDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFDekYsWUFBWSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDbEMsSUFBSSxRQUF3QyxDQUFDO1FBQzdDLElBQUksQ0FBQztZQUNILElBQUksSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsY0FBYztnQkFBRSxNQUFNLElBQUksbUJBQW1CLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUMzRixNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUMxRSxRQUFRLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3ZELE1BQU0sSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLEVBQUUsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3RELFNBQVMsQ0FBQyxNQUFNLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDbEMsWUFBWSxDQUFDLEtBQUssQ0FBQyw2Q0FBNkMsQ0FBQyxDQUFDO1lBQ2xFLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FBQyxZQUFZLEVBQUUsUUFBUSxFQUFFO2dCQUM1QyxVQUFVLEVBQUUsSUFBSTtnQkFDaEIsUUFBUSxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQzthQUNsQyxFQUFFLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN2QixDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsSUFBSSxDQUFDLGdCQUFnQixJQUFJLENBQUMsQ0FBQztZQUMzQixRQUFRLEVBQUUsT0FBTyxFQUFFLENBQUM7WUFDcEIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZLEVBQUUsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ2pELENBQUM7Z0JBQVMsQ0FBQztZQUNULFNBQVMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNwQixZQUFZLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNuQyxDQUFDO0lBQ0gsQ0FBQztJQUVPLEtBQUssQ0FBQyxhQUFhLENBQ3pCLE9BQXFDLEVBQ3JDLFlBQW1DLEVBQ25DLElBQW9CO1FBRXBCLElBQUksQ0FBQyxlQUFlLElBQUksQ0FBQyxDQUFDO1FBQzFCLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDN0IsSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQzlDLE9BQU87UUFDVCxDQUFDO1FBQ0QsWUFBWSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3JCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQy9DLE1BQU0sS0FBSyxHQUFHLEdBQVMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLElBQUksbUJBQW1CLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztRQUN6RixZQUFZLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsQ0FBQztRQUNsQyxJQUFJLFFBQXdDLENBQUM7UUFDN0MsSUFBSSxDQUFDO1lBQ0gsSUFDRSxPQUFPLENBQUMsTUFBTSxLQUFLLEtBQUs7bUJBQ3JCLE1BQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLFdBQVcsRUFBRSxLQUFLLFdBQVc7bUJBQzdELENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQztxQkFDNUQsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDO2dCQUNuRCxNQUFNLElBQUksbUJBQW1CLENBQUMsZUFBZSxDQUFDLENBQUM7WUFDakQsTUFBTSxZQUFZLEdBQUcscUJBQXFCLENBQ3hDLE9BQU8sQ0FBQyxPQUFPLENBQUMsbUJBQW1CLENBQUMsRUFDcEMsbUJBQW1CLEVBQ25CLEVBQUUsRUFDRixFQUFFLENBQ0gsQ0FBQztZQUNGLElBQ0UsT0FBTyxDQUFDLE9BQU8sQ0FBQyx1QkFBdUIsQ0FBQyxLQUFLLElBQUk7bUJBQzlDLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQzttQkFDM0MsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsWUFBWSxFQUFFLFFBQVEsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsS0FBSyxZQUFZO2dCQUNsRixNQUFNLElBQUksbUJBQW1CLENBQUMsZUFBZSxDQUFDLENBQUM7WUFDakQsTUFBTSxjQUFjLEdBQUcsT0FBTyxDQUFDLE1BQU07aUJBQ2xDLFVBQVUsQ0FBQyxNQUFNLENBQUM7aUJBQ2xCLE1BQU0sQ0FBQyxHQUFHLFlBQVksc0NBQXNDLEVBQUUsT0FBTyxDQUFDO2lCQUN0RSxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDcEIsSUFBSSxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxjQUFjO2dCQUFFLE1BQU0sSUFBSSxtQkFBbUIsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQzNGLE1BQU0sTUFBTSxHQUFHLE1BQU0sSUFBSSxDQUFDLHFCQUFxQixDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNyRixRQUFRLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3ZELE1BQU0sSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLEVBQUUsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3RELE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3RELE9BQU8sQ0FBQyxJQUFJLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQztZQUNqQyxPQUFPLENBQUMsVUFBVSxHQUFHLFNBQVMsQ0FBQztZQUMvQixPQUFPLENBQUMsT0FBTyxHQUFHLFdBQVcsQ0FBQztZQUM5QixNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUNyRSxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQztnQkFDbEIsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLEdBQUcsSUFBSSxLQUFLLEtBQUssRUFBRSxDQUFDO2dCQUMzQyxDQUFDLENBQUMsS0FBSyxLQUFLLFNBQVM7b0JBQ25CLENBQUMsQ0FBQyxFQUFFO29CQUNKLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxLQUFLLEtBQUssRUFBRSxDQUFDLENBQzVCLENBQUMsQ0FBQztZQUNILFFBQVEsQ0FBQyxLQUFLLENBQ1osR0FBRyxPQUFPLENBQUMsTUFBTSxJQUFJLEtBQUssSUFBSSxNQUFNLENBQUMsSUFBSSxnQkFBZ0IsV0FBVyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUM1RixDQUFDO1lBQ0YsTUFBTSxTQUFTLEdBQUcsTUFBTSxJQUFJLENBQUMsc0JBQXNCLENBQ2pELFFBQVEsRUFDUixTQUFTLENBQUMsTUFBTSxFQUNoQixjQUFjLENBQ2YsQ0FBQztZQUNGLFlBQVksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3JDLE1BQU0sSUFBSSxDQUFDLFVBQVUsQ0FDbkIsWUFBWSxFQUNaLFFBQVEsRUFDUixFQUFFLFVBQVUsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLFNBQVMsQ0FBQyxTQUFTLEVBQUUsRUFDbkQsU0FBUyxDQUFDLE1BQU0sQ0FDakIsQ0FBQztRQUNKLENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUCxJQUFJLENBQUMsZ0JBQWdCLElBQUksQ0FBQyxDQUFDO1lBQzNCLFFBQVEsRUFBRSxPQUFPLEVBQUUsQ0FBQztZQUNwQixJQUFJLENBQUMsZUFBZSxDQUFDLFlBQVksRUFBRSxHQUFHLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDakQsQ0FBQztnQkFBUyxDQUFDO1lBQ1QsU0FBUyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3BCLFlBQVksQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ25DLENBQUM7SUFDSCxDQUFDO0lBRU8sU0FBUyxDQUFDLE9BQXFDO1FBQ3JELE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMscUJBQXFCLENBQUMsQ0FBQztRQUNyRCxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQzlCLElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxDQUFDLENBQUM7WUFDM0IsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO1FBQ0QsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ3BELE1BQU0sUUFBUSxHQUFHLFFBQVEsQ0FBQyxVQUFVLEtBQUssSUFBSSxDQUFDLHFCQUFxQixDQUFDLFVBQVU7ZUFDekUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxlQUFlLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1FBQzFFLElBQUksQ0FBQyxRQUFRO1lBQUUsSUFBSSxDQUFDLGdCQUFnQixJQUFJLENBQUMsQ0FBQztRQUMxQyxPQUFPLFFBQVEsQ0FBQztJQUNsQixDQUFDO0lBRU8sK0JBQStCLENBQUMsUUFBcUM7UUFDM0UsUUFBUSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7WUFDdEIsVUFBVSxFQUFFLE9BQU87WUFDbkIsZ0JBQWdCLEVBQUUsR0FBRztZQUNyQixvQkFBb0IsRUFBRSwrQkFBK0I7U0FDdEQsQ0FBQyxDQUFDO1FBQ0gsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQ2pCLENBQUM7SUFFTyxlQUFlLENBQUMsUUFBcUMsRUFBRSxNQUFjO1FBQzNFLFFBQVEsQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLEVBQUUsVUFBVSxFQUFFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQzNFLFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUNqQixDQUFDO0lBRU8sZUFBZSxDQUNyQixNQUE2QixFQUM3QixNQUFpQixFQUNqQixZQUFxQjtRQUVyQixJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ3JCLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNqQixPQUFPO1FBQ1QsQ0FBQztRQUNELE1BQU0sVUFBVSxHQUFHLE1BQU0sS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLCtCQUErQixDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUM7UUFDcEYsTUFBTSxTQUFTLEdBQUcsWUFBWTtZQUM1QixDQUFDLENBQUMsdURBQXVEO1lBQ3pELENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDUCxNQUFNLENBQUMsR0FBRyxDQUNSLFlBQVksTUFBTSxJQUFJLFVBQVUsT0FBTyxTQUFTLGdEQUFnRCxDQUNqRyxDQUFDO0lBQ0osQ0FBQztJQUVPLGVBQWUsQ0FDckIsT0FBeUM7UUFFekMsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLEdBQUcsQ0FDOUIsQ0FBQyxPQUFPLE9BQU8sQ0FBQyxVQUFVLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7YUFDL0QsS0FBSyxDQUFDLEdBQUcsQ0FBQzthQUNWLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDO2FBQzFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FDbkIsQ0FBQztRQUNGLE1BQU0sTUFBTSxHQUFxQyxFQUFFLENBQUM7UUFDcEQsS0FBSyxNQUFNLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNwRCxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDMUMsSUFBSSxlQUFlLENBQUMsR0FBRyxDQUFDLGNBQWMsQ0FBQyxJQUFJLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUM7Z0JBQUUsU0FBUztZQUMxRixNQUFNLENBQUMsY0FBYyxDQUFDLEdBQUcsS0FBSyxDQUFDO1FBQ2pDLENBQUM7UUFDRCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRU8sS0FBSyxDQUFDLHFCQUFxQixDQUNqQyxNQUEwQixFQUMxQixPQUFnQixFQUNoQixNQUFtQjtRQUVuQixJQUFJLENBQUMsTUFBTSxJQUFJLE9BQU8sQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsR0FBRyxJQUFJLEVBQUUsQ0FBQztZQUNoRSxNQUFNLElBQUksbUJBQW1CLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDakQsQ0FBQztRQUNELElBQUksTUFBVyxDQUFDO1FBQ2hCLElBQUksQ0FBQztZQUNILE1BQU0sR0FBRyxJQUFJLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMzQixDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsTUFBTSxJQUFJLG1CQUFtQixDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ2pELENBQUM7UUFDRCxNQUFNLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQ2xGLElBQ0UsQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQztlQUNuQyxNQUFNLENBQUMsUUFBUTtlQUNmLE1BQU0sQ0FBQyxRQUFRO2VBQ2YsTUFBTSxDQUFDLElBQUksRUFDZCxDQUFDO1lBQ0QsTUFBTSxJQUFJLG1CQUFtQixDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ2pELENBQUM7UUFDRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzVELE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxJQUFJO1lBQ3RCLENBQUMsQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxhQUFhLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQztZQUMvRCxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ1AsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDaEUsT0FBTztZQUNMLEdBQUcsUUFBUTtZQUNYLElBQUksRUFBRSxHQUFHLE1BQU0sQ0FBQyxRQUFRLElBQUksR0FBRyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEVBQUU7WUFDakQsVUFBVSxFQUFFLE1BQU0sQ0FBQyxJQUFJO1NBQ3hCLENBQUM7SUFDSixDQUFDO0lBRU8sS0FBSyxDQUFDLGdCQUFnQixDQUM1QixZQUFnQyxFQUNoQyxNQUFtQjtRQUVuQixJQUNFLENBQUMsWUFBWTtlQUNWLFlBQVksQ0FBQyxNQUFNLEdBQUcsR0FBRztlQUN6QixTQUFTLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxFQUMvQixDQUFDO1lBQ0QsTUFBTSxJQUFJLG1CQUFtQixDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ2pELENBQUM7UUFDRCxJQUFJLGFBQXFCLENBQUM7UUFDMUIsSUFBSSxTQUFpQixDQUFDO1FBQ3RCLElBQUksWUFBWSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ2pDLE1BQU0sY0FBYyxHQUFHLFlBQVksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDakQsSUFBSSxjQUFjLEdBQUcsQ0FBQyxJQUFJLFlBQVksQ0FBQyxjQUFjLEdBQUcsQ0FBQyxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUM7Z0JBQ25FLE1BQU0sSUFBSSxtQkFBbUIsQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUNqRCxDQUFDO1lBQ0QsYUFBYSxHQUFHLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLGNBQWMsQ0FBQyxDQUFDO1lBQ3RELFNBQVMsR0FBRyxZQUFZLENBQUMsS0FBSyxDQUFDLGNBQWMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNyRCxDQUFDO2FBQU0sQ0FBQztZQUNOLE1BQU0sU0FBUyxHQUFHLFlBQVksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDaEQsSUFBSSxTQUFTLEdBQUcsQ0FBQyxJQUFJLFlBQVksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQzdELE1BQU0sSUFBSSxtQkFBbUIsQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUNqRCxDQUFDO1lBQ0QsYUFBYSxHQUFHLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBQ2pELFNBQVMsR0FBRyxZQUFZLENBQUMsS0FBSyxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNoRCxDQUFDO1FBQ0QsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO1lBQUUsTUFBTSxJQUFJLG1CQUFtQixDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ2pGLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUMxRCxNQUFNLElBQUksR0FBRyxlQUFlLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxFQUFFLGFBQWEsRUFBRSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDekUsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDaEUsT0FBTyxFQUFFLEdBQUcsUUFBUSxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxDQUFDO0lBQzdELENBQUM7SUFFTyxvQkFBb0IsQ0FBQyxXQUFtQjtRQUM5QyxNQUFNLFdBQVcsR0FBRyxXQUFXLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxJQUFJLFdBQVcsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDO1lBQzFFLENBQUMsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztZQUMxQixDQUFDLENBQUMsV0FBVyxDQUFDO1FBQ2hCLElBQUksQ0FBQyxXQUFXLElBQUksV0FBVyxDQUFDLE1BQU0sR0FBRyxHQUFHLElBQUksV0FBVyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQzFFLE1BQU0sSUFBSSxtQkFBbUIsQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUNqRCxDQUFDO1FBQ0QsSUFBSSxPQUFPLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO1lBQ3hDLE9BQU8sT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztRQUNoRSxDQUFDO1FBQ0QsTUFBTSxrQkFBa0IsR0FBRyxXQUFXLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUM7UUFDOUYsTUFBTSxLQUFLLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUMxRSxJQUNFLENBQUMsS0FBSztlQUNILEtBQUssQ0FBQyxNQUFNLEdBQUcsR0FBRztlQUNsQixDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDO2VBQ3BCLEtBQUssQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUNsQyxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUM7bUJBQ2IsS0FBSyxDQUFDLE1BQU0sR0FBRyxFQUFFO21CQUNqQixDQUFDLG1DQUFtQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FDcEQsQ0FBQyxFQUNGLENBQUM7WUFDRCxNQUFNLElBQUksbUJBQW1CLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDakQsQ0FBQztRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVPLEtBQUssQ0FBQyxXQUFXLENBQ3ZCLFFBQWdCLEVBQ2hCLElBQVksRUFDWixNQUFtQjtRQUVuQixJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUNqQyxNQUFNLElBQUksbUJBQW1CLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDakQsQ0FBQztRQUNELE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQztZQUM5QyxDQUFDLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLElBQUksRUFBRSxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUMzRixDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUNsQixJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUM5RCxNQUFNLENBQ1AsQ0FBQztRQUNOLE1BQU0sQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxPQUFPLENBQUMsTUFBTSxHQUFHLEVBQUUsRUFBRSxDQUFDO1lBQ3pFLE1BQU0sSUFBSSxtQkFBbUIsQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUNqRCxDQUFDO1FBQ0QsTUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQ3ZDLElBQ0UsQ0FBQyxNQUFNO21CQUNKLENBQUMsTUFBTSxDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxDQUFDLENBQUM7bUJBQzVDLE9BQU8sTUFBTSxDQUFDLE9BQU8sS0FBSyxRQUFRO21CQUNsQyxNQUFNLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUM7bUJBQzVCLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxFQUMxQyxDQUFDO2dCQUNELE1BQU0sSUFBSSxtQkFBbUIsQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUNqRCxDQUFDO1lBQ0QsTUFBTSxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3BELElBQ0UsQ0FDRSxNQUFNLENBQUMsSUFBSSxFQUFFLEtBQUssTUFBTTttQkFDcEIsTUFBOEIsQ0FBQyxtQkFBbUIsRUFBRSxDQUN6RDttQkFDRSxNQUFNLENBQUMsS0FBSyxFQUFFLEtBQUssU0FBUzttQkFDNUIsQ0FDRCxNQUFNLENBQUMsSUFBSSxFQUFFLEtBQUssTUFBTTt1QkFDckIsQ0FBRSxNQUE4QixDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FDN0UsRUFDRCxDQUFDO2dCQUNELE1BQU0sSUFBSSxtQkFBbUIsQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUNqRCxDQUFDO1lBQ0QsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLElBQUksRUFBRSxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDaEQsSUFBSSxNQUFNLEtBQUssTUFBTSxDQUFDLE1BQU07Z0JBQUUsTUFBTSxJQUFJLG1CQUFtQixDQUFDLGVBQWUsQ0FBQyxDQUFDO1lBQzdFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxDQUFDLGtCQUFrQixFQUFFLEVBQUUsTUFBTSxFQUFXLENBQUM7UUFDbkUsQ0FBQyxDQUFDLENBQUM7UUFDSCxPQUFPLEVBQUUsR0FBRyxTQUFTLENBQUMsQ0FBQyxDQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDO0lBQzlDLENBQUM7SUFFTyxZQUFZLENBQ2xCLE1BQW9ELEVBQ3BELE1BQW1CO1FBRW5CLE1BQU0sT0FBTyxHQUFvQztZQUMvQyxPQUFPLEVBQUUsTUFBTSxDQUFDLE9BQU87WUFDdkIsTUFBTSxFQUFFLE1BQU0sQ0FBQyxNQUFNO1lBQ3JCLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSTtZQUNqQixRQUFRLEVBQUUsTUFBTSxDQUFDLFFBQVE7WUFDekIsTUFBTTtTQUNQLENBQUM7UUFDRixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxDQUFDLE1BQU0sWUFBWSxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDNUMsTUFBTSxJQUFJLG1CQUFtQixDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQ2pELENBQUM7UUFDRCxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNqQyxNQUFNLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUMzQyxNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDOUQsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUNoRSxJQUFJLE1BQU0sQ0FBQyxPQUFPO1lBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7O1lBQzdDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUMzRixPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRU8sS0FBSyxDQUFDLGNBQWMsQ0FBQyxNQUEwQixFQUFFLE1BQW1CO1FBQzFFLElBQ0UsQ0FBQyxNQUFNLENBQUMsVUFBVTtlQUNmLENBQUMsTUFBTSxDQUFDLE9BQU87ZUFDZixDQUFDLE1BQU0sQ0FBQyxTQUFTO2VBQ2pCLE1BQU0sQ0FBQyxhQUFhO1lBQ3ZCLE9BQU87UUFDVCxJQUFJLENBQUMsTUFBTSxDQUFDLFVBQVUsSUFBSSxNQUFNLENBQUMsU0FBUztZQUFFLE1BQU0sSUFBSSxtQkFBbUIsQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUMzRixNQUFNLElBQUksT0FBTyxDQUFPLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQzFDLE1BQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQyxHQUFHLEVBQUU7Z0JBQzVCLE9BQU8sRUFBRSxDQUFDO2dCQUNWLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDakIsTUFBTSxDQUFDLElBQUksbUJBQW1CLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztZQUM3QyxDQUFDLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7WUFDMUIsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ2QsTUFBTSxPQUFPLEdBQUcsR0FBUyxFQUFFO2dCQUN6QixZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ3BCLE1BQU0sQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDO2dCQUNqQyxNQUFNLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFDN0IsTUFBTSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7Z0JBQzdCLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDL0MsQ0FBQyxDQUFDO1lBQ0YsTUFBTSxTQUFTLEdBQUcsR0FBUyxFQUFFO2dCQUMzQixPQUFPLEVBQUUsQ0FBQztnQkFDVixPQUFPLEVBQUUsQ0FBQztZQUNaLENBQUMsQ0FBQztZQUNGLE1BQU0sT0FBTyxHQUFHLEdBQVMsRUFBRTtnQkFDekIsT0FBTyxFQUFFLENBQUM7Z0JBQ1YsTUFBTSxDQUFDLElBQUksbUJBQW1CLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQztZQUNuRCxDQUFDLENBQUM7WUFDRixNQUFNLE9BQU8sR0FBRyxHQUFTLEVBQUU7Z0JBQ3pCLE9BQU8sRUFBRSxDQUFDO2dCQUNWLE1BQU0sQ0FBQyxJQUFJLG1CQUFtQixDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUM7WUFDbkQsQ0FBQyxDQUFDO1lBQ0YsTUFBTSxPQUFPLEdBQUcsR0FBUyxFQUFFO2dCQUN6QixPQUFPLEVBQUUsQ0FBQztnQkFDVixNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDOUIsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN4QixDQUFDLENBQUM7WUFDRixNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FBQztZQUNsQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztZQUM5QixNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztZQUM5QixNQUFNLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzVELENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVPLEtBQUssQ0FBQyxVQUFVLENBQ3RCLFlBQW1DLEVBQ25DLFFBQTRCLEVBQzVCLE9BQWlFLEVBQ2pFLE1BQW1CO1FBRW5CLElBQUksV0FBVyxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsVUFBVSxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUMsVUFBVSxDQUFDO1FBQzlFLElBQUksV0FBVyxHQUFHLElBQUksQ0FBQyxjQUFjO1lBQUUsTUFBTSxJQUFJLG1CQUFtQixDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDdkYsTUFBTSxhQUFhLEdBQUcsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUNwQyxZQUFZLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDdkIsUUFBUSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ3JCLENBQUMsRUFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUMxQixhQUFhLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDdEIsTUFBTSxLQUFLLEdBQUcsQ0FBQyxLQUFxQixFQUFRLEVBQUU7WUFDNUMsV0FBVyxJQUFJLEtBQUssQ0FBQyxVQUFVLENBQUM7WUFDaEMsSUFBSSxXQUFXLEdBQUcsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUN0QyxZQUFZLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ3ZCLFFBQVEsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNyQixDQUFDO1FBQ0gsQ0FBQyxDQUFDO1FBQ0YsWUFBWSxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDL0IsUUFBUSxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDM0IsTUFBTSxPQUFPLEdBQUcsR0FBUyxFQUFFO1lBQ3pCLFlBQVksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3BDLFFBQVEsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ2xDLENBQUMsQ0FBQztRQUNGLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLEVBQUUsT0FBTyxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7UUFDMUQsSUFBSSxPQUFPLENBQUMsVUFBVSxDQUFDLFVBQVUsR0FBRyxDQUFDO1lBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDMUUsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLFVBQVUsR0FBRyxDQUFDO1lBQUUsWUFBWSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDMUUsWUFBWSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM1QixRQUFRLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBQzVCLFlBQVksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUN0QixNQUFNLE9BQU8sQ0FBQyxJQUFJLENBQUM7WUFDakIsSUFBSSxPQUFPLENBQU8sQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1lBQ25FLElBQUksT0FBTyxDQUFPLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztTQUNoRSxDQUFDLENBQUM7UUFDSCxZQUFZLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDNUIsWUFBWSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDaEMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDNUIsTUFBTSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztRQUM3QyxZQUFZLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDdkIsUUFBUSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ3JCLENBQUM7SUFFTyxLQUFLLENBQUMsc0JBQXNCLENBQ2xDLFFBQTRCLEVBQzVCLE1BQW1CLEVBQ25CLGNBQXNCO1FBRXRCLE1BQU0sSUFBSSxHQUFHLE1BQU0sSUFBSSxPQUFPLENBQWlCLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ2pFLElBQUksUUFBUSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3ZDLE1BQU0sT0FBTyxHQUFHLEdBQVMsRUFBRTtnQkFDekIsUUFBUSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQzdCLFFBQVEsQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO2dCQUMvQixRQUFRLENBQUMsR0FBRyxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFDL0IsTUFBTSxDQUFDLG1CQUFtQixDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQztZQUMvQyxDQUFDLENBQUM7WUFDRixNQUFNLE1BQU0sR0FBRyxDQUFDLEtBQXFCLEVBQVEsRUFBRTtnQkFDN0MsUUFBUSxHQUFHLE9BQU8sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7Z0JBQ3BELE1BQU0sUUFBUSxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7Z0JBQzlDLElBQUksUUFBUSxHQUFHLENBQUMsSUFBSSxRQUFRLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztvQkFDOUQsT0FBTyxFQUFFLENBQUM7b0JBQ1YsTUFBTSxDQUFDLElBQUksbUJBQW1CLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDO29CQUNsRCxPQUFPO2dCQUNULENBQUM7Z0JBQ0QsSUFBSSxRQUFRLEdBQUcsQ0FBQztvQkFBRSxPQUFPO2dCQUN6QixJQUFJLFFBQVEsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO29CQUN2QyxPQUFPLEVBQUUsQ0FBQztvQkFDVixNQUFNLENBQUMsSUFBSSxtQkFBbUIsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUM7b0JBQ2xELE9BQU87Z0JBQ1QsQ0FBQztnQkFDRCxPQUFPLEVBQUUsQ0FBQztnQkFDVixPQUFPLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDcEIsQ0FBQyxDQUFDO1lBQ0YsTUFBTSxPQUFPLEdBQUcsR0FBUyxFQUFFO2dCQUN6QixPQUFPLEVBQUUsQ0FBQztnQkFDVixNQUFNLENBQUMsSUFBSSxtQkFBbUIsQ0FBQyxlQUFlLENBQUMsQ0FBQyxDQUFDO1lBQ25ELENBQUMsQ0FBQztZQUNGLE1BQU0sT0FBTyxHQUFHLEdBQVMsRUFBRTtnQkFDekIsT0FBTyxFQUFFLENBQUM7Z0JBQ1YsTUFBTSxDQUFDLElBQUksbUJBQW1CLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQztZQUNuRCxDQUFDLENBQUM7WUFDRixNQUFNLE9BQU8sR0FBRyxHQUFTLEVBQUU7Z0JBQ3pCLE9BQU8sRUFBRSxDQUFDO2dCQUNWLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDeEIsQ0FBQyxDQUFDO1lBQ0YsUUFBUSxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDNUIsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDaEMsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDaEMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUM1RCxDQUFDLENBQUMsQ0FBQztRQUNILE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDMUMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsUUFBUSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQzlDLE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDakYsSUFBSSxDQUFDLDJCQUEyQixDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1lBQ2xELE1BQU0sSUFBSSxtQkFBbUIsQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUNqRCxDQUFDO1FBQ0QsTUFBTSxXQUFXLEdBQUcsTUFBTSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3pFLE1BQU0sT0FBTyxHQUFHLElBQUksR0FBRyxFQUFvQixDQUFDO1FBQzVDLEtBQUssTUFBTSxVQUFVLElBQUksV0FBVyxFQUFFLENBQUM7WUFDckMsTUFBTSxTQUFTLEdBQUcsVUFBVSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUMxQyxJQUFJLFNBQVMsR0FBRyxDQUFDO2dCQUFFLE1BQU0sSUFBSSxtQkFBbUIsQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUNsRSxNQUFNLElBQUksR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNqRSxNQUFNLEtBQUssR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLFNBQVMsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNyRCxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUN2QyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ25CLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQzVCLENBQUM7UUFDRCxNQUFNLGdCQUFnQixHQUFHLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLENBQUM7YUFDdkQsT0FBTyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2FBQ3BDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7UUFDOUMsSUFDRSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUM7ZUFDbEMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsRUFBRSxNQUFNLEtBQUssQ0FBQztlQUNwQyxPQUFPLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsV0FBVyxFQUFFLEtBQUssV0FBVztlQUMxRCxPQUFPLENBQUMsR0FBRyxDQUFDLHNCQUFzQixDQUFDLEVBQUUsTUFBTSxLQUFLLENBQUM7ZUFDakQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxzQkFBc0IsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssY0FBYztZQUM5RCxNQUFNLElBQUksbUJBQW1CLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDakQsT0FBTyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUM1RCxDQUFDO0lBRU8scUJBQXFCO1FBSzNCLE1BQU0sVUFBVSxHQUFHLElBQUksZUFBZSxFQUFFLENBQUM7UUFDekMsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLGVBQWUsRUFBRSxDQUFDO1FBQ2hELE1BQU0sT0FBTyxHQUFHLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDOUIsaUJBQWlCLENBQUMsS0FBSyxDQUFDLElBQUksbUJBQW1CLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztRQUM5RCxDQUFDLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFDMUIsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ2hCLE9BQU87WUFDTCxVQUFVO1lBQ1YsTUFBTSxFQUFFLFdBQVcsQ0FBQyxHQUFHLENBQUM7Z0JBQ3RCLFVBQVUsQ0FBQyxNQUFNO2dCQUNqQixpQkFBaUIsQ0FBQyxNQUFNO2dCQUN4QixJQUFJLENBQUMsbUJBQW1CLENBQUMsTUFBTTthQUNoQyxDQUFDO1lBQ0YsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLFlBQVksQ0FBQyxPQUFPLENBQUM7U0FDckMsQ0FBQztJQUNKLENBQUM7SUFFTyxLQUFLLENBQUMsU0FBUyxDQUFJLE9BQW1CLEVBQUUsTUFBbUI7UUFDakUsTUFBTSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3hCLElBQUksT0FBb0IsQ0FBQztRQUN6QixNQUFNLE9BQU8sR0FBRyxJQUFJLE9BQU8sQ0FBUSxDQUFDLFFBQVEsRUFBRSxNQUFNLEVBQUUsRUFBRTtZQUN0RCxPQUFPLEdBQUcsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN0QyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzVELENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDO1lBQ0gsT0FBTyxNQUFNLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUNoRCxDQUFDO2dCQUFTLENBQUM7WUFDVCxNQUFNLENBQUMsbUJBQW1CLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQy9DLENBQUM7SUFDSCxDQUFDO0lBRU8sS0FBSyxDQUFDLHlCQUF5QixDQUFDLFFBQXFDO1FBQzNFLElBQUksUUFBUSxDQUFDLGdCQUFnQixJQUFJLFFBQVEsQ0FBQyxTQUFTO1lBQUUsT0FBTztRQUM1RCxNQUFNLElBQUksT0FBTyxDQUFPLENBQUMsT0FBTyxFQUFFLEVBQUU7WUFDbEMsTUFBTSxNQUFNLEdBQUcsR0FBUyxFQUFFO2dCQUN4QixRQUFRLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztnQkFDL0IsUUFBUSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7Z0JBQzlCLE9BQU8sRUFBRSxDQUFDO1lBQ1osQ0FBQyxDQUFDO1lBQ0YsUUFBUSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDaEMsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDakMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0YifQ==