@push.rocks/smartjmap 1.0.0 → 2.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.
@@ -1,4 +1,86 @@
1
1
  import * as plugins from './smartjmap.plugins.js';
2
+ import { JMAP_CORE_CAPABILITY, JMAP_MAIL_CAPABILITY, JMAP_SUBMISSION_CAPABILITY, } from './classes.jmapclient.js';
3
+ import {} from './interfaces.backend.js';
4
+ import { MemoryMailBackend } from './classes.memorymailbackend.js';
5
+ /** The advertised — and enforced — RFC 8620 core limits. */
6
+ export const JMAP_SERVER_LIMITS = {
7
+ maxSizeUpload: 50_000_000,
8
+ maxConcurrentUpload: 4,
9
+ maxSizeRequest: 10_000_000,
10
+ maxConcurrentRequests: 4,
11
+ maxCallsInRequest: 16,
12
+ maxObjectsInGet: 500,
13
+ maxObjectsInSet: 500,
14
+ };
15
+ /** The session object never changes at runtime, so its state is constant. */
16
+ const SESSION_STATE = '0';
17
+ /** Default Email/get properties per RFC 8621 §4.2. */
18
+ const DEFAULT_EMAIL_PROPERTIES = [
19
+ 'id',
20
+ 'blobId',
21
+ 'threadId',
22
+ 'mailboxIds',
23
+ 'keywords',
24
+ 'size',
25
+ 'receivedAt',
26
+ 'messageId',
27
+ 'inReplyTo',
28
+ 'references',
29
+ 'sender',
30
+ 'from',
31
+ 'to',
32
+ 'cc',
33
+ 'bcc',
34
+ 'replyTo',
35
+ 'subject',
36
+ 'sentAt',
37
+ 'hasAttachment',
38
+ 'preview',
39
+ 'bodyValues',
40
+ 'textBody',
41
+ 'htmlBody',
42
+ 'attachments',
43
+ ];
44
+ const KNOWN_EMAIL_PROPERTIES = new Set(DEFAULT_EMAIL_PROPERTIES);
45
+ const MAILBOX_PROPERTIES = [
46
+ 'id',
47
+ 'name',
48
+ 'parentId',
49
+ 'role',
50
+ 'sortOrder',
51
+ 'totalEmails',
52
+ 'unreadEmails',
53
+ 'totalThreads',
54
+ 'unreadThreads',
55
+ 'myRights',
56
+ 'isSubscribed',
57
+ ];
58
+ const KNOWN_MAILBOX_PROPERTIES = new Set(MAILBOX_PROPERTIES);
59
+ const SUPPORTED_EMAIL_FILTER_KEYS = new Set([
60
+ 'inMailbox',
61
+ 'text',
62
+ 'subject',
63
+ 'from',
64
+ 'to',
65
+ 'before',
66
+ 'after',
67
+ 'hasKeyword',
68
+ 'notKeyword',
69
+ ]);
70
+ const DEFAULT_MAILBOX_RIGHTS = {
71
+ mayReadItems: true,
72
+ mayAddItems: true,
73
+ mayRemoveItems: true,
74
+ maySetSeen: true,
75
+ maySetKeywords: true,
76
+ mayCreateChild: true,
77
+ mayRename: true,
78
+ mayDelete: true,
79
+ maySubmit: true,
80
+ };
81
+ const textEncoder = new TextEncoder();
82
+ /** Ensures bytes are backed by a plain ArrayBuffer so they satisfy BodyInit. */
83
+ const asBodyBytes = (data) => data.buffer instanceof ArrayBuffer ? data : new Uint8Array(data);
2
84
  /** Error type used inside method dispatch; rendered as a JMAP `error` method response. */
