@percena/weft 0.4.0-next.7 → 0.4.0-next.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chat.cjs +2 -2
- package/dist/chat.d.cts +0 -167
- package/dist/chat.d.ts +0 -167
- package/dist/chat.js +2 -2
- package/dist/index.cjs +23 -17
- package/dist/index.d.cts +51 -1774
- package/dist/index.d.ts +51 -1774
- package/dist/index.js +23 -17
- package/dist/providers-flitro.cjs +35 -29
- package/dist/providers-flitro.d.cts +51 -49
- package/dist/providers-flitro.d.ts +51 -49
- package/dist/providers-flitro.js +31 -25
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -332,13 +332,14 @@ function timelineKey(item) {
|
|
|
332
332
|
}
|
|
333
333
|
|
|
334
334
|
// ../packages/client/dist/index.js
|
|
335
|
-
var
|
|
335
|
+
var WeftHttpClient = class {
|
|
336
336
|
baseUrl;
|
|
337
337
|
timeout;
|
|
338
338
|
apiKey;
|
|
339
339
|
tenantId;
|
|
340
340
|
onTokenExpired;
|
|
341
341
|
token;
|
|
342
|
+
embedMode;
|
|
342
343
|
constructor(options) {
|
|
343
344
|
this.baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
344
345
|
this.timeout = options.timeout ?? 3e4;
|
|
@@ -346,6 +347,11 @@ var FlitroHttpClient = class {
|
|
|
346
347
|
this.tenantId = options.tenantId ?? "";
|
|
347
348
|
this.token = options.token ?? "";
|
|
348
349
|
this.onTokenExpired = options.onTokenExpired;
|
|
350
|
+
this.embedMode = !!(this.token && !this.apiKey);
|
|
351
|
+
}
|
|
352
|
+
sessionPath(sessionId) {
|
|
353
|
+
const encoded = encodeURIComponent(sessionId);
|
|
354
|
+
return this.embedMode ? `/v1/embed/sessions/${encoded}` : `/v1/sessions/${encoded}`;
|
|
349
355
|
}
|
|
350
356
|
/** Current Authorization bearer (scoped token wins over apiKey). */
|
|
351
357
|
getBearerToken() {
|
|
@@ -377,7 +383,7 @@ var FlitroHttpClient = class {
|
|
|
377
383
|
});
|
|
378
384
|
}
|
|
379
385
|
async getSession(sessionId) {
|
|
380
|
-
return this.get(
|
|
386
|
+
return this.get(`${this.sessionPath(sessionId)}`);
|
|
381
387
|
}
|
|
382
388
|
async sendMessage(sessionId, message, options) {
|
|
383
389
|
const budget = options?.budget ? {
|
|
@@ -385,7 +391,7 @@ var FlitroHttpClient = class {
|
|
|
385
391
|
max_tokens: options.budget.maxTokens,
|
|
386
392
|
max_wall_time_sec: options.budget.maxWallTimeSec
|
|
387
393
|
} : void 0;
|
|
388
|
-
return this.post(
|
|
394
|
+
return this.post(`${this.sessionPath(sessionId)}/runs`, {
|
|
389
395
|
message,
|
|
390
396
|
model: options?.model,
|
|
391
397
|
skill_names: options?.skillNames,
|
|
@@ -408,13 +414,13 @@ var FlitroHttpClient = class {
|
|
|
408
414
|
}
|
|
409
415
|
async respondToPermission(sessionId, requestId, allowed, options) {
|
|
410
416
|
return this.post(
|
|
411
|
-
|
|
417
|
+
`${this.sessionPath(sessionId)}/permission-response`,
|
|
412
418
|
{ requestId, allowed, remember: options?.remember, text: options?.text, answer: options?.answer }
|
|
413
419
|
);
|
|
414
420
|
}
|
|
415
421
|
async patchSession(sessionId, patch) {
|
|
416
422
|
return this.patch(
|
|
417
|
-
|
|
423
|
+
`${this.sessionPath(sessionId)}`,
|
|
418
424
|
patch
|
|
419
425
|
);
|
|
420
426
|
}
|
|
@@ -426,12 +432,12 @@ var FlitroHttpClient = class {
|
|
|
426
432
|
if (afterSeq !== void 0) params.set("after_seq", String(afterSeq));
|
|
427
433
|
if (limit !== void 0) params.set("limit", String(limit));
|
|
428
434
|
const qs = params.toString();
|
|
429
|
-
const url =
|
|
435
|
+
const url = `${this.sessionPath(sessionId)}/timeline/fetch${qs ? `?${qs}` : ""}`;
|
|
430
436
|
return this.get(url);
|
|
431
437
|
}
|
|
432
438
|
/** Returns the SSE stream URL for a session's canonical timeline. */
|
|
433
439
|
sessionTimelineUrl(sessionId) {
|
|
434
|
-
return `${this.baseUrl}
|
|
440
|
+
return `${this.baseUrl}${this.sessionPath(sessionId)}/timeline`;
|
|
435
441
|
}
|
|
436
442
|
async get(path) {
|
|
437
443
|
return this.request("GET", path, void 0);
|
|
@@ -461,7 +467,7 @@ var FlitroHttpClient = class {
|
|
|
461
467
|
}
|
|
462
468
|
}
|
|
463
469
|
if (!response.ok) {
|
|
464
|
-
let errorMsg = `
|
|
470
|
+
let errorMsg = `Weft HTTP ${response.status}`;
|
|
465
471
|
try {
|
|
466
472
|
const errBody = await response.json();
|
|
467
473
|
if (errBody.error) errorMsg = `${errorMsg}: ${errBody.error}`;
|
|
@@ -475,7 +481,7 @@ var FlitroHttpClient = class {
|
|
|
475
481
|
}
|
|
476
482
|
}
|
|
477
483
|
};
|
|
478
|
-
var
|
|
484
|
+
var WeftFetchSseTimelineStream = class {
|
|
479
485
|
listeners = /* @__PURE__ */ new Set();
|
|
480
486
|
abortController = null;
|
|
481
487
|
connected = false;
|
|
@@ -548,7 +554,7 @@ var FlitroFetchSseTimelineStream = class {
|
|
|
548
554
|
if (fresh) this.tokenOverride = fresh;
|
|
549
555
|
}
|
|
550
556
|
if (!response.ok || !response.body) {
|
|
551
|
-
throw new Error(`
|
|
557
|
+
throw new Error(`Weft SSE: HTTP ${response.status}`);
|
|
552
558
|
}
|
|
553
559
|
this.reconnectAttempts = 0;
|
|
554
560
|
const reader = response.body.getReader();
|
|
@@ -583,7 +589,7 @@ var FlitroFetchSseTimelineStream = class {
|
|
|
583
589
|
scheduleReconnect() {
|
|
584
590
|
if (this.disposed) return;
|
|
585
591
|
if (this.reconnectAttempts >= this.options.maxReconnectAttempts) {
|
|
586
|
-
this.emitError(new Error(`
|
|
592
|
+
this.emitError(new Error(`Weft SSE: max reconnect attempts reached`));
|
|
587
593
|
return;
|
|
588
594
|
}
|
|
589
595
|
this.reconnectAttempts++;
|
|
@@ -620,8 +626,8 @@ function parseSseBuffer(buffer) {
|
|
|
620
626
|
}
|
|
621
627
|
return { items, remainder };
|
|
622
628
|
}
|
|
623
|
-
function
|
|
624
|
-
return new
|
|
629
|
+
function createTimelineStream(options) {
|
|
630
|
+
return new WeftFetchSseTimelineStream(options);
|
|
625
631
|
}
|
|
626
632
|
|
|
627
633
|
// ../packages/provider-flitro/dist/index.js
|
|
@@ -726,7 +732,7 @@ function createFlitroRuntimeCapabilityReport(options) {
|
|
|
726
732
|
function createFlitroProviderRuntime(options) {
|
|
727
733
|
const report = createFlitroRuntimeCapabilityReport(options);
|
|
728
734
|
const extensions = createRuntimeExtensionContext(options.extensions);
|
|
729
|
-
const client = new
|
|
735
|
+
const client = new WeftHttpClient(options.server);
|
|
730
736
|
let resolvedSessionId = options.sessionId ?? "";
|
|
731
737
|
let epoch = options.epoch ?? (resolvedSessionId ? `flitro-${resolvedSessionId}` : "flitro-pending");
|
|
732
738
|
const now = options.now ?? (() => Date.now());
|
|
@@ -847,7 +853,7 @@ function createFlitroProviderRuntime(options) {
|
|
|
847
853
|
}
|
|
848
854
|
function connectSse() {
|
|
849
855
|
if (!resolvedSessionId || sseStream) return;
|
|
850
|
-
sseStream =
|
|
856
|
+
sseStream = createTimelineStream({
|
|
851
857
|
url: client.sessionTimelineUrl(resolvedSessionId),
|
|
852
858
|
apiKey: options.server.apiKey,
|
|
853
859
|
tenantId: options.server.tenantId,
|
|
@@ -991,7 +997,7 @@ var PushTimelineStream = class {
|
|
|
991
997
|
}
|
|
992
998
|
};
|
|
993
999
|
|
|
994
|
-
// ../packages/
|
|
1000
|
+
// ../packages/chat/dist/index.js
|
|
995
1001
|
import { useState as useState22 } from "react";
|
|
996
1002
|
|
|
997
1003
|
// ../packages/ui/dist/chunk-MRPTNS4U.js
|
|
@@ -7783,7 +7789,7 @@ function useEventProcessor(options) {
|
|
|
7783
7789
|
};
|
|
7784
7790
|
}
|
|
7785
7791
|
|
|
7786
|
-
// ../packages/
|
|
7792
|
+
// ../packages/chat/dist/index.js
|
|
7787
7793
|
import { useCallback as useCallback9, useEffect as useEffect9, useMemo as useMemo8, useRef as useRef8, useState as useState12 } from "react";
|
|
7788
7794
|
import { jsx as jsx39, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
7789
7795
|
import { useCallback as useCallback22, useEffect as useEffect23, useMemo as useMemo22, useRef as useRef22, useState as useState32 } from "react";
|
|
@@ -20,17 +20,17 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/providers-flitro.ts
|
|
21
21
|
var providers_flitro_exports = {};
|
|
22
22
|
__export(providers_flitro_exports, {
|
|
23
|
-
FlitroFetchSseTimelineStream: () => FlitroFetchSseTimelineStream,
|
|
24
|
-
FlitroHttpClient: () => FlitroHttpClient,
|
|
25
|
-
FlitroSseTimelineStream: () => FlitroSseTimelineStream,
|
|
26
23
|
WeftClient: () => WeftClient,
|
|
24
|
+
WeftFetchSseTimelineStream: () => WeftFetchSseTimelineStream,
|
|
25
|
+
WeftHttpClient: () => WeftHttpClient,
|
|
26
|
+
WeftSseTimelineStream: () => WeftSseTimelineStream,
|
|
27
27
|
createFlitroDriver: () => createFlitroDriver,
|
|
28
28
|
createFlitroEmbedRuntime: () => createFlitroEmbedRuntime,
|
|
29
29
|
createFlitroProviderRuntime: () => createFlitroProviderRuntime,
|
|
30
30
|
createFlitroRuntime: () => createFlitroRuntime,
|
|
31
31
|
createFlitroRuntimeCandidates: () => createFlitroRuntimeCandidates,
|
|
32
32
|
createFlitroRuntimeCapabilityReport: () => createFlitroRuntimeCapabilityReport,
|
|
33
|
-
|
|
33
|
+
createTimelineStream: () => createTimelineStream,
|
|
34
34
|
probeFlitroCapabilities: () => probeFlitroCapabilities
|
|
35
35
|
});
|
|
36
36
|
module.exports = __toCommonJS(providers_flitro_exports);
|
|
@@ -260,13 +260,14 @@ function sortTimeline(timeline) {
|
|
|
260
260
|
}
|
|
261
261
|
|
|
262
262
|
// ../packages/client/dist/index.js
|
|
263
|
-
var
|
|
263
|
+
var WeftHttpClient = class {
|
|
264
264
|
baseUrl;
|
|
265
265
|
timeout;
|
|
266
266
|
apiKey;
|
|
267
267
|
tenantId;
|
|
268
268
|
onTokenExpired;
|
|
269
269
|
token;
|
|
270
|
+
embedMode;
|
|
270
271
|
constructor(options) {
|
|
271
272
|
this.baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
272
273
|
this.timeout = options.timeout ?? 3e4;
|
|
@@ -274,6 +275,11 @@ var FlitroHttpClient = class {
|
|
|
274
275
|
this.tenantId = options.tenantId ?? "";
|
|
275
276
|
this.token = options.token ?? "";
|
|
276
277
|
this.onTokenExpired = options.onTokenExpired;
|
|
278
|
+
this.embedMode = !!(this.token && !this.apiKey);
|
|
279
|
+
}
|
|
280
|
+
sessionPath(sessionId) {
|
|
281
|
+
const encoded = encodeURIComponent(sessionId);
|
|
282
|
+
return this.embedMode ? `/v1/embed/sessions/${encoded}` : `/v1/sessions/${encoded}`;
|
|
277
283
|
}
|
|
278
284
|
/** Current Authorization bearer (scoped token wins over apiKey). */
|
|
279
285
|
getBearerToken() {
|
|
@@ -305,7 +311,7 @@ var FlitroHttpClient = class {
|
|
|
305
311
|
});
|
|
306
312
|
}
|
|
307
313
|
async getSession(sessionId) {
|
|
308
|
-
return this.get(
|
|
314
|
+
return this.get(`${this.sessionPath(sessionId)}`);
|
|
309
315
|
}
|
|
310
316
|
async sendMessage(sessionId, message, options) {
|
|
311
317
|
const budget = options?.budget ? {
|
|
@@ -313,7 +319,7 @@ var FlitroHttpClient = class {
|
|
|
313
319
|
max_tokens: options.budget.maxTokens,
|
|
314
320
|
max_wall_time_sec: options.budget.maxWallTimeSec
|
|
315
321
|
} : void 0;
|
|
316
|
-
return this.post(
|
|
322
|
+
return this.post(`${this.sessionPath(sessionId)}/runs`, {
|
|
317
323
|
message,
|
|
318
324
|
model: options?.model,
|
|
319
325
|
skill_names: options?.skillNames,
|
|
@@ -336,13 +342,13 @@ var FlitroHttpClient = class {
|
|
|
336
342
|
}
|
|
337
343
|
async respondToPermission(sessionId, requestId, allowed, options) {
|
|
338
344
|
return this.post(
|
|
339
|
-
|
|
345
|
+
`${this.sessionPath(sessionId)}/permission-response`,
|
|
340
346
|
{ requestId, allowed, remember: options?.remember, text: options?.text, answer: options?.answer }
|
|
341
347
|
);
|
|
342
348
|
}
|
|
343
349
|
async patchSession(sessionId, patch) {
|
|
344
350
|
return this.patch(
|
|
345
|
-
|
|
351
|
+
`${this.sessionPath(sessionId)}`,
|
|
346
352
|
patch
|
|
347
353
|
);
|
|
348
354
|
}
|
|
@@ -354,12 +360,12 @@ var FlitroHttpClient = class {
|
|
|
354
360
|
if (afterSeq !== void 0) params.set("after_seq", String(afterSeq));
|
|
355
361
|
if (limit !== void 0) params.set("limit", String(limit));
|
|
356
362
|
const qs = params.toString();
|
|
357
|
-
const url =
|
|
363
|
+
const url = `${this.sessionPath(sessionId)}/timeline/fetch${qs ? `?${qs}` : ""}`;
|
|
358
364
|
return this.get(url);
|
|
359
365
|
}
|
|
360
366
|
/** Returns the SSE stream URL for a session's canonical timeline. */
|
|
361
367
|
sessionTimelineUrl(sessionId) {
|
|
362
|
-
return `${this.baseUrl}
|
|
368
|
+
return `${this.baseUrl}${this.sessionPath(sessionId)}/timeline`;
|
|
363
369
|
}
|
|
364
370
|
async get(path) {
|
|
365
371
|
return this.request("GET", path, void 0);
|
|
@@ -389,7 +395,7 @@ var FlitroHttpClient = class {
|
|
|
389
395
|
}
|
|
390
396
|
}
|
|
391
397
|
if (!response.ok) {
|
|
392
|
-
let errorMsg = `
|
|
398
|
+
let errorMsg = `Weft HTTP ${response.status}`;
|
|
393
399
|
try {
|
|
394
400
|
const errBody = await response.json();
|
|
395
401
|
if (errBody.error) errorMsg = `${errorMsg}: ${errBody.error}`;
|
|
@@ -403,7 +409,7 @@ var FlitroHttpClient = class {
|
|
|
403
409
|
}
|
|
404
410
|
}
|
|
405
411
|
};
|
|
406
|
-
var
|
|
412
|
+
var WeftSseTimelineStream = class {
|
|
407
413
|
listeners = /* @__PURE__ */ new Set();
|
|
408
414
|
eventSource = null;
|
|
409
415
|
disposed = false;
|
|
@@ -412,7 +418,7 @@ var FlitroSseTimelineStream = class {
|
|
|
412
418
|
// Native EventSource cannot set headers or observe HTTP status codes, so
|
|
413
419
|
// scoped tokens travel as a ?token= query param (re-read on every reconnect
|
|
414
420
|
// to pick up rotation); onTokenExpired is only actionable in the fetch-based
|
|
415
|
-
// stream, which is what
|
|
421
|
+
// stream, which is what createTimelineStream returns.
|
|
416
422
|
getBearerToken;
|
|
417
423
|
options;
|
|
418
424
|
constructor(options) {
|
|
@@ -500,7 +506,7 @@ var FlitroSseTimelineStream = class {
|
|
|
500
506
|
scheduleReconnect() {
|
|
501
507
|
if (this.disposed) return;
|
|
502
508
|
if (this.reconnectAttempts >= this.options.maxReconnectAttempts) {
|
|
503
|
-
this.emitError(new Error(`
|
|
509
|
+
this.emitError(new Error(`Weft SSE: max reconnect attempts (${this.options.maxReconnectAttempts}) reached`));
|
|
504
510
|
return;
|
|
505
511
|
}
|
|
506
512
|
this.reconnectAttempts++;
|
|
@@ -516,7 +522,7 @@ var FlitroSseTimelineStream = class {
|
|
|
516
522
|
}
|
|
517
523
|
}
|
|
518
524
|
};
|
|
519
|
-
var
|
|
525
|
+
var WeftFetchSseTimelineStream = class {
|
|
520
526
|
listeners = /* @__PURE__ */ new Set();
|
|
521
527
|
abortController = null;
|
|
522
528
|
connected = false;
|
|
@@ -589,7 +595,7 @@ var FlitroFetchSseTimelineStream = class {
|
|
|
589
595
|
if (fresh) this.tokenOverride = fresh;
|
|
590
596
|
}
|
|
591
597
|
if (!response.ok || !response.body) {
|
|
592
|
-
throw new Error(`
|
|
598
|
+
throw new Error(`Weft SSE: HTTP ${response.status}`);
|
|
593
599
|
}
|
|
594
600
|
this.reconnectAttempts = 0;
|
|
595
601
|
const reader = response.body.getReader();
|
|
@@ -624,7 +630,7 @@ var FlitroFetchSseTimelineStream = class {
|
|
|
624
630
|
scheduleReconnect() {
|
|
625
631
|
if (this.disposed) return;
|
|
626
632
|
if (this.reconnectAttempts >= this.options.maxReconnectAttempts) {
|
|
627
|
-
this.emitError(new Error(`
|
|
633
|
+
this.emitError(new Error(`Weft SSE: max reconnect attempts reached`));
|
|
628
634
|
return;
|
|
629
635
|
}
|
|
630
636
|
this.reconnectAttempts++;
|
|
@@ -661,8 +667,8 @@ function parseSseBuffer(buffer) {
|
|
|
661
667
|
}
|
|
662
668
|
return { items, remainder };
|
|
663
669
|
}
|
|
664
|
-
function
|
|
665
|
-
return new
|
|
670
|
+
function createTimelineStream(options) {
|
|
671
|
+
return new WeftFetchSseTimelineStream(options);
|
|
666
672
|
}
|
|
667
673
|
var TimelineSubscriptionImpl = class {
|
|
668
674
|
constructor(stream) {
|
|
@@ -726,7 +732,7 @@ var WeftClient = class {
|
|
|
726
732
|
options;
|
|
727
733
|
constructor(options) {
|
|
728
734
|
this.options = options;
|
|
729
|
-
this.http = new
|
|
735
|
+
this.http = new WeftHttpClient({
|
|
730
736
|
baseUrl: options.server,
|
|
731
737
|
apiKey: options.apiKey,
|
|
732
738
|
tenantId: options.tenantId,
|
|
@@ -764,7 +770,7 @@ var WeftClient = class {
|
|
|
764
770
|
* async iterable (`for await`).
|
|
765
771
|
*/
|
|
766
772
|
subscribe: (sessionId, options) => {
|
|
767
|
-
const stream = new
|
|
773
|
+
const stream = new WeftFetchSseTimelineStream({
|
|
768
774
|
url: this.http.sessionTimelineUrl(sessionId),
|
|
769
775
|
apiKey: this.options.apiKey,
|
|
770
776
|
tenantId: this.options.token ? void 0 : this.options.tenantId,
|
|
@@ -945,7 +951,7 @@ function createFlitroRuntimeCapabilityReport(options) {
|
|
|
945
951
|
function createFlitroProviderRuntime(options) {
|
|
946
952
|
const report = createFlitroRuntimeCapabilityReport(options);
|
|
947
953
|
const extensions = createRuntimeExtensionContext(options.extensions);
|
|
948
|
-
const client = new
|
|
954
|
+
const client = new WeftHttpClient(options.server);
|
|
949
955
|
let resolvedSessionId = options.sessionId ?? "";
|
|
950
956
|
let epoch = options.epoch ?? (resolvedSessionId ? `flitro-${resolvedSessionId}` : "flitro-pending");
|
|
951
957
|
const now = options.now ?? (() => Date.now());
|
|
@@ -1066,7 +1072,7 @@ function createFlitroProviderRuntime(options) {
|
|
|
1066
1072
|
}
|
|
1067
1073
|
function connectSse() {
|
|
1068
1074
|
if (!resolvedSessionId || sseStream) return;
|
|
1069
|
-
sseStream =
|
|
1075
|
+
sseStream = createTimelineStream({
|
|
1070
1076
|
url: client.sessionTimelineUrl(resolvedSessionId),
|
|
1071
1077
|
apiKey: options.server.apiKey,
|
|
1072
1078
|
tenantId: options.server.tenantId,
|
|
@@ -1210,7 +1216,7 @@ var PushTimelineStream = class {
|
|
|
1210
1216
|
}
|
|
1211
1217
|
};
|
|
1212
1218
|
async function createFlitroRuntime(options) {
|
|
1213
|
-
const client = new
|
|
1219
|
+
const client = new WeftHttpClient(options.server);
|
|
1214
1220
|
const probe = await probeFlitroCapabilities(client);
|
|
1215
1221
|
return createFlitroProviderRuntime({
|
|
1216
1222
|
server: options.server,
|
|
@@ -1229,16 +1235,16 @@ async function createFlitroRuntime(options) {
|
|
|
1229
1235
|
}
|
|
1230
1236
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1231
1237
|
0 && (module.exports = {
|
|
1232
|
-
FlitroFetchSseTimelineStream,
|
|
1233
|
-
FlitroHttpClient,
|
|
1234
|
-
FlitroSseTimelineStream,
|
|
1235
1238
|
WeftClient,
|
|
1239
|
+
WeftFetchSseTimelineStream,
|
|
1240
|
+
WeftHttpClient,
|
|
1241
|
+
WeftSseTimelineStream,
|
|
1236
1242
|
createFlitroDriver,
|
|
1237
1243
|
createFlitroEmbedRuntime,
|
|
1238
1244
|
createFlitroProviderRuntime,
|
|
1239
1245
|
createFlitroRuntime,
|
|
1240
1246
|
createFlitroRuntimeCandidates,
|
|
1241
1247
|
createFlitroRuntimeCapabilityReport,
|
|
1242
|
-
|
|
1248
|
+
createTimelineStream,
|
|
1243
1249
|
probeFlitroCapabilities
|
|
1244
1250
|
});
|