@geminixiang/mikan 1.0.0-beta.87 → 1.0.0-beta.89
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/CHANGELOG.md +44 -1370
- package/README.md +2 -2
- package/dist/adapters/commands/session-view.d.ts.map +1 -1
- package/dist/adapters/commands/session-view.js +4 -4
- package/dist/adapters/commands/session-view.js.map +1 -1
- package/dist/adapters/discord/bot.d.ts +4 -1
- package/dist/adapters/discord/bot.d.ts.map +1 -1
- package/dist/adapters/discord/bot.js +6 -3
- package/dist/adapters/discord/bot.js.map +1 -1
- package/dist/adapters/discord/context.d.ts.map +1 -1
- package/dist/adapters/discord/context.js +3 -1
- package/dist/adapters/discord/context.js.map +1 -1
- package/dist/adapters/discord/types.d.ts +1 -0
- package/dist/adapters/discord/types.d.ts.map +1 -1
- package/dist/adapters/discord/types.js.map +1 -1
- package/dist/adapters/github/activity.d.ts.map +1 -1
- package/dist/adapters/github/activity.js +7 -13
- package/dist/adapters/github/activity.js.map +1 -1
- package/dist/adapters/github/bot.d.ts +4 -1
- package/dist/adapters/github/bot.d.ts.map +1 -1
- package/dist/adapters/github/bot.js +3 -3
- package/dist/adapters/github/bot.js.map +1 -1
- package/dist/adapters/github/context.d.ts.map +1 -1
- package/dist/adapters/github/context.js +3 -1
- package/dist/adapters/github/context.js.map +1 -1
- package/dist/adapters/github/types.d.ts +0 -3
- package/dist/adapters/github/types.d.ts.map +1 -1
- package/dist/adapters/github/types.js.map +1 -1
- package/dist/adapters/intake.d.ts.map +1 -1
- package/dist/adapters/intake.js +12 -2
- package/dist/adapters/intake.js.map +1 -1
- package/dist/adapters/shared.d.ts +2 -1
- package/dist/adapters/shared.d.ts.map +1 -1
- package/dist/adapters/shared.js +7 -2
- package/dist/adapters/shared.js.map +1 -1
- package/dist/adapters/slack/assistant.d.ts +2 -4
- package/dist/adapters/slack/assistant.d.ts.map +1 -1
- package/dist/adapters/slack/assistant.js +10 -16
- package/dist/adapters/slack/assistant.js.map +1 -1
- package/dist/adapters/slack/bot.d.ts +5 -1
- package/dist/adapters/slack/bot.d.ts.map +1 -1
- package/dist/adapters/slack/bot.js +15 -11
- package/dist/adapters/slack/bot.js.map +1 -1
- package/dist/adapters/slack/response-lifecycle.d.ts.map +1 -1
- package/dist/adapters/slack/response-lifecycle.js +1 -1
- package/dist/adapters/slack/response-lifecycle.js.map +1 -1
- package/dist/adapters/slack/task-status.d.ts.map +1 -1
- package/dist/adapters/slack/task-status.js +1 -2
- package/dist/adapters/slack/task-status.js.map +1 -1
- package/dist/adapters/telegram/bot.d.ts +4 -1
- package/dist/adapters/telegram/bot.d.ts.map +1 -1
- package/dist/adapters/telegram/bot.js +3 -3
- package/dist/adapters/telegram/bot.js.map +1 -1
- package/dist/adapters/telegram/context.d.ts.map +1 -1
- package/dist/adapters/telegram/context.js +3 -1
- package/dist/adapters/telegram/context.js.map +1 -1
- package/dist/adapters/types.d.ts +3 -1
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/types.js.map +1 -1
- package/dist/adapters/web/admin/client-assets.js +1 -1
- package/dist/adapters/web/admin/client-assets.js.map +1 -1
- package/dist/adapters/web/admin/portal.d.ts +0 -1
- package/dist/adapters/web/admin/portal.d.ts.map +1 -1
- package/dist/adapters/web/admin/portal.js +26 -42
- package/dist/adapters/web/admin/portal.js.map +1 -1
- package/dist/adapters/web/admin/types.d.ts +0 -2
- package/dist/adapters/web/admin/types.d.ts.map +1 -1
- package/dist/adapters/web/admin/types.js.map +1 -1
- package/dist/adapters/web/login/portal.d.ts.map +1 -1
- package/dist/adapters/web/login/portal.js +0 -8
- package/dist/adapters/web/login/portal.js.map +1 -1
- package/dist/adapters/web/server.d.ts.map +1 -1
- package/dist/adapters/web/server.js +0 -1
- package/dist/adapters/web/server.js.map +1 -1
- package/dist/adapters/web/session-view/portal.d.ts +1 -2
- package/dist/adapters/web/session-view/portal.d.ts.map +1 -1
- package/dist/adapters/web/session-view/portal.js +38 -328
- package/dist/adapters/web/session-view/portal.js.map +1 -1
- package/dist/adapters/web/session-view/types.d.ts +4 -6
- package/dist/adapters/web/session-view/types.d.ts.map +1 -1
- package/dist/adapters/web/session-view/types.js.map +1 -1
- package/dist/env-manifest.d.ts +0 -4
- package/dist/env-manifest.d.ts.map +1 -1
- package/dist/env-manifest.js +5 -8
- package/dist/env-manifest.js.map +1 -1
- package/dist/events/index.d.ts +2 -9
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +0 -1
- package/dist/events/index.js.map +1 -1
- package/dist/events/scheduler.d.ts +0 -1
- package/dist/events/scheduler.d.ts.map +1 -1
- package/dist/events/scheduler.js +2 -7
- package/dist/events/scheduler.js.map +1 -1
- package/dist/harness/execution-env.d.ts +1 -1
- package/dist/harness/execution-env.d.ts.map +1 -1
- package/dist/harness/execution-env.js +32 -32
- package/dist/harness/execution-env.js.map +1 -1
- package/dist/harness/index.d.ts +2 -3
- package/dist/harness/index.d.ts.map +1 -1
- package/dist/harness/index.js +0 -1
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/mcp-result.d.ts +4 -3
- package/dist/harness/mcp-result.d.ts.map +1 -1
- package/dist/harness/mcp-result.js +27 -13
- package/dist/harness/mcp-result.js.map +1 -1
- package/dist/harness/mcp.js +4 -4
- package/dist/harness/mcp.js.map +1 -1
- package/dist/harness/presenter.d.ts.map +1 -1
- package/dist/harness/presenter.js +20 -25
- package/dist/harness/presenter.js.map +1 -1
- package/dist/harness/prompt.d.ts +0 -1
- package/dist/harness/prompt.d.ts.map +1 -1
- package/dist/harness/prompt.js +3 -32
- package/dist/harness/prompt.js.map +1 -1
- package/dist/harness/run-events.d.ts.map +1 -1
- package/dist/harness/run-events.js +4 -12
- package/dist/harness/run-events.js.map +1 -1
- package/dist/harness/runner.d.ts.map +1 -1
- package/dist/harness/runner.js +35 -38
- package/dist/harness/runner.js.map +1 -1
- package/dist/harness/session.d.ts +37 -38
- package/dist/harness/session.d.ts.map +1 -1
- package/dist/harness/session.js +387 -388
- package/dist/harness/session.js.map +1 -1
- package/dist/harness/subagent.d.ts +5 -5
- package/dist/harness/subagent.d.ts.map +1 -1
- package/dist/harness/subagent.js +40 -45
- package/dist/harness/subagent.js.map +1 -1
- package/dist/harness/tools/codemode.d.ts +3 -0
- package/dist/harness/tools/codemode.d.ts.map +1 -0
- package/dist/harness/tools/codemode.js +173 -0
- package/dist/harness/tools/codemode.js.map +1 -0
- package/dist/harness/tools/history.d.ts +20 -0
- package/dist/harness/tools/history.d.ts.map +1 -0
- package/dist/harness/tools/history.js +293 -0
- package/dist/harness/tools/history.js.map +1 -0
- package/dist/harness/tools/pi-tools.d.ts +1 -1
- package/dist/harness/tools/pi-tools.d.ts.map +1 -1
- package/dist/harness/tools/pi-tools.js +47 -21
- package/dist/harness/tools/pi-tools.js.map +1 -1
- package/dist/harness/tools/secret-redaction.d.ts.map +1 -1
- package/dist/harness/tools/secret-redaction.js +46 -2
- package/dist/harness/tools/secret-redaction.js.map +1 -1
- package/dist/harness/tools/tool-search.d.ts +5 -0
- package/dist/harness/tools/tool-search.d.ts.map +1 -0
- package/dist/harness/tools/tool-search.js +84 -0
- package/dist/harness/tools/tool-search.js.map +1 -0
- package/dist/harness/types.d.ts +75 -15
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/index.d.ts +3 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -3
- package/dist/index.js.map +1 -1
- package/dist/log.d.ts +0 -3
- package/dist/log.d.ts.map +1 -1
- package/dist/log.js +0 -15
- package/dist/log.js.map +1 -1
- package/dist/main.js +2 -2
- package/dist/main.js.map +1 -1
- package/dist/memory-capture/index.js +0 -1
- package/dist/memory-capture/index.js.map +1 -1
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/migrations/index.js +2 -0
- package/dist/migrations/index.js.map +1 -1
- package/dist/migrations/session-files.d.ts +3 -2
- package/dist/migrations/session-files.d.ts.map +1 -1
- package/dist/migrations/session-files.js.map +1 -1
- package/dist/migrations/session-v4.d.ts +77 -0
- package/dist/migrations/session-v4.d.ts.map +1 -0
- package/dist/migrations/session-v4.js +177 -0
- package/dist/migrations/session-v4.js.map +1 -0
- package/dist/migrations/sessions-sqlite.d.ts +3 -0
- package/dist/migrations/sessions-sqlite.d.ts.map +1 -0
- package/dist/migrations/sessions-sqlite.js +215 -0
- package/dist/migrations/sessions-sqlite.js.map +1 -0
- package/dist/migrations/sessions-v3.d.ts +2 -2
- package/dist/migrations/sessions-v3.d.ts.map +1 -1
- package/dist/migrations/sessions-v3.js +8 -19
- package/dist/migrations/sessions-v3.js.map +1 -1
- package/dist/migrations/types.d.ts +0 -5
- package/dist/migrations/types.d.ts.map +1 -1
- package/dist/migrations/types.js.map +1 -1
- package/dist/observability/sentry.d.ts +2 -9
- package/dist/observability/sentry.d.ts.map +1 -1
- package/dist/observability/sentry.js +12 -64
- package/dist/observability/sentry.js.map +1 -1
- package/dist/observability/types.d.ts +0 -16
- package/dist/observability/types.d.ts.map +1 -1
- package/dist/observability/types.js.map +1 -1
- package/dist/office/index.d.ts +1 -4
- package/dist/office/index.d.ts.map +1 -1
- package/dist/office/index.js +2 -14
- package/dist/office/index.js.map +1 -1
- package/dist/office/projection.d.ts.map +1 -1
- package/dist/office/projection.js +0 -1
- package/dist/office/projection.js.map +1 -1
- package/dist/office/types.d.ts +1 -2
- package/dist/office/types.d.ts.map +1 -1
- package/dist/office/types.js.map +1 -1
- package/dist/runtime/conversation-runtime.d.ts.map +1 -1
- package/dist/runtime/conversation-runtime.js +2 -16
- package/dist/runtime/conversation-runtime.js.map +1 -1
- package/dist/runtime/session-lifecycle.d.ts +1 -2
- package/dist/runtime/session-lifecycle.d.ts.map +1 -1
- package/dist/runtime/session-lifecycle.js +7 -16
- package/dist/runtime/session-lifecycle.js.map +1 -1
- package/dist/runtime/types.d.ts +0 -1
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/sandbox/provisioner.d.ts.map +1 -1
- package/dist/sandbox/provisioner.js +3 -4
- package/dist/sandbox/provisioner.js.map +1 -1
- package/dist/sessions/chat-history-sync.d.ts +8 -6
- package/dist/sessions/chat-history-sync.d.ts.map +1 -1
- package/dist/sessions/chat-history-sync.js +70 -143
- package/dist/sessions/chat-history-sync.js.map +1 -1
- package/dist/sessions/compaction-summary.d.ts +4 -0
- package/dist/sessions/compaction-summary.d.ts.map +1 -0
- package/dist/sessions/compaction-summary.js +16 -0
- package/dist/sessions/compaction-summary.js.map +1 -0
- package/dist/sessions/session-key.d.ts +1 -0
- package/dist/sessions/session-key.d.ts.map +1 -1
- package/dist/sessions/session-key.js +3 -0
- package/dist/sessions/session-key.js.map +1 -1
- package/dist/sessions/session-store.d.ts +47 -29
- package/dist/sessions/session-store.d.ts.map +1 -1
- package/dist/sessions/session-store.js +578 -484
- package/dist/sessions/session-store.js.map +1 -1
- package/dist/sessions/types.d.ts +60 -46
- package/dist/sessions/types.d.ts.map +1 -1
- package/dist/sessions/types.js +1 -1
- package/dist/sessions/types.js.map +1 -1
- package/dist/settings/apply.js +2 -2
- package/dist/settings/apply.js.map +1 -1
- package/dist/types.d.ts +10 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/vault/index.d.ts.map +1 -1
- package/dist/vault/index.js +0 -3
- package/dist/vault/index.js.map +1 -1
- package/dist/vault/types.d.ts +0 -3
- package/dist/vault/types.d.ts.map +1 -1
- package/dist/vault/types.js.map +1 -1
- package/package.json +8 -5
- package/dist/sessions/store.d.ts +0 -17
- package/dist/sessions/store.d.ts.map +0 -1
- package/dist/sessions/store.js +0 -211
- package/dist/sessions/store.js.map +0 -1
|
@@ -25,7 +25,6 @@ import { loadMcpTools } from "../../../harness/mcp.js";
|
|
|
25
25
|
import { isValidMcpServerName, parseStandardMcpServers, redactMcpUrl, } from "../../../harness/mcp.js";
|
|
26
26
|
import { applyConversationSettings, applyOfficeVisibility, applyGlobalSettings, } from "../../../settings/apply.js";
|
|
27
27
|
import { escapeHtml, jsonResponse as jsonRes, readJsonBody, renderPortalShell, } from "../portal-shell.js";
|
|
28
|
-
import { resolveExistingSessionFile } from "../session-view/portal.js";
|
|
29
28
|
import { PRODUCT_NAME } from "../../messages.js";
|
|
30
29
|
import { credentialAuthorizationKey } from "../../../sandbox/identity.js";
|
|
31
30
|
import { resolveWorkspaceProjection } from "../../../office/projection.js";
|
|
@@ -251,25 +250,18 @@ async function serveSessionUsage(res, services) {
|
|
|
251
250
|
jsonRes(res, 200, { sessions: rows });
|
|
252
251
|
}
|
|
253
252
|
async function listConversationSessionUsage(workspace, office, label) {
|
|
254
|
-
const
|
|
255
|
-
let files;
|
|
256
|
-
try {
|
|
257
|
-
files = readdirSync(sessionDir, { withFileTypes: true })
|
|
258
|
-
.filter((entry) => entry.isFile() && entry.name.endsWith(".jsonl"))
|
|
259
|
-
.map((entry) => entry.name);
|
|
260
|
-
}
|
|
261
|
-
catch {
|
|
262
|
-
return [];
|
|
263
|
-
}
|
|
253
|
+
const conversationOffice = workspace.office(office);
|
|
264
254
|
const rows = [];
|
|
265
|
-
for (const
|
|
266
|
-
rows.push(...(await readSessionUsage(
|
|
255
|
+
for (const session of await SessionStore.list(conversationOffice)) {
|
|
256
|
+
rows.push(...(await readSessionUsage(conversationOffice, session.key, office.conversationId, label)));
|
|
267
257
|
}
|
|
268
258
|
return rows;
|
|
269
259
|
}
|
|
270
|
-
async function readSessionUsage(
|
|
260
|
+
async function readSessionUsage(office, sessionKey, conversationId, label) {
|
|
271
261
|
try {
|
|
272
|
-
const manager = await SessionStore.inspect(
|
|
262
|
+
const manager = await SessionStore.inspect(office, sessionKey);
|
|
263
|
+
if (!manager)
|
|
264
|
+
return [];
|
|
273
265
|
const header = manager.getHeader();
|
|
274
266
|
const entries = await manager.getEntries();
|
|
275
267
|
const usage = entries.reduce((sum, entry) => {
|
|
@@ -293,9 +285,10 @@ async function readSessionUsage(sessionFile, conversationId, label) {
|
|
|
293
285
|
{
|
|
294
286
|
conversationId,
|
|
295
287
|
label,
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
288
|
+
sessionKey,
|
|
289
|
+
updatedAt: entries.length > 0
|
|
290
|
+
? new Date(entries.at(-1).timestamp).toISOString()
|
|
291
|
+
: new Date(header.createdAt).toISOString(),
|
|
299
292
|
...usage,
|
|
300
293
|
total,
|
|
301
294
|
},
|
|
@@ -344,15 +337,10 @@ async function serveConversationUsage(res, url, services) {
|
|
|
344
337
|
const cutoff = new Date(today);
|
|
345
338
|
cutoff.setDate(today.getDate() - (days - 1));
|
|
346
339
|
const flags = { hasOlder: false };
|
|
347
|
-
const
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
if (!entry.isFile() || !entry.name.endsWith(".jsonl"))
|
|
351
|
-
continue;
|
|
352
|
-
await accumulateSessionUsageByDay(join(sessionDir, entry.name), cutoff, buckets, flags);
|
|
353
|
-
}
|
|
340
|
+
const conversationOffice = workspace.office(office);
|
|
341
|
+
for (const session of await SessionStore.list(conversationOffice)) {
|
|
342
|
+
await accumulateSessionUsageByDay(conversationOffice, session.key, cutoff, buckets, flags);
|
|
354
343
|
}
|
|
355
|
-
catch { }
|
|
356
344
|
const series = order.map((key) => buckets.get(key) ?? emptyBucket(key));
|
|
357
345
|
const totals = series.reduce((sum, b) => {
|
|
358
346
|
sum.input += b.input;
|
|
@@ -380,9 +368,11 @@ async function serveConversationUsage(res, url, services) {
|
|
|
380
368
|
},
|
|
381
369
|
});
|
|
382
370
|
}
|
|
383
|
-
async function accumulateSessionUsageByDay(
|
|
371
|
+
async function accumulateSessionUsageByDay(office, sessionKey, cutoff, buckets, flags) {
|
|
384
372
|
try {
|
|
385
|
-
const manager = await SessionStore.inspect(
|
|
373
|
+
const manager = await SessionStore.inspect(office, sessionKey);
|
|
374
|
+
if (!manager)
|
|
375
|
+
return;
|
|
386
376
|
for (const entry of await manager.getEntries()) {
|
|
387
377
|
if (entry.type !== "message" || entry.message.role !== "assistant")
|
|
388
378
|
continue;
|
|
@@ -554,7 +544,7 @@ function serveConversationSlackUpdate(res, body, services, token) {
|
|
|
554
544
|
return { ok: true };
|
|
555
545
|
});
|
|
556
546
|
}
|
|
557
|
-
function serveConversationSessionLink(res, body, services, token) {
|
|
547
|
+
async function serveConversationSessionLink(res, body, services, token) {
|
|
558
548
|
const target = requireConversationWorkspace(res, body, services, token);
|
|
559
549
|
if (!target)
|
|
560
550
|
return;
|
|
@@ -569,9 +559,9 @@ function serveConversationSessionLink(res, body, services, token) {
|
|
|
569
559
|
});
|
|
570
560
|
return;
|
|
571
561
|
}
|
|
572
|
-
const
|
|
573
|
-
if (!
|
|
574
|
-
jsonRes(res, 404, { error: "No session
|
|
562
|
+
const office = workspace.office(scope.address);
|
|
563
|
+
if (!(await SessionStore.exists(office, scope.conversationId))) {
|
|
564
|
+
jsonRes(res, 404, { error: "No session found for this conversation" });
|
|
575
565
|
return;
|
|
576
566
|
}
|
|
577
567
|
try {
|
|
@@ -580,7 +570,7 @@ function serveConversationSessionLink(res, body, services, token) {
|
|
|
580
570
|
platformUserId: token.platformUserId,
|
|
581
571
|
conversationId: scope.conversationId,
|
|
582
572
|
sessionKey: scope.conversationId,
|
|
583
|
-
|
|
573
|
+
office,
|
|
584
574
|
platformUserName: token.platformUserName,
|
|
585
575
|
});
|
|
586
576
|
const url = `${services.portalBaseUrl}/session?token=${encodeURIComponent(viewToken)}`;
|
|
@@ -751,13 +741,11 @@ function buildTree(startDir, relPrefix) {
|
|
|
751
741
|
name,
|
|
752
742
|
path: rel,
|
|
753
743
|
type: "file",
|
|
754
|
-
size: stats.size,
|
|
755
|
-
mtimeMs: stats.mtimeMs,
|
|
756
744
|
};
|
|
757
745
|
}
|
|
758
746
|
counter.value += 1;
|
|
759
747
|
if (depth >= WORKSPACE_TREE_MAX_DEPTH) {
|
|
760
|
-
return { name, path: rel, type: "dir"
|
|
748
|
+
return { name, path: rel, type: "dir" };
|
|
761
749
|
}
|
|
762
750
|
let entries;
|
|
763
751
|
try {
|
|
@@ -767,7 +755,6 @@ function buildTree(startDir, relPrefix) {
|
|
|
767
755
|
return { name, path: rel, type: "dir" };
|
|
768
756
|
}
|
|
769
757
|
const children = [];
|
|
770
|
-
let truncated = false;
|
|
771
758
|
for (const entry of entries.toSorted((a, b) => {
|
|
772
759
|
if (a.isDirectory() !== b.isDirectory())
|
|
773
760
|
return a.isDirectory() ? -1 : 1;
|
|
@@ -777,7 +764,6 @@ function buildTree(startDir, relPrefix) {
|
|
|
777
764
|
if (!isWorkspacePathAllowed(childRel))
|
|
778
765
|
continue;
|
|
779
766
|
if (counter.value >= WORKSPACE_TREE_MAX_ENTRIES) {
|
|
780
|
-
truncated = true;
|
|
781
767
|
break;
|
|
782
768
|
}
|
|
783
769
|
const node = walk(join(dir, entry.name), childRel, depth + 1);
|
|
@@ -789,7 +775,6 @@ function buildTree(startDir, relPrefix) {
|
|
|
789
775
|
path: rel,
|
|
790
776
|
type: "dir",
|
|
791
777
|
children,
|
|
792
|
-
truncated: truncated ? true : undefined,
|
|
793
778
|
};
|
|
794
779
|
};
|
|
795
780
|
const node = walk(startDir, relPrefix, 0);
|
|
@@ -956,7 +941,6 @@ export function readSkillsFromDir(skillsDir, source) {
|
|
|
956
941
|
name: meta.name ?? entry.name,
|
|
957
942
|
description: meta.description ?? "",
|
|
958
943
|
source,
|
|
959
|
-
path: skillMd,
|
|
960
944
|
directory: entry.name,
|
|
961
945
|
});
|
|
962
946
|
}
|
|
@@ -1014,10 +998,10 @@ async function verifyMcpServers(servers) {
|
|
|
1014
998
|
if (failure) {
|
|
1015
999
|
const url = servers[name]?.url;
|
|
1016
1000
|
const error = url ? failure.error.split(url).join(redactMcpUrl(url)) : failure.error;
|
|
1017
|
-
return {
|
|
1001
|
+
return { error };
|
|
1018
1002
|
}
|
|
1019
1003
|
const prefix = `mcp__${name}__`;
|
|
1020
|
-
return {
|
|
1004
|
+
return { tools: loaded.tools.filter((t) => t.name.startsWith(prefix)).length };
|
|
1021
1005
|
});
|
|
1022
1006
|
}
|
|
1023
1007
|
finally {
|