3
85
  class JmapServerMethodError extends Error {
4
86
  constructor(type, description) {
@@ -6,238 +88,207 @@ class JmapServerMethodError extends Error {
6
88
  this.type = type;
7
89
  }
8
90
  }
91
+ /** UTF-8-safe truncation: cuts at a codepoint boundary at or below maxBytes. */
92
+ const truncateUtf8 = (value, maxBytes) => {
93
+ const bytes = textEncoder.encode(value);
94
+ if (bytes.length <= maxBytes) {
95
+ return value;
96
+ }
97
+ let end = maxBytes;
98
+ while (end > 0 && (bytes[end] & 0b1100_0000) === 0b1000_0000) {
99
+ end--;
100
+ }
101
+ return new TextDecoder().decode(bytes.subarray(0, end));
102
+ };
9
103
  /**
10
- * A minimal in-memory JMAP server (RFC 8620 core + RFC 8621 mail subset)
11
- * for offline testing. Serves the session resource at /.well-known/jmap and
12
- * /jmap/session, the API at /jmap/api, blob downloads at /jmap/download/...,
13
- * and StateChange pushes via SSE at /jmap/eventsource.
104
+ * Evaluates an RFC 6901 JSON pointer with the RFC 8620 §3.7 extension: a `*`
105
+ * token applied to an array maps the rest of the pointer over every item,
106
+ * flattening one array level. Throws on any unresolvable path.
107
+ */
108
+ const evalJsonPointer = (root, pointer) => {
109
+ if (pointer === '') {
110
+ return root;
111
+ }
112
+ if (!pointer.startsWith('/')) {
113
+ throw new Error(`Invalid JSON pointer "${pointer}".`);
114
+ }
115
+ const tokens = pointer.slice(1).split('/');
116
+ const evaluate = (value, index) => {
117
+ if (index === tokens.length) {
118
+ return value;
119
+ }
120
+ const token = tokens[index].replaceAll('~1', '/').replaceAll('~0', '~');
121
+ if (Array.isArray(value)) {
122
+ if (token === '*') {
123
+ const results = value.map((item) => evaluate(item, index + 1));
124
+ return results.some((result) => Array.isArray(result))
125
+ ? results.flatMap((result) => (Array.isArray(result) ? result : [result]))
126
+ : results;
127
+ }
128
+ const arrayIndex = Number(token);
129
+ if (!Number.isInteger(arrayIndex) || arrayIndex < 0 || arrayIndex >= value.length) {
130
+ throw new Error(`JSON pointer index "${token}" is out of range.`);
131
+ }
132
+ return evaluate(value[arrayIndex], index + 1);
133
+ }
134
+ if (value !== null && typeof value === 'object' && token in value) {
135
+ return evaluate(value[token], index + 1);
136
+ }
137
+ throw new Error(`JSON pointer token "${token}" does not resolve.`);
138
+ };
139
+ return evaluate(root, 0);
140
+ };
141
+ /**
142
+ * A JMAP server core (RFC 8620) with the RFC 8621 mail method surface,
143
+ * dispatching all storage into a pluggable `IJmapMailBackend`.
144
+ *
145
+ * The primary API is the web-standard `fetchHandler(request)` — mount it in
146
+ * any Request/Response runtime (Deno, Bun, service workers, Node ≥18). The
147
+ * `start(port)`/`stop()` pair wraps it in a node:http server for convenience.
148
+ *
149
+ * Endpoints: session (`/.well-known/jmap`, `/jmap/session`), API
150
+ * (`/jmap/api`), upload (`/jmap/upload/{accountId}`), download
151
+ * (`/jmap/download/{accountId}/{blobId}/{name}?type=`), and event source
152
+ * (`/jmap/eventsource` — SSE StateChange pushes per RFC 8620 §7.3).
153
+ *
154
+ * With no options this behaves as the offline test helper: an in-memory
155
+ * backend plus a static credential registry (`addUser`/`addBearerToken`).
14
156
  */
15
157
  export class JmapServer {
16
- constructor() {
17
- this.users = new Map();
158
+ constructor(options = {}) {
159
+ this.registry = new Map();
160
+ this.httpServer = null;
18
161
  this.sockets = new Set();
19
- this.eventStreams = new Map();
20
- this.server = plugins.http.createServer((req, res) => {
21
- this.handleRequest(req, res);
22
- });
23
- this.server.on('connection', (socket) => {
24
- this.sockets.add(socket);
25
- socket.on('close', () => {
26
- this.sockets.delete(socket);
27
- });
28
- });
162
+ this.eventStreams = new Set();
163
+ this.changeFeedUnsubscribe = null;
164
+ this.activeApiRequests = 0;
165
+ this.options = options;
166
+ this.backend = options.backend ?? new MemoryMailBackend();
29
167
  }
30
168
  // ======================
31
- // store management
169
+ // default auth registry
32
170
  // ======================
171
+ /**
172
+ * Registers Basic credentials in the default authenticator's registry.
173
+ * Only consulted when no custom `authenticate` option is set. Account data
174
+ * itself lives in the backend (the memory backend auto-creates accounts).
175
+ */
33
176
  addUser(username, password) {
34
- if (this.users.has(username)) {
177
+ if (this.registry.has(username)) {
35
178
  throw new Error(`User "${username}" already exists.`);
36
179
  }
37
- const email = username.includes('@') ? username : `${username}@example.com`;
38
- this.users.set(username, {
39
- username,
40
- password,
41
- bearerTokens: new Set(),
42
- accountId: `account_${username}`,
43
- mailboxes: new Map(),
44
- emails: new Map(),
45
- blobs: new Map(),
46
- submissions: new Map(),
47
- identities: [{ id: 'identity_1', name: username, email, mayDelete: false }],
48
- state: 0,
49
- changes: [],
50
- idCounter: 0,
51
- });
180
+ this.registry.set(username, { password, bearerTokens: new Set() });
52
181
  }
53
- /** Registers a valid Bearer token for a user. */
182
+ /** Registers a valid Bearer token for a user in the default authenticator. */
54
183
  addBearerToken(username, token) {
55
- const user = this.requireUser(username);
56
- user.bearerTokens.add(token);
57
- }
58
- createMailbox(username, name, role) {
59
- const user = this.requireUser(username);
60
- for (const mailbox of user.mailboxes.values()) {
61
- if (mailbox.name === name) {
62
- throw new Error(`Mailbox "${name}" already exists for user "${username}".`);
63
- }
64
- }
65
- const id = `mailbox_${++user.idCounter}`;
66
- user.mailboxes.set(id, {
67
- id,
68
- name,
69
- role: role ?? null,
70
- parentId: null,
71
- sortOrder: user.mailboxes.size,
72
- });
73
- return id;
74
- }
75
- /** Seeds an email into a user's mailbox; bumps state and pushes a StateChange. Returns the email id. */
76
- addEmail(username, mailboxName, input) {
77
- const user = this.requireUser(username);
78
- const mailbox = Array.from(user.mailboxes.values()).find((candidate) => candidate.name === mailboxName || candidate.role === mailboxName);
79
- if (!mailbox) {
80
- throw new Error(`Mailbox "${mailboxName}" does not exist for user "${username}".`);
81
- }
82
- const from = Array.isArray(input.from) ? input.from : [input.from];
83
- const to = Array.isArray(input.to) ? input.to : [input.to];
84
- const id = `email_${++user.idCounter}`;
85
- const receivedAt = input.receivedAt ?? new Date().toISOString();
86
- const textBody = input.textBody ?? '';
87
- // raw message blob for Email/get blobId + downloads
88
- const blobId = `blob_${id}`;
89
- const rawLines = [
90
- `From: ${from.map((address) => address.email).join(', ')}`,
91
- `To: ${to.map((address) => address.email).join(', ')}`,
92
- `Subject: ${input.subject ?? ''}`,
93
- `Date: ${receivedAt}`,
94
- '',
95
- textBody,
96
- ];
97
- user.blobs.set(blobId, {
98
- data: Buffer.from(rawLines.join('\r\n'), 'utf8'),
99
- type: 'message/rfc822',
100
- name: `${id}.eml`,
101
- });
102
- const bodyValues = {
103
- text: { value: textBody, isTruncated: false },
104
- };
105
- const textBodyParts = [{ partId: 'text', type: 'text/plain', size: textBody.length }];
106
- const htmlBodyParts = [];
107
- if (typeof input.htmlBody === 'string') {
108
- bodyValues.html = { value: input.htmlBody, isTruncated: false };
109
- htmlBodyParts.push({ partId: 'html', type: 'text/html', size: input.htmlBody.length });
110
- }
111
- const attachmentParts = [];
112
- for (const [index, attachment] of (input.attachments ?? []).entries()) {
113
- const attachmentBlobId = `blob_${id}_att${index + 1}`;
114
- const data = Buffer.from(attachment.content);
115
- user.blobs.set(attachmentBlobId, {
116
- data,
117
- type: attachment.type,
118
- name: attachment.name,
119
- });
120
- attachmentParts.push({
121
- partId: null,
122
- blobId: attachmentBlobId,
123
- name: attachment.name,
124
- type: attachment.type,
125
- size: data.length,
126
- disposition: 'attachment',
127
- });
184
+ const entry = this.registry.get(username);
185
+ if (!entry) {
186
+ throw new Error(`User "${username}" does not exist.`);
128
187
  }
129
- const email = {
130
- id,
131
- blobId,
132
- threadId: `thread_${id}`,
133
- mailboxIds: { [mailbox.id]: true },
134
- keywords: input.keywords ?? {},
135
- size: textBody.length,
136
- receivedAt,
137
- sentAt: receivedAt,
138
- subject: input.subject ?? null,
139
- from,
140
- to,
141
- cc: input.cc ?? null,
142
- bcc: input.bcc ?? null,
143
- replyTo: null,
144
- hasAttachment: attachmentParts.length > 0,
145
- preview: textBody.slice(0, 100),
146
- bodyValues,
147
- textBody: textBodyParts,
148
- htmlBody: htmlBodyParts,
149
- attachments: attachmentParts,
150
- };
151
- user.emails.set(id, email);
152
- this.bumpState(user, { created: [id] });
153
- return id;
188
+ entry.bearerTokens.add(token);
154
189
  }
155
190
  // ======================
156
- // lifecycle
191
+ // lifecycle (node wrapper)
157
192
  // ======================
158
- /** Starts the server. Resolves with the bound port (pass 0 for an ephemeral port). */
193
+ /** Starts a node:http server around fetchHandler. Resolves with the bound port (pass 0 for ephemeral). */
159
194
  start(port) {
195
+ if (this.httpServer) {
196
+ throw new Error('JmapServer is already started.');
197
+ }
198
+ const server = plugins.http.createServer((req, res) => {
199
+ void this.handleNodeRequest(req, res);
200
+ });
201
+ server.on('connection', (socket) => {
202
+ this.sockets.add(socket);
203
+ socket.on('close', () => {
204
+ this.sockets.delete(socket);
205
+ });
206
+ });
207
+ this.httpServer = server;
160
208
  return new Promise((resolve, reject) => {
161
- this.server.once('error', reject);
162
- this.server.listen(port, () => {
163
- const address = this.server.address();
209
+ server.once('error', reject);
210
+ server.listen(port, () => {
211
+ const address = server.address();
164
212
  const boundPort = typeof address === 'object' && address ? address.port : port;
165
213
  resolve(boundPort);
166
214
  });
167
215
  });
168
216
  }
169
- /** Stops the server, ending open event streams and destroying open connections. */
170
- stop() {
171
- for (const response of this.eventStreams.keys()) {
172
- try {
173
- response.end();
174
- }
175
- catch {
176
- // response already gone
177
- }
217
+ /**
218
+ * Stops the server: closes all event streams (clearing their ping timers
219
+ * and the backend change-feed subscription), destroys open connections,
220
+ * and closes the node listener when one was started.
221
+ */
222
+ async stop() {
223
+ for (const stream of Array.from(this.eventStreams)) {
224
+ this.closeStream(stream);
178
225
  }
179
- this.eventStreams.clear();
180
226
  for (const socket of this.sockets) {
181
227
  socket.destroy();
182
228
  }
183
229
  this.sockets.clear();
184
- return new Promise((resolve) => {
185
- this.server.close(() => {
186
- resolve();
230
+ const server = this.httpServer;
231
+ this.httpServer = null;
232
+ if (server) {
233
+ await new Promise((resolve) => {
234
+ server.close(() => {
235
+ resolve();
236
+ });
187
237
  });
188
- });
238
+ }
189
239
  }
190
240
  // ======================
191
- // http handling
241
+ // web-standard core
192
242
  // ======================
193
- handleRequest(req, res) {
243
+ /**
244
+ * Handles a JMAP request end to end and returns the Response. This is the
245
+ * runtime-agnostic core — mount it directly as a Deno/Bun fetch handler.
246
+ */
247
+ async fetchHandler(request) {
194
248
  try {
195
- const user = this.authenticate(req);
196
- if (!user) {
197
- res.writeHead(401, {
249
+ const principal = await this.authenticatePrincipal(request);
250
+ if (!principal) {
251
+ return this.problemResponse(401, 'about:blank', 'Authentication required', {
198
252
  'www-authenticate': 'Bearer realm="jmap", Basic realm="jmap"',
199
- 'content-type': 'application/problem+json',
200
253
  });
201
- res.end(JSON.stringify({ type: 'about:blank', status: 401, detail: 'Authentication required' }));
202
- return;
203
254
  }
204
- const url = new URL(req.url ?? '/', 'http://localhost');
255
+ const account = await this.backend.resolveAccount(principal);
256
+ if (!account) {
257
+ return this.problemResponse(403, 'about:blank', 'No account for this principal');
258
+ }
259
+ const url = new URL(request.url);
205
260
  const pathname = url.pathname;
206
- if (req.method === 'GET' && (pathname === '/.well-known/jmap' || pathname === '/jmap/session')) {
207
- this.handleSession(user, res);
208
- return;
261
+ const method = request.method.toUpperCase();
262
+ if (method === 'GET' && (pathname === '/.well-known/jmap' || pathname === '/jmap/session')) {
263
+ return this.handleSession(account, principal);
209
264
  }
210
- if (req.method === 'POST' && pathname === '/jmap/api') {
211
- let body = '';
212
- req.on('data', (chunk) => {
213
- body += chunk;
214
- });
215
- req.on('end', () => {
216
- this.handleApi(user, body, res);
217
- });
218
- return;
265
+ if (method === 'POST' && pathname === '/jmap/api') {
266
+ return this.handleApi(account, request);
219
267
  }
220
- if (req.method === 'GET' && pathname === '/jmap/eventsource') {
221
- this.handleEventSource(user, req, res);
222
- return;
268
+ if (method === 'POST' && pathname.startsWith('/jmap/upload/')) {
269
+ return this.handleUpload(account, pathname, request);
223
270
  }
224
- if (req.method === 'GET' && pathname.startsWith('/jmap/download/')) {
225
- this.handleDownload(user, pathname, url, res);
226
- return;
271
+ if (method === 'GET' && pathname.startsWith('/jmap/download/')) {
272
+ return this.handleDownload(account, pathname, url);
273
+ }
274
+ if (method === 'GET' && pathname === '/jmap/eventsource') {
275
+ return this.handleEventSource(account, url);
227
276
  }
228
- res.writeHead(404, { 'content-type': 'application/problem+json' });
229
- res.end(JSON.stringify({ type: 'about:blank', status: 404, detail: 'Not found' }));
277
+ return this.problemResponse(404, 'about:blank', 'Not found');
230
278
  }
231
279
  catch (error) {
232
280
  const message = error instanceof Error ? error.message : String(error);
233
- if (!res.headersSent) {
234
- res.writeHead(500, { 'content-type': 'application/problem+json' });
235
- }
236
- res.end(JSON.stringify({ type: 'about:blank', status: 500, detail: message }));
281
+ return this.problemResponse(500, 'about:blank', message);
237
282
  }
238
283
  }
239
- authenticate(req) {
240
- const header = req.headers.authorization;
284
+ // ======================
285
+ // authentication
286
+ // ======================
287
+ async authenticatePrincipal(request) {
288
+ if (this.options.authenticate) {
289
+ return this.options.authenticate(request);
290
+ }
291
+ const header = request.headers.get('authorization');
241
292
  if (!header) {
242
293
  return null;
243
294
  }
@@ -248,431 +299,669 @@ export class JmapServer {
248
299
  const scheme = header.slice(0, spaceIndex).toLowerCase();
249
300
  const value = header.slice(spaceIndex + 1).trim();
250
301
  if (scheme === 'bearer') {
251
- for (const user of this.users.values()) {
252
- if (user.bearerTokens.has(value)) {
253
- return user;
302
+ for (const [username, entry] of this.registry) {
303
+ if (entry.bearerTokens.has(value)) {
304
+ return { username };
254
305
  }
255
306
  }
256
307
  return null;
257
308
  }
258
309
  if (scheme === 'basic') {
259
- const decoded = Buffer.from(value, 'base64').toString('utf8');
310
+ let decoded;
311
+ try {
312
+ const binary = atob(value);
313
+ decoded = new TextDecoder().decode(Uint8Array.from(binary, (char) => char.charCodeAt(0)));
314
+ }
315
+ catch {
316
+ return null;
317
+ }
260
318
  const colonIndex = decoded.indexOf(':');
261
319
  if (colonIndex === -1) {
262
320
  return null;
263
321
  }
264
322
  const username = decoded.slice(0, colonIndex);
265
323
  const password = decoded.slice(colonIndex + 1);
266
- const user = this.users.get(username);
267
- if (user && user.password === password) {
268
- return user;
324
+ const entry = this.registry.get(username);
325
+ if (entry && entry.password === password) {
326
+ return { username };
269
327
  }
270
328
  return null;
271
329
  }
272
330
  return null;
273
331
  }
274
- handleSession(user, res) {
332
+ // ======================
333
+ // session
334
+ // ======================
335
+ handleSession(account, principal) {
275
336
  const session = {
276
337
  capabilities: {
277
- 'urn:ietf:params:jmap:core': {
278
- maxSizeUpload: 50_000_000,
279
- maxConcurrentUpload: 4,
280
- maxSizeRequest: 10_000_000,
281
- maxConcurrentRequests: 4,
282
- maxCallsInRequest: 16,
283
- maxObjectsInGet: 500,
284
- maxObjectsInSet: 500,
285
- collationAlgorithms: ['i;ascii-numeric', 'i;ascii-casemap'],
338
+ [JMAP_CORE_CAPABILITY]: {
339
+ ...JMAP_SERVER_LIMITS,
340
+ collationAlgorithms: ['i;ascii-casemap'],
286
341
  },
287
- 'urn:ietf:params:jmap:mail': {},
288
- 'urn:ietf:params:jmap:submission': {},
342
+ [JMAP_MAIL_CAPABILITY]: {},
343
+ [JMAP_SUBMISSION_CAPABILITY]: {},
289
344
  },
290
345
  accounts: {
291
- [user.accountId]: {
292
- name: user.username,
293
- isPersonal: true,
294
- isReadOnly: false,
346
+ [account.accountId]: {
347
+ name: account.name,
348
+ isPersonal: account.isPersonal ?? true,
349
+ isReadOnly: account.isReadOnly ?? false,
295
350
  accountCapabilities: {
296
- 'urn:ietf:params:jmap:mail': {},
297
- 'urn:ietf:params:jmap:submission': {},
351
+ [JMAP_MAIL_CAPABILITY]: {
352
+ maxMailboxesPerEmail: null,
353
+ maxMailboxDepth: null,
354
+ maxSizeMailboxName: 490,
355
+ maxSizeAttachmentsPerEmail: JMAP_SERVER_LIMITS.maxSizeUpload,
356
+ emailQuerySortOptions: ['receivedAt'],
357
+ mayCreateTopLevelMailbox: false,
358
+ },
359
+ [JMAP_SUBMISSION_CAPABILITY]: {
360
+ maxDelayedSend: 0,
361
+ submissionExtensions: {},
362
+ },
298
363
  },
299
364
  },
300
365
  },
301
366
  primaryAccounts: {
302
- 'urn:ietf:params:jmap:core': user.accountId,
303
- 'urn:ietf:params:jmap:mail': user.accountId,
304
- 'urn:ietf:params:jmap:submission': user.accountId,
367
+ [JMAP_CORE_CAPABILITY]: account.accountId,
368
+ [JMAP_MAIL_CAPABILITY]: account.accountId,
369
+ [JMAP_SUBMISSION_CAPABILITY]: account.accountId,
305
370
  },
306
- username: user.username,
307
- apiUrl: '/jmap/api',
308
- downloadUrl: '/jmap/download/{accountId}/{blobId}/{name}?type={type}',
309
- uploadUrl: '/jmap/upload/{accountId}',
310
- eventSourceUrl: '/jmap/eventsource?types={types}&closeafter={closeafter}&ping={ping}',
311
- state: String(user.state),
371
+ username: principal.username,
372
+ apiUrl: this.buildUrl('/jmap/api'),
373
+ downloadUrl: this.buildUrl('/jmap/download/{accountId}/{blobId}/{name}?type={type}'),
374
+ uploadUrl: this.buildUrl('/jmap/upload/{accountId}'),
375
+ eventSourceUrl: this.buildUrl('/jmap/eventsource?types={types}&closeafter={closeafter}&ping={ping}'),
376
+ state: SESSION_STATE,
312
377
  };
313
- res.writeHead(200, { 'content-type': 'application/json' });
314
- res.end(JSON.stringify(session));
378
+ return this.jsonResponse(200, session);
315
379
  }
316
- handleApi(user, body, res) {
317
- let parsed;
318
- try {
319
- parsed = JSON.parse(body);
320
- }
321
- catch {
322
- res.writeHead(400, { 'content-type': 'application/problem+json' });
323
- res.end(JSON.stringify({
324
- type: 'urn:ietf:params:jmap:error:notJSON',
325
- status: 400,
326
- detail: 'The request body is not valid JSON.',
327
- }));
328
- return;
329
- }
330
- if (!Array.isArray(parsed?.methodCalls)) {
331
- res.writeHead(400, { 'content-type': 'application/problem+json' });
332
- res.end(JSON.stringify({
333
- type: 'urn:ietf:params:jmap:error:notRequest',
334
- status: 400,
335
- detail: 'The request body is not a valid JMAP request object.',
336
- }));
337
- return;
380
+ buildUrl(path) {
381
+ const base = this.options.baseUrl;
382
+ return base ? `${base.replace(/\/+$/, '')}${path}` : path;
383
+ }
384
+ // ======================
385
+ // api endpoint
386
+ // ======================
387
+ async handleApi(account, request) {
388
+ if (this.activeApiRequests >= JMAP_SERVER_LIMITS.maxConcurrentRequests) {
389
+ return this.limitResponse(429, 'maxConcurrentRequests', 'Too many concurrent requests.');
338
390
  }
339
- const createdIds = new Map();
340
- const methodResponses = [];
341
- for (const call of parsed.methodCalls) {
342
- const [methodName, args, callId] = call;
391
+ this.activeApiRequests++;
392
+ try {
393
+ const bytes = new Uint8Array(await request.arrayBuffer());
394
+ if (bytes.length > JMAP_SERVER_LIMITS.maxSizeRequest) {
395
+ return this.limitResponse(400, 'maxSizeRequest', `The request is larger than ${JMAP_SERVER_LIMITS.maxSizeRequest} bytes.`);
396
+ }
397
+ let parsed;
343
398
  try {
344
- const result = this.dispatchMethod(user, methodName, args ?? {}, createdIds);
345
- methodResponses.push([methodName, result, callId]);
399
+ parsed = JSON.parse(new TextDecoder().decode(bytes));
346
400
  }
347
- catch (error) {
348
- if (error instanceof JmapServerMethodError) {
349
- methodResponses.push([
350
- 'error',
351
- { type: error.type, description: error.message },
352
- callId,
353
- ]);
401
+ catch {
402
+ return this.problemResponse(400, 'urn:ietf:params:jmap:error:notJSON', 'The request body is not valid JSON.');
403
+ }
404
+ if (!parsed ||
405
+ typeof parsed !== 'object' ||
406
+ !Array.isArray(parsed.using) ||
407
+ !Array.isArray(parsed.methodCalls)) {
408
+ return this.problemResponse(400, 'urn:ietf:params:jmap:error:notRequest', 'The request body is not a valid JMAP request object.');
409
+ }
410
+ const knownCapabilities = new Set([
411
+ JMAP_CORE_CAPABILITY,
412
+ JMAP_MAIL_CAPABILITY,
413
+ JMAP_SUBMISSION_CAPABILITY,
414
+ ]);
415
+ const using = new Set(parsed.using);
416
+ for (const capability of using) {
417
+ if (!knownCapabilities.has(capability)) {
418
+ return this.problemResponse(400, 'urn:ietf:params:jmap:error:unknownCapability', `The capability "${capability}" is not supported by this server.`);
419
+ }
420
+ }
421
+ if (parsed.methodCalls.length > JMAP_SERVER_LIMITS.maxCallsInRequest) {
422
+ return this.limitResponse(400, 'maxCallsInRequest', `The request has more than ${JMAP_SERVER_LIMITS.maxCallsInRequest} method calls.`);
423
+ }
424
+ const createdIds = new Map(Object.entries((parsed.createdIds ?? {})));
425
+ const methodResponses = [];
426
+ let mutated = false;
427
+ for (const call of parsed.methodCalls) {
428
+ if (!Array.isArray(call) || typeof call[0] !== 'string' || typeof call[2] !== 'string') {
429
+ return this.problemResponse(400, 'urn:ietf:params:jmap:error:notRequest', 'Each method call must be a [name, arguments, callId] tuple.');
430
+ }
431
+ const [methodName, rawArgs, callId] = call;
432
+ try {
433
+ const args = this.resolveBackReferences(rawArgs ?? {}, methodResponses);
434
+ const results = await this.dispatchMethod(account, methodName, args, using, createdIds);
435
+ for (const entry of results) {
436
+ methodResponses.push([entry.name, entry.result, callId]);
437
+ if (entry.mutated) {
438
+ mutated = true;
439
+ }
440
+ }
354
441
  }
355
- else {
356
- const message = error instanceof Error ? error.message : String(error);
357
- methodResponses.push(['error', { type: 'serverFail', description: message }, callId]);
442
+ catch (error) {
443
+ if (error instanceof JmapServerMethodError) {
444
+ methodResponses.push([
445
+ 'error',
446
+ { type: error.type, description: error.message },
447
+ callId,
448
+ ]);
449
+ }
450
+ else {
451
+ const message = error instanceof Error ? error.message : String(error);
452
+ methodResponses.push(['error', { type: 'serverFail', description: message }, callId]);
453
+ }
358
454
  }
359
455
  }
456
+ if (mutated) {
457
+ await this.pushAfterMutation(account);
458
+ }
459
+ const responseBody = {
460
+ methodResponses,
461
+ sessionState: SESSION_STATE,
462
+ };
463
+ if (parsed.createdIds !== undefined) {
464
+ responseBody.createdIds = Object.fromEntries(createdIds);
465
+ }
466
+ return this.jsonResponse(200, responseBody);
360
467
  }
361
- res.writeHead(200, { 'content-type': 'application/json' });
362
- res.end(JSON.stringify({ methodResponses, sessionState: String(user.state) }));
363
- }
364
- handleEventSource(user, req, res) {
365
- res.writeHead(200, {
366
- 'content-type': 'text/event-stream',
367
- 'cache-control': 'no-cache',
368
- connection: 'keep-alive',
369
- });
370
- res.write(': jmap event stream\n\n');
371
- this.eventStreams.set(res, user);
372
- req.on('close', () => {
373
- this.eventStreams.delete(res);
374
- });
375
- }
376
- handleDownload(user, pathname, url, res) {
377
- // /jmap/download/{accountId}/{blobId}/{name}
378
- const segments = pathname.split('/').filter((segment) => segment.length > 0);
379
- const accountId = decodeURIComponent(segments[2] ?? '');
380
- const blobId = decodeURIComponent(segments[3] ?? '');
381
- if (accountId !== user.accountId) {
382
- res.writeHead(404, { 'content-type': 'application/problem+json' });
383
- res.end(JSON.stringify({ type: 'about:blank', status: 404, detail: 'Unknown account' }));
384
- return;
468
+ finally {
469
+ this.activeApiRequests--;
385
470
  }
386
- const blob = user.blobs.get(blobId);
387
- if (!blob) {
388
- res.writeHead(404, { 'content-type': 'application/problem+json' });
389
- res.end(JSON.stringify({ type: 'about:blank', status: 404, detail: 'Unknown blob' }));
390
- return;
471
+ }
472
+ /**
473
+ * Resolves `#argument` ResultReference objects (RFC 8620 §3.7) against the
474
+ * responses of earlier method calls in the same request.
475
+ */
476
+ resolveBackReferences(args, priorResponses) {
477
+ const resolved = {};
478
+ for (const [key, value] of Object.entries(args)) {
479
+ if (!key.startsWith('#')) {
480
+ resolved[key] = value;
481
+ continue;
482
+ }
483
+ const name = key.slice(1);
484
+ if (name in args) {
485
+ throw new JmapServerMethodError('invalidArguments', `The arguments contain both "${name}" and "#${name}".`);
486
+ }
487
+ if (!value ||
488
+ typeof value !== 'object' ||
489
+ typeof value.resultOf !== 'string' ||
490
+ typeof value.name !== 'string' ||
491
+ typeof value.path !== 'string') {
492
+ throw new JmapServerMethodError('invalidResultReference', `"#${name}" is not a valid ResultReference object.`);
493
+ }
494
+ const source = priorResponses.find((entry) => entry[2] === value.resultOf && entry[0] === value.name);
495
+ if (!source) {
496
+ throw new JmapServerMethodError('invalidResultReference', `No response found for resultOf "${value.resultOf}" and name "${value.name}".`);
497
+ }
498
+ try {
499
+ resolved[name] = evalJsonPointer(source[1], value.path);
500
+ }
501
+ catch (error) {
502
+ throw new JmapServerMethodError('invalidResultReference', error instanceof Error ? error.message : String(error));
503
+ }
391
504
  }
392
- const type = url.searchParams.get('type') ?? blob.type;
393
- res.writeHead(200, { 'content-type': type, 'content-length': blob.data.length });
394
- res.end(blob.data);
505
+ return resolved;
395
506
  }
396
507
  // ======================
397
- // jmap method dispatch
508
+ // method dispatch
398
509
  // ======================
399
- dispatchMethod(user, methodName, args, createdIds) {
510
+ async dispatchMethod(account, methodName, args, using, createdIds) {
511
+ const requiredCapability = {
512
+ 'Core/echo': JMAP_CORE_CAPABILITY,
513
+ 'Mailbox/get': JMAP_MAIL_CAPABILITY,
514
+ 'Mailbox/query': JMAP_MAIL_CAPABILITY,
515
+ 'Mailbox/changes': JMAP_MAIL_CAPABILITY,
516
+ 'Thread/get': JMAP_MAIL_CAPABILITY,
517
+ 'Email/get': JMAP_MAIL_CAPABILITY,
518
+ 'Email/query': JMAP_MAIL_CAPABILITY,
519
+ 'Email/changes': JMAP_MAIL_CAPABILITY,
520
+ 'Email/queryChanges': JMAP_MAIL_CAPABILITY,
521
+ 'Email/set': JMAP_MAIL_CAPABILITY,
522
+ 'Identity/get': JMAP_SUBMISSION_CAPABILITY,
523
+ 'EmailSubmission/set': JMAP_SUBMISSION_CAPABILITY,
524
+ };
525
+ const capability = requiredCapability[methodName];
526
+ if (!capability) {
527
+ throw new JmapServerMethodError('unknownMethod', `Unknown method "${methodName}".`);
528
+ }
529
+ if (!using.has(capability)) {
530
+ throw new JmapServerMethodError('unknownMethod', `Method "${methodName}" requires the capability "${capability}" in "using".`);
531
+ }
532
+ if (methodName !== 'Core/echo') {
533
+ this.requireAccountId(account, args);
534
+ }
400
535
  switch (methodName) {
401
536
  case 'Core/echo':
402
- return args;
537
+ return [{ name: methodName, result: args }];
403
538
  case 'Mailbox/get':
404
- return this.methodMailboxGet(user, args);
539
+ return [{ name: methodName, result: await this.methodMailboxGet(account, args) }];
405
540
  case 'Mailbox/query':
406
- return this.methodMailboxQuery(user, args);
541
+ return [{ name: methodName, result: await this.methodMailboxQuery(account, args) }];
542
+ case 'Mailbox/changes':
543
+ return [{ name: methodName, result: await this.methodMailboxChanges(account, args) }];
544
+ case 'Thread/get':
545
+ return [{ name: methodName, result: await this.methodThreadGet(account, args) }];
407
546
  case 'Email/get':
408
- return this.methodEmailGet(user, args);
547
+ return [{ name: methodName, result: await this.methodEmailGet(account, args) }];
409
548
  case 'Email/query':
410
- return this.methodEmailQuery(user, args);
549
+ return [{ name: methodName, result: await this.methodEmailQuery(account, args) }];
411
550
  case 'Email/changes':
412
- return this.methodEmailChanges(user, args);
413
- case 'Email/set':
414
- return this.methodEmailSet(user, args, createdIds);
551
+ return [{ name: methodName, result: await this.methodEmailChanges(account, args) }];
552
+ case 'Email/queryChanges':
553
+ // Explicitly unsupported in phase 1: clients fall back to Email/query.
554
+ throw new JmapServerMethodError('cannotCalculateChanges', 'Email/queryChanges is not supported; re-run the query instead.');
555
+ case 'Email/set': {
556
+ const result = await this.methodEmailSet(account, args, createdIds);
557
+ return [{ name: methodName, result, mutated: result.newState !== result.oldState }];
558
+ }
415
559
  case 'Identity/get':
416
- return this.methodIdentityGet(user);
560
+ return [{ name: methodName, result: await this.methodIdentityGet(account, args) }];
417
561
  case 'EmailSubmission/set':
418
- return this.methodEmailSubmissionSet(user, args, createdIds);
562
+ return this.methodEmailSubmissionSet(account, args, createdIds);
419
563
  default:
420
564
  throw new JmapServerMethodError('unknownMethod', `Unknown method "${methodName}".`);
421
565
  }
422
566
  }
423
- methodMailboxGet(user, args) {
424
- const all = Array.from(user.mailboxes.values());
425
- let list;
426
- const notFound = [];
427
- if (args.ids == null) {
428
- list = all;
429
- }
430
- else {
431
- list = [];
432
- for (const id of args.ids) {
433
- const mailbox = user.mailboxes.get(id);
434
- if (mailbox) {
435
- list.push(mailbox);
436
- }
437
- else {
438
- notFound.push(id);
439
- }
567
+ requireAccountId(account, args) {
568
+ if (typeof args.accountId !== 'string') {
569
+ throw new JmapServerMethodError('invalidArguments', 'accountId is required.');
570
+ }
571
+ if (args.accountId !== account.accountId) {
572
+ throw new JmapServerMethodError('accountNotFound', `Account "${args.accountId}" is not accessible with these credentials.`);
573
+ }
574
+ }
575
+ // ======================
576
+ // mailbox methods
577
+ // ======================
578
+ async methodMailboxGet(account, args) {
579
+ let ids = null;
580
+ if (args.ids !== null && args.ids !== undefined) {
581
+ if (!Array.isArray(args.ids)) {
582
+ throw new JmapServerMethodError('invalidArguments', 'ids must be an array of ids or null.');
583
+ }
584
+ if (args.ids.length > JMAP_SERVER_LIMITS.maxObjectsInGet) {
585
+ throw new JmapServerMethodError('requestTooLarge', `ids exceeds maxObjectsInGet (${JMAP_SERVER_LIMITS.maxObjectsInGet}).`);
440
586
  }
587
+ ids = args.ids;
441
588
  }
442
- const augmented = list.map((mailbox) => {
443
- const emails = Array.from(user.emails.values()).filter((email) => email.mailboxIds?.[mailbox.id]);
444
- return {
589
+ const properties = this.validateProperties(args.properties, KNOWN_MAILBOX_PROPERTIES);
590
+ const result = await this.backend.getMailboxes(account.accountId, ids);
591
+ const list = result.list.map((mailbox) => {
592
+ const full = {
445
593
  ...mailbox,
446
- totalEmails: emails.length,
447
- unreadEmails: emails.filter((email) => !email.keywords?.$seen).length,
448
- totalThreads: emails.length,
449
- unreadThreads: emails.filter((email) => !email.keywords?.$seen).length,
450
- myRights: {
451
- mayReadItems: true,
452
- mayAddItems: true,
453
- mayRemoveItems: true,
454
- maySetSeen: true,
455
- maySetKeywords: true,
456
- mayCreateChild: true,
457
- mayRename: true,
458
- mayDelete: true,
459
- maySubmit: true,
460
- },
461
- isSubscribed: true,
594
+ isSubscribed: mailbox.isSubscribed ?? true,
595
+ myRights: mailbox.myRights ?? { ...DEFAULT_MAILBOX_RIGHTS },
462
596
  };
597
+ return this.projectObject(full, properties ?? MAILBOX_PROPERTIES);
463
598
  });
464
599
  return {
465
- accountId: user.accountId,
466
- state: String(user.state),
467
- list: augmented,
468
- notFound,
600
+ accountId: account.accountId,
601
+ state: result.state,
602
+ list,
603
+ notFound: result.notFound,
469
604
  };
470
605
  }
471
- methodMailboxQuery(user, args) {
472
- const filter = args.filter ?? {};
473
- let mailboxes = Array.from(user.mailboxes.values());
606
+ async methodMailboxQuery(account, args) {
607
+ const filter = (args.filter ?? {});
608
+ if ('operator' in filter) {
609
+ throw new JmapServerMethodError('unsupportedFilter', 'FilterOperator is not supported for Mailbox/query.');
610
+ }
611
+ for (const key of Object.keys(filter)) {
612
+ if (!['role', 'name', 'parentId'].includes(key)) {
613
+ throw new JmapServerMethodError('unsupportedFilter', `Mailbox filter condition "${key}" is not supported.`);
614
+ }
615
+ }
616
+ for (const comparator of (args.sort ?? [])) {
617
+ if (!['name', 'sortOrder'].includes(comparator.property)) {
618
+ throw new JmapServerMethodError('unsupportedSort', `Mailbox sort property "${comparator.property}" is not supported.`);
619
+ }
620
+ }
621
+ const result = await this.backend.getMailboxes(account.accountId, null);
622
+ let mailboxes = result.list;
474
623
  if (typeof filter.role === 'string') {
475
624
  mailboxes = mailboxes.filter((mailbox) => mailbox.role === filter.role);
476
625
  }
477
626
  if (typeof filter.name === 'string') {
478
627
  mailboxes = mailboxes.filter((mailbox) => mailbox.name === filter.name);
479
628
  }
480
- const ids = mailboxes.map((mailbox) => mailbox.id);
481
- return {
482
- accountId: user.accountId,
483
- queryState: String(user.state),
629
+ if ('parentId' in filter) {
630
+ mailboxes = mailboxes.filter((mailbox) => mailbox.parentId === filter.parentId);
631
+ }
632
+ const comparators = (args.sort ?? []);
633
+ if (comparators.length) {
634
+ mailboxes = [...mailboxes].sort((a, b) => {
635
+ for (const comparator of comparators) {
636
+ const direction = comparator.isAscending === false ? -1 : 1;
637
+ const property = comparator.property;
638
+ const left = a[property] ?? 0;
639
+ const right = b[property] ?? 0;
640
+ if (left < right) {
641
+ return -direction;
642
+ }
643
+ if (left > right) {
644
+ return direction;
645
+ }
646
+ }
647
+ return 0;
648
+ });
649
+ }
650
+ const position = this.validatePosition(args);
651
+ let ids = mailboxes.map((mailbox) => mailbox.id).slice(position);
652
+ if (typeof args.limit === 'number') {
653
+ ids = ids.slice(0, args.limit);
654
+ }
655
+ const response = {
656
+ accountId: account.accountId,
657
+ queryState: result.state,
484
658
  canCalculateChanges: false,
485
- position: 0,
659
+ position,
486
660
  ids,
487
- total: ids.length,
488
661
  };
662
+ if (args.calculateTotal === true) {
663
+ response.total = mailboxes.length;
664
+ }
665
+ return response;
489
666
  }
490
- methodEmailGet(user, args) {
667
+ async methodMailboxChanges(account, args) {
668
+ const { sinceState, maxChanges } = this.validateChangesArgs(args);
669
+ const changes = await this.backend.getMailboxChanges(account.accountId, sinceState, maxChanges);
670
+ if (!changes) {
671
+ throw new JmapServerMethodError('cannotCalculateChanges', `Cannot calculate mailbox changes since state "${sinceState}".`);
672
+ }
673
+ return { accountId: account.accountId, ...changes };
674
+ }
675
+ // ======================
676
+ // thread methods
677
+ // ======================
678
+ async methodThreadGet(account, args) {
491
679
  if (!Array.isArray(args.ids)) {
492
- throw new JmapServerMethodError('invalidArguments', 'Email/get requires an ids array.');
680
+ throw new JmapServerMethodError('invalidArguments', 'Thread/get requires an ids array.');
493
681
  }
494
- const list = [];
495
- const notFound = [];
496
- for (const id of args.ids) {
497
- const email = user.emails.get(id);
498
- if (email) {
499
- // Returned as a full superset of the requestable properties;
500
- // property projection is intentionally not implemented.
501
- list.push({ ...email });
502
- }
503
- else {
504
- notFound.push(id);
505
- }
682
+ if (args.ids.length > JMAP_SERVER_LIMITS.maxObjectsInGet) {
683
+ throw new JmapServerMethodError('requestTooLarge', `ids exceeds maxObjectsInGet (${JMAP_SERVER_LIMITS.maxObjectsInGet}).`);
506
684
  }
685
+ // Result-reference chains like Email/get -> /list/*/threadId commonly
686
+ // contain duplicates; deduplicate so each thread is returned once.
687
+ const ids = Array.from(new Set(args.ids));
688
+ const result = await this.backend.getThreads(account.accountId, ids);
507
689
  return {
508
- accountId: user.accountId,
509
- state: String(user.state),
510
- list,
511
- notFound,
690
+ accountId: account.accountId,
691
+ state: result.state,
692
+ list: result.list,
693
+ notFound: result.notFound,
512
694
  };
513
695
  }
514
- methodEmailQuery(user, args) {
515
- const filter = args.filter ?? {};
516
- let emails = Array.from(user.emails.values());
517
- if (typeof filter.inMailbox === 'string') {
518
- emails = emails.filter((email) => email.mailboxIds?.[filter.inMailbox]);
519
- }
520
- if (typeof filter.subject === 'string') {
521
- emails = emails.filter((email) => String(email.subject ?? '').toLowerCase().includes(filter.subject.toLowerCase()));
522
- }
523
- if (typeof filter.text === 'string') {
524
- const needle = filter.text.toLowerCase();
525
- emails = emails.filter((email) => String(email.subject ?? '').toLowerCase().includes(needle) ||
526
- String(email.bodyValues?.text?.value ?? '').toLowerCase().includes(needle));
527
- }
528
- const sort = Array.isArray(args.sort) && args.sort.length ? args.sort[0] : null;
529
- if (sort?.property === 'receivedAt') {
530
- emails.sort((a, b) => {
531
- const comparison = String(a.receivedAt ?? '').localeCompare(String(b.receivedAt ?? ''));
532
- return sort.isAscending === false ? -comparison : comparison;
533
- });
696
+ // ======================
697
+ // email methods
698
+ // ======================
699
+ async methodEmailGet(account, args) {
700
+ if (args.ids === null || args.ids === undefined) {
701
+ // RFC 8621 allows rejecting "fetch all" for the potentially huge Email type.
702
+ throw new JmapServerMethodError('requestTooLarge', 'Email/get requires an explicit ids array on this server.');
534
703
  }
535
- const position = typeof args.position === 'number' ? args.position : 0;
536
- let ids = emails.map((email) => email.id).slice(position);
537
- const total = emails.length;
538
- if (typeof args.limit === 'number') {
539
- ids = ids.slice(0, args.limit);
704
+ if (!Array.isArray(args.ids)) {
705
+ throw new JmapServerMethodError('invalidArguments', 'Email/get requires an ids array.');
706
+ }
707
+ if (args.ids.length > JMAP_SERVER_LIMITS.maxObjectsInGet) {
708
+ throw new JmapServerMethodError('requestTooLarge', `ids exceeds maxObjectsInGet (${JMAP_SERVER_LIMITS.maxObjectsInGet}).`);
540
709
  }
710
+ const properties = this.validateProperties(args.properties, KNOWN_EMAIL_PROPERTIES);
711
+ const result = await this.backend.getEmails(account.accountId, args.ids, properties);
712
+ const effectiveProperties = properties ?? DEFAULT_EMAIL_PROPERTIES;
713
+ const list = result.list.map((record) => {
714
+ const projected = this.projectObject(record, effectiveProperties);
715
+ if (effectiveProperties.includes('bodyValues')) {
716
+ projected.bodyValues = this.buildBodyValues(record, args);
717
+ }
718
+ return projected;
719
+ });
541
720
  return {
542
- accountId: user.accountId,
543
- queryState: String(user.state),
544
- canCalculateChanges: false,
545
- position,
546
- ids,
547
- total,
721
+ accountId: account.accountId,
722
+ state: result.state,
723
+ list,
724
+ notFound: result.notFound,
548
725
  };
549
726
  }
550
- methodEmailChanges(user, args) {
551
- const since = Number(args.sinceState);
552
- if (!Number.isFinite(since) || since < 0 || since > user.state) {
553
- throw new JmapServerMethodError('cannotCalculateChanges', `Cannot calculate changes since state "${args.sinceState}".`);
727
+ /** Applies the Email/get body-value fetch flags and maxBodyValueBytes truncation. */
728
+ buildBodyValues(record, args) {
729
+ const wanted = new Set();
730
+ if (args.fetchAllBodyValues === true) {
731
+ for (const partId of Object.keys(record.bodyValues)) {
732
+ wanted.add(partId);
733
+ }
554
734
  }
555
- const created = new Set();
556
- const updated = new Set();
557
- const destroyed = new Set();
558
- for (const entry of user.changes) {
559
- if (entry.state <= since) {
560
- continue;
735
+ if (args.fetchTextBodyValues === true) {
736
+ for (const part of record.textBody) {
737
+ if (part.partId != null) {
738
+ wanted.add(part.partId);
739
+ }
561
740
  }
562
- for (const id of entry.created) {
563
- created.add(id);
741
+ }
742
+ if (args.fetchHTMLBodyValues === true) {
743
+ for (const part of record.htmlBody) {
744
+ if (part.partId != null) {
745
+ wanted.add(part.partId);
746
+ }
564
747
  }
565
- for (const id of entry.updated) {
566
- updated.add(id);
748
+ }
749
+ const maxBytes = typeof args.maxBodyValueBytes === 'number' && args.maxBodyValueBytes > 0
750
+ ? args.maxBodyValueBytes
751
+ : null;
752
+ const result = {};
753
+ for (const partId of wanted) {
754
+ const bodyValue = record.bodyValues[partId];
755
+ if (!bodyValue) {
756
+ continue;
567
757
  }
568
- for (const id of entry.destroyed) {
569
- if (created.has(id)) {
570
- // created and destroyed within the window: omit entirely
571
- created.delete(id);
572
- }
573
- else {
574
- destroyed.add(id);
758
+ let value = bodyValue.value;
759
+ let isTruncated = bodyValue.isTruncated === true;
760
+ if (maxBytes !== null) {
761
+ const truncated = truncateUtf8(value, maxBytes);
762
+ if (truncated.length < value.length) {
763
+ value = truncated;
764
+ isTruncated = true;
575
765
  }
576
- updated.delete(id);
577
766
  }
767
+ result[partId] = { value, isTruncated };
578
768
  }
579
- for (const id of created) {
580
- updated.delete(id);
769
+ return result;
770
+ }
771
+ async methodEmailQuery(account, args) {
772
+ const filter = (args.filter ?? {});
773
+ if ('operator' in filter) {
774
+ throw new JmapServerMethodError('unsupportedFilter', 'FilterOperator is not supported; use a flat FilterCondition.');
581
775
  }
582
- return {
583
- accountId: user.accountId,
584
- oldState: String(since),
585
- newState: String(user.state),
586
- hasMoreChanges: false,
587
- created: Array.from(created),
588
- updated: Array.from(updated),
589
- destroyed: Array.from(destroyed),
776
+ for (const key of Object.keys(filter)) {
777
+ if (!SUPPORTED_EMAIL_FILTER_KEYS.has(key)) {
778
+ throw new JmapServerMethodError('unsupportedFilter', `Email filter condition "${key}" is not supported.`);
779
+ }
780
+ }
781
+ const sort = (args.sort ?? []);
782
+ for (const comparator of sort) {
783
+ if (comparator.property !== 'receivedAt') {
784
+ throw new JmapServerMethodError('unsupportedSort', `Email sort property "${comparator.property}" is not supported.`);
785
+ }
786
+ }
787
+ if (args.anchor !== undefined && args.anchor !== null) {
788
+ throw new JmapServerMethodError('invalidArguments', 'anchor is not supported.');
789
+ }
790
+ const position = this.validatePosition(args);
791
+ const result = await this.backend.queryEmails(account.accountId, {
792
+ filter: filter,
793
+ sort: sort,
794
+ position,
795
+ limit: typeof args.limit === 'number' ? args.limit : null,
796
+ calculateTotal: args.calculateTotal === true,
797
+ });
798
+ const response = {
799
+ accountId: account.accountId,
800
+ queryState: result.queryState,
801
+ canCalculateChanges: false,
802
+ position: result.position,
803
+ ids: result.ids,
590
804
  };
805
+ if (args.calculateTotal === true) {
806
+ response.total = result.total ?? 0;
807
+ }
808
+ return response;
591
809
  }
592
- methodEmailSet(user, args, createdIds) {
593
- const oldState = String(user.state);
594
- const created = {};
595
- const notCreated = {};
596
- const updated = {};
597
- const notUpdated = {};
598
- const destroyed = [];
599
- const notDestroyed = {};
600
- const changedCreated = [];
601
- const changedUpdated = [];
602
- const changedDestroyed = [];
603
- for (const [creationId, spec] of Object.entries((args.create ?? {}))) {
604
- try {
605
- const email = this.createEmailFromSpec(user, spec);
606
- user.emails.set(email.id, email);
607
- createdIds.set(creationId, email.id);
608
- changedCreated.push(email.id);
609
- created[creationId] = {
610
- id: email.id,
611
- blobId: email.blobId,
612
- threadId: email.threadId,
613
- size: email.size,
614
- };
810
+ async methodEmailChanges(account, args) {
811
+ const { sinceState, maxChanges } = this.validateChangesArgs(args);
812
+ const changes = await this.backend.getEmailChanges(account.accountId, sinceState, maxChanges);
813
+ if (!changes) {
814
+ throw new JmapServerMethodError('cannotCalculateChanges', `Cannot calculate changes since state "${sinceState}".`);
815
+ }
816
+ return { accountId: account.accountId, ...changes };
817
+ }
818
+ async methodEmailSet(account, args, createdIds) {
819
+ const createEntries = Object.entries((args.create ?? {}));
820
+ const updateEntries = Object.entries((args.update ?? {}));
821
+ const destroyIds = (args.destroy ?? []);
822
+ if (createEntries.length + updateEntries.length + destroyIds.length >
823
+ JMAP_SERVER_LIMITS.maxObjectsInSet) {
824
+ throw new JmapServerMethodError('requestTooLarge', `The set request exceeds maxObjectsInSet (${JMAP_SERVER_LIMITS.maxObjectsInSet}).`);
825
+ }
826
+ if (typeof args.ifInState === 'string') {
827
+ const current = await this.backend.getEmails(account.accountId, []);
828
+ if (current.state !== args.ifInState) {
829
+ throw new JmapServerMethodError('stateMismatch', `ifInState "${args.ifInState}" does not match the current state "${current.state}".`);
615
830
  }
616
- catch (error) {
617
- const message = error instanceof Error ? error.message : String(error);
618
- notCreated[creationId] = { type: 'invalidProperties', description: message };
831
+ }
832
+ const backendRequest = {};
833
+ const notUpdatedEarly = {};
834
+ if (createEntries.length) {
835
+ backendRequest.create = {};
836
+ for (const [creationId, spec] of createEntries) {
837
+ backendRequest.create[creationId] = spec;
619
838
  }
620
839
  }
621
- for (const [id, patch] of Object.entries((args.update ?? {}))) {
622
- const email = user.emails.get(id);
623
- if (!email) {
624
- notUpdated[id] = { type: 'notFound', description: `Email "${id}" does not exist.` };
840
+ if (updateEntries.length) {
841
+ backendRequest.update = {};
842
+ for (const [id, patch] of updateEntries) {
843
+ try {
844
+ backendRequest.update[id] = this.parseEmailUpdatePatch(patch);
845
+ }
846
+ catch (error) {
847
+ notUpdatedEarly[id] =
848
+ error instanceof JmapServerMethodError
849
+ ? { type: error.type, description: error.message }
850
+ : { type: 'invalidPatch', description: String(error) };
851
+ }
852
+ }
853
+ }
854
+ if (destroyIds.length) {
855
+ backendRequest.destroy = destroyIds;
856
+ }
857
+ const result = await this.backend.setEmails(account.accountId, backendRequest);
858
+ const created = {};
859
+ for (const [creationId, record] of Object.entries(result.created)) {
860
+ createdIds.set(creationId, record.id);
861
+ created[creationId] = {
862
+ id: record.id,
863
+ blobId: record.blobId,
864
+ threadId: record.threadId,
865
+ size: record.size,
866
+ };
867
+ }
868
+ const updated = {};
869
+ for (const id of result.updated) {
870
+ updated[id] = null;
871
+ }
872
+ return {
873
+ accountId: account.accountId,
874
+ oldState: result.oldState,
875
+ newState: result.newState,
876
+ created,
877
+ notCreated: result.notCreated,
878
+ updated,
879
+ notUpdated: { ...result.notUpdated, ...notUpdatedEarly },
880
+ destroyed: result.destroyed,
881
+ notDestroyed: result.notDestroyed,
882
+ };
883
+ }
884
+ /**
885
+ * Normalizes an Email/set update patch (RFC 8620 §5.3): full `keywords`/
886
+ * `mailboxIds` replacements and single-key JSON-pointer patches
887
+ * (`keywords/$seen`, `mailboxIds/<id>`). Email properties other than these
888
+ * two are immutable (RFC 8621 §4.6).
889
+ */
890
+ parseEmailUpdatePatch(patch) {
891
+ const update = {};
892
+ const unescape = (token) => token.replaceAll('~1', '/').replaceAll('~0', '~');
893
+ for (const [path, value] of Object.entries(patch)) {
894
+ if (path === 'keywords' || path === 'mailboxIds') {
895
+ if (value === null || typeof value !== 'object' || Array.isArray(value)) {
896
+ throw new JmapServerMethodError('invalidProperties', `"${path}" must be an object.`);
897
+ }
898
+ const normalized = {};
899
+ for (const [key, entryValue] of Object.entries(value)) {
900
+ if (entryValue !== true) {
901
+ throw new JmapServerMethodError('invalidProperties', `Values in "${path}" must be true; remove entries instead of setting them false.`);
902
+ }
903
+ normalized[key] = true;
904
+ }
905
+ update[path] = normalized;
625
906
  continue;
626
907
  }
627
- try {
628
- this.applyPatch(email, patch);
629
- changedUpdated.push(id);
630
- updated[id] = null;
908
+ const slashIndex = path.indexOf('/');
909
+ if (slashIndex === -1) {
910
+ throw new JmapServerMethodError('invalidProperties', `Email property "${path}" is immutable or unknown.`);
631
911
  }
632
- catch (error) {
633
- const message = error instanceof Error ? error.message : String(error);
634
- notUpdated[id] = { type: 'invalidPatch', description: message };
912
+ const property = path.slice(0, slashIndex);
913
+ const rest = path.slice(slashIndex + 1);
914
+ if ((property !== 'keywords' && property !== 'mailboxIds') || rest.includes('/') || !rest) {
915
+ throw new JmapServerMethodError('invalidPatch', `Unsupported patch path "${path}".`);
635
916
  }
636
- }
637
- for (const id of (args.destroy ?? [])) {
638
- if (user.emails.delete(id)) {
639
- changedDestroyed.push(id);
640
- destroyed.push(id);
917
+ const key = unescape(rest);
918
+ const normalizedValue = value === true ? true : value === null || value === false ? null : undefined;
919
+ if (normalizedValue === undefined) {
920
+ throw new JmapServerMethodError('invalidPatch', `Patch value for "${path}" must be true or null.`);
921
+ }
922
+ if (property === 'keywords') {
923
+ update.keywordsPatch = update.keywordsPatch ?? {};
924
+ update.keywordsPatch[key] = normalizedValue;
641
925
  }
642
926
  else {
643
- notDestroyed[id] = { type: 'notFound', description: `Email "${id}" does not exist.` };
927
+ update.mailboxIdsPatch = update.mailboxIdsPatch ?? {};
928
+ update.mailboxIdsPatch[key] = normalizedValue;
644
929
  }
645
930
  }
646
- if (changedCreated.length || changedUpdated.length || changedDestroyed.length) {
647
- this.bumpState(user, {
648
- created: changedCreated,
649
- updated: changedUpdated,
650
- destroyed: changedDestroyed,
651
- });
931
+ if (update.keywords && update.keywordsPatch) {
932
+ throw new JmapServerMethodError('invalidPatch', 'A patch must not set "keywords" and patch "keywords/..." at the same time.');
652
933
  }
653
- return {
654
- accountId: user.accountId,
655
- oldState,
656
- newState: String(user.state),
657
- created,
658
- notCreated,
659
- updated,
660
- notUpdated,
661
- destroyed,
662
- notDestroyed,
663
- };
934
+ if (update.mailboxIds && update.mailboxIdsPatch) {
935
+ throw new JmapServerMethodError('invalidPatch', 'A patch must not set "mailboxIds" and patch "mailboxIds/..." at the same time.');
936
+ }
937
+ return update;
664
938
  }
665
- methodIdentityGet(user) {
666
- return {
667
- accountId: user.accountId,
668
- state: '0',
669
- list: user.identities,
670
- notFound: [],
671
- };
939
+ // ======================
940
+ // identity + submission methods
941
+ // ======================
942
+ async methodIdentityGet(account, args) {
943
+ const result = await this.backend.getIdentities(account.accountId);
944
+ let list = result.list;
945
+ const notFound = [];
946
+ if (Array.isArray(args.ids)) {
947
+ const wanted = new Set(args.ids);
948
+ list = list.filter((identity) => wanted.has(identity.id));
949
+ for (const id of wanted) {
950
+ if (!list.some((identity) => identity.id === id)) {
951
+ notFound.push(id);
952
+ }
953
+ }
954
+ }
955
+ return { accountId: account.accountId, state: result.state, list, notFound };
672
956
  }
673
- methodEmailSubmissionSet(user, args, createdIds) {
957
+ async methodEmailSubmissionSet(account, args, createdIds) {
674
958
  const created = {};
675
959
  const notCreated = {};
960
+ const notUpdated = {};
961
+ const notDestroyed = {};
962
+ /** creationId -> { submissionId, emailId } for onSuccess* resolution. */
963
+ const createdSubmissions = new Map();
964
+ const identitiesResult = await this.backend.getIdentities(account.accountId);
676
965
  for (const [creationId, spec] of Object.entries((args.create ?? {}))) {
677
966
  let emailId = spec.emailId;
678
967
  if (typeof emailId === 'string' && emailId.startsWith('#')) {
@@ -686,14 +975,16 @@ export class JmapServer {
686
975
  }
687
976
  emailId = resolved;
688
977
  }
689
- if (!user.emails.has(emailId)) {
978
+ const emailResult = await this.backend.getEmails(account.accountId, [emailId]);
979
+ const email = emailResult.list[0];
980
+ if (!email) {
690
981
  notCreated[creationId] = {
691
982
  type: 'invalidProperties',
692
983
  description: `Email "${emailId}" does not exist.`,
693
984
  };
694
985
  continue;
695
986
  }
696
- const identity = user.identities.find((candidate) => candidate.id === spec.identityId);
987
+ const identity = identitiesResult.list.find((candidate) => candidate.id === spec.identityId);
697
988
  if (!identity) {
698
989
  notCreated[creationId] = {
699
990
  type: 'invalidProperties',
@@ -701,173 +992,488 @@ export class JmapServer {
701
992
  };
702
993
  continue;
703
994
  }
704
- const id = `submission_${++user.idCounter}`;
705
- const submission = {
706
- id,
707
- emailId,
708
- identityId: identity.id,
709
- undoStatus: 'final',
710
- sendAt: new Date().toISOString(),
995
+ const envelope = this.resolveEnvelope(spec.envelope, identity.email, email);
996
+ if (!envelope.rcptTo.length) {
997
+ notCreated[creationId] = {
998
+ type: 'noRecipients',
999
+ description: 'The email has no to/cc/bcc recipients and no envelope was given.',
1000
+ };
1001
+ continue;
1002
+ }
1003
+ const blob = await this.backend.getBlob(account.accountId, email.blobId);
1004
+ if (!blob) {
1005
+ notCreated[creationId] = {
1006
+ type: 'invalidProperties',
1007
+ description: `Raw message blob "${email.blobId}" does not exist.`,
1008
+ };
1009
+ continue;
1010
+ }
1011
+ try {
1012
+ const submission = await this.backend.submitEmail(account.accountId, {
1013
+ emailId,
1014
+ identityId: identity.id,
1015
+ envelope,
1016
+ message: blob.data,
1017
+ });
1018
+ createdSubmissions.set(creationId, { submissionId: submission.id, emailId });
1019
+ created[creationId] = {
1020
+ id: submission.id,
1021
+ undoStatus: submission.undoStatus,
1022
+ sendAt: submission.sendAt,
1023
+ };
1024
+ }
1025
+ catch (error) {
1026
+ notCreated[creationId] = {
1027
+ type: 'forbiddenToSend',
1028
+ description: error instanceof Error ? error.message : String(error),
1029
+ };
1030
+ }
1031
+ }
1032
+ for (const id of Object.keys((args.update ?? {}))) {
1033
+ notUpdated[id] = {
1034
+ type: 'forbidden',
1035
+ description: 'EmailSubmission updates are not supported.',
1036
+ };
1037
+ }
1038
+ for (const id of (args.destroy ?? [])) {
1039
+ notDestroyed[id] = {
1040
+ type: 'forbidden',
1041
+ description: 'EmailSubmission destroys are not supported.',
1042
+ };
1043
+ }
1044
+ const responses = [
1045
+ {
1046
+ name: 'EmailSubmission/set',
1047
+ result: {
1048
+ accountId: account.accountId,
1049
+ oldState: null,
1050
+ newState: '0',
1051
+ created,
1052
+ notCreated,
1053
+ updated: {},
1054
+ notUpdated,
1055
+ destroyed: [],
1056
+ notDestroyed,
1057
+ },
1058
+ mutated: createdSubmissions.size > 0,
1059
+ },
1060
+ ];
1061
+ // onSuccessUpdateEmail / onSuccessDestroyEmail (RFC 8621 §7.5): apply an
1062
+ // implicit Email/set for successfully created submissions and append its
1063
+ // response after the EmailSubmission/set response.
1064
+ const resolveSubmissionRef = (reference) => {
1065
+ if (reference.startsWith('#')) {
1066
+ return createdSubmissions.get(reference.slice(1)) ?? null;
1067
+ }
1068
+ for (const entry of createdSubmissions.values()) {
1069
+ if (entry.submissionId === reference) {
1070
+ return entry;
1071
+ }
1072
+ }
1073
+ return null;
1074
+ };
1075
+ const implicitSet = { accountId: account.accountId };
1076
+ let hasImplicitSet = false;
1077
+ if (args.onSuccessUpdateEmail && typeof args.onSuccessUpdateEmail === 'object') {
1078
+ const update = {};
1079
+ for (const [reference, patch] of Object.entries(args.onSuccessUpdateEmail)) {
1080
+ const entry = resolveSubmissionRef(reference);
1081
+ if (entry) {
1082
+ update[entry.emailId] = patch;
1083
+ hasImplicitSet = true;
1084
+ }
1085
+ }
1086
+ implicitSet.update = update;
1087
+ }
1088
+ if (Array.isArray(args.onSuccessDestroyEmail)) {
1089
+ const destroy = [];
1090
+ for (const reference of args.onSuccessDestroyEmail) {
1091
+ const entry = resolveSubmissionRef(reference);
1092
+ if (entry) {
1093
+ destroy.push(entry.emailId);
1094
+ hasImplicitSet = true;
1095
+ }
1096
+ }
1097
+ implicitSet.destroy = destroy;
1098
+ }
1099
+ if (hasImplicitSet) {
1100
+ const result = await this.methodEmailSet(account, implicitSet, createdIds);
1101
+ responses.push({
1102
+ name: 'Email/set',
1103
+ result,
1104
+ mutated: result.newState !== result.oldState,
1105
+ });
1106
+ }
1107
+ return responses;
1108
+ }
1109
+ /** Uses the client-provided envelope or derives it from the email's addresses. */
1110
+ resolveEnvelope(specEnvelope, identityEmail, email) {
1111
+ if (specEnvelope &&
1112
+ typeof specEnvelope === 'object' &&
1113
+ specEnvelope.mailFrom?.email &&
1114
+ Array.isArray(specEnvelope.rcptTo)) {
1115
+ return {
1116
+ mailFrom: { email: String(specEnvelope.mailFrom.email) },
1117
+ rcptTo: specEnvelope.rcptTo
1118
+ .filter((recipient) => typeof recipient?.email === 'string')
1119
+ .map((recipient) => ({ email: recipient.email })),
711
1120
  };
712
- user.submissions.set(id, submission);
713
- created[creationId] = { id, undoStatus: submission.undoStatus, sendAt: submission.sendAt };
1121
+ }
1122
+ const recipients = new Set();
1123
+ for (const list of [email.to, email.cc, email.bcc]) {
1124
+ for (const address of list ?? []) {
1125
+ recipients.add(address.email);
1126
+ }
714
1127
  }
715
1128
  return {
716
- accountId: user.accountId,
717
- oldState: String(user.state),
718
- newState: String(user.state),
719
- created,
720
- notCreated,
721
- updated: {},
722
- notUpdated: {},
723
- destroyed: [],
724
- notDestroyed: {},
1129
+ mailFrom: { email: email.from?.[0]?.email ?? identityEmail },
1130
+ rcptTo: Array.from(recipients).map((address) => ({ email: address })),
725
1131
  };
726
1132
  }
727
1133
  // ======================
728
- // internal helpers
1134
+ // upload + download
729
1135
  // ======================
730
- requireUser(username) {
731
- const user = this.users.get(username);
732
- if (!user) {
733
- throw new Error(`User "${username}" does not exist.`);
1136
+ async handleUpload(account, pathname, request) {
1137
+ const segments = pathname.split('/').filter((segment) => segment.length > 0);
1138
+ const accountId = decodeURIComponent(segments[2] ?? '');
1139
+ if (accountId !== account.accountId) {
1140
+ return this.problemResponse(404, 'about:blank', 'Unknown account');
734
1141
  }
735
- return user;
736
- }
737
- createEmailFromSpec(user, spec) {
738
- const mailboxIds = spec.mailboxIds;
739
- if (!mailboxIds || !Object.keys(mailboxIds).length) {
740
- throw new Error('Email create requires mailboxIds.');
741
- }
742
- for (const mailboxId of Object.keys(mailboxIds)) {
743
- if (!user.mailboxes.has(mailboxId)) {
744
- throw new Error(`Mailbox "${mailboxId}" does not exist.`);
745
- }
746
- }
747
- const id = `email_${++user.idCounter}`;
748
- const receivedAt = new Date().toISOString();
749
- const bodyValues = (spec.bodyValues ?? {});
750
- const resolvePart = (part) => part?.partId != null ? bodyValues[part.partId]?.value ?? '' : '';
751
- const textBodyParts = (spec.textBody ?? []).map((part) => ({
752
- partId: part.partId ?? null,
753
- type: part.type ?? 'text/plain',
754
- size: resolvePart(part).length,
755
- }));
756
- const htmlBodyParts = (spec.htmlBody ?? []).map((part) => ({
757
- partId: part.partId ?? null,
758
- type: part.type ?? 'text/html',
759
- size: resolvePart(part).length,
760
- }));
761
- const textValue = textBodyParts.map((part) => bodyValues[part.partId ?? '']?.value ?? '').join('\n');
762
- const from = (spec.from ?? []);
763
- const to = (spec.to ?? []);
764
- const blobId = `blob_${id}`;
765
- const rawLines = [
766
- `From: ${from.map((address) => address.email).join(', ')}`,
767
- `To: ${to.map((address) => address.email).join(', ')}`,
768
- `Subject: ${spec.subject ?? ''}`,
769
- `Date: ${receivedAt}`,
770
- '',
771
- textValue,
772
- ];
773
- user.blobs.set(blobId, {
774
- data: Buffer.from(rawLines.join('\r\n'), 'utf8'),
775
- type: 'message/rfc822',
776
- name: `${id}.eml`,
777
- });
778
- const normalizedBodyValues = {};
779
- for (const [partId, bodyValue] of Object.entries(bodyValues)) {
780
- normalizedBodyValues[partId] = { value: bodyValue.value ?? '', isTruncated: false };
1142
+ const data = new Uint8Array(await request.arrayBuffer());
1143
+ if (data.length > JMAP_SERVER_LIMITS.maxSizeUpload) {
1144
+ return this.limitResponse(400, 'maxSizeUpload', `The upload is larger than ${JMAP_SERVER_LIMITS.maxSizeUpload} bytes.`);
781
1145
  }
782
- return {
783
- id,
784
- blobId,
785
- threadId: `thread_${id}`,
786
- mailboxIds: { ...mailboxIds },
787
- keywords: spec.keywords ?? {},
788
- size: textValue.length,
789
- receivedAt,
790
- sentAt: receivedAt,
791
- subject: spec.subject ?? null,
792
- from,
793
- to,
794
- cc: spec.cc ?? null,
795
- bcc: spec.bcc ?? null,
796
- replyTo: spec.replyTo ?? null,
797
- hasAttachment: false,
798
- preview: textValue.slice(0, 100),
799
- bodyValues: normalizedBodyValues,
800
- textBody: textBodyParts,
801
- htmlBody: htmlBodyParts,
802
- attachments: [],
1146
+ const type = request.headers.get('content-type') ?? 'application/octet-stream';
1147
+ const { blobId, size } = await this.backend.uploadBlob(account.accountId, data, type);
1148
+ return this.jsonResponse(200, { accountId: account.accountId, blobId, type, size });
1149
+ }
1150
+ async handleDownload(account, pathname, url) {
1151
+ // /jmap/download/{accountId}/{blobId}/{name}
1152
+ const segments = pathname.split('/').filter((segment) => segment.length > 0);
1153
+ const accountId = decodeURIComponent(segments[2] ?? '');
1154
+ const blobId = decodeURIComponent(segments[3] ?? '');
1155
+ const name = decodeURIComponent(segments[4] ?? 'blob');
1156
+ if (accountId !== account.accountId) {
1157
+ return this.problemResponse(404, 'about:blank', 'Unknown account');
1158
+ }
1159
+ const blob = await this.backend.getBlob(account.accountId, blobId);
1160
+ if (!blob) {
1161
+ return this.problemResponse(404, 'about:blank', 'Unknown blob');
1162
+ }
1163
+ const type = url.searchParams.get('type') ?? blob.type;
1164
+ return new Response(asBodyBytes(blob.data), {
1165
+ status: 200,
1166
+ headers: {
1167
+ 'content-type': type,
1168
+ 'content-length': String(blob.data.length),
1169
+ 'content-disposition': `attachment; filename="${name.replaceAll('"', '')}"`,
1170
+ },
1171
+ });
1172
+ }
1173
+ // ======================
1174
+ // event source (SSE)
1175
+ // ======================
1176
+ handleEventSource(account, url) {
1177
+ const typesParam = url.searchParams.get('types') ?? '*';
1178
+ const types = typesParam === '*' || typesParam === ''
1179
+ ? null
1180
+ : new Set(typesParam
1181
+ .split(',')
1182
+ .map((entry) => entry.trim())
1183
+ .filter((entry) => entry.length > 0));
1184
+ const closeAfterState = url.searchParams.get('closeafter') === 'state';
1185
+ const pingRaw = Number(url.searchParams.get('ping') ?? '0');
1186
+ const pingSeconds = Number.isFinite(pingRaw) && pingRaw > 0 ? Math.max(1, Math.floor(pingRaw)) : 0;
1187
+ const state = {
1188
+ accountId: account.accountId,
1189
+ types,
1190
+ closeAfterState,
1191
+ controller: null,
1192
+ pingTimer: null,
1193
+ lastSent: new Map(),
1194
+ closed: false,
803
1195
  };
1196
+ const stream = new ReadableStream({
1197
+ start: (controller) => {
1198
+ state.controller = controller;
1199
+ controller.enqueue(textEncoder.encode(': jmap event stream\n\n'));
1200
+ if (pingSeconds > 0) {
1201
+ state.pingTimer = setInterval(() => {
1202
+ this.writeToStream(state, `event: ping\ndata: {"interval":${pingSeconds}}\n\n`);
1203
+ }, pingSeconds * 1000);
1204
+ }
1205
+ try {
1206
+ this.registerStream(state);
1207
+ }
1208
+ catch (error) {
1209
+ // a throwing backend.subscribeToChanges must not strand the ping timer
1210
+ this.unregisterStream(state);
1211
+ throw error;
1212
+ }
1213
+ },
1214
+ cancel: () => {
1215
+ this.unregisterStream(state);
1216
+ },
1217
+ });
1218
+ return new Response(stream, {
1219
+ status: 200,
1220
+ headers: {
1221
+ 'content-type': 'text/event-stream',
1222
+ 'cache-control': 'no-cache',
1223
+ },
1224
+ });
1225
+ }
1226
+ registerStream(state) {
1227
+ if (!this.changeFeedUnsubscribe) {
1228
+ this.changeFeedUnsubscribe = this.backend.subscribeToChanges((change) => {
1229
+ this.pushStateChange(change.accountId, change.changed);
1230
+ });
1231
+ }
1232
+ this.eventStreams.add(state);
1233
+ }
1234
+ unregisterStream(state) {
1235
+ state.closed = true;
1236
+ if (state.pingTimer) {
1237
+ clearInterval(state.pingTimer);
1238
+ state.pingTimer = null;
1239
+ }
1240
+ this.eventStreams.delete(state);
1241
+ if (!this.eventStreams.size && this.changeFeedUnsubscribe) {
1242
+ this.changeFeedUnsubscribe();
1243
+ this.changeFeedUnsubscribe = null;
1244
+ }
1245
+ }
1246
+ closeStream(state) {
1247
+ this.unregisterStream(state);
1248
+ try {
1249
+ state.controller?.close();
1250
+ }
1251
+ catch {
1252
+ // already closed or errored
1253
+ }
1254
+ }
1255
+ writeToStream(state, payload) {
1256
+ if (state.closed || !state.controller) {
1257
+ return;
1258
+ }
1259
+ try {
1260
+ state.controller.enqueue(textEncoder.encode(payload));
1261
+ }
1262
+ catch {
1263
+ this.closeStream(state);
1264
+ }
804
1265
  }
805
1266
  /**
806
- * Applies an Email/set update patch: either whole properties (e.g. keywords)
807
- * or JSON-pointer style paths like "keywords/$seen" (RFC 8620 §5.3).
1267
+ * Pushes a StateChange to matching event streams. Per-type states are
1268
+ * deduplicated per stream, so a mutation notified both by the backend
1269
+ * change feed and by the post-request push is delivered once.
808
1270
  */
809
- applyPatch(email, patch) {
810
- for (const [path, value] of Object.entries(patch)) {
811
- const segments = path.split('/');
812
- if (segments.length === 1) {
813
- if (value === null) {
814
- delete email[path];
815
- }
816
- else {
817
- email[path] = value;
818
- }
1271
+ pushStateChange(accountId, changed) {
1272
+ for (const state of Array.from(this.eventStreams)) {
1273
+ if (state.accountId !== accountId) {
819
1274
  continue;
820
1275
  }
821
- let target = email;
822
- for (const segment of segments.slice(0, -1)) {
823
- if (typeof target[segment] !== 'object' || target[segment] === null) {
824
- target[segment] = {};
1276
+ const filtered = {};
1277
+ for (const [type, typeState] of Object.entries(changed)) {
1278
+ if (state.types && !state.types.has(type)) {
1279
+ continue;
1280
+ }
1281
+ if (state.lastSent.get(type) === typeState) {
1282
+ continue;
825
1283
  }
826
- target = target[segment];
1284
+ filtered[type] = typeState;
827
1285
  }
828
- const leaf = segments[segments.length - 1];
829
- if (value === null || value === false) {
830
- delete target[leaf];
1286
+ if (!Object.keys(filtered).length) {
1287
+ continue;
831
1288
  }
832
- else {
833
- target[leaf] = value;
1289
+ for (const [type, typeState] of Object.entries(filtered)) {
1290
+ state.lastSent.set(type, typeState);
1291
+ }
1292
+ const stateChange = {
1293
+ '@type': 'StateChange',
1294
+ changed: { [accountId]: filtered },
1295
+ };
1296
+ this.writeToStream(state, `event: state\ndata: ${JSON.stringify(stateChange)}\n\n`);
1297
+ if (state.closeAfterState) {
1298
+ this.closeStream(state);
834
1299
  }
835
1300
  }
836
1301
  }
837
- /** Increments the account state, records the change, and pushes a StateChange to open event streams. */
838
- bumpState(user, change) {
839
- user.state += 1;
840
- user.changes.push({
841
- state: user.state,
842
- created: change.created ?? [],
843
- updated: change.updated ?? [],
844
- destroyed: change.destroyed ?? [],
1302
+ /**
1303
+ * Emits a StateChange after a mutating JMAP request, covering backends
1304
+ * whose change feed only reports out-of-band mutations. Deduplicated
1305
+ * against feed-driven pushes via the per-stream state tracking.
1306
+ */
1307
+ async pushAfterMutation(account) {
1308
+ if (!this.eventStreams.size) {
1309
+ return;
1310
+ }
1311
+ const [emails, mailboxes, threads] = await Promise.all([
1312
+ this.backend.getEmails(account.accountId, []),
1313
+ this.backend.getMailboxes(account.accountId, []),
1314
+ this.backend.getThreads(account.accountId, []),
1315
+ ]);
1316
+ this.pushStateChange(account.accountId, {
1317
+ Email: emails.state,
1318
+ Thread: threads.state,
1319
+ Mailbox: mailboxes.state,
845
1320
  });
846
- this.notifyStateChange(user);
847
- }
848
- notifyStateChange(user) {
849
- const stateChange = {
850
- '@type': 'StateChange',
851
- changed: {
852
- [user.accountId]: {
853
- Email: String(user.state),
854
- Mailbox: String(user.state),
855
- Thread: String(user.state),
856
- },
857
- },
858
- };
859
- const payload = `event: state\ndata: ${JSON.stringify(stateChange)}\n\n`;
860
- for (const [response, streamUser] of this.eventStreams) {
861
- if (streamUser !== user) {
862
- continue;
1321
+ }
1322
+ // ======================
1323
+ // node req/res adapter
1324
+ // ======================
1325
+ async handleNodeRequest(req, res) {
1326
+ try {
1327
+ const method = (req.method ?? 'GET').toUpperCase();
1328
+ let body;
1329
+ if (method !== 'GET' && method !== 'HEAD') {
1330
+ const chunks = [];
1331
+ let total = 0;
1332
+ // Cap request buffering at maxSizeUpload; larger requests never make
1333
+ // it to fetchHandler (which enforces the JMAP per-endpoint limits).
1334
+ const maxBuffered = JMAP_SERVER_LIMITS.maxSizeUpload + 1;
1335
+ for await (const chunk of req) {
1336
+ const buffer = chunk;
1337
+ total += buffer.length;
1338
+ if (total > maxBuffered) {
1339
+ res.writeHead(413, { 'content-type': 'application/problem+json' });
1340
+ res.end(JSON.stringify({
1341
+ type: 'urn:ietf:params:jmap:error:limit',
1342
+ limit: 'maxSizeUpload',
1343
+ status: 413,
1344
+ detail: 'Request body too large.',
1345
+ }));
1346
+ req.destroy();
1347
+ return;
1348
+ }
1349
+ chunks.push(buffer);
1350
+ }
1351
+ body = Buffer.concat(chunks);
863
1352
  }
1353
+ const headers = new Headers();
1354
+ const skippedHeaders = new Set([
1355
+ 'connection',
1356
+ 'content-length',
1357
+ 'expect',
1358
+ 'keep-alive',
1359
+ 'proxy-connection',
1360
+ 'transfer-encoding',
1361
+ 'upgrade',
1362
+ ]);
1363
+ for (const [key, value] of Object.entries(req.headers)) {
1364
+ if (value === undefined || skippedHeaders.has(key.toLowerCase())) {
1365
+ continue;
1366
+ }
1367
+ headers.set(key, Array.isArray(value) ? value.join(', ') : value);
1368
+ }
1369
+ const host = req.headers.host ?? '127.0.0.1';
1370
+ const request = new Request(`http://${host}${req.url ?? '/'}`, {
1371
+ method,
1372
+ headers,
1373
+ body: body ? asBodyBytes(body) : undefined,
1374
+ });
1375
+ const response = await this.fetchHandler(request);
1376
+ const responseHeaders = {};
1377
+ response.headers.forEach((value, key) => {
1378
+ responseHeaders[key] = value;
1379
+ });
1380
+ res.writeHead(response.status, responseHeaders);
1381
+ if (!response.body) {
1382
+ res.end();
1383
+ return;
1384
+ }
1385
+ const reader = response.body.getReader();
1386
+ let clientClosed = false;
1387
+ res.on('close', () => {
1388
+ clientClosed = true;
1389
+ // Cancelling the reader triggers the stream's cancel handler, which
1390
+ // releases any per-stream resources (SSE registration, ping timer).
1391
+ void reader.cancel().catch(() => { });
1392
+ });
864
1393
  try {
865
- response.write(payload);
1394
+ while (true) {
1395
+ const { done, value } = await reader.read();
1396
+ if (done || clientClosed || res.destroyed) {
1397
+ break;
1398
+ }
1399
+ res.write(value);
1400
+ }
866
1401
  }
867
1402
  catch {
868
- this.eventStreams.delete(response);
1403
+ // stream cancelled or connection gone
1404
+ }
1405
+ if (!res.destroyed) {
1406
+ res.end();
1407
+ }
1408
+ }
1409
+ catch (error) {
1410
+ const message = error instanceof Error ? error.message : String(error);
1411
+ if (!res.headersSent) {
1412
+ res.writeHead(500, { 'content-type': 'application/problem+json' });
869
1413
  }
1414
+ res.end(JSON.stringify({ type: 'about:blank', status: 500, detail: message }));
1415
+ }
1416
+ }
1417
+ // ======================
1418
+ // shared validators + responses
1419
+ // ======================
1420
+ validateProperties(requested, known) {
1421
+ if (requested === null || requested === undefined) {
1422
+ return null;
1423
+ }
1424
+ if (!Array.isArray(requested)) {
1425
+ throw new JmapServerMethodError('invalidArguments', 'properties must be an array or null.');
1426
+ }
1427
+ for (const property of requested) {
1428
+ if (typeof property !== 'string' || !known.has(property)) {
1429
+ throw new JmapServerMethodError('invalidArguments', `Unknown property "${String(property)}".`);
1430
+ }
1431
+ }
1432
+ return requested.includes('id') ? requested : ['id', ...requested];
1433
+ }
1434
+ projectObject(source, properties) {
1435
+ const projected = {};
1436
+ for (const property of properties) {
1437
+ projected[property] = source[property] === undefined ? null : source[property];
870
1438
  }
1439
+ return projected;
1440
+ }
1441
+ validatePosition(args) {
1442
+ if (args.position === undefined || args.position === null) {
1443
+ return 0;
1444
+ }
1445
+ if (!Number.isInteger(args.position) || args.position < 0) {
1446
+ throw new JmapServerMethodError('invalidArguments', 'position must be a non-negative integer.');
1447
+ }
1448
+ return args.position;
1449
+ }
1450
+ validateChangesArgs(args) {
1451
+ if (typeof args.sinceState !== 'string') {
1452
+ throw new JmapServerMethodError('invalidArguments', 'sinceState is required.');
1453
+ }
1454
+ let maxChanges;
1455
+ if (args.maxChanges !== undefined && args.maxChanges !== null) {
1456
+ if (!Number.isInteger(args.maxChanges) || args.maxChanges <= 0) {
1457
+ throw new JmapServerMethodError('invalidArguments', 'maxChanges must be a positive integer.');
1458
+ }
1459
+ maxChanges = args.maxChanges;
1460
+ }
1461
+ return { sinceState: args.sinceState, maxChanges };
1462
+ }
1463
+ jsonResponse(status, body) {
1464
+ return new Response(JSON.stringify(body), {
1465
+ status,
1466
+ headers: { 'content-type': 'application/json' },
1467
+ });
1468
+ }
1469
+ problemResponse(status, type, detail, extraHeaders = {}) {
1470
+ return new Response(JSON.stringify({ type, status, detail }), {
1471
+ status,
1472
+ headers: { 'content-type': 'application/problem+json', ...extraHeaders },
1473
+ });
1474
+ }
1475
+ limitResponse(status, limit, detail) {
1476
+ return new Response(JSON.stringify({ type: 'urn:ietf:params:jmap:error:limit', limit, status, detail }), { status, headers: { 'content-type': 'application/problem+json' } });
871
1477
  }
872
1478
  }
873
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5qbWFwc2VydmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2xhc3Nlcy5qbWFwc2VydmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sd0JBQXdCLENBQUM7QUFtRWxELDBGQUEwRjtBQUMxRixNQUFNLHFCQUFzQixTQUFRLEtBQUs7SUFDdkMsWUFBbUIsSUFBWSxFQUFFLFdBQW9CO1FBQ25ELEtBQUssQ0FBQyxXQUFXLElBQUksSUFBSSxDQUFDLENBQUM7UUFEVixTQUFJLEdBQUosSUFBSSxDQUFRO0lBRS9CLENBQUM7Q0FDRjtBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxPQUFPLFVBQVU7SUFNckI7UUFMTyxVQUFLLEdBQWlDLElBQUksR0FBRyxFQUFFLENBQUM7UUFFL0MsWUFBTyxHQUE0QixJQUFJLEdBQUcsRUFBRSxDQUFDO1FBQzdDLGlCQUFZLEdBQXNELElBQUksR0FBRyxFQUFFLENBQUM7UUFHbEYsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRTtZQUNuRCxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUMvQixDQUFDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLFlBQVksRUFBRSxDQUFDLE1BQU0sRUFBRSxFQUFFO1lBQ3RDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ3pCLE1BQU0sQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRTtnQkFDdEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDOUIsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCx5QkFBeUI7SUFDekIsbUJBQW1CO0lBQ25CLHlCQUF5QjtJQUVsQixPQUFPLENBQUMsUUFBZ0IsRUFBRSxRQUFnQjtRQUMvQyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7WUFDN0IsTUFBTSxJQUFJLEtBQUssQ0FBQyxTQUFTLFFBQVEsbUJBQW1CLENBQUMsQ0FBQztRQUN4RCxDQUFDO1FBQ0QsTUFBTSxLQUFLLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxHQUFHLFFBQVEsY0FBYyxDQUFDO1FBQzVFLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRTtZQUN2QixRQUFRO1lBQ1IsUUFBUTtZQUNSLFlBQVksRUFBRSxJQUFJLEdBQUcsRUFBRTtZQUN2QixTQUFTLEVBQUUsV0FBVyxRQUFRLEVBQUU7WUFDaEMsU0FBUyxFQUFFLElBQUksR0FBRyxFQUFFO1lBQ3BCLE1BQU0sRUFBRSxJQUFJLEdBQUcsRUFBRTtZQUNqQixLQUFLLEVBQUUsSUFBSSxHQUFHLEVBQUU7WUFDaEIsV0FBVyxFQUFFLElBQUksR0FBRyxFQUFFO1lBQ3RCLFVBQVUsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLFlBQVksRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLENBQUM7WUFDM0UsS0FBSyxFQUFFLENBQUM7WUFDUixPQUFPLEVBQUUsRUFBRTtZQUNYLFNBQVMsRUFBRSxDQUFDO1NBQ2IsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELGlEQUFpRDtJQUMxQyxjQUFjLENBQUMsUUFBZ0IsRUFBRSxLQUFhO1FBQ25ELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDeEMsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUVNLGFBQWEsQ0FBQyxRQUFnQixFQUFFLElBQVksRUFBRSxJQUFhO1FBQ2hFLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDeEMsS0FBSyxNQUFNLE9BQU8sSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUM7WUFDOUMsSUFBSSxPQUFPLENBQUMsSUFBSSxLQUFLLElBQUksRUFBRSxDQUFDO2dCQUMxQixNQUFNLElBQUksS0FBSyxDQUFDLFlBQVksSUFBSSw4QkFBOEIsUUFBUSxJQUFJLENBQUMsQ0FBQztZQUM5RSxDQUFDO1FBQ0gsQ0FBQztRQUNELE1BQU0sRUFBRSxHQUFHLFdBQVcsRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDekMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFO1lBQ3JCLEVBQUU7WUFDRixJQUFJO1lBQ0osSUFBSSxFQUFFLElBQUksSUFBSSxJQUFJO1lBQ2xCLFFBQVEsRUFBRSxJQUFJO1lBQ2QsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSTtTQUMvQixDQUFDLENBQUM7UUFDSCxPQUFPLEVBQUUsQ0FBQztJQUNaLENBQUM7SUFFRCx3R0FBd0c7SUFDakcsUUFBUSxDQUFDLFFBQWdCLEVBQUUsV0FBbUIsRUFBRSxLQUE0QjtRQUNqRixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3hDLE1BQU0sT0FBTyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FDdEQsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEtBQUssV0FBVyxJQUFJLFNBQVMsQ0FBQyxJQUFJLEtBQUssV0FBVyxDQUNoRixDQUFDO1FBQ0YsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2IsTUFBTSxJQUFJLEtBQUssQ0FBQyxZQUFZLFdBQVcsOEJBQThCLFFBQVEsSUFBSSxDQUFDLENBQUM7UUFDckYsQ0FBQztRQUVELE1BQU0sSUFBSSxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNuRSxNQUFNLEVBQUUsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDM0QsTUFBTSxFQUFFLEdBQUcsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUN2QyxNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsVUFBVSxJQUFJLElBQUksSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUM7UUFDaEUsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLFFBQVEsSUFBSSxFQUFFLENBQUM7UUFFdEMsb0RBQW9EO1FBQ3BELE1BQU0sTUFBTSxHQUFHLFFBQVEsRUFBRSxFQUFFLENBQUM7UUFDNUIsTUFBTSxRQUFRLEdBQUc7WUFDZixTQUFTLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDMUQsT0FBTyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQ3RELFlBQVksS0FBSyxDQUFDLE9BQU8sSUFBSSxFQUFFLEVBQUU7WUFDakMsU0FBUyxVQUFVLEVBQUU7WUFDckIsRUFBRTtZQUNGLFFBQVE7U0FDVCxDQUFDO1FBQ0YsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFO1lBQ3JCLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsTUFBTSxDQUFDO1lBQ2hELElBQUksRUFBRSxnQkFBZ0I7WUFDdEIsSUFBSSxFQUFFLEdBQUcsRUFBRSxNQUFNO1NBQ2xCLENBQUMsQ0FBQztRQUVILE1BQU0sVUFBVSxHQUE0RDtZQUMxRSxJQUFJLEVBQUUsRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUU7U0FDOUMsQ0FBQztRQUNGLE1BQU0sYUFBYSxHQUFHLENBQUMsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsSUFBSSxFQUFFLFFBQVEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ3RGLE1BQU0sYUFBYSxHQUErQixFQUFFLENBQUM7UUFDckQsSUFBSSxPQUFPLEtBQUssQ0FBQyxRQUFRLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDdkMsVUFBVSxDQUFDLElBQUksR0FBRyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsUUFBUSxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsQ0FBQztZQUNoRSxhQUFhLENBQUMsSUFBSSxDQUFDLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLElBQUksRUFBRSxLQUFLLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDekYsQ0FBQztRQUVELE1BQU0sZUFBZSxHQUErQixFQUFFLENBQUM7UUFDdkQsS0FBSyxNQUFNLENBQUMsS0FBSyxFQUFFLFVBQVUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsSUFBSSxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDO1lBQ3RFLE1BQU0sZ0JBQWdCLEdBQUcsUUFBUSxFQUFFLE9BQU8sS0FBSyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3RELE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLE9BQWMsQ0FBQyxDQUFDO1lBQ3BELElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLGdCQUFnQixFQUFFO2dCQUMvQixJQUFJO2dCQUNKLElBQUksRUFBRSxVQUFVLENBQUMsSUFBSTtnQkFDckIsSUFBSSxFQUFFLFVBQVUsQ0FBQyxJQUFJO2FBQ3RCLENBQUMsQ0FBQztZQUNILGVBQWUsQ0FBQyxJQUFJLENBQUM7Z0JBQ25CLE1BQU0sRUFBRSxJQUFJO2dCQUNaLE1BQU0sRUFBRSxnQkFBZ0I7Z0JBQ3hCLElBQUksRUFBRSxVQUFVLENBQUMsSUFBSTtnQkFDckIsSUFBSSxFQUFFLFVBQVUsQ0FBQyxJQUFJO2dCQUNyQixJQUFJLEVBQUUsSUFBSSxDQUFDLE1BQU07Z0JBQ2pCLFdBQVcsRUFBRSxZQUFZO2FBQzFCLENBQUMsQ0FBQztRQUNMLENBQUM7UUFFRCxNQUFNLEtBQUssR0FBd0I7WUFDakMsRUFBRTtZQUNGLE1BQU07WUFDTixRQUFRLEVBQUUsVUFBVSxFQUFFLEVBQUU7WUFDeEIsVUFBVSxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFO1lBQ2xDLFFBQVEsRUFBRSxLQUFLLENBQUMsUUFBUSxJQUFJLEVBQUU7WUFDOUIsSUFBSSxFQUFFLFFBQVEsQ0FBQyxNQUFNO1lBQ3JCLFVBQVU7WUFDVixNQUFNLEVBQUUsVUFBVTtZQUNsQixPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU8sSUFBSSxJQUFJO1lBQzlCLElBQUk7WUFDSixFQUFFO1lBQ0YsRUFBRSxFQUFFLEtBQUssQ0FBQyxFQUFFLElBQUksSUFBSTtZQUNwQixHQUFHLEVBQUUsS0FBSyxDQUFDLEdBQUcsSUFBSSxJQUFJO1lBQ3RCLE9BQU8sRUFBRSxJQUFJO1lBQ2IsYUFBYSxFQUFFLGVBQWUsQ0FBQyxNQUFNLEdBQUcsQ0FBQztZQUN6QyxPQUFPLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDO1lBQy9CLFVBQVU7WUFDVixRQUFRLEVBQUUsYUFBYTtZQUN2QixRQUFRLEVBQUUsYUFBYTtZQUN2QixXQUFXLEVBQUUsZUFBZTtTQUM3QixDQUFDO1FBQ0YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQzNCLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLEVBQUUsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3hDLE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQztJQUVELHlCQUF5QjtJQUN6QixZQUFZO0lBQ1oseUJBQXlCO0lBRXpCLHNGQUFzRjtJQUMvRSxLQUFLLENBQUMsSUFBWTtRQUN2QixPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ3JDLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsQ0FBQztZQUNsQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFO2dCQUM1QixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO2dCQUN0QyxNQUFNLFNBQVMsR0FDYixPQUFPLE9BQU8sS0FBSyxRQUFRLElBQUksT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7Z0JBQy9ELE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztZQUNyQixDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELG1GQUFtRjtJQUM1RSxJQUFJO1FBQ1QsS0FBSyxNQUFNLFFBQVEsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxFQUFFLENBQUM7WUFDaEQsSUFBSSxDQUFDO2dCQUNILFFBQVEsQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNqQixDQUFDO1lBQUMsTUFBTSxDQUFDO2dCQUNQLHdCQUF3QjtZQUMxQixDQUFDO1FBQ0gsQ0FBQztRQUNELElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDMUIsS0FBSyxNQUFNLE1BQU0sSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDbEMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ25CLENBQUM7UUFDRCxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3JCLE9BQU8sSUFBSSxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUM3QixJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUU7Z0JBQ3JCLE9BQU8sRUFBRSxDQUFDO1lBQ1osQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCx5QkFBeUI7SUFDekIsZ0JBQWdCO0lBQ2hCLHlCQUF5QjtJQUVqQixhQUFhLENBQUMsR0FBaUMsRUFBRSxHQUFnQztRQUN2RixJQUFJLENBQUM7WUFDSCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3BDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDVixHQUFHLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRTtvQkFDakIsa0JBQWtCLEVBQUUseUNBQXlDO29CQUM3RCxjQUFjLEVBQUUsMEJBQTBCO2lCQUMzQyxDQUFDLENBQUM7Z0JBQ0gsR0FBRyxDQUFDLEdBQUcsQ0FDTCxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUUsSUFBSSxFQUFFLGFBQWEsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSx5QkFBeUIsRUFBRSxDQUFDLENBQ3hGLENBQUM7Z0JBQ0YsT0FBTztZQUNULENBQUM7WUFFRCxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO1lBQ3hELE1BQU0sUUFBUSxHQUFHLEdBQUcsQ0FBQyxRQUFRLENBQUM7WUFFOUIsSUFBSSxHQUFHLENBQUMsTUFBTSxLQUFLLEtBQUssSUFBSSxDQUFDLFFBQVEsS0FBSyxtQkFBbUIsSUFBSSxRQUFRLEtBQUssZUFBZSxDQUFDLEVBQUUsQ0FBQztnQkFDL0YsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQzlCLE9BQU87WUFDVCxDQUFDO1lBQ0QsSUFBSSxHQUFHLENBQUMsTUFBTSxLQUFLLE1BQU0sSUFBSSxRQUFRLEtBQUssV0FBVyxFQUFFLENBQUM7Z0JBQ3RELElBQUksSUFBSSxHQUFHLEVBQUUsQ0FBQztnQkFDZCxHQUFHLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFO29CQUN2QixJQUFJLElBQUksS0FBSyxDQUFDO2dCQUNoQixDQUFDLENBQUMsQ0FBQztnQkFDSCxHQUFHLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxHQUFHLEVBQUU7b0JBQ2pCLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFDbEMsQ0FBQyxDQUFDLENBQUM7Z0JBQ0gsT0FBTztZQUNULENBQUM7WUFDRCxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssS0FBSyxJQUFJLFFBQVEsS0FBSyxtQkFBbUIsRUFBRSxDQUFDO2dCQUM3RCxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFDdkMsT0FBTztZQUNULENBQUM7WUFDRCxJQUFJLEdBQUcsQ0FBQyxNQUFNLEtBQUssS0FBSyxJQUFJLFFBQVEsQ0FBQyxVQUFVLENBQUMsaUJBQWlCLENBQUMsRUFBRSxDQUFDO2dCQUNuRSxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO2dCQUM5QyxPQUFPO1lBQ1QsQ0FBQztZQUVELEdBQUcsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLEVBQUUsY0FBYyxFQUFFLDBCQUEwQixFQUFFLENBQUMsQ0FBQztZQUNuRSxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxJQUFJLEVBQUUsYUFBYSxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNyRixDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE1BQU0sT0FBTyxHQUFHLEtBQUssWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN2RSxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxDQUFDO2dCQUNyQixHQUFHLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxFQUFFLGNBQWMsRUFBRSwwQkFBMEIsRUFBRSxDQUFDLENBQUM7WUFDckUsQ0FBQztZQUNELEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLElBQUksRUFBRSxhQUFhLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ2pGLENBQUM7SUFDSCxDQUFDO0lBRU8sWUFBWSxDQUFDLEdBQWlDO1FBQ3BELE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDO1FBQ3pDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNaLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUNELE1BQU0sVUFBVSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDdkMsSUFBSSxVQUFVLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUN0QixPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFDRCxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxVQUFVLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN6RCxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLFVBQVUsR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNsRCxJQUFJLE1BQU0sS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUN4QixLQUFLLE1BQU0sSUFBSSxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQztnQkFDdkMsSUFBSSxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO29CQUNqQyxPQUFPLElBQUksQ0FBQztnQkFDZCxDQUFDO1lBQ0gsQ0FBQztZQUNELE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUNELElBQUksTUFBTSxLQUFLLE9BQU8sRUFBRSxDQUFDO1lBQ3ZCLE1BQU0sT0FBTyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUM5RCxNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3hDLElBQUksVUFBVSxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7Z0JBQ3RCLE9BQU8sSUFBSSxDQUFDO1lBQ2QsQ0FBQztZQUNELE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBQzlDLE1BQU0sUUFBUSxHQUFHLE9BQU8sQ0FBQyxLQUFLLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQy9DLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3RDLElBQUksSUFBSSxJQUFJLElBQUksQ0FBQyxRQUFRLEtBQUssUUFBUSxFQUFFLENBQUM7Z0JBQ3ZDLE9BQU8sSUFBSSxDQUFDO1lBQ2QsQ0FBQztZQUNELE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVPLGFBQWEsQ0FBQyxJQUFxQixFQUFFLEdBQWdDO1FBQzNFLE1BQU0sT0FBTyxHQUFHO1lBQ2QsWUFBWSxFQUFFO2dCQUNaLDJCQUEyQixFQUFFO29CQUMzQixhQUFhLEVBQUUsVUFBVTtvQkFDekIsbUJBQW1CLEVBQUUsQ0FBQztvQkFDdEIsY0FBYyxFQUFFLFVBQVU7b0JBQzFCLHFCQUFxQixFQUFFLENBQUM7b0JBQ3hCLGlCQUFpQixFQUFFLEVBQUU7b0JBQ3JCLGVBQWUsRUFBRSxHQUFHO29CQUNwQixlQUFlLEVBQUUsR0FBRztvQkFDcEIsbUJBQW1CLEVBQUUsQ0FBQyxpQkFBaUIsRUFBRSxpQkFBaUIsQ0FBQztpQkFDNUQ7Z0JBQ0QsMkJBQTJCLEVBQUUsRUFBRTtnQkFDL0IsaUNBQWlDLEVBQUUsRUFBRTthQUN0QztZQUNELFFBQVEsRUFBRTtnQkFDUixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRTtvQkFDaEIsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRO29CQUNuQixVQUFVLEVBQUUsSUFBSTtvQkFDaEIsVUFBVSxFQUFFLEtBQUs7b0JBQ2pCLG1CQUFtQixFQUFFO3dCQUNuQiwyQkFBMkIsRUFBRSxFQUFFO3dCQUMvQixpQ0FBaUMsRUFBRSxFQUFFO3FCQUN0QztpQkFDRjthQUNGO1lBQ0QsZUFBZSxFQUFFO2dCQUNmLDJCQUEyQixFQUFFLElBQUksQ0FBQyxTQUFTO2dCQUMzQywyQkFBMkIsRUFBRSxJQUFJLENBQUMsU0FBUztnQkFDM0MsaUNBQWlDLEVBQUUsSUFBSSxDQUFDLFNBQVM7YUFDbEQ7WUFDRCxRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7WUFDdkIsTUFBTSxFQUFFLFdBQVc7WUFDbkIsV0FBVyxFQUFFLHdEQUF3RDtZQUNyRSxTQUFTLEVBQUUsMEJBQTBCO1lBQ3JDLGNBQWMsRUFBRSxxRUFBcUU7WUFDckYsS0FBSyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO1NBQzFCLENBQUM7UUFDRixHQUFHLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxFQUFFLGNBQWMsRUFBRSxrQkFBa0IsRUFBRSxDQUFDLENBQUM7UUFDM0QsR0FBRyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUVPLFNBQVMsQ0FBQyxJQUFxQixFQUFFLElBQVksRUFBRSxHQUFnQztRQUNyRixJQUFJLE1BQVcsQ0FBQztRQUNoQixJQUFJLENBQUM7WUFDSCxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM1QixDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsR0FBRyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxjQUFjLEVBQUUsMEJBQTBCLEVBQUUsQ0FBQyxDQUFDO1lBQ25FLEdBQUcsQ0FBQyxHQUFHLENBQ0wsSUFBSSxDQUFDLFNBQVMsQ0FBQztnQkFDYixJQUFJLEVBQUUsb0NBQW9DO2dCQUMxQyxNQUFNLEVBQUUsR0FBRztnQkFDWCxNQUFNLEVBQUUscUNBQXFDO2FBQzlDLENBQUMsQ0FDSCxDQUFDO1lBQ0YsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsV0FBVyxDQUFDLEVBQUUsQ0FBQztZQUN4QyxHQUFHLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxFQUFFLGNBQWMsRUFBRSwwQkFBMEIsRUFBRSxDQUFDLENBQUM7WUFDbkUsR0FBRyxDQUFDLEdBQUcsQ0FDTCxJQUFJLENBQUMsU0FBUyxDQUFDO2dCQUNiLElBQUksRUFBRSx1Q0FBdUM7Z0JBQzdDLE1BQU0sRUFBRSxHQUFHO2dCQUNYLE1BQU0sRUFBRSxzREFBc0Q7YUFDL0QsQ0FBQyxDQUNILENBQUM7WUFDRixPQUFPO1FBQ1QsQ0FBQztRQUVELE1BQU0sVUFBVSxHQUFHLElBQUksR0FBRyxFQUFrQixDQUFDO1FBQzdDLE1BQU0sZUFBZSxHQUFpRCxFQUFFLENBQUM7UUFDekUsS0FBSyxNQUFNLElBQUksSUFBSSxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDdEMsTUFBTSxDQUFDLFVBQVUsRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLEdBQUcsSUFBNkMsQ0FBQztZQUNqRixJQUFJLENBQUM7Z0JBQ0gsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFLElBQUksSUFBSSxFQUFFLEVBQUUsVUFBVSxDQUFDLENBQUM7Z0JBQzdFLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDckQsQ0FBQztZQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7Z0JBQ2YsSUFBSSxLQUFLLFlBQVkscUJBQXFCLEVBQUUsQ0FBQztvQkFDM0MsZUFBZSxDQUFDLElBQUksQ0FBQzt3QkFDbkIsT0FBTzt3QkFDUCxFQUFFLElBQUksRUFBRSxLQUFLLENBQUMsSUFBSSxFQUFFLFdBQVcsRUFBRSxLQUFLLENBQUMsT0FBTyxFQUFFO3dCQUNoRCxNQUFNO3FCQUNQLENBQUMsQ0FBQztnQkFDTCxDQUFDO3FCQUFNLENBQUM7b0JBQ04sTUFBTSxPQUFPLEdBQUcsS0FBSyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUN2RSxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLEVBQUUsTUFBTSxDQUFDLENBQUMsQ0FBQztnQkFDeEYsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBRUQsR0FBRyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxjQUFjLEVBQUUsa0JBQWtCLEVBQUUsQ0FBQyxDQUFDO1FBQzNELEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLGVBQWUsRUFBRSxZQUFZLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNqRixDQUFDO0lBRU8saUJBQWlCLENBQ3ZCLElBQXFCLEVBQ3JCLEdBQWlDLEVBQ2pDLEdBQWdDO1FBRWhDLEdBQUcsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFO1lBQ2pCLGNBQWMsRUFBRSxtQkFBbUI7WUFDbkMsZUFBZSxFQUFFLFVBQVU7WUFDM0IsVUFBVSxFQUFFLFlBQVk7U0FDekIsQ0FBQyxDQUFDO1FBQ0gsR0FBRyxDQUFDLEtBQUssQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNqQyxHQUFHLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxHQUFHLEVBQUU7WUFDbkIsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDaEMsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8sY0FBYyxDQUNwQixJQUFxQixFQUNyQixRQUFnQixFQUNoQixHQUFRLEVBQ1IsR0FBZ0M7UUFFaEMsNkNBQTZDO1FBQzdDLE1BQU0sUUFBUSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQzdFLE1BQU0sU0FBUyxHQUFHLGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUN4RCxNQUFNLE1BQU0sR0FBRyxrQkFBa0IsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFDckQsSUFBSSxTQUFTLEtBQUssSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ2pDLEdBQUcsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLEVBQUUsY0FBYyxFQUFFLDBCQUEwQixFQUFFLENBQUMsQ0FBQztZQUNuRSxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxJQUFJLEVBQUUsYUFBYSxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLGlCQUFpQixFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3pGLE9BQU87UUFDVCxDQUFDO1FBQ0QsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDcEMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ1YsR0FBRyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxjQUFjLEVBQUUsMEJBQTBCLEVBQUUsQ0FBQyxDQUFDO1lBQ25FLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxFQUFFLElBQUksRUFBRSxhQUFhLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ3RGLE9BQU87UUFDVCxDQUFDO1FBQ0QsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQztRQUN2RCxHQUFHLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFBRSxFQUFFLGNBQWMsRUFBRSxJQUFJLEVBQUUsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ2pGLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3JCLENBQUM7SUFFRCx5QkFBeUI7SUFDekIsdUJBQXVCO0lBQ3ZCLHlCQUF5QjtJQUVqQixjQUFjLENBQ3BCLElBQXFCLEVBQ3JCLFVBQWtCLEVBQ2xCLElBQXlCLEVBQ3pCLFVBQStCO1FBRS9CLFFBQVEsVUFBVSxFQUFFLENBQUM7WUFDbkIsS0FBSyxXQUFXO2dCQUNkLE9BQU8sSUFBSSxDQUFDO1lBQ2QsS0FBSyxhQUFhO2dCQUNoQixPQUFPLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDM0MsS0FBSyxlQUFlO2dCQUNsQixPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDN0MsS0FBSyxXQUFXO2dCQUNkLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDekMsS0FBSyxhQUFhO2dCQUNoQixPQUFPLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDM0MsS0FBSyxlQUFlO2dCQUNsQixPQUFPLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDN0MsS0FBSyxXQUFXO2dCQUNkLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBQ3JELEtBQUssY0FBYztnQkFDakIsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDdEMsS0FBSyxxQkFBcUI7Z0JBQ3hCLE9BQU8sSUFBSSxDQUFDLHdCQUF3QixDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFDL0Q7Z0JBQ0UsTUFBTSxJQUFJLHFCQUFxQixDQUFDLGVBQWUsRUFBRSxtQkFBbUIsVUFBVSxJQUFJLENBQUMsQ0FBQztRQUN4RixDQUFDO0lBQ0gsQ0FBQztJQUVPLGdCQUFnQixDQUFDLElBQXFCLEVBQUUsSUFBeUI7UUFDdkUsTUFBTSxHQUFHLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7UUFDaEQsSUFBSSxJQUEwQixDQUFDO1FBQy9CLE1BQU0sUUFBUSxHQUFhLEVBQUUsQ0FBQztRQUM5QixJQUFJLElBQUksQ0FBQyxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7WUFDckIsSUFBSSxHQUFHLEdBQUcsQ0FBQztRQUNiLENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxHQUFHLEVBQUUsQ0FBQztZQUNWLEtBQUssTUFBTSxFQUFFLElBQUksSUFBSSxDQUFDLEdBQWUsRUFBRSxDQUFDO2dCQUN0QyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDdkMsSUFBSSxPQUFPLEVBQUUsQ0FBQztvQkFDWixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUNyQixDQUFDO3FCQUFNLENBQUM7b0JBQ04sUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDcEIsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBQ0QsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQ3JDLE1BQU0sTUFBTSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FDcEQsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQzFDLENBQUM7WUFDRixPQUFPO2dCQUNMLEdBQUcsT0FBTztnQkFDVixXQUFXLEVBQUUsTUFBTSxDQUFDLE1BQU07Z0JBQzFCLFlBQVksRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUMsTUFBTTtnQkFDckUsWUFBWSxFQUFFLE1BQU0sQ0FBQyxNQUFNO2dCQUMzQixhQUFhLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDLE1BQU07Z0JBQ3RFLFFBQVEsRUFBRTtvQkFDUixZQUFZLEVBQUUsSUFBSTtvQkFDbEIsV0FBVyxFQUFFLElBQUk7b0JBQ2pCLGNBQWMsRUFBRSxJQUFJO29CQUNwQixVQUFVLEVBQUUsSUFBSTtvQkFDaEIsY0FBYyxFQUFFLElBQUk7b0JBQ3BCLGNBQWMsRUFBRSxJQUFJO29CQUNwQixTQUFTLEVBQUUsSUFBSTtvQkFDZixTQUFTLEVBQUUsSUFBSTtvQkFDZixTQUFTLEVBQUUsSUFBSTtpQkFDaEI7Z0JBQ0QsWUFBWSxFQUFFLElBQUk7YUFDbkIsQ0FBQztRQUNKLENBQUMsQ0FBQyxDQUFDO1FBQ0gsT0FBTztZQUNMLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztZQUN6QixLQUFLLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7WUFDekIsSUFBSSxFQUFFLFNBQVM7WUFDZixRQUFRO1NBQ1QsQ0FBQztJQUNKLENBQUM7SUFFTyxrQkFBa0IsQ0FBQyxJQUFxQixFQUFFLElBQXlCO1FBQ3pFLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLElBQUksRUFBRSxDQUFDO1FBQ2pDLElBQUksU0FBUyxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ3BELElBQUksT0FBTyxNQUFNLENBQUMsSUFBSSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQ3BDLFNBQVMsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxLQUFLLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMxRSxDQUFDO1FBQ0QsSUFBSSxPQUFPLE1BQU0sQ0FBQyxJQUFJLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDcEMsU0FBUyxHQUFHLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxJQUFJLEtBQUssTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzFFLENBQUM7UUFDRCxNQUFNLEdBQUcsR0FBRyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDbkQsT0FBTztZQUNMLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztZQUN6QixVQUFVLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7WUFDOUIsbUJBQW1CLEVBQUUsS0FBSztZQUMxQixRQUFRLEVBQUUsQ0FBQztZQUNYLEdBQUc7WUFDSCxLQUFLLEVBQUUsR0FBRyxDQUFDLE1BQU07U0FDbEIsQ0FBQztJQUNKLENBQUM7SUFFTyxjQUFjLENBQUMsSUFBcUIsRUFBRSxJQUF5QjtRQUNyRSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUM3QixNQUFNLElBQUkscUJBQXFCLENBQUMsa0JBQWtCLEVBQUUsa0NBQWtDLENBQUMsQ0FBQztRQUMxRixDQUFDO1FBQ0QsTUFBTSxJQUFJLEdBQStCLEVBQUUsQ0FBQztRQUM1QyxNQUFNLFFBQVEsR0FBYSxFQUFFLENBQUM7UUFDOUIsS0FBSyxNQUFNLEVBQUUsSUFBSSxJQUFJLENBQUMsR0FBZSxFQUFFLENBQUM7WUFDdEMsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDbEMsSUFBSSxLQUFLLEVBQUUsQ0FBQztnQkFDViw2REFBNkQ7Z0JBQzdELHdEQUF3RDtnQkFDeEQsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsS0FBSyxFQUFFLENBQUMsQ0FBQztZQUMxQixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNwQixDQUFDO1FBQ0gsQ0FBQztRQUNELE9BQU87WUFDTCxTQUFTLEVBQUUsSUFBSSxDQUFDLFNBQVM7WUFDekIsS0FBSyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO1lBQ3pCLElBQUk7WUFDSixRQUFRO1NBQ1QsQ0FBQztJQUNKLENBQUM7SUFFTyxnQkFBZ0IsQ0FBQyxJQUFxQixFQUFFLElBQXlCO1FBQ3ZFLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNLElBQUksRUFBRSxDQUFDO1FBQ2pDLElBQUksTUFBTSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQzlDLElBQUksT0FBTyxNQUFNLENBQUMsU0FBUyxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQ3pDLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsVUFBVSxFQUFFLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFDMUUsQ0FBQztRQUNELElBQUksT0FBTyxNQUFNLENBQUMsT0FBTyxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQ3ZDLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FDL0IsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FDakYsQ0FBQztRQUNKLENBQUM7UUFDRCxJQUFJLE9BQU8sTUFBTSxDQUFDLElBQUksS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUNwQyxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3pDLE1BQU0sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUNwQixDQUFDLEtBQUssRUFBRSxFQUFFLENBQ1IsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQztnQkFDMUQsTUFBTSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsSUFBSSxFQUFFLEtBQUssSUFBSSxFQUFFLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQzdFLENBQUM7UUFDSixDQUFDO1FBQ0QsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUNoRixJQUFJLElBQUksRUFBRSxRQUFRLEtBQUssWUFBWSxFQUFFLENBQUM7WUFDcEMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtnQkFDbkIsTUFBTSxVQUFVLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxVQUFVLElBQUksRUFBRSxDQUFDLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsVUFBVSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUM7Z0JBQ3hGLE9BQU8sSUFBSSxDQUFDLFdBQVcsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUM7WUFDL0QsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDO1FBQ0QsTUFBTSxRQUFRLEdBQUcsT0FBTyxJQUFJLENBQUMsUUFBUSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZFLElBQUksR0FBRyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFZLENBQUMsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDcEUsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztRQUM1QixJQUFJLE9BQU8sSUFBSSxDQUFDLEtBQUssS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUNuQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2pDLENBQUM7UUFDRCxPQUFPO1lBQ0wsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTO1lBQ3pCLFVBQVUsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztZQUM5QixtQkFBbUIsRUFBRSxLQUFLO1lBQzFCLFFBQVE7WUFDUixHQUFHO1lBQ0gsS0FBSztTQUNOLENBQUM7SUFDSixDQUFDO0lBRU8sa0JBQWtCLENBQUMsSUFBcUIsRUFBRSxJQUF5QjtRQUN6RSxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3RDLElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLEtBQUssR0FBRyxDQUFDLElBQUksS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUMvRCxNQUFNLElBQUkscUJBQXFCLENBQzdCLHdCQUF3QixFQUN4Qix5Q0FBeUMsSUFBSSxDQUFDLFVBQVUsSUFBSSxDQUM3RCxDQUFDO1FBQ0osQ0FBQztRQUNELE1BQU0sT0FBTyxHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7UUFDbEMsTUFBTSxPQUFPLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztRQUNsQyxNQUFNLFNBQVMsR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO1FBQ3BDLEtBQUssTUFBTSxLQUFLLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2pDLElBQUksS0FBSyxDQUFDLEtBQUssSUFBSSxLQUFLLEVBQUUsQ0FBQztnQkFDekIsU0FBUztZQUNYLENBQUM7WUFDRCxLQUFLLE1BQU0sRUFBRSxJQUFJLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztnQkFDL0IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNsQixDQUFDO1lBQ0QsS0FBSyxNQUFNLEVBQUUsSUFBSSxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQy9CLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDbEIsQ0FBQztZQUNELEtBQUssTUFBTSxFQUFFLElBQUksS0FBSyxDQUFDLFNBQVMsRUFBRSxDQUFDO2dCQUNqQyxJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztvQkFDcEIseURBQXlEO29CQUN6RCxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNyQixDQUFDO3FCQUFNLENBQUM7b0JBQ04sU0FBUyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDcEIsQ0FBQztnQkFDRCxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3JCLENBQUM7UUFDSCxDQUFDO1FBQ0QsS0FBSyxNQUFNLEVBQUUsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUN6QixPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3JCLENBQUM7UUFDRCxPQUFPO1lBQ0wsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTO1lBQ3pCLFFBQVEsRUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDO1lBQ3ZCLFFBQVEsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztZQUM1QixjQUFjLEVBQUUsS0FBSztZQUNyQixPQUFPLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7WUFDNUIsT0FBTyxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO1lBQzVCLFNBQVMsRUFBRSxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQztTQUNqQyxDQUFDO0lBQ0osQ0FBQztJQUVPLGNBQWMsQ0FDcEIsSUFBcUIsRUFDckIsSUFBeUIsRUFDekIsVUFBK0I7UUFFL0IsTUFBTSxRQUFRLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNwQyxNQUFNLE9BQU8sR0FBd0IsRUFBRSxDQUFDO1FBQ3hDLE1BQU0sVUFBVSxHQUF3QixFQUFFLENBQUM7UUFDM0MsTUFBTSxPQUFPLEdBQXdCLEVBQUUsQ0FBQztRQUN4QyxNQUFNLFVBQVUsR0FBd0IsRUFBRSxDQUFDO1FBQzNDLE1BQU0sU0FBUyxHQUFhLEVBQUUsQ0FBQztRQUMvQixNQUFNLFlBQVksR0FBd0IsRUFBRSxDQUFDO1FBQzdDLE1BQU0sY0FBYyxHQUFhLEVBQUUsQ0FBQztRQUNwQyxNQUFNLGNBQWMsR0FBYSxFQUFFLENBQUM7UUFDcEMsTUFBTSxnQkFBZ0IsR0FBYSxFQUFFLENBQUM7UUFFdEMsS0FBSyxNQUFNLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLEVBQUUsQ0FBd0IsQ0FBQyxFQUFFLENBQUM7WUFDNUYsSUFBSSxDQUFDO2dCQUNILE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7Z0JBQ25ELElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsS0FBSyxDQUFDLENBQUM7Z0JBQ2pDLFVBQVUsQ0FBQyxHQUFHLENBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFDckMsY0FBYyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUM7Z0JBQzlCLE9BQU8sQ0FBQyxVQUFVLENBQUMsR0FBRztvQkFDcEIsRUFBRSxFQUFFLEtBQUssQ0FBQyxFQUFFO29CQUNaLE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTTtvQkFDcEIsUUFBUSxFQUFFLEtBQUssQ0FBQyxRQUFRO29CQUN4QixJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUk7aUJBQ2pCLENBQUM7WUFDSixDQUFDO1lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztnQkFDZixNQUFNLE9BQU8sR0FBRyxLQUFLLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ3ZFLFVBQVUsQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxtQkFBbUIsRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLENBQUM7WUFDL0UsQ0FBQztRQUNILENBQUM7UUFFRCxLQUFLLE1BQU0sQ0FBQyxFQUFFLEVBQUUsS0FBSyxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksRUFBRSxDQUF3QixDQUFDLEVBQUUsQ0FBQztZQUNyRixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNsQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQ1gsVUFBVSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLG1CQUFtQixFQUFFLENBQUM7Z0JBQ3BGLFNBQVM7WUFDWCxDQUFDO1lBQ0QsSUFBSSxDQUFDO2dCQUNILElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO2dCQUM5QixjQUFjLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUN4QixPQUFPLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDO1lBQ3JCLENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLE1BQU0sT0FBTyxHQUFHLEtBQUssWUFBWSxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDdkUsVUFBVSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLGNBQWMsRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLENBQUM7WUFDbEUsQ0FBQztRQUNILENBQUM7UUFFRCxLQUFLLE1BQU0sRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sSUFBSSxFQUFFLENBQWEsRUFBRSxDQUFDO1lBQ2xELElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQztnQkFDM0IsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUMxQixTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ3JCLENBQUM7aUJBQU0sQ0FBQztnQkFDTixZQUFZLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxJQUFJLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxVQUFVLEVBQUUsbUJBQW1CLEVBQUUsQ0FBQztZQUN4RixDQUFDO1FBQ0gsQ0FBQztRQUVELElBQUksY0FBYyxDQUFDLE1BQU0sSUFBSSxjQUFjLENBQUMsTUFBTSxJQUFJLGdCQUFnQixDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQzlFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFO2dCQUNuQixPQUFPLEVBQUUsY0FBYztnQkFDdkIsT0FBTyxFQUFFLGNBQWM7Z0JBQ3ZCLFNBQVMsRUFBRSxnQkFBZ0I7YUFDNUIsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUVELE9BQU87WUFDTCxTQUFTLEVBQUUsSUFBSSxDQUFDLFNBQVM7WUFDekIsUUFBUTtZQUNSLFFBQVEsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztZQUM1QixPQUFPO1lBQ1AsVUFBVTtZQUNWLE9BQU87WUFDUCxVQUFVO1lBQ1YsU0FBUztZQUNULFlBQVk7U0FDYixDQUFDO0lBQ0osQ0FBQztJQUVPLGlCQUFpQixDQUFDLElBQXFCO1FBQzdDLE9BQU87WUFDTCxTQUFTLEVBQUUsSUFBSSxDQUFDLFNBQVM7WUFDekIsS0FBSyxFQUFFLEdBQUc7WUFDVixJQUFJLEVBQUUsSUFBSSxDQUFDLFVBQVU7WUFDckIsUUFBUSxFQUFFLEVBQUU7U0FDYixDQUFDO0lBQ0osQ0FBQztJQUVPLHdCQUF3QixDQUM5QixJQUFxQixFQUNyQixJQUF5QixFQUN6QixVQUErQjtRQUUvQixNQUFNLE9BQU8sR0FBd0IsRUFBRSxDQUFDO1FBQ3hDLE1BQU0sVUFBVSxHQUF3QixFQUFFLENBQUM7UUFDM0MsS0FBSyxNQUFNLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxJQUFJLEVBQUUsQ0FBd0IsQ0FBQyxFQUFFLENBQUM7WUFDNUYsSUFBSSxPQUFPLEdBQVcsSUFBSSxDQUFDLE9BQU8sQ0FBQztZQUNuQyxJQUFJLE9BQU8sT0FBTyxLQUFLLFFBQVEsSUFBSSxPQUFPLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQzNELE1BQU0sUUFBUSxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNsRCxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7b0JBQ2QsVUFBVSxDQUFDLFVBQVUsQ0FBQyxHQUFHO3dCQUN2QixJQUFJLEVBQUUsbUJBQW1CO3dCQUN6QixXQUFXLEVBQUUsa0NBQWtDLE9BQU8sSUFBSTtxQkFDM0QsQ0FBQztvQkFDRixTQUFTO2dCQUNYLENBQUM7Z0JBQ0QsT0FBTyxHQUFHLFFBQVEsQ0FBQztZQUNyQixDQUFDO1lBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQzlCLFVBQVUsQ0FBQyxVQUFVLENBQUMsR0FBRztvQkFDdkIsSUFBSSxFQUFFLG1CQUFtQjtvQkFDekIsV0FBVyxFQUFFLFVBQVUsT0FBTyxtQkFBbUI7aUJBQ2xELENBQUM7Z0JBQ0YsU0FBUztZQUNYLENBQUM7WUFDRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsU0FBUyxDQUFDLEVBQUUsS0FBSyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDdkYsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO2dCQUNkLFVBQVUsQ0FBQyxVQUFVLENBQUMsR0FBRztvQkFDdkIsSUFBSSxFQUFFLG1CQUFtQjtvQkFDekIsV0FBVyxFQUFFLGFBQWEsSUFBSSxDQUFDLFVBQVUsbUJBQW1CO2lCQUM3RCxDQUFDO2dCQUNGLFNBQVM7WUFDWCxDQUFDO1lBQ0QsTUFBTSxFQUFFLEdBQUcsY0FBYyxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUM1QyxNQUFNLFVBQVUsR0FBMEI7Z0JBQ3hDLEVBQUU7Z0JBQ0YsT0FBTztnQkFDUCxVQUFVLEVBQUUsUUFBUSxDQUFDLEVBQUU7Z0JBQ3ZCLFVBQVUsRUFBRSxPQUFPO2dCQUNuQixNQUFNLEVBQUUsSUFBSSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUU7YUFDakMsQ0FBQztZQUNGLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxVQUFVLENBQUMsQ0FBQztZQUNyQyxPQUFPLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRSxFQUFFLEVBQUUsVUFBVSxFQUFFLFVBQVUsQ0FBQyxVQUFVLEVBQUUsTUFBTSxFQUFFLFVBQVUsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUM3RixDQUFDO1FBQ0QsT0FBTztZQUNMLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztZQUN6QixRQUFRLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7WUFDNUIsUUFBUSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO1lBQzVCLE9BQU87WUFDUCxVQUFVO1lBQ1YsT0FBTyxFQUFFLEVBQUU7WUFDWCxVQUFVLEVBQUUsRUFBRTtZQUNkLFNBQVMsRUFBRSxFQUFFO1lBQ2IsWUFBWSxFQUFFLEVBQUU7U0FDakIsQ0FBQztJQUNKLENBQUM7SUFFRCx5QkFBeUI7SUFDekIsbUJBQW1CO0lBQ25CLHlCQUF5QjtJQUVqQixXQUFXLENBQUMsUUFBZ0I7UUFDbEMsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDdEMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQ1YsTUFBTSxJQUFJLEtBQUssQ0FBQyxTQUFTLFFBQVEsbUJBQW1CLENBQUMsQ0FBQztRQUN4RCxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRU8sbUJBQW1CLENBQUMsSUFBcUIsRUFBRSxJQUF5QjtRQUMxRSxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsVUFBaUQsQ0FBQztRQUMxRSxJQUFJLENBQUMsVUFBVSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNuRCxNQUFNLElBQUksS0FBSyxDQUFDLG1DQUFtQyxDQUFDLENBQUM7UUFDdkQsQ0FBQztRQUNELEtBQUssTUFBTSxTQUFTLElBQUksTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1lBQ2hELElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO2dCQUNuQyxNQUFNLElBQUksS0FBSyxDQUFDLFlBQVksU0FBUyxtQkFBbUIsQ0FBQyxDQUFDO1lBQzVELENBQUM7UUFDSCxDQUFDO1FBQ0QsTUFBTSxFQUFFLEdBQUcsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUN2QyxNQUFNLFVBQVUsR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQzVDLE1BQU0sVUFBVSxHQUFHLENBQUMsSUFBSSxDQUFDLFVBQVUsSUFBSSxFQUFFLENBQXNDLENBQUM7UUFDaEYsTUFBTSxXQUFXLEdBQUcsQ0FBQyxJQUF5QixFQUFVLEVBQUUsQ0FDeEQsSUFBSSxFQUFFLE1BQU0sSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsS0FBSyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQ25FLE1BQU0sYUFBYSxHQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsSUFBSSxFQUFFLENBQWdDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1lBQ3pGLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUk7WUFDM0IsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLElBQUksWUFBWTtZQUMvQixJQUFJLEVBQUUsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU07U0FDL0IsQ0FBQyxDQUFDLENBQUM7UUFDSixNQUFNLGFBQWEsR0FBSSxDQUFDLElBQUksQ0FBQyxRQUFRLElBQUksRUFBRSxDQUFnQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztZQUN6RixNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sSUFBSSxJQUFJO1lBQzNCLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxJQUFJLFdBQVc7WUFDOUIsSUFBSSxFQUFFLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNO1NBQy9CLENBQUMsQ0FBQyxDQUFDO1FBQ0osTUFBTSxTQUFTLEdBQUcsYUFBYSxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksRUFBRSxDQUFDLEVBQUUsS0FBSyxJQUFJLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUVyRyxNQUFNLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksRUFBRSxDQUF3QixDQUFDO1FBQ3RELE1BQU0sRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQXdCLENBQUM7UUFDbEQsTUFBTSxNQUFNLEdBQUcsUUFBUSxFQUFFLEVBQUUsQ0FBQztRQUM1QixNQUFNLFFBQVEsR0FBRztZQUNmLFNBQVMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUMxRCxPQUFPLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDdEQsWUFBWSxJQUFJLENBQUMsT0FBTyxJQUFJLEVBQUUsRUFBRTtZQUNoQyxTQUFTLFVBQVUsRUFBRTtZQUNyQixFQUFFO1lBQ0YsU0FBUztTQUNWLENBQUM7UUFDRixJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUU7WUFDckIsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxNQUFNLENBQUM7WUFDaEQsSUFBSSxFQUFFLGdCQUFnQjtZQUN0QixJQUFJLEVBQUUsR0FBRyxFQUFFLE1BQU07U0FDbEIsQ0FBQyxDQUFDO1FBRUgsTUFBTSxvQkFBb0IsR0FBNEQsRUFBRSxDQUFDO1FBQ3pGLEtBQUssTUFBTSxDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUM7WUFDN0Qsb0JBQW9CLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsU0FBUyxDQUFDLEtBQUssSUFBSSxFQUFFLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBRSxDQUFDO1FBQ3RGLENBQUM7UUFFRCxPQUFPO1lBQ0wsRUFBRTtZQUNGLE1BQU07WUFDTixRQUFRLEVBQUUsVUFBVSxFQUFFLEVBQUU7WUFDeEIsVUFBVSxFQUFFLEVBQUUsR0FBRyxVQUFVLEVBQUU7WUFDN0IsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLElBQUksRUFBRTtZQUM3QixJQUFJLEVBQUUsU0FBUyxDQUFDLE1BQU07WUFDdEIsVUFBVTtZQUNWLE1BQU0sRUFBRSxVQUFVO1lBQ2xCLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTyxJQUFJLElBQUk7WUFDN0IsSUFBSTtZQUNKLEVBQUU7WUFDRixFQUFFLEVBQUUsSUFBSSxDQUFDLEVBQUUsSUFBSSxJQUFJO1lBQ25CLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxJQUFJLElBQUk7WUFDckIsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSTtZQUM3QixhQUFhLEVBQUUsS0FBSztZQUNwQixPQUFPLEVBQUUsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDO1lBQ2hDLFVBQVUsRUFBRSxvQkFBb0I7WUFDaEMsUUFBUSxFQUFFLGFBQWE7WUFDdkIsUUFBUSxFQUFFLGFBQWE7WUFDdkIsV0FBVyxFQUFFLEVBQUU7U0FDaEIsQ0FBQztJQUNKLENBQUM7SUFFRDs7O09BR0c7SUFDSyxVQUFVLENBQUMsS0FBMEIsRUFBRSxLQUEwQjtRQUN2RSxLQUFLLE1BQU0sQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1lBQ2xELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDakMsSUFBSSxRQUFRLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO2dCQUMxQixJQUFJLEtBQUssS0FBSyxJQUFJLEVBQUUsQ0FBQztvQkFDbkIsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ3JCLENBQUM7cUJBQU0sQ0FBQztvQkFDTixLQUFLLENBQUMsSUFBSSxDQUFDLEdBQUcsS0FBSyxDQUFDO2dCQUN0QixDQUFDO2dCQUNELFNBQVM7WUFDWCxDQUFDO1lBQ0QsSUFBSSxNQUFNLEdBQUcsS0FBSyxDQUFDO1lBQ25CLEtBQUssTUFBTSxPQUFPLElBQUksUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUM1QyxJQUFJLE9BQU8sTUFBTSxDQUFDLE9BQU8sQ0FBQyxLQUFLLFFBQVEsSUFBSSxNQUFNLENBQUMsT0FBTyxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUM7b0JBQ3BFLE1BQU0sQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7Z0JBQ3ZCLENBQUM7Z0JBQ0QsTUFBTSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUMzQixDQUFDO1lBQ0QsTUFBTSxJQUFJLEdBQUcsUUFBUSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDM0MsSUFBSSxLQUFLLEtBQUssSUFBSSxJQUFJLEtBQUssS0FBSyxLQUFLLEVBQUUsQ0FBQztnQkFDdEMsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDdEIsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxLQUFLLENBQUM7WUFDdkIsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQsd0dBQXdHO0lBQ2hHLFNBQVMsQ0FDZixJQUFxQixFQUNyQixNQUF3RTtRQUV4RSxJQUFJLENBQUMsS0FBSyxJQUFJLENBQUMsQ0FBQztRQUNoQixJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQztZQUNoQixLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUs7WUFDakIsT0FBTyxFQUFFLE1BQU0sQ0FBQyxPQUFPLElBQUksRUFBRTtZQUM3QixPQUFPLEVBQUUsTUFBTSxDQUFDLE9BQU8sSUFBSSxFQUFFO1lBQzdCLFNBQVMsRUFBRSxNQUFNLENBQUMsU0FBUyxJQUFJLEVBQUU7U0FDbEMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQy9CLENBQUM7SUFFTyxpQkFBaUIsQ0FBQyxJQUFxQjtRQUM3QyxNQUFNLFdBQVcsR0FBRztZQUNsQixPQUFPLEVBQUUsYUFBYTtZQUN0QixPQUFPLEVBQUU7Z0JBQ1AsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLEVBQUU7b0JBQ2hCLEtBQUssRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztvQkFDekIsT0FBTyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO29CQUMzQixNQUFNLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7aUJBQzNCO2FBQ0Y7U0FDRixDQUFDO1FBQ0YsTUFBTSxPQUFPLEdBQUcsdUJBQXVCLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQztRQUN6RSxLQUFLLE1BQU0sQ0FBQyxRQUFRLEVBQUUsVUFBVSxDQUFDLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3ZELElBQUksVUFBVSxLQUFLLElBQUksRUFBRSxDQUFDO2dCQUN4QixTQUFTO1lBQ1gsQ0FBQztZQUNELElBQUksQ0FBQztnQkFDSCxRQUFRLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzFCLENBQUM7WUFBQyxNQUFNLENBQUM7Z0JBQ1AsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDckMsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0NBQ0YifQ==
1479
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5qbWFwc2VydmVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2xhc3Nlcy5qbWFwc2VydmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sd0JBQXdCLENBQUM7QUFDbEQsT0FBTyxFQUNMLG9CQUFvQixFQUNwQixvQkFBb0IsRUFDcEIsMEJBQTBCLEdBRzNCLE1BQU0seUJBQXlCLENBQUM7QUFDakMsT0FBTyxFQVdOLE1BQU0seUJBQXlCLENBQUM7QUFDakMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFvQm5FLDREQUE0RDtBQUM1RCxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRztJQUNoQyxhQUFhLEVBQUUsVUFBVTtJQUN6QixtQkFBbUIsRUFBRSxDQUFDO0lBQ3RCLGNBQWMsRUFBRSxVQUFVO0lBQzFCLHFCQUFxQixFQUFFLENBQUM7SUFDeEIsaUJBQWlCLEVBQUUsRUFBRTtJQUNyQixlQUFlLEVBQUUsR0FBRztJQUNwQixlQUFlLEVBQUUsR0FBRztDQUNyQixDQUFDO0FBRUYsNkVBQTZFO0FBQzdFLE1BQU0sYUFBYSxHQUFHLEdBQUcsQ0FBQztBQUUxQixzREFBc0Q7QUFDdEQsTUFBTSx3QkFBd0IsR0FBRztJQUMvQixJQUFJO0lBQ0osUUFBUTtJQUNSLFVBQVU7SUFDVixZQUFZO0lBQ1osVUFBVTtJQUNWLE1BQU07SUFDTixZQUFZO0lBQ1osV0FBVztJQUNYLFdBQVc7SUFDWCxZQUFZO0lBQ1osUUFBUTtJQUNSLE1BQU07SUFDTixJQUFJO0lBQ0osSUFBSTtJQUNKLEtBQUs7SUFDTCxTQUFTO0lBQ1QsU0FBUztJQUNULFFBQVE7SUFDUixlQUFlO0lBQ2YsU0FBUztJQUNULFlBQVk7SUFDWixVQUFVO0lBQ1YsVUFBVTtJQUNWLGFBQWE7Q0FDZCxDQUFDO0FBQ0YsTUFBTSxzQkFBc0IsR0FBRyxJQUFJLEdBQUcsQ0FBQyx3QkFBd0IsQ0FB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