@geminixiang/mikan 1.0.0-beta.76 → 1.0.0-beta.78
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 +39 -0
- package/dist/adapters/commands/login.d.ts.map +1 -1
- package/dist/adapters/commands/login.js +0 -9
- package/dist/adapters/commands/login.js.map +1 -1
- package/dist/adapters/commands/manifest.d.ts +0 -19
- package/dist/adapters/commands/manifest.d.ts.map +1 -1
- package/dist/adapters/commands/manifest.js +0 -34
- package/dist/adapters/commands/manifest.js.map +1 -1
- package/dist/adapters/commands/model.d.ts +0 -5
- package/dist/adapters/commands/model.d.ts.map +1 -1
- package/dist/adapters/commands/model.js +0 -5
- package/dist/adapters/commands/model.js.map +1 -1
- package/dist/adapters/commands/new.d.ts.map +1 -1
- package/dist/adapters/commands/new.js +0 -2
- package/dist/adapters/commands/new.js.map +1 -1
- package/dist/adapters/commands/registry.d.ts +0 -1
- package/dist/adapters/commands/registry.d.ts.map +1 -1
- package/dist/adapters/commands/registry.js +0 -8
- package/dist/adapters/commands/registry.js.map +1 -1
- package/dist/adapters/commands/session-view.d.ts.map +1 -1
- package/dist/adapters/commands/session-view.js +0 -2
- package/dist/adapters/commands/session-view.js.map +1 -1
- package/dist/adapters/commands/types.d.ts +0 -29
- package/dist/adapters/commands/types.d.ts.map +1 -1
- package/dist/adapters/commands/types.js.map +1 -1
- package/dist/adapters/commands/utils.d.ts +0 -3
- package/dist/adapters/commands/utils.d.ts.map +1 -1
- package/dist/adapters/commands/utils.js +0 -3
- package/dist/adapters/commands/utils.js.map +1 -1
- package/dist/adapters/discord/bot.d.ts +0 -4
- package/dist/adapters/discord/bot.d.ts.map +1 -1
- package/dist/adapters/discord/bot.js +5 -41
- package/dist/adapters/discord/bot.js.map +1 -1
- package/dist/adapters/discord/components.d.ts +0 -23
- package/dist/adapters/discord/components.d.ts.map +1 -1
- package/dist/adapters/discord/components.js +0 -23
- package/dist/adapters/discord/components.js.map +1 -1
- package/dist/adapters/discord/context.d.ts.map +1 -1
- package/dist/adapters/discord/context.js +1 -11
- package/dist/adapters/discord/context.js.map +1 -1
- package/dist/adapters/discord/format.d.ts +0 -1
- package/dist/adapters/discord/format.d.ts.map +1 -1
- package/dist/adapters/discord/format.js +0 -37
- package/dist/adapters/discord/format.js.map +1 -1
- package/dist/adapters/github/bot.d.ts +0 -44
- package/dist/adapters/github/bot.d.ts.map +1 -1
- package/dist/adapters/github/bot.js +1 -120
- package/dist/adapters/github/bot.js.map +1 -1
- package/dist/adapters/github/client.d.ts +0 -57
- package/dist/adapters/github/client.d.ts.map +1 -1
- package/dist/adapters/github/client.js +0 -59
- package/dist/adapters/github/client.js.map +1 -1
- package/dist/adapters/github/context.d.ts.map +1 -1
- package/dist/adapters/github/context.js +1 -8
- package/dist/adapters/github/context.js.map +1 -1
- package/dist/adapters/github/github-ops.d.ts +0 -55
- package/dist/adapters/github/github-ops.d.ts.map +1 -1
- package/dist/adapters/github/github-ops.js +0 -59
- package/dist/adapters/github/github-ops.js.map +1 -1
- package/dist/adapters/github/ids.d.ts +0 -27
- package/dist/adapters/github/ids.d.ts.map +1 -1
- package/dist/adapters/github/ids.js +0 -29
- package/dist/adapters/github/ids.js.map +1 -1
- package/dist/adapters/github/repo.d.ts +0 -25
- package/dist/adapters/github/repo.d.ts.map +1 -1
- package/dist/adapters/github/repo.js +0 -49
- package/dist/adapters/github/repo.js.map +1 -1
- package/dist/adapters/github/tool-pack.d.ts +0 -10
- package/dist/adapters/github/tool-pack.d.ts.map +1 -1
- package/dist/adapters/github/tool-pack.js +0 -10
- package/dist/adapters/github/tool-pack.js.map +1 -1
- package/dist/adapters/github/tools/checks.d.ts +0 -6
- package/dist/adapters/github/tools/checks.d.ts.map +1 -1
- package/dist/adapters/github/tools/checks.js +0 -7
- package/dist/adapters/github/tools/checks.js.map +1 -1
- package/dist/adapters/github/tools/issue.d.ts +0 -5
- package/dist/adapters/github/tools/issue.d.ts.map +1 -1
- package/dist/adapters/github/tools/issue.js +0 -5
- package/dist/adapters/github/tools/issue.js.map +1 -1
- package/dist/adapters/github/tools/pr.d.ts +0 -7
- package/dist/adapters/github/tools/pr.d.ts.map +1 -1
- package/dist/adapters/github/tools/pr.js +0 -7
- package/dist/adapters/github/tools/pr.js.map +1 -1
- package/dist/adapters/github/tools/read.d.ts +0 -6
- package/dist/adapters/github/tools/read.d.ts.map +1 -1
- package/dist/adapters/github/tools/read.js +0 -8
- package/dist/adapters/github/tools/read.js.map +1 -1
- package/dist/adapters/github/tools/review-reply.d.ts +0 -5
- package/dist/adapters/github/tools/review-reply.d.ts.map +1 -1
- package/dist/adapters/github/tools/review-reply.js +0 -5
- package/dist/adapters/github/tools/review-reply.js.map +1 -1
- package/dist/adapters/github/tools/sync.d.ts +0 -6
- package/dist/adapters/github/tools/sync.d.ts.map +1 -1
- package/dist/adapters/github/tools/sync.js +0 -6
- package/dist/adapters/github/tools/sync.js.map +1 -1
- package/dist/adapters/github/types.d.ts +0 -88
- package/dist/adapters/github/types.d.ts.map +1 -1
- package/dist/adapters/github/types.js.map +1 -1
- package/dist/adapters/github/webhook.d.ts +0 -13
- package/dist/adapters/github/webhook.d.ts.map +1 -1
- package/dist/adapters/github/webhook.js +0 -16
- package/dist/adapters/github/webhook.js.map +1 -1
- package/dist/adapters/index.d.ts +3 -4
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +4 -4
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/intake.d.ts +0 -17
- package/dist/adapters/intake.d.ts.map +1 -1
- package/dist/adapters/intake.js +6 -32
- package/dist/adapters/intake.js.map +1 -1
- package/dist/adapters/markdown-tables.d.ts +0 -10
- package/dist/adapters/markdown-tables.d.ts.map +1 -1
- package/dist/adapters/markdown-tables.js +1 -42
- package/dist/adapters/markdown-tables.js.map +1 -1
- package/dist/adapters/progressive-renderer.d.ts.map +1 -1
- package/dist/adapters/progressive-renderer.js +3 -25
- package/dist/adapters/progressive-renderer.js.map +1 -1
- package/dist/adapters/shared.d.ts +0 -57
- package/dist/adapters/shared.d.ts.map +1 -1
- package/dist/adapters/shared.js +0 -71
- package/dist/adapters/shared.js.map +1 -1
- package/dist/adapters/slack/assistant.d.ts +0 -49
- package/dist/adapters/slack/assistant.d.ts.map +1 -1
- package/dist/adapters/slack/assistant.js +0 -97
- package/dist/adapters/slack/assistant.js.map +1 -1
- package/dist/adapters/slack/auto-reply-context.d.ts +0 -7
- package/dist/adapters/slack/auto-reply-context.d.ts.map +1 -1
- package/dist/adapters/slack/auto-reply-context.js +0 -7
- package/dist/adapters/slack/auto-reply-context.js.map +1 -1
- package/dist/adapters/slack/blocks.d.ts +0 -9
- package/dist/adapters/slack/blocks.d.ts.map +1 -1
- package/dist/adapters/slack/blocks.js +0 -20
- package/dist/adapters/slack/blocks.js.map +1 -1
- package/dist/adapters/slack/bot.d.ts +0 -116
- package/dist/adapters/slack/bot.d.ts.map +1 -1
- package/dist/adapters/slack/bot.js +7 -231
- package/dist/adapters/slack/bot.js.map +1 -1
- package/dist/adapters/slack/context.d.ts.map +1 -1
- package/dist/adapters/slack/context.js +1 -3
- package/dist/adapters/slack/context.js.map +1 -1
- package/dist/adapters/slack/jev-context.d.ts +0 -13
- package/dist/adapters/slack/jev-context.d.ts.map +1 -1
- package/dist/adapters/slack/jev-context.js +0 -12
- package/dist/adapters/slack/jev-context.js.map +1 -1
- package/dist/adapters/slack/markdown.d.ts +0 -1
- package/dist/adapters/slack/markdown.d.ts.map +1 -1
- package/dist/adapters/slack/markdown.js +0 -5
- package/dist/adapters/slack/markdown.js.map +1 -1
- package/dist/adapters/slack/persona.d.ts +0 -9
- package/dist/adapters/slack/persona.d.ts.map +1 -1
- package/dist/adapters/slack/persona.js +0 -9
- package/dist/adapters/slack/persona.js.map +1 -1
- package/dist/adapters/slack/response-lifecycle.d.ts.map +1 -1
- package/dist/adapters/slack/response-lifecycle.js +1 -45
- package/dist/adapters/slack/response-lifecycle.js.map +1 -1
- package/dist/adapters/slack/session.d.ts +2 -1
- package/dist/adapters/slack/session.d.ts.map +1 -1
- package/dist/adapters/slack/session.js +2 -2
- package/dist/adapters/slack/session.js.map +1 -1
- package/dist/adapters/slack/stream-limits.d.ts +0 -25
- package/dist/adapters/slack/stream-limits.d.ts.map +1 -1
- package/dist/adapters/slack/stream-limits.js +0 -34
- package/dist/adapters/slack/stream-limits.js.map +1 -1
- package/dist/adapters/slack/task-intent.d.ts +0 -13
- package/dist/adapters/slack/task-intent.d.ts.map +1 -1
- package/dist/adapters/slack/task-intent.js +0 -7
- package/dist/adapters/slack/task-intent.js.map +1 -1
- package/dist/adapters/slack/task-status.d.ts +0 -1
- package/dist/adapters/slack/task-status.d.ts.map +1 -1
- package/dist/adapters/slack/task-status.js +1 -9
- package/dist/adapters/slack/task-status.js.map +1 -1
- package/dist/adapters/slack/tool-pack.d.ts +0 -6
- package/dist/adapters/slack/tool-pack.d.ts.map +1 -1
- package/dist/adapters/slack/tool-pack.js +0 -6
- package/dist/adapters/slack/tool-pack.js.map +1 -1
- package/dist/adapters/slack/tools/blockkit.d.ts.map +1 -1
- package/dist/adapters/slack/tools/blockkit.js +0 -11
- package/dist/adapters/slack/tools/blockkit.js.map +1 -1
- package/dist/adapters/slack/types.d.ts +0 -19
- package/dist/adapters/slack/types.d.ts.map +1 -1
- package/dist/adapters/slack/types.js.map +1 -1
- package/dist/adapters/slack/update-diagnostics.d.ts +0 -1
- package/dist/adapters/slack/update-diagnostics.d.ts.map +1 -1
- package/dist/adapters/slack/update-diagnostics.js +1 -7
- package/dist/adapters/slack/update-diagnostics.js.map +1 -1
- package/dist/adapters/telegram/bot.d.ts +0 -6
- package/dist/adapters/telegram/bot.d.ts.map +1 -1
- package/dist/adapters/telegram/bot.js +1 -50
- 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 +1 -8
- package/dist/adapters/telegram/context.js.map +1 -1
- package/dist/adapters/types.d.ts +0 -57
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/types.js.map +1 -1
- package/dist/adapters/web/admin/client-assets.d.ts +4 -0
- package/dist/adapters/web/admin/client-assets.d.ts.map +1 -0
- package/dist/adapters/web/admin/client-assets.js +1765 -0
- package/dist/adapters/web/admin/client-assets.js.map +1 -0
- package/dist/adapters/web/admin/portal.d.ts +0 -10
- package/dist/adapters/web/admin/portal.d.ts.map +1 -1
- package/dist/adapters/web/admin/portal.js +6 -1909
- package/dist/adapters/web/admin/portal.js.map +1 -1
- package/dist/adapters/web/admin/types.d.ts +0 -3
- 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/oauth.d.ts.map +1 -1
- package/dist/adapters/web/login/oauth.js +3 -7
- package/dist/adapters/web/login/oauth.js.map +1 -1
- package/dist/adapters/web/login/portal.d.ts +0 -10
- package/dist/adapters/web/login/portal.d.ts.map +1 -1
- package/dist/adapters/web/login/portal.js +4 -37
- package/dist/adapters/web/login/portal.js.map +1 -1
- package/dist/adapters/web/login/types.d.ts +0 -5
- package/dist/adapters/web/login/types.d.ts.map +1 -1
- package/dist/adapters/web/login/types.js.map +1 -1
- package/dist/adapters/web/portal-shell.d.ts +0 -12
- package/dist/adapters/web/portal-shell.d.ts.map +1 -1
- package/dist/adapters/web/portal-shell.js +8 -25
- package/dist/adapters/web/portal-shell.js.map +1 -1
- package/dist/adapters/web/server.d.ts +0 -1
- package/dist/adapters/web/server.d.ts.map +1 -1
- package/dist/adapters/web/server.js +0 -2
- package/dist/adapters/web/server.js.map +1 -1
- package/dist/adapters/web/session-view/portal.d.ts.map +1 -1
- package/dist/adapters/web/session-view/portal.js +13 -24
- package/dist/adapters/web/session-view/portal.js.map +1 -1
- 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/adapters/web/token-store.d.ts +0 -2
- package/dist/adapters/web/token-store.d.ts.map +1 -1
- package/dist/adapters/web/token-store.js +0 -2
- package/dist/adapters/web/token-store.js.map +1 -1
- package/dist/cli/arg-grammar.d.ts +0 -3
- package/dist/cli/arg-grammar.d.ts.map +1 -1
- package/dist/cli/arg-grammar.js +0 -3
- package/dist/cli/arg-grammar.js.map +1 -1
- package/dist/cli/boot.d.ts.map +1 -1
- package/dist/cli/boot.js +3 -12
- package/dist/cli/boot.js.map +1 -1
- package/dist/cli/download.d.ts.map +1 -1
- package/dist/cli/download.js +2 -6
- package/dist/cli/download.js.map +1 -1
- package/dist/cli/office.d.ts.map +1 -1
- package/dist/cli/office.js +0 -31
- package/dist/cli/office.js.map +1 -1
- package/dist/cli/onboard.d.ts +0 -2
- package/dist/cli/onboard.d.ts.map +1 -1
- package/dist/cli/onboard.js +0 -30
- package/dist/cli/onboard.js.map +1 -1
- package/dist/cli/process-lifecycle.d.ts +0 -5
- package/dist/cli/process-lifecycle.d.ts.map +1 -1
- package/dist/cli/process-lifecycle.js +0 -6
- package/dist/cli/process-lifecycle.js.map +1 -1
- package/dist/cli/sandbox.d.ts +3 -0
- package/dist/cli/sandbox.d.ts.map +1 -0
- package/dist/cli/sandbox.js +79 -0
- package/dist/cli/sandbox.js.map +1 -0
- package/dist/cli/sessions.d.ts.map +1 -1
- package/dist/cli/sessions.js +0 -11
- package/dist/cli/sessions.js.map +1 -1
- package/dist/cli/types.d.ts +2 -6
- package/dist/cli/types.d.ts.map +1 -1
- package/dist/cli/types.js.map +1 -1
- package/dist/env-manifest.d.ts +0 -21
- package/dist/env-manifest.d.ts.map +1 -1
- package/dist/env-manifest.js +0 -11
- package/dist/env-manifest.js.map +1 -1
- package/dist/events/index.d.ts +0 -51
- package/dist/events/index.d.ts.map +1 -1
- package/dist/events/index.js +0 -42
- package/dist/events/index.js.map +1 -1
- package/dist/events/scheduler.d.ts +0 -8
- package/dist/events/scheduler.d.ts.map +1 -1
- package/dist/events/scheduler.js +0 -8
- package/dist/events/scheduler.js.map +1 -1
- package/dist/file-guards.d.ts +0 -15
- package/dist/file-guards.d.ts.map +1 -1
- package/dist/file-guards.js +2 -26
- package/dist/file-guards.js.map +1 -1
- package/dist/harness/execution-env.d.ts +0 -15
- package/dist/harness/execution-env.d.ts.map +1 -1
- package/dist/harness/execution-env.js +4 -55
- package/dist/harness/execution-env.js.map +1 -1
- package/dist/harness/http.d.ts +0 -12
- package/dist/harness/http.d.ts.map +1 -1
- package/dist/harness/http.js +0 -34
- package/dist/harness/http.js.map +1 -1
- package/dist/harness/index.d.ts +4 -7
- package/dist/harness/index.d.ts.map +1 -1
- package/dist/harness/index.js +4 -7
- package/dist/harness/index.js.map +1 -1
- package/dist/harness/jev.d.ts +0 -28
- package/dist/harness/jev.d.ts.map +1 -1
- package/dist/harness/jev.js +0 -45
- package/dist/harness/jev.js.map +1 -1
- package/dist/harness/mcp-result.d.ts +20 -0
- package/dist/harness/mcp-result.d.ts.map +1 -0
- package/dist/harness/mcp-result.js +171 -0
- package/dist/harness/mcp-result.js.map +1 -0
- package/dist/harness/mcp.d.ts +0 -19
- package/dist/harness/mcp.d.ts.map +1 -1
- package/dist/harness/mcp.js +7 -66
- package/dist/harness/mcp.js.map +1 -1
- package/dist/harness/models.d.ts +0 -19
- package/dist/harness/models.d.ts.map +1 -1
- package/dist/harness/models.js +0 -52
- package/dist/harness/models.js.map +1 -1
- package/dist/harness/open-connector.d.ts +0 -12
- package/dist/harness/open-connector.d.ts.map +1 -1
- package/dist/harness/open-connector.js +0 -22
- package/dist/harness/open-connector.js.map +1 -1
- package/dist/harness/presenter.d.ts +1 -0
- package/dist/harness/presenter.d.ts.map +1 -1
- package/dist/harness/presenter.js +16 -66
- package/dist/harness/presenter.js.map +1 -1
- package/dist/harness/prompt.d.ts +0 -11
- package/dist/harness/prompt.d.ts.map +1 -1
- package/dist/harness/prompt.js +1 -18
- package/dist/harness/prompt.js.map +1 -1
- package/dist/harness/runner.d.ts.map +1 -1
- package/dist/harness/runner.js +8 -28
- package/dist/harness/runner.js.map +1 -1
- package/dist/harness/session.d.ts +11 -28
- package/dist/harness/session.d.ts.map +1 -1
- package/dist/harness/session.js +100 -38
- package/dist/harness/session.js.map +1 -1
- package/dist/harness/skills.d.ts +0 -22
- package/dist/harness/skills.d.ts.map +1 -1
- package/dist/harness/skills.js +0 -20
- package/dist/harness/skills.js.map +1 -1
- package/dist/harness/subagent-profiles.d.ts +0 -4
- package/dist/harness/subagent-profiles.d.ts.map +1 -1
- package/dist/harness/subagent-profiles.js +0 -29
- package/dist/harness/subagent-profiles.js.map +1 -1
- package/dist/harness/subagent.d.ts +0 -25
- package/dist/harness/subagent.d.ts.map +1 -1
- package/dist/harness/subagent.js +1 -70
- package/dist/harness/subagent.js.map +1 -1
- package/dist/harness/tools/event.d.ts.map +1 -1
- package/dist/harness/tools/event.js +0 -9
- package/dist/harness/tools/event.js.map +1 -1
- package/dist/harness/tools/generate-image.d.ts +0 -6
- package/dist/harness/tools/generate-image.d.ts.map +1 -1
- package/dist/harness/tools/generate-image.js.map +1 -1
- package/dist/harness/tools/host-fn-tool.d.ts +0 -17
- package/dist/harness/tools/host-fn-tool.d.ts.map +1 -1
- package/dist/harness/tools/host-fn-tool.js +0 -16
- package/dist/harness/tools/host-fn-tool.js.map +1 -1
- package/dist/harness/tools/index.d.ts +1 -7
- package/dist/harness/tools/index.d.ts.map +1 -1
- package/dist/harness/tools/index.js +3 -14
- package/dist/harness/tools/index.js.map +1 -1
- package/dist/harness/tools/jev-browser.d.ts +4 -94
- package/dist/harness/tools/jev-browser.d.ts.map +1 -1
- package/dist/harness/tools/jev-browser.js +203 -92
- package/dist/harness/tools/jev-browser.js.map +1 -1
- package/dist/harness/tools/jev.d.ts +0 -8
- package/dist/harness/tools/jev.d.ts.map +1 -1
- package/dist/harness/tools/jev.js +0 -11
- package/dist/harness/tools/jev.js.map +1 -1
- package/dist/harness/tools/pi-tools.d.ts +1 -11
- package/dist/harness/tools/pi-tools.d.ts.map +1 -1
- package/dist/harness/tools/pi-tools.js +1 -30
- package/dist/harness/tools/pi-tools.js.map +1 -1
- package/dist/harness/tools/react.d.ts +0 -5
- package/dist/harness/tools/react.d.ts.map +1 -1
- package/dist/harness/tools/react.js +0 -5
- package/dist/harness/tools/react.js.map +1 -1
- package/dist/harness/tools/secret-redaction.d.ts +0 -25
- package/dist/harness/tools/secret-redaction.d.ts.map +1 -1
- package/dist/harness/tools/secret-redaction.js +3 -36
- package/dist/harness/tools/secret-redaction.js.map +1 -1
- package/dist/harness/tools/subagent.d.ts +0 -34
- package/dist/harness/tools/subagent.d.ts.map +1 -1
- package/dist/harness/tools/subagent.js +0 -92
- package/dist/harness/tools/subagent.js.map +1 -1
- package/dist/harness/tools/task.d.ts +0 -1
- package/dist/harness/tools/task.d.ts.map +1 -1
- package/dist/harness/tools/task.js +0 -1
- package/dist/harness/tools/task.js.map +1 -1
- package/dist/harness/tools/types.d.ts +0 -16
- package/dist/harness/tools/types.d.ts.map +1 -1
- package/dist/harness/tools/types.js.map +1 -1
- package/dist/harness/types.d.ts +1 -77
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -2
- package/dist/index.js.map +1 -1
- package/dist/log.d.ts.map +1 -1
- package/dist/log.js +0 -13
- package/dist/log.js.map +1 -1
- package/dist/main.js +7 -52
- package/dist/main.js.map +1 -1
- package/dist/memory-capture/index.d.ts +16 -0
- package/dist/memory-capture/index.d.ts.map +1 -0
- package/dist/memory-capture/index.js +194 -0
- package/dist/memory-capture/index.js.map +1 -0
- package/dist/memory-capture/types.d.ts +27 -0
- package/dist/memory-capture/types.d.ts.map +1 -0
- package/dist/memory-capture/types.js.map +1 -0
- package/dist/observability/index.d.ts +0 -9
- package/dist/observability/index.d.ts.map +1 -1
- package/dist/observability/index.js +0 -9
- package/dist/observability/index.js.map +1 -1
- package/dist/observability/instrument.js +0 -5
- package/dist/observability/instrument.js.map +1 -1
- package/dist/observability/otel.js +0 -1
- package/dist/observability/otel.js.map +1 -1
- package/dist/observability/sentry.d.ts +0 -18
- package/dist/observability/sentry.d.ts.map +1 -1
- package/dist/observability/sentry.js +0 -36
- package/dist/observability/sentry.js.map +1 -1
- package/dist/observability/types.d.ts +1 -10
- package/dist/observability/types.d.ts.map +1 -1
- package/dist/observability/types.js.map +1 -1
- package/dist/office/index.d.ts +0 -76
- package/dist/office/index.d.ts.map +1 -1
- package/dist/office/index.js +4 -154
- package/dist/office/index.js.map +1 -1
- package/dist/office/projection.d.ts +0 -29
- package/dist/office/projection.d.ts.map +1 -1
- package/dist/office/projection.js +5 -41
- package/dist/office/projection.js.map +1 -1
- package/dist/office/types.d.ts +0 -66
- 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 +22 -83
- package/dist/runtime/conversation-runtime.js.map +1 -1
- package/dist/runtime/session-lifecycle.d.ts +0 -10
- package/dist/runtime/session-lifecycle.d.ts.map +1 -1
- package/dist/runtime/session-lifecycle.js +0 -12
- package/dist/runtime/session-lifecycle.js.map +1 -1
- package/dist/runtime/types.d.ts +2 -29
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/sandbox/cloudflare.d.ts.map +1 -1
- package/dist/sandbox/cloudflare.js +2 -1
- package/dist/sandbox/cloudflare.js.map +1 -1
- package/dist/sandbox/container.d.ts.map +1 -1
- package/dist/sandbox/container.js +21 -15
- package/dist/sandbox/container.js.map +1 -1
- package/dist/sandbox/host.d.ts.map +1 -1
- package/dist/sandbox/host.js +0 -2
- package/dist/sandbox/host.js.map +1 -1
- package/dist/sandbox/identity.d.ts +0 -28
- package/dist/sandbox/identity.d.ts.map +1 -1
- package/dist/sandbox/identity.js +0 -28
- package/dist/sandbox/identity.js.map +1 -1
- package/dist/sandbox/index.d.ts +0 -18
- package/dist/sandbox/index.d.ts.map +1 -1
- package/dist/sandbox/index.js +2 -19
- package/dist/sandbox/index.js.map +1 -1
- package/dist/sandbox/layout.d.ts +7 -0
- package/dist/sandbox/layout.d.ts.map +1 -0
- package/dist/sandbox/layout.js +13 -0
- package/dist/sandbox/layout.js.map +1 -0
- package/dist/sandbox/provisioner.d.ts +24 -65
- package/dist/sandbox/provisioner.d.ts.map +1 -1
- package/dist/sandbox/provisioner.js +213 -125
- package/dist/sandbox/provisioner.js.map +1 -1
- package/dist/sandbox/types.d.ts +0 -39
- package/dist/sandbox/types.d.ts.map +1 -1
- package/dist/sandbox/types.js.map +1 -1
- package/dist/sandbox/utils.d.ts +2 -5
- package/dist/sandbox/utils.d.ts.map +1 -1
- package/dist/sandbox/utils.js +31 -31
- package/dist/sandbox/utils.js.map +1 -1
- package/dist/sessions/chat-history-sync.d.ts +0 -6
- package/dist/sessions/chat-history-sync.d.ts.map +1 -1
- package/dist/sessions/chat-history-sync.js +1 -33
- package/dist/sessions/chat-history-sync.js.map +1 -1
- package/dist/sessions/history-line.d.ts +0 -20
- package/dist/sessions/history-line.d.ts.map +1 -1
- package/dist/sessions/history-line.js +0 -20
- package/dist/sessions/history-line.js.map +1 -1
- package/dist/sessions/migrate-common.d.ts +0 -15
- package/dist/sessions/migrate-common.d.ts.map +1 -1
- package/dist/sessions/migrate-common.js +0 -19
- package/dist/sessions/migrate-common.js.map +1 -1
- package/dist/sessions/migrate-pi-084.d.ts.map +1 -1
- package/dist/sessions/migrate-pi-084.js +0 -7
- package/dist/sessions/migrate-pi-084.js.map +1 -1
- package/dist/sessions/migrate-v3.d.ts +0 -7
- package/dist/sessions/migrate-v3.d.ts.map +1 -1
- package/dist/sessions/migrate-v3.js +1 -67
- package/dist/sessions/migrate-v3.js.map +1 -1
- package/dist/sessions/session-key.d.ts +3 -17
- package/dist/sessions/session-key.d.ts.map +1 -1
- package/dist/sessions/session-key.js +8 -35
- package/dist/sessions/session-key.js.map +1 -1
- package/dist/sessions/session-store.d.ts +1 -7
- package/dist/sessions/session-store.d.ts.map +1 -1
- package/dist/sessions/session-store.js +8 -50
- package/dist/sessions/session-store.js.map +1 -1
- package/dist/sessions/store.d.ts +0 -60
- package/dist/sessions/store.d.ts.map +1 -1
- package/dist/sessions/store.js +0 -113
- package/dist/sessions/store.js.map +1 -1
- package/dist/sessions/types.d.ts +0 -17
- package/dist/sessions/types.d.ts.map +1 -1
- package/dist/sessions/types.js.map +1 -1
- package/dist/settings/apply.d.ts +0 -6
- package/dist/settings/apply.d.ts.map +1 -1
- package/dist/settings/apply.js +0 -29
- package/dist/settings/apply.js.map +1 -1
- package/dist/settings/index.d.ts +0 -53
- package/dist/settings/index.d.ts.map +1 -1
- package/dist/settings/index.js +0 -77
- package/dist/settings/index.js.map +1 -1
- package/dist/settings/migrate.d.ts +0 -5
- package/dist/settings/migrate.d.ts.map +1 -1
- package/dist/settings/migrate.js +0 -17
- package/dist/settings/migrate.js.map +1 -1
- package/dist/types.d.ts +9 -159
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/vault/index.d.ts +2 -36
- package/dist/vault/index.d.ts.map +1 -1
- package/dist/vault/index.js +135 -65
- package/dist/vault/index.js.map +1 -1
- package/dist/vault/types.d.ts +0 -15
- package/dist/vault/types.d.ts.map +1 -1
- package/dist/vault/types.js.map +1 -1
- package/package.json +1 -1
- package/dist/dream/index.d.ts +0 -20
- package/dist/dream/index.d.ts.map +0 -1
- package/dist/dream/index.js +0 -264
- package/dist/dream/index.js.map +0 -1
- package/dist/dream/types.d.ts +0 -30
- package/dist/dream/types.d.ts.map +0 -1
- package/dist/dream/types.js.map +0 -1
- /package/dist/{dream → memory-capture}/types.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"portal.js","sourceRoot":"","sources":["../../../../src/adapters/web/session-view/portal.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAKlD,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAElE,OAAO,EACL,oBAAoB,EACpB,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAUtE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,UAAU,MAAM,aAAa,CAAC;AAErC,OAAO,EACL,uBAAuB,EACvB,yBAAyB,GAE1B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,GAAG,MAAM,iBAAiB,CAAC;AACvC,OAAO,EACL,UAAU,EACV,YAAY,IAAI,IAAI,EACpB,YAAY,EACZ,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAEtF,MAAM,yBAAyB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEtD,MAAM,OAAO,6BAA8B,SAAQ,kBAAoC;IACrF,MAAM,CAAC,OAAsC;QAC3C,OAAO,IAAI,CAAC,YAAY,CAAC,yBAAyB,EAAE;YAClD,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnF,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,WAAW,EAAE,OAAO,CAAC,WAAW;SACjC,CAAC,CAAC;IACL,CAAC;CACF;AAED,MAAM,QAAQ,GAAG,IAAI,UAAU,CAAC;IAC9B,IAAI,EAAE,KAAK;IACX,OAAO,EAAE,IAAI;IACb,MAAM,EAAE,IAAI;CACb,CAAC,CAAC;AAEH,MAAM,eAAe,GAAG,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC;AAE1D,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,GAAG,IAA8B,EAAE,EAAE;IACxE,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC;IAC/C,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,KAAK,EAAE,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACnC,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,qBAAqB,CAAC,CAAC;IAC7C,OAAO,eAAe;QACpB,CAAC,CAAC,eAAe,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC;QAClD,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;AAC7C,CAAC,CAAC;AAkBF,MAAM,oBAAoB;IAA1B;QACU,cAAS,GAAG,IAAI,GAAG,EAAoD,CAAC;IAmBlF,CAAC;IAjBC,SAAS,CAAC,GAAW,EAAE,QAA6C;QAClE,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,EAAuC,CAAC;QACtF,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAClB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC7B,OAAO,GAAG,EAAE;YACV,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACxC,IAAI,CAAC,OAAO;gBAAE,OAAO;YACrB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACzB,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC;gBAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACrD,CAAC,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,GAAW,EAAE,KAAyB;QAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,GAAG;YAAE,OAAO;QACjB,KAAK,MAAM,QAAQ,IAAI,GAAG;YAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9C,CAAC;CACF;AAED,MAAM,oBAAoB,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAKxD,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,GAAoB,EACpB,GAAmB,EACnB,GAAQ,EACR,qBAAqD,EACrD,WAA2C;IAE3C,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,IAAI,GAAG,CAAC,QAAQ,KAAK,kBAAkB,EAAE,CAAC;QACjE,MAAM,2BAA2B,CAAC,GAAG,EAAE,GAAG,EAAE,qBAAqB,EAAE,WAAW,CAAC,CAAC;QAChF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,QAAQ,KAAK,iBAAiB,EAAE,CAAC;QAC/D,MAAM,0BAA0B,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,qBAAqB,EAAE,WAAW,CAAC,CAAC;QACpF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;QACxD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,2BAA2B,CAC9C,qBAAqB,EACrB,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAC7B,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAChC,CAAC;IACF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC,CAAC;QAC7E,GAAG,CAAC,GAAG,CAAC,gBAAgB,CAAC,qBAAqB,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;QACjE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,iBAAiB,EAAE,GAAG,MAAM,CAAC;IAE9D,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;QAC5D,MAAM,mBAAmB,GAAG,gBAAgB,CAAC;QAC7C,MAAM,SAAS,GACb,WAAW,EAAE,OAAO,CAAC,SAAS,CAC5B,mBAAmB,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,cAAc,CAAC,EACzD,mBAAmB,CACpB,IAAI,KAAK,CAAC;QACb,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;YACjB,cAAc,EAAE,0BAA0B;YAC1C,eAAe,EAAE,UAAU;SAC5B,CAAC,CAAC;QACH,GAAG,CAAC,GAAG,CACL,iBAAiB,CAAC;YAChB,KAAK;YACL,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,SAAS;YACT,mBAAmB;YACnB,cAAc,EAAE,KAAK,CAAC,cAAc;SACrC,CAAC,CACH,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,UAAU,CACZ,IAAI,KAAK,CAAC,cAAc,8BAA8B,KAAK,CAAC,WAAW,EAAE,EACzE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACvD,CAAC;QACF,qBAAqB,CAAC,KAAK,EAAE;YAC3B,MAAM,EAAE,cAAc;YACtB,OAAO,EAAE,cAAc;YACvB,SAAS,EAAE,gBAAgB;YAC3B,QAAQ,EAAE,OAAO;YACjB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,OAAO,EAAE;gBACP,cAAc,EAAE,KAAK,CAAC,cAAc;gBACpC,UAAU,EAAE,KAAK,CAAC,UAAU;gBAC5B,WAAW,EAAE,QAAQ,CAAC,iBAAiB,CAAC;aACzC;SACF,CAAC,CAAC;QACH,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC,CAAC;QACnE,GAAG,CAAC,GAAG,CAAC,gBAAgB,CAAC,qBAAqB,EAAE,4CAA4C,CAAC,CAAC,CAAC;IACjG,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAeD;;;;GAIG;AACH,KAAK,UAAU,2BAA2B,CACxC,qBAAgE,EAChE,QAAmC,EACnC,gBAA2C;IAE3C,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC3B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,iCAAiC,EAAE,CAAC;IAChF,CAAC;IACD,MAAM,KAAK,GAAG,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACrC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACpE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,8CAA8C,EAAE,CAAC;IAC7F,CAAC;IAED,IAAI,iBAAgC,CAAC;IACrC,IAAI,CAAC;QACH,iBAAiB,GAAG,MAAM,2BAA2B,CAAC,KAAK,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;IAC7F,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,UAAU,CACZ,IAAI,KAAK,CAAC,cAAc,2CAA2C,KAAK,CAAC,WAAW,EAAE,EACtF,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACvD,CAAC;QACF,qBAAqB,CAAC,KAAK,EAAE;YAC3B,MAAM,EAAE,cAAc;YACtB,OAAO,EAAE,cAAc;YACvB,SAAS,EAAE,2BAA2B;YACtC,QAAQ,EAAE,OAAO;YACjB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,OAAO,EAAE;gBACP,cAAc,EAAE,KAAK,CAAC,cAAc;gBACpC,UAAU,EAAE,KAAK,CAAC,UAAU;gBAC5B,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC;gBACxC,gBAAgB;aACjB;SACF,CAAC,CAAC;QACH,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,yCAAyC,EAAE,CAAC;IACxF,CAAC;IACD,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,kCAAkC,EAAE,CAAC;IACjF,CAAC;IAED,OAAO;QACL,EAAE,EAAE,IAAI;QACR,KAAK;QACL,iBAAiB;QACjB,gBAAgB,EAAE,0BAA0B,CAAC,KAAK,EAAE,iBAAiB,CAAC;KACvE,CAAC;AACJ,CAAC;AAED,SAAS,0BAA0B,CACjC,KAAuE,EACvE,WAAmB;IAEnB,IAAI,KAAK,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QACjD,IAAI,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YAChC,OAAO,GAAG,KAAK,CAAC,cAAc,IAAI,QAAQ,EAAE,CAAC;QAC/C,CAAC;QACD,OAAO,KAAK,CAAC,cAAc,CAAC;IAC9B,CAAC;IACD,OAAO,KAAK,CAAC,UAAU,CAAC;AAC1B,CAAC;AAED,SAAS,gBAAgB,CAAC,KAIzB;IACC,OAAO,GAAG,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;AACzE,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAwB,EAAE,KAAa;IAClE,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC;QACrB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QACzD,CAAC,CAAC,qJAAqJ,CAAC;AAC5J,CAAC;AAED,SAAS,iBAAiB,CAAC,OAO1B;IACC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,mBAAmB,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC;IAC5F,MAAM,KAAK,GAAG,mBAAmB,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAEtD,MAAM,eAAe,GAAG,KAAK,CAAC,MAAM;QAClC,CAAC,CAAC;;UAEI,kBAAkB,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC;iBAChC;QACb,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,IAAI,GAAG;;;iCAGkB,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC;;0BAEvB,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;uDACH,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;+CACxC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;;;;yDAInB,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,wEAAwE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;sCAC5J,GAAG,CAAC,mBAAmB,KAAK,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;;;;;4FAKZ,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;yFACnC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;4FAChB,GAAG,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;;;MAGxI,eAAe;;;;UAIX,KAAK;;;;;;;;mDAQoC,GAAG,CAAC,KAAK,CAAC;qDACR,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;wDAChB,GAAG,CAAC,mBAAmB,CAAC;;;;;;;eAOjE,CAAC;IAEd,OAAO,kBAAkB,CAAC,GAAG,KAAK,CAAC,KAAK,mBAAmB,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;AAChF,CAAC;AAED,SAAS,kBAAkB,CAAC,QAA6B,EAAE,KAAa;IACtE,MAAM,IAAI,GAAG,kBAAkB,kBAAkB,CAAC,KAAK,CAAC,YAAY,kBAAkB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;IAC5G,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,8BAA8B,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAClG,OAAO,iCAAiC,IAAI;;sCAER,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC;QACjD,OAAO;mCACoB,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,cAAc,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC;;;OAGzI,CAAC;AACR,CAAC;AAED,SAAS,iBAAiB,CAAC,SAA4C,EAAE,KAAa;IACpF,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACpD,OAAO,6BAA6B,SAAS;SAC1C,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;QAChB,MAAM,IAAI,GAAG,kBAAkB,kBAAkB,CAAC,KAAK,CAAC,YAAY,kBAAkB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5G,OAAO,gCAAgC,IAAI,iBAAiB,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC;;;WAG1E,CAAC;IACR,CAAC,CAAC;SACD,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAW;IAOvC,iDAAiD;IACjD,IAAI,CAAC,GAAG,GAAG,CAAC,KAAK,CACf,8IAA8I,CAC/I,CAAC;IACF,IAAI,CAAC,EAAE,CAAC;QACN,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;aACzE,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,GAAG,CAAC,CAAC;QACb,OAAO;YACL,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI;YACvB,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI;YACtB,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI;YACtB,MAAM;YACN,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;SACpB,CAAC;IACJ,CAAC;IACD,qCAAqC;IACrC,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,2DAA2D,CAAC,CAAC;IAC3E,IAAI,CAAC,EAAE,CAAC;QACN,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1F,OAAO;YACL,SAAS,EAAE,IAAI;YACf,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI;YACtB,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI;YACtB,MAAM;YACN,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;SACpB,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;AACzF,CAAC;AAID,SAAS,gBAAgB,CAAC,KAAK,GAAG,cAAc;IAC9C,OAAO,4GAA4G,GAAG,CAAC,KAAK,CAAC,iBAAiB,GAAG,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,KAAK,CAAC,iVAAiV,CAAC;AAClgB,CAAC;AAED,SAAS,UAAU,CAAC,IAAqB,EAAE,KAAc;IACvD,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACtF,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI;YACpB,CAAC,CAAC,+BAA+B,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS;YACpE,CAAC,CAAC,EAAE,CAAC;QACP,OAAO,qFAAqF,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,IAAI,QAAQ,CAAC;IACtI,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3F,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,0BAA0B,SAAS,KAAK,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7F,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,2BAA2B,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7F,OAAO;;;8BAGmB,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;MACvC,IAAI;;IAEN,IAAI;OACD,CAAC;IACN,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,0BAA0B,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IAE5F,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACzB,MAAM,MAAM,GAAmB,IAAI,CAAC,IAAI;YACtC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;YAC1B,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;QACnF,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;QACvD,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QACzE,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,+BAA+B,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;QACnF,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACjE,MAAM,WAAW,GAAG,QAAQ;YAC1B,CAAC,CAAC,2CAA2C,GAAG,CAAC,QAAQ,CAAC,oBAAoB,GAAG,CAAC,QAAQ,CAAC,eAAe;YAC1G,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QAC7D,OAAO;;;QAGH,SAAS;QACT,WAAW;QACX,IAAI;QACJ,OAAO;QACP,IAAI;;MAEN,gBAAgB,EAAE;;+CAEuB,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,OAAO;OACrF,CAAC;IACN,CAAC;IAED,YAAY;IACZ,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1E,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;IAC7D,OAAO;;;;QAID,IAAI;QACJ,OAAO;QACP,IAAI;;MAEN,gBAAgB,EAAE;;OAEjB,CAAC;AACR,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAY,EAAE,OAA6B;IACtE,OAAO,+CAA+C,OAAO,KAAK,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;AAClG,CAAC;AAED,SAAS,qBAAqB,CAAC,IAAY,EAAE,QAAgB;IAC3D,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IACxD,OAAO;;;QAGD,mBAAmB,CAAC,IAAI,EAAE,MAAM,CAAC;;MAEnC,gBAAgB,EAAE;;+CAEuB,GAAG,CAAC,QAAQ,CAAC,KAAK,OAAO;OACjE,CAAC;AACR,CAAC;AAED,SAAS,0BAA0B,CAAC,IAAY;IAC9C,OAAO;;;;QAID,mBAAmB,CAAC,IAAI,EAAE,WAAW,CAAC;;MAExC,gBAAgB,EAAE;;OAEjB,CAAC;AACR,CAAC;AAED,SAAS,oBAAoB,CAAC,MAI7B;IACC,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC;IAC5D,OAAO;;;8BAGqB,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC;;2BAEvB,SAAS,KAAK,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC;OACpD,CAAC;AACR,CAAC;AAED,SAAS,qBAAqB,CAAC,IAAY,EAAE,IAAI,GAAsB,SAAS;IAC9E,MAAM,GAAG,GAAG,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,CAAC;IACtD,OAAO,2BAA2B,GAAG,4EAA4E,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC;AAC5I,CAAC;AAED,KAAK,UAAU,0BAA0B,CACvC,GAAoB,EACpB,GAAmB,EACnB,GAAQ,EACR,qBAAqD,EACrD,WAA2C;IAE3C,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,2BAA2B,EAAE,CAAC,CAAC;QACpE,GAAG,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;QAC7C,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,2BAA2B,CAC9C,qBAAqB,EACrB,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAC7B,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAChC,CAAC;IACF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,cAAc,EAAE,2BAA2B,EAAE,CAAC,CAAC;QAC9E,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACxB,OAAO;IACT,CAAC;IACD,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;IAC3C,MAAM,SAAS,GAAG,gBAAgB,CAAC,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAC/E,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;QACjB,cAAc,EAAE,kCAAkC;QAClD,eAAe,EAAE,UAAU;QAC3B,UAAU,EAAE,YAAY;KACzB,CAAC,CAAC;IACH,GAAG,CAAC,KAAK,CACP,SAAS,IAAI,CAAC,SAAS,CAAC;QACtB,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,SAAS,CACpC,mBAAmB,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,cAAc,CAAC,EACzD,gBAAgB,CACjB;KACF,CAAC,MAAM,CACT,CAAC;IAEF,MAAM,WAAW,GAAG,oBAAoB,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;QACtE,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IACH,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE;QACjC,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IAChC,CAAC,EAAE,KAAK,CAAC,CAAC;IAEV,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;QACnB,aAAa,CAAC,SAAS,CAAC,CAAC;QACzB,WAAW,EAAE,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,2BAA2B,CACxC,GAAoB,EACpB,GAAmB,EACnB,qBAAqD,EACrD,WAA2C;IAE3C,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,iCAAiC,EAAE,CAAC,CAAC;QACxE,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,GAAG,IAAI,CAAC,CAAC;IACvD,IAAI,CAAC,IAAI;QAAE,OAAO;IAElB,MAAM,KAAK,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACtE,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACnE,MAAM,gBAAgB,GAAG,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/F,MAAM,mBAAmB,GAAG,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9F,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;QACpB,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAC;QAC/D,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,2BAA2B,CAAC,qBAAqB,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC;IACjG,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/D,OAAO;IACT,CAAC;IACD,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,iBAAiB,EAAE,GAAG,MAAM,CAAC;IAC9D,IAAI,mBAAmB,IAAI,mBAAmB,KAAK,gBAAgB,EAAE,CAAC;QACpE,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,0BAA0B,EAAE,CAAC,CAAC;QACjE,OAAO;IACT,CAAC;IAED,MAAM,0BAA0B,CAAC;QAC/B,GAAG;QACH,WAAW;QACX,KAAK;QACL,IAAI;QACJ,gBAAgB;QAChB,KAAK;QACL,iBAAiB;KAClB,CAAC,CAAC;AACL,CAAC;AAYD,KAAK,UAAU,0BAA0B,CAAC,KAAiC;IACzE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,iBAAiB,EAAE,GAAG,KAAK,CAAC;IAC5F,MAAM,GAAG,GAAG,WAAW,CAAC,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACvD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,yBAAyB,KAAK,CAAC,QAAQ,GAAG,EAAE,CAAC,CAAC;QACjF,OAAO;IACT,CAAC;IAED,MAAM,SAAS,GAAG,gBAAgB,CAAC,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAC/E,MAAM,gBAAgB,GAAG,qBAAqB,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;IACrF,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC1C,MAAM,YAAY,GAAG,GAAG,CAAC,gBAAgB,EAAE,CAAC;IAC5C,MAAM,gBAAgB,GACpB,KAAK,CAAC,gBAAgB;QACtB,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,KAAK,CAAC,cAAc,CAAC,EAAE,QAAQ;QAC7E,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,KAAK,CAAC,cAAc,CAAC,EAAE,WAAW;QAChF,SAAS,CAAC;IACZ,MAAM,SAAS,GAAG,gCAAgC,CAAC,CAAC,KAAK,EAAE,EAAE;QAC3D,oBAAoB,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,uBAAuB,CAAC;QACpC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,IAAI,EAAE,cAAc;QACpB,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,gBAAgB;QAChB,EAAE;QACF,IAAI,EAAE,KAAK,CAAC,cAAc;QAC1B,IAAI;QACJ,WAAW,EAAE,EAAE;QACf,UAAU,EAAE,gBAAgB;QAC5B,GAAG,CAAC,kBAAkB,CAAC,gBAAgB,CAAC;YACtC,CAAC,CAAC,EAAE,SAAS,EAAE,cAAc,CAAC,gBAAgB,CAAE,EAAE;YAClD,CAAC,CAAC,EAAE,CAAC;KACR,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,yBAAyB,CAAC;QACxC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,EAAE,EAAE,EAAE;QACN,UAAU,EAAE,gBAAgB;QAC5B,gBAAgB;QAChB,MAAM,EAAE,KAAK,CAAC,cAAc;QAC5B,QAAQ,EAAE,gBAAgB;QAC1B,IAAI;QACJ,WAAW,EAAE,EAAE;QACf,QAAQ,EAAE,KAAK,CAAC,SAAS;KAC1B,CAAC,CAAC;IACH,MAAM,OAAO,GAAwB;QACnC,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,OAAO;QACP,SAAS;QACT,QAAQ,EAAE,EAAE,GAAG,YAAY,EAAE,WAAW,EAAE,EAAE,gBAAgB,EAAE,KAAK,EAAE,EAAE;KACxE,CAAC;IAEF,oBAAoB,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3E,oBAAoB,CAAC,OAAO,CAAC,SAAS,EAAE;QACtC,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,qBAAqB,CAAC,IAAI,EAAE,gBAAgB,CAAC;KACpD,CAAC,CAAC;IAEH,KAAK,WAAW,CAAC,OAAO;SACrB,WAAW,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,CAAC;SAChC,IAAI,CAAC,KAAK,IAAI,EAAE;QACf,MAAM,KAAK,GAAG,MAAM,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;QAC5D,oBAAoB,CAAC,OAAO,CAAC,SAAS,EAAE;YACtC,IAAI,EAAE,SAAS;YACf,YAAY,EAAE,mBAAmB,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC;YACrD,SAAS,EAAE,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC;YACtC,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;IACL,CAAC,CAAC;SACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACf,GAAG,CAAC,UAAU,CACZ,IAAI,KAAK,CAAC,cAAc,+BAA+B,EACvD,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACvD,CAAC;QACF,qBAAqB,CAAC,KAAK,EAAE;YAC3B,MAAM,EAAE,cAAc;YACtB,OAAO,EAAE,cAAc;YACvB,SAAS,EAAE,qBAAqB;YAChC,QAAQ,EAAE,OAAO;YACjB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,OAAO,EAAE;gBACP,cAAc,EAAE,KAAK,CAAC,cAAc;gBACpC,UAAU,EAAE,gBAAgB;gBAC5B,SAAS,EAAE,EAAE;gBACb,UAAU,EAAE,IAAI,CAAC,MAAM;aACxB;SACF,CAAC,CAAC;QACH,oBAAoB,CAAC,OAAO,CAAC,SAAS,EAAE;YACtC,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAChE,CAAC,CAAC;QACH,oBAAoB,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEL,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;AAC/C,CAAC;AAED,SAAS,gCAAgC,CACvC,OAA4C;IAE5C,IAAI,eAAe,GAAG,EAAE,CAAC;IAEzB,OAAO;QACL,OAAO,EAAE,KAAK,EAAE,IAAY,EAAE,EAAE;YAC9B,eAAe,GAAG,eAAe,CAAC,CAAC,CAAC,GAAG,eAAe,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YACzE,OAAO,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,0BAA0B,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;QACpF,CAAC;QACD,eAAe,EAAE,KAAK,EAAE,IAAY,EAAE,EAAE;YACtC,eAAe,GAAG,IAAI,CAAC;YACvB,OAAO,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,0BAA0B,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;QACpF,CAAC;QACD,iBAAiB,EAAE,KAAK,EAAE,IAAY,EAAE,OAAuC,EAAE,EAAE;YACjF,IAAI,OAAO,EAAE,KAAK,KAAK,OAAO,EAAE,CAAC;gBAC/B,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,qBAAqB,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;YACxE,CAAC;QACH,CAAC;QACD,iBAAiB,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YAClC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,oBAAoB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAChE,CAAC;QACD,SAAS,EAAE,KAAK,IAAI,EAAE;YACpB,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7C,CAAC;QACD,UAAU,EAAE,KAAK,EAAE,OAAgB,EAAE,EAAE;YACrC,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAChD,CAAC;QACD,UAAU,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QAC1B,cAAc,EAAE,KAAK,IAAI,EAAE;YACzB,eAAe,GAAG,EAAE,CAAC;YACrB,OAAO,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,CAAC;QACxC,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAa,EAAE,OAAe;IACtD,OAAO,kBAAkB,CACvB,KAAK,EACL;;+BAE2B,GAAG,CAAC,KAAK,CAAC;gCACT,GAAG,CAAC,OAAO,CAAC;eAC7B,EACX,KAAK,CACN,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAa,EAAE,YAAoB,EAAE,SAAkB;IACjF,OAAO,iBAAiB,CAAC;QACvB,UAAU,EAAE,SAAS;QACrB,SAAS,EAAE,SAAS;QACpB,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,iBAAiB;QAC9B,cAAc,EAAE,EAAE,sBAAsB,EAAE,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE;QACxE,YAAY,EAAE,iBAAiB;KAChC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwKzB,CAAC;AAEF,SAAS,UAAU,CAAC,KAAa;IAC/B,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7B,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/C,OAAO,IAAI,CAAC,cAAc,EAAE,CAAC;AAC/B,CAAC;AAED,MAAM,GAAG,GAAG,UAAU,CAAC;AAEvB,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+0BzB,CAAC;AAEF,iFAAiF;AAEjF,SAAS,YAAY,CAAC,KAA+B;IACnD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;QACvF,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,eAAuB,EACvB,UAAkB;IAElB,IAAI,kBAAkB,CAAC,UAAU,CAAC,EAAE,CAAC;QACnC,OAAO,uBAAuB,CAAC,oBAAoB,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC,CAAC;IACpF,CAAC;IACD,OAAO,yBAAyB,CAAC,eAAe,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,WAAmB;IAC5D,MAAM,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1C,MAAM,EAAE,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC;IAE9B,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,UAAU,EAAE,CAAC;IACtC,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC;IACnE,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC,cAAc,EAAE,CAAC,IAAI,WAAW,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IAEhF,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACjE,MAAM,gBAAgB,GAA0B,EAAE,CAAC;IACnD,KAAK,MAAM,SAAS,IAAI,uBAAuB,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9D,IAAI,SAAS,KAAK,YAAY;YAAE,SAAS;QACzC,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CACzC,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,MAAM,CAAC,EAAE,EACT,OAAO,CACR,CAAC;QACF,IAAI,QAAQ;YAAE,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAChD,CAAC;IACD,MAAM,OAAO,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACjD,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CACnE,CAAC;IAEF,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAiC,CAAC;IAClE,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM,CAAC,aAAa;YAAE,SAAS;QACpC,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;QAChE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpB,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;QACtC,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,CAAC;QACrB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,eAAe,GAAG,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC3D,IAAI,eAAe,EAAE,CAAC;gBACpB,IAAI,CAAC,OAAO,GAAG,eAAe,CAAC;YACjC,CAAC;QACH,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,SAAS,EAAE,MAAM,CAAC,EAAE;QACpB,QAAQ,EAAE,QAAQ,CAAC,YAAY,CAAC;QAChC,KAAK;QACL,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,SAAS;QACT,UAAU,EAAE,OAAO,CAAC,MAAM;QAC1B,KAAK;QACL,MAAM,EAAE,MAAM,IAAI,SAAS;QAC3B,OAAO;KACR,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,2BAA2B,CACxC,eAAuB,EACvB,iBAAiC;IAEjC,MAAM,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAC9C,IAAI,CAAC,iBAAiB;QAAE,OAAO,YAAY,CAAC;IAE5C,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,EAAE,CAAC;IACzC,IAAI,CAAC,OAAO;QAAE,OAAO,YAAY,CAAC;IAElC,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IACnC,IAAI,QAAQ,KAAK,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAEtE,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,QAAQ,CAAC,CAAC;IACxD,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IAExC,IAAI,CAAC;QACH,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IACrF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,8BAA8B,SAAS,KACrC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CACjD,EAAE,EACF,EAAE,KAAK,EAAE,GAAG,EAAE,CACf,CAAC;IACJ,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,uBAAuB,CAAC,WAAmB;IAClD,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACjC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAEhC,OAAO,WAAW,CAAC,GAAG,CAAC;SACpB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;SACzC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED,KAAK,UAAU,oBAAoB,CACjC,WAAmB,EACnB,IAAyB,EACzB,cAAuB,EACvB,gBAAyB,EACzB,qBAAsC;IAEtC,IAAI,EAAoD,CAAC;IACzD,IAAI,CAAC;QACH,EAAE,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,UAAU,CACZ,kDAAkD,IAAI,cAAc,WAAW,EAAE,EACjF,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CACjD,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,MAAM,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC;IAC9B,IACE,IAAI,KAAK,QAAQ;QACjB,CAAC,oBAAoB,CACnB,WAAW,EACX,MAAM,CAAC,aAAa,EACpB,cAAc,EACd,gBAAgB,EAChB,MAAM,CAAC,eAAe,CACvB,EACD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,UAAU,EAAE,CAAC;IACtC,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC;IACnE,MAAM,QAAQ,GAAG,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,uBAAuB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACjF,MAAM,aAAa,GACjB,IAAI,KAAK,QAAQ,IAAI,cAAc;QACjC,CAAC,CAAC,uBAAuB,CACrB,qBAAqB;YACnB,CAAC,MAAM,CAAC,MAAM,YAAY,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,EACnE,OAAO,EACP,QAAQ,CACT;QACH,CAAC,CAAC,SAAS,CAAC;IAChB,OAAO;QACL,IAAI;QACJ,QAAQ,EAAE,QAAQ,CAAC,WAAW,CAAC;QAC/B,SAAS,EAAE,MAAM,CAAC,EAAE;QACpB,KAAK,EAAE,CAAC,MAAM,EAAE,CAAC,cAAc,EAAE,CAAC,IAAI,WAAW,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;QACxE,SAAS;QACT,UAAU,EAAE,OAAO,CAAC,MAAM;QAC1B,OAAO,EAAE,qBAAqB,CAAC,OAAO,CAAC;QACvC,aAAa;KACd,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,qBAAqB,CAClC,WAAmB,EACnB,MAAqB;IAErB,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;QACzB,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QACjD,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,MAAM,oBAAoB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,IAAI,SAAS,CAAC;QACzE,CAAC;QACD,sDAAsD;QACtD,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,mBAAmB,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;YAChF,IAAI,KAAK;gBAAE,OAAO,CAAC,MAAM,oBAAoB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,IAAI,SAAS,CAAC;QAC/E,CAAC;IACH,CAAC;IACD,OAAO,iCAAiC,CAAC,WAAW,CAAC,CAAC;AACxD,CAAC;AAED,SAAS,mBAAmB,CAAC,UAAkB,EAAE,QAAgB;IAC/D,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3C,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAAE,SAAS;QACvC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;YACxC,IAAI,YAAY,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,EAAE,KAAK,QAAQ;gBAAE,OAAO,QAAQ,CAAC;QAC1E,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,KAAK,UAAU,iCAAiC,CAC9C,WAAmB;IAEnB,IAAI,CAAC,uBAAuB,CAAC,WAAW,CAAC;QAAE,OAAO,SAAS,CAAC;IAE5D,MAAM,aAAa,GAAG,yBAAyB,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAC/E,IAAI,CAAC,aAAa,IAAI,aAAa,KAAK,WAAW;QAAE,OAAO,SAAS,CAAC;IAEtE,OAAO,CAAC,MAAM,oBAAoB,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC,IAAI,SAAS,CAAC;AAC5E,CAAC;AAED,SAAS,oBAAoB,CAC3B,WAAmB,EACnB,aAAiC,EACjC,cAAkC,EAClC,gBAAyB,EACzB,qBAA8B;IAE9B,IAAI,CAAC,cAAc;QAAE,OAAO,KAAK,CAAC;IAElC,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;QAC9C,IACE,cAAc,KAAK,cAAc;YACjC,CAAC,wBAAwB,CAAC,cAAc,CAAC,IAAI,wBAAwB,CAAC,cAAc,CAAC,CAAC,EACtF,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,gDAAgD;QAChD,IAAI,gBAAgB,IAAI,qBAAqB,EAAE,CAAC;YAC9C,OAAO,qBAAqB,KAAK,gBAAgB,CAAC;QACpD,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC,uBAAuB,CAAC,WAAW,CAAC;QAAE,OAAO,KAAK,CAAC;IACxD,OAAO,yBAAyB,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,cAAc,CAAC;AACrF,CAAC;AAED,SAAS,uBAAuB,CAAC,WAAmB;IAClD,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;IACvC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9C,IAAI,4CAA4C,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7E,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,uBAAuB,CAC9B,aAA6B,EAC7B,YAA4B,EAC5B,QAAuB;IAEvB,MAAM,eAAe,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IACvE,IAAI,eAAe,KAAK,SAAS,IAAI,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;QACtE,MAAM,eAAe,GAAG,6BAA6B,CAAC,aAAa,EAAE,eAAe,CAAC,CAAC;QACtF,IAAI,eAAe;YAAE,OAAO,eAAe,CAAC;IAC9C,CAAC;IACD,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,OACE,WAAW,GAAG,aAAa,CAAC,MAAM;QAClC,WAAW,GAAG,YAAY,CAAC,MAAM;QACjC,aAAa,CAAC,WAAW,CAAC,EAAE,EAAE,KAAK,YAAY,CAAC,WAAW,CAAC,EAAE,EAAE,EAChE,CAAC;QACD,WAAW,IAAI,CAAC,CAAC;IACnB,CAAC;IAED,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;QACpB,OAAO,aAAa,CAAC,WAAW,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC;IAC5C,CAAC;IAED,MAAM,aAAa,GAAG,8BAA8B,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IAClF,IAAI,aAAa;QAAE,OAAO,aAAa,CAAC;IAExC,MAAM,SAAS,GAAG,yBAAyB,CAAC,YAAY,CAAC,CAAC;IAC1D,IAAI,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IAEjC,OAAO,6BAA6B,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,6BAA6B,CACpC,OAAuB,EACvB,SAAiB;IAEjB,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;YAAE,SAAS;QACvC,MAAM,gBAAgB,GAAI,KAAK,CAAC,OAAmC,CAAC,SAAS,CAAC;QAC9E,IAAI,gBAAgB,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC,EAAE,CAAC;IACtD,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,8BAA8B,CACrC,aAA6B,EAC7B,YAA4B;IAE5B,MAAM,cAAc,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;QACrD,MAAM,UAAU,GAAG,2BAA2B,CAAC,KAAK,CAAC,CAAC;QACtD,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACxC,CAAC,CAAC,CAAC;IACH,MAAM,aAAa,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;QACnD,MAAM,UAAU,GAAG,2BAA2B,CAAC,KAAK,CAAC,CAAC;QACtD,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACxC,CAAC,CAAC,CAAC;IACH,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAEhF,IAAI,aAAa,GAAG,CAAC,CAAC,CAAC;IACvB,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,KAAK,IAAI,WAAW,GAAG,CAAC,EAAE,WAAW,GAAG,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,CAAC;QAC7E,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,OAAO,WAAW,GAAG,MAAM,GAAG,cAAc,CAAC,MAAM,IAAI,MAAM,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC;YACrF,MAAM,aAAa,GAAG,cAAc,CAAC,WAAW,GAAG,MAAM,CAAC,CAAC;YAC3D,MAAM,YAAY,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;YAC3C,IACE,aAAa,KAAK,SAAS;gBAC3B,YAAY,KAAK,SAAS;gBAC1B,aAAa,CAAC,IAAI,KAAK,YAAY,CAAC,IAAI;gBACxC,aAAa,CAAC,cAAc,KAAK,YAAY,CAAC,cAAc,EAC5D,CAAC;gBACD,MAAM;YACR,CAAC;YACD,MAAM,IAAI,CAAC,CAAC;QACd,CAAC;QACD,IAAI,MAAM,GAAG,UAAU,EAAE,CAAC;YACxB,UAAU,GAAG,MAAM,CAAC;YACpB,aAAa,GAAG,WAAW,GAAG,MAAM,GAAG,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,OAAO,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7E,CAAC;AAQD,SAAS,2BAA2B,CAAC,KAAmB;IACtD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAC1C,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;IAChC,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IAEzD,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAClD,MAAM,cAAc,GAAG,8BAA8B,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAClE,IAAI,CAAC,cAAc;QAAE,OAAO,IAAI,CAAC;IAEjC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;AACrD,CAAC;AAED,SAAS,8BAA8B,CAAC,IAAY,EAAE,IAA0B;IAC9E,MAAM,UAAU,GAAG,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,2BAA2B,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IACrF,OAAO,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AAChD,CAAC;AAED,SAAS,6BAA6B,CACpC,aAA6B,EAC7B,SAAgC;IAEhC,IAAI,WAA+B,CAAC;IAEpC,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;QAClC,MAAM,UAAU,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAC;QACnD,IAAI,CAAC,UAAU;YAAE,SAAS;QAC1B,IAAI,UAAU,CAAC,cAAc,KAAK,SAAS,CAAC,cAAc;YAAE,SAAS;QACrE,IACE,SAAS,CAAC,gBAAgB,KAAK,SAAS;YACxC,UAAU,CAAC,gBAAgB,KAAK,SAAS;YACzC,UAAU,CAAC,gBAAgB,KAAK,SAAS,CAAC,gBAAgB,EAC1D,CAAC;YACD,OAAO,KAAK,CAAC,EAAE,CAAC;QAClB,CAAC;QACD,WAAW,KAAK,KAAK,CAAC,EAAE,CAAC;IAC3B,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAOD,SAAS,yBAAyB,CAAC,OAAuB;IACxD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,UAAU,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAC;QACnD,IAAI,UAAU;YAAE,OAAO,UAAU,CAAC;IACpC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,wBAAwB,CAAC,KAAmB;IACnD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAE3E,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAClD,MAAM,cAAc,GAAG,2BAA2B,CAAC,IAAI,CAAC,CAAC;IACzD,IAAI,CAAC,cAAc;QAAE,OAAO,IAAI,CAAC;IAEjC,MAAM,gBAAgB,GACpB,OAAO,KAAK,CAAC,OAAO,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;IACpF,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,CAAC;AAC9C,CAAC;AAED,SAAS,2BAA2B,CAAC,IAAY;IAC/C,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,CACnC,iIAAiI,EACjI,EAAE,CACH,CAAC;IACF,OAAO,gBAAgB;SACpB,OAAO,CAAC,8DAA8D,EAAE,EAAE,CAAC;SAC3E,IAAI,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,qBAAqB,CAAC,OAAuB;IACpD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;YAAE,SAAS;QACvC,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,EAAE,IAAI;YAAE,SAAS;QAC1B,OAAO,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,eAAe,CAAC,IAAY;IACnC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACpD,OAAO,UAAU,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC;AAC7E,CAAC;AAED,SAAS,cAAc,CAAC,KAAmB;IACzC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,SAAS;YACZ,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC;QAChC,KAAK,YAAY;YACf,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC;QACnC,KAAK,gBAAgB;YACnB,OAAO,sBAAsB,CAAC,KAAK,CAAC,CAAC;QACvC,KAAK,QAAQ;YACX,OAAO;gBACL,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,iBAAiB,KAAK,CAAC,UAAU,EAAE;gBAC1C,IAAI,EAAE,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;gBAClF,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE;gBAC/B,IAAI,EAAE,OAAO;aACd,CAAC;QACJ;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAoBD,SAAS,eAAe,CAAC,KAA0B;IACjD,MAAM,OAAO,GAAG,KAAK,CAAC,OAA2C,CAAC;IAElE,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,MAAM;YACT,OAAO;gBACL,IAAI,EAAE,MAAM;gBACZ,KAAK,EAAE,MAAM;gBACb,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC;gBACpC,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE;gBAC/B,OAAO,EAAE,KAAK,CAAC,EAAE;aAClB,CAAC;QACJ,KAAK,WAAW,EAAE,CAAC;YACjB,MAAM,aAAa,GACjB,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC9F,MAAM,SAAS,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACxF,OAAO;gBACL,IAAI,EAAE,WAAW;gBACjB,KAAK,EAAE,WAAW;gBAClB,IAAI,EAAE,aAAa;gBACnB,IAAI,EACF,SAAS,CAAC,MAAM,GAAG,CAAC;oBAClB,CAAC,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;oBAC3D,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;gBACjC,OAAO,EAAE,KAAK,CAAC,EAAE;aAClB,CAAC;QACJ,CAAC;QACD,KAAK,YAAY;YACf,OAAO;gBACL,IAAI,EAAE,MAAM;gBACZ,KAAK,EAAE,iBAAiB,MAAM,CAAC,OAAO,CAAC,QAAQ,IAAI,SAAS,CAAC,EAAE;gBAC/D,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC;gBACpC,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE;gBAC/B,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;gBACpC,OAAO,EAAE,KAAK,CAAC,EAAE;aAClB,CAAC;QACJ,KAAK,eAAe,EAAE,CAAC;YACrB,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YACrD,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YACnD,MAAM,OAAO,GAAG;gBACd,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAc,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE;gBAC5E,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE;gBAC3C,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE;aAC5C,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAClB,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC9F,OAAO;gBACL,IAAI,EAAE,MAAM;gBACZ,KAAK,EAAE,gBAAgB;gBACvB,IAAI,EAAE,IAAI,IAAI,aAAa;gBAC3B,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE;gBAC/B,OAAO,EAAE,KAAK,CAAC,EAAE;aAClB,CAAC;QACJ,CAAC;QACD,KAAK,QAAQ;YACX,OAAO;gBACL,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,oBAAoB,MAAM,CAAC,OAAO,CAAC,UAAU,IAAI,QAAQ,CAAC,EAAE;gBACnE,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC;gBACpC,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE;gBAC/B,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,KAAK,CAAC,EAAE;aAClB,CAAC;QACJ,KAAK,eAAe;YAClB,OAAO;gBACL,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,iBAAiB;gBACxB,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;gBACnC,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE;gBAC/B,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,KAAK,CAAC,EAAE;aAClB,CAAC;QACJ,KAAK,mBAAmB;YACtB,OAAO;gBACL,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,oBAAoB;gBAC3B,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;gBACnC,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE;gBAC/B,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,KAAK,CAAC,EAAE;aAClB,CAAC;QACJ;YACE,OAAO;gBACL,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,aAAa,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,SAAS,CAAC,EAAE;gBACvD,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC;gBACpC,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE;gBAC/B,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,KAAK,CAAC,EAAE;aAClB,CAAC;IACN,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAsB;IAChD,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,mBAAmB;QAC1B,IAAI,EAAE,KAAK,CAAC,OAAO;QACnB,IAAI,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,KAAK,CAAC,YAAY,2BAA2B;QACrF,IAAI,EAAE,OAAO;KACd,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAgC;IAC9D,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,iBAAiB;QACxB,IAAI,EAAE,KAAK,CAAC,OAAO;QACnB,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE;QAC/B,IAAI,EAAE,OAAO;KACd,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,OAAgB;IACrC,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC;IAChD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,CAAC;IAEvC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,SAAS;QAClD,MAAM,KAAK,GAAG,KAAgC,CAAC;QAC/C,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC5D,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACvB,SAAS;QACX,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACpE,KAAK,CAAC,IAAI,CAAC,eAAe,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC5C,SAAS;QACX,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAG,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;YAClE,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAC3F,KAAK,CAAC,IAAI,CAAC,CAAC,cAAc,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YACpE,SAAS;QACX,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC,UAAU,MAAM,CAAC,KAAK,CAAC,QAAQ,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC5B,CAAC","sourcesContent":["import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { existsSync, readdirSync } from \"node:fs\";\nimport type {\n BranchSummaryEntry as SessionBranchSummaryEntry,\n CompactionEntry,\n} from \"../../../harness/index.js\";\nimport { SessionStore } from \"../../../sessions/session-store.js\";\nimport type { SessionEntry, SessionMessageEntry } from \"../../../sessions/types.js\";\nimport {\n getThreadSessionFile,\n resolveChannelSessionFile,\n tryResolveThreadSession,\n} from \"../../../sessions/store.js\";\nimport { isPlatformHistorySession } from \"../../../sessions/store.js\";\nimport type { SessionHeader } from \"../../../sessions/types.js\";\nimport type {\n SessionViewItem,\n SessionViewRelation,\n SessionViewModel,\n SessionViewToken,\n SessionViewTokenCreateOptions,\n} from \"./types.js\";\nexport type { SessionViewModel, SessionViewToken, SessionViewTokenCreateOptions } from \"./types.js\";\nimport { basename } from \"node:path\";\nimport { InMemoryTokenStore } from \"../token-store.js\";\nimport MarkdownIt from \"markdown-it\";\nimport type { ConversationResponder } from \"../../index.js\";\nimport {\n createConversationEvent,\n createConversationMessage,\n type ConversationContext,\n} from \"../../index.js\";\nimport { createOfficeAddress } from \"../../../office/index.js\";\nimport * as log from \"../../../log.js\";\nimport {\n escapeHtml,\n jsonResponse as json,\n readJsonBody,\n renderPortalShell,\n} from \"../portal-shell.js\";\nimport { reportUserFacingError } from \"../../../observability/index.js\";\nimport { inferConversationKind } from \"../../../sessions/session-key.js\";\nimport { isThreadSessionKey, threadSuffixOf } from \"../../../sessions/session-key.js\";\n\nconst SESSION_VIEW_TOKEN_TTL_MS = 24 * 60 * 60 * 1000;\n\nexport class InMemorySessionViewTokenStore extends InMemoryTokenStore<SessionViewToken> {\n create(options: SessionViewTokenCreateOptions): SessionViewToken {\n return this.createRecord(SESSION_VIEW_TOKEN_TTL_MS, {\n platform: options.platform,\n platformUserId: options.platformUserId,\n ...(options.platformUserName ? { platformUserName: options.platformUserName } : {}),\n conversationId: options.conversationId,\n sessionKey: options.sessionKey,\n sessionFile: options.sessionFile,\n });\n }\n}\n\nconst markdown = new MarkdownIt({\n html: false,\n linkify: true,\n breaks: true,\n});\n\nconst defaultLinkOpen = markdown.renderer.rules.link_open;\ntype LinkOpenRule = NonNullable<typeof defaultLinkOpen>;\nmarkdown.renderer.rules.link_open = (...args: Parameters<LinkOpenRule>) => {\n const [tokens, idx, options, env, self] = args;\n const token = tokens[idx];\n token?.attrSet(\"target\", \"_blank\");\n token?.attrSet(\"rel\", \"noreferrer noopener\");\n return defaultLinkOpen\n ? defaultLinkOpen(tokens, idx, options, env, self)\n : self.renderToken(tokens, idx, options);\n};\n\ntype SessionStreamEvent =\n | { type: \"status\"; running: boolean }\n | { type: \"user\"; html: string }\n | { type: \"assistant\"; html: string }\n | { type: \"assistant_remove\" }\n | { type: \"tool\"; html: string }\n | { type: \"system\"; html: string }\n | {\n type: \"refresh\";\n timelineHtml: string;\n updatedAt: string;\n entryCount: number;\n running: boolean;\n }\n | { type: \"error\"; message: string };\n\nclass SessionViewStreamHub {\n private listeners = new Map<string, Set<(event: SessionStreamEvent) => void>>();\n\n subscribe(key: string, listener: (event: SessionStreamEvent) => void): () => void {\n const set = this.listeners.get(key) ?? new Set<(event: SessionStreamEvent) => void>();\n set.add(listener);\n this.listeners.set(key, set);\n return () => {\n const current = this.listeners.get(key);\n if (!current) return;\n current.delete(listener);\n if (current.size === 0) this.listeners.delete(key);\n };\n }\n\n publish(key: string, event: SessionStreamEvent): void {\n const set = this.listeners.get(key);\n if (!set) return;\n for (const listener of set) listener(event);\n }\n}\n\nconst sessionViewStreamHub = new SessionViewStreamHub();\n\nexport type { SessionViewInteractiveOptions } from \"./types.js\";\nimport type { SessionViewInteractiveOptions } from \"./types.js\";\n\nexport async function handleSessionViewRequest(\n req: IncomingMessage,\n res: ServerResponse,\n url: URL,\n sessionViewTokenStore?: InMemorySessionViewTokenStore,\n interactive?: SessionViewInteractiveOptions,\n): Promise<boolean> {\n if (req.method === \"POST\" && url.pathname === \"/session/message\") {\n await handleSessionMessageRequest(req, res, sessionViewTokenStore, interactive);\n return true;\n }\n\n if (req.method === \"GET\" && url.pathname === \"/session/stream\") {\n await handleSessionStreamRequest(req, res, url, sessionViewTokenStore, interactive);\n return true;\n }\n\n if (req.method !== \"GET\" || url.pathname !== \"/session\") {\n return false;\n }\n\n const target = await resolveSessionRequestTarget(\n sessionViewTokenStore,\n url.searchParams.get(\"token\"),\n url.searchParams.get(\"session\"),\n );\n if (!target.ok) {\n res.writeHead(target.status, { \"Content-Type\": \"text/html; charset=utf-8\" });\n res.end(renderStatusPage(\"Session unavailable\", target.message));\n return true;\n }\n const { activeSessionKey, entry, targetSessionFile } = target;\n\n try {\n const model = await loadSessionViewModel(targetSessionFile);\n const displayedSessionKey = activeSessionKey;\n const isRunning =\n interactive?.handler.isRunning(\n createOfficeAddress(entry.platform, entry.conversationId),\n displayedSessionKey,\n ) ?? false;\n res.writeHead(200, {\n \"Content-Type\": \"text/html; charset=utf-8\",\n \"Cache-Control\": \"no-store\",\n });\n res.end(\n renderSessionPage({\n model,\n token: entry.token,\n expiresAt: entry.expiresAt,\n isRunning,\n displayedSessionKey,\n conversationId: entry.conversationId,\n }),\n );\n } catch (error) {\n log.logWarning(\n `[${entry.conversationId}] Failed to render session ${entry.sessionFile}`,\n error instanceof Error ? error.message : String(error),\n );\n reportUserFacingError(error, {\n domain: \"session_view\",\n surface: \"session_view\",\n operation: \"render_session\",\n severity: \"error\",\n platform: entry.platform,\n context: {\n conversationId: entry.conversationId,\n sessionKey: entry.sessionKey,\n sessionFile: basename(targetSessionFile),\n },\n });\n res.writeHead(500, { \"Content-Type\": \"text/html; charset=utf-8\" });\n res.end(renderStatusPage(\"Session unavailable\", \"The session could not be loaded right now.\"));\n }\n\n return true;\n}\n\ntype SessionRequestTarget =\n | {\n ok: true;\n entry: SessionViewToken;\n targetSessionFile: string;\n activeSessionKey: string;\n }\n | {\n ok: false;\n status: 400 | 500 | 503;\n message: string;\n };\n\n/**\n * Token/session selection is shared by HTML, SSE, and message transports.\n * Invalid or expired client capabilities are 400; missing server wiring is\n * 503; a selected corrupt session is a server-side storage failure and is 500.\n */\nasync function resolveSessionRequestTarget(\n sessionViewTokenStore: InMemorySessionViewTokenStore | undefined,\n rawToken: string | null | undefined,\n requestedSession: string | null | undefined,\n): Promise<SessionRequestTarget> {\n if (!sessionViewTokenStore) {\n return { ok: false, status: 503, message: \"Session view is not configured.\" };\n }\n const token = rawToken?.trim() ?? \"\";\n const entry = token ? sessionViewTokenStore.peek(token) : undefined;\n if (!entry) {\n return { ok: false, status: 400, message: \"This session link is invalid or has expired.\" };\n }\n\n let targetSessionFile: string | null;\n try {\n targetSessionFile = await resolveRequestedSessionFile(entry.sessionFile, requestedSession);\n } catch (error) {\n log.logWarning(\n `[${entry.conversationId}] Corrupted session file referenced for ${entry.sessionFile}`,\n error instanceof Error ? error.message : String(error),\n );\n reportUserFacingError(error, {\n domain: \"session_view\",\n surface: \"session_view\",\n operation: \"resolve_requested_session\",\n severity: \"error\",\n platform: entry.platform,\n context: {\n conversationId: entry.conversationId,\n sessionKey: entry.sessionKey,\n sessionFile: basename(entry.sessionFile),\n requestedSession,\n },\n });\n return { ok: false, status: 500, message: \"The selected session file is corrupted.\" };\n }\n if (!targetSessionFile) {\n return { ok: false, status: 400, message: \"The selected session is invalid.\" };\n }\n\n return {\n ok: true,\n entry,\n targetSessionFile,\n activeSessionKey: resolveDisplayedSessionKey(entry, targetSessionFile),\n };\n}\n\nfunction resolveDisplayedSessionKey(\n entry: { platform: string; conversationId: string; sessionKey: string },\n sessionFile: string,\n): string {\n if (entry.platform === \"slack\") {\n const fileName = basename(sessionFile, \".jsonl\");\n if (/^\\d+\\.\\d+$/.test(fileName)) {\n return `${entry.conversationId}:${fileName}`;\n }\n return entry.conversationId;\n }\n return entry.sessionKey;\n}\n\nfunction sessionStreamKey(entry: {\n platform: string;\n conversationId: string;\n sessionKey: string;\n}): string {\n return `${entry.platform}:${entry.conversationId}:${entry.sessionKey}`;\n}\n\nfunction renderTimelineItems(items: SessionViewItem[], token: string): string {\n return items.length > 0\n ? items.map((item) => renderItem(item, token)).join(\"\\n\")\n : `<div class=\"system-event\"><span class=\"event-dot\"></span><span class=\"event-text\">No messages yet — send one to the bot, then refresh.</span></div>`;\n}\n\nfunction renderSessionPage(options: {\n model: SessionViewModel;\n token: string;\n expiresAt: number;\n isRunning: boolean;\n displayedSessionKey: string;\n conversationId: string;\n}): string {\n const { model, token, expiresAt, isRunning, displayedSessionKey, conversationId } = options;\n const items = renderTimelineItems(model.items, token);\n\n const relatedSections = model.parent\n ? `<section class=\"related-card stack\">\n <p class=\"eyebrow\">Parent session</p>\n ${renderRelationCard(model.parent, token)}\n </section>`\n : \"\";\n\n const body = `<header class=\"page-head\">\n <div>\n <p class=\"eyebrow\">Session</p>\n <h2 class=\"page-title\">${esc(model.title)}</h2>\n <p class=\"page-desc\">\n <span>Created ${esc(formatDate(model.createdAt))}</span> ·\n <span>Updated <strong data-session-updated>${esc(formatDate(model.updatedAt))}</strong></span> ·\n <span><strong data-session-entries>${esc(String(model.entryCount))}</strong> entries</span>\n </p>\n </div>\n <div class=\"session-side\">\n <span class=\"session-badge session-badge-status${isRunning ? \" is-running\" : \"\"}\"><span class=\"session-badge-dot\"></span><strong data-session-status>${esc(isRunning ? \"Running\" : \"Idle\")}</strong></span>\n <span class=\"session-badge\">${esc(displayedSessionKey === conversationId ? \"Channel\" : \"Thread\")}</span>\n </div>\n </header>\n\n <div class=\"session-detail-row\">\n <span class=\"session-detail\"><span class=\"session-detail-label\">Session</span><code>${esc(model.sessionId.slice(0, 8))}</code></span>\n <span class=\"session-detail\"><span class=\"session-detail-label\">File</span><code>${esc(model.fileName)}</code></span>\n <span class=\"session-detail\"><span class=\"session-detail-label\">Expires</span><span>${esc(formatDate(new Date(expiresAt).toISOString()))}</span></span>\n </div>\n\n ${relatedSections}\n\n <div class=\"timeline-shell\">\n <div class=\"timeline-list\" data-timeline-list>\n ${items}\n </div>\n </div>\n\n <button class=\"jump-latest-btn\" type=\"button\" hidden data-jump-latest aria-label=\"Jump to latest\" title=\"Jump to latest\">↓</button>\n\n <section class=\"composer-card\">\n <form class=\"composer-form\" data-session-composer>\n <input type=\"hidden\" name=\"token\" value=\"${esc(token)}\">\n <input type=\"hidden\" name=\"session\" value=\"${esc(model.fileName)}\">\n <input type=\"hidden\" name=\"sessionKey\" value=\"${esc(displayedSessionKey)}\">\n <textarea name=\"text\" rows=\"1\" placeholder=\"Ask mikan in this session… (replies stay in Session View)\" required></textarea>\n <div class=\"composer-actions\">\n <span class=\"composer-status\" data-composer-status></span>\n <button class=\"composer-send-btn\" type=\"submit\" aria-label=\"Send\" title=\"Send\">↑</button>\n </div>\n </form>\n </section>`;\n\n return renderHtmlDocument(`${model.title} · Session Viewer`, body, isRunning);\n}\n\nfunction renderRelationCard(relation: SessionViewRelation, token: string): string {\n const href = `/session?token=${encodeURIComponent(token)}&session=${encodeURIComponent(relation.fileName)}`;\n const summary = relation.summary ? `<p class=\"related-summary\">${esc(relation.summary)}</p>` : \"\";\n return `<a class=\"related-link\" href=\"${href}\">\n <span class=\"related-copy\">\n <strong class=\"related-title\">${esc(relation.title)}</strong>\n ${summary}\n <span class=\"related-meta\">${esc(formatDate(relation.updatedAt))} · ${esc(String(relation.entryCount))} entries · ${esc(relation.fileName)}</span>\n </span>\n <span class=\"related-arrow\" aria-hidden=\"true\">→</span>\n </a>`;\n}\n\nfunction renderThreadLinks(relations: SessionViewRelation[] | undefined, token: string): string {\n if (!relations || relations.length === 0) return \"\";\n return `<div class=\"thread-links\">${relations\n .map((relation) => {\n const href = `/session?token=${encodeURIComponent(token)}&session=${encodeURIComponent(relation.fileName)}`;\n return `<a class=\"thread-link\" href=\"${href}\" title=\"Open ${esc(relation.title)}\">\n <span class=\"thread-dot\" aria-hidden=\"true\"></span>\n <span class=\"thread-text\">Thread</span>\n </a>`;\n })\n .join(\"\")}</div>`;\n}\n\nexport function parseUserBody(raw: string): {\n timestamp: string | null;\n username: string | null;\n threadTs: string | null;\n header: string | null;\n content: string;\n} {\n // [timestamp] [username] [in-thread:ts]: content\n let m = raw.match(\n /^\\[([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}[+-][0-9]{2}:[0-9]{2})\\]\\s*\\[([^\\]]+)\\](?:\\s*\\[in-thread:([^\\]]+)\\])?:\\s*([\\s\\S]*)$/,\n );\n if (m) {\n const header = [`[${m[1]}]`, `[${m[2]}]`, m[3] ? `[in-thread:${m[3]}]` : \"\"]\n .filter(Boolean)\n .join(\" \");\n return {\n timestamp: m[1] ?? null,\n username: m[2] ?? null,\n threadTs: m[3] ?? null,\n header,\n content: m[4] ?? \"\",\n };\n }\n // [username] [in-thread:ts]: content\n m = raw.match(/^\\[([^\\]]+)\\](?:\\s*\\[in-thread:([^\\]]+)\\])?:\\s*([\\s\\S]*)$/);\n if (m) {\n const header = [`[${m[1]}]`, m[2] ? `[in-thread:${m[2]}]` : \"\"].filter(Boolean).join(\" \");\n return {\n timestamp: null,\n username: m[1] ?? null,\n threadTs: m[2] ?? null,\n header,\n content: m[3] ?? \"\",\n };\n }\n return { timestamp: null, username: null, threadTs: null, header: null, content: raw };\n}\n\ntype ParsedUserBody = ReturnType<typeof parseUserBody>;\n\nfunction renderCopyButton(label = \"Copy message\"): string {\n return `<div class=\"msg-actions\"><button class=\"copy-action-btn\" type=\"button\" data-copy-button data-copy-label=\"${esc(label)}\" aria-label=\"${esc(label)}\" title=\"${esc(label)}\"><svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\"><rect x=\"9\" y=\"9\" width=\"11\" height=\"11\" rx=\"2\" stroke=\"currentColor\" stroke-width=\"1.8\"></rect><path d=\"M6 15H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v1\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"></path></svg></button></div>`;\n}\n\nfunction renderItem(item: SessionViewItem, token?: string): string {\n if (item.kind === \"system\") {\n const parts = [item.title, item.body].filter((x): x is string => Boolean(x)).map(esc);\n const time = item.meta\n ? ` · <time class=\"event-time\">${esc(formatDate(item.meta))}</time>`\n : \"\";\n return `<div class=\"system-event\"><span class=\"event-dot\"></span><span class=\"event-text\">${parts.join(\" — \")}</span>${time}</div>`;\n }\n\n if (item.kind === \"tool\") {\n const toneClass = item.tone === \"err\" ? \" tone-err\" : item.tone === \"ok\" ? \" tone-ok\" : \"\";\n const body = item.body ? `<pre class=\"tool-output${toneClass}\">${esc(item.body)}</pre>` : \"\";\n const time = item.meta ? `<time class=\"tool-time\">${esc(formatDate(item.meta))}</time>` : \"\";\n return `<div class=\"tool-block\">\n <div class=\"tool-header\">\n <span class=\"tool-icon\"><svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\"><path d=\"M1.5 2L5 5.5 1.5 9\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 9h2.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/></svg></span>\n <span class=\"tool-name\">${esc(item.title)}</span>\n ${time}\n </div>\n ${body}\n</div>`;\n }\n\n const time = item.meta ? `<time class=\"msg-time\">${esc(formatDate(item.meta))}</time>` : \"\";\n\n if (item.kind === \"user\") {\n const parsed: ParsedUserBody = item.body\n ? parseUserBody(item.body)\n : { timestamp: null, username: null, threadTs: null, header: null, content: \"\" };\n const { username, threadTs, header, content } = parsed;\n const initial = username ? esc(username.slice(0, 2).toUpperCase()) : \"U\";\n const rawHeader = header ? `<div class=\"msg-raw-header\">${esc(header)}</div>` : \"\";\n const body = content ? renderMarkdownBlock(content, \"user\") : \"\";\n const threadBadge = threadTs\n ? `<div class=\"thread-badge\" title=\"Thread ${esc(threadTs)}\">Thread · <code>${esc(threadTs)}</code></div>`\n : \"\";\n const threads = renderThreadLinks(item.threads, token ?? \"\");\n return `<div class=\"msg-row msg-user copy-host\">\n <div class=\"msg-main user-main\">\n <div class=\"user-bubble\">\n ${rawHeader}\n ${threadBadge}\n ${body}\n ${threads}\n ${time}\n </div>\n ${renderCopyButton()}\n </div>\n <div class=\"msg-avatar user-avatar\" title=\"${username ? esc(username) : \"User\"}\">${initial}</div>\n</div>`;\n }\n\n // assistant\n const body = item.body ? renderMarkdownBlock(item.body, \"assistant\") : \"\";\n const threads = renderThreadLinks(item.threads, token ?? \"\");\n return `<div class=\"msg-row msg-assistant copy-host\">\n <div class=\"msg-avatar asst-avatar\" aria-hidden=\"true\">A</div>\n <div class=\"msg-main asst-main\">\n <div class=\"asst-card\">\n ${body}\n ${threads}\n ${time}\n </div>\n ${renderCopyButton()}\n </div>\n</div>`;\n}\n\nfunction renderMarkdownBlock(text: string, variant: \"user\" | \"assistant\"): string {\n return `<div class=\"msg-body markdown-body markdown-${variant}\">${markdown.render(text)}</div>`;\n}\n\nfunction renderLiveUserMessage(text: string, userName: string): string {\n const initial = esc(userName.slice(0, 2).toUpperCase());\n return `<div class=\"msg-row msg-user copy-host\" data-live-item>\n <div class=\"msg-main user-main\">\n <div class=\"user-bubble\">\n ${renderMarkdownBlock(text, \"user\")}\n </div>\n ${renderCopyButton()}\n </div>\n <div class=\"msg-avatar user-avatar\" title=\"${esc(userName)}\">${initial}</div>\n</div>`;\n}\n\nfunction renderLiveAssistantMessage(text: string): string {\n return `<div class=\"msg-row msg-assistant copy-host\" data-live-assistant>\n <div class=\"msg-avatar asst-avatar\" aria-hidden=\"true\">A</div>\n <div class=\"msg-main asst-main\">\n <div class=\"asst-card\">\n ${renderMarkdownBlock(text, \"assistant\")}\n </div>\n ${renderCopyButton()}\n </div>\n</div>`;\n}\n\nfunction renderLiveToolResult(result: {\n toolName: string;\n result: string;\n isError: boolean;\n}): string {\n const toneClass = result.isError ? \" tone-err\" : \" tone-ok\";\n return `<div class=\"tool-block\" data-live-item>\n <div class=\"tool-header\">\n <span class=\"tool-icon\"><svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\"><path d=\"M1.5 2L5 5.5 1.5 9\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 9h2.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/></svg></span>\n <span class=\"tool-name\">${esc(result.toolName)}</span>\n </div>\n <pre class=\"tool-output${toneClass}\">${esc(result.result)}</pre>\n</div>`;\n}\n\nfunction renderLiveSystemEvent(text: string, tone: \"default\" | \"err\" = \"default\"): string {\n const cls = tone === \"err\" ? \" system-event-err\" : \"\";\n return `<div class=\"system-event${cls}\" data-live-item><span class=\"event-dot\"></span><span class=\"event-text\">${esc(text)}</span></div>`;\n}\n\nasync function handleSessionStreamRequest(\n req: IncomingMessage,\n res: ServerResponse,\n url: URL,\n sessionViewTokenStore?: InMemorySessionViewTokenStore,\n interactive?: SessionViewInteractiveOptions,\n): Promise<void> {\n if (!interactive) {\n res.writeHead(503, { \"Content-Type\": \"text/plain; charset=utf-8\" });\n res.end(\"Session stream is not configured.\");\n return;\n }\n\n const target = await resolveSessionRequestTarget(\n sessionViewTokenStore,\n url.searchParams.get(\"token\"),\n url.searchParams.get(\"session\"),\n );\n if (!target.ok) {\n res.writeHead(target.status, { \"Content-Type\": \"text/plain; charset=utf-8\" });\n res.end(target.message);\n return;\n }\n const { activeSessionKey, entry } = target;\n const streamKey = sessionStreamKey({ ...entry, sessionKey: activeSessionKey });\n res.writeHead(200, {\n \"Content-Type\": \"text/event-stream; charset=utf-8\",\n \"Cache-Control\": \"no-store\",\n Connection: \"keep-alive\",\n });\n res.write(\n `data: ${JSON.stringify({\n type: \"status\",\n running: interactive.handler.isRunning(\n createOfficeAddress(entry.platform, entry.conversationId),\n activeSessionKey,\n ),\n })}\\n\\n`,\n );\n\n const unsubscribe = sessionViewStreamHub.subscribe(streamKey, (event) => {\n res.write(`data: ${JSON.stringify(event)}\\n\\n`);\n });\n const heartbeat = setInterval(() => {\n res.write(\": keep-alive\\n\\n\");\n }, 15000);\n\n req.on(\"close\", () => {\n clearInterval(heartbeat);\n unsubscribe();\n });\n}\n\nasync function handleSessionMessageRequest(\n req: IncomingMessage,\n res: ServerResponse,\n sessionViewTokenStore?: InMemorySessionViewTokenStore,\n interactive?: SessionViewInteractiveOptions,\n): Promise<void> {\n if (!interactive) {\n json(res, 503, { ok: false, error: \"Session chat is not configured.\" });\n return;\n }\n\n const body = await readJsonBody(req, res, 1024 * 1024);\n if (!body) return;\n\n const token = typeof body.token === \"string\" ? body.token.trim() : \"\";\n const text = typeof body.text === \"string\" ? body.text.trim() : \"\";\n const requestedSession = typeof body.session === \"string\" ? body.session.trim() || null : null;\n const requestedSessionKey = typeof body.sessionKey === \"string\" ? body.sessionKey.trim() : \"\";\n if (!token || !text) {\n json(res, 400, { ok: false, error: \"Missing token or text.\" });\n return;\n }\n\n const target = await resolveSessionRequestTarget(sessionViewTokenStore, token, requestedSession);\n if (!target.ok) {\n json(res, target.status, { ok: false, error: target.message });\n return;\n }\n const { activeSessionKey, entry, targetSessionFile } = target;\n if (requestedSessionKey && requestedSessionKey !== activeSessionKey) {\n json(res, 400, { ok: false, error: \"Session target mismatch.\" });\n return;\n }\n\n await dispatchSessionViewMessage({\n res,\n interactive,\n token,\n text,\n activeSessionKey,\n entry,\n targetSessionFile,\n });\n}\n\ninterface SessionViewMessageDispatch {\n res: ServerResponse;\n interactive: SessionViewInteractiveOptions;\n token: string;\n text: string;\n activeSessionKey: string;\n entry: SessionViewToken;\n targetSessionFile: string;\n}\n\nasync function dispatchSessionViewMessage(input: SessionViewMessageDispatch): Promise<void> {\n const { res, interactive, token, text, activeSessionKey, entry, targetSessionFile } = input;\n const bot = interactive.botsByPlatform[entry.platform];\n if (!bot) {\n json(res, 503, { ok: false, error: `No bot configured for ${entry.platform}.` });\n return;\n }\n\n const streamKey = sessionStreamKey({ ...entry, sessionKey: activeSessionKey });\n const conversationKind = inferConversationKind(entry.platform, entry.conversationId);\n const ts = (Date.now() / 1000).toFixed(6);\n const platformInfo = bot.getMessagingInfo();\n const platformUserName =\n entry.platformUserName ||\n platformInfo.users.find((user) => user.id === entry.platformUserId)?.userName ||\n platformInfo.users.find((user) => user.id === entry.platformUserId)?.displayName ||\n \"unknown\";\n const responder = createSessionViewResponseContext((event) => {\n sessionViewStreamHub.publish(streamKey, event);\n });\n const event = createConversationEvent({\n platform: entry.platform,\n type: \"session_view\",\n conversationId: entry.conversationId,\n conversationKind,\n ts,\n user: entry.platformUserId,\n text,\n attachments: [],\n sessionKey: activeSessionKey,\n ...(isThreadSessionKey(activeSessionKey)\n ? { thread_ts: threadSuffixOf(activeSessionKey)! }\n : {}),\n });\n const message = createConversationMessage({\n platform: entry.platform,\n conversationId: entry.conversationId,\n id: ts,\n sessionKey: activeSessionKey,\n conversationKind,\n userId: entry.platformUserId,\n userName: platformUserName,\n text,\n attachments: [],\n threadTs: event.thread_ts,\n });\n const context: ConversationContext = {\n address: event.address,\n message,\n responder,\n platform: { ...platformInfo, diagnostics: { showUsageSummary: false } },\n };\n\n sessionViewStreamHub.publish(streamKey, { type: \"status\", running: true });\n sessionViewStreamHub.publish(streamKey, {\n type: \"user\",\n html: renderLiveUserMessage(text, platformUserName),\n });\n\n void interactive.handler\n .handleEvent(event, bot, context)\n .then(async () => {\n const model = await loadSessionViewModel(targetSessionFile);\n sessionViewStreamHub.publish(streamKey, {\n type: \"refresh\",\n timelineHtml: renderTimelineItems(model.items, token),\n updatedAt: formatDate(model.updatedAt),\n entryCount: model.entryCount,\n running: false,\n });\n })\n .catch((error) => {\n log.logWarning(\n `[${entry.conversationId}] Session view message failed`,\n error instanceof Error ? error.message : String(error),\n );\n reportUserFacingError(error, {\n domain: \"session_view\",\n surface: \"session_view\",\n operation: \"interactive_message\",\n severity: \"error\",\n platform: entry.platform,\n context: {\n conversationId: entry.conversationId,\n sessionKey: activeSessionKey,\n messageId: ts,\n textLength: text.length,\n },\n });\n sessionViewStreamHub.publish(streamKey, {\n type: \"error\",\n message: error instanceof Error ? error.message : String(error),\n });\n sessionViewStreamHub.publish(streamKey, { type: \"status\", running: false });\n });\n\n json(res, 202, { ok: true, accepted: true });\n}\n\nfunction createSessionViewResponseContext(\n publish: (event: SessionStreamEvent) => void,\n): ConversationResponder {\n let accumulatedText = \"\";\n\n return {\n respond: async (text: string) => {\n accumulatedText = accumulatedText ? `${accumulatedText}\\n${text}` : text;\n publish({ type: \"assistant\", html: renderLiveAssistantMessage(accumulatedText) });\n },\n replaceResponse: async (text: string) => {\n accumulatedText = text;\n publish({ type: \"assistant\", html: renderLiveAssistantMessage(accumulatedText) });\n },\n respondDiagnostic: async (text: string, options?: { style?: \"muted\" | \"error\" }) => {\n if (options?.style === \"error\") {\n publish({ type: \"system\", html: renderLiveSystemEvent(text, \"err\") });\n }\n },\n respondToolResult: async (result) => {\n publish({ type: \"tool\", html: renderLiveToolResult(result) });\n },\n setTyping: async () => {\n publish({ type: \"status\", running: true });\n },\n setWorking: async (working: boolean) => {\n publish({ type: \"status\", running: working });\n },\n uploadFile: async () => {},\n deleteResponse: async () => {\n accumulatedText = \"\";\n publish({ type: \"assistant_remove\" });\n },\n };\n}\n\nfunction renderStatusPage(title: string, message: string): string {\n return renderHtmlDocument(\n title,\n `<section class=\"card stack\">\n <p class=\"eyebrow\">mikan</p>\n <h1 class=\"page-title\">${esc(title)}</h1>\n <div class=\"status err\">${esc(message)}</div>\n </section>`,\n false,\n );\n}\n\nfunction renderHtmlDocument(title: string, shellContent: string, isRunning: boolean): string {\n return renderPortalShell({\n activeView: \"session\",\n pageTitle: \"Session\",\n body: shellContent,\n extraStyles: sessionViewStyles,\n bodyAttributes: { \"data-session-running\": isRunning ? \"true\" : \"false\" },\n inlineScript: sessionViewScript,\n });\n}\n\nconst sessionViewScript = `\n const form = document.querySelector('[data-session-composer]');\n const timelineList = document.querySelector('[data-timeline-list]');\n const jumpLatestBtn = document.querySelector('[data-jump-latest]');\n const statusEl = document.querySelector('[data-session-status]');\n const updatedEl = document.querySelector('[data-session-updated]');\n const entriesEl = document.querySelector('[data-session-entries]');\n const composerStatus = form?.querySelector('[data-composer-status]');\n const textarea = form?.querySelector('textarea[name=\"text\"]');\n const submitButton = form?.querySelector('button[type=\"submit\"]');\n let liveAssistant = null;\n let running = document.body.dataset.sessionRunning === 'true';\n\n const isNearMessagingBottom = () => window.innerHeight + window.scrollY >= document.body.offsetHeight - 120;\n const scrollToLatest = (behavior = 'smooth') => window.scrollTo({ top: document.body.scrollHeight, behavior });\n const toggleJumpButton = () => {\n if (!jumpLatestBtn) return;\n jumpLatestBtn.hidden = isNearMessagingBottom();\n };\n const updateFollowState = () => {\n if (isNearMessagingBottom()) scrollToLatest('smooth');\n else toggleJumpButton();\n };\n const canSubmit = () => Boolean(textarea && textarea.value.trim()) && !running;\n const updateSubmitButtonState = () => {\n if (submitButton) submitButton.disabled = !canSubmit();\n };\n const setRunning = (value) => {\n running = value;\n document.body.dataset.sessionRunning = value ? 'true' : 'false';\n if (statusEl) statusEl.textContent = value ? 'Running' : 'Idle';\n updateSubmitButtonState();\n if (composerStatus && !value && composerStatus.textContent === 'Thinking…') {\n composerStatus.textContent = '';\n }\n };\n\n jumpLatestBtn?.addEventListener('click', () => {\n scrollToLatest('smooth');\n toggleJumpButton();\n });\n document.addEventListener('click', async (event) => {\n const button = event.target instanceof Element ? event.target.closest('[data-copy-button]') : null;\n if (!(button instanceof HTMLButtonElement)) return;\n const label = button.dataset.copyLabel || 'Copy message';\n const source = button.closest('.msg-actions')?.previousElementSibling;\n const text = source instanceof HTMLElement ? (source.innerText || source.textContent || '').trim() : '';\n if (!text) return;\n const setState = (state, transient) => {\n button.dataset.copyState = state;\n button.title = transient;\n button.setAttribute('aria-label', transient);\n window.setTimeout(() => {\n if (!button.isConnected) return;\n delete button.dataset.copyState;\n button.title = label;\n button.setAttribute('aria-label', label);\n }, 1200);\n };\n try {\n await navigator.clipboard.writeText(text);\n setState('done', 'Copied');\n } catch {\n setState('error', 'Copy failed');\n }\n });\n window.addEventListener('scroll', toggleJumpButton, { passive: true });\n\n if (textarea) {\n const resize = () => {\n textarea.style.height = 'auto';\n textarea.style.height = Math.min(textarea.scrollHeight, 240) + 'px';\n };\n textarea.addEventListener('input', () => {\n resize();\n updateSubmitButtonState();\n });\n textarea.addEventListener('keydown', (event) => {\n if (event.key !== 'Enter' || event.shiftKey) return;\n if (event.isComposing || event.keyCode === 229) return;\n event.preventDefault();\n if (!running) form?.requestSubmit();\n });\n resize();\n }\n\n setRunning(running);\n updateSubmitButtonState();\n\n const streamUrl = form\n ? '/session/stream?token=' + encodeURIComponent(form.token.value) + '&session=' + encodeURIComponent(form.session.value)\n : null;\n if (streamUrl) {\n const source = new EventSource(streamUrl);\n source.onmessage = (event) => {\n const payload = JSON.parse(event.data);\n switch (payload.type) {\n case 'status':\n setRunning(Boolean(payload.running));\n if (payload.running && composerStatus) composerStatus.textContent = 'Thinking…';\n break;\n case 'user':\n case 'tool':\n case 'system': {\n timelineList?.insertAdjacentHTML('beforeend', payload.html);\n updateFollowState();\n break;\n }\n case 'assistant': {\n if (!liveAssistant || !liveAssistant.isConnected) {\n timelineList?.insertAdjacentHTML('beforeend', payload.html);\n liveAssistant = timelineList?.querySelector('[data-live-assistant]:last-of-type') || null;\n } else {\n liveAssistant.outerHTML = payload.html;\n liveAssistant = timelineList?.querySelector('[data-live-assistant]:last-of-type') || null;\n }\n updateFollowState();\n break;\n }\n case 'assistant_remove':\n if (liveAssistant?.isConnected) liveAssistant.remove();\n liveAssistant = null;\n break;\n case 'refresh':\n if (timelineList) timelineList.innerHTML = payload.timelineHtml;\n liveAssistant = null;\n if (updatedEl) updatedEl.textContent = payload.updatedAt;\n if (entriesEl) entriesEl.textContent = String(payload.entryCount);\n setRunning(Boolean(payload.running));\n if (composerStatus) composerStatus.textContent = '';\n updateFollowState();\n break;\n case 'error':\n if (composerStatus) composerStatus.textContent = payload.message || 'Something went wrong';\n setRunning(false);\n break;\n }\n };\n }\n\n form?.addEventListener('submit', async (event) => {\n event.preventDefault();\n if (!textarea || !composerStatus) return;\n const text = textarea.value.trim();\n if (!text || running) return;\n composerStatus.textContent = 'Sending…';\n updateSubmitButtonState();\n try {\n const response = await fetch('/session/message', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ token: form.token.value, session: form.session.value, sessionKey: form.sessionKey.value, text }),\n });\n const payload = await response.json();\n if (!response.ok || !payload.ok) throw new Error(payload.error || 'Request failed');\n textarea.value = '';\n textarea.style.height = 'auto';\n composerStatus.textContent = 'Thinking…';\n setRunning(true);\n updateSubmitButtonState();\n scrollToLatest('smooth');\n } catch (err) {\n composerStatus.textContent = err && err.message ? err.message : String(err);\n submitButton.disabled = false;\n }\n });\n\n toggleJumpButton();\n`;\n\nfunction formatDate(value: string): string {\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return value;\n return date.toLocaleString();\n}\n\nconst esc = escapeHtml;\n\nconst sessionViewStyles = `\n :root {\n --user-bg: #18181b;\n --user-text: #fafafa;\n --user-time: rgba(250, 250, 250, 0.5);\n\n --asst-border: #22c55e;\n --asst-avatar-bg: #f0fdf4;\n --asst-avatar-text: #16a34a;\n\n --tool-bg: #0d1117;\n --tool-header: #161b22;\n --tool-text: #c9d1d9;\n --tool-accent: #58a6ff;\n --tool-ok: #3fb950;\n --tool-err: #f85149;\n --tool-time: #484f58;\n }\n\n body {\n /* Extra bottom padding for the fixed composer */\n padding-bottom: calc(140px + env(safe-area-inset-bottom, 0px));\n overflow-x: hidden;\n }\n\n /* ── Session-specific page-head extras ─────────────────────────────── */\n\n .session-side {\n display: flex; flex-direction: column; align-items: flex-end; gap: 8px;\n flex-shrink: 0;\n }\n .session-badge {\n display: inline-flex; align-items: center; gap: 8px;\n padding: 6px 11px; border: 1px solid var(--border); border-radius: 999px;\n background: rgba(255,255,255,0.7); font-size: 0.78rem; color: var(--muted);\n line-height: 1;\n }\n .session-badge strong { color: var(--text); font-weight: 600; }\n .session-badge-status.is-running {\n background: #fff7ed; border-color: rgba(217, 119, 6, 0.18); color: #9a3412;\n }\n .session-badge-dot {\n width: 7px; height: 7px; border-radius: 50%;\n background: #a1a1aa; flex-shrink: 0;\n }\n .session-badge-status.is-running .session-badge-dot {\n background: #d97706; box-shadow: 0 0 0 4px rgba(217, 119, 6, 0.14);\n }\n\n .session-detail-row {\n display: flex; flex-wrap: wrap; gap: 8px;\n padding: 12px 14px; border: 1px solid var(--border); border-radius: 14px;\n background: rgba(255,255,255,0.6);\n }\n .session-detail {\n display: inline-flex; align-items: center; gap: 8px; min-width: 0;\n padding: 4px 10px; border-radius: 10px; background: rgba(0, 0, 0, 0.025);\n color: var(--muted); font-size: 0.78rem;\n }\n .session-detail-label {\n text-transform: uppercase; letter-spacing: 0.08em;\n font-size: 0.68rem; color: var(--subtle);\n }\n .session-detail code {\n min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;\n font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 0.74rem;\n color: var(--text); padding: 0;\n }\n\n /* ── Timeline shell ───────────────────────────────────────────────────── */\n\n .thread-links {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 10px;\n }\n\n .thread-link {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 10px;\n border-radius: 999px;\n border: 1px solid rgba(239, 68, 68, 0.18);\n background: rgba(254, 242, 242, 0.95);\n color: #b91c1c;\n text-decoration: none;\n font-size: 0.74rem;\n font-weight: 600;\n line-height: 1;\n transition: transform 120ms, background 120ms, border-color 120ms;\n }\n\n .thread-link:hover {\n transform: translateY(-1px);\n background: #fff1f2;\n border-color: rgba(239, 68, 68, 0.28);\n }\n\n .thread-dot {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: #ef4444;\n box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.12);\n flex-shrink: 0;\n }\n\n .thread-text {\n white-space: nowrap;\n }\n\n .related-card {\n padding: 18px 20px;\n border: 1px solid var(--border);\n border-radius: 18px;\n background: rgba(255,255,255,0.78);\n box-shadow: 0 1px 2px rgba(0,0,0,0.04), 0 4px 16px rgba(0,0,0,0.04);\n backdrop-filter: blur(12px);\n }\n\n .related-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n }\n\n .related-link {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 12px 14px;\n border-radius: 14px;\n border: 1px solid var(--border);\n background: rgba(255,255,255,0.82);\n color: inherit;\n text-decoration: none;\n transition: transform 120ms, border-color 120ms, box-shadow 120ms, background 120ms;\n }\n\n .related-link:hover {\n transform: translateY(-1px);\n border-color: rgba(0,0,0,0.16);\n background: #fff;\n box-shadow: 0 8px 18px rgba(0,0,0,0.05);\n }\n\n .related-copy {\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n }\n\n .related-title {\n color: var(--text);\n font-size: 0.94rem;\n line-height: 1.3;\n }\n\n .related-summary {\n color: var(--muted);\n font-size: 0.82rem;\n line-height: 1.45;\n }\n\n .related-meta {\n color: var(--subtle);\n font-size: 0.74rem;\n line-height: 1.4;\n }\n\n .related-arrow {\n flex-shrink: 0;\n color: var(--subtle);\n font-size: 1rem;\n }\n\n .timeline-shell {\n padding: 20px 0;\n }\n\n .timeline-list {\n display: flex;\n flex-direction: column;\n gap: 14px;\n min-width: 0;\n }\n\n .copy-host {\n position: relative;\n }\n\n .msg-actions {\n height: 32px;\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n opacity: 0;\n visibility: hidden;\n transition: opacity 140ms ease, visibility 140ms ease;\n }\n\n .copy-host:hover .msg-actions,\n .copy-host .msg-actions:hover,\n .copy-host:focus-within .msg-actions,\n .timeline-list > .copy-host:last-child .msg-actions,\n .copy-action-btn[data-copy-state] {\n opacity: 1;\n visibility: visible;\n }\n\n .copy-action-btn {\n width: 24px;\n height: 24px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: 0;\n border-radius: 0;\n background: transparent;\n color: rgba(63,63,70,0.8);\n transition: color 140ms ease, opacity 140ms ease;\n cursor: pointer;\n padding: 0;\n appearance: none;\n }\n\n .copy-action-btn:hover {\n background: transparent;\n color: rgba(24,24,27,0.96);\n border-color: transparent;\n }\n\n .copy-action-btn[data-copy-state='done'] {\n background: transparent;\n border-color: transparent;\n color: rgba(24,24,27,0.96);\n }\n\n .copy-action-btn[data-copy-state='done'] svg {\n position: absolute;\n opacity: 0;\n transform: scale(0.6);\n pointer-events: none;\n }\n\n .copy-action-btn svg {\n transition: opacity 140ms ease, transform 140ms ease;\n }\n\n .copy-action-btn[data-copy-state='done']::before {\n content: '';\n width: 14px;\n height: 14px;\n background-color: currentColor;\n -webkit-mask: url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='4 12 10 18 20 6'/></svg>\") center / contain no-repeat;\n mask: url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='4 12 10 18 20 6'/></svg>\") center / contain no-repeat;\n animation: copy-check-in 200ms ease-out both;\n }\n\n @keyframes copy-check-in {\n from { opacity: 0; transform: scale(0.6); }\n to { opacity: 1; transform: scale(1); }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .copy-action-btn svg,\n .copy-action-btn[data-copy-state='done']::before {\n transition: none;\n animation: none;\n }\n }\n\n .copy-action-btn[data-copy-state='error'] {\n background: transparent;\n border-color: transparent;\n color: #b91c1c;\n }\n\n /* ── Message rows ─────────────────────────────────────────────────────── */\n\n .msg-row {\n display: flex;\n align-items: flex-end;\n gap: 8px;\n padding: 4px 0;\n min-width: 0;\n }\n\n /* ── User messages ────────────────────────────────────────────────────── */\n\n .msg-user {\n justify-content: flex-end;\n }\n\n .msg-main {\n min-width: 0;\n }\n\n .user-main {\n max-width: 85%;\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n }\n\n .user-bubble {\n max-width: 100%;\n min-width: 0;\n padding: 12px 16px;\n border-radius: 18px 18px 4px 18px;\n background: var(--user-bg);\n color: var(--user-text);\n box-shadow: 0 1px 2px rgba(0,0,0,0.12);\n }\n\n .msg-raw-header {\n margin-bottom: 8px;\n color: rgba(250, 250, 250, 0.72);\n font-family: 'JetBrains Mono', ui-monospace, monospace;\n font-size: 0.72rem;\n line-height: 1.5;\n white-space: pre-wrap;\n word-break: break-word;\n }\n\n .thread-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n margin-bottom: 8px;\n padding: 4px 10px;\n border-radius: 999px;\n background: rgba(255,255,255,0.22);\n color: var(--user-text);\n font-size: 0.68rem;\n font-weight: 700;\n letter-spacing: 0.01em;\n }\n\n .thread-badge code {\n font-family: 'JetBrains Mono', ui-monospace, monospace;\n font-size: 0.66rem;\n background: rgba(255,255,255,0.16);\n padding: 1px 6px;\n border-radius: 999px;\n color: inherit;\n }\n\n .msg-user .msg-body {\n color: var(--user-text);\n }\n\n .msg-user .msg-time {\n display: block;\n margin-top: 6px;\n font-size: 0.72rem;\n color: var(--user-time);\n text-align: right;\n }\n\n /* ── Avatars ──────────────────────────────────────────────────────────── */\n\n .msg-avatar {\n flex: 0 0 28px;\n width: 28px;\n height: 28px;\n border-radius: 50%;\n font-size: 0.68rem;\n font-weight: 700;\n display: flex;\n align-items: center;\n justify-content: center;\n letter-spacing: 0;\n flex-shrink: 0;\n }\n\n .user-avatar {\n background: #eff6ff;\n border: 1.5px solid #93c5fd;\n color: #1d4ed8;\n }\n\n .asst-avatar {\n background: var(--asst-avatar-bg);\n border: 1.5px solid var(--asst-border);\n color: var(--asst-avatar-text);\n margin-bottom: 2px;\n }\n\n /* ── Assistant messages ───────────────────────────────────────────────── */\n\n .msg-assistant {\n align-items: flex-end;\n gap: 8px;\n max-width: 85%;\n min-width: 0;\n }\n\n .asst-main {\n max-width: 100%;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n }\n\n .asst-card {\n min-width: 0;\n max-width: 100%;\n padding: 14px 18px;\n border: 1px solid var(--border);\n border-radius: 18px 18px 18px 4px;\n background: var(--surface);\n box-shadow: 0 1px 3px rgba(0,0,0,0.04);\n }\n\n .msg-assistant .msg-body {\n color: var(--text);\n }\n\n .msg-assistant .msg-time {\n display: block;\n margin-top: 8px;\n font-size: 0.72rem;\n color: var(--subtle);\n }\n\n /* ── Tool blocks ──────────────────────────────────────────────────────── */\n\n .tool-block {\n max-width: 92%;\n margin-left: 36px;\n border-radius: 10px;\n overflow: hidden;\n border: 1px solid rgba(255,255,255,0.06);\n box-shadow: 0 2px 8px rgba(0,0,0,0.16);\n margin: 2px 0;\n }\n\n .tool-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 14px;\n background: var(--tool-header);\n border-bottom: 1px solid rgba(255,255,255,0.06);\n overflow: hidden;\n }\n\n .tool-icon {\n color: var(--tool-accent);\n flex-shrink: 0;\n display: flex;\n align-items: center;\n }\n\n .tool-name {\n flex: 1;\n font-family: 'JetBrains Mono', 'Fira Code', ui-monospace, monospace;\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--tool-accent);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .tool-time {\n flex-shrink: 0;\n font-family: 'JetBrains Mono', ui-monospace, monospace;\n font-size: 0.7rem;\n color: var(--tool-time);\n }\n\n .tool-output {\n display: block;\n padding: 12px 14px;\n background: var(--tool-bg);\n color: var(--tool-text);\n font-family: 'JetBrains Mono', 'Fira Code', ui-monospace, monospace;\n font-size: 0.78rem;\n line-height: 1.6;\n white-space: pre-wrap;\n word-break: break-word;\n overflow-x: auto;\n max-height: 400px;\n overflow-y: auto;\n }\n\n .tool-output.tone-ok { color: var(--tool-ok); }\n .tool-output.tone-err { color: var(--tool-err); }\n\n /* ── Markdown blocks ──────────────────────────────────────────────────── */\n\n .markdown-body {\n font-family: 'DM Sans', system-ui, sans-serif;\n font-size: 0.9rem;\n line-height: 1.65;\n word-break: break-word;\n }\n\n .markdown-body > *:first-child { margin-top: 0; }\n .markdown-body > *:last-child { margin-bottom: 0; }\n .markdown-body p,\n .markdown-body ul,\n .markdown-body ol,\n .markdown-body blockquote,\n .markdown-body pre,\n .markdown-body table,\n .markdown-body hr {\n margin: 0 0 0.85em;\n }\n\n .markdown-body h1,\n .markdown-body h2,\n .markdown-body h3,\n .markdown-body h4,\n .markdown-body h5,\n .markdown-body h6 {\n margin: 0 0 0.55em;\n line-height: 1.25;\n font-weight: 700;\n letter-spacing: -0.01em;\n }\n\n .markdown-body h1 { font-size: 1.4rem; }\n .markdown-body h2 { font-size: 1.22rem; }\n .markdown-body h3 { font-size: 1.08rem; }\n .markdown-body h4,\n .markdown-body h5,\n .markdown-body h6 { font-size: 0.95rem; }\n\n .markdown-body ul,\n .markdown-body ol {\n padding-left: 1.3em;\n }\n\n .markdown-body li + li {\n margin-top: 0.22em;\n }\n\n .markdown-body blockquote {\n padding-left: 12px;\n border-left: 3px solid rgba(34, 197, 94, 0.35);\n opacity: 0.95;\n }\n\n .markdown-body a {\n color: inherit;\n text-decoration: underline;\n text-underline-offset: 2px;\n }\n\n .markdown-body code {\n font-family: 'JetBrains Mono', 'Fira Code', ui-monospace, monospace;\n font-size: 0.82em;\n padding: 0.16em 0.38em;\n border-radius: 6px;\n }\n\n .markdown-body pre {\n overflow-x: auto;\n border-radius: 12px;\n padding: 12px 14px;\n }\n\n .markdown-body pre code {\n display: block;\n padding: 0;\n border-radius: 0;\n background: transparent;\n font-size: 0.82rem;\n line-height: 1.6;\n }\n\n .markdown-body table {\n width: 100%;\n border-collapse: collapse;\n font-size: 0.85rem;\n }\n\n .markdown-body th,\n .markdown-body td {\n padding: 8px 10px;\n border: 1px solid rgba(0, 0, 0, 0.08);\n text-align: left;\n vertical-align: top;\n }\n\n .markdown-body img {\n max-width: 100%;\n border-radius: 12px;\n }\n\n .markdown-user code {\n background: rgba(255,255,255,0.14);\n color: var(--user-text);\n }\n\n .markdown-user pre {\n background: rgba(255,255,255,0.08);\n border: 1px solid rgba(255,255,255,0.08);\n }\n\n .markdown-user table th,\n .markdown-user table td {\n border-color: rgba(255,255,255,0.16);\n }\n\n .markdown-assistant code {\n background: #f4f4f5;\n color: #27272a;\n }\n\n .markdown-assistant pre {\n background: #0f172a;\n color: #e5e7eb;\n }\n\n .markdown-assistant pre code {\n background: transparent;\n color: inherit;\n }\n\n .markdown-assistant table th,\n .markdown-assistant table td {\n border-color: rgba(0, 0, 0, 0.08);\n }\n\n /* ── System events ────────────────────────────────────────────────────── */\n\n .system-event {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n padding: 10px 0;\n color: var(--subtle);\n font-size: 0.775rem;\n }\n\n .event-dot {\n width: 4px;\n height: 4px;\n border-radius: 50%;\n background: var(--subtle);\n flex-shrink: 0;\n opacity: 0.6;\n }\n\n .event-text {\n color: var(--muted);\n }\n\n .system-event-err .event-text {\n color: var(--err-text);\n }\n\n .event-time {\n color: var(--subtle);\n font-style: normal;\n }\n\n /* ── Status page ──────────────────────────────────────────────────────── */\n\n .stack > * + * { margin-top: 14px; }\n\n p { color: var(--muted); font-size: 0.9rem; line-height: 1.5; }\n\n .status {\n padding: 12px 16px;\n border-radius: 10px;\n font-size: 0.9rem;\n }\n\n .status.err {\n background: var(--err-bg);\n color: var(--err-text);\n border: 1px solid rgba(185, 28, 28, 0.12);\n }\n\n /* ── Composer ─────────────────────────────────────────────────────────── */\n\n .composer-card {\n position: fixed;\n left: calc(72px + (100vw - 72px) / 2);\n bottom: calc(16px + env(safe-area-inset-bottom, 0px));\n transform: translateX(-50%);\n width: min(960px, calc(100vw - 96px));\n padding: 10px 12px 10px 14px;\n border: 1px solid var(--border);\n border-radius: 22px;\n background: rgba(250, 248, 244, 0.92);\n box-shadow: 0 12px 36px rgba(0,0,0,0.10), 0 2px 6px rgba(0,0,0,0.04);\n backdrop-filter: blur(14px);\n -webkit-backdrop-filter: blur(14px);\n z-index: 20;\n }\n\n .composer-form {\n display: flex;\n flex-direction: column;\n gap: 6px;\n }\n\n .jump-latest-btn {\n position: fixed;\n left: calc(72px + (100vw - 72px) / 2);\n bottom: calc(env(safe-area-inset-bottom, 0px) + 120px);\n z-index: 25;\n width: 42px;\n height: 42px;\n border: 1px solid var(--border);\n border-radius: 999px;\n background: var(--bg);\n color: var(--text);\n font: 700 1rem/1 'DM Sans', sans-serif;\n box-shadow: 0 10px 30px rgba(0,0,0,0.12);\n cursor: pointer;\n backdrop-filter: blur(10px);\n transform: translateX(-50%);\n outline: none;\n appearance: none;\n -webkit-tap-highlight-color: transparent;\n }\n\n .jump-latest-btn:hover {\n transform: translateX(-50%) translateY(-1px);\n background: #e8e3d9;\n }\n\n .jump-latest-btn:focus,\n .jump-latest-btn:active {\n outline: none;\n }\n\n .jump-latest-btn:focus-visible {\n box-shadow: 0 10px 30px rgba(0,0,0,0.12), 0 0 0 3px rgba(0,0,0,0.08);\n }\n\n .composer-copy { margin-bottom: 12px; color: var(--muted); }\n\n .composer-form textarea {\n width: 100%;\n resize: none;\n overflow-y: auto;\n min-height: 28px;\n max-height: 200px;\n padding: 6px 6px 2px;\n border: 0;\n border-radius: 0;\n font: inherit;\n color: var(--text);\n background: transparent;\n }\n\n .composer-form textarea::placeholder {\n color: rgba(63,63,70,0.55);\n }\n\n .composer-form textarea:focus {\n outline: none;\n border: 0;\n }\n\n .composer-actions {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n margin-top: 0;\n }\n\n .composer-status { color: var(--muted); font-size: 13px; }\n .composer-actions button:disabled { opacity: 0.55; cursor: wait; }\n\n .composer-send-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n border-radius: 999px;\n background: #d97706;\n color: #ffffff;\n font: 700 1rem/1 'DM Sans', sans-serif;\n cursor: pointer;\n box-shadow: 0 10px 24px rgba(217, 119, 6, 0.26);\n transition: transform 120ms, filter 120ms, box-shadow 120ms, background 120ms;\n }\n\n .composer-send-btn:hover:not(:disabled) {\n transform: translateY(-1px);\n filter: saturate(1.06) brightness(0.98);\n box-shadow: 0 12px 28px rgba(217, 119, 6, 0.32);\n }\n\n .composer-send-btn:focus-visible {\n outline: 2px solid rgba(217, 119, 6, 0.28);\n outline-offset: 3px;\n }\n\n .composer-send-btn:disabled {\n background: #d4d4d8;\n color: rgba(24, 24, 27, 0.45);\n box-shadow: none;\n transform: none;\n filter: none;\n cursor: not-allowed;\n opacity: 1;\n }\n\n /* ── Responsive ───────────────────────────────────────────────────────── */\n\n @media (max-width: 900px) {\n .composer-card {\n left: 50%;\n width: min(960px, calc(100vw - 24px));\n }\n .jump-latest-btn { left: 50%; }\n }\n\n @media (max-width: 600px) {\n body { padding-bottom: calc(130px + env(safe-area-inset-bottom, 0px)); }\n\n .composer-card {\n width: calc(100vw - 16px);\n bottom: calc(8px + env(safe-area-inset-bottom, 0px));\n padding: 8px 10px;\n border-radius: 18px;\n }\n\n .session-side { align-items: flex-start; flex-direction: row; }\n\n .user-bubble,\n .msg-assistant,\n .tool-block { max-width: 100%; }\n\n .asst-avatar { display: none; }\n\n .asst-card { border-radius: 4px 14px 14px 14px; }\n }\n`;\n\n// ── Session view model (formerly service.ts) ──────────────────────────────────\n\nfunction entryIsoTime(entry: SessionEntry | undefined): string | undefined {\n if (!entry || typeof entry.timestamp !== \"number\" || !Number.isFinite(entry.timestamp)) {\n return undefined;\n }\n return new Date(entry.timestamp).toISOString();\n}\n\nexport function resolveExistingSessionFile(\n conversationDir: string,\n sessionKey: string,\n): string | null {\n if (isThreadSessionKey(sessionKey)) {\n return tryResolveThreadSession(getThreadSessionFile(conversationDir, sessionKey));\n }\n return resolveChannelSessionFile(conversationDir);\n}\n\nexport async function loadSessionViewModel(sessionFile: string): Promise<SessionViewModel> {\n const resolvedFile = resolve(sessionFile);\n const sm = await SessionStore.inspect(resolvedFile);\n const header = sm.getHeader();\n\n const entries = await sm.getEntries();\n const updatedAt = entryIsoTime(entries.at(-1)) ?? header.timestamp;\n const title = (await sm.getSessionName()) || `Session ${header.id.slice(0, 8)}`;\n\n const parent = await resolveParentRelation(resolvedFile, header);\n const threadCandidates: SessionViewRelation[] = [];\n for (const candidate of listRelatedSessionFiles(resolvedFile)) {\n if (candidate === resolvedFile) continue;\n const relation = await buildSessionRelation(\n candidate,\n \"thread\",\n resolvedFile,\n header.id,\n entries,\n );\n if (relation) threadCandidates.push(relation);\n }\n const threads = threadCandidates.toSorted((a, b) =>\n a.updatedAt < b.updatedAt ? -1 : a.updatedAt > b.updatedAt ? 1 : 0,\n );\n\n const threadsByEntryId = new Map<string, SessionViewRelation[]>();\n for (const thread of threads) {\n if (!thread.anchorEntryId) continue;\n const bucket = threadsByEntryId.get(thread.anchorEntryId) ?? [];\n bucket.push(thread);\n threadsByEntryId.set(thread.anchorEntryId, bucket);\n }\n\n const items = entries.flatMap((entry) => {\n const item = mapEntryToItem(entry);\n if (!item) return [];\n if (item.entryId) {\n const anchoredThreads = threadsByEntryId.get(item.entryId);\n if (anchoredThreads) {\n item.threads = anchoredThreads;\n }\n }\n return [item];\n });\n\n return {\n sessionId: header.id,\n fileName: basename(resolvedFile),\n title,\n createdAt: header.timestamp,\n updatedAt,\n entryCount: entries.length,\n items,\n parent: parent ?? undefined,\n threads,\n };\n}\n\nasync function resolveRequestedSessionFile(\n baseSessionFile: string,\n requestedFileName?: string | null,\n): Promise<string | null> {\n const resolvedBase = resolve(baseSessionFile);\n if (!requestedFileName) return resolvedBase;\n\n const trimmed = requestedFileName.trim();\n if (!trimmed) return resolvedBase;\n\n const fileName = basename(trimmed);\n if (fileName !== trimmed || !fileName.endsWith(\".jsonl\")) return null;\n\n const candidate = join(dirname(resolvedBase), fileName);\n if (!existsSync(candidate)) return null;\n\n try {\n if (!SessionStore.readHeader(candidate)) throw new Error(\"Invalid session header\");\n } catch (err) {\n throw new Error(\n `Session file is corrupted: ${candidate}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n { cause: err },\n );\n }\n return candidate;\n}\n\nfunction listRelatedSessionFiles(sessionFile: string): string[] {\n const dir = dirname(sessionFile);\n if (!existsSync(dir)) return [];\n\n return readdirSync(dir)\n .filter((name) => name.endsWith(\".jsonl\"))\n .map((fileName) => join(dir, fileName));\n}\n\nasync function buildSessionRelation(\n sessionFile: string,\n kind: \"parent\" | \"thread\",\n expectedParent?: string,\n expectedParentId?: string,\n expectedParentEntries?: SessionEntry[],\n): Promise<SessionViewRelation | null> {\n let sm: Awaited<ReturnType<typeof SessionStore.inspect>>;\n try {\n sm = await SessionStore.inspect(sessionFile);\n } catch (err) {\n log.logWarning(\n `Skipping corrupted session file while building ${kind} relation: ${sessionFile}`,\n err instanceof Error ? err.message : String(err),\n );\n return null;\n }\n const header = sm.getHeader();\n if (\n kind === \"thread\" &&\n !isChildThreadSession(\n sessionFile,\n header.parentSession,\n expectedParent,\n expectedParentId,\n header.parentSessionId,\n )\n ) {\n return null;\n }\n\n const entries = await sm.getEntries();\n const updatedAt = entryIsoTime(entries.at(-1)) ?? header.timestamp;\n const threadId = kind === \"thread\" ? getFixedThreadSessionId(sessionFile) : null;\n const anchorEntryId =\n kind === \"thread\" && expectedParent\n ? findThreadAnchorEntryId(\n expectedParentEntries ??\n (await (await SessionStore.inspect(expectedParent)).getEntries()),\n entries,\n threadId,\n )\n : undefined;\n return {\n kind,\n fileName: basename(sessionFile),\n sessionId: header.id,\n title: (await sm.getSessionName()) || `Session ${header.id.slice(0, 8)}`,\n updatedAt,\n entryCount: entries.length,\n summary: extractSessionSummary(entries),\n anchorEntryId,\n };\n}\n\nasync function resolveParentRelation(\n sessionFile: string,\n header: SessionHeader,\n): Promise<SessionViewRelation | undefined> {\n if (header.parentSession) {\n const parentPath = resolve(header.parentSession);\n if (existsSync(parentPath)) {\n return (await buildSessionRelation(parentPath, \"parent\")) ?? undefined;\n }\n // Path is stale — try UUID fallback before heuristic.\n if (header.parentSessionId) {\n const found = findSessionFileById(dirname(sessionFile), header.parentSessionId);\n if (found) return (await buildSessionRelation(found, \"parent\")) ?? undefined;\n }\n }\n return buildInferredThreadParentRelation(sessionFile);\n}\n\nfunction findSessionFileById(sessionDir: string, targetId: string): string | null {\n if (!existsSync(sessionDir)) return null;\n for (const name of readdirSync(sessionDir)) {\n if (!name.endsWith(\".jsonl\")) continue;\n try {\n const filePath = join(sessionDir, name);\n if (SessionStore.readHeader(filePath)?.id === targetId) return filePath;\n } catch {\n continue;\n }\n }\n return null;\n}\n\nasync function buildInferredThreadParentRelation(\n sessionFile: string,\n): Promise<SessionViewRelation | undefined> {\n if (!getFixedThreadSessionId(sessionFile)) return undefined;\n\n const parentSession = resolveChannelSessionFile(dirname(dirname(sessionFile)));\n if (!parentSession || parentSession === sessionFile) return undefined;\n\n return (await buildSessionRelation(parentSession, \"parent\")) ?? undefined;\n}\n\nfunction isChildThreadSession(\n sessionFile: string,\n parentSession: string | undefined,\n expectedParent: string | undefined,\n expectedParentId?: string,\n threadParentSessionId?: string,\n): boolean {\n if (!expectedParent) return false;\n\n if (parentSession) {\n const resolvedParent = resolve(parentSession);\n if (\n resolvedParent === expectedParent ||\n (isPlatformHistorySession(expectedParent) && isPlatformHistorySession(resolvedParent))\n ) {\n return true;\n }\n // Path is stale — fall back to UUID comparison.\n if (expectedParentId && threadParentSessionId) {\n return threadParentSessionId === expectedParentId;\n }\n return false;\n }\n\n if (!getFixedThreadSessionId(sessionFile)) return false;\n return resolveChannelSessionFile(dirname(dirname(sessionFile))) === expectedParent;\n}\n\nfunction getFixedThreadSessionId(sessionFile: string): string | null {\n const fileName = basename(sessionFile);\n if (!fileName.endsWith(\".jsonl\")) return null;\n if (/^\\d{4}-\\d{2}-\\d{2}T.+_[0-9a-f]{8}\\.jsonl$/i.test(fileName)) return null;\n return fileName.slice(0, -\".jsonl\".length);\n}\n\nfunction findThreadAnchorEntryId(\n parentEntries: SessionEntry[],\n childEntries: SessionEntry[],\n threadId: string | null,\n): string | undefined {\n const threadTimestamp = threadId ? Number(threadId) * 1000 : undefined;\n if (threadTimestamp !== undefined && Number.isFinite(threadTimestamp)) {\n const timestampAnchor = findEntryIdByMessageTimestamp(parentEntries, threadTimestamp);\n if (timestampAnchor) return timestampAnchor;\n }\n let sharedCount = 0;\n while (\n sharedCount < parentEntries.length &&\n sharedCount < childEntries.length &&\n parentEntries[sharedCount]?.id === childEntries[sharedCount]?.id\n ) {\n sharedCount += 1;\n }\n\n if (sharedCount > 0) {\n return parentEntries[sharedCount - 1]?.id;\n }\n\n const contentAnchor = findSharedContentAnchorEntryId(parentEntries, childEntries);\n if (contentAnchor) return contentAnchor;\n\n const childRoot = findComparableUserMessage(childEntries);\n if (!childRoot) return undefined;\n\n return findParentAnchorByRootMessage(parentEntries, childRoot);\n}\n\nfunction findEntryIdByMessageTimestamp(\n entries: SessionEntry[],\n timestamp: number,\n): string | undefined {\n for (const entry of entries) {\n if (entry.type !== \"message\") continue;\n const messageTimestamp = (entry.message as { timestamp?: unknown }).timestamp;\n if (messageTimestamp === timestamp) return entry.id;\n }\n return undefined;\n}\n\nfunction findSharedContentAnchorEntryId(\n parentEntries: SessionEntry[],\n childEntries: SessionEntry[],\n): string | undefined {\n const parentMessages = parentEntries.flatMap((entry) => {\n const comparable = getComparableSessionMessage(entry);\n return comparable ? [comparable] : [];\n });\n const childMessages = childEntries.flatMap((entry) => {\n const comparable = getComparableSessionMessage(entry);\n return comparable ? [comparable] : [];\n });\n if (parentMessages.length === 0 || childMessages.length === 0) return undefined;\n\n let bestParentEnd = -1;\n let bestLength = 0;\n for (let parentStart = 0; parentStart < parentMessages.length; parentStart++) {\n let length = 0;\n while (parentStart + length < parentMessages.length && length < childMessages.length) {\n const parentMessage = parentMessages[parentStart + length];\n const childMessage = childMessages[length];\n if (\n parentMessage === undefined ||\n childMessage === undefined ||\n parentMessage.role !== childMessage.role ||\n parentMessage.normalizedText !== childMessage.normalizedText\n ) {\n break;\n }\n length += 1;\n }\n if (length > bestLength) {\n bestLength = length;\n bestParentEnd = parentStart + length - 1;\n }\n }\n\n return bestLength > 0 ? parentMessages[bestParentEnd]?.entryId : undefined;\n}\n\ninterface ComparableSessionMessage {\n entryId: string;\n role: \"user\" | \"assistant\";\n normalizedText: string;\n}\n\nfunction getComparableSessionMessage(entry: SessionEntry): ComparableSessionMessage | null {\n if (entry.type !== \"message\") return null;\n const role = entry.message.role;\n if (role !== \"user\" && role !== \"assistant\") return null;\n\n const body = contentToText(entry.message.content);\n const normalizedText = normalizeComparableSessionText(body, role);\n if (!normalizedText) return null;\n\n return { entryId: entry.id, role, normalizedText };\n}\n\nfunction normalizeComparableSessionText(text: string, role: \"user\" | \"assistant\"): string {\n const normalized = role === \"user\" ? normalizeComparableUserText(text) : text.trim();\n return normalized.replace(/\\s+/g, \" \").trim();\n}\n\nfunction findParentAnchorByRootMessage(\n parentEntries: SessionEntry[],\n childRoot: ComparableUserMessage,\n): string | undefined {\n let textMatchId: string | undefined;\n\n for (const entry of parentEntries) {\n const comparable = getComparableUserMessage(entry);\n if (!comparable) continue;\n if (comparable.normalizedText !== childRoot.normalizedText) continue;\n if (\n childRoot.messageTimestamp !== undefined &&\n comparable.messageTimestamp !== undefined &&\n comparable.messageTimestamp === childRoot.messageTimestamp\n ) {\n return entry.id;\n }\n textMatchId ??= entry.id;\n }\n\n return textMatchId;\n}\n\ninterface ComparableUserMessage {\n normalizedText: string;\n messageTimestamp?: number;\n}\n\nfunction findComparableUserMessage(entries: SessionEntry[]): ComparableUserMessage | null {\n for (const entry of entries) {\n const comparable = getComparableUserMessage(entry);\n if (comparable) return comparable;\n }\n return null;\n}\n\nfunction getComparableUserMessage(entry: SessionEntry): ComparableUserMessage | null {\n if (entry.type !== \"message\" || entry.message.role !== \"user\") return null;\n\n const body = contentToText(entry.message.content);\n const normalizedText = normalizeComparableUserText(body);\n if (!normalizedText) return null;\n\n const messageTimestamp =\n typeof entry.message.timestamp === \"number\" ? entry.message.timestamp : undefined;\n return { normalizedText, messageTimestamp };\n}\n\nfunction normalizeComparableUserText(text: string): string {\n const withoutTimestamp = text.replace(\n /^\\[[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}[+-][0-9]{2}:[0-9]{2}\\]\\s+(?=\\[[^\\]]+\\](?:\\s+\\[in-thread:[^\\]]+\\])?:\\s)/,\n \"\",\n );\n return withoutTimestamp\n .replace(/\\n*<slack_attachments>\\n[\\s\\S]*?\\n<\\/slack_attachments>\\s*$/g, \"\")\n .trim();\n}\n\nfunction extractSessionSummary(entries: SessionEntry[]): string | undefined {\n for (const entry of entries) {\n if (entry.type !== \"message\") continue;\n const item = mapEntryToItem(entry);\n if (!item?.body) continue;\n return collapseSummary(item.body);\n }\n return undefined;\n}\n\nfunction collapseSummary(text: string): string {\n const singleLine = text.replace(/\\s+/g, \" \").trim();\n return singleLine.length > 96 ? `${singleLine.slice(0, 93)}…` : singleLine;\n}\n\nfunction mapEntryToItem(entry: SessionEntry): SessionViewItem | null {\n switch (entry.type) {\n case \"message\":\n return mapMessageEntry(entry);\n case \"compaction\":\n return mapCompactionEntry(entry);\n case \"branch_summary\":\n return mapSessionSummaryEntry(entry);\n case \"custom\":\n return {\n kind: \"system\",\n title: `Custom data · ${entry.customType}`,\n body: entry.data === undefined ? \"(no data)\" : JSON.stringify(entry.data, null, 2),\n meta: entryIsoTime(entry) ?? \"\",\n tone: \"muted\",\n };\n default:\n return null;\n }\n}\n\ninterface SessionMessagePayload extends Record<string, unknown> {\n role?: string;\n content?: unknown;\n provider?: string;\n model?: string;\n toolName?: string;\n isError?: boolean;\n command?: string;\n output?: string;\n exitCode?: number;\n cancelled?: boolean;\n truncated?: boolean;\n stopReason?: string;\n errorMessage?: string;\n customType?: string;\n summary?: string;\n}\n\nfunction mapMessageEntry(entry: SessionMessageEntry): SessionViewItem {\n const message = entry.message as unknown as SessionMessagePayload;\n\n switch (message.role) {\n case \"user\":\n return {\n kind: \"user\",\n title: \"User\",\n body: contentToText(message.content),\n meta: entryIsoTime(entry) ?? \"\",\n entryId: entry.id,\n };\n case \"assistant\": {\n const assistantBody =\n contentToText(message.content) || (message.errorMessage ? `_${message.errorMessage}_` : \"\");\n const metaParts = [message.provider, message.model, message.stopReason].filter(Boolean);\n return {\n kind: \"assistant\",\n title: \"Assistant\",\n body: assistantBody,\n meta:\n metaParts.length > 0\n ? `${entryIsoTime(entry) ?? \"\"} · ${metaParts.join(\" · \")}`\n : (entryIsoTime(entry) ?? \"\"),\n entryId: entry.id,\n };\n }\n case \"toolResult\":\n return {\n kind: \"tool\",\n title: `Tool result · ${String(message.toolName ?? \"unknown\")}`,\n body: contentToText(message.content),\n meta: entryIsoTime(entry) ?? \"\",\n tone: message.isError ? \"err\" : \"ok\",\n entryId: entry.id,\n };\n case \"bashExecution\": {\n const command = String(message.command ?? \"\").trim();\n const output = String(message.output ?? \"\").trim();\n const details = [\n typeof message.exitCode === \"number\" ? `[exitCode] ${message.exitCode}` : \"\",\n message.cancelled ? `[cancelled] true` : \"\",\n message.truncated ? `[truncated] true` : \"\",\n ].filter(Boolean);\n const body = [command ? `$ ${command}` : \"\", output, ...details].filter(Boolean).join(\"\\n\\n\");\n return {\n kind: \"tool\",\n title: \"Bash execution\",\n body: body || \"(no output)\",\n meta: entryIsoTime(entry) ?? \"\",\n entryId: entry.id,\n };\n }\n case \"custom\":\n return {\n kind: \"system\",\n title: `Custom message · ${String(message.customType ?? \"custom\")}`,\n body: contentToText(message.content),\n meta: entryIsoTime(entry) ?? \"\",\n tone: \"muted\",\n entryId: entry.id,\n };\n case \"branchSummary\":\n return {\n kind: \"system\",\n title: \"Session summary\",\n body: String(message.summary ?? \"\"),\n meta: entryIsoTime(entry) ?? \"\",\n tone: \"muted\",\n entryId: entry.id,\n };\n case \"compactionSummary\":\n return {\n kind: \"system\",\n title: \"Compaction summary\",\n body: String(message.summary ?? \"\"),\n meta: entryIsoTime(entry) ?? \"\",\n tone: \"muted\",\n entryId: entry.id,\n };\n default:\n return {\n kind: \"system\",\n title: `Message · ${String(message.role ?? \"unknown\")}`,\n body: contentToText(message.content),\n meta: entryIsoTime(entry) ?? \"\",\n tone: \"muted\",\n entryId: entry.id,\n };\n }\n}\n\nfunction mapCompactionEntry(entry: CompactionEntry): SessionViewItem {\n return {\n kind: \"system\",\n title: \"Context compacted\",\n body: entry.summary,\n meta: `${entryIsoTime(entry) ?? \"\"} · ${entry.tokensBefore} tokens before compaction`,\n tone: \"muted\",\n };\n}\n\nfunction mapSessionSummaryEntry(entry: SessionBranchSummaryEntry): SessionViewItem {\n return {\n kind: \"system\",\n title: \"Session summary\",\n body: entry.summary,\n meta: entryIsoTime(entry) ?? \"\",\n tone: \"muted\",\n };\n}\n\nfunction contentToText(content: unknown): string {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return \"\";\n\n const lines: string[] = [];\n for (const block of content) {\n if (!block || typeof block !== \"object\") continue;\n const value = block as Record<string, unknown>;\n if (value.type === \"text\" && typeof value.text === \"string\") {\n lines.push(value.text);\n continue;\n }\n if (value.type === \"thinking\" && typeof value.thinking === \"string\") {\n lines.push(`[thinking]\\n${value.thinking}`);\n continue;\n }\n if (value.type === \"toolCall\") {\n const name = typeof value.name === \"string\" ? value.name : \"tool\";\n const args = value.arguments === undefined ? \"\" : JSON.stringify(value.arguments, null, 2);\n lines.push([`[toolCall] ${name}`, args].filter(Boolean).join(\"\\n\"));\n continue;\n }\n if (value.type === \"image\") {\n lines.push(`[image ${String(value.mimeType ?? \"unknown\")}]`);\n }\n }\n\n return lines.join(\"\\n\\n\");\n}\n"]}
|
|
1
|
+
{"version":3,"file":"portal.js","sourceRoot":"","sources":["../../../../src/adapters/web/session-view/portal.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAKlD,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAElE,OAAO,EACL,oBAAoB,EACpB,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAUtE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,UAAU,MAAM,aAAa,CAAC;AAErC,OAAO,EACL,uBAAuB,EACvB,yBAAyB,GAE1B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,GAAG,MAAM,iBAAiB,CAAC;AACvC,OAAO,EACL,UAAU,EACV,YAAY,IAAI,IAAI,EACpB,YAAY,EACZ,iBAAiB,GAClB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAEtF,MAAM,yBAAyB,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAEtD,MAAM,OAAO,6BAA8B,SAAQ,kBAAoC;IACrF,MAAM,CAAC,OAAsC;QAC3C,OAAO,IAAI,CAAC,YAAY,CAAC,yBAAyB,EAAE;YAClD,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,GAAG,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnF,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,WAAW,EAAE,OAAO,CAAC,WAAW;SACjC,CAAC,CAAC;IACL,CAAC;CACF;AAED,MAAM,QAAQ,GAAG,IAAI,UAAU,CAAC;IAC9B,IAAI,EAAE,KAAK;IACX,OAAO,EAAE,IAAI;IACb,MAAM,EAAE,IAAI;CACb,CAAC,CAAC;AAEH,MAAM,eAAe,GAAG,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC;AAE1D,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,GAAG,IAA8B,EAAE,EAAE;IACxE,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC;IAC/C,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IAC1B,KAAK,EAAE,OAAO,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACnC,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,qBAAqB,CAAC,CAAC;IAC7C,OAAO,eAAe;QACpB,CAAC,CAAC,eAAe,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC;QAClD,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;AAC7C,CAAC,CAAC;AAkBF,MAAM,oBAAoB;IAA1B;QACU,cAAS,GAAG,IAAI,GAAG,EAAoD,CAAC;IAmBlF,CAAC;IAjBC,SAAS,CAAC,GAAW,EAAE,QAA6C;QAClE,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,EAAuC,CAAC;QACtF,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAClB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QAC7B,OAAO,GAAG,EAAE;YACV,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACxC,IAAI,CAAC,OAAO;gBAAE,OAAO;YACrB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACzB,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC;gBAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACrD,CAAC,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,GAAW,EAAE,KAAyB;QAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,GAAG;YAAE,OAAO;QACjB,KAAK,MAAM,QAAQ,IAAI,GAAG;YAAE,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9C,CAAC;CACF;AAED,MAAM,oBAAoB,GAAG,IAAI,oBAAoB,EAAE,CAAC;AAKxD,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,GAAoB,EACpB,GAAmB,EACnB,GAAQ,EACR,qBAAqD,EACrD,WAA2C;IAE3C,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,IAAI,GAAG,CAAC,QAAQ,KAAK,kBAAkB,EAAE,CAAC;QACjE,MAAM,2BAA2B,CAAC,GAAG,EAAE,GAAG,EAAE,qBAAqB,EAAE,WAAW,CAAC,CAAC;QAChF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,QAAQ,KAAK,iBAAiB,EAAE,CAAC;QAC/D,MAAM,0BAA0B,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,qBAAqB,EAAE,WAAW,CAAC,CAAC;QACpF,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,GAAG,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;QACxD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,2BAA2B,CAC9C,qBAAqB,EACrB,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAC7B,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAChC,CAAC;IACF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC,CAAC;QAC7E,GAAG,CAAC,GAAG,CAAC,gBAAgB,CAAC,qBAAqB,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;QACjE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,iBAAiB,EAAE,GAAG,MAAM,CAAC;IAE9D,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;QAC5D,MAAM,mBAAmB,GAAG,gBAAgB,CAAC;QAC7C,MAAM,SAAS,GACb,WAAW,EAAE,OAAO,CAAC,SAAS,CAC5B,mBAAmB,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,cAAc,CAAC,EACzD,mBAAmB,CACpB,IAAI,KAAK,CAAC;QACb,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;YACjB,cAAc,EAAE,0BAA0B;YAC1C,eAAe,EAAE,UAAU;SAC5B,CAAC,CAAC;QACH,GAAG,CAAC,GAAG,CACL,iBAAiB,CAAC;YAChB,KAAK;YACL,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,SAAS,EAAE,KAAK,CAAC,SAAS;YAC1B,SAAS;YACT,mBAAmB;YACnB,cAAc,EAAE,KAAK,CAAC,cAAc;SACrC,CAAC,CACH,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,UAAU,CACZ,IAAI,KAAK,CAAC,cAAc,8BAA8B,KAAK,CAAC,WAAW,EAAE,EACzE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACvD,CAAC;QACF,qBAAqB,CAAC,KAAK,EAAE;YAC3B,MAAM,EAAE,cAAc;YACtB,OAAO,EAAE,cAAc;YACvB,SAAS,EAAE,gBAAgB;YAC3B,QAAQ,EAAE,OAAO;YACjB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,OAAO,EAAE;gBACP,cAAc,EAAE,KAAK,CAAC,cAAc;gBACpC,UAAU,EAAE,KAAK,CAAC,UAAU;gBAC5B,WAAW,EAAE,QAAQ,CAAC,iBAAiB,CAAC;aACzC;SACF,CAAC,CAAC;QACH,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC,CAAC;QACnE,GAAG,CAAC,GAAG,CAAC,gBAAgB,CAAC,qBAAqB,EAAE,4CAA4C,CAAC,CAAC,CAAC;IACjG,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAeD,KAAK,UAAU,2BAA2B,CACxC,qBAAgE,EAChE,QAAmC,EACnC,gBAA2C;IAE3C,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC3B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,iCAAiC,EAAE,CAAC;IAChF,CAAC;IACD,MAAM,KAAK,GAAG,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACrC,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,qBAAqB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACpE,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,8CAA8C,EAAE,CAAC;IAC7F,CAAC;IAED,IAAI,iBAAgC,CAAC;IACrC,IAAI,CAAC;QACH,iBAAiB,GAAG,MAAM,2BAA2B,CAAC,KAAK,CAAC,WAAW,EAAE,gBAAgB,CAAC,CAAC;IAC7F,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,UAAU,CACZ,IAAI,KAAK,CAAC,cAAc,2CAA2C,KAAK,CAAC,WAAW,EAAE,EACtF,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACvD,CAAC;QACF,qBAAqB,CAAC,KAAK,EAAE;YAC3B,MAAM,EAAE,cAAc;YACtB,OAAO,EAAE,cAAc;YACvB,SAAS,EAAE,2BAA2B;YACtC,QAAQ,EAAE,OAAO;YACjB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,OAAO,EAAE;gBACP,cAAc,EAAE,KAAK,CAAC,cAAc;gBACpC,UAAU,EAAE,KAAK,CAAC,UAAU;gBAC5B,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC;gBACxC,gBAAgB;aACjB;SACF,CAAC,CAAC;QACH,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,yCAAyC,EAAE,CAAC;IACxF,CAAC;IACD,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,kCAAkC,EAAE,CAAC;IACjF,CAAC;IAED,OAAO;QACL,EAAE,EAAE,IAAI;QACR,KAAK;QACL,iBAAiB;QACjB,gBAAgB,EAAE,0BAA0B,CAAC,KAAK,EAAE,iBAAiB,CAAC;KACvE,CAAC;AACJ,CAAC;AAED,SAAS,0BAA0B,CACjC,KAAuE,EACvE,WAAmB;IAEnB,IAAI,KAAK,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QACjD,IAAI,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YAChC,OAAO,GAAG,KAAK,CAAC,cAAc,IAAI,QAAQ,EAAE,CAAC;QAC/C,CAAC;QACD,OAAO,KAAK,CAAC,cAAc,CAAC;IAC9B,CAAC;IACD,OAAO,KAAK,CAAC,UAAU,CAAC;AAC1B,CAAC;AAED,SAAS,gBAAgB,CAAC,KAIzB;IACC,OAAO,GAAG,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,cAAc,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC;AACzE,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAwB,EAAE,KAAa;IAClE,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC;QACrB,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QACzD,CAAC,CAAC,qJAAqJ,CAAC;AAC5J,CAAC;AAED,SAAS,iBAAiB,CAAC,OAO1B;IACC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,mBAAmB,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC;IAC5F,MAAM,KAAK,GAAG,mBAAmB,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IAEtD,MAAM,eAAe,GAAG,KAAK,CAAC,MAAM;QAClC,CAAC,CAAC;;UAEI,kBAAkB,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC;iBAChC;QACb,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,IAAI,GAAG;;;iCAGkB,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC;;0BAEvB,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;uDACH,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;+CACxC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;;;;yDAInB,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,wEAAwE,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;sCAC5J,GAAG,CAAC,mBAAmB,KAAK,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;;;;;4FAKZ,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;yFACnC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;4FAChB,GAAG,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;;;MAGxI,eAAe;;;;UAIX,KAAK;;;;;;;;mDAQoC,GAAG,CAAC,KAAK,CAAC;qDACR,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;wDAChB,GAAG,CAAC,mBAAmB,CAAC;;;;;;;eAOjE,CAAC;IAEd,OAAO,kBAAkB,CAAC,GAAG,KAAK,CAAC,KAAK,mBAAmB,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;AAChF,CAAC;AAED,SAAS,kBAAkB,CAAC,QAA6B,EAAE,KAAa;IACtE,MAAM,IAAI,GAAG,kBAAkB,kBAAkB,CAAC,KAAK,CAAC,YAAY,kBAAkB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;IAC5G,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,8BAA8B,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAClG,OAAO,iCAAiC,IAAI;;sCAER,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC;QACjD,OAAO;mCACoB,GAAG,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,MAAM,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,cAAc,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC;;;OAGzI,CAAC;AACR,CAAC;AAED,SAAS,iBAAiB,CAAC,SAA4C,EAAE,KAAa;IACpF,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACpD,OAAO,6BAA6B,SAAS;SAC1C,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;QAChB,MAAM,IAAI,GAAG,kBAAkB,kBAAkB,CAAC,KAAK,CAAC,YAAY,kBAAkB,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5G,OAAO,gCAAgC,IAAI,iBAAiB,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC;;;WAG1E,CAAC;IACR,CAAC,CAAC;SACD,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAW;IAOvC,IAAI,CAAC,GAAG,GAAG,CAAC,KAAK,CACf,8IAA8I,CAC/I,CAAC;IACF,IAAI,CAAC,EAAE,CAAC;QACN,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;aACzE,MAAM,CAAC,OAAO,CAAC;aACf,IAAI,CAAC,GAAG,CAAC,CAAC;QACb,OAAO;YACL,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI;YACvB,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI;YACtB,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI;YACtB,MAAM;YACN,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;SACpB,CAAC;IACJ,CAAC;IACD,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,2DAA2D,CAAC,CAAC;IAC3E,IAAI,CAAC,EAAE,CAAC;QACN,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC1F,OAAO;YACL,SAAS,EAAE,IAAI;YACf,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI;YACtB,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI;YACtB,MAAM;YACN,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;SACpB,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC;AACzF,CAAC;AAID,SAAS,gBAAgB,CAAC,KAAK,GAAG,cAAc;IAC9C,OAAO,4GAA4G,GAAG,CAAC,KAAK,CAAC,iBAAiB,GAAG,CAAC,KAAK,CAAC,YAAY,GAAG,CAAC,KAAK,CAAC,iVAAiV,CAAC;AAClgB,CAAC;AAED,SAAS,UAAU,CAAC,IAAqB,EAAE,KAAc;IACvD,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC3B,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACtF,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI;YACpB,CAAC,CAAC,+BAA+B,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS;YACpE,CAAC,CAAC,EAAE,CAAC;QACP,OAAO,qFAAqF,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,IAAI,QAAQ,CAAC;IACtI,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3F,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,0BAA0B,SAAS,KAAK,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7F,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,2BAA2B,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7F,OAAO;;;8BAGmB,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;MACvC,IAAI;;IAEN,IAAI;OACD,CAAC;IACN,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,0BAA0B,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IAE5F,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACzB,MAAM,MAAM,GAAmB,IAAI,CAAC,IAAI;YACtC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC;YAC1B,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;QACnF,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;QACvD,MAAM,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;QACzE,MAAM,SAAS,GAAG,MAAM,CAAC,CAAC,CAAC,+BAA+B,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;QACnF,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACjE,MAAM,WAAW,GAAG,QAAQ;YAC1B,CAAC,CAAC,2CAA2C,GAAG,CAAC,QAAQ,CAAC,oBAAoB,GAAG,CAAC,QAAQ,CAAC,eAAe;YAC1G,CAAC,CAAC,EAAE,CAAC;QACP,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QAC7D,OAAO;;;QAGH,SAAS;QACT,WAAW;QACX,IAAI;QACJ,OAAO;QACP,IAAI;;MAEN,gBAAgB,EAAE;;+CAEuB,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,OAAO;OACrF,CAAC;IACN,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1E,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;IAC7D,OAAO;;;;QAID,IAAI;QACJ,OAAO;QACP,IAAI;;MAEN,gBAAgB,EAAE;;OAEjB,CAAC;AACR,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAY,EAAE,OAA6B;IACtE,OAAO,+CAA+C,OAAO,KAAK,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC;AAClG,CAAC;AAED,SAAS,qBAAqB,CAAC,IAAY,EAAE,QAAgB;IAC3D,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IACxD,OAAO;;;QAGD,mBAAmB,CAAC,IAAI,EAAE,MAAM,CAAC;;MAEnC,gBAAgB,EAAE;;+CAEuB,GAAG,CAAC,QAAQ,CAAC,KAAK,OAAO;OACjE,CAAC;AACR,CAAC;AAED,SAAS,0BAA0B,CAAC,IAAY;IAC9C,OAAO;;;;QAID,mBAAmB,CAAC,IAAI,EAAE,WAAW,CAAC;;MAExC,gBAAgB,EAAE;;OAEjB,CAAC;AACR,CAAC;AAED,SAAS,oBAAoB,CAAC,MAI7B;IACC,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,UAAU,CAAC;IAC5D,OAAO;;;8BAGqB,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC;;2BAEvB,SAAS,KAAK,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC;OACpD,CAAC;AACR,CAAC;AAED,SAAS,qBAAqB,CAAC,IAAY,EAAE,IAAI,GAAsB,SAAS;IAC9E,MAAM,GAAG,GAAG,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,CAAC;IACtD,OAAO,2BAA2B,GAAG,4EAA4E,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC;AAC5I,CAAC;AAED,KAAK,UAAU,0BAA0B,CACvC,GAAoB,EACpB,GAAmB,EACnB,GAAQ,EACR,qBAAqD,EACrD,WAA2C;IAE3C,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,2BAA2B,EAAE,CAAC,CAAC;QACpE,GAAG,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;QAC7C,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,2BAA2B,CAC9C,qBAAqB,EACrB,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAC7B,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAChC,CAAC;IACF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,cAAc,EAAE,2BAA2B,EAAE,CAAC,CAAC;QAC9E,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACxB,OAAO;IACT,CAAC;IACD,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;IAC3C,MAAM,SAAS,GAAG,gBAAgB,CAAC,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAC/E,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE;QACjB,cAAc,EAAE,kCAAkC;QAClD,eAAe,EAAE,UAAU;QAC3B,UAAU,EAAE,YAAY;KACzB,CAAC,CAAC;IACH,GAAG,CAAC,KAAK,CACP,SAAS,IAAI,CAAC,SAAS,CAAC;QACtB,IAAI,EAAE,QAAQ;QACd,OAAO,EAAE,WAAW,CAAC,OAAO,CAAC,SAAS,CACpC,mBAAmB,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,cAAc,CAAC,EACzD,gBAAgB,CACjB;KACF,CAAC,MAAM,CACT,CAAC;IAEF,MAAM,WAAW,GAAG,oBAAoB,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;QACtE,GAAG,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IACH,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE;QACjC,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IAChC,CAAC,EAAE,KAAK,CAAC,CAAC;IAEV,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;QACnB,aAAa,CAAC,SAAS,CAAC,CAAC;QACzB,WAAW,EAAE,CAAC;IAChB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,2BAA2B,CACxC,GAAoB,EACpB,GAAmB,EACnB,qBAAqD,EACrD,WAA2C;IAE3C,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,iCAAiC,EAAE,CAAC,CAAC;QACxE,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,GAAG,IAAI,CAAC,CAAC;IACvD,IAAI,CAAC,IAAI;QAAE,OAAO;IAElB,MAAM,KAAK,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACtE,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACnE,MAAM,gBAAgB,GAAG,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAC/F,MAAM,mBAAmB,GAAG,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9F,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;QACpB,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,wBAAwB,EAAE,CAAC,CAAC;QAC/D,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,2BAA2B,CAAC,qBAAqB,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC;IACjG,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;QACf,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC;QAC/D,OAAO;IACT,CAAC;IACD,MAAM,EAAE,gBAAgB,EAAE,KAAK,EAAE,iBAAiB,EAAE,GAAG,MAAM,CAAC;IAC9D,IAAI,mBAAmB,IAAI,mBAAmB,KAAK,gBAAgB,EAAE,CAAC;QACpE,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,0BAA0B,EAAE,CAAC,CAAC;QACjE,OAAO;IACT,CAAC;IAED,MAAM,0BAA0B,CAAC;QAC/B,GAAG;QACH,WAAW;QACX,KAAK;QACL,IAAI;QACJ,gBAAgB;QAChB,KAAK;QACL,iBAAiB;KAClB,CAAC,CAAC;AACL,CAAC;AAYD,KAAK,UAAU,0BAA0B,CAAC,KAAiC;IACzE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,iBAAiB,EAAE,GAAG,KAAK,CAAC;IAC5F,MAAM,GAAG,GAAG,WAAW,CAAC,cAAc,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACvD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,yBAAyB,KAAK,CAAC,QAAQ,GAAG,EAAE,CAAC,CAAC;QACjF,OAAO;IACT,CAAC;IAED,MAAM,SAAS,GAAG,gBAAgB,CAAC,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAC/E,MAAM,gBAAgB,GAAG,qBAAqB,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,cAAc,CAAC,CAAC;IACrF,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IAC1C,MAAM,YAAY,GAAG,GAAG,CAAC,gBAAgB,EAAE,CAAC;IAC5C,MAAM,gBAAgB,GACpB,KAAK,CAAC,gBAAgB;QACtB,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,KAAK,CAAC,cAAc,CAAC,EAAE,QAAQ;QAC7E,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,KAAK,CAAC,cAAc,CAAC,EAAE,WAAW;QAChF,SAAS,CAAC;IACZ,MAAM,SAAS,GAAG,gCAAgC,CAAC,CAAC,KAAK,EAAE,EAAE;QAC3D,oBAAoB,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,uBAAuB,CAAC;QACpC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,IAAI,EAAE,cAAc;QACpB,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,gBAAgB;QAChB,EAAE;QACF,IAAI,EAAE,KAAK,CAAC,cAAc;QAC1B,IAAI;QACJ,WAAW,EAAE,EAAE;QACf,UAAU,EAAE,gBAAgB;QAC5B,GAAG,CAAC,kBAAkB,CAAC,gBAAgB,CAAC;YACtC,CAAC,CAAC,EAAE,SAAS,EAAE,cAAc,CAAC,gBAAgB,CAAE,EAAE;YAClD,CAAC,CAAC,EAAE,CAAC;KACR,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,yBAAyB,CAAC;QACxC,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,cAAc,EAAE,KAAK,CAAC,cAAc;QACpC,EAAE,EAAE,EAAE;QACN,UAAU,EAAE,gBAAgB;QAC5B,gBAAgB;QAChB,MAAM,EAAE,KAAK,CAAC,cAAc;QAC5B,QAAQ,EAAE,gBAAgB;QAC1B,IAAI;QACJ,WAAW,EAAE,EAAE;QACf,QAAQ,EAAE,KAAK,CAAC,SAAS;KAC1B,CAAC,CAAC;IACH,MAAM,OAAO,GAAwB;QACnC,OAAO,EAAE,KAAK,CAAC,OAAO;QACtB,OAAO;QACP,SAAS;QACT,QAAQ,EAAE,EAAE,GAAG,YAAY,EAAE,WAAW,EAAE,EAAE,gBAAgB,EAAE,KAAK,EAAE,EAAE;KACxE,CAAC;IAEF,oBAAoB,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3E,oBAAoB,CAAC,OAAO,CAAC,SAAS,EAAE;QACtC,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,qBAAqB,CAAC,IAAI,EAAE,gBAAgB,CAAC;KACpD,CAAC,CAAC;IAEH,KAAK,WAAW,CAAC,OAAO;SACrB,WAAW,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,CAAC;SAChC,IAAI,CAAC,KAAK,IAAI,EAAE;QACf,MAAM,KAAK,GAAG,MAAM,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;QAC5D,oBAAoB,CAAC,OAAO,CAAC,SAAS,EAAE;YACtC,IAAI,EAAE,SAAS;YACf,YAAY,EAAE,mBAAmB,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC;YACrD,SAAS,EAAE,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC;YACtC,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;IACL,CAAC,CAAC;SACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACf,GAAG,CAAC,UAAU,CACZ,IAAI,KAAK,CAAC,cAAc,+BAA+B,EACvD,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CACvD,CAAC;QACF,qBAAqB,CAAC,KAAK,EAAE;YAC3B,MAAM,EAAE,cAAc;YACtB,OAAO,EAAE,cAAc;YACvB,SAAS,EAAE,qBAAqB;YAChC,QAAQ,EAAE,OAAO;YACjB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,OAAO,EAAE;gBACP,cAAc,EAAE,KAAK,CAAC,cAAc;gBACpC,UAAU,EAAE,gBAAgB;gBAC5B,SAAS,EAAE,EAAE;gBACb,UAAU,EAAE,IAAI,CAAC,MAAM;aACxB;SACF,CAAC,CAAC;QACH,oBAAoB,CAAC,OAAO,CAAC,SAAS,EAAE;YACtC,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAChE,CAAC,CAAC;QACH,oBAAoB,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEL,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;AAC/C,CAAC;AAED,SAAS,gCAAgC,CACvC,OAA4C;IAE5C,IAAI,eAAe,GAAG,EAAE,CAAC;IAEzB,OAAO;QACL,OAAO,EAAE,KAAK,EAAE,IAAY,EAAE,EAAE;YAC9B,eAAe,GAAG,eAAe,CAAC,CAAC,CAAC,GAAG,eAAe,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YACzE,OAAO,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,0BAA0B,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;QACpF,CAAC;QACD,eAAe,EAAE,KAAK,EAAE,IAAY,EAAE,EAAE;YACtC,eAAe,GAAG,IAAI,CAAC;YACvB,OAAO,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,0BAA0B,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;QACpF,CAAC;QACD,iBAAiB,EAAE,KAAK,EAAE,IAAY,EAAE,OAAuC,EAAE,EAAE;YACjF,IAAI,OAAO,EAAE,KAAK,KAAK,OAAO,EAAE,CAAC;gBAC/B,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,qBAAqB,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;YACxE,CAAC;QACH,CAAC;QACD,iBAAiB,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;YAClC,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,oBAAoB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAChE,CAAC;QACD,SAAS,EAAE,KAAK,IAAI,EAAE;YACpB,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7C,CAAC;QACD,UAAU,EAAE,KAAK,EAAE,OAAgB,EAAE,EAAE;YACrC,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAChD,CAAC;QACD,UAAU,EAAE,KAAK,IAAI,EAAE,GAAE,CAAC;QAC1B,cAAc,EAAE,KAAK,IAAI,EAAE;YACzB,eAAe,GAAG,EAAE,CAAC;YACrB,OAAO,CAAC,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,CAAC;QACxC,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAa,EAAE,OAAe;IACtD,OAAO,kBAAkB,CACvB,KAAK,EACL;;+BAE2B,GAAG,CAAC,KAAK,CAAC;gCACT,GAAG,CAAC,OAAO,CAAC;eAC7B,EACX,KAAK,CACN,CAAC;AACJ,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAa,EAAE,YAAoB,EAAE,SAAkB;IACjF,OAAO,iBAAiB,CAAC;QACvB,UAAU,EAAE,SAAS;QACrB,SAAS,EAAE,SAAS;QACpB,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,iBAAiB;QAC9B,cAAc,EAAE,EAAE,sBAAsB,EAAE,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,EAAE;QACxE,YAAY,EAAE,iBAAiB;KAChC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwKzB,CAAC;AAEF,SAAS,UAAU,CAAC,KAAa;IAC/B,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7B,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/C,OAAO,IAAI,CAAC,cAAc,EAAE,CAAC;AAC/B,CAAC;AAED,MAAM,GAAG,GAAG,UAAU,CAAC;AAEvB,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+0BzB,CAAC;AAEF,SAAS,YAAY,CAAC,KAA+B;IACnD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;QACvF,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,0BAA0B,CACxC,eAAuB,EACvB,UAAkB;IAElB,IAAI,kBAAkB,CAAC,UAAU,CAAC,EAAE,CAAC;QACnC,OAAO,uBAAuB,CAAC,oBAAoB,CAAC,eAAe,EAAE,UAAU,CAAC,CAAC,CAAC;IACpF,CAAC;IACD,OAAO,yBAAyB,CAAC,eAAe,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,WAAmB;IAC5D,MAAM,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1C,MAAM,EAAE,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC;IAE9B,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,UAAU,EAAE,CAAC;IACtC,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC;IACnE,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC,cAAc,EAAE,CAAC,IAAI,WAAW,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IAEhF,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACjE,MAAM,gBAAgB,GAA0B,EAAE,CAAC;IACnD,KAAK,MAAM,SAAS,IAAI,uBAAuB,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9D,IAAI,SAAS,KAAK,YAAY;YAAE,SAAS;QACzC,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CACzC,SAAS,EACT,QAAQ,EACR,YAAY,EACZ,MAAM,CAAC,EAAE,EACT,OAAO,CACR,CAAC;QACF,IAAI,QAAQ;YAAE,gBAAgB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAChD,CAAC;IACD,MAAM,OAAO,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACjD,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CACnE,CAAC;IAEF,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAiC,CAAC;IAClE,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM,CAAC,aAAa;YAAE,SAAS;QACpC,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;QAChE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACpB,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;IACrD,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;QACtC,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,CAAC;QACrB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,eAAe,GAAG,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC3D,IAAI,eAAe,EAAE,CAAC;gBACpB,IAAI,CAAC,OAAO,GAAG,eAAe,CAAC;YACjC,CAAC;QACH,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC;IAChB,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,SAAS,EAAE,MAAM,CAAC,EAAE;QACpB,QAAQ,EAAE,QAAQ,CAAC,YAAY,CAAC;QAChC,KAAK;QACL,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,SAAS;QACT,UAAU,EAAE,OAAO,CAAC,MAAM;QAC1B,KAAK;QACL,MAAM,EAAE,MAAM,IAAI,SAAS;QAC3B,OAAO;KACR,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,2BAA2B,CACxC,eAAuB,EACvB,iBAAiC;IAEjC,MAAM,YAAY,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IAC9C,IAAI,CAAC,iBAAiB;QAAE,OAAO,YAAY,CAAC;IAE5C,MAAM,OAAO,GAAG,iBAAiB,CAAC,IAAI,EAAE,CAAC;IACzC,IAAI,CAAC,OAAO;QAAE,OAAO,YAAY,CAAC;IAElC,MAAM,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;IACnC,IAAI,QAAQ,KAAK,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAEtE,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,QAAQ,CAAC,CAAC;IACxD,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,IAAI,CAAC;IAExC,IAAI,CAAC;QACH,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IACrF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CACb,8BAA8B,SAAS,KACrC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CACjD,EAAE,EACF,EAAE,KAAK,EAAE,GAAG,EAAE,CACf,CAAC;IACJ,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,uBAAuB,CAAC,WAAmB;IAClD,MAAM,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IACjC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IAEhC,OAAO,WAAW,CAAC,GAAG,CAAC;SACpB,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;SACzC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED,KAAK,UAAU,oBAAoB,CACjC,WAAmB,EACnB,IAAyB,EACzB,cAAuB,EACvB,gBAAyB,EACzB,qBAAsC;IAEtC,IAAI,EAAoD,CAAC;IACzD,IAAI,CAAC;QACH,EAAE,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,GAAG,CAAC,UAAU,CACZ,kDAAkD,IAAI,cAAc,WAAW,EAAE,EACjF,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CACjD,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,MAAM,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC;IAC9B,IACE,IAAI,KAAK,QAAQ;QACjB,CAAC,oBAAoB,CACnB,WAAW,EACX,MAAM,CAAC,aAAa,EACpB,cAAc,EACd,gBAAgB,EAChB,MAAM,CAAC,eAAe,CACvB,EACD,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,UAAU,EAAE,CAAC;IACtC,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,SAAS,CAAC;IACnE,MAAM,QAAQ,GAAG,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,uBAAuB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IACjF,MAAM,aAAa,GACjB,IAAI,KAAK,QAAQ,IAAI,cAAc;QACjC,CAAC,CAAC,uBAAuB,CACrB,qBAAqB;YACnB,CAAC,MAAM,CAAC,MAAM,YAAY,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,EACnE,OAAO,EACP,QAAQ,CACT;QACH,CAAC,CAAC,SAAS,CAAC;IAChB,OAAO;QACL,IAAI;QACJ,QAAQ,EAAE,QAAQ,CAAC,WAAW,CAAC;QAC/B,SAAS,EAAE,MAAM,CAAC,EAAE;QACpB,KAAK,EAAE,CAAC,MAAM,EAAE,CAAC,cAAc,EAAE,CAAC,IAAI,WAAW,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;QACxE,SAAS;QACT,UAAU,EAAE,OAAO,CAAC,MAAM;QAC1B,OAAO,EAAE,qBAAqB,CAAC,OAAO,CAAC;QACvC,aAAa;KACd,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,qBAAqB,CAClC,WAAmB,EACnB,MAAqB;IAErB,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;QACzB,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QACjD,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,MAAM,oBAAoB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,IAAI,SAAS,CAAC;QACzE,CAAC;QACD,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;YAC3B,MAAM,KAAK,GAAG,mBAAmB,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;YAChF,IAAI,KAAK;gBAAE,OAAO,CAAC,MAAM,oBAAoB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,IAAI,SAAS,CAAC;QAC/E,CAAC;IACH,CAAC;IACD,OAAO,iCAAiC,CAAC,WAAW,CAAC,CAAC;AACxD,CAAC;AAED,SAAS,mBAAmB,CAAC,UAAkB,EAAE,QAAgB;IAC/D,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3C,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAAE,SAAS;QACvC,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;YACxC,IAAI,YAAY,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,EAAE,KAAK,QAAQ;gBAAE,OAAO,QAAQ,CAAC;QAC1E,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,KAAK,UAAU,iCAAiC,CAC9C,WAAmB;IAEnB,IAAI,CAAC,uBAAuB,CAAC,WAAW,CAAC;QAAE,OAAO,SAAS,CAAC;IAE5D,MAAM,aAAa,GAAG,yBAAyB,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAC/E,IAAI,CAAC,aAAa,IAAI,aAAa,KAAK,WAAW;QAAE,OAAO,SAAS,CAAC;IAEtE,OAAO,CAAC,MAAM,oBAAoB,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC,IAAI,SAAS,CAAC;AAC5E,CAAC;AAED,SAAS,oBAAoB,CAC3B,WAAmB,EACnB,aAAiC,EACjC,cAAkC,EAClC,gBAAyB,EACzB,qBAA8B;IAE9B,IAAI,CAAC,cAAc;QAAE,OAAO,KAAK,CAAC;IAElC,IAAI,aAAa,EAAE,CAAC;QAClB,MAAM,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;QAC9C,IACE,cAAc,KAAK,cAAc;YACjC,CAAC,wBAAwB,CAAC,cAAc,CAAC,IAAI,wBAAwB,CAAC,cAAc,CAAC,CAAC,EACtF,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,gBAAgB,IAAI,qBAAqB,EAAE,CAAC;YAC9C,OAAO,qBAAqB,KAAK,gBAAgB,CAAC;QACpD,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,CAAC,uBAAuB,CAAC,WAAW,CAAC;QAAE,OAAO,KAAK,CAAC;IACxD,OAAO,yBAAyB,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,cAAc,CAAC;AACrF,CAAC;AAED,SAAS,uBAAuB,CAAC,WAAmB;IAClD,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;IACvC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9C,IAAI,4CAA4C,CAAC,IAAI,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAC7E,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,uBAAuB,CAC9B,aAA6B,EAC7B,YAA4B,EAC5B,QAAuB;IAEvB,MAAM,eAAe,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IACvE,IAAI,eAAe,KAAK,SAAS,IAAI,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE,CAAC;QACtE,MAAM,eAAe,GAAG,6BAA6B,CAAC,aAAa,EAAE,eAAe,CAAC,CAAC;QACtF,IAAI,eAAe;YAAE,OAAO,eAAe,CAAC;IAC9C,CAAC;IACD,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,OACE,WAAW,GAAG,aAAa,CAAC,MAAM;QAClC,WAAW,GAAG,YAAY,CAAC,MAAM;QACjC,aAAa,CAAC,WAAW,CAAC,EAAE,EAAE,KAAK,YAAY,CAAC,WAAW,CAAC,EAAE,EAAE,EAChE,CAAC;QACD,WAAW,IAAI,CAAC,CAAC;IACnB,CAAC;IAED,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;QACpB,OAAO,aAAa,CAAC,WAAW,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC;IAC5C,CAAC;IAED,MAAM,aAAa,GAAG,8BAA8B,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IAClF,IAAI,aAAa;QAAE,OAAO,aAAa,CAAC;IAExC,MAAM,SAAS,GAAG,yBAAyB,CAAC,YAAY,CAAC,CAAC;IAC1D,IAAI,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IAEjC,OAAO,6BAA6B,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;AACjE,CAAC;AAED,SAAS,6BAA6B,CACpC,OAAuB,EACvB,SAAiB;IAEjB,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;YAAE,SAAS;QACvC,MAAM,gBAAgB,GAAI,KAAK,CAAC,OAAmC,CAAC,SAAS,CAAC;QAC9E,IAAI,gBAAgB,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC,EAAE,CAAC;IACtD,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,8BAA8B,CACrC,aAA6B,EAC7B,YAA4B;IAE5B,MAAM,cAAc,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;QACrD,MAAM,UAAU,GAAG,2BAA2B,CAAC,KAAK,CAAC,CAAC;QACtD,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACxC,CAAC,CAAC,CAAC;IACH,MAAM,aAAa,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;QACnD,MAAM,UAAU,GAAG,2BAA2B,CAAC,KAAK,CAAC,CAAC;QACtD,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACxC,CAAC,CAAC,CAAC;IACH,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAEhF,IAAI,aAAa,GAAG,CAAC,CAAC,CAAC;IACvB,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,KAAK,IAAI,WAAW,GAAG,CAAC,EAAE,WAAW,GAAG,cAAc,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,CAAC;QAC7E,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,OAAO,WAAW,GAAG,MAAM,GAAG,cAAc,CAAC,MAAM,IAAI,MAAM,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC;YACrF,MAAM,aAAa,GAAG,cAAc,CAAC,WAAW,GAAG,MAAM,CAAC,CAAC;YAC3D,MAAM,YAAY,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;YAC3C,IACE,aAAa,KAAK,SAAS;gBAC3B,YAAY,KAAK,SAAS;gBAC1B,aAAa,CAAC,IAAI,KAAK,YAAY,CAAC,IAAI;gBACxC,aAAa,CAAC,cAAc,KAAK,YAAY,CAAC,cAAc,EAC5D,CAAC;gBACD,MAAM;YACR,CAAC;YACD,MAAM,IAAI,CAAC,CAAC;QACd,CAAC;QACD,IAAI,MAAM,GAAG,UAAU,EAAE,CAAC;YACxB,UAAU,GAAG,MAAM,CAAC;YACpB,aAAa,GAAG,WAAW,GAAG,MAAM,GAAG,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IAED,OAAO,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AAC7E,CAAC;AAQD,SAAS,2BAA2B,CAAC,KAAmB;IACtD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAC1C,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;IAChC,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IAEzD,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAClD,MAAM,cAAc,GAAG,8BAA8B,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAClE,IAAI,CAAC,cAAc;QAAE,OAAO,IAAI,CAAC;IAEjC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;AACrD,CAAC;AAED,SAAS,8BAA8B,CAAC,IAAY,EAAE,IAA0B;IAC9E,MAAM,UAAU,GAAG,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,2BAA2B,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IACrF,OAAO,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;AAChD,CAAC;AAED,SAAS,6BAA6B,CACpC,aAA6B,EAC7B,SAAgC;IAEhC,IAAI,WAA+B,CAAC;IAEpC,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;QAClC,MAAM,UAAU,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAC;QACnD,IAAI,CAAC,UAAU;YAAE,SAAS;QAC1B,IAAI,UAAU,CAAC,cAAc,KAAK,SAAS,CAAC,cAAc;YAAE,SAAS;QACrE,IACE,SAAS,CAAC,gBAAgB,KAAK,SAAS;YACxC,UAAU,CAAC,gBAAgB,KAAK,SAAS;YACzC,UAAU,CAAC,gBAAgB,KAAK,SAAS,CAAC,gBAAgB,EAC1D,CAAC;YACD,OAAO,KAAK,CAAC,EAAE,CAAC;QAClB,CAAC;QACD,WAAW,KAAK,KAAK,CAAC,EAAE,CAAC;IAC3B,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAOD,SAAS,yBAAyB,CAAC,OAAuB;IACxD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,UAAU,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAC;QACnD,IAAI,UAAU;YAAE,OAAO,UAAU,CAAC;IACpC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,wBAAwB,CAAC,KAAmB;IACnD,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAE3E,MAAM,IAAI,GAAG,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAClD,MAAM,cAAc,GAAG,2BAA2B,CAAC,IAAI,CAAC,CAAC;IACzD,IAAI,CAAC,cAAc;QAAE,OAAO,IAAI,CAAC;IAEjC,MAAM,gBAAgB,GACpB,OAAO,KAAK,CAAC,OAAO,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;IACpF,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,CAAC;AAC9C,CAAC;AAED,SAAS,2BAA2B,CAAC,IAAY;IAC/C,MAAM,gBAAgB,GAAG,IAAI,CAAC,OAAO,CACnC,iIAAiI,EACjI,EAAE,CACH,CAAC;IACF,OAAO,gBAAgB;SACpB,OAAO,CAAC,8DAA8D,EAAE,EAAE,CAAC;SAC3E,IAAI,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,qBAAqB,CAAC,OAAuB;IACpD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;YAAE,SAAS;QACvC,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,EAAE,IAAI;YAAE,SAAS;QAC1B,OAAO,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,eAAe,CAAC,IAAY;IACnC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACpD,OAAO,UAAU,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,UAAU,CAAC;AAC7E,CAAC;AAED,SAAS,cAAc,CAAC,KAAmB;IACzC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,SAAS;YACZ,OAAO,eAAe,CAAC,KAAK,CAAC,CAAC;QAChC,KAAK,YAAY;YACf,OAAO,kBAAkB,CAAC,KAAK,CAAC,CAAC;QACnC,KAAK,gBAAgB;YACnB,OAAO,sBAAsB,CAAC,KAAK,CAAC,CAAC;QACvC,KAAK,QAAQ;YACX,OAAO;gBACL,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,iBAAiB,KAAK,CAAC,UAAU,EAAE;gBAC1C,IAAI,EAAE,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;gBAClF,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE;gBAC/B,IAAI,EAAE,OAAO;aACd,CAAC;QACJ;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAoBD,SAAS,eAAe,CAAC,KAA0B;IACjD,MAAM,OAAO,GAAG,KAAK,CAAC,OAA2C,CAAC;IAElE,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;QACrB,KAAK,MAAM;YACT,OAAO;gBACL,IAAI,EAAE,MAAM;gBACZ,KAAK,EAAE,MAAM;gBACb,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC;gBACpC,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE;gBAC/B,OAAO,EAAE,KAAK,CAAC,EAAE;aAClB,CAAC;QACJ,KAAK,WAAW,EAAE,CAAC;YACjB,MAAM,aAAa,GACjB,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,YAAY,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC9F,MAAM,SAAS,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACxF,OAAO;gBACL,IAAI,EAAE,WAAW;gBACjB,KAAK,EAAE,WAAW;gBAClB,IAAI,EAAE,aAAa;gBACnB,IAAI,EACF,SAAS,CAAC,MAAM,GAAG,CAAC;oBAClB,CAAC,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE;oBAC3D,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;gBACjC,OAAO,EAAE,KAAK,CAAC,EAAE;aAClB,CAAC;QACJ,CAAC;QACD,KAAK,YAAY;YACf,OAAO;gBACL,IAAI,EAAE,MAAM;gBACZ,KAAK,EAAE,iBAAiB,MAAM,CAAC,OAAO,CAAC,QAAQ,IAAI,SAAS,CAAC,EAAE;gBAC/D,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC;gBACpC,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE;gBAC/B,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;gBACpC,OAAO,EAAE,KAAK,CAAC,EAAE;aAClB,CAAC;QACJ,KAAK,eAAe,EAAE,CAAC;YACrB,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YACrD,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YACnD,MAAM,OAAO,GAAG;gBACd,OAAO,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,cAAc,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE;gBAC5E,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE;gBAC3C,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE;aAC5C,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YAClB,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC9F,OAAO;gBACL,IAAI,EAAE,MAAM;gBACZ,KAAK,EAAE,gBAAgB;gBACvB,IAAI,EAAE,IAAI,IAAI,aAAa;gBAC3B,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE;gBAC/B,OAAO,EAAE,KAAK,CAAC,EAAE;aAClB,CAAC;QACJ,CAAC;QACD,KAAK,QAAQ;YACX,OAAO;gBACL,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,oBAAoB,MAAM,CAAC,OAAO,CAAC,UAAU,IAAI,QAAQ,CAAC,EAAE;gBACnE,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC;gBACpC,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE;gBAC/B,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,KAAK,CAAC,EAAE;aAClB,CAAC;QACJ,KAAK,eAAe;YAClB,OAAO;gBACL,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,iBAAiB;gBACxB,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;gBACnC,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE;gBAC/B,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,KAAK,CAAC,EAAE;aAClB,CAAC;QACJ,KAAK,mBAAmB;YACtB,OAAO;gBACL,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,oBAAoB;gBAC3B,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;gBACnC,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE;gBAC/B,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,KAAK,CAAC,EAAE;aAClB,CAAC;QACJ;YACE,OAAO;gBACL,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,aAAa,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,SAAS,CAAC,EAAE;gBACvD,IAAI,EAAE,aAAa,CAAC,OAAO,CAAC,OAAO,CAAC;gBACpC,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE;gBAC/B,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,KAAK,CAAC,EAAE;aAClB,CAAC;IACN,CAAC;AACH,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAsB;IAChD,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,mBAAmB;QAC1B,IAAI,EAAE,KAAK,CAAC,OAAO;QACnB,IAAI,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,KAAK,CAAC,YAAY,2BAA2B;QACrF,IAAI,EAAE,OAAO;KACd,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAgC;IAC9D,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,iBAAiB;QACxB,IAAI,EAAE,KAAK,CAAC,OAAO;QACnB,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE;QAC/B,IAAI,EAAE,OAAO;KACd,CAAC;AACJ,CAAC;AAED,SAAS,aAAa,CAAC,OAAgB;IACrC,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC;IAChD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,CAAC;IAEvC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,SAAS;QAClD,MAAM,KAAK,GAAG,KAAgC,CAAC;QAC/C,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC5D,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACvB,SAAS;QACX,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,OAAO,KAAK,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YACpE,KAAK,CAAC,IAAI,CAAC,eAAe,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC5C,SAAS;QACX,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAG,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;YAClE,MAAM,IAAI,GAAG,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAC3F,KAAK,CAAC,IAAI,CAAC,CAAC,cAAc,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;YACpE,SAAS;QACX,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC3B,KAAK,CAAC,IAAI,CAAC,UAAU,MAAM,CAAC,KAAK,CAAC,QAAQ,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC5B,CAAC","sourcesContent":["import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { existsSync, readdirSync } from \"node:fs\";\nimport type {\n BranchSummaryEntry as SessionBranchSummaryEntry,\n CompactionEntry,\n} from \"../../../harness/index.js\";\nimport { SessionStore } from \"../../../sessions/session-store.js\";\nimport type { SessionEntry, SessionMessageEntry } from \"../../../sessions/types.js\";\nimport {\n getThreadSessionFile,\n resolveChannelSessionFile,\n tryResolveThreadSession,\n} from \"../../../sessions/store.js\";\nimport { isPlatformHistorySession } from \"../../../sessions/store.js\";\nimport type { SessionHeader } from \"../../../sessions/types.js\";\nimport type {\n SessionViewItem,\n SessionViewRelation,\n SessionViewModel,\n SessionViewToken,\n SessionViewTokenCreateOptions,\n} from \"./types.js\";\nexport type { SessionViewModel, SessionViewToken, SessionViewTokenCreateOptions } from \"./types.js\";\nimport { basename } from \"node:path\";\nimport { InMemoryTokenStore } from \"../token-store.js\";\nimport MarkdownIt from \"markdown-it\";\nimport type { ConversationResponder } from \"../../index.js\";\nimport {\n createConversationEvent,\n createConversationMessage,\n type ConversationContext,\n} from \"../../index.js\";\nimport { createOfficeAddress } from \"../../../office/index.js\";\nimport * as log from \"../../../log.js\";\nimport {\n escapeHtml,\n jsonResponse as json,\n readJsonBody,\n renderPortalShell,\n} from \"../portal-shell.js\";\nimport { reportUserFacingError } from \"../../../observability/index.js\";\nimport { inferConversationKind } from \"../../../sessions/session-key.js\";\nimport { isThreadSessionKey, threadSuffixOf } from \"../../../sessions/session-key.js\";\n\nconst SESSION_VIEW_TOKEN_TTL_MS = 24 * 60 * 60 * 1000;\n\nexport class InMemorySessionViewTokenStore extends InMemoryTokenStore<SessionViewToken> {\n create(options: SessionViewTokenCreateOptions): SessionViewToken {\n return this.createRecord(SESSION_VIEW_TOKEN_TTL_MS, {\n platform: options.platform,\n platformUserId: options.platformUserId,\n ...(options.platformUserName ? { platformUserName: options.platformUserName } : {}),\n conversationId: options.conversationId,\n sessionKey: options.sessionKey,\n sessionFile: options.sessionFile,\n });\n }\n}\n\nconst markdown = new MarkdownIt({\n html: false,\n linkify: true,\n breaks: true,\n});\n\nconst defaultLinkOpen = markdown.renderer.rules.link_open;\ntype LinkOpenRule = NonNullable<typeof defaultLinkOpen>;\nmarkdown.renderer.rules.link_open = (...args: Parameters<LinkOpenRule>) => {\n const [tokens, idx, options, env, self] = args;\n const token = tokens[idx];\n token?.attrSet(\"target\", \"_blank\");\n token?.attrSet(\"rel\", \"noreferrer noopener\");\n return defaultLinkOpen\n ? defaultLinkOpen(tokens, idx, options, env, self)\n : self.renderToken(tokens, idx, options);\n};\n\ntype SessionStreamEvent =\n | { type: \"status\"; running: boolean }\n | { type: \"user\"; html: string }\n | { type: \"assistant\"; html: string }\n | { type: \"assistant_remove\" }\n | { type: \"tool\"; html: string }\n | { type: \"system\"; html: string }\n | {\n type: \"refresh\";\n timelineHtml: string;\n updatedAt: string;\n entryCount: number;\n running: boolean;\n }\n | { type: \"error\"; message: string };\n\nclass SessionViewStreamHub {\n private listeners = new Map<string, Set<(event: SessionStreamEvent) => void>>();\n\n subscribe(key: string, listener: (event: SessionStreamEvent) => void): () => void {\n const set = this.listeners.get(key) ?? new Set<(event: SessionStreamEvent) => void>();\n set.add(listener);\n this.listeners.set(key, set);\n return () => {\n const current = this.listeners.get(key);\n if (!current) return;\n current.delete(listener);\n if (current.size === 0) this.listeners.delete(key);\n };\n }\n\n publish(key: string, event: SessionStreamEvent): void {\n const set = this.listeners.get(key);\n if (!set) return;\n for (const listener of set) listener(event);\n }\n}\n\nconst sessionViewStreamHub = new SessionViewStreamHub();\n\nexport type { SessionViewInteractiveOptions } from \"./types.js\";\nimport type { SessionViewInteractiveOptions } from \"./types.js\";\n\nexport async function handleSessionViewRequest(\n req: IncomingMessage,\n res: ServerResponse,\n url: URL,\n sessionViewTokenStore?: InMemorySessionViewTokenStore,\n interactive?: SessionViewInteractiveOptions,\n): Promise<boolean> {\n if (req.method === \"POST\" && url.pathname === \"/session/message\") {\n await handleSessionMessageRequest(req, res, sessionViewTokenStore, interactive);\n return true;\n }\n\n if (req.method === \"GET\" && url.pathname === \"/session/stream\") {\n await handleSessionStreamRequest(req, res, url, sessionViewTokenStore, interactive);\n return true;\n }\n\n if (req.method !== \"GET\" || url.pathname !== \"/session\") {\n return false;\n }\n\n const target = await resolveSessionRequestTarget(\n sessionViewTokenStore,\n url.searchParams.get(\"token\"),\n url.searchParams.get(\"session\"),\n );\n if (!target.ok) {\n res.writeHead(target.status, { \"Content-Type\": \"text/html; charset=utf-8\" });\n res.end(renderStatusPage(\"Session unavailable\", target.message));\n return true;\n }\n const { activeSessionKey, entry, targetSessionFile } = target;\n\n try {\n const model = await loadSessionViewModel(targetSessionFile);\n const displayedSessionKey = activeSessionKey;\n const isRunning =\n interactive?.handler.isRunning(\n createOfficeAddress(entry.platform, entry.conversationId),\n displayedSessionKey,\n ) ?? false;\n res.writeHead(200, {\n \"Content-Type\": \"text/html; charset=utf-8\",\n \"Cache-Control\": \"no-store\",\n });\n res.end(\n renderSessionPage({\n model,\n token: entry.token,\n expiresAt: entry.expiresAt,\n isRunning,\n displayedSessionKey,\n conversationId: entry.conversationId,\n }),\n );\n } catch (error) {\n log.logWarning(\n `[${entry.conversationId}] Failed to render session ${entry.sessionFile}`,\n error instanceof Error ? error.message : String(error),\n );\n reportUserFacingError(error, {\n domain: \"session_view\",\n surface: \"session_view\",\n operation: \"render_session\",\n severity: \"error\",\n platform: entry.platform,\n context: {\n conversationId: entry.conversationId,\n sessionKey: entry.sessionKey,\n sessionFile: basename(targetSessionFile),\n },\n });\n res.writeHead(500, { \"Content-Type\": \"text/html; charset=utf-8\" });\n res.end(renderStatusPage(\"Session unavailable\", \"The session could not be loaded right now.\"));\n }\n\n return true;\n}\n\ntype SessionRequestTarget =\n | {\n ok: true;\n entry: SessionViewToken;\n targetSessionFile: string;\n activeSessionKey: string;\n }\n | {\n ok: false;\n status: 400 | 500 | 503;\n message: string;\n };\n\nasync function resolveSessionRequestTarget(\n sessionViewTokenStore: InMemorySessionViewTokenStore | undefined,\n rawToken: string | null | undefined,\n requestedSession: string | null | undefined,\n): Promise<SessionRequestTarget> {\n if (!sessionViewTokenStore) {\n return { ok: false, status: 503, message: \"Session view is not configured.\" };\n }\n const token = rawToken?.trim() ?? \"\";\n const entry = token ? sessionViewTokenStore.peek(token) : undefined;\n if (!entry) {\n return { ok: false, status: 400, message: \"This session link is invalid or has expired.\" };\n }\n\n let targetSessionFile: string | null;\n try {\n targetSessionFile = await resolveRequestedSessionFile(entry.sessionFile, requestedSession);\n } catch (error) {\n log.logWarning(\n `[${entry.conversationId}] Corrupted session file referenced for ${entry.sessionFile}`,\n error instanceof Error ? error.message : String(error),\n );\n reportUserFacingError(error, {\n domain: \"session_view\",\n surface: \"session_view\",\n operation: \"resolve_requested_session\",\n severity: \"error\",\n platform: entry.platform,\n context: {\n conversationId: entry.conversationId,\n sessionKey: entry.sessionKey,\n sessionFile: basename(entry.sessionFile),\n requestedSession,\n },\n });\n return { ok: false, status: 500, message: \"The selected session file is corrupted.\" };\n }\n if (!targetSessionFile) {\n return { ok: false, status: 400, message: \"The selected session is invalid.\" };\n }\n\n return {\n ok: true,\n entry,\n targetSessionFile,\n activeSessionKey: resolveDisplayedSessionKey(entry, targetSessionFile),\n };\n}\n\nfunction resolveDisplayedSessionKey(\n entry: { platform: string; conversationId: string; sessionKey: string },\n sessionFile: string,\n): string {\n if (entry.platform === \"slack\") {\n const fileName = basename(sessionFile, \".jsonl\");\n if (/^\\d+\\.\\d+$/.test(fileName)) {\n return `${entry.conversationId}:${fileName}`;\n }\n return entry.conversationId;\n }\n return entry.sessionKey;\n}\n\nfunction sessionStreamKey(entry: {\n platform: string;\n conversationId: string;\n sessionKey: string;\n}): string {\n return `${entry.platform}:${entry.conversationId}:${entry.sessionKey}`;\n}\n\nfunction renderTimelineItems(items: SessionViewItem[], token: string): string {\n return items.length > 0\n ? items.map((item) => renderItem(item, token)).join(\"\\n\")\n : `<div class=\"system-event\"><span class=\"event-dot\"></span><span class=\"event-text\">No messages yet — send one to the bot, then refresh.</span></div>`;\n}\n\nfunction renderSessionPage(options: {\n model: SessionViewModel;\n token: string;\n expiresAt: number;\n isRunning: boolean;\n displayedSessionKey: string;\n conversationId: string;\n}): string {\n const { model, token, expiresAt, isRunning, displayedSessionKey, conversationId } = options;\n const items = renderTimelineItems(model.items, token);\n\n const relatedSections = model.parent\n ? `<section class=\"related-card stack\">\n <p class=\"eyebrow\">Parent session</p>\n ${renderRelationCard(model.parent, token)}\n </section>`\n : \"\";\n\n const body = `<header class=\"page-head\">\n <div>\n <p class=\"eyebrow\">Session</p>\n <h2 class=\"page-title\">${esc(model.title)}</h2>\n <p class=\"page-desc\">\n <span>Created ${esc(formatDate(model.createdAt))}</span> ·\n <span>Updated <strong data-session-updated>${esc(formatDate(model.updatedAt))}</strong></span> ·\n <span><strong data-session-entries>${esc(String(model.entryCount))}</strong> entries</span>\n </p>\n </div>\n <div class=\"session-side\">\n <span class=\"session-badge session-badge-status${isRunning ? \" is-running\" : \"\"}\"><span class=\"session-badge-dot\"></span><strong data-session-status>${esc(isRunning ? \"Running\" : \"Idle\")}</strong></span>\n <span class=\"session-badge\">${esc(displayedSessionKey === conversationId ? \"Channel\" : \"Thread\")}</span>\n </div>\n </header>\n\n <div class=\"session-detail-row\">\n <span class=\"session-detail\"><span class=\"session-detail-label\">Session</span><code>${esc(model.sessionId.slice(0, 8))}</code></span>\n <span class=\"session-detail\"><span class=\"session-detail-label\">File</span><code>${esc(model.fileName)}</code></span>\n <span class=\"session-detail\"><span class=\"session-detail-label\">Expires</span><span>${esc(formatDate(new Date(expiresAt).toISOString()))}</span></span>\n </div>\n\n ${relatedSections}\n\n <div class=\"timeline-shell\">\n <div class=\"timeline-list\" data-timeline-list>\n ${items}\n </div>\n </div>\n\n <button class=\"jump-latest-btn\" type=\"button\" hidden data-jump-latest aria-label=\"Jump to latest\" title=\"Jump to latest\">↓</button>\n\n <section class=\"composer-card\">\n <form class=\"composer-form\" data-session-composer>\n <input type=\"hidden\" name=\"token\" value=\"${esc(token)}\">\n <input type=\"hidden\" name=\"session\" value=\"${esc(model.fileName)}\">\n <input type=\"hidden\" name=\"sessionKey\" value=\"${esc(displayedSessionKey)}\">\n <textarea name=\"text\" rows=\"1\" placeholder=\"Ask mikan in this session… (replies stay in Session View)\" required></textarea>\n <div class=\"composer-actions\">\n <span class=\"composer-status\" data-composer-status></span>\n <button class=\"composer-send-btn\" type=\"submit\" aria-label=\"Send\" title=\"Send\">↑</button>\n </div>\n </form>\n </section>`;\n\n return renderHtmlDocument(`${model.title} · Session Viewer`, body, isRunning);\n}\n\nfunction renderRelationCard(relation: SessionViewRelation, token: string): string {\n const href = `/session?token=${encodeURIComponent(token)}&session=${encodeURIComponent(relation.fileName)}`;\n const summary = relation.summary ? `<p class=\"related-summary\">${esc(relation.summary)}</p>` : \"\";\n return `<a class=\"related-link\" href=\"${href}\">\n <span class=\"related-copy\">\n <strong class=\"related-title\">${esc(relation.title)}</strong>\n ${summary}\n <span class=\"related-meta\">${esc(formatDate(relation.updatedAt))} · ${esc(String(relation.entryCount))} entries · ${esc(relation.fileName)}</span>\n </span>\n <span class=\"related-arrow\" aria-hidden=\"true\">→</span>\n </a>`;\n}\n\nfunction renderThreadLinks(relations: SessionViewRelation[] | undefined, token: string): string {\n if (!relations || relations.length === 0) return \"\";\n return `<div class=\"thread-links\">${relations\n .map((relation) => {\n const href = `/session?token=${encodeURIComponent(token)}&session=${encodeURIComponent(relation.fileName)}`;\n return `<a class=\"thread-link\" href=\"${href}\" title=\"Open ${esc(relation.title)}\">\n <span class=\"thread-dot\" aria-hidden=\"true\"></span>\n <span class=\"thread-text\">Thread</span>\n </a>`;\n })\n .join(\"\")}</div>`;\n}\n\nexport function parseUserBody(raw: string): {\n timestamp: string | null;\n username: string | null;\n threadTs: string | null;\n header: string | null;\n content: string;\n} {\n let m = raw.match(\n /^\\[([0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}[+-][0-9]{2}:[0-9]{2})\\]\\s*\\[([^\\]]+)\\](?:\\s*\\[in-thread:([^\\]]+)\\])?:\\s*([\\s\\S]*)$/,\n );\n if (m) {\n const header = [`[${m[1]}]`, `[${m[2]}]`, m[3] ? `[in-thread:${m[3]}]` : \"\"]\n .filter(Boolean)\n .join(\" \");\n return {\n timestamp: m[1] ?? null,\n username: m[2] ?? null,\n threadTs: m[3] ?? null,\n header,\n content: m[4] ?? \"\",\n };\n }\n m = raw.match(/^\\[([^\\]]+)\\](?:\\s*\\[in-thread:([^\\]]+)\\])?:\\s*([\\s\\S]*)$/);\n if (m) {\n const header = [`[${m[1]}]`, m[2] ? `[in-thread:${m[2]}]` : \"\"].filter(Boolean).join(\" \");\n return {\n timestamp: null,\n username: m[1] ?? null,\n threadTs: m[2] ?? null,\n header,\n content: m[3] ?? \"\",\n };\n }\n return { timestamp: null, username: null, threadTs: null, header: null, content: raw };\n}\n\ntype ParsedUserBody = ReturnType<typeof parseUserBody>;\n\nfunction renderCopyButton(label = \"Copy message\"): string {\n return `<div class=\"msg-actions\"><button class=\"copy-action-btn\" type=\"button\" data-copy-button data-copy-label=\"${esc(label)}\" aria-label=\"${esc(label)}\" title=\"${esc(label)}\"><svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" aria-hidden=\"true\"><rect x=\"9\" y=\"9\" width=\"11\" height=\"11\" rx=\"2\" stroke=\"currentColor\" stroke-width=\"1.8\"></rect><path d=\"M6 15H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h8a2 2 0 0 1 2 2v1\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"></path></svg></button></div>`;\n}\n\nfunction renderItem(item: SessionViewItem, token?: string): string {\n if (item.kind === \"system\") {\n const parts = [item.title, item.body].filter((x): x is string => Boolean(x)).map(esc);\n const time = item.meta\n ? ` · <time class=\"event-time\">${esc(formatDate(item.meta))}</time>`\n : \"\";\n return `<div class=\"system-event\"><span class=\"event-dot\"></span><span class=\"event-text\">${parts.join(\" — \")}</span>${time}</div>`;\n }\n\n if (item.kind === \"tool\") {\n const toneClass = item.tone === \"err\" ? \" tone-err\" : item.tone === \"ok\" ? \" tone-ok\" : \"\";\n const body = item.body ? `<pre class=\"tool-output${toneClass}\">${esc(item.body)}</pre>` : \"\";\n const time = item.meta ? `<time class=\"tool-time\">${esc(formatDate(item.meta))}</time>` : \"\";\n return `<div class=\"tool-block\">\n <div class=\"tool-header\">\n <span class=\"tool-icon\"><svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\"><path d=\"M1.5 2L5 5.5 1.5 9\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 9h2.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/></svg></span>\n <span class=\"tool-name\">${esc(item.title)}</span>\n ${time}\n </div>\n ${body}\n</div>`;\n }\n\n const time = item.meta ? `<time class=\"msg-time\">${esc(formatDate(item.meta))}</time>` : \"\";\n\n if (item.kind === \"user\") {\n const parsed: ParsedUserBody = item.body\n ? parseUserBody(item.body)\n : { timestamp: null, username: null, threadTs: null, header: null, content: \"\" };\n const { username, threadTs, header, content } = parsed;\n const initial = username ? esc(username.slice(0, 2).toUpperCase()) : \"U\";\n const rawHeader = header ? `<div class=\"msg-raw-header\">${esc(header)}</div>` : \"\";\n const body = content ? renderMarkdownBlock(content, \"user\") : \"\";\n const threadBadge = threadTs\n ? `<div class=\"thread-badge\" title=\"Thread ${esc(threadTs)}\">Thread · <code>${esc(threadTs)}</code></div>`\n : \"\";\n const threads = renderThreadLinks(item.threads, token ?? \"\");\n return `<div class=\"msg-row msg-user copy-host\">\n <div class=\"msg-main user-main\">\n <div class=\"user-bubble\">\n ${rawHeader}\n ${threadBadge}\n ${body}\n ${threads}\n ${time}\n </div>\n ${renderCopyButton()}\n </div>\n <div class=\"msg-avatar user-avatar\" title=\"${username ? esc(username) : \"User\"}\">${initial}</div>\n</div>`;\n }\n\n const body = item.body ? renderMarkdownBlock(item.body, \"assistant\") : \"\";\n const threads = renderThreadLinks(item.threads, token ?? \"\");\n return `<div class=\"msg-row msg-assistant copy-host\">\n <div class=\"msg-avatar asst-avatar\" aria-hidden=\"true\">A</div>\n <div class=\"msg-main asst-main\">\n <div class=\"asst-card\">\n ${body}\n ${threads}\n ${time}\n </div>\n ${renderCopyButton()}\n </div>\n</div>`;\n}\n\nfunction renderMarkdownBlock(text: string, variant: \"user\" | \"assistant\"): string {\n return `<div class=\"msg-body markdown-body markdown-${variant}\">${markdown.render(text)}</div>`;\n}\n\nfunction renderLiveUserMessage(text: string, userName: string): string {\n const initial = esc(userName.slice(0, 2).toUpperCase());\n return `<div class=\"msg-row msg-user copy-host\" data-live-item>\n <div class=\"msg-main user-main\">\n <div class=\"user-bubble\">\n ${renderMarkdownBlock(text, \"user\")}\n </div>\n ${renderCopyButton()}\n </div>\n <div class=\"msg-avatar user-avatar\" title=\"${esc(userName)}\">${initial}</div>\n</div>`;\n}\n\nfunction renderLiveAssistantMessage(text: string): string {\n return `<div class=\"msg-row msg-assistant copy-host\" data-live-assistant>\n <div class=\"msg-avatar asst-avatar\" aria-hidden=\"true\">A</div>\n <div class=\"msg-main asst-main\">\n <div class=\"asst-card\">\n ${renderMarkdownBlock(text, \"assistant\")}\n </div>\n ${renderCopyButton()}\n </div>\n</div>`;\n}\n\nfunction renderLiveToolResult(result: {\n toolName: string;\n result: string;\n isError: boolean;\n}): string {\n const toneClass = result.isError ? \" tone-err\" : \" tone-ok\";\n return `<div class=\"tool-block\" data-live-item>\n <div class=\"tool-header\">\n <span class=\"tool-icon\"><svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"none\"><path d=\"M1.5 2L5 5.5 1.5 9\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/><path d=\"M6 9h2.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"/></svg></span>\n <span class=\"tool-name\">${esc(result.toolName)}</span>\n </div>\n <pre class=\"tool-output${toneClass}\">${esc(result.result)}</pre>\n</div>`;\n}\n\nfunction renderLiveSystemEvent(text: string, tone: \"default\" | \"err\" = \"default\"): string {\n const cls = tone === \"err\" ? \" system-event-err\" : \"\";\n return `<div class=\"system-event${cls}\" data-live-item><span class=\"event-dot\"></span><span class=\"event-text\">${esc(text)}</span></div>`;\n}\n\nasync function handleSessionStreamRequest(\n req: IncomingMessage,\n res: ServerResponse,\n url: URL,\n sessionViewTokenStore?: InMemorySessionViewTokenStore,\n interactive?: SessionViewInteractiveOptions,\n): Promise<void> {\n if (!interactive) {\n res.writeHead(503, { \"Content-Type\": \"text/plain; charset=utf-8\" });\n res.end(\"Session stream is not configured.\");\n return;\n }\n\n const target = await resolveSessionRequestTarget(\n sessionViewTokenStore,\n url.searchParams.get(\"token\"),\n url.searchParams.get(\"session\"),\n );\n if (!target.ok) {\n res.writeHead(target.status, { \"Content-Type\": \"text/plain; charset=utf-8\" });\n res.end(target.message);\n return;\n }\n const { activeSessionKey, entry } = target;\n const streamKey = sessionStreamKey({ ...entry, sessionKey: activeSessionKey });\n res.writeHead(200, {\n \"Content-Type\": \"text/event-stream; charset=utf-8\",\n \"Cache-Control\": \"no-store\",\n Connection: \"keep-alive\",\n });\n res.write(\n `data: ${JSON.stringify({\n type: \"status\",\n running: interactive.handler.isRunning(\n createOfficeAddress(entry.platform, entry.conversationId),\n activeSessionKey,\n ),\n })}\\n\\n`,\n );\n\n const unsubscribe = sessionViewStreamHub.subscribe(streamKey, (event) => {\n res.write(`data: ${JSON.stringify(event)}\\n\\n`);\n });\n const heartbeat = setInterval(() => {\n res.write(\": keep-alive\\n\\n\");\n }, 15000);\n\n req.on(\"close\", () => {\n clearInterval(heartbeat);\n unsubscribe();\n });\n}\n\nasync function handleSessionMessageRequest(\n req: IncomingMessage,\n res: ServerResponse,\n sessionViewTokenStore?: InMemorySessionViewTokenStore,\n interactive?: SessionViewInteractiveOptions,\n): Promise<void> {\n if (!interactive) {\n json(res, 503, { ok: false, error: \"Session chat is not configured.\" });\n return;\n }\n\n const body = await readJsonBody(req, res, 1024 * 1024);\n if (!body) return;\n\n const token = typeof body.token === \"string\" ? body.token.trim() : \"\";\n const text = typeof body.text === \"string\" ? body.text.trim() : \"\";\n const requestedSession = typeof body.session === \"string\" ? body.session.trim() || null : null;\n const requestedSessionKey = typeof body.sessionKey === \"string\" ? body.sessionKey.trim() : \"\";\n if (!token || !text) {\n json(res, 400, { ok: false, error: \"Missing token or text.\" });\n return;\n }\n\n const target = await resolveSessionRequestTarget(sessionViewTokenStore, token, requestedSession);\n if (!target.ok) {\n json(res, target.status, { ok: false, error: target.message });\n return;\n }\n const { activeSessionKey, entry, targetSessionFile } = target;\n if (requestedSessionKey && requestedSessionKey !== activeSessionKey) {\n json(res, 400, { ok: false, error: \"Session target mismatch.\" });\n return;\n }\n\n await dispatchSessionViewMessage({\n res,\n interactive,\n token,\n text,\n activeSessionKey,\n entry,\n targetSessionFile,\n });\n}\n\ninterface SessionViewMessageDispatch {\n res: ServerResponse;\n interactive: SessionViewInteractiveOptions;\n token: string;\n text: string;\n activeSessionKey: string;\n entry: SessionViewToken;\n targetSessionFile: string;\n}\n\nasync function dispatchSessionViewMessage(input: SessionViewMessageDispatch): Promise<void> {\n const { res, interactive, token, text, activeSessionKey, entry, targetSessionFile } = input;\n const bot = interactive.botsByPlatform[entry.platform];\n if (!bot) {\n json(res, 503, { ok: false, error: `No bot configured for ${entry.platform}.` });\n return;\n }\n\n const streamKey = sessionStreamKey({ ...entry, sessionKey: activeSessionKey });\n const conversationKind = inferConversationKind(entry.platform, entry.conversationId);\n const ts = (Date.now() / 1000).toFixed(6);\n const platformInfo = bot.getMessagingInfo();\n const platformUserName =\n entry.platformUserName ||\n platformInfo.users.find((user) => user.id === entry.platformUserId)?.userName ||\n platformInfo.users.find((user) => user.id === entry.platformUserId)?.displayName ||\n \"unknown\";\n const responder = createSessionViewResponseContext((event) => {\n sessionViewStreamHub.publish(streamKey, event);\n });\n const event = createConversationEvent({\n platform: entry.platform,\n type: \"session_view\",\n conversationId: entry.conversationId,\n conversationKind,\n ts,\n user: entry.platformUserId,\n text,\n attachments: [],\n sessionKey: activeSessionKey,\n ...(isThreadSessionKey(activeSessionKey)\n ? { thread_ts: threadSuffixOf(activeSessionKey)! }\n : {}),\n });\n const message = createConversationMessage({\n platform: entry.platform,\n conversationId: entry.conversationId,\n id: ts,\n sessionKey: activeSessionKey,\n conversationKind,\n userId: entry.platformUserId,\n userName: platformUserName,\n text,\n attachments: [],\n threadTs: event.thread_ts,\n });\n const context: ConversationContext = {\n address: event.address,\n message,\n responder,\n platform: { ...platformInfo, diagnostics: { showUsageSummary: false } },\n };\n\n sessionViewStreamHub.publish(streamKey, { type: \"status\", running: true });\n sessionViewStreamHub.publish(streamKey, {\n type: \"user\",\n html: renderLiveUserMessage(text, platformUserName),\n });\n\n void interactive.handler\n .handleEvent(event, bot, context)\n .then(async () => {\n const model = await loadSessionViewModel(targetSessionFile);\n sessionViewStreamHub.publish(streamKey, {\n type: \"refresh\",\n timelineHtml: renderTimelineItems(model.items, token),\n updatedAt: formatDate(model.updatedAt),\n entryCount: model.entryCount,\n running: false,\n });\n })\n .catch((error) => {\n log.logWarning(\n `[${entry.conversationId}] Session view message failed`,\n error instanceof Error ? error.message : String(error),\n );\n reportUserFacingError(error, {\n domain: \"session_view\",\n surface: \"session_view\",\n operation: \"interactive_message\",\n severity: \"error\",\n platform: entry.platform,\n context: {\n conversationId: entry.conversationId,\n sessionKey: activeSessionKey,\n messageId: ts,\n textLength: text.length,\n },\n });\n sessionViewStreamHub.publish(streamKey, {\n type: \"error\",\n message: error instanceof Error ? error.message : String(error),\n });\n sessionViewStreamHub.publish(streamKey, { type: \"status\", running: false });\n });\n\n json(res, 202, { ok: true, accepted: true });\n}\n\nfunction createSessionViewResponseContext(\n publish: (event: SessionStreamEvent) => void,\n): ConversationResponder {\n let accumulatedText = \"\";\n\n return {\n respond: async (text: string) => {\n accumulatedText = accumulatedText ? `${accumulatedText}\\n${text}` : text;\n publish({ type: \"assistant\", html: renderLiveAssistantMessage(accumulatedText) });\n },\n replaceResponse: async (text: string) => {\n accumulatedText = text;\n publish({ type: \"assistant\", html: renderLiveAssistantMessage(accumulatedText) });\n },\n respondDiagnostic: async (text: string, options?: { style?: \"muted\" | \"error\" }) => {\n if (options?.style === \"error\") {\n publish({ type: \"system\", html: renderLiveSystemEvent(text, \"err\") });\n }\n },\n respondToolResult: async (result) => {\n publish({ type: \"tool\", html: renderLiveToolResult(result) });\n },\n setTyping: async () => {\n publish({ type: \"status\", running: true });\n },\n setWorking: async (working: boolean) => {\n publish({ type: \"status\", running: working });\n },\n uploadFile: async () => {},\n deleteResponse: async () => {\n accumulatedText = \"\";\n publish({ type: \"assistant_remove\" });\n },\n };\n}\n\nfunction renderStatusPage(title: string, message: string): string {\n return renderHtmlDocument(\n title,\n `<section class=\"card stack\">\n <p class=\"eyebrow\">mikan</p>\n <h1 class=\"page-title\">${esc(title)}</h1>\n <div class=\"status err\">${esc(message)}</div>\n </section>`,\n false,\n );\n}\n\nfunction renderHtmlDocument(title: string, shellContent: string, isRunning: boolean): string {\n return renderPortalShell({\n activeView: \"session\",\n pageTitle: \"Session\",\n body: shellContent,\n extraStyles: sessionViewStyles,\n bodyAttributes: { \"data-session-running\": isRunning ? \"true\" : \"false\" },\n inlineScript: sessionViewScript,\n });\n}\n\nconst sessionViewScript = `\n const form = document.querySelector('[data-session-composer]');\n const timelineList = document.querySelector('[data-timeline-list]');\n const jumpLatestBtn = document.querySelector('[data-jump-latest]');\n const statusEl = document.querySelector('[data-session-status]');\n const updatedEl = document.querySelector('[data-session-updated]');\n const entriesEl = document.querySelector('[data-session-entries]');\n const composerStatus = form?.querySelector('[data-composer-status]');\n const textarea = form?.querySelector('textarea[name=\"text\"]');\n const submitButton = form?.querySelector('button[type=\"submit\"]');\n let liveAssistant = null;\n let running = document.body.dataset.sessionRunning === 'true';\n\n const isNearMessagingBottom = () => window.innerHeight + window.scrollY >= document.body.offsetHeight - 120;\n const scrollToLatest = (behavior = 'smooth') => window.scrollTo({ top: document.body.scrollHeight, behavior });\n const toggleJumpButton = () => {\n if (!jumpLatestBtn) return;\n jumpLatestBtn.hidden = isNearMessagingBottom();\n };\n const updateFollowState = () => {\n if (isNearMessagingBottom()) scrollToLatest('smooth');\n else toggleJumpButton();\n };\n const canSubmit = () => Boolean(textarea && textarea.value.trim()) && !running;\n const updateSubmitButtonState = () => {\n if (submitButton) submitButton.disabled = !canSubmit();\n };\n const setRunning = (value) => {\n running = value;\n document.body.dataset.sessionRunning = value ? 'true' : 'false';\n if (statusEl) statusEl.textContent = value ? 'Running' : 'Idle';\n updateSubmitButtonState();\n if (composerStatus && !value && composerStatus.textContent === 'Thinking…') {\n composerStatus.textContent = '';\n }\n };\n\n jumpLatestBtn?.addEventListener('click', () => {\n scrollToLatest('smooth');\n toggleJumpButton();\n });\n document.addEventListener('click', async (event) => {\n const button = event.target instanceof Element ? event.target.closest('[data-copy-button]') : null;\n if (!(button instanceof HTMLButtonElement)) return;\n const label = button.dataset.copyLabel || 'Copy message';\n const source = button.closest('.msg-actions')?.previousElementSibling;\n const text = source instanceof HTMLElement ? (source.innerText || source.textContent || '').trim() : '';\n if (!text) return;\n const setState = (state, transient) => {\n button.dataset.copyState = state;\n button.title = transient;\n button.setAttribute('aria-label', transient);\n window.setTimeout(() => {\n if (!button.isConnected) return;\n delete button.dataset.copyState;\n button.title = label;\n button.setAttribute('aria-label', label);\n }, 1200);\n };\n try {\n await navigator.clipboard.writeText(text);\n setState('done', 'Copied');\n } catch {\n setState('error', 'Copy failed');\n }\n });\n window.addEventListener('scroll', toggleJumpButton, { passive: true });\n\n if (textarea) {\n const resize = () => {\n textarea.style.height = 'auto';\n textarea.style.height = Math.min(textarea.scrollHeight, 240) + 'px';\n };\n textarea.addEventListener('input', () => {\n resize();\n updateSubmitButtonState();\n });\n textarea.addEventListener('keydown', (event) => {\n if (event.key !== 'Enter' || event.shiftKey) return;\n if (event.isComposing || event.keyCode === 229) return;\n event.preventDefault();\n if (!running) form?.requestSubmit();\n });\n resize();\n }\n\n setRunning(running);\n updateSubmitButtonState();\n\n const streamUrl = form\n ? '/session/stream?token=' + encodeURIComponent(form.token.value) + '&session=' + encodeURIComponent(form.session.value)\n : null;\n if (streamUrl) {\n const source = new EventSource(streamUrl);\n source.onmessage = (event) => {\n const payload = JSON.parse(event.data);\n switch (payload.type) {\n case 'status':\n setRunning(Boolean(payload.running));\n if (payload.running && composerStatus) composerStatus.textContent = 'Thinking…';\n break;\n case 'user':\n case 'tool':\n case 'system': {\n timelineList?.insertAdjacentHTML('beforeend', payload.html);\n updateFollowState();\n break;\n }\n case 'assistant': {\n if (!liveAssistant || !liveAssistant.isConnected) {\n timelineList?.insertAdjacentHTML('beforeend', payload.html);\n liveAssistant = timelineList?.querySelector('[data-live-assistant]:last-of-type') || null;\n } else {\n liveAssistant.outerHTML = payload.html;\n liveAssistant = timelineList?.querySelector('[data-live-assistant]:last-of-type') || null;\n }\n updateFollowState();\n break;\n }\n case 'assistant_remove':\n if (liveAssistant?.isConnected) liveAssistant.remove();\n liveAssistant = null;\n break;\n case 'refresh':\n if (timelineList) timelineList.innerHTML = payload.timelineHtml;\n liveAssistant = null;\n if (updatedEl) updatedEl.textContent = payload.updatedAt;\n if (entriesEl) entriesEl.textContent = String(payload.entryCount);\n setRunning(Boolean(payload.running));\n if (composerStatus) composerStatus.textContent = '';\n updateFollowState();\n break;\n case 'error':\n if (composerStatus) composerStatus.textContent = payload.message || 'Something went wrong';\n setRunning(false);\n break;\n }\n };\n }\n\n form?.addEventListener('submit', async (event) => {\n event.preventDefault();\n if (!textarea || !composerStatus) return;\n const text = textarea.value.trim();\n if (!text || running) return;\n composerStatus.textContent = 'Sending…';\n updateSubmitButtonState();\n try {\n const response = await fetch('/session/message', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ token: form.token.value, session: form.session.value, sessionKey: form.sessionKey.value, text }),\n });\n const payload = await response.json();\n if (!response.ok || !payload.ok) throw new Error(payload.error || 'Request failed');\n textarea.value = '';\n textarea.style.height = 'auto';\n composerStatus.textContent = 'Thinking…';\n setRunning(true);\n updateSubmitButtonState();\n scrollToLatest('smooth');\n } catch (err) {\n composerStatus.textContent = err && err.message ? err.message : String(err);\n submitButton.disabled = false;\n }\n });\n\n toggleJumpButton();\n`;\n\nfunction formatDate(value: string): string {\n const date = new Date(value);\n if (Number.isNaN(date.getTime())) return value;\n return date.toLocaleString();\n}\n\nconst esc = escapeHtml;\n\nconst sessionViewStyles = `\n :root {\n --user-bg: #18181b;\n --user-text: #fafafa;\n --user-time: rgba(250, 250, 250, 0.5);\n\n --asst-border: #22c55e;\n --asst-avatar-bg: #f0fdf4;\n --asst-avatar-text: #16a34a;\n\n --tool-bg: #0d1117;\n --tool-header: #161b22;\n --tool-text: #c9d1d9;\n --tool-accent: #58a6ff;\n --tool-ok: #3fb950;\n --tool-err: #f85149;\n --tool-time: #484f58;\n }\n\n body {\n\n padding-bottom: calc(140px + env(safe-area-inset-bottom, 0px));\n overflow-x: hidden;\n }\n\n\n\n .session-side {\n display: flex; flex-direction: column; align-items: flex-end; gap: 8px;\n flex-shrink: 0;\n }\n .session-badge {\n display: inline-flex; align-items: center; gap: 8px;\n padding: 6px 11px; border: 1px solid var(--border); border-radius: 999px;\n background: rgba(255,255,255,0.7); font-size: 0.78rem; color: var(--muted);\n line-height: 1;\n }\n .session-badge strong { color: var(--text); font-weight: 600; }\n .session-badge-status.is-running {\n background: #fff7ed; border-color: rgba(217, 119, 6, 0.18); color: #9a3412;\n }\n .session-badge-dot {\n width: 7px; height: 7px; border-radius: 50%;\n background: #a1a1aa; flex-shrink: 0;\n }\n .session-badge-status.is-running .session-badge-dot {\n background: #d97706; box-shadow: 0 0 0 4px rgba(217, 119, 6, 0.14);\n }\n\n .session-detail-row {\n display: flex; flex-wrap: wrap; gap: 8px;\n padding: 12px 14px; border: 1px solid var(--border); border-radius: 14px;\n background: rgba(255,255,255,0.6);\n }\n .session-detail {\n display: inline-flex; align-items: center; gap: 8px; min-width: 0;\n padding: 4px 10px; border-radius: 10px; background: rgba(0, 0, 0, 0.025);\n color: var(--muted); font-size: 0.78rem;\n }\n .session-detail-label {\n text-transform: uppercase; letter-spacing: 0.08em;\n font-size: 0.68rem; color: var(--subtle);\n }\n .session-detail code {\n min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;\n font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 0.74rem;\n color: var(--text); padding: 0;\n }\n\n\n\n .thread-links {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 10px;\n }\n\n .thread-link {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n padding: 5px 10px;\n border-radius: 999px;\n border: 1px solid rgba(239, 68, 68, 0.18);\n background: rgba(254, 242, 242, 0.95);\n color: #b91c1c;\n text-decoration: none;\n font-size: 0.74rem;\n font-weight: 600;\n line-height: 1;\n transition: transform 120ms, background 120ms, border-color 120ms;\n }\n\n .thread-link:hover {\n transform: translateY(-1px);\n background: #fff1f2;\n border-color: rgba(239, 68, 68, 0.28);\n }\n\n .thread-dot {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: #ef4444;\n box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.12);\n flex-shrink: 0;\n }\n\n .thread-text {\n white-space: nowrap;\n }\n\n .related-card {\n padding: 18px 20px;\n border: 1px solid var(--border);\n border-radius: 18px;\n background: rgba(255,255,255,0.78);\n box-shadow: 0 1px 2px rgba(0,0,0,0.04), 0 4px 16px rgba(0,0,0,0.04);\n backdrop-filter: blur(12px);\n }\n\n .related-list {\n display: flex;\n flex-direction: column;\n gap: 10px;\n }\n\n .related-link {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n padding: 12px 14px;\n border-radius: 14px;\n border: 1px solid var(--border);\n background: rgba(255,255,255,0.82);\n color: inherit;\n text-decoration: none;\n transition: transform 120ms, border-color 120ms, box-shadow 120ms, background 120ms;\n }\n\n .related-link:hover {\n transform: translateY(-1px);\n border-color: rgba(0,0,0,0.16);\n background: #fff;\n box-shadow: 0 8px 18px rgba(0,0,0,0.05);\n }\n\n .related-copy {\n min-width: 0;\n display: flex;\n flex-direction: column;\n gap: 4px;\n }\n\n .related-title {\n color: var(--text);\n font-size: 0.94rem;\n line-height: 1.3;\n }\n\n .related-summary {\n color: var(--muted);\n font-size: 0.82rem;\n line-height: 1.45;\n }\n\n .related-meta {\n color: var(--subtle);\n font-size: 0.74rem;\n line-height: 1.4;\n }\n\n .related-arrow {\n flex-shrink: 0;\n color: var(--subtle);\n font-size: 1rem;\n }\n\n .timeline-shell {\n padding: 20px 0;\n }\n\n .timeline-list {\n display: flex;\n flex-direction: column;\n gap: 14px;\n min-width: 0;\n }\n\n .copy-host {\n position: relative;\n }\n\n .msg-actions {\n height: 32px;\n display: flex;\n align-items: center;\n gap: 8px;\n margin-top: 8px;\n opacity: 0;\n visibility: hidden;\n transition: opacity 140ms ease, visibility 140ms ease;\n }\n\n .copy-host:hover .msg-actions,\n .copy-host .msg-actions:hover,\n .copy-host:focus-within .msg-actions,\n .timeline-list > .copy-host:last-child .msg-actions,\n .copy-action-btn[data-copy-state] {\n opacity: 1;\n visibility: visible;\n }\n\n .copy-action-btn {\n width: 24px;\n height: 24px;\n display: inline-flex;\n align-items: center;\n justify-content: center;\n border: 0;\n border-radius: 0;\n background: transparent;\n color: rgba(63,63,70,0.8);\n transition: color 140ms ease, opacity 140ms ease;\n cursor: pointer;\n padding: 0;\n appearance: none;\n }\n\n .copy-action-btn:hover {\n background: transparent;\n color: rgba(24,24,27,0.96);\n border-color: transparent;\n }\n\n .copy-action-btn[data-copy-state='done'] {\n background: transparent;\n border-color: transparent;\n color: rgba(24,24,27,0.96);\n }\n\n .copy-action-btn[data-copy-state='done'] svg {\n position: absolute;\n opacity: 0;\n transform: scale(0.6);\n pointer-events: none;\n }\n\n .copy-action-btn svg {\n transition: opacity 140ms ease, transform 140ms ease;\n }\n\n .copy-action-btn[data-copy-state='done']::before {\n content: '';\n width: 14px;\n height: 14px;\n background-color: currentColor;\n -webkit-mask: url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='4 12 10 18 20 6'/></svg>\") center / contain no-repeat;\n mask: url(\"data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='4 12 10 18 20 6'/></svg>\") center / contain no-repeat;\n animation: copy-check-in 200ms ease-out both;\n }\n\n @keyframes copy-check-in {\n from { opacity: 0; transform: scale(0.6); }\n to { opacity: 1; transform: scale(1); }\n }\n\n @media (prefers-reduced-motion: reduce) {\n .copy-action-btn svg,\n .copy-action-btn[data-copy-state='done']::before {\n transition: none;\n animation: none;\n }\n }\n\n .copy-action-btn[data-copy-state='error'] {\n background: transparent;\n border-color: transparent;\n color: #b91c1c;\n }\n\n\n\n .msg-row {\n display: flex;\n align-items: flex-end;\n gap: 8px;\n padding: 4px 0;\n min-width: 0;\n }\n\n\n\n .msg-user {\n justify-content: flex-end;\n }\n\n .msg-main {\n min-width: 0;\n }\n\n .user-main {\n max-width: 85%;\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n }\n\n .user-bubble {\n max-width: 100%;\n min-width: 0;\n padding: 12px 16px;\n border-radius: 18px 18px 4px 18px;\n background: var(--user-bg);\n color: var(--user-text);\n box-shadow: 0 1px 2px rgba(0,0,0,0.12);\n }\n\n .msg-raw-header {\n margin-bottom: 8px;\n color: rgba(250, 250, 250, 0.72);\n font-family: 'JetBrains Mono', ui-monospace, monospace;\n font-size: 0.72rem;\n line-height: 1.5;\n white-space: pre-wrap;\n word-break: break-word;\n }\n\n .thread-badge {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n margin-bottom: 8px;\n padding: 4px 10px;\n border-radius: 999px;\n background: rgba(255,255,255,0.22);\n color: var(--user-text);\n font-size: 0.68rem;\n font-weight: 700;\n letter-spacing: 0.01em;\n }\n\n .thread-badge code {\n font-family: 'JetBrains Mono', ui-monospace, monospace;\n font-size: 0.66rem;\n background: rgba(255,255,255,0.16);\n padding: 1px 6px;\n border-radius: 999px;\n color: inherit;\n }\n\n .msg-user .msg-body {\n color: var(--user-text);\n }\n\n .msg-user .msg-time {\n display: block;\n margin-top: 6px;\n font-size: 0.72rem;\n color: var(--user-time);\n text-align: right;\n }\n\n\n\n .msg-avatar {\n flex: 0 0 28px;\n width: 28px;\n height: 28px;\n border-radius: 50%;\n font-size: 0.68rem;\n font-weight: 700;\n display: flex;\n align-items: center;\n justify-content: center;\n letter-spacing: 0;\n flex-shrink: 0;\n }\n\n .user-avatar {\n background: #eff6ff;\n border: 1.5px solid #93c5fd;\n color: #1d4ed8;\n }\n\n .asst-avatar {\n background: var(--asst-avatar-bg);\n border: 1.5px solid var(--asst-border);\n color: var(--asst-avatar-text);\n margin-bottom: 2px;\n }\n\n\n\n .msg-assistant {\n align-items: flex-end;\n gap: 8px;\n max-width: 85%;\n min-width: 0;\n }\n\n .asst-main {\n max-width: 100%;\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n }\n\n .asst-card {\n min-width: 0;\n max-width: 100%;\n padding: 14px 18px;\n border: 1px solid var(--border);\n border-radius: 18px 18px 18px 4px;\n background: var(--surface);\n box-shadow: 0 1px 3px rgba(0,0,0,0.04);\n }\n\n .msg-assistant .msg-body {\n color: var(--text);\n }\n\n .msg-assistant .msg-time {\n display: block;\n margin-top: 8px;\n font-size: 0.72rem;\n color: var(--subtle);\n }\n\n\n\n .tool-block {\n max-width: 92%;\n margin-left: 36px;\n border-radius: 10px;\n overflow: hidden;\n border: 1px solid rgba(255,255,255,0.06);\n box-shadow: 0 2px 8px rgba(0,0,0,0.16);\n margin: 2px 0;\n }\n\n .tool-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 14px;\n background: var(--tool-header);\n border-bottom: 1px solid rgba(255,255,255,0.06);\n overflow: hidden;\n }\n\n .tool-icon {\n color: var(--tool-accent);\n flex-shrink: 0;\n display: flex;\n align-items: center;\n }\n\n .tool-name {\n flex: 1;\n font-family: 'JetBrains Mono', 'Fira Code', ui-monospace, monospace;\n font-size: 0.75rem;\n font-weight: 500;\n color: var(--tool-accent);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .tool-time {\n flex-shrink: 0;\n font-family: 'JetBrains Mono', ui-monospace, monospace;\n font-size: 0.7rem;\n color: var(--tool-time);\n }\n\n .tool-output {\n display: block;\n padding: 12px 14px;\n background: var(--tool-bg);\n color: var(--tool-text);\n font-family: 'JetBrains Mono', 'Fira Code', ui-monospace, monospace;\n font-size: 0.78rem;\n line-height: 1.6;\n white-space: pre-wrap;\n word-break: break-word;\n overflow-x: auto;\n max-height: 400px;\n overflow-y: auto;\n }\n\n .tool-output.tone-ok { color: var(--tool-ok); }\n .tool-output.tone-err { color: var(--tool-err); }\n\n\n\n .markdown-body {\n font-family: 'DM Sans', system-ui, sans-serif;\n font-size: 0.9rem;\n line-height: 1.65;\n word-break: break-word;\n }\n\n .markdown-body > *:first-child { margin-top: 0; }\n .markdown-body > *:last-child { margin-bottom: 0; }\n .markdown-body p,\n .markdown-body ul,\n .markdown-body ol,\n .markdown-body blockquote,\n .markdown-body pre,\n .markdown-body table,\n .markdown-body hr {\n margin: 0 0 0.85em;\n }\n\n .markdown-body h1,\n .markdown-body h2,\n .markdown-body h3,\n .markdown-body h4,\n .markdown-body h5,\n .markdown-body h6 {\n margin: 0 0 0.55em;\n line-height: 1.25;\n font-weight: 700;\n letter-spacing: -0.01em;\n }\n\n .markdown-body h1 { font-size: 1.4rem; }\n .markdown-body h2 { font-size: 1.22rem; }\n .markdown-body h3 { font-size: 1.08rem; }\n .markdown-body h4,\n .markdown-body h5,\n .markdown-body h6 { font-size: 0.95rem; }\n\n .markdown-body ul,\n .markdown-body ol {\n padding-left: 1.3em;\n }\n\n .markdown-body li + li {\n margin-top: 0.22em;\n }\n\n .markdown-body blockquote {\n padding-left: 12px;\n border-left: 3px solid rgba(34, 197, 94, 0.35);\n opacity: 0.95;\n }\n\n .markdown-body a {\n color: inherit;\n text-decoration: underline;\n text-underline-offset: 2px;\n }\n\n .markdown-body code {\n font-family: 'JetBrains Mono', 'Fira Code', ui-monospace, monospace;\n font-size: 0.82em;\n padding: 0.16em 0.38em;\n border-radius: 6px;\n }\n\n .markdown-body pre {\n overflow-x: auto;\n border-radius: 12px;\n padding: 12px 14px;\n }\n\n .markdown-body pre code {\n display: block;\n padding: 0;\n border-radius: 0;\n background: transparent;\n font-size: 0.82rem;\n line-height: 1.6;\n }\n\n .markdown-body table {\n width: 100%;\n border-collapse: collapse;\n font-size: 0.85rem;\n }\n\n .markdown-body th,\n .markdown-body td {\n padding: 8px 10px;\n border: 1px solid rgba(0, 0, 0, 0.08);\n text-align: left;\n vertical-align: top;\n }\n\n .markdown-body img {\n max-width: 100%;\n border-radius: 12px;\n }\n\n .markdown-user code {\n background: rgba(255,255,255,0.14);\n color: var(--user-text);\n }\n\n .markdown-user pre {\n background: rgba(255,255,255,0.08);\n border: 1px solid rgba(255,255,255,0.08);\n }\n\n .markdown-user table th,\n .markdown-user table td {\n border-color: rgba(255,255,255,0.16);\n }\n\n .markdown-assistant code {\n background: #f4f4f5;\n color: #27272a;\n }\n\n .markdown-assistant pre {\n background: #0f172a;\n color: #e5e7eb;\n }\n\n .markdown-assistant pre code {\n background: transparent;\n color: inherit;\n }\n\n .markdown-assistant table th,\n .markdown-assistant table td {\n border-color: rgba(0, 0, 0, 0.08);\n }\n\n\n\n .system-event {\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n padding: 10px 0;\n color: var(--subtle);\n font-size: 0.775rem;\n }\n\n .event-dot {\n width: 4px;\n height: 4px;\n border-radius: 50%;\n background: var(--subtle);\n flex-shrink: 0;\n opacity: 0.6;\n }\n\n .event-text {\n color: var(--muted);\n }\n\n .system-event-err .event-text {\n color: var(--err-text);\n }\n\n .event-time {\n color: var(--subtle);\n font-style: normal;\n }\n\n\n\n .stack > * + * { margin-top: 14px; }\n\n p { color: var(--muted); font-size: 0.9rem; line-height: 1.5; }\n\n .status {\n padding: 12px 16px;\n border-radius: 10px;\n font-size: 0.9rem;\n }\n\n .status.err {\n background: var(--err-bg);\n color: var(--err-text);\n border: 1px solid rgba(185, 28, 28, 0.12);\n }\n\n\n\n .composer-card {\n position: fixed;\n left: calc(72px + (100vw - 72px) / 2);\n bottom: calc(16px + env(safe-area-inset-bottom, 0px));\n transform: translateX(-50%);\n width: min(960px, calc(100vw - 96px));\n padding: 10px 12px 10px 14px;\n border: 1px solid var(--border);\n border-radius: 22px;\n background: rgba(250, 248, 244, 0.92);\n box-shadow: 0 12px 36px rgba(0,0,0,0.10), 0 2px 6px rgba(0,0,0,0.04);\n backdrop-filter: blur(14px);\n -webkit-backdrop-filter: blur(14px);\n z-index: 20;\n }\n\n .composer-form {\n display: flex;\n flex-direction: column;\n gap: 6px;\n }\n\n .jump-latest-btn {\n position: fixed;\n left: calc(72px + (100vw - 72px) / 2);\n bottom: calc(env(safe-area-inset-bottom, 0px) + 120px);\n z-index: 25;\n width: 42px;\n height: 42px;\n border: 1px solid var(--border);\n border-radius: 999px;\n background: var(--bg);\n color: var(--text);\n font: 700 1rem/1 'DM Sans', sans-serif;\n box-shadow: 0 10px 30px rgba(0,0,0,0.12);\n cursor: pointer;\n backdrop-filter: blur(10px);\n transform: translateX(-50%);\n outline: none;\n appearance: none;\n -webkit-tap-highlight-color: transparent;\n }\n\n .jump-latest-btn:hover {\n transform: translateX(-50%) translateY(-1px);\n background: #e8e3d9;\n }\n\n .jump-latest-btn:focus,\n .jump-latest-btn:active {\n outline: none;\n }\n\n .jump-latest-btn:focus-visible {\n box-shadow: 0 10px 30px rgba(0,0,0,0.12), 0 0 0 3px rgba(0,0,0,0.08);\n }\n\n .composer-copy { margin-bottom: 12px; color: var(--muted); }\n\n .composer-form textarea {\n width: 100%;\n resize: none;\n overflow-y: auto;\n min-height: 28px;\n max-height: 200px;\n padding: 6px 6px 2px;\n border: 0;\n border-radius: 0;\n font: inherit;\n color: var(--text);\n background: transparent;\n }\n\n .composer-form textarea::placeholder {\n color: rgba(63,63,70,0.55);\n }\n\n .composer-form textarea:focus {\n outline: none;\n border: 0;\n }\n\n .composer-actions {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n margin-top: 0;\n }\n\n .composer-status { color: var(--muted); font-size: 13px; }\n .composer-actions button:disabled { opacity: 0.55; cursor: wait; }\n\n .composer-send-btn {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: 32px;\n height: 32px;\n border: none;\n border-radius: 999px;\n background: #d97706;\n color: #ffffff;\n font: 700 1rem/1 'DM Sans', sans-serif;\n cursor: pointer;\n box-shadow: 0 10px 24px rgba(217, 119, 6, 0.26);\n transition: transform 120ms, filter 120ms, box-shadow 120ms, background 120ms;\n }\n\n .composer-send-btn:hover:not(:disabled) {\n transform: translateY(-1px);\n filter: saturate(1.06) brightness(0.98);\n box-shadow: 0 12px 28px rgba(217, 119, 6, 0.32);\n }\n\n .composer-send-btn:focus-visible {\n outline: 2px solid rgba(217, 119, 6, 0.28);\n outline-offset: 3px;\n }\n\n .composer-send-btn:disabled {\n background: #d4d4d8;\n color: rgba(24, 24, 27, 0.45);\n box-shadow: none;\n transform: none;\n filter: none;\n cursor: not-allowed;\n opacity: 1;\n }\n\n\n\n @media (max-width: 900px) {\n .composer-card {\n left: 50%;\n width: min(960px, calc(100vw - 24px));\n }\n .jump-latest-btn { left: 50%; }\n }\n\n @media (max-width: 600px) {\n body { padding-bottom: calc(130px + env(safe-area-inset-bottom, 0px)); }\n\n .composer-card {\n width: calc(100vw - 16px);\n bottom: calc(8px + env(safe-area-inset-bottom, 0px));\n padding: 8px 10px;\n border-radius: 18px;\n }\n\n .session-side { align-items: flex-start; flex-direction: row; }\n\n .user-bubble,\n .msg-assistant,\n .tool-block { max-width: 100%; }\n\n .asst-avatar { display: none; }\n\n .asst-card { border-radius: 4px 14px 14px 14px; }\n }\n`;\n\nfunction entryIsoTime(entry: SessionEntry | undefined): string | undefined {\n if (!entry || typeof entry.timestamp !== \"number\" || !Number.isFinite(entry.timestamp)) {\n return undefined;\n }\n return new Date(entry.timestamp).toISOString();\n}\n\nexport function resolveExistingSessionFile(\n conversationDir: string,\n sessionKey: string,\n): string | null {\n if (isThreadSessionKey(sessionKey)) {\n return tryResolveThreadSession(getThreadSessionFile(conversationDir, sessionKey));\n }\n return resolveChannelSessionFile(conversationDir);\n}\n\nexport async function loadSessionViewModel(sessionFile: string): Promise<SessionViewModel> {\n const resolvedFile = resolve(sessionFile);\n const sm = await SessionStore.inspect(resolvedFile);\n const header = sm.getHeader();\n\n const entries = await sm.getEntries();\n const updatedAt = entryIsoTime(entries.at(-1)) ?? header.timestamp;\n const title = (await sm.getSessionName()) || `Session ${header.id.slice(0, 8)}`;\n\n const parent = await resolveParentRelation(resolvedFile, header);\n const threadCandidates: SessionViewRelation[] = [];\n for (const candidate of listRelatedSessionFiles(resolvedFile)) {\n if (candidate === resolvedFile) continue;\n const relation = await buildSessionRelation(\n candidate,\n \"thread\",\n resolvedFile,\n header.id,\n entries,\n );\n if (relation) threadCandidates.push(relation);\n }\n const threads = threadCandidates.toSorted((a, b) =>\n a.updatedAt < b.updatedAt ? -1 : a.updatedAt > b.updatedAt ? 1 : 0,\n );\n\n const threadsByEntryId = new Map<string, SessionViewRelation[]>();\n for (const thread of threads) {\n if (!thread.anchorEntryId) continue;\n const bucket = threadsByEntryId.get(thread.anchorEntryId) ?? [];\n bucket.push(thread);\n threadsByEntryId.set(thread.anchorEntryId, bucket);\n }\n\n const items = entries.flatMap((entry) => {\n const item = mapEntryToItem(entry);\n if (!item) return [];\n if (item.entryId) {\n const anchoredThreads = threadsByEntryId.get(item.entryId);\n if (anchoredThreads) {\n item.threads = anchoredThreads;\n }\n }\n return [item];\n });\n\n return {\n sessionId: header.id,\n fileName: basename(resolvedFile),\n title,\n createdAt: header.timestamp,\n updatedAt,\n entryCount: entries.length,\n items,\n parent: parent ?? undefined,\n threads,\n };\n}\n\nasync function resolveRequestedSessionFile(\n baseSessionFile: string,\n requestedFileName?: string | null,\n): Promise<string | null> {\n const resolvedBase = resolve(baseSessionFile);\n if (!requestedFileName) return resolvedBase;\n\n const trimmed = requestedFileName.trim();\n if (!trimmed) return resolvedBase;\n\n const fileName = basename(trimmed);\n if (fileName !== trimmed || !fileName.endsWith(\".jsonl\")) return null;\n\n const candidate = join(dirname(resolvedBase), fileName);\n if (!existsSync(candidate)) return null;\n\n try {\n if (!SessionStore.readHeader(candidate)) throw new Error(\"Invalid session header\");\n } catch (err) {\n throw new Error(\n `Session file is corrupted: ${candidate}: ${\n err instanceof Error ? err.message : String(err)\n }`,\n { cause: err },\n );\n }\n return candidate;\n}\n\nfunction listRelatedSessionFiles(sessionFile: string): string[] {\n const dir = dirname(sessionFile);\n if (!existsSync(dir)) return [];\n\n return readdirSync(dir)\n .filter((name) => name.endsWith(\".jsonl\"))\n .map((fileName) => join(dir, fileName));\n}\n\nasync function buildSessionRelation(\n sessionFile: string,\n kind: \"parent\" | \"thread\",\n expectedParent?: string,\n expectedParentId?: string,\n expectedParentEntries?: SessionEntry[],\n): Promise<SessionViewRelation | null> {\n let sm: Awaited<ReturnType<typeof SessionStore.inspect>>;\n try {\n sm = await SessionStore.inspect(sessionFile);\n } catch (err) {\n log.logWarning(\n `Skipping corrupted session file while building ${kind} relation: ${sessionFile}`,\n err instanceof Error ? err.message : String(err),\n );\n return null;\n }\n const header = sm.getHeader();\n if (\n kind === \"thread\" &&\n !isChildThreadSession(\n sessionFile,\n header.parentSession,\n expectedParent,\n expectedParentId,\n header.parentSessionId,\n )\n ) {\n return null;\n }\n\n const entries = await sm.getEntries();\n const updatedAt = entryIsoTime(entries.at(-1)) ?? header.timestamp;\n const threadId = kind === \"thread\" ? getFixedThreadSessionId(sessionFile) : null;\n const anchorEntryId =\n kind === \"thread\" && expectedParent\n ? findThreadAnchorEntryId(\n expectedParentEntries ??\n (await (await SessionStore.inspect(expectedParent)).getEntries()),\n entries,\n threadId,\n )\n : undefined;\n return {\n kind,\n fileName: basename(sessionFile),\n sessionId: header.id,\n title: (await sm.getSessionName()) || `Session ${header.id.slice(0, 8)}`,\n updatedAt,\n entryCount: entries.length,\n summary: extractSessionSummary(entries),\n anchorEntryId,\n };\n}\n\nasync function resolveParentRelation(\n sessionFile: string,\n header: SessionHeader,\n): Promise<SessionViewRelation | undefined> {\n if (header.parentSession) {\n const parentPath = resolve(header.parentSession);\n if (existsSync(parentPath)) {\n return (await buildSessionRelation(parentPath, \"parent\")) ?? undefined;\n }\n if (header.parentSessionId) {\n const found = findSessionFileById(dirname(sessionFile), header.parentSessionId);\n if (found) return (await buildSessionRelation(found, \"parent\")) ?? undefined;\n }\n }\n return buildInferredThreadParentRelation(sessionFile);\n}\n\nfunction findSessionFileById(sessionDir: string, targetId: string): string | null {\n if (!existsSync(sessionDir)) return null;\n for (const name of readdirSync(sessionDir)) {\n if (!name.endsWith(\".jsonl\")) continue;\n try {\n const filePath = join(sessionDir, name);\n if (SessionStore.readHeader(filePath)?.id === targetId) return filePath;\n } catch {\n continue;\n }\n }\n return null;\n}\n\nasync function buildInferredThreadParentRelation(\n sessionFile: string,\n): Promise<SessionViewRelation | undefined> {\n if (!getFixedThreadSessionId(sessionFile)) return undefined;\n\n const parentSession = resolveChannelSessionFile(dirname(dirname(sessionFile)));\n if (!parentSession || parentSession === sessionFile) return undefined;\n\n return (await buildSessionRelation(parentSession, \"parent\")) ?? undefined;\n}\n\nfunction isChildThreadSession(\n sessionFile: string,\n parentSession: string | undefined,\n expectedParent: string | undefined,\n expectedParentId?: string,\n threadParentSessionId?: string,\n): boolean {\n if (!expectedParent) return false;\n\n if (parentSession) {\n const resolvedParent = resolve(parentSession);\n if (\n resolvedParent === expectedParent ||\n (isPlatformHistorySession(expectedParent) && isPlatformHistorySession(resolvedParent))\n ) {\n return true;\n }\n if (expectedParentId && threadParentSessionId) {\n return threadParentSessionId === expectedParentId;\n }\n return false;\n }\n\n if (!getFixedThreadSessionId(sessionFile)) return false;\n return resolveChannelSessionFile(dirname(dirname(sessionFile))) === expectedParent;\n}\n\nfunction getFixedThreadSessionId(sessionFile: string): string | null {\n const fileName = basename(sessionFile);\n if (!fileName.endsWith(\".jsonl\")) return null;\n if (/^\\d{4}-\\d{2}-\\d{2}T.+_[0-9a-f]{8}\\.jsonl$/i.test(fileName)) return null;\n return fileName.slice(0, -\".jsonl\".length);\n}\n\nfunction findThreadAnchorEntryId(\n parentEntries: SessionEntry[],\n childEntries: SessionEntry[],\n threadId: string | null,\n): string | undefined {\n const threadTimestamp = threadId ? Number(threadId) * 1000 : undefined;\n if (threadTimestamp !== undefined && Number.isFinite(threadTimestamp)) {\n const timestampAnchor = findEntryIdByMessageTimestamp(parentEntries, threadTimestamp);\n if (timestampAnchor) return timestampAnchor;\n }\n let sharedCount = 0;\n while (\n sharedCount < parentEntries.length &&\n sharedCount < childEntries.length &&\n parentEntries[sharedCount]?.id === childEntries[sharedCount]?.id\n ) {\n sharedCount += 1;\n }\n\n if (sharedCount > 0) {\n return parentEntries[sharedCount - 1]?.id;\n }\n\n const contentAnchor = findSharedContentAnchorEntryId(parentEntries, childEntries);\n if (contentAnchor) return contentAnchor;\n\n const childRoot = findComparableUserMessage(childEntries);\n if (!childRoot) return undefined;\n\n return findParentAnchorByRootMessage(parentEntries, childRoot);\n}\n\nfunction findEntryIdByMessageTimestamp(\n entries: SessionEntry[],\n timestamp: number,\n): string | undefined {\n for (const entry of entries) {\n if (entry.type !== \"message\") continue;\n const messageTimestamp = (entry.message as { timestamp?: unknown }).timestamp;\n if (messageTimestamp === timestamp) return entry.id;\n }\n return undefined;\n}\n\nfunction findSharedContentAnchorEntryId(\n parentEntries: SessionEntry[],\n childEntries: SessionEntry[],\n): string | undefined {\n const parentMessages = parentEntries.flatMap((entry) => {\n const comparable = getComparableSessionMessage(entry);\n return comparable ? [comparable] : [];\n });\n const childMessages = childEntries.flatMap((entry) => {\n const comparable = getComparableSessionMessage(entry);\n return comparable ? [comparable] : [];\n });\n if (parentMessages.length === 0 || childMessages.length === 0) return undefined;\n\n let bestParentEnd = -1;\n let bestLength = 0;\n for (let parentStart = 0; parentStart < parentMessages.length; parentStart++) {\n let length = 0;\n while (parentStart + length < parentMessages.length && length < childMessages.length) {\n const parentMessage = parentMessages[parentStart + length];\n const childMessage = childMessages[length];\n if (\n parentMessage === undefined ||\n childMessage === undefined ||\n parentMessage.role !== childMessage.role ||\n parentMessage.normalizedText !== childMessage.normalizedText\n ) {\n break;\n }\n length += 1;\n }\n if (length > bestLength) {\n bestLength = length;\n bestParentEnd = parentStart + length - 1;\n }\n }\n\n return bestLength > 0 ? parentMessages[bestParentEnd]?.entryId : undefined;\n}\n\ninterface ComparableSessionMessage {\n entryId: string;\n role: \"user\" | \"assistant\";\n normalizedText: string;\n}\n\nfunction getComparableSessionMessage(entry: SessionEntry): ComparableSessionMessage | null {\n if (entry.type !== \"message\") return null;\n const role = entry.message.role;\n if (role !== \"user\" && role !== \"assistant\") return null;\n\n const body = contentToText(entry.message.content);\n const normalizedText = normalizeComparableSessionText(body, role);\n if (!normalizedText) return null;\n\n return { entryId: entry.id, role, normalizedText };\n}\n\nfunction normalizeComparableSessionText(text: string, role: \"user\" | \"assistant\"): string {\n const normalized = role === \"user\" ? normalizeComparableUserText(text) : text.trim();\n return normalized.replace(/\\s+/g, \" \").trim();\n}\n\nfunction findParentAnchorByRootMessage(\n parentEntries: SessionEntry[],\n childRoot: ComparableUserMessage,\n): string | undefined {\n let textMatchId: string | undefined;\n\n for (const entry of parentEntries) {\n const comparable = getComparableUserMessage(entry);\n if (!comparable) continue;\n if (comparable.normalizedText !== childRoot.normalizedText) continue;\n if (\n childRoot.messageTimestamp !== undefined &&\n comparable.messageTimestamp !== undefined &&\n comparable.messageTimestamp === childRoot.messageTimestamp\n ) {\n return entry.id;\n }\n textMatchId ??= entry.id;\n }\n\n return textMatchId;\n}\n\ninterface ComparableUserMessage {\n normalizedText: string;\n messageTimestamp?: number;\n}\n\nfunction findComparableUserMessage(entries: SessionEntry[]): ComparableUserMessage | null {\n for (const entry of entries) {\n const comparable = getComparableUserMessage(entry);\n if (comparable) return comparable;\n }\n return null;\n}\n\nfunction getComparableUserMessage(entry: SessionEntry): ComparableUserMessage | null {\n if (entry.type !== \"message\" || entry.message.role !== \"user\") return null;\n\n const body = contentToText(entry.message.content);\n const normalizedText = normalizeComparableUserText(body);\n if (!normalizedText) return null;\n\n const messageTimestamp =\n typeof entry.message.timestamp === \"number\" ? entry.message.timestamp : undefined;\n return { normalizedText, messageTimestamp };\n}\n\nfunction normalizeComparableUserText(text: string): string {\n const withoutTimestamp = text.replace(\n /^\\[[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}[+-][0-9]{2}:[0-9]{2}\\]\\s+(?=\\[[^\\]]+\\](?:\\s+\\[in-thread:[^\\]]+\\])?:\\s)/,\n \"\",\n );\n return withoutTimestamp\n .replace(/\\n*<slack_attachments>\\n[\\s\\S]*?\\n<\\/slack_attachments>\\s*$/g, \"\")\n .trim();\n}\n\nfunction extractSessionSummary(entries: SessionEntry[]): string | undefined {\n for (const entry of entries) {\n if (entry.type !== \"message\") continue;\n const item = mapEntryToItem(entry);\n if (!item?.body) continue;\n return collapseSummary(item.body);\n }\n return undefined;\n}\n\nfunction collapseSummary(text: string): string {\n const singleLine = text.replace(/\\s+/g, \" \").trim();\n return singleLine.length > 96 ? `${singleLine.slice(0, 93)}…` : singleLine;\n}\n\nfunction mapEntryToItem(entry: SessionEntry): SessionViewItem | null {\n switch (entry.type) {\n case \"message\":\n return mapMessageEntry(entry);\n case \"compaction\":\n return mapCompactionEntry(entry);\n case \"branch_summary\":\n return mapSessionSummaryEntry(entry);\n case \"custom\":\n return {\n kind: \"system\",\n title: `Custom data · ${entry.customType}`,\n body: entry.data === undefined ? \"(no data)\" : JSON.stringify(entry.data, null, 2),\n meta: entryIsoTime(entry) ?? \"\",\n tone: \"muted\",\n };\n default:\n return null;\n }\n}\n\ninterface SessionMessagePayload extends Record<string, unknown> {\n role?: string;\n content?: unknown;\n provider?: string;\n model?: string;\n toolName?: string;\n isError?: boolean;\n command?: string;\n output?: string;\n exitCode?: number;\n cancelled?: boolean;\n truncated?: boolean;\n stopReason?: string;\n errorMessage?: string;\n customType?: string;\n summary?: string;\n}\n\nfunction mapMessageEntry(entry: SessionMessageEntry): SessionViewItem {\n const message = entry.message as unknown as SessionMessagePayload;\n\n switch (message.role) {\n case \"user\":\n return {\n kind: \"user\",\n title: \"User\",\n body: contentToText(message.content),\n meta: entryIsoTime(entry) ?? \"\",\n entryId: entry.id,\n };\n case \"assistant\": {\n const assistantBody =\n contentToText(message.content) || (message.errorMessage ? `_${message.errorMessage}_` : \"\");\n const metaParts = [message.provider, message.model, message.stopReason].filter(Boolean);\n return {\n kind: \"assistant\",\n title: \"Assistant\",\n body: assistantBody,\n meta:\n metaParts.length > 0\n ? `${entryIsoTime(entry) ?? \"\"} · ${metaParts.join(\" · \")}`\n : (entryIsoTime(entry) ?? \"\"),\n entryId: entry.id,\n };\n }\n case \"toolResult\":\n return {\n kind: \"tool\",\n title: `Tool result · ${String(message.toolName ?? \"unknown\")}`,\n body: contentToText(message.content),\n meta: entryIsoTime(entry) ?? \"\",\n tone: message.isError ? \"err\" : \"ok\",\n entryId: entry.id,\n };\n case \"bashExecution\": {\n const command = String(message.command ?? \"\").trim();\n const output = String(message.output ?? \"\").trim();\n const details = [\n typeof message.exitCode === \"number\" ? `[exitCode] ${message.exitCode}` : \"\",\n message.cancelled ? `[cancelled] true` : \"\",\n message.truncated ? `[truncated] true` : \"\",\n ].filter(Boolean);\n const body = [command ? `$ ${command}` : \"\", output, ...details].filter(Boolean).join(\"\\n\\n\");\n return {\n kind: \"tool\",\n title: \"Bash execution\",\n body: body || \"(no output)\",\n meta: entryIsoTime(entry) ?? \"\",\n entryId: entry.id,\n };\n }\n case \"custom\":\n return {\n kind: \"system\",\n title: `Custom message · ${String(message.customType ?? \"custom\")}`,\n body: contentToText(message.content),\n meta: entryIsoTime(entry) ?? \"\",\n tone: \"muted\",\n entryId: entry.id,\n };\n case \"branchSummary\":\n return {\n kind: \"system\",\n title: \"Session summary\",\n body: String(message.summary ?? \"\"),\n meta: entryIsoTime(entry) ?? \"\",\n tone: \"muted\",\n entryId: entry.id,\n };\n case \"compactionSummary\":\n return {\n kind: \"system\",\n title: \"Compaction summary\",\n body: String(message.summary ?? \"\"),\n meta: entryIsoTime(entry) ?? \"\",\n tone: \"muted\",\n entryId: entry.id,\n };\n default:\n return {\n kind: \"system\",\n title: `Message · ${String(message.role ?? \"unknown\")}`,\n body: contentToText(message.content),\n meta: entryIsoTime(entry) ?? \"\",\n tone: \"muted\",\n entryId: entry.id,\n };\n }\n}\n\nfunction mapCompactionEntry(entry: CompactionEntry): SessionViewItem {\n return {\n kind: \"system\",\n title: \"Context compacted\",\n body: entry.summary,\n meta: `${entryIsoTime(entry) ?? \"\"} · ${entry.tokensBefore} tokens before compaction`,\n tone: \"muted\",\n };\n}\n\nfunction mapSessionSummaryEntry(entry: SessionBranchSummaryEntry): SessionViewItem {\n return {\n kind: \"system\",\n title: \"Session summary\",\n body: entry.summary,\n meta: entryIsoTime(entry) ?? \"\",\n tone: \"muted\",\n };\n}\n\nfunction contentToText(content: unknown): string {\n if (typeof content === \"string\") return content;\n if (!Array.isArray(content)) return \"\";\n\n const lines: string[] = [];\n for (const block of content) {\n if (!block || typeof block !== \"object\") continue;\n const value = block as Record<string, unknown>;\n if (value.type === \"text\" && typeof value.text === \"string\") {\n lines.push(value.text);\n continue;\n }\n if (value.type === \"thinking\" && typeof value.thinking === \"string\") {\n lines.push(`[thinking]\\n${value.thinking}`);\n continue;\n }\n if (value.type === \"toolCall\") {\n const name = typeof value.name === \"string\" ? value.name : \"tool\";\n const args = value.arguments === undefined ? \"\" : JSON.stringify(value.arguments, null, 2);\n lines.push([`[toolCall] ${name}`, args].filter(Boolean).join(\"\\n\"));\n continue;\n }\n if (value.type === \"image\") {\n lines.push(`[image ${String(value.mimeType ?? \"unknown\")}]`);\n }\n }\n\n return lines.join(\"\\n\\n\");\n}\n"]}
|