sea-dev 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (784) hide show
  1. package/.claude/tasks/README.md +89 -0
  2. package/.cursor/rules/commits.mdc +31 -0
  3. package/.cursor/rules/general.mdc +84 -0
  4. package/.github/workflows/ci-cd.yml +141 -0
  5. package/CLAUDE.md +337 -0
  6. package/README.md +129 -0
  7. package/apps/api/.prettierignore +6 -0
  8. package/apps/api/.prettierrc.js +3 -0
  9. package/apps/api/dotenvx-safe.sh +11 -0
  10. package/apps/api/eslint.config.mjs +3 -0
  11. package/apps/api/package.json +58 -0
  12. package/apps/api/src/clients/posthog.ts +25 -0
  13. package/apps/api/src/dal/submission.ts +59 -0
  14. package/apps/api/src/errors.ts +55 -0
  15. package/apps/api/src/index.ts +21 -0
  16. package/apps/api/src/lib/channel.ts +28 -0
  17. package/apps/api/src/lib/config.ts +9 -0
  18. package/apps/api/src/lib/fmt.test.ts +9 -0
  19. package/apps/api/src/lib/fmt.ts +62 -0
  20. package/apps/api/src/lib/invariant.ts +23 -0
  21. package/apps/api/src/middleware/auth.ts +66 -0
  22. package/apps/api/src/routes/index.ts +20 -0
  23. package/apps/api/src/routes/v2/chat/handlers.ts +693 -0
  24. package/apps/api/src/routes/v2/chat/index.ts +257 -0
  25. package/apps/api/src/routes/v2/chat/schemas.ts +43 -0
  26. package/apps/api/src/routes/v2/deals/handlers.ts +64 -0
  27. package/apps/api/src/routes/v2/deals/index.ts +88 -0
  28. package/apps/api/src/routes/v2/deals/schemas.ts +38 -0
  29. package/apps/api/src/routes/v2/forms/handlers.ts +415 -0
  30. package/apps/api/src/routes/v2/forms/index.ts +382 -0
  31. package/apps/api/src/routes/v2/forms/schemas.ts +243 -0
  32. package/apps/api/src/routes/v2/index.ts +19 -0
  33. package/apps/api/src/routes/v2/pipelines/handlers.ts +261 -0
  34. package/apps/api/src/routes/v2/pipelines/index.ts +224 -0
  35. package/apps/api/src/routes/v2/pipelines/schemas.ts +173 -0
  36. package/apps/api/src/routes/v2/submissions/handlers.ts +555 -0
  37. package/apps/api/src/routes/v2/submissions/index.ts +366 -0
  38. package/apps/api/src/routes/v2/submissions/schemas.ts +233 -0
  39. package/apps/api/src/routes/v2/workflows/handlers.ts +81 -0
  40. package/apps/api/src/routes/v2/workflows/index.ts +88 -0
  41. package/apps/api/src/routes/v2/workflows/schemas.ts +40 -0
  42. package/apps/api/src/server.ts +146 -0
  43. package/apps/api/src/static/favicon.ico +0 -0
  44. package/apps/api/src/types/api.ts +14 -0
  45. package/apps/api/src/types/result.ts +3 -0
  46. package/apps/api/tsconfig.json +22 -0
  47. package/apps/api/vite.config.ts +28 -0
  48. package/apps/api/vitest.config.ts +14 -0
  49. package/apps/conversion-worker/Dockerfile +59 -0
  50. package/apps/conversion-worker/package.json +31 -0
  51. package/apps/conversion-worker/src/lib/config.ts +7 -0
  52. package/apps/conversion-worker/src/main.ts +22 -0
  53. package/apps/conversion-worker/src/workflows/convert-pptx.ts +116 -0
  54. package/apps/conversion-worker/tsconfig.json +27 -0
  55. package/apps/conversion-worker/vite.config.ts +33 -0
  56. package/apps/main/.prettierignore +6 -0
  57. package/apps/main/.prettierrc.js +3 -0
  58. package/apps/main/CLAUDE.md +245 -0
  59. package/apps/main/Procfile +1 -0
  60. package/apps/main/README.md +193 -0
  61. package/apps/main/db-tests.jsonl +116 -0
  62. package/apps/main/dotenvx-safe.sh +11 -0
  63. package/apps/main/drizzle/meta/_journal.json +1 -0
  64. package/apps/main/drizzle.config.ts +25 -0
  65. package/apps/main/eslint.config.mjs +3 -0
  66. package/apps/main/generate-routes.mjs +5 -0
  67. package/apps/main/package.json +131 -0
  68. package/apps/main/playwright.config.ts +23 -0
  69. package/apps/main/postcss.config.ts +5 -0
  70. package/apps/main/public/bg-dark.svg +10 -0
  71. package/apps/main/public/bg.svg +10 -0
  72. package/apps/main/public/favicon.ico +0 -0
  73. package/apps/main/run.sh +146 -0
  74. package/apps/main/scripts/browser.ts +14 -0
  75. package/apps/main/scripts/db-test-cov.ts +277 -0
  76. package/apps/main/scripts/login.ts +78 -0
  77. package/apps/main/scripts/repl.ts +61 -0
  78. package/apps/main/src/_foo.ts +31 -0
  79. package/apps/main/src/_tests/db.test.ts +19 -0
  80. package/apps/main/src/_tests/mock-db.ts +60 -0
  81. package/apps/main/src/client.tsx +13 -0
  82. package/apps/main/src/clients/loops.ts +13 -0
  83. package/apps/main/src/clients/polar.ts +12 -0
  84. package/apps/main/src/clients/posthog.ts +12 -0
  85. package/apps/main/src/components/chat/chat-context.tsx +99 -0
  86. package/apps/main/src/components/chat/chat-messages.tsx +184 -0
  87. package/apps/main/src/components/chat/chat-status.tsx +140 -0
  88. package/apps/main/src/components/chat/chat.tsx +458 -0
  89. package/apps/main/src/components/chat/citation-modal.tsx +54 -0
  90. package/apps/main/src/components/cta.tsx +21 -0
  91. package/apps/main/src/components/data-display/derived.tsx +40 -0
  92. package/apps/main/src/components/data-display/group-single.tsx +57 -0
  93. package/apps/main/src/components/data-display/group-table.tsx +165 -0
  94. package/apps/main/src/components/data-display/group-wrapper.tsx +54 -0
  95. package/apps/main/src/components/data-display/item.tsx +678 -0
  96. package/apps/main/src/components/error.tsx +45 -0
  97. package/apps/main/src/components/forms/error.tsx +22 -0
  98. package/apps/main/src/components/grid.tsx +7 -0
  99. package/apps/main/src/components/header/container.tsx +73 -0
  100. package/apps/main/src/components/header/header-bar.tsx +102 -0
  101. package/apps/main/src/components/modals/copy-display.tsx +37 -0
  102. package/apps/main/src/components/modals/copy-form.tsx +152 -0
  103. package/apps/main/src/components/modals/duplicate-workflow.tsx +89 -0
  104. package/apps/main/src/components/modals/field-correction.tsx +323 -0
  105. package/apps/main/src/components/modals/form-viewer.tsx +126 -0
  106. package/apps/main/src/components/modals/modals.tsx +44 -0
  107. package/apps/main/src/components/modals/new-deal.tsx +78 -0
  108. package/apps/main/src/components/modals/new-form.tsx +133 -0
  109. package/apps/main/src/components/modals/new-pipeline.tsx +70 -0
  110. package/apps/main/src/components/modals/new-submission.tsx +321 -0
  111. package/apps/main/src/components/modals/new-workflow.tsx +342 -0
  112. package/apps/main/src/components/modals/transformation-sources-modal.tsx +157 -0
  113. package/apps/main/src/components/modals/view-report.tsx +193 -0
  114. package/apps/main/src/components/not-found.tsx +14 -0
  115. package/apps/main/src/components/search/search-bar.tsx +178 -0
  116. package/apps/main/src/components/sheet-selector.tsx +135 -0
  117. package/apps/main/src/components/side-panel/doc-list.tsx +480 -0
  118. package/apps/main/src/components/sidebar/admin-sidebar.tsx +75 -0
  119. package/apps/main/src/components/sidebar/app-sidebar.tsx +417 -0
  120. package/apps/main/src/components/sidebar/model-select.tsx +134 -0
  121. package/apps/main/src/components/sidebar/settings-sidebar.tsx +132 -0
  122. package/apps/main/src/components/sidebar/sidebar-right.tsx +22 -0
  123. package/apps/main/src/components/sidebar/stop-impersonate.tsx +21 -0
  124. package/apps/main/src/components/svg/loading.tsx +33 -0
  125. package/apps/main/src/components/theme-selector.tsx +43 -0
  126. package/apps/main/src/components/unsaved-badge.tsx +19 -0
  127. package/apps/main/src/components/upload/file-upload.tsx +354 -0
  128. package/apps/main/src/fns/submission-groups.ts +28 -0
  129. package/apps/main/src/fns/submission-items.ts +11 -0
  130. package/apps/main/src/global-middleware.ts +16 -0
  131. package/apps/main/src/hooks/use-update-state.ts +18 -0
  132. package/apps/main/src/lib/auth-client.ts +16 -0
  133. package/apps/main/src/lib/auth.test.ts +359 -0
  134. package/apps/main/src/lib/auth.ts +144 -0
  135. package/apps/main/src/lib/billing.ts +23 -0
  136. package/apps/main/src/lib/config-iso.ts +76 -0
  137. package/apps/main/src/lib/config.ts +61 -0
  138. package/apps/main/src/lib/excel.ts +16 -0
  139. package/apps/main/src/lib/feedback-cache.ts +70 -0
  140. package/apps/main/src/lib/logger.ts +44 -0
  141. package/apps/main/src/lib/models.ts +22 -0
  142. package/apps/main/src/lib/not-found.ts +17 -0
  143. package/apps/main/src/lib/pdf.ts +16 -0
  144. package/apps/main/src/lib/tabularize.ts +54 -0
  145. package/apps/main/src/lib/utils.ts +10 -0
  146. package/apps/main/src/lib/zfd.ts +217 -0
  147. package/apps/main/src/middleware.ts +55 -0
  148. package/apps/main/src/routeTree.gen.ts +1255 -0
  149. package/apps/main/src/router.tsx +24 -0
  150. package/apps/main/src/routes/__root.tsx +92 -0
  151. package/apps/main/src/routes/_authed/_app/(dashboard)/index.tsx +227 -0
  152. package/apps/main/src/routes/_authed/_app/agents/$agentId/config.tsx +224 -0
  153. package/apps/main/src/routes/_authed/_app/agents/$agentId/index.tsx +206 -0
  154. package/apps/main/src/routes/_authed/_app/agents/-components/agent-actions-menu.tsx +94 -0
  155. package/apps/main/src/routes/_authed/_app/agents/-components/agent-artifacts.tsx +153 -0
  156. package/apps/main/src/routes/_authed/_app/agents/-components/agent-chat.tsx +220 -0
  157. package/apps/main/src/routes/_authed/_app/agents/-components/agent-history-menu.tsx +81 -0
  158. package/apps/main/src/routes/_authed/_app/agents/-components/agent-model-select.tsx +84 -0
  159. package/apps/main/src/routes/_authed/_app/agents/-components/agent-relevant-items.tsx +226 -0
  160. package/apps/main/src/routes/_authed/_app/agents/-components/agent-upload-button.tsx +298 -0
  161. package/apps/main/src/routes/_authed/_app/agents/-components/context-modal.tsx +187 -0
  162. package/apps/main/src/routes/_authed/_app/agents/-fns.ts +560 -0
  163. package/apps/main/src/routes/_authed/_app/agents/index.tsx +65 -0
  164. package/apps/main/src/routes/_authed/_app/deals/$dealId/$subId/-components/citation-tree.tsx +268 -0
  165. package/apps/main/src/routes/_authed/_app/deals/$dealId/$subId.tsx +655 -0
  166. package/apps/main/src/routes/_authed/_app/deals/$dealId/-components/doc-loading.tsx +37 -0
  167. package/apps/main/src/routes/_authed/_app/deals/$dealId/-components/share-link.tsx +42 -0
  168. package/apps/main/src/routes/_authed/_app/deals/$dealId/-components/submission-card.tsx +89 -0
  169. package/apps/main/src/routes/_authed/_app/deals/$dealId/-components/submission-filter.tsx +193 -0
  170. package/apps/main/src/routes/_authed/_app/deals/$dealId/-components/submissions.tsx +36 -0
  171. package/apps/main/src/routes/_authed/_app/deals/$dealId/-components/summary.tsx +82 -0
  172. package/apps/main/src/routes/_authed/_app/deals/$dealId/-components/upload-doc.tsx +120 -0
  173. package/apps/main/src/routes/_authed/_app/deals/$dealId/-fns.ts +653 -0
  174. package/apps/main/src/routes/_authed/_app/deals/$dealId/index.tsx +259 -0
  175. package/apps/main/src/routes/_authed/_app/deals/$dealId/route.tsx +29 -0
  176. package/apps/main/src/routes/_authed/_app/deals/index.tsx +104 -0
  177. package/apps/main/src/routes/_authed/_app/feedback/index.tsx +639 -0
  178. package/apps/main/src/routes/_authed/_app/feedback/insights.tsx +250 -0
  179. package/apps/main/src/routes/_authed/_app/pipelines/$pipelineId/$runId/-components/blockers-panel.tsx +260 -0
  180. package/apps/main/src/routes/_authed/_app/pipelines/$pipelineId/$runId/-components/manual-input-panel.tsx +301 -0
  181. package/apps/main/src/routes/_authed/_app/pipelines/$pipelineId/$runId/-components/submission-selector-modal.tsx +143 -0
  182. package/apps/main/src/routes/_authed/_app/pipelines/$pipelineId/$runId/-components/upload-doc.tsx +120 -0
  183. package/apps/main/src/routes/_authed/_app/pipelines/$pipelineId/$runId/index.tsx +1485 -0
  184. package/apps/main/src/routes/_authed/_app/pipelines/$pipelineId/-components/dag-view.tsx +296 -0
  185. package/apps/main/src/routes/_authed/_app/pipelines/$pipelineId/-components/step-config-modal.tsx +634 -0
  186. package/apps/main/src/routes/_authed/_app/pipelines/$pipelineId/index.tsx +911 -0
  187. package/apps/main/src/routes/_authed/_app/pipelines/-fns.ts +510 -0
  188. package/apps/main/src/routes/_authed/_app/pipelines/index.tsx +103 -0
  189. package/apps/main/src/routes/_authed/_app/reports/$reportId.tsx +397 -0
  190. package/apps/main/src/routes/_authed/_app/reports/-fns.ts +11 -0
  191. package/apps/main/src/routes/_authed/_app/reports/index.tsx +22 -0
  192. package/apps/main/src/routes/_authed/_app/route.tsx +48 -0
  193. package/apps/main/src/routes/_authed/_app/submissions/-columns.tsx +161 -0
  194. package/apps/main/src/routes/_authed/_app/submissions/-fns.ts +128 -0
  195. package/apps/main/src/routes/_authed/_app/submissions/index.tsx +190 -0
  196. package/apps/main/src/routes/_authed/_app/workflows/$wfSlug/$formId.tsx +542 -0
  197. package/apps/main/src/routes/_authed/_app/workflows/$wfSlug/-components/derived.tsx +154 -0
  198. package/apps/main/src/routes/_authed/_app/workflows/$wfSlug/-components/field.tsx +369 -0
  199. package/apps/main/src/routes/_authed/_app/workflows/$wfSlug/-components/group.tsx +475 -0
  200. package/apps/main/src/routes/_authed/_app/workflows/$wfSlug/index.tsx +263 -0
  201. package/apps/main/src/routes/_authed/_app/workflows/$wfSlug/route.tsx +33 -0
  202. package/apps/main/src/routes/_authed/_app/workflows/-components/form-card.tsx +315 -0
  203. package/apps/main/src/routes/_authed/_app/workflows/index.tsx +86 -0
  204. package/apps/main/src/routes/_authed/admin/index.tsx +12 -0
  205. package/apps/main/src/routes/_authed/admin/route.tsx +42 -0
  206. package/apps/main/src/routes/_authed/admin/users/-columns.tsx +124 -0
  207. package/apps/main/src/routes/_authed/admin/users/-fns.ts +30 -0
  208. package/apps/main/src/routes/_authed/admin/users/index.tsx +29 -0
  209. package/apps/main/src/routes/_authed/catchNotFound.tsx +114 -0
  210. package/apps/main/src/routes/_authed/redirects/forms.$id.tsx +29 -0
  211. package/apps/main/src/routes/_authed/redirects/submissions.$id.tsx +27 -0
  212. package/apps/main/src/routes/_authed/redirects/workflows.$id.tsx +27 -0
  213. package/apps/main/src/routes/_authed/route.tsx +51 -0
  214. package/apps/main/src/routes/_authed/settings/-components/new-api-key.tsx +85 -0
  215. package/apps/main/src/routes/_authed/settings/-components/new-invite.tsx +100 -0
  216. package/apps/main/src/routes/_authed/settings/analytics.tsx +1710 -0
  217. package/apps/main/src/routes/_authed/settings/billing/-components/price-table.tsx +129 -0
  218. package/apps/main/src/routes/_authed/settings/billing/-fns.ts +76 -0
  219. package/apps/main/src/routes/_authed/settings/billing/index.tsx +119 -0
  220. package/apps/main/src/routes/_authed/settings/embed.tsx +337 -0
  221. package/apps/main/src/routes/_authed/settings/index.tsx +12 -0
  222. package/apps/main/src/routes/_authed/settings/keys.tsx +157 -0
  223. package/apps/main/src/routes/_authed/settings/members.tsx +276 -0
  224. package/apps/main/src/routes/_authed/settings/route.tsx +22 -0
  225. package/apps/main/src/routes/_authed/settings/user.tsx +87 -0
  226. package/apps/main/src/routes/_authed/settings/workspace.tsx +206 -0
  227. package/apps/main/src/routes/_public/-components/sign-in-up.tsx +96 -0
  228. package/apps/main/src/routes/_public/embedded.tsx +57 -0
  229. package/apps/main/src/routes/_public/invite.$inviteId.tsx +143 -0
  230. package/apps/main/src/routes/_public/no-access.tsx +38 -0
  231. package/apps/main/src/routes/_public/no-invite.tsx +39 -0
  232. package/apps/main/src/routes/_public/otp.tsx +103 -0
  233. package/apps/main/src/routes/_public/route.tsx +15 -0
  234. package/apps/main/src/routes/_public/sign-in.tsx +111 -0
  235. package/apps/main/src/routes/_public/sign-up.tsx +114 -0
  236. package/apps/main/src/routes/api/auth/$.ts +11 -0
  237. package/apps/main/src/routes/api/billing/paid.ts +42 -0
  238. package/apps/main/src/routes/api/billing/webhooks.ts +70 -0
  239. package/apps/main/src/routes/api/chat/agent.ts +40 -0
  240. package/apps/main/src/routes/api/chat/key.ts +42 -0
  241. package/apps/main/src/routes/api/chat/member.ts +35 -0
  242. package/apps/main/src/routes/api/test/index.ts +19 -0
  243. package/apps/main/src/server.tsx +6 -0
  244. package/apps/main/src/styles/app.css +23 -0
  245. package/apps/main/src/vite-env.d.ts +7 -0
  246. package/apps/main/test.http +6 -0
  247. package/apps/main/tsconfig.json +17 -0
  248. package/apps/main/vite.config.ts +24 -0
  249. package/apps/main/vitest.config.js +17 -0
  250. package/apps/mcp/README.md +171 -0
  251. package/apps/mcp/eslint.config.mjs +3 -0
  252. package/apps/mcp/package.json +37 -0
  253. package/apps/mcp/src/index.ts +414 -0
  254. package/apps/mcp/tsconfig.json +19 -0
  255. package/apps/mcp/vite.config.ts +22 -0
  256. package/apps/posthog-proxy/index.html +9 -0
  257. package/apps/workers/.prettierignore +7 -0
  258. package/apps/workers/.prettierrc.js +3 -0
  259. package/apps/workers/dotenvx-safe.sh +11 -0
  260. package/apps/workers/eslint.config.mjs +3 -0
  261. package/apps/workers/package.json +65 -0
  262. package/apps/workers/src/lib/config.ts +7 -0
  263. package/apps/workers/src/lib/messages.ts +0 -0
  264. package/apps/workers/src/lib/posthog.ts +25 -0
  265. package/apps/workers/src/main.ts +58 -0
  266. package/apps/workers/src/workflows/extraction.ts +866 -0
  267. package/apps/workers/src/workflows/index.ts +3 -0
  268. package/apps/workers/src/workflows/pipeline-dag.ts +210 -0
  269. package/apps/workers/src/workflows/pipeline-steps.ts +1393 -0
  270. package/apps/workers/tsconfig.json +16 -0
  271. package/apps/workers/vite.config.ts +35 -0
  272. package/docs/CHANGELOG.md +84 -0
  273. package/docs/agent-templates-and-runs.md +859 -0
  274. package/docs/aws-migration-plan.md +267 -0
  275. package/docs/impl-p0-form-builder-improvements.md +683 -0
  276. package/docs/on-prem-deployment-spec.docx +0 -0
  277. package/docs/on-prem-deployment-spec.md +378 -0
  278. package/docs/prd-form-builder-strategy.md +1120 -0
  279. package/docs/widget-ng-apf-packaging-spec.md +43 -0
  280. package/infra/k8s/charts/seadotdev/Chart.yaml +6 -0
  281. package/infra/k8s/charts/seadotdev/templates/_helpers.tpl +27 -0
  282. package/infra/k8s/charts/seadotdev/templates/api-v2.yaml +105 -0
  283. package/infra/k8s/charts/seadotdev/templates/external-secrets.yaml +83 -0
  284. package/infra/k8s/charts/seadotdev/templates/ingress.yaml +54 -0
  285. package/infra/k8s/charts/seadotdev/templates/main-app.yaml +104 -0
  286. package/infra/k8s/charts/seadotdev/templates/workers.yaml +182 -0
  287. package/infra/k8s/charts/seadotdev/values.yaml +143 -0
  288. package/infra/terraform/main.tf +399 -0
  289. package/libs/ai/.prettierignore +2 -0
  290. package/libs/ai/.prettierrc.js +5 -0
  291. package/libs/ai/README.md +139 -0
  292. package/libs/ai/eslint.config.mjs +3 -0
  293. package/libs/ai/package.json +42 -0
  294. package/libs/ai/src/index.ts +5 -0
  295. package/libs/ai/src/models.ts +19 -0
  296. package/libs/ai/src/rag/index.ts +1 -0
  297. package/libs/ai/src/rag/rag.test.ts +99 -0
  298. package/libs/ai/src/rag/rag.ts +510 -0
  299. package/libs/ai/tsconfig.json +21 -0
  300. package/libs/ai/vite.config.ts +38 -0
  301. package/libs/cache/.prettierignore +2 -0
  302. package/libs/cache/eslint.config.mjs +3 -0
  303. package/libs/cache/package.json +35 -0
  304. package/libs/cache/src/feedback.ts +77 -0
  305. package/libs/cache/src/index.ts +2 -0
  306. package/libs/cache/tsconfig.json +19 -0
  307. package/libs/cache/vite.config.ts +36 -0
  308. package/libs/clients/.prettierignore +6 -0
  309. package/libs/clients/eslint.config.mjs +3 -0
  310. package/libs/clients/package.json +59 -0
  311. package/libs/clients/src/azure.ts +249 -0
  312. package/libs/clients/src/gcp.ts +220 -0
  313. package/libs/clients/src/hatchet.ts +86 -0
  314. package/libs/clients/src/index.ts +8 -0
  315. package/libs/clients/src/loops.ts +86 -0
  316. package/libs/clients/src/polar.ts +77 -0
  317. package/libs/clients/src/posthog.ts +55 -0
  318. package/libs/clients/tsconfig.json +19 -0
  319. package/libs/clients/vite.config.ts +35 -0
  320. package/libs/config/.prettierignore +6 -0
  321. package/libs/config/.prettierrc.js +12 -0
  322. package/libs/config/eslint.config.mjs +3 -0
  323. package/libs/config/package.json +50 -0
  324. package/libs/config/src/azure.ts +54 -0
  325. package/libs/config/src/db.ts +18 -0
  326. package/libs/config/src/gcp.ts +53 -0
  327. package/libs/config/src/google.ts +17 -0
  328. package/libs/config/src/hatchet.ts +20 -0
  329. package/libs/config/src/index.ts +108 -0
  330. package/libs/config/src/llm.ts +17 -0
  331. package/libs/config/src/polar.ts +24 -0
  332. package/libs/config/src/util.ts +8 -0
  333. package/libs/config/src/vercel.ts +26 -0
  334. package/libs/config/tsconfig.json +19 -0
  335. package/libs/config/vite.config.ts +34 -0
  336. package/libs/core/.prettierignore +2 -0
  337. package/libs/core/eslint.config.mjs +3 -0
  338. package/libs/core/package.json +59 -0
  339. package/libs/core/src/chat/derived.ts +97 -0
  340. package/libs/core/src/chat/feedback.ts +293 -0
  341. package/libs/core/src/chat/index.ts +6 -0
  342. package/libs/core/src/chat/model.ts +92 -0
  343. package/libs/core/src/chat/prepare-tools.ts +286 -0
  344. package/libs/core/src/chat/prompts.ts +623 -0
  345. package/libs/core/src/chat/stream.ts +311 -0
  346. package/libs/core/src/chat/summarize.ts +168 -0
  347. package/libs/core/src/chat/tools/agent.ts +403 -0
  348. package/libs/core/src/chat/tools/chart-agent.ts +526 -0
  349. package/libs/core/src/chat/tools/chart-helpers/sandbox.ts +47 -0
  350. package/libs/core/src/chat/tools/chart.ts +86 -0
  351. package/libs/core/src/chat/tools/credit-agent.ts +1383 -0
  352. package/libs/core/src/chat/tools/credit.ts +1435 -0
  353. package/libs/core/src/chat/tools/deep-dive-agent.ts +100 -0
  354. package/libs/core/src/chat/tools/deep-dive.ts +141 -0
  355. package/libs/core/src/chat/tools/form.ts +449 -0
  356. package/libs/core/src/chat/tools/helpers.ts +91 -0
  357. package/libs/core/src/chat/tools/index.ts +42 -0
  358. package/libs/core/src/chat/tools/pipeline-artifact.ts +76 -0
  359. package/libs/core/src/chat/tools/report.ts +40 -0
  360. package/libs/core/src/chat/tools/search.ts +390 -0
  361. package/libs/core/src/chat/tools/submission.ts +227 -0
  362. package/libs/core/src/chat/tools/workflow.ts +684 -0
  363. package/libs/core/src/chat/types.ts +3 -0
  364. package/libs/core/src/data-extraction/classification/azure.ts +168 -0
  365. package/libs/core/src/data-extraction/classification/index.ts +1 -0
  366. package/libs/core/src/data-extraction/dal.ts +246 -0
  367. package/libs/core/src/data-extraction/form-structure-extractor.ts +294 -0
  368. package/libs/core/src/data-extraction/index.ts +4 -0
  369. package/libs/core/src/data-extraction/layout/azure.ts +730 -0
  370. package/libs/core/src/data-extraction/layout/excel.ts +180 -0
  371. package/libs/core/src/data-extraction/layout/gcp.ts +1071 -0
  372. package/libs/core/src/data-extraction/layout/index.ts +266 -0
  373. package/libs/core/src/data-extraction/layout/plaintext.ts +45 -0
  374. package/libs/core/src/data-extraction/models.ts +38 -0
  375. package/libs/core/src/data-extraction/pdf-utils.ts +96 -0
  376. package/libs/core/src/data-extraction/structuring/bank-statement.ts +1182 -0
  377. package/libs/core/src/data-extraction/structuring/custom.ts +495 -0
  378. package/libs/core/src/data-extraction/structuring/index.ts +290 -0
  379. package/libs/core/src/data-extraction/structuring/prompts.ts +69 -0
  380. package/libs/core/src/data-extraction/type-guards.ts +110 -0
  381. package/libs/core/src/data-extraction/types.ts +84 -0
  382. package/libs/core/src/data-extraction/utils.ts +31 -0
  383. package/libs/core/src/data-extraction/validation/bank-statement.ts +127 -0
  384. package/libs/core/src/deals.ts +17 -0
  385. package/libs/core/src/documents.ts +152 -0
  386. package/libs/core/src/index.ts +5 -0
  387. package/libs/core/src/pipelines/display.ts +678 -0
  388. package/libs/core/src/pipelines/execute.ts +2342 -0
  389. package/libs/core/src/pipelines/index.ts +4 -0
  390. package/libs/core/src/pipelines/list.ts +12 -0
  391. package/libs/core/src/pipelines/runs.ts +53 -0
  392. package/libs/core/tsconfig.json +20 -0
  393. package/libs/core/vite.config.ts +56 -0
  394. package/libs/dal/.prettierignore +6 -0
  395. package/libs/dal/.prettierrc.js +12 -0
  396. package/libs/dal/eslint.config.mjs +3 -0
  397. package/libs/dal/package.json +57 -0
  398. package/libs/dal/src/_tests/db.test.ts +19 -0
  399. package/libs/dal/src/_tests/mock-db.ts +60 -0
  400. package/libs/dal/src/api-key.test.ts +397 -0
  401. package/libs/dal/src/api-key.ts +110 -0
  402. package/libs/dal/src/billing.ts +23 -0
  403. package/libs/dal/src/conversation.test.ts +655 -0
  404. package/libs/dal/src/conversation.ts +532 -0
  405. package/libs/dal/src/deal.test.ts +45 -0
  406. package/libs/dal/src/deal.ts +87 -0
  407. package/libs/dal/src/defaults-consumer-lending-uk.ts +33 -0
  408. package/libs/dal/src/defaults-consumer-lending-us.ts +33 -0
  409. package/libs/dal/src/defaults-private-credit.ts +57 -0
  410. package/libs/dal/src/defaults-private-equity.ts +51 -0
  411. package/libs/dal/src/defaults-smb-lending-us.ts +1569 -0
  412. package/libs/dal/src/defaults-sme-lending-uk-express.ts +1527 -0
  413. package/libs/dal/src/defaults-sme-lending-uk.ts +1669 -0
  414. package/libs/dal/src/defaults-types.ts +23 -0
  415. package/libs/dal/src/defaults.ts +550 -0
  416. package/libs/dal/src/document.test.ts +70 -0
  417. package/libs/dal/src/document.ts +192 -0
  418. package/libs/dal/src/feedback.ts +255 -0
  419. package/libs/dal/src/form.test.ts +637 -0
  420. package/libs/dal/src/form.ts +1165 -0
  421. package/libs/dal/src/index.ts +20 -0
  422. package/libs/dal/src/invitation.test.ts +746 -0
  423. package/libs/dal/src/invitation.ts +207 -0
  424. package/libs/dal/src/member.test.ts +185 -0
  425. package/libs/dal/src/member.ts +80 -0
  426. package/libs/dal/src/organization.ts +116 -0
  427. package/libs/dal/src/permission.ts +25 -0
  428. package/libs/dal/src/pipeline.test.ts +388 -0
  429. package/libs/dal/src/pipeline.ts +4222 -0
  430. package/libs/dal/src/report.ts +199 -0
  431. package/libs/dal/src/result.ts +16 -0
  432. package/libs/dal/src/search.ts +172 -0
  433. package/libs/dal/src/session.test.ts +110 -0
  434. package/libs/dal/src/session.ts +31 -0
  435. package/libs/dal/src/submission.test.ts +1304 -0
  436. package/libs/dal/src/submission.ts +1396 -0
  437. package/libs/dal/src/tool.ts +159 -0
  438. package/libs/dal/src/user.ts +16 -0
  439. package/libs/dal/src/workflow.test.ts +89 -0
  440. package/libs/dal/src/workflow.ts +262 -0
  441. package/libs/dal/tsconfig.build.json +4 -0
  442. package/libs/dal/tsconfig.json +22 -0
  443. package/libs/dal/vite.config.ts +34 -0
  444. package/libs/db/.prettierignore +6 -0
  445. package/libs/db/.prettierrc.js +12 -0
  446. package/libs/db/eslint.config.mjs +3 -0
  447. package/libs/db/package.json +52 -0
  448. package/libs/db/src/index.ts +24 -0
  449. package/libs/db/src/relations.ts +549 -0
  450. package/libs/db/src/schema.ts +2 -0
  451. package/libs/db/src/schemas/api.ts +35 -0
  452. package/libs/db/src/schemas/conversations.ts +175 -0
  453. package/libs/db/src/schemas/core.ts +359 -0
  454. package/libs/db/src/schemas/documents.ts +181 -0
  455. package/libs/db/src/schemas/feedback.ts +40 -0
  456. package/libs/db/src/schemas/index.ts +26 -0
  457. package/libs/db/src/schemas/organisations.ts +97 -0
  458. package/libs/db/src/schemas/pipelines.ts +440 -0
  459. package/libs/db/src/schemas/users.ts +95 -0
  460. package/libs/db/src/types.ts +190 -0
  461. package/libs/db/src/utils.ts +14 -0
  462. package/libs/db/tsconfig.json +19 -0
  463. package/libs/db/vite.config.ts +31 -0
  464. package/libs/lint/.prettierignore +6 -0
  465. package/libs/lint/eslint.config.mjs +61 -0
  466. package/libs/lint/package.json +29 -0
  467. package/libs/lint/prettier.config.js +12 -0
  468. package/libs/schemas/.prettierignore +6 -0
  469. package/libs/schemas/.prettierrc.js +12 -0
  470. package/libs/schemas/README.md +15 -0
  471. package/libs/schemas/eslint.config.mjs +3 -0
  472. package/libs/schemas/package.json +67 -0
  473. package/libs/schemas/src/core/chat.ts +67 -0
  474. package/libs/schemas/src/core/core-result.ts +15 -0
  475. package/libs/schemas/src/core/data-extraction.ts +184 -0
  476. package/libs/schemas/src/core/layout.ts +478 -0
  477. package/libs/schemas/src/core/pipeline.ts +128 -0
  478. package/libs/schemas/src/core/submission.ts +97 -0
  479. package/libs/schemas/src/db/account.ts +57 -0
  480. package/libs/schemas/src/db/apiKey.ts +57 -0
  481. package/libs/schemas/src/db/context.ts +33 -0
  482. package/libs/schemas/src/db/conversation.ts +65 -0
  483. package/libs/schemas/src/db/deal.ts +42 -0
  484. package/libs/schemas/src/db/document.ts +103 -0
  485. package/libs/schemas/src/db/documentCitation.ts +58 -0
  486. package/libs/schemas/src/db/documentExtraction.ts +69 -0
  487. package/libs/schemas/src/db/fieldCorrection.ts +85 -0
  488. package/libs/schemas/src/db/form.ts +45 -0
  489. package/libs/schemas/src/db/formField.ts +59 -0
  490. package/libs/schemas/src/db/formGroup.ts +42 -0
  491. package/libs/schemas/src/db/impersonation.ts +39 -0
  492. package/libs/schemas/src/db/index.ts +25 -0
  493. package/libs/schemas/src/db/invitation.ts +42 -0
  494. package/libs/schemas/src/db/member.ts +36 -0
  495. package/libs/schemas/src/db/message.ts +58 -0
  496. package/libs/schemas/src/db/organization.ts +62 -0
  497. package/libs/schemas/src/db/session.ts +48 -0
  498. package/libs/schemas/src/db/submission.ts +54 -0
  499. package/libs/schemas/src/db/submissionGroup.ts +36 -0
  500. package/libs/schemas/src/db/submissionItem.ts +33 -0
  501. package/libs/schemas/src/db/submissionItemVersion.ts +70 -0
  502. package/libs/schemas/src/db/user.ts +51 -0
  503. package/libs/schemas/src/db/utils.ts +3 -0
  504. package/libs/schemas/src/db/verification.ts +36 -0
  505. package/libs/schemas/src/db/workflow.ts +42 -0
  506. package/libs/schemas/src/index.ts +10 -0
  507. package/libs/schemas/tsconfig.json +21 -0
  508. package/libs/schemas/vite.config.ts +38 -0
  509. package/libs/ui/.prettierignore +6 -0
  510. package/libs/ui/.prettierrc.js +12 -0
  511. package/libs/ui/components.json +24 -0
  512. package/libs/ui/eslint.config.mjs +3 -0
  513. package/libs/ui/package.json +142 -0
  514. package/libs/ui/src/components/chart-viz/chart.tsx +255 -0
  515. package/libs/ui/src/components/chart-viz/converters.ts +474 -0
  516. package/libs/ui/src/components/chart-viz/dashboard.tsx +146 -0
  517. package/libs/ui/src/components/chart-viz/index.ts +37 -0
  518. package/libs/ui/src/components/chart-viz/markdown.tsx +344 -0
  519. package/libs/ui/src/components/chart-viz/table.tsx +446 -0
  520. package/libs/ui/src/components/chart-viz/theme-context.tsx +70 -0
  521. package/libs/ui/src/components/chart-viz/themes/dark.ts +98 -0
  522. package/libs/ui/src/components/chart-viz/themes/index.ts +69 -0
  523. package/libs/ui/src/components/chart-viz/themes/light.ts +98 -0
  524. package/libs/ui/src/components/chart-viz/themes/tailwind.ts +326 -0
  525. package/libs/ui/src/components/chart-viz/themes/types.ts +99 -0
  526. package/libs/ui/src/components/chart-viz/tool-display.tsx +150 -0
  527. package/libs/ui/src/components/chart-viz/types.ts +95 -0
  528. package/libs/ui/src/components/doc-viewers/excel/index.tsx +431 -0
  529. package/libs/ui/src/components/doc-viewers/excel/themes.ts +160 -0
  530. package/libs/ui/src/components/doc-viewers/image/index.tsx +410 -0
  531. package/libs/ui/src/components/doc-viewers/pdf/index.tsx +258 -0
  532. package/libs/ui/src/components/doc-viewers/pdf/virtualized-pdf.tsx +556 -0
  533. package/libs/ui/src/components/misc/rel-date.tsx +52 -0
  534. package/libs/ui/src/components/misc/styled-link.tsx +2 -0
  535. package/libs/ui/src/components/table/data-table.tsx +546 -0
  536. package/libs/ui/src/components/table/report-table.tsx +305 -0
  537. package/libs/ui/src/components/table/sortable-column.tsx +34 -0
  538. package/libs/ui/src/components/ui/accordion.tsx +62 -0
  539. package/libs/ui/src/components/ui/alert-dialog.tsx +142 -0
  540. package/libs/ui/src/components/ui/alert.tsx +62 -0
  541. package/libs/ui/src/components/ui/artifact.tsx +118 -0
  542. package/libs/ui/src/components/ui/attachments.tsx +388 -0
  543. package/libs/ui/src/components/ui/avatar.tsx +39 -0
  544. package/libs/ui/src/components/ui/badge.tsx +43 -0
  545. package/libs/ui/src/components/ui/breadcrumb.tsx +102 -0
  546. package/libs/ui/src/components/ui/button-group.tsx +78 -0
  547. package/libs/ui/src/components/ui/button.tsx +79 -0
  548. package/libs/ui/src/components/ui/card.tsx +32 -0
  549. package/libs/ui/src/components/ui/carousel.tsx +228 -0
  550. package/libs/ui/src/components/ui/chain-of-thought.tsx +198 -0
  551. package/libs/ui/src/components/ui/checkbox.tsx +27 -0
  552. package/libs/ui/src/components/ui/citation.tsx +34 -0
  553. package/libs/ui/src/components/ui/code-block.tsx +500 -0
  554. package/libs/ui/src/components/ui/collapsible.tsx +19 -0
  555. package/libs/ui/src/components/ui/command.tsx +161 -0
  556. package/libs/ui/src/components/ui/conversation.tsx +90 -0
  557. package/libs/ui/src/components/ui/dialog.tsx +142 -0
  558. package/libs/ui/src/components/ui/dropdown-menu.tsx +246 -0
  559. package/libs/ui/src/components/ui/highlight.tsx +3 -0
  560. package/libs/ui/src/components/ui/hover-card.tsx +36 -0
  561. package/libs/ui/src/components/ui/inline-citation.tsx +251 -0
  562. package/libs/ui/src/components/ui/input-group.tsx +156 -0
  563. package/libs/ui/src/components/ui/input-otp.tsx +78 -0
  564. package/libs/ui/src/components/ui/input.tsx +21 -0
  565. package/libs/ui/src/components/ui/label.tsx +19 -0
  566. package/libs/ui/src/components/ui/model-selector.tsx +174 -0
  567. package/libs/ui/src/components/ui/multisidebar.tsx +750 -0
  568. package/libs/ui/src/components/ui/popover.tsx +43 -0
  569. package/libs/ui/src/components/ui/progress.tsx +28 -0
  570. package/libs/ui/src/components/ui/reasoning.tsx +178 -0
  571. package/libs/ui/src/components/ui/resizable.tsx +49 -0
  572. package/libs/ui/src/components/ui/scroll-area.tsx +54 -0
  573. package/libs/ui/src/components/ui/select.tsx +171 -0
  574. package/libs/ui/src/components/ui/separator.tsx +26 -0
  575. package/libs/ui/src/components/ui/sheet.tsx +128 -0
  576. package/libs/ui/src/components/ui/shimmer.tsx +53 -0
  577. package/libs/ui/src/components/ui/skeleton.tsx +13 -0
  578. package/libs/ui/src/components/ui/sonner.tsx +23 -0
  579. package/libs/ui/src/components/ui/switch.tsx +26 -0
  580. package/libs/ui/src/components/ui/table.tsx +96 -0
  581. package/libs/ui/src/components/ui/tabs.tsx +52 -0
  582. package/libs/ui/src/components/ui/textarea.tsx +41 -0
  583. package/libs/ui/src/components/ui/tool.tsx +209 -0
  584. package/libs/ui/src/components/ui/tooltip.tsx +58 -0
  585. package/libs/ui/src/components/ui/typography.tsx +113 -0
  586. package/libs/ui/src/fonts/manrope-v15-latin-300.woff2 +0 -0
  587. package/libs/ui/src/fonts/manrope-v15-latin-400.woff2 +0 -0
  588. package/libs/ui/src/fonts/manrope-v15-latin-500.woff2 +0 -0
  589. package/libs/ui/src/fonts/manrope-v15-latin-600.woff2 +0 -0
  590. package/libs/ui/src/hooks/use-mobile.ts +19 -0
  591. package/libs/ui/src/lib/utils.ts +6 -0
  592. package/libs/ui/src/styles/fonts.css +35 -0
  593. package/libs/ui/src/styles/style.css +218 -0
  594. package/libs/ui/tsconfig.json +21 -0
  595. package/libs/ui/vite.config.ts +80 -0
  596. package/libs/ui-lit/README.md +245 -0
  597. package/libs/ui-lit/TESTING_GUIDE.md +296 -0
  598. package/libs/ui-lit/eslint.config.mjs +3 -0
  599. package/libs/ui-lit/package.json +41 -0
  600. package/libs/ui-lit/scripts/build-css.js +43 -0
  601. package/libs/ui-lit/src/components/sea-alert.ts +132 -0
  602. package/libs/ui-lit/src/components/sea-button.ts +95 -0
  603. package/libs/ui-lit/src/components/sea-card.ts +113 -0
  604. package/libs/ui-lit/src/components/sea-input.ts +184 -0
  605. package/libs/ui-lit/src/components/sea-spinner.ts +65 -0
  606. package/libs/ui-lit/src/index.ts +15 -0
  607. package/libs/ui-lit/src/lib/utils.ts +6 -0
  608. package/libs/ui-lit/src/styles/tailwind.css +76 -0
  609. package/libs/ui-lit/src/theme.css +66 -0
  610. package/libs/ui-lit/src/theme.ts +79 -0
  611. package/libs/ui-lit/src/vite-env.d.ts +6 -0
  612. package/libs/ui-lit/tailwind.config.ts +50 -0
  613. package/libs/ui-lit/test.html +289 -0
  614. package/libs/ui-lit/tsconfig.json +23 -0
  615. package/libs/ui-lit/vite.config.ts +31 -0
  616. package/libs/ui-lit/vite.css.config.ts +20 -0
  617. package/libs/util/.prettierignore +6 -0
  618. package/libs/util/.prettierrc.js +12 -0
  619. package/libs/util/eslint.config.mjs +3 -0
  620. package/libs/util/package.json +45 -0
  621. package/libs/util/src/billing.ts +10 -0
  622. package/libs/util/src/data-transform.ts +19 -0
  623. package/libs/util/src/encryption.ts +45 -0
  624. package/libs/util/src/fmt.test.ts +9 -0
  625. package/libs/util/src/fmt.ts +71 -0
  626. package/libs/util/src/fuzzy.ts +47 -0
  627. package/libs/util/src/id.ts +24 -0
  628. package/libs/util/src/invariant.ts +31 -0
  629. package/libs/util/src/sub-name.ts +7 -0
  630. package/libs/util/tsconfig.json +19 -0
  631. package/libs/util/vite.config.ts +34 -0
  632. package/package.json +28 -0
  633. package/packages/widget/.prettierignore +6 -0
  634. package/packages/widget/.prettierrc.js +12 -0
  635. package/packages/widget/README.md +95 -0
  636. package/packages/widget/eslint.config.mjs +11 -0
  637. package/packages/widget/openapi-ts.config.ts +8 -0
  638. package/packages/widget/package.json +89 -0
  639. package/packages/widget/postcss.config.mjs +10 -0
  640. package/packages/widget/src/clients/api/client/client.ts +187 -0
  641. package/packages/widget/src/clients/api/client/index.ts +22 -0
  642. package/packages/widget/src/clients/api/client/types.ts +192 -0
  643. package/packages/widget/src/clients/api/client/utils.ts +394 -0
  644. package/packages/widget/src/clients/api/client.gen.ts +18 -0
  645. package/packages/widget/src/clients/api/core/auth.ts +39 -0
  646. package/packages/widget/src/clients/api/core/bodySerializer.ts +74 -0
  647. package/packages/widget/src/clients/api/core/params.ts +132 -0
  648. package/packages/widget/src/clients/api/core/pathSerializer.ts +169 -0
  649. package/packages/widget/src/clients/api/core/types.ts +80 -0
  650. package/packages/widget/src/clients/api/index.ts +3 -0
  651. package/packages/widget/src/clients/api/sdk.gen.ts +805 -0
  652. package/packages/widget/src/clients/api/types.gen.ts +2085 -0
  653. package/packages/widget/src/components/container.tsx +42 -0
  654. package/packages/widget/src/components/data-display.tsx +384 -0
  655. package/packages/widget/src/components/data-viewer.tsx +311 -0
  656. package/packages/widget/src/components/doc-list.tsx +102 -0
  657. package/packages/widget/src/components/field-correction-modal.tsx +265 -0
  658. package/packages/widget/src/components/header.tsx +71 -0
  659. package/packages/widget/src/components/new-submission.tsx +290 -0
  660. package/packages/widget/src/components/sidebar-right.tsx +19 -0
  661. package/packages/widget/src/components/submission-card.tsx +66 -0
  662. package/packages/widget/src/components/submission-page.tsx +75 -0
  663. package/packages/widget/src/components/upload-doc.tsx +241 -0
  664. package/packages/widget/src/components/widget.tsx +101 -0
  665. package/packages/widget/src/index.tsx +167 -0
  666. package/packages/widget/src/lib/config.ts +2 -0
  667. package/packages/widget/src/lib/util.ts +40 -0
  668. package/packages/widget/src/styles/index.css +5 -0
  669. package/packages/widget/src/styles/tw-properties.css +337 -0
  670. package/packages/widget/src/vite-env.d.ts +3 -0
  671. package/packages/widget/tsconfig.app.json +35 -0
  672. package/packages/widget/tsconfig.json +4 -0
  673. package/packages/widget/tsconfig.node.json +24 -0
  674. package/packages/widget/vite.config.ts +116 -0
  675. package/packages/widget-lit/BOTTLENECKS.md +250 -0
  676. package/packages/widget-lit/IMPLEMENTATION_SUMMARY.md +295 -0
  677. package/packages/widget-lit/README.md +232 -0
  678. package/packages/widget-lit/eslint.config.mjs +3 -0
  679. package/packages/widget-lit/package.json +52 -0
  680. package/packages/widget-lit/src/api-client.ts +230 -0
  681. package/packages/widget-lit/src/api-client.ts.backup +218 -0
  682. package/packages/widget-lit/src/components/sea-chat.ts +382 -0
  683. package/packages/widget-lit/src/components/sea-submission-viewer.ts +267 -0
  684. package/packages/widget-lit/src/components/sea-widget.ts +317 -0
  685. package/packages/widget-lit/src/index.ts +48 -0
  686. package/packages/widget-lit/src/react.ts +58 -0
  687. package/packages/widget-lit/src/style.css +47 -0
  688. package/packages/widget-lit/tsconfig.json +24 -0
  689. package/packages/widget-lit/vite.config.ts +29 -0
  690. package/packages/widget-ng/DEVELOPMENT.md +74 -0
  691. package/packages/widget-ng/README.md +657 -0
  692. package/packages/widget-ng/dev.sh +14 -0
  693. package/packages/widget-ng/eslint.config.mjs +24 -0
  694. package/packages/widget-ng/ng-package.json +9 -0
  695. package/packages/widget-ng/package.json +85 -0
  696. package/packages/widget-ng/src/index.ts +45 -0
  697. package/packages/widget-ng/src/lib/components/sea-chat.component.ts +737 -0
  698. package/packages/widget-ng/src/lib/components/sea-data-viewer.component.ts +2240 -0
  699. package/packages/widget-ng/src/lib/components/sea-deal-form-modal.component.ts +702 -0
  700. package/packages/widget-ng/src/lib/components/sea-document-list.component.ts +350 -0
  701. package/packages/widget-ng/src/lib/components/sea-feedback-modal.component.ts +461 -0
  702. package/packages/widget-ng/src/lib/components/sea-file-upload.component.ts +655 -0
  703. package/packages/widget-ng/src/lib/components/sea-model-selection-modal.component.ts +367 -0
  704. package/packages/widget-ng/src/lib/components/sea-new-submission-modal.component.ts +414 -0
  705. package/packages/widget-ng/src/lib/components/sea-pdf-viewer.component.ts +869 -0
  706. package/packages/widget-ng/src/lib/components/sea-submission-card.component.ts +251 -0
  707. package/packages/widget-ng/src/lib/components/sea-widget.component.ts +684 -0
  708. package/packages/widget-ng/src/lib/models/submission.model.ts +170 -0
  709. package/packages/widget-ng/src/lib/pipes/markdown.pipe.ts +57 -0
  710. package/packages/widget-ng/src/lib/services/api-client.service.ts +715 -0
  711. package/packages/widget-ng/src/lib/services/chat.service.ts +330 -0
  712. package/packages/widget-ng/src/lib/services/config.service.ts +107 -0
  713. package/packages/widget-ng/src/web-component.ts +56 -0
  714. package/packages/widget-ng/tsconfig.json +25 -0
  715. package/packages/widget-ng/tsconfig.lib.json +9 -0
  716. package/packages/widget-ng/vite.config.elements.ts +26 -0
  717. package/packages/widget-ng/vitest.config.ts +19 -0
  718. package/packages/widget-ng/vitest.setup.ts +13 -0
  719. package/pnpm-workspace.yaml +18 -0
  720. package/render.yaml +136 -0
  721. package/scripts/README.md +57 -0
  722. package/scripts/package.json +22 -0
  723. package/scripts/python/.python-version +1 -0
  724. package/scripts/python/README.md +3 -0
  725. package/scripts/python/export-org-data.py +693 -0
  726. package/scripts/python/pyproject.toml +29 -0
  727. package/scripts/python/requirements-dev.lock +36 -0
  728. package/scripts/python/requirements.lock +36 -0
  729. package/scripts/python/src/gen.py +297 -0
  730. package/scripts/python/test.py +34 -0
  731. package/scripts/src/fix-storage-provider-mismatch.ts +239 -0
  732. package/scripts/src/sync-render-yaml.ts +290 -0
  733. package/scripts/src/test-chat-stream.ts +300 -0
  734. package/scripts/src/test-reconciliation.ts +230 -0
  735. package/scripts/tsconfig.json +15 -0
  736. package/tests/angular-test-app/.vscode/extensions.json +4 -0
  737. package/tests/angular-test-app/.vscode/launch.json +13 -0
  738. package/tests/angular-test-app/.vscode/tasks.json +24 -0
  739. package/tests/angular-test-app/README.md +59 -0
  740. package/tests/angular-test-app/angular.json +111 -0
  741. package/tests/angular-test-app/clean-start.sh +14 -0
  742. package/tests/angular-test-app/package.json +36 -0
  743. package/tests/angular-test-app/public/favicon.ico +0 -0
  744. package/tests/angular-test-app/src/app/app.component.ts +220 -0
  745. package/tests/angular-test-app/src/app/app.config.ts +5 -0
  746. package/tests/angular-test-app/src/env.d.ts +13 -0
  747. package/tests/angular-test-app/src/index.html +13 -0
  748. package/tests/angular-test-app/src/main.ts +6 -0
  749. package/tests/angular-test-app/src/styles.css +8 -0
  750. package/tests/angular-test-app/tsconfig.app.json +15 -0
  751. package/tests/angular-test-app/tsconfig.json +27 -0
  752. package/tests/crm-viewer-app/API_INTEGRATION_SUMMARY.md +295 -0
  753. package/tests/crm-viewer-app/CURRENT_ASSETS_FIELDS.md +148 -0
  754. package/tests/crm-viewer-app/FIELD_ID_MAPPING.md +206 -0
  755. package/tests/crm-viewer-app/INTEGRATION_GUIDE.md +309 -0
  756. package/tests/crm-viewer-app/README.md +174 -0
  757. package/tests/crm-viewer-app/REAL_API_INTEGRATION.md +240 -0
  758. package/tests/crm-viewer-app/UPDATED_IMPLEMENTATION.md +279 -0
  759. package/tests/crm-viewer-app/angular.json +114 -0
  760. package/tests/crm-viewer-app/package.json +35 -0
  761. package/tests/crm-viewer-app/src/app/app.component.ts +534 -0
  762. package/tests/crm-viewer-app/src/app/citation.service.ts +316 -0
  763. package/tests/crm-viewer-app/src/env.d.ts +16 -0
  764. package/tests/crm-viewer-app/src/index.html +19 -0
  765. package/tests/crm-viewer-app/src/main.ts +7 -0
  766. package/tests/crm-viewer-app/src/styles.css +409 -0
  767. package/tests/crm-viewer-app/src/template.html +2678 -0
  768. package/tests/crm-viewer-app/tsconfig.app.json +15 -0
  769. package/tests/crm-viewer-app/tsconfig.json +27 -0
  770. package/tests/e2e/package.json +17 -0
  771. package/tests/e2e/playwright.config.ts +75 -0
  772. package/tests/e2e/tests/api/health.spec.ts +10 -0
  773. package/tests/e2e/tests/app/example.spec.ts +10 -0
  774. package/tests/widget-test-app/.prettierignore +6 -0
  775. package/tests/widget-test-app/README.md +48 -0
  776. package/tests/widget-test-app/index.html +12 -0
  777. package/tests/widget-test-app/package.json +24 -0
  778. package/tests/widget-test-app/src/App.css +192 -0
  779. package/tests/widget-test-app/src/App.tsx +80 -0
  780. package/tests/widget-test-app/src/main.tsx +9 -0
  781. package/tests/widget-test-app/src/vite-env.d.ts +4 -0
  782. package/tests/widget-test-app/tsconfig.json +25 -0
  783. package/tests/widget-test-app/tsconfig.node.json +11 -0
  784. package/tests/widget-test-app/vite.config.ts +14 -0
@@ -0,0 +1,2678 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>LOS - Financial Services</title>
7
+ <style>
8
+ * {
9
+ margin: 0;
10
+ padding: 0;
11
+ box-sizing: border-box;
12
+ }
13
+
14
+ body {
15
+ font-family: 'Salesforce Sans', Arial, sans-serif;
16
+ background-color: #f3f2f2;
17
+ font-size: 13px;
18
+ }
19
+
20
+ /* Top Navigation Bar */
21
+ .sf-header {
22
+ background: linear-gradient(to bottom, #2574a9 0%, #1c5a85 100%);
23
+ height: 40px;
24
+ display: flex;
25
+ align-items: center;
26
+ padding: 0 15px;
27
+ box-shadow: 0 2px 4px rgba(0,0,0,0.2);
28
+ }
29
+
30
+ .sf-logo {
31
+ color: white;
32
+ font-weight: bold;
33
+ font-size: 16px;
34
+ margin-right: 30px;
35
+ }
36
+
37
+ .sf-nav {
38
+ display: flex;
39
+ gap: 5px;
40
+ flex: 1;
41
+ }
42
+
43
+ .sf-nav-item {
44
+ color: white;
45
+ padding: 8px 12px;
46
+ cursor: pointer;
47
+ border-radius: 3px;
48
+ transition: background 0.2s;
49
+ }
50
+
51
+ .sf-nav-item:hover {
52
+ background: rgba(255,255,255,0.1);
53
+ }
54
+
55
+ .sf-nav-item.active {
56
+ background: rgba(255,255,255,0.2);
57
+ font-weight: bold;
58
+ }
59
+
60
+ .sf-user-menu {
61
+ margin-left: auto;
62
+ color: white;
63
+ display: flex;
64
+ align-items: center;
65
+ gap: 10px;
66
+ }
67
+
68
+ /* Sub Navigation */
69
+ .sf-sub-nav {
70
+ background: white;
71
+ border-bottom: 1px solid #d8dde6;
72
+ padding: 10px 15px;
73
+ display: flex;
74
+ align-items: center;
75
+ gap: 15px;
76
+ }
77
+
78
+ .sf-breadcrumb {
79
+ color: #0070d2;
80
+ font-size: 12px;
81
+ }
82
+
83
+ .sf-search {
84
+ padding: 6px 12px;
85
+ border: 1px solid #d8dde6;
86
+ border-radius: 3px;
87
+ width: 300px;
88
+ background: #fafaf9;
89
+ }
90
+
91
+ /* Main Content */
92
+ .sf-container {
93
+ padding: 15px;
94
+ max-width: 1400px;
95
+ margin: 0 auto;
96
+ }
97
+
98
+ /* Page Header */
99
+ .sf-page-header {
100
+ background: white;
101
+ border: 1px solid #d8dde6;
102
+ border-radius: 4px;
103
+ padding: 15px 20px;
104
+ margin-bottom: 15px;
105
+ display: flex;
106
+ align-items: center;
107
+ justify-content: space-between;
108
+ }
109
+
110
+ .sf-page-title {
111
+ display: flex;
112
+ align-items: center;
113
+ gap: 12px;
114
+ }
115
+
116
+ .sf-icon {
117
+ width: 32px;
118
+ height: 32px;
119
+ background: #0070d2;
120
+ border-radius: 4px;
121
+ display: flex;
122
+ align-items: center;
123
+ justify-content: center;
124
+ color: white;
125
+ font-weight: bold;
126
+ }
127
+
128
+ .sf-title-text h1 {
129
+ font-size: 18px;
130
+ color: #080707;
131
+ font-weight: 400;
132
+ }
133
+
134
+ .sf-title-text .subtitle {
135
+ font-size: 12px;
136
+ color: #706e6b;
137
+ }
138
+
139
+ .sf-actions {
140
+ display: flex;
141
+ gap: 8px;
142
+ }
143
+
144
+ .sf-button {
145
+ padding: 8px 16px;
146
+ border: 1px solid #d8dde6;
147
+ background: white;
148
+ border-radius: 3px;
149
+ cursor: pointer;
150
+ font-size: 13px;
151
+ transition: all 0.2s;
152
+ }
153
+
154
+ .sf-button:hover {
155
+ background: #f4f6f9;
156
+ }
157
+
158
+ .sf-button-primary {
159
+ background: #0070d2;
160
+ color: white;
161
+ border-color: #0070d2;
162
+ }
163
+
164
+ .sf-button-primary:hover {
165
+ background: #005fb2;
166
+ }
167
+
168
+ /* Content Layout */
169
+ .sf-content {
170
+ display: grid;
171
+ grid-template-columns: 2fr 1fr;
172
+ gap: 15px;
173
+ }
174
+
175
+ .sf-content.full-width {
176
+ grid-template-columns: 1fr;
177
+ }
178
+
179
+ .sf-sidebar {
180
+ transition: all 0.3s ease;
181
+ }
182
+
183
+ .sf-content.full-width .sf-sidebar {
184
+ display: none;
185
+ }
186
+
187
+ .sf-section {
188
+ background: white;
189
+ border: 1px solid #d8dde6;
190
+ border-radius: 4px;
191
+ overflow: hidden;
192
+ }
193
+
194
+ .sf-section-header {
195
+ background: #fafaf9;
196
+ border-bottom: 1px solid #d8dde6;
197
+ padding: 12px 15px;
198
+ font-weight: bold;
199
+ color: #080707;
200
+ display: flex;
201
+ justify-content: space-between;
202
+ align-items: center;
203
+ }
204
+
205
+ .sf-section-body {
206
+ padding: 15px;
207
+ }
208
+
209
+ .sf-table {
210
+ width: 100%;
211
+ border-collapse: collapse;
212
+ }
213
+
214
+ .sf-table th {
215
+ background: #fafaf9;
216
+ padding: 10px;
217
+ text-align: left;
218
+ font-weight: 600;
219
+ border-bottom: 1px solid #d8dde6;
220
+ font-size: 12px;
221
+ color: #080707;
222
+ }
223
+
224
+ .sf-table td {
225
+ padding: 10px;
226
+ border-bottom: 1px solid #e5e5e5;
227
+ font-size: 13px;
228
+ }
229
+
230
+ .sf-table tr:hover {
231
+ background: #f4f6f9;
232
+ }
233
+
234
+ .sf-link {
235
+ color: #0070d2;
236
+ text-decoration: none;
237
+ cursor: pointer;
238
+ }
239
+
240
+ .sf-link:hover {
241
+ text-decoration: underline;
242
+ }
243
+
244
+ .sf-field-row {
245
+ display: grid;
246
+ grid-template-columns: 1fr 1fr;
247
+ gap: 15px;
248
+ margin-bottom: 15px;
249
+ }
250
+
251
+ .sf-field {
252
+ display: flex;
253
+ flex-direction: column;
254
+ }
255
+
256
+ .sf-field-label {
257
+ font-size: 11px;
258
+ color: #706e6b;
259
+ margin-bottom: 4px;
260
+ text-transform: uppercase;
261
+ font-weight: 600;
262
+ }
263
+
264
+ .sf-field-value {
265
+ color: #080707;
266
+ font-size: 13px;
267
+ }
268
+
269
+ .sf-status-badge {
270
+ display: inline-block;
271
+ padding: 4px 8px;
272
+ border-radius: 3px;
273
+ font-size: 11px;
274
+ font-weight: 600;
275
+ }
276
+
277
+ .status-open {
278
+ background: #e0f3ff;
279
+ color: #014486;
280
+ }
281
+
282
+ .status-closed {
283
+ background: #c9f2c7;
284
+ color: #2e844a;
285
+ }
286
+
287
+ .status-pending {
288
+ background: #ffd351;
289
+ color: #514f4d;
290
+ }
291
+
292
+ /* Widget Container */
293
+ .sf-widget-container {
294
+ grid-column: 1 / -1;
295
+ height: 600px;
296
+ }
297
+
298
+ .sf-widget-container .sf-section-body {
299
+ padding: 0;
300
+ height: calc(100% - 45px);
301
+ overflow: hidden;
302
+ position: relative;
303
+ }
304
+
305
+ .sf-widget-container iframe {
306
+ width: calc(100% + 60px);
307
+ height: 100%;
308
+ border: none;
309
+ position: relative;
310
+ left: -60px;
311
+ }
312
+
313
+ /* Tabs */
314
+ .sf-tabs {
315
+ display: flex;
316
+ border-bottom: 1px solid #d8dde6;
317
+ background: #fafaf9;
318
+ }
319
+
320
+ .sf-tab {
321
+ padding: 12px 20px;
322
+ cursor: pointer;
323
+ border-bottom: 3px solid transparent;
324
+ transition: all 0.2s;
325
+ }
326
+
327
+ .sf-tab:hover {
328
+ background: #f4f6f9;
329
+ }
330
+
331
+ .sf-tab.active {
332
+ border-bottom-color: #0070d2;
333
+ background: white;
334
+ font-weight: 600;
335
+ }
336
+
337
+ /* Financial Tab Specific Styles */
338
+ .sf-financial-tabs {
339
+ display: flex;
340
+ border-bottom: 1px solid #d8dde6;
341
+ background: #fafaf9;
342
+ margin-top: -1px;
343
+ }
344
+
345
+ .sf-financial-tab {
346
+ padding: 10px 16px;
347
+ cursor: pointer;
348
+ border-bottom: 3px solid transparent;
349
+ transition: all 0.2s;
350
+ font-size: 11px;
351
+ font-weight: 600;
352
+ color: #706e6b;
353
+ }
354
+
355
+ .sf-financial-tab:hover {
356
+ background: #f4f6f9;
357
+ }
358
+
359
+ .sf-financial-tab.active {
360
+ border-bottom-color: #0070d2;
361
+ background: white;
362
+ color: #0070d2;
363
+ }
364
+
365
+ .sf-upload-area {
366
+ padding: 40px 20px;
367
+ text-align: center;
368
+ border: 2px dashed #d8dde6;
369
+ border-radius: 4px;
370
+ margin: 20px;
371
+ background: #fafaf9;
372
+ }
373
+
374
+ .sf-upload-area h3 {
375
+ font-size: 16px;
376
+ margin-bottom: 8px;
377
+ color: #080707;
378
+ }
379
+
380
+ .sf-upload-area p {
381
+ color: #706e6b;
382
+ font-size: 13px;
383
+ margin-bottom: 20px;
384
+ }
385
+
386
+ .sf-upload-widget {
387
+ border: 1px solid #d8dde6;
388
+ border-radius: 4px;
389
+ background: white;
390
+ margin: 20px;
391
+ min-height: 500px;
392
+ overflow: hidden;
393
+ position: relative;
394
+ }
395
+
396
+ .sf-upload-widget.hidden {
397
+ display: none;
398
+ }
399
+
400
+ .sf-upload-widget iframe {
401
+ width: calc(100% + 60px);
402
+ height: 800px;
403
+ border: none;
404
+ position: relative;
405
+ left: -60px;
406
+ top: -40px;
407
+ }
408
+
409
+ .sf-financial-table {
410
+ width: 100%;
411
+ border-collapse: collapse;
412
+ margin-top: 15px;
413
+ }
414
+
415
+ .sf-financial-table th {
416
+ background: #f8f8f8;
417
+ border-bottom: 2px solid #ddd;
418
+ padding: 8px 12px;
419
+ text-align: left;
420
+ font-size: 11px;
421
+ font-weight: bold;
422
+ color: #333;
423
+ }
424
+
425
+ .sf-financial-table td {
426
+ padding: 6px 12px;
427
+ border-bottom: 1px solid #f0f0f0;
428
+ font-size: 11px;
429
+ }
430
+
431
+ .sf-financial-table .amount-cell {
432
+ text-align: right;
433
+ font-family: 'Courier New', monospace;
434
+ }
435
+
436
+ .sf-financial-table .total-row {
437
+ background: #f0f8ff;
438
+ font-weight: bold;
439
+ }
440
+
441
+ .sf-statement-header {
442
+ background: #f8f9fa;
443
+ padding: 12px;
444
+ border-bottom: 1px solid #ddd;
445
+ margin-top: 20px;
446
+ }
447
+
448
+ .sf-statement-header h4 {
449
+ margin: 0 0 4px 0;
450
+ font-size: 13px;
451
+ color: #333;
452
+ font-weight: bold;
453
+ }
454
+
455
+ .sf-statement-source {
456
+ font-size: 10px;
457
+ color: #666;
458
+ font-style: italic;
459
+ }
460
+
461
+ .sf-tab-content {
462
+ display: none;
463
+ }
464
+
465
+ .sf-tab-content.active {
466
+ display: block;
467
+ }
468
+
469
+ .sf-spread-viewer {
470
+ margin: 20px;
471
+ border: 1px solid #d8dde6;
472
+ border-radius: 4px;
473
+ background: white;
474
+ min-height: 600px;
475
+ overflow: hidden;
476
+ position: relative;
477
+ }
478
+
479
+ .sf-spread-viewer iframe {
480
+ width: calc(100% + 60px);
481
+ height: 800px;
482
+ border: none;
483
+ position: relative;
484
+ left: -60px;
485
+ top: -40px;
486
+ }
487
+
488
+ .sf-no-data {
489
+ text-align: center;
490
+ padding: 60px 20px;
491
+ color: #706e6b;
492
+ }
493
+
494
+ .sf-no-data h3 {
495
+ margin-bottom: 12px;
496
+ font-size: 16px;
497
+ }
498
+
499
+ /* Expand Button */
500
+ .sf-expand-iframe-btn {
501
+ position: absolute;
502
+ top: 10px;
503
+ right: 10px;
504
+ background: oklch(0.26 0.07 284.42);
505
+ color: white;
506
+ border: 1px solid transparent;
507
+ width: 36px;
508
+ height: 36px;
509
+ padding: 0;
510
+ border-radius: 8px;
511
+ cursor: pointer;
512
+ font-size: 18px;
513
+ font-weight: 500;
514
+ font-family: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
515
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
516
+ transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
517
+ z-index: 10;
518
+ outline: none;
519
+ display: flex;
520
+ align-items: center;
521
+ justify-content: center;
522
+ }
523
+
524
+ .sf-expand-iframe-btn:hover {
525
+ background: oklch(0.23 0.07 284.42);
526
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05), 0 0 0 4px oklch(0.26 0.07 284.42 / 0.3);
527
+ }
528
+
529
+ .sf-expand-iframe-btn:focus-visible {
530
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05), 0 0 0 3px oklch(0.26 0.07 284.42 / 0.5);
531
+ border-color: oklch(0.26 0.07 284.42);
532
+ }
533
+
534
+ /* Modal Styles */
535
+ .sf-iframe-modal-overlay {
536
+ position: fixed;
537
+ top: 0;
538
+ left: 0;
539
+ right: 0;
540
+ bottom: 0;
541
+ background: rgba(0, 0, 0, 0.7);
542
+ display: none;
543
+ align-items: center;
544
+ justify-content: center;
545
+ z-index: 10000;
546
+ padding: 20px;
547
+ }
548
+
549
+ .sf-iframe-modal-overlay.active {
550
+ display: flex;
551
+ animation: fadeIn 0.3s ease;
552
+ }
553
+
554
+ @keyframes fadeIn {
555
+ from {
556
+ opacity: 0;
557
+ }
558
+ to {
559
+ opacity: 1;
560
+ }
561
+ }
562
+
563
+
564
+ /* Expanded iframe state */
565
+ .sf-upload-widget {
566
+ transition: all 0.3s ease;
567
+ }
568
+
569
+ .sf-upload-widget.expanded {
570
+ position: fixed !important;
571
+ top: 50% !important;
572
+ left: 50% !important;
573
+ transform: translate(-50%, -50%) !important;
574
+ width: 90vw !important;
575
+ height: 90vh !important;
576
+ max-width: 90vw !important;
577
+ max-height: 90vh !important;
578
+ z-index: 10001 !important;
579
+ margin: 0 !important;
580
+ border-radius: 8px !important;
581
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3) !important;
582
+ display: flex !important;
583
+ flex-direction: column !important;
584
+ animation: modalSlideIn 0.3s ease;
585
+ }
586
+
587
+ .sf-upload-widget.expanded iframe {
588
+ flex: 1 !important;
589
+ height: 100% !important;
590
+ }
591
+
592
+ .sf-spread-viewer {
593
+ transition: all 0.3s ease;
594
+ }
595
+
596
+ .sf-spread-viewer.expanded {
597
+ position: fixed !important;
598
+ top: 50% !important;
599
+ left: 50% !important;
600
+ transform: translate(-50%, -50%) !important;
601
+ width: 90vw !important;
602
+ height: 90vh !important;
603
+ max-width: 90vw !important;
604
+ max-height: 90vh !important;
605
+ z-index: 10001 !important;
606
+ margin: 0 !important;
607
+ border-radius: 8px !important;
608
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3) !important;
609
+ display: flex !important;
610
+ flex-direction: column !important;
611
+ animation: modalSlideIn 0.3s ease;
612
+ }
613
+
614
+ .sf-spread-viewer.expanded iframe {
615
+ flex: 1 !important;
616
+ height: 100% !important;
617
+ }
618
+
619
+ @keyframes modalSlideIn {
620
+ from {
621
+ transform: translate(-50%, -50%) scale(0.95);
622
+ opacity: 0;
623
+ }
624
+ to {
625
+ transform: translate(-50%, -50%) scale(1);
626
+ opacity: 1;
627
+ }
628
+ }
629
+
630
+ /* Hide expand button when expanded */
631
+ .sf-upload-widget.expanded .sf-expand-iframe-btn,
632
+ .sf-spread-viewer.expanded .sf-expand-iframe-btn {
633
+ display: none;
634
+ }
635
+
636
+ /* Close button for expanded state - matches expand button style */
637
+ .sf-expand-close-btn {
638
+ position: absolute;
639
+ top: 10px;
640
+ right: 10px;
641
+ background: oklch(0.26 0.07 284.42);
642
+ color: white;
643
+ border: 1px solid transparent;
644
+ width: 36px;
645
+ height: 36px;
646
+ padding: 0;
647
+ border-radius: 8px;
648
+ cursor: pointer;
649
+ font-size: 18px;
650
+ font-weight: 500;
651
+ font-family: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
652
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
653
+ transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
654
+ z-index: 11;
655
+ outline: none;
656
+ display: none;
657
+ align-items: center;
658
+ justify-content: center;
659
+ }
660
+
661
+ .sf-upload-widget.expanded .sf-expand-close-btn,
662
+ .sf-spread-viewer.expanded .sf-expand-close-btn {
663
+ display: flex;
664
+ }
665
+
666
+ .sf-expand-close-btn:hover {
667
+ background: oklch(0.23 0.07 284.42);
668
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05), 0 0 0 4px oklch(0.26 0.07 284.42 / 0.3);
669
+ }
670
+
671
+ .sf-expand-close-btn:focus-visible {
672
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05), 0 0 0 3px oklch(0.26 0.07 284.42 / 0.5);
673
+ border-color: oklch(0.26 0.07 284.42);
674
+ }
675
+
676
+ /* Import Manrope font */
677
+ @import url('https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700&display=swap');
678
+
679
+ /* Chat Widget Styles */
680
+ .chat-widget-button {
681
+ position: fixed;
682
+ bottom: 20px;
683
+ right: 20px;
684
+ width: 56px;
685
+ height: 56px;
686
+ border-radius: 8px;
687
+ background: oklch(0.26 0.07 284.42);
688
+ border: 1px solid transparent;
689
+ cursor: pointer;
690
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
691
+ transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
692
+ z-index: 10000;
693
+ display: flex;
694
+ align-items: center;
695
+ justify-content: center;
696
+ font-family: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
697
+ outline: none;
698
+ }
699
+
700
+ .chat-widget-button:hover {
701
+ background: oklch(0.23 0.07 284.42);
702
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05), 0 0 0 4px oklch(0.26 0.07 284.42 / 0.3);
703
+ }
704
+
705
+ .chat-widget-button:focus-visible {
706
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05), 0 0 0 3px oklch(0.26 0.07 284.42 / 0.5);
707
+ border-color: oklch(0.26 0.07 284.42);
708
+ }
709
+
710
+ .chat-widget-button.open {
711
+ background: oklch(0.23 0.07 284.42);
712
+ }
713
+
714
+ .chat-widget-button svg {
715
+ width: 28px;
716
+ height: 28px;
717
+ fill: white;
718
+ }
719
+
720
+ .chat-widget-window {
721
+ position: fixed;
722
+ bottom: 90px;
723
+ right: 20px;
724
+ width: 400px;
725
+ height: 600px;
726
+ background: white;
727
+ border-radius: 12px;
728
+ border: 1px solid #e5e7eb;
729
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
730
+ display: none;
731
+ flex-direction: column;
732
+ z-index: 9999;
733
+ overflow: hidden;
734
+ font-family: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
735
+ }
736
+
737
+ .chat-widget-window.open {
738
+ display: flex;
739
+ animation: slideUp 0.3s cubic-bezier(0.4, 0, 0.2, 1);
740
+ }
741
+
742
+ @keyframes slideUp {
743
+ from {
744
+ opacity: 0;
745
+ transform: translateY(10px);
746
+ }
747
+ to {
748
+ opacity: 1;
749
+ transform: translateY(0);
750
+ }
751
+ }
752
+
753
+ .chat-widget-header {
754
+ background: white;
755
+ border-bottom: 1px solid #e5e7eb;
756
+ color: #111827;
757
+ padding: 18px 20px;
758
+ display: flex;
759
+ justify-content: space-between;
760
+ align-items: center;
761
+ min-height: 60px;
762
+ }
763
+
764
+ .chat-widget-title {
765
+ display: flex;
766
+ align-items: center;
767
+ gap: 10px;
768
+ font-weight: 600;
769
+ font-size: 16px;
770
+ color: #111827;
771
+ flex: 1;
772
+ }
773
+
774
+ .chat-widget-title svg {
775
+ width: 22px;
776
+ height: 22px;
777
+ fill: #4f46e5;
778
+ flex-shrink: 0;
779
+ }
780
+
781
+ .chat-widget-header-actions {
782
+ display: flex;
783
+ gap: 12px;
784
+ align-items: center;
785
+ }
786
+
787
+ .chat-widget-sea-link {
788
+ background: none;
789
+ border: none;
790
+ color: #6b7280;
791
+ font-size: 18px;
792
+ cursor: pointer;
793
+ padding: 6px;
794
+ width: 32px;
795
+ height: 32px;
796
+ display: flex;
797
+ align-items: center;
798
+ justify-content: center;
799
+ border-radius: 6px;
800
+ transition: all 0.2s;
801
+ text-decoration: none;
802
+ }
803
+
804
+ .chat-widget-sea-link:hover {
805
+ background: #f3f4f6;
806
+ transform: scale(1.05);
807
+ }
808
+
809
+ .chat-widget-expand {
810
+ background: none;
811
+ border: none;
812
+ color: #6b7280;
813
+ font-size: 20px;
814
+ cursor: pointer;
815
+ padding: 6px;
816
+ width: 32px;
817
+ height: 32px;
818
+ display: flex;
819
+ align-items: center;
820
+ justify-content: center;
821
+ border-radius: 6px;
822
+ transition: all 0.2s;
823
+ }
824
+
825
+ .chat-widget-expand:hover {
826
+ background: #f3f4f6;
827
+ color: #111827;
828
+ }
829
+
830
+ .chat-widget-close {
831
+ background: none;
832
+ border: none;
833
+ color: #6b7280;
834
+ font-size: 22px;
835
+ cursor: pointer;
836
+ width: 32px;
837
+ height: 32px;
838
+ display: flex;
839
+ align-items: center;
840
+ justify-content: center;
841
+ border-radius: 6px;
842
+ transition: all 0.2s;
843
+ }
844
+
845
+ .chat-widget-close:hover {
846
+ background: #f3f4f6;
847
+ color: #111827;
848
+ }
849
+
850
+ .chat-widget-window.expanded {
851
+ width: 600px;
852
+ height: 700px;
853
+ max-height: 85vh;
854
+ }
855
+
856
+ .chat-messages {
857
+ flex: 1;
858
+ overflow-y: auto;
859
+ padding: 20px;
860
+ background: #fafafa;
861
+ display: flex;
862
+ flex-direction: column;
863
+ gap: 12px;
864
+ }
865
+
866
+ .chat-messages::-webkit-scrollbar {
867
+ width: 6px;
868
+ }
869
+
870
+ .chat-messages::-webkit-scrollbar-track {
871
+ background: transparent;
872
+ }
873
+
874
+ .chat-messages::-webkit-scrollbar-thumb {
875
+ background: #d1d5db;
876
+ border-radius: 3px;
877
+ }
878
+
879
+ .chat-messages::-webkit-scrollbar-thumb:hover {
880
+ background: #9ca3af;
881
+ }
882
+
883
+ .chat-message {
884
+ display: flex;
885
+ margin-bottom: 4px;
886
+ }
887
+
888
+ .chat-message.user {
889
+ justify-content: flex-end;
890
+ }
891
+
892
+ .chat-message.assistant {
893
+ justify-content: flex-start;
894
+ }
895
+
896
+ .chat-message-content {
897
+ max-width: 80%;
898
+ padding: 10px 14px;
899
+ border-radius: 8px;
900
+ font-size: 14px;
901
+ line-height: 1.5;
902
+ word-wrap: break-word;
903
+ text-align: left;
904
+ }
905
+
906
+ .chat-message.user .chat-message-content {
907
+ background: oklch(0.26 0.07 284.42);
908
+ color: white;
909
+ border-bottom-right-radius: 4px;
910
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
911
+ }
912
+
913
+ .chat-message.assistant .chat-message-content {
914
+ background: white;
915
+ color: #374151;
916
+ border: 1px solid #e5e7eb;
917
+ border-bottom-left-radius: 4px;
918
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
919
+ }
920
+
921
+ .chat-message-content ul {
922
+ margin: 4px 0 8px 0;
923
+ padding-left: 20px;
924
+ list-style-type: disc;
925
+ }
926
+
927
+ .chat-message-content li {
928
+ margin: 4px 0;
929
+ }
930
+
931
+ .chat-message-content strong {
932
+ font-weight: 600;
933
+ color: inherit;
934
+ }
935
+
936
+ .chat-message-content div {
937
+ margin: 2px 0;
938
+ }
939
+
940
+ .chat-input-container {
941
+ display: flex;
942
+ align-items: flex-end;
943
+ gap: 8px;
944
+ padding: 16px;
945
+ background: white;
946
+ border-top: 1px solid #e5e7eb;
947
+ }
948
+
949
+ .chat-input {
950
+ flex: 1;
951
+ border: 1px solid #d1d5db;
952
+ border-radius: 8px;
953
+ padding: 10px 12px;
954
+ font-size: 14px;
955
+ font-family: 'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
956
+ outline: none;
957
+ transition: all 0.2s;
958
+ background: transparent;
959
+ color: #111827;
960
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
961
+ }
962
+
963
+ .chat-input::placeholder {
964
+ color: #9ca3af;
965
+ }
966
+
967
+ .chat-input:focus {
968
+ border-color: #6366f1;
969
+ box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
970
+ }
971
+
972
+ .chat-send-button {
973
+ width: 36px;
974
+ height: 36px;
975
+ border-radius: 8px;
976
+ background: oklch(0.26 0.07 284.42);
977
+ border: 1px solid transparent;
978
+ color: white;
979
+ cursor: pointer;
980
+ display: flex;
981
+ align-items: center;
982
+ justify-content: center;
983
+ transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
984
+ flex-shrink: 0;
985
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
986
+ outline: none;
987
+ }
988
+
989
+ .chat-send-button:hover:not(:disabled) {
990
+ background: oklch(0.23 0.07 284.42);
991
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05), 0 0 0 4px oklch(0.26 0.07 284.42 / 0.3);
992
+ }
993
+
994
+ .chat-send-button:focus-visible {
995
+ box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05), 0 0 0 3px oklch(0.26 0.07 284.42 / 0.5);
996
+ border-color: oklch(0.26 0.07 284.42);
997
+ }
998
+
999
+ .chat-send-button:disabled {
1000
+ opacity: 0.5;
1001
+ cursor: not-allowed;
1002
+ }
1003
+
1004
+ .chat-send-button svg {
1005
+ width: 18px;
1006
+ height: 18px;
1007
+ fill: white;
1008
+ }
1009
+
1010
+ .chat-loading {
1011
+ display: flex;
1012
+ gap: 4px;
1013
+ padding: 10px 14px;
1014
+ }
1015
+
1016
+ /* User Menu Dropdown */
1017
+ .sf-user-menu {
1018
+ position: relative;
1019
+ }
1020
+
1021
+ .sf-user-dropdown {
1022
+ position: absolute;
1023
+ top: 100%;
1024
+ right: 0;
1025
+ background: white;
1026
+ border: 1px solid #d8dde6;
1027
+ border-radius: 4px;
1028
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
1029
+ min-width: 250px;
1030
+ margin-top: 5px;
1031
+ display: none;
1032
+ z-index: 1000;
1033
+ }
1034
+
1035
+ .sf-user-dropdown.active {
1036
+ display: block;
1037
+ }
1038
+
1039
+ .sf-user-dropdown-header {
1040
+ padding: 12px 15px;
1041
+ border-bottom: 1px solid #d8dde6;
1042
+ font-weight: 600;
1043
+ font-size: 12px;
1044
+ color: #080707;
1045
+ }
1046
+
1047
+ .sf-user-dropdown-item {
1048
+ padding: 10px 15px;
1049
+ cursor: pointer;
1050
+ transition: background 0.2s;
1051
+ display: flex;
1052
+ align-items: center;
1053
+ gap: 10px;
1054
+ font-size: 13px;
1055
+ }
1056
+
1057
+ .sf-user-dropdown-item:hover {
1058
+ background: #f4f6f9;
1059
+ }
1060
+
1061
+ .sf-user-dropdown-item input[type="checkbox"] {
1062
+ cursor: pointer;
1063
+ }
1064
+
1065
+ .sf-user-dropdown-item label {
1066
+ cursor: pointer;
1067
+ flex: 1;
1068
+ }
1069
+
1070
+ /* Collapsed Account Details */
1071
+ .sf-section.collapsed {
1072
+ max-height: 0;
1073
+ overflow: hidden;
1074
+ opacity: 0;
1075
+ margin: 0;
1076
+ padding: 0;
1077
+ border: none;
1078
+ transition: all 0.3s ease;
1079
+ }
1080
+
1081
+ .sf-section:not(.collapsed) {
1082
+ max-height: 1000px;
1083
+ opacity: 1;
1084
+ transition: all 0.3s ease;
1085
+ }
1086
+
1087
+ .chat-loading-dot {
1088
+ width: 8px;
1089
+ height: 8px;
1090
+ border-radius: 50%;
1091
+ background: #9ca3af;
1092
+ animation: chatDotPulse 1.4s infinite both;
1093
+ }
1094
+
1095
+ .chat-loading-dot:nth-child(2) {
1096
+ animation-delay: 0.2s;
1097
+ }
1098
+
1099
+ .chat-loading-dot:nth-child(3) {
1100
+ animation-delay: 0.4s;
1101
+ }
1102
+
1103
+ @keyframes chatDotPulse {
1104
+ 0%, 80%, 100% {
1105
+ opacity: 0.3;
1106
+ transform: scale(0.8);
1107
+ }
1108
+ 40% {
1109
+ opacity: 1;
1110
+ transform: scale(1);
1111
+ }
1112
+ }
1113
+ </style>
1114
+ </head>
1115
+ <body>
1116
+ <!-- Top Navigation -->
1117
+ <div class="sf-header">
1118
+ <div class="sf-logo">LOS</div>
1119
+ <div class="sf-nav">
1120
+ <div class="sf-nav-item">Home</div>
1121
+ <div class="sf-nav-item active">Accounts</div>
1122
+ <div class="sf-nav-item">Contacts</div>
1123
+ <div class="sf-nav-item">Opportunities</div>
1124
+ <div class="sf-nav-item">Financial Accounts</div>
1125
+ <div class="sf-nav-item">Leads</div>
1126
+ <div class="sf-nav-item">Reports</div>
1127
+ <div class="sf-nav-item">+</div>
1128
+ </div>
1129
+ <div class="sf-user-menu">
1130
+ <span onclick="toggleUserMenu()" style="cursor: pointer;">John Smith</span>
1131
+ <span onclick="toggleUserMenu()" style="cursor: pointer;">▼</span>
1132
+ <div class="sf-user-dropdown" id="userDropdown">
1133
+ <div class="sf-user-dropdown-header">Demo Settings</div>
1134
+ <div class="sf-user-dropdown-item" onclick="event.stopPropagation();">
1135
+ <input type="checkbox" id="embeddedToggle" onchange="toggleEmbedded()" checked>
1136
+ <label for="embeddedToggle">Embedded Features</label>
1137
+ </div>
1138
+ <div class="sf-user-dropdown-item" onclick="event.stopPropagation();">
1139
+ <input type="checkbox" id="inputFinancialsToggle" onchange="toggleInputFinancials()">
1140
+ <label for="inputFinancialsToggle">Input Financials</label>
1141
+ </div>
1142
+ </div>
1143
+ </div>
1144
+ </div>
1145
+
1146
+ <!-- Sub Navigation -->
1147
+ <div class="sf-sub-nav">
1148
+ <div class="sf-breadcrumb">Home > Accounts > Enterprise Financial Group</div>
1149
+ <input type="text" class="sf-search" placeholder="Search Legacy LOS..." />
1150
+ </div>
1151
+
1152
+ <!-- Main Content -->
1153
+ <div class="sf-container">
1154
+ <!-- Page Header -->
1155
+ <div class="sf-page-header">
1156
+ <div class="sf-page-title">
1157
+ <div class="sf-icon">🏢</div>
1158
+ <div class="sf-title-text">
1159
+ <h1>Enterprise Financial Group</h1>
1160
+ <div class="subtitle">Account • Customer - Direct</div>
1161
+ </div>
1162
+ </div>
1163
+ <div class="sf-actions">
1164
+ <button class="sf-button">Follow</button>
1165
+ <button class="sf-button">Edit</button>
1166
+ <button class="sf-button">Delete</button>
1167
+ <button class="sf-button-primary">New Opportunity</button>
1168
+ </div>
1169
+ </div>
1170
+
1171
+ <!-- Content Grid -->
1172
+ <div class="sf-content" id="mainContent">
1173
+ <!-- Left Column - Main Content -->
1174
+ <div>
1175
+ <!-- Account Details -->
1176
+ <div class="sf-section" id="accountDetailsSection">
1177
+ <div class="sf-section-header">Account Details</div>
1178
+ <div class="sf-section-body">
1179
+ <div class="sf-field-row">
1180
+ <div class="sf-field">
1181
+ <div class="sf-field-label">Account Name</div>
1182
+ <div class="sf-field-value">Enterprise Financial Group</div>
1183
+ </div>
1184
+ <div class="sf-field">
1185
+ <div class="sf-field-label">Account Owner</div>
1186
+ <div class="sf-field-value"><a href="#" class="sf-link">John Smith</a></div>
1187
+ </div>
1188
+ </div>
1189
+ <div class="sf-field-row">
1190
+ <div class="sf-field">
1191
+ <div class="sf-field-label">Type</div>
1192
+ <div class="sf-field-value">Customer - Direct</div>
1193
+ </div>
1194
+ <div class="sf-field">
1195
+ <div class="sf-field-label">Industry</div>
1196
+ <div class="sf-field-value">Financial Services</div>
1197
+ </div>
1198
+ </div>
1199
+ <div class="sf-field-row">
1200
+ <div class="sf-field">
1201
+ <div class="sf-field-label">Phone</div>
1202
+ <div class="sf-field-value">(415) 555-0123</div>
1203
+ </div>
1204
+ <div class="sf-field">
1205
+ <div class="sf-field-label">Annual Revenue</div>
1206
+ <div class="sf-field-value">$45,000,000</div>
1207
+ </div>
1208
+ </div>
1209
+ <div class="sf-field-row">
1210
+ <div class="sf-field">
1211
+ <div class="sf-field-label">Billing Address</div>
1212
+ <div class="sf-field-value">123 Market Street<br>San Francisco, CA 94105</div>
1213
+ </div>
1214
+ <div class="sf-field">
1215
+ <div class="sf-field-label">Website</div>
1216
+ <div class="sf-field-value"><a href="#" class="sf-link">www.enterprisefinancial.com</a></div>
1217
+ </div>
1218
+ </div>
1219
+ </div>
1220
+ </div>
1221
+
1222
+ <!-- Related Lists -->
1223
+ <div class="sf-section" style="margin-top: 15px;">
1224
+ <div class="sf-tabs">
1225
+ <div class="sf-tab active" onclick="switchMainTab('opportunities')">Opportunities</div>
1226
+ <div class="sf-tab" onclick="switchMainTab('contacts')">Contacts</div>
1227
+ <div class="sf-tab" onclick="switchMainTab('cases')">Cases</div>
1228
+ <div class="sf-tab" onclick="switchMainTab('activity')">Activity</div>
1229
+ <div class="sf-tab" onclick="switchMainTab('notes')">Notes & Attachments</div>
1230
+ <div class="sf-tab" onclick="switchMainTab('financials')">Financials</div>
1231
+ </div>
1232
+
1233
+ <!-- Opportunities Tab Content -->
1234
+ <div id="opportunities-content" class="sf-tab-content active">
1235
+ <div class="sf-section-body">
1236
+ <table class="sf-table">
1237
+ <thead>
1238
+ <tr>
1239
+ <th>Opportunity Name</th>
1240
+ <th>Stage</th>
1241
+ <th>Amount</th>
1242
+ <th>Close Date</th>
1243
+ <th>Probability</th>
1244
+ </tr>
1245
+ </thead>
1246
+ <tbody>
1247
+ <tr>
1248
+ <td><a href="#" class="sf-link">Wealth Management Platform</a></td>
1249
+ <td><span class="sf-status-badge status-open">Negotiation/Review</span></td>
1250
+ <td>$250,000</td>
1251
+ <td>03/15/2024</td>
1252
+ <td>75%</td>
1253
+ </tr>
1254
+ <tr>
1255
+ <td><a href="#" class="sf-link">Investment Portfolio System</a></td>
1256
+ <td><span class="sf-status-badge status-pending">Proposal/Price Quote</span></td>
1257
+ <td>$180,000</td>
1258
+ <td>04/30/2024</td>
1259
+ <td>50%</td>
1260
+ </tr>
1261
+ <tr>
1262
+ <td><a href="#" class="sf-link">Risk Assessment Tools</a></td>
1263
+ <td><span class="sf-status-badge status-closed">Closed Won</span></td>
1264
+ <td>$320,000</td>
1265
+ <td>01/20/2024</td>
1266
+ <td>100%</td>
1267
+ </tr>
1268
+ </tbody>
1269
+ </table>
1270
+ </div>
1271
+ </div>
1272
+
1273
+ <!-- Contacts Tab Content -->
1274
+ <div id="contacts-content" class="sf-tab-content">
1275
+ <div class="sf-section-body">
1276
+ <p>Contacts content goes here...</p>
1277
+ </div>
1278
+ </div>
1279
+
1280
+ <!-- Cases Tab Content -->
1281
+ <div id="cases-content" class="sf-tab-content">
1282
+ <div class="sf-section-body">
1283
+ <p>Cases content goes here...</p>
1284
+ </div>
1285
+ </div>
1286
+
1287
+ <!-- Activity Tab Content -->
1288
+ <div id="activity-content" class="sf-tab-content">
1289
+ <div class="sf-section-body">
1290
+ <p>Activity content goes here...</p>
1291
+ </div>
1292
+ </div>
1293
+
1294
+ <!-- Notes Tab Content -->
1295
+ <div id="notes-content" class="sf-tab-content">
1296
+ <div class="sf-section-body">
1297
+ <p>Notes & Attachments content goes here...</p>
1298
+ </div>
1299
+ </div>
1300
+
1301
+ <!-- Financials Tab Content -->
1302
+ <div id="financials-content" class="sf-tab-content">
1303
+ <!-- Financial Sub-Tabs -->
1304
+ <div class="sf-financial-tabs">
1305
+ <div class="sf-financial-tab active" onclick="switchFinancialTab('ai')">AI Financials</div>
1306
+ <div class="sf-financial-tab" onclick="switchFinancialTab('input')">Input Financials</div>
1307
+ <div class="sf-financial-tab" onclick="switchFinancialTab('analysis')">Financial Analysis</div>
1308
+ </div>
1309
+
1310
+ <!-- AI Financials Tab Content -->
1311
+ <div id="ai-content" class="sf-tab-content active">
1312
+ <div id="upload-widget" class="sf-upload-widget" style="margin: 0; border: none; border-radius: 0; min-height: 700px;">
1313
+ <button class="sf-expand-iframe-btn" onclick="expandIframe()" title="Expand">⛶</button>
1314
+ <button class="sf-expand-close-btn" onclick="closeIframeModal()">×</button>
1315
+ <iframe
1316
+ src="https://app.sea.dev/deals/28eq483grdz4gbfkhsili/j62iaw4d5piudvlnjexzi"
1317
+ allow="clipboard-write; clipboard-read">
1318
+ </iframe>
1319
+ </div>
1320
+ </div>
1321
+
1322
+ <!-- Input Financials Tab Content -->
1323
+ <div id="input-content" class="sf-tab-content">
1324
+ <div style="padding: 20px;">
1325
+ <!-- Top Section: Requirements in Left/Right Panels -->
1326
+ <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 20px; margin-bottom: 20px;">
1327
+ <!-- Left Panel: Required Documents -->
1328
+ <div style="background: #fff3cd; border: 1px solid #ffc107; border-radius: 4px; padding: 15px;">
1329
+ <h4 style="margin: 0 0 10px 0; color: #856404; font-size: 14px; font-weight: 600;">Required Documents</h4>
1330
+ <ul style="margin: 0; padding-left: 20px; color: #856404; font-size: 12px; line-height: 1.8;">
1331
+ <li>Balance Sheet (most recent fiscal year-end)</li>
1332
+ <li>Income Statement / Profit & Loss (last 3 years)</li>
1333
+ <li>Cash Flow Statement (last 3 years)</li>
1334
+ <li>Tax Returns (last 2 years, all schedules)</li>
1335
+ <li>Accounts Receivable Aging Report</li>
1336
+ <li>Accounts Payable Aging Report</li>
1337
+ <li>Inventory Report (if applicable)</li>
1338
+ </ul>
1339
+ </div>
1340
+
1341
+ <!-- Right Panel: Data Entry Requirements -->
1342
+ <div style="background: #f8f9fa; border: 1px solid #dee2e6; border-radius: 4px; padding: 15px;">
1343
+ <h4 style="margin: 0 0 10px 0; font-size: 14px; font-weight: 600;">Data Entry Requirements</h4>
1344
+ <ul style="margin: 0; padding-left: 20px; font-size: 11px; line-height: 1.8; color: #495057;">
1345
+ <li>All amounts must be entered in whole dollars (no cents)</li>
1346
+ <li>Negative values must be entered with parentheses, e.g., (5000)</li>
1347
+ <li>Do not include currency symbols ($, €, etc.)</li>
1348
+ <li>Separate thousands with commas (e.g., 1,000,000)</li>
1349
+ <li>Percentages must be entered as decimals (e.g., 0.15 for 15%)</li>
1350
+ <li>All fields marked with * are required</li>
1351
+ <li>Data must match supporting documentation exactly</li>
1352
+ <li>Contact CFO if discrepancies exceed $500</li>
1353
+ </ul>
1354
+ </div>
1355
+ </div>
1356
+
1357
+ <!-- Bottom Section: Data Entry Forms -->
1358
+
1359
+ <!-- Balance Sheet Section -->
1360
+ <div style="border: 1px solid #d8dde6; border-radius: 4px; margin-bottom: 20px; overflow: hidden;">
1361
+ <div style="background: #fafaf9; border-bottom: 1px solid #d8dde6; padding: 12px 15px; font-weight: 600;">
1362
+ Balance Sheet (Year-End)
1363
+ </div>
1364
+ <div style="padding: 15px;">
1365
+ <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px; margin-bottom: 15px;">
1366
+ <div>
1367
+ <label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px; font-weight: 600;">FISCAL YEAR END DATE *</label>
1368
+ <input type="date" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
1369
+ </div>
1370
+ <div>
1371
+ <label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px; font-weight: 600;">REPORTING CURRENCY *</label>
1372
+ <select style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;">
1373
+ <option>USD</option>
1374
+ <option>EUR</option>
1375
+ <option>GBP</option>
1376
+ </select>
1377
+ </div>
1378
+ </div>
1379
+
1380
+ <h5 style="margin: 15px 0 10px 0; font-size: 12px; color: #080707; font-weight: 600;">Current Assets</h5>
1381
+ <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px;">
1382
+ <div>
1383
+ <label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px;">Cash and Cash Equivalents *</label>
1384
+ <input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
1385
+ </div>
1386
+ <div>
1387
+ <label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px;">Accounts Receivable *</label>
1388
+ <input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
1389
+ </div>
1390
+ <div>
1391
+ <label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px;">Inventory</label>
1392
+ <input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
1393
+ </div>
1394
+ <div>
1395
+ <label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px;">Prepaid Expenses</label>
1396
+ <input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
1397
+ </div>
1398
+ <div>
1399
+ <label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px;">Other Current Assets</label>
1400
+ <input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
1401
+ </div>
1402
+ <div>
1403
+ <label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px; font-weight: 600;">TOTAL CURRENT ASSETS *</label>
1404
+ <input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px; background: #fafaf9; font-weight: 600;" readonly />
1405
+ </div>
1406
+ </div>
1407
+
1408
+ <h5 style="margin: 15px 0 10px 0; font-size: 12px; color: #080707; font-weight: 600;">Fixed Assets</h5>
1409
+ <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px;">
1410
+ <div>
1411
+ <label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px;">Property, Plant & Equipment *</label>
1412
+ <input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
1413
+ </div>
1414
+ <div>
1415
+ <label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px;">Accumulated Depreciation *</label>
1416
+ <input type="text" placeholder="(0)" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
1417
+ </div>
1418
+ <div>
1419
+ <label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px;">Intangible Assets</label>
1420
+ <input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
1421
+ </div>
1422
+ <div>
1423
+ <label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px;">Goodwill</label>
1424
+ <input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
1425
+ </div>
1426
+ </div>
1427
+ </div>
1428
+ </div>
1429
+
1430
+ <!-- Income Statement Section -->
1431
+ <div style="border: 1px solid #d8dde6; border-radius: 4px; margin-bottom: 20px; overflow: hidden;">
1432
+ <div style="background: #fafaf9; border-bottom: 1px solid #d8dde6; padding: 12px 15px; font-weight: 600;">
1433
+ Income Statement (Year-End)
1434
+ </div>
1435
+ <div style="padding: 15px;">
1436
+ <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 15px;">
1437
+ <div style="grid-column: 1 / -1;">
1438
+ <label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px; font-weight: 600;">FINANCIAL PERIOD *</label>
1439
+ <input type="text" placeholder="e.g., Q4 2023, FY 2023, Jan 2024" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
1440
+ <div style="font-size: 10px; color: #706e6b; margin-top: 4px;">The relevant financial period. Typically month or quarter.</div>
1441
+ </div>
1442
+
1443
+ <div>
1444
+ <label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px; font-weight: 600;">REVENUE *</label>
1445
+ <input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
1446
+ <div style="font-size: 10px; color: #706e6b; margin-top: 4px;">Total income generated from normal business operations</div>
1447
+ </div>
1448
+ <div>
1449
+ <label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px;">REFUNDS</label>
1450
+ <input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
1451
+ <div style="font-size: 10px; color: #706e6b; margin-top: 4px;">Any indication of refunds from the income statement</div>
1452
+ </div>
1453
+
1454
+ <div>
1455
+ <label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px; font-weight: 600;">COGS (Cost of Goods Sold) *</label>
1456
+ <input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
1457
+ <div style="font-size: 10px; color: #706e6b; margin-top: 4px;">Direct costs of producing goods sold; includes materials and labor</div>
1458
+ </div>
1459
+ <div>
1460
+ <label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px; font-weight: 600;">SG&A (Selling, General & Admin) *</label>
1461
+ <input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
1462
+ <div style="font-size: 10px; color: #706e6b; margin-top: 4px;">Overhead and operating expenses not tied to production</div>
1463
+ </div>
1464
+
1465
+ <div>
1466
+ <label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px; font-weight: 600;">EBIT *</label>
1467
+ <input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px; background: #fafaf9; font-weight: 600;" readonly />
1468
+ <div style="font-size: 10px; color: #706e6b; margin-top: 4px;">Calculate as gross profit minus SG&A, then subtract other expenses</div>
1469
+ </div>
1470
+ <div>
1471
+ <label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px; font-weight: 600;">EBITDA *</label>
1472
+ <input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px; background: #fafaf9; font-weight: 600;" readonly />
1473
+ <div style="font-size: 10px; color: #706e6b; margin-top: 4px;">Earnings before interest, taxes, depreciation, and amortization</div>
1474
+ </div>
1475
+
1476
+ <div>
1477
+ <label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px; font-weight: 600;">ADJUSTED EBITDA *</label>
1478
+ <input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px;" />
1479
+ <div style="font-size: 10px; color: #706e6b; margin-top: 4px;">Permitted add-backs to normalise for one-time expenses</div>
1480
+ </div>
1481
+ <div>
1482
+ <label style="display: block; font-size: 11px; color: #706e6b; margin-bottom: 4px; font-weight: 600;">NET INCOME *</label>
1483
+ <input type="text" placeholder="0" style="width: 100%; padding: 8px; border: 1px solid #d8dde6; border-radius: 3px; font-size: 13px; background: #fafaf9; font-weight: 600;" readonly />
1484
+ <div style="font-size: 10px; color: #706e6b; margin-top: 4px;">Total profit of the company after all expenses and taxes</div>
1485
+ </div>
1486
+ </div>
1487
+ </div>
1488
+ </div>
1489
+
1490
+ <!-- Action Buttons -->
1491
+ <div style="display: flex; gap: 10px; justify-content: flex-end; padding-top: 10px;">
1492
+ <button class="sf-button">Cancel</button>
1493
+ <button class="sf-button">Save Draft</button>
1494
+ <button class="sf-button-primary">Submit for Review</button>
1495
+ </div>
1496
+ </div>
1497
+ </div>
1498
+
1499
+ <!-- Financial Analysis Tab Content -->
1500
+ <div id="analysis-content" class="sf-tab-content">
1501
+ <!-- Error State when AI is turned off -->
1502
+ <div id="analysis-error-state" style="display: none; padding: 60px 20px; text-align: center;">
1503
+ <div style="max-width: 500px; margin: 0 auto;">
1504
+ <svg width="120" height="120" viewBox="0 0 120 120" style="margin-bottom: 24px;">
1505
+ <circle cx="60" cy="60" r="50" fill="none" stroke="#c23934" stroke-width="3"/>
1506
+ <path d="M60 35 L60 65 M60 75 L60 85" stroke="#c23934" stroke-width="6" stroke-linecap="round"/>
1507
+ </svg>
1508
+ <h3 style="font-size: 20px; font-weight: 600; color: #080707; margin-bottom: 12px;">Financial Analysis Unavailable</h3>
1509
+ <p style="font-size: 14px; color: #706e6b; line-height: 1.6; margin-bottom: 24px;">
1510
+ Please complete the financial data entry in the <strong>Input Financials</strong> tab to generate automated analysis and insights.
1511
+ </p>
1512
+ <button class="sf-button-primary" onclick="switchFinancialTab('input')" style="font-size: 13px;">
1513
+ Go to Input Financials
1514
+ </button>
1515
+ </div>
1516
+ </div>
1517
+
1518
+ <!-- Actual Analysis Content -->
1519
+ <div id="analysis-actual-content" style="padding: 20px;">
1520
+ <!-- Overall Assessment at Top -->
1521
+ <div style="background: #e0f3ff; border: 1px solid #b3d9f2; border-radius: 4px; padding: 15px; margin-bottom: 20px;">
1522
+ <h4 style="margin: 0 0 10px 0; color: #014486; font-size: 14px; font-weight: 600;">Overall Lending Assessment</h4>
1523
+ <div style="font-size: 12px; color: #080707; line-height: 1.8;">
1524
+ <strong>Credit Decision:</strong> <span style="color: #2e844a; font-weight: 600;">APPROVED - Strong Candidate</span><br>
1525
+ <strong>Risk Rating:</strong> Low to Moderate<br>
1526
+ <strong>Key Strengths:</strong> Excellent liquidity, strong debt service coverage, healthy profitability margins<br>
1527
+ <strong>Considerations:</strong> Debt-to-Equity ratio is at upper acceptable range; recommend monitoring leverage trends
1528
+ </div>
1529
+ </div>
1530
+
1531
+ <!-- Metrics Dashboard Grid -->
1532
+ <div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 15px;">
1533
+ <!-- Current Ratio Card -->
1534
+ <div style="border: 1px solid #d8dde6; border-radius: 4px; padding: 15px; background: white; display: flex; justify-content: space-between; align-items: center; gap: 15px;">
1535
+ <div style="flex: 0 0 50%;">
1536
+ <div style="font-size: 11px; color: #706e6b; margin-bottom: 4px; text-transform: uppercase; font-weight: 600;">Current Ratio</div>
1537
+ <div style="font-size: 24px; font-weight: 600; color: #080707; margin-bottom: 8px;">2.1</div>
1538
+ <div style="font-size: 10px; color: #2e844a; font-weight: 600; margin-bottom: 8px;">15% above industry standard</div>
1539
+ <span style="background: #c9f2c7; color: #2e844a; padding: 4px 8px; border-radius: 3px; font-size: 11px; font-weight: 600;">PASS</span>
1540
+ </div>
1541
+ <div style="flex: 0 0 50%; height: 60px;">
1542
+ <svg width="100%" height="100%" viewBox="0 0 135 60" style="display: block;">
1543
+ <polyline points="0,45 25,42 50,48 75,37 100,30" fill="none" stroke="#2e844a" stroke-width="2"/>
1544
+ <circle cx="0" cy="45" r="2" fill="#2e844a"/>
1545
+ <circle cx="25" cy="42" r="2" fill="#2e844a"/>
1546
+ <circle cx="50" cy="48" r="2" fill="#2e844a"/>
1547
+ <circle cx="75" cy="37" r="2" fill="#2e844a"/>
1548
+ <circle cx="100" cy="30" r="3" fill="#2e844a"/>
1549
+ <text x="105" y="30" font-size="10" fill="#2e844a" alignment-baseline="middle" font-weight="600">2.1</text>
1550
+ </svg>
1551
+ </div>
1552
+ </div>
1553
+
1554
+ <!-- Quick Ratio Card -->
1555
+ <div style="border: 1px solid #d8dde6; border-radius: 4px; padding: 15px; background: white; display: flex; justify-content: space-between; align-items: center; gap: 15px;">
1556
+ <div style="flex: 0 0 50%;">
1557
+ <div style="font-size: 11px; color: #706e6b; margin-bottom: 4px; text-transform: uppercase; font-weight: 600;">Quick Ratio</div>
1558
+ <div style="font-size: 24px; font-weight: 600; color: #080707; margin-bottom: 8px;">1.8</div>
1559
+ <div style="font-size: 10px; color: #2e844a; font-weight: 600; margin-bottom: 8px;">12% above industry standard</div>
1560
+ <span style="background: #c9f2c7; color: #2e844a; padding: 4px 8px; border-radius: 3px; font-size: 11px; font-weight: 600;">PASS</span>
1561
+ </div>
1562
+ <div style="flex: 0 0 50%; height: 60px;">
1563
+ <svg width="100%" height="100%" viewBox="0 0 135 60" style="display: block;">
1564
+ <polyline points="0,48 25,45 50,42 75,36 100,33" fill="none" stroke="#2e844a" stroke-width="2"/>
1565
+ <circle cx="0" cy="48" r="2" fill="#2e844a"/>
1566
+ <circle cx="25" cy="45" r="2" fill="#2e844a"/>
1567
+ <circle cx="50" cy="42" r="2" fill="#2e844a"/>
1568
+ <circle cx="75" cy="36" r="2" fill="#2e844a"/>
1569
+ <circle cx="100" cy="33" r="3" fill="#2e844a"/>
1570
+ <text x="105" y="33" font-size="10" fill="#2e844a" alignment-baseline="middle" font-weight="600">1.8</text>
1571
+ </svg>
1572
+ </div>
1573
+ </div>
1574
+
1575
+ <!-- Debt-to-Equity Card -->
1576
+ <div style="border: 1px solid #d8dde6; border-radius: 4px; padding: 15px; background: white; display: flex; justify-content: space-between; align-items: center; gap: 15px;">
1577
+ <div style="flex: 0 0 50%;">
1578
+ <div style="font-size: 11px; color: #706e6b; margin-bottom: 4px; text-transform: uppercase; font-weight: 600;">Debt-to-Equity</div>
1579
+ <div style="font-size: 24px; font-weight: 600; color: #080707; margin-bottom: 8px;">1.9</div>
1580
+ <div style="font-size: 10px; color: #ca8a04; font-weight: 600; margin-bottom: 8px;">10% below industry standard</div>
1581
+ <span style="background: #ffd351; color: #514f4d; padding: 4px 8px; border-radius: 3px; font-size: 11px; font-weight: 600;">REVIEW</span>
1582
+ </div>
1583
+ <div style="flex: 0 0 50%; height: 60px;">
1584
+ <svg width="100%" height="100%" viewBox="0 0 135 60" style="display: block;">
1585
+ <polyline points="0,52 25,45 50,42 75,39 100,33" fill="none" stroke="#ca8a04" stroke-width="2"/>
1586
+ <circle cx="0" cy="52" r="2" fill="#ca8a04"/>
1587
+ <circle cx="25" cy="45" r="2" fill="#ca8a04"/>
1588
+ <circle cx="50" cy="42" r="2" fill="#ca8a04"/>
1589
+ <circle cx="75" cy="39" r="2" fill="#ca8a04"/>
1590
+ <circle cx="100" cy="33" r="3" fill="#ca8a04"/>
1591
+ <text x="105" y="33" font-size="10" fill="#ca8a04" alignment-baseline="middle" font-weight="600">1.9</text>
1592
+ </svg>
1593
+ </div>
1594
+ </div>
1595
+
1596
+ <!-- Debt-to-EBITDA Card -->
1597
+ <div style="border: 1px solid #d8dde6; border-radius: 4px; padding: 15px; background: white; display: flex; justify-content: space-between; align-items: center; gap: 15px;">
1598
+ <div style="flex: 0 0 50%;">
1599
+ <div style="font-size: 11px; color: #706e6b; margin-bottom: 4px; text-transform: uppercase; font-weight: 600;">Debt-to-EBITDA</div>
1600
+ <div style="font-size: 24px; font-weight: 600; color: #080707; margin-bottom: 8px;">2.8</div>
1601
+ <div style="font-size: 10px; color: #706e6b; font-weight: 600; margin-bottom: 8px;">At industry standard</div>
1602
+ <span style="background: #c9f2c7; color: #2e844a; padding: 4px 8px; border-radius: 3px; font-size: 11px; font-weight: 600;">PASS</span>
1603
+ </div>
1604
+ <div style="flex: 0 0 50%; height: 60px;">
1605
+ <svg width="100%" height="100%" viewBox="0 0 135 60" style="display: block;">
1606
+ <polyline points="0,22 25,30 50,37 75,40 100,36" fill="none" stroke="#2e844a" stroke-width="2"/>
1607
+ <circle cx="0" cy="22" r="2" fill="#2e844a"/>
1608
+ <circle cx="25" cy="30" r="2" fill="#2e844a"/>
1609
+ <circle cx="50" cy="37" r="2" fill="#2e844a"/>
1610
+ <circle cx="75" cy="40" r="2" fill="#2e844a"/>
1611
+ <circle cx="100" cy="36" r="3" fill="#2e844a"/>
1612
+ <text x="105" y="36" font-size="10" fill="#2e844a" alignment-baseline="middle" font-weight="600">2.8</text>
1613
+ </svg>
1614
+ </div>
1615
+ </div>
1616
+
1617
+ <!-- DSCR Card -->
1618
+ <div style="border: 1px solid #d8dde6; border-radius: 4px; padding: 15px; background: white; display: flex; justify-content: space-between; align-items: center; gap: 15px;">
1619
+ <div style="flex: 0 0 50%;">
1620
+ <div style="font-size: 11px; color: #706e6b; margin-bottom: 4px; text-transform: uppercase; font-weight: 600;">DSCR</div>
1621
+ <div style="font-size: 24px; font-weight: 600; color: #080707; margin-bottom: 8px;">1.45</div>
1622
+ <div style="font-size: 10px; color: #2e844a; font-weight: 600; margin-bottom: 8px;">20% above industry standard</div>
1623
+ <span style="background: #c9f2c7; color: #2e844a; padding: 4px 8px; border-radius: 3px; font-size: 11px; font-weight: 600;">PASS</span>
1624
+ </div>
1625
+ <div style="flex: 0 0 50%; height: 60px;">
1626
+ <svg width="100%" height="100%" viewBox="0 0 135 60" style="display: block;">
1627
+ <polyline points="0,45 25,48 50,42 75,39 100,30" fill="none" stroke="#2e844a" stroke-width="2"/>
1628
+ <circle cx="0" cy="45" r="2" fill="#2e844a"/>
1629
+ <circle cx="25" cy="48" r="2" fill="#2e844a"/>
1630
+ <circle cx="50" cy="42" r="2" fill="#2e844a"/>
1631
+ <circle cx="75" cy="39" r="2" fill="#2e844a"/>
1632
+ <circle cx="100" cy="30" r="3" fill="#2e844a"/>
1633
+ <text x="105" y="30" font-size="10" fill="#2e844a" alignment-baseline="middle" font-weight="600">1.45</text>
1634
+ </svg>
1635
+ </div>
1636
+ </div>
1637
+
1638
+ <!-- Interest Coverage Card -->
1639
+ <div style="border: 1px solid #d8dde6; border-radius: 4px; padding: 15px; background: white; display: flex; justify-content: space-between; align-items: center; gap: 15px;">
1640
+ <div style="flex: 0 0 50%;">
1641
+ <div style="font-size: 11px; color: #706e6b; margin-bottom: 4px; text-transform: uppercase; font-weight: 600;">Interest Coverage</div>
1642
+ <div style="font-size: 24px; font-weight: 600; color: #080707; margin-bottom: 8px;">5.2</div>
1643
+ <div style="font-size: 10px; color: #2e844a; font-weight: 600; margin-bottom: 8px;">30% above industry standard</div>
1644
+ <span style="background: #c9f2c7; color: #2e844a; padding: 4px 8px; border-radius: 3px; font-size: 11px; font-weight: 600;">PASS</span>
1645
+ </div>
1646
+ <div style="flex: 0 0 50%; height: 60px;">
1647
+ <svg width="100%" height="100%" viewBox="0 0 135 60" style="display: block;">
1648
+ <polyline points="0,42 25,39 50,45 75,36 100,27" fill="none" stroke="#2e844a" stroke-width="2"/>
1649
+ <circle cx="0" cy="42" r="2" fill="#2e844a"/>
1650
+ <circle cx="25" cy="39" r="2" fill="#2e844a"/>
1651
+ <circle cx="50" cy="45" r="2" fill="#2e844a"/>
1652
+ <circle cx="75" cy="36" r="2" fill="#2e844a"/>
1653
+ <circle cx="100" cy="27" r="3" fill="#2e844a"/>
1654
+ <text x="105" y="27" font-size="10" fill="#2e844a" alignment-baseline="middle" font-weight="600">5.2</text>
1655
+ </svg>
1656
+ </div>
1657
+ </div>
1658
+
1659
+ <!-- Net Profit Margin Card -->
1660
+ <div style="border: 1px solid #d8dde6; border-radius: 4px; padding: 15px; background: white; display: flex; justify-content: space-between; align-items: center; gap: 15px;">
1661
+ <div style="flex: 0 0 50%;">
1662
+ <div style="font-size: 11px; color: #706e6b; margin-bottom: 4px; text-transform: uppercase; font-weight: 600;">Net Profit Margin</div>
1663
+ <div style="font-size: 24px; font-weight: 600; color: #080707; margin-bottom: 8px;">12.4%</div>
1664
+ <div style="font-size: 10px; color: #2e844a; font-weight: 600; margin-bottom: 8px;">18% above industry standard</div>
1665
+ <span style="background: #c9f2c7; color: #2e844a; padding: 4px 8px; border-radius: 3px; font-size: 11px; font-weight: 600;">PASS</span>
1666
+ </div>
1667
+ <div style="flex: 0 0 50%; height: 60px;">
1668
+ <svg width="100%" height="100%" viewBox="0 0 135 60" style="display: block;">
1669
+ <polyline points="0,52 25,48 50,45 75,39 100,33" fill="none" stroke="#2e844a" stroke-width="2"/>
1670
+ <circle cx="0" cy="52" r="2" fill="#2e844a"/>
1671
+ <circle cx="25" cy="48" r="2" fill="#2e844a"/>
1672
+ <circle cx="50" cy="45" r="2" fill="#2e844a"/>
1673
+ <circle cx="75" cy="39" r="2" fill="#2e844a"/>
1674
+ <circle cx="100" cy="33" r="3" fill="#2e844a"/>
1675
+ <text x="105" y="33" font-size="10" fill="#2e844a" alignment-baseline="middle" font-weight="600">12.4%</text>
1676
+ </svg>
1677
+ </div>
1678
+ </div>
1679
+
1680
+ <!-- ROA Card -->
1681
+ <div style="border: 1px solid #d8dde6; border-radius: 4px; padding: 15px; background: white; display: flex; justify-content: space-between; align-items: center; gap: 15px;">
1682
+ <div style="flex: 0 0 50%;">
1683
+ <div style="font-size: 11px; color: #706e6b; margin-bottom: 4px; text-transform: uppercase; font-weight: 600;">Return on Assets</div>
1684
+ <div style="font-size: 24px; font-weight: 600; color: #080707; margin-bottom: 8px;">8.7%</div>
1685
+ <div style="font-size: 10px; color: #ca8a04; font-weight: 600; margin-bottom: 8px;">25% below industry standard</div>
1686
+ <span style="background: #c9f2c7; color: #2e844a; padding: 4px 8px; border-radius: 3px; font-size: 11px; font-weight: 600;">PASS</span>
1687
+ </div>
1688
+ <div style="flex: 0 0 50%; height: 60px;">
1689
+ <svg width="100%" height="100%" viewBox="0 0 135 60" style="display: block;">
1690
+ <polyline points="0,48 25,42 50,45 75,37 100,30" fill="none" stroke="#2e844a" stroke-width="2"/>
1691
+ <circle cx="0" cy="48" r="2" fill="#2e844a"/>
1692
+ <circle cx="25" cy="42" r="2" fill="#2e844a"/>
1693
+ <circle cx="50" cy="45" r="2" fill="#2e844a"/>
1694
+ <circle cx="75" cy="37" r="2" fill="#2e844a"/>
1695
+ <circle cx="100" cy="30" r="3" fill="#2e844a"/>
1696
+ <text x="105" y="30" font-size="10" fill="#2e844a" alignment-baseline="middle" font-weight="600">8.7%</text>
1697
+ </svg>
1698
+ </div>
1699
+ </div>
1700
+
1701
+ <!-- ROE Card -->
1702
+ <div style="border: 1px solid #d8dde6; border-radius: 4px; padding: 15px; background: white; display: flex; justify-content: space-between; align-items: center; gap: 15px;">
1703
+ <div style="flex: 0 0 50%;">
1704
+ <div style="font-size: 11px; color: #706e6b; margin-bottom: 4px; text-transform: uppercase; font-weight: 600;">Return on Equity</div>
1705
+ <div style="font-size: 24px; font-weight: 600; color: #080707; margin-bottom: 8px;">15.3%</div>
1706
+ <div style="font-size: 10px; color: #2e844a; font-weight: 600; margin-bottom: 8px;">8% above industry standard</div>
1707
+ <span style="background: #c9f2c7; color: #2e844a; padding: 4px 8px; border-radius: 3px; font-size: 11px; font-weight: 600;">PASS</span>
1708
+ </div>
1709
+ <div style="flex: 0 0 50%; height: 60px;">
1710
+ <svg width="100%" height="100%" viewBox="0 0 135 60" style="display: block;">
1711
+ <polyline points="0,45 25,42 50,48 75,39 100,30" fill="none" stroke="#2e844a" stroke-width="2"/>
1712
+ <circle cx="0" cy="45" r="2" fill="#2e844a"/>
1713
+ <circle cx="25" cy="42" r="2" fill="#2e844a"/>
1714
+ <circle cx="50" cy="48" r="2" fill="#2e844a"/>
1715
+ <circle cx="75" cy="39" r="2" fill="#2e844a"/>
1716
+ <circle cx="100" cy="30" r="3" fill="#2e844a"/>
1717
+ <text x="105" y="30" font-size="10" fill="#2e844a" alignment-baseline="middle" font-weight="600">15.3%</text>
1718
+ </svg>
1719
+ </div>
1720
+ </div>
1721
+ </div>
1722
+ </div>
1723
+ <!-- End Actual Analysis Content -->
1724
+ </div>
1725
+ </div>
1726
+ </div>
1727
+ </div>
1728
+ </div>
1729
+
1730
+ <!-- Right Column - Sidebar -->
1731
+ <div class="sf-sidebar">
1732
+ <!-- Key Metrics -->
1733
+ <div class="sf-section">
1734
+ <div class="sf-section-header">Key Account Metrics</div>
1735
+ <div class="sf-section-body">
1736
+ <div class="sf-field">
1737
+ <div class="sf-field-label">Total Revenue (YTD)</div>
1738
+ <div class="sf-field-value" style="font-size: 20px; color: #2e844a; font-weight: 600;">$1,250,000</div>
1739
+ </div>
1740
+ <div class="sf-field" style="margin-top: 15px;">
1741
+ <div class="sf-field-label">Open Opportunities</div>
1742
+ <div class="sf-field-value" style="font-size: 20px; font-weight: 600;">8</div>
1743
+ </div>
1744
+ <div class="sf-field" style="margin-top: 15px;">
1745
+ <div class="sf-field-label">Total Pipeline Value</div>
1746
+ <div class="sf-field-value" style="font-size: 20px; font-weight: 600;">$2,100,000</div>
1747
+ </div>
1748
+ <div class="sf-field" style="margin-top: 15px;">
1749
+ <div class="sf-field-label">Customer Since</div>
1750
+ <div class="sf-field-value">June 2019</div>
1751
+ </div>
1752
+ <div class="sf-field" style="margin-top: 15px;">
1753
+ <div class="sf-field-label">Support Tier</div>
1754
+ <div class="sf-field-value">Premium</div>
1755
+ </div>
1756
+ </div>
1757
+ </div>
1758
+
1759
+ <!-- Recent Activity -->
1760
+ <div class="sf-section" style="margin-top: 15px;">
1761
+ <div class="sf-section-header">Activity Timeline</div>
1762
+ <div class="sf-section-body">
1763
+ <div style="margin-bottom: 12px;">
1764
+ <div style="font-weight: 600; font-size: 12px; color: #080707;">Email Sent</div>
1765
+ <div style="font-size: 11px; color: #706e6b; margin-top: 2px;">Today at 10:30 AM</div>
1766
+ <div style="font-size: 12px; margin-top: 4px;">Q1 Review Meeting Follow-up</div>
1767
+ </div>
1768
+ <div style="margin-bottom: 12px;">
1769
+ <div style="font-weight: 600; font-size: 12px; color: #080707;">Meeting Completed</div>
1770
+ <div style="font-size: 11px; color: #706e6b; margin-top: 2px;">Yesterday at 2:00 PM</div>
1771
+ <div style="font-size: 12px; margin-top: 4px;">Quarterly Business Review</div>
1772
+ </div>
1773
+ <div style="margin-bottom: 12px;">
1774
+ <div style="font-weight: 600; font-size: 12px; color: #080707;">Opportunity Updated</div>
1775
+ <div style="font-size: 11px; color: #706e6b; margin-top: 2px;">2 days ago</div>
1776
+ <div style="font-size: 12px; margin-top: 4px;">Wealth Management Platform moved to Negotiation</div>
1777
+ </div>
1778
+ </div>
1779
+ </div>
1780
+
1781
+ <!-- Contact Info -->
1782
+ <div class="sf-section" style="margin-top: 15px;">
1783
+ <div class="sf-section-header">Primary Contact</div>
1784
+ <div class="sf-section-body">
1785
+ <div class="sf-field">
1786
+ <div class="sf-field-label">Name</div>
1787
+ <div class="sf-field-value"><a href="#" class="sf-link">Sarah Johnson</a></div>
1788
+ </div>
1789
+ <div class="sf-field" style="margin-top: 10px;">
1790
+ <div class="sf-field-label">Title</div>
1791
+ <div class="sf-field-value">VP of Operations</div>
1792
+ </div>
1793
+ <div class="sf-field" style="margin-top: 10px;">
1794
+ <div class="sf-field-label">Email</div>
1795
+ <div class="sf-field-value"><a href="#" class="sf-link">sjohnson@enterprisefinancial.com</a></div>
1796
+ </div>
1797
+ <div class="sf-field" style="margin-top: 10px;">
1798
+ <div class="sf-field-label">Phone</div>
1799
+ <div class="sf-field-value">(415) 555-0199</div>
1800
+ </div>
1801
+ </div>
1802
+ </div>
1803
+ </div>
1804
+
1805
+ </div>
1806
+ </div>
1807
+
1808
+ <!-- Iframe Expansion Modal Overlay (just for background) -->
1809
+ <div class="sf-iframe-modal-overlay" id="iframeModal" onclick="closeIframeModal(event)"></div>
1810
+
1811
+ <!-- Chat Widget -->
1812
+ <button class="chat-widget-button" id="chatButton" onclick="toggleChat()">
1813
+ <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
1814
+ <path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z"/>
1815
+ <path d="M7 9h10v2H7zm0-3h10v2H7z"/>
1816
+ </svg>
1817
+ </button>
1818
+
1819
+ <div class="chat-widget-window" id="chatWindow">
1820
+ <div class="chat-widget-header">
1821
+ <div class="chat-widget-title">
1822
+ <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
1823
+ <path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z"/>
1824
+ </svg>
1825
+ Sea Assistant
1826
+ </div>
1827
+ <div class="chat-widget-header-actions">
1828
+ <a href="https://app.sea.dev/deals/28eq483grdz4gbfkhsili/j62iaw4d5piudvlnjexzi" target="_blank" class="chat-widget-sea-link" title="Open in Sea.dev">↗</a>
1829
+ <button class="chat-widget-expand" onclick="toggleExpand()" title="Expand">⊡</button>
1830
+ <button class="chat-widget-close" onclick="toggleChat()">×</button>
1831
+ </div>
1832
+ </div>
1833
+
1834
+ <div class="chat-messages" id="chatMessages">
1835
+ <div class="chat-message assistant">
1836
+ <div class="chat-message-content">
1837
+ Hi, how can I help?
1838
+ </div>
1839
+ </div>
1840
+ </div>
1841
+
1842
+ <div class="chat-input-container">
1843
+ <input
1844
+ type="text"
1845
+ class="chat-input"
1846
+ id="chatInput"
1847
+ placeholder="Type your message..."
1848
+ onkeypress="handleChatKeypress(event)"
1849
+ />
1850
+ <button class="chat-send-button" onclick="sendMessage()">
1851
+ <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
1852
+ <path d="M2.01 21L23 12 2.01 3 2 10l15 2-15 2z"/>
1853
+ </svg>
1854
+ </button>
1855
+ </div>
1856
+ </div>
1857
+
1858
+ <!-- OpenAI SDK -->
1859
+ <script src="https://cdn.jsdelivr.net/npm/openai@4.20.1/+esm" type="module"></script>
1860
+
1861
+ <script type="module">
1862
+ import OpenAI from 'https://cdn.jsdelivr.net/npm/openai@4.20.1/+esm';
1863
+
1864
+ // Initialize OpenAI
1865
+ const openai = new OpenAI({
1866
+ apiKey: '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',
1867
+ dangerouslyAllowBrowser: true
1868
+ });
1869
+
1870
+ // Make openai globally available
1871
+ window.openai = openai;
1872
+ window.conversationHistory = [];
1873
+ </script>
1874
+
1875
+ <script>
1876
+ // Switch main tabs (Opportunities, Contacts, Cases, etc.)
1877
+ function switchMainTab(tabName) {
1878
+ // Hide all main tab contents
1879
+ const tabContents = document.querySelectorAll('.sf-section > .sf-tab-content');
1880
+ tabContents.forEach(content => {
1881
+ content.classList.remove('active');
1882
+ });
1883
+
1884
+ // Remove active class from all tabs
1885
+ const tabs = document.querySelectorAll('.sf-tabs > .sf-tab');
1886
+ tabs.forEach(tab => {
1887
+ tab.classList.remove('active');
1888
+ });
1889
+
1890
+ // Show selected tab content
1891
+ const selectedContent = document.getElementById(tabName + '-content');
1892
+ if (selectedContent) {
1893
+ selectedContent.classList.add('active');
1894
+ }
1895
+
1896
+ // Add active class to clicked tab
1897
+ event.target.classList.add('active');
1898
+
1899
+ // Toggle full-width layout for financials tab
1900
+ const mainContent = document.getElementById('mainContent');
1901
+ const accountDetails = document.getElementById('accountDetailsSection');
1902
+
1903
+ if (tabName === 'financials') {
1904
+ mainContent.classList.add('full-width');
1905
+ // Collapse account details when Financials tab is clicked
1906
+ if (accountDetails) {
1907
+ accountDetails.classList.add('collapsed');
1908
+ }
1909
+ } else {
1910
+ mainContent.classList.remove('full-width');
1911
+ // Expand account details for other tabs
1912
+ if (accountDetails) {
1913
+ accountDetails.classList.remove('collapsed');
1914
+ }
1915
+ }
1916
+ }
1917
+
1918
+ // Switch financial sub-tabs (Upload, Spread, Results)
1919
+ function switchFinancialTab(tabName) {
1920
+ // Hide all financial tab contents
1921
+ const financialContents = document.querySelectorAll('#financials-content .sf-tab-content');
1922
+ financialContents.forEach(content => {
1923
+ content.classList.remove('active');
1924
+ });
1925
+
1926
+ // Remove active class from all financial tabs
1927
+ const financialTabs = document.querySelectorAll('.sf-financial-tab');
1928
+ financialTabs.forEach(tab => {
1929
+ tab.classList.remove('active');
1930
+ });
1931
+
1932
+ // Show selected financial tab content
1933
+ const selectedContent = document.getElementById(tabName + '-content');
1934
+ if (selectedContent) {
1935
+ selectedContent.classList.add('active');
1936
+ }
1937
+
1938
+ // Add active class to clicked tab
1939
+ event.target.classList.add('active');
1940
+ }
1941
+
1942
+
1943
+ // Expand iframe to modal
1944
+ function expandIframe() {
1945
+ // Find the iframe container (either upload-widget or spread-viewer)
1946
+ const uploadWidget = document.getElementById('upload-widget');
1947
+ const spreadViewer = document.querySelector('.sf-spread-viewer');
1948
+
1949
+ let container = null;
1950
+
1951
+ // Check which container has the iframe
1952
+ if (uploadWidget && !uploadWidget.classList.contains('hidden')) {
1953
+ container = uploadWidget;
1954
+ } else if (spreadViewer) {
1955
+ container = spreadViewer;
1956
+ }
1957
+
1958
+ if (!container) return;
1959
+
1960
+ // Add expanded class to container
1961
+ container.classList.add('expanded');
1962
+
1963
+ // Show modal overlay
1964
+ const modal = document.getElementById('iframeModal');
1965
+ if (modal) {
1966
+ modal.classList.add('active');
1967
+ // Prevent body scroll when modal is open
1968
+ document.body.style.overflow = 'hidden';
1969
+ }
1970
+ }
1971
+
1972
+ // Close iframe modal
1973
+ function closeIframeModal(event) {
1974
+ // Remove expanded class from all containers
1975
+ const uploadWidget = document.getElementById('upload-widget');
1976
+ const spreadViewer = document.querySelector('.sf-spread-viewer');
1977
+
1978
+ if (uploadWidget) {
1979
+ uploadWidget.classList.remove('expanded');
1980
+ }
1981
+ if (spreadViewer) {
1982
+ spreadViewer.classList.remove('expanded');
1983
+ }
1984
+
1985
+ // Hide modal overlay
1986
+ const modal = document.getElementById('iframeModal');
1987
+ if (modal) {
1988
+ modal.classList.remove('active');
1989
+ // Restore body scroll
1990
+ document.body.style.overflow = '';
1991
+ }
1992
+ }
1993
+
1994
+ // Close modal on Escape key
1995
+ document.addEventListener('keydown', function(event) {
1996
+ if (event.key === 'Escape') {
1997
+ closeIframeModal();
1998
+ }
1999
+ });
2000
+
2001
+ // Demo function to show financial results (would be triggered after actual upload)
2002
+ function showFinancialResults() {
2003
+ const noData = document.querySelector('.sf-no-data');
2004
+ const results = document.getElementById('financial-results');
2005
+
2006
+ if (noData) noData.style.display = 'none';
2007
+ if (results) results.style.display = 'block';
2008
+ }
2009
+
2010
+ // Toggle user menu dropdown
2011
+ function toggleUserMenu() {
2012
+ const dropdown = document.getElementById('userDropdown');
2013
+ dropdown.classList.toggle('active');
2014
+ }
2015
+
2016
+ // Close dropdown when clicking outside
2017
+ document.addEventListener('click', function(event) {
2018
+ const userMenu = document.querySelector('.sf-user-menu');
2019
+ const dropdown = document.getElementById('userDropdown');
2020
+ if (dropdown && !userMenu.contains(event.target)) {
2021
+ dropdown.classList.remove('active');
2022
+ }
2023
+ });
2024
+
2025
+ // Toggle embedded features (AI Financials tab and Chat button)
2026
+ function toggleEmbedded() {
2027
+ const isChecked = document.getElementById('embeddedToggle').checked;
2028
+ const chatButton = document.getElementById('chatButton');
2029
+ const chatWindow = document.getElementById('chatWindow');
2030
+ const aiFinancialsTab = document.querySelector('.sf-financial-tab[onclick*="ai"]');
2031
+ const analysisErrorState = document.getElementById('analysis-error-state');
2032
+ const analysisActualContent = document.getElementById('analysis-actual-content');
2033
+
2034
+ if (chatButton) {
2035
+ chatButton.style.display = isChecked ? 'flex' : 'none';
2036
+ }
2037
+ if (chatWindow && !isChecked) {
2038
+ chatWindow.classList.remove('open');
2039
+ }
2040
+ if (aiFinancialsTab) {
2041
+ aiFinancialsTab.style.display = isChecked ? 'block' : 'none';
2042
+ }
2043
+
2044
+ // Toggle Financial Analysis content
2045
+ if (analysisErrorState && analysisActualContent) {
2046
+ if (isChecked) {
2047
+ analysisErrorState.style.display = 'none';
2048
+ analysisActualContent.style.display = 'block';
2049
+ } else {
2050
+ analysisErrorState.style.display = 'block';
2051
+ analysisActualContent.style.display = 'none';
2052
+ }
2053
+ }
2054
+
2055
+ // If AI tab is hidden and currently active, switch to Input tab
2056
+ if (!isChecked) {
2057
+ const aiContent = document.getElementById('ai-content');
2058
+ if (aiContent && aiContent.classList.contains('active')) {
2059
+ switchFinancialTab('input');
2060
+ }
2061
+ }
2062
+ }
2063
+
2064
+ // Populate Input Financials tab
2065
+ function toggleInputFinancials() {
2066
+ const isChecked = document.getElementById('inputFinancialsToggle').checked;
2067
+
2068
+ if (isChecked) {
2069
+ // Financial data from the provided dataset (using the latest period)
2070
+ const financialData = {
2071
+ revenue: '4489000000',
2072
+ refunds: '0',
2073
+ cogs: '2813000000',
2074
+ sga: '1184000000',
2075
+ ebit: '492000000',
2076
+ ebitda: '550000000',
2077
+ adjustedEbitda: '550000000',
2078
+ netIncome: '348000000',
2079
+ period: '2025-03-29',
2080
+ fiscalYearEnd: '2025-03-29'
2081
+ };
2082
+
2083
+ // Find and populate inputs in the Input Financials tab
2084
+ const inputTab = document.getElementById('input-content');
2085
+ if (inputTab) {
2086
+ // Get all input fields
2087
+ const allInputs = inputTab.querySelectorAll('input[type="text"], input[type="date"]');
2088
+
2089
+ // Populate based on labels or placeholders
2090
+ allInputs.forEach(input => {
2091
+ const label = input.previousElementSibling?.textContent || '';
2092
+ const placeholder = input.placeholder || '';
2093
+
2094
+ // Fiscal Year End Date
2095
+ if (input.type === 'date' || label.includes('FISCAL YEAR END DATE')) {
2096
+ input.value = financialData.fiscalYearEnd;
2097
+ }
2098
+ // Financial Period
2099
+ else if (label.includes('FINANCIAL PERIOD') || placeholder.includes('Q4') || placeholder.includes('FY')) {
2100
+ input.value = financialData.period;
2101
+ }
2102
+ // Currency (skip)
2103
+ else if (label.includes('CURRENCY')) {
2104
+ // Keep default USD
2105
+ }
2106
+ // Skip readonly fields
2107
+ else if (input.readOnly) {
2108
+ // Skip calculated fields
2109
+ }
2110
+ });
2111
+
2112
+ // Find all number inputs by placeholder
2113
+ const numberInputs = inputTab.querySelectorAll('input[placeholder="0"], input[placeholder="(0)"]');
2114
+
2115
+ // Map inputs to their parent labels to populate correctly (including readonly/calculated fields)
2116
+ numberInputs.forEach(input => {
2117
+ const parentDiv = input.closest('div');
2118
+ const label = parentDiv?.querySelector('label')?.textContent || '';
2119
+
2120
+ // Balance Sheet - Assets
2121
+ if (label.includes('Cash')) {
2122
+ input.value = '125,000,000';
2123
+ } else if (label.includes('Accounts Receivable')) {
2124
+ input.value = '85,000,000';
2125
+ } else if (label.includes('Inventory')) {
2126
+ input.value = '45,000,000';
2127
+ } else if (label.includes('Prepaid')) {
2128
+ input.value = '12,000,000';
2129
+ } else if (label.includes('Other Current Assets') && !label.includes('Total')) {
2130
+ input.value = '8,000,000';
2131
+ } else if (label.includes('Total Current Assets')) {
2132
+ input.value = '275,000,000';
2133
+ input.readOnly = false; // Force populate
2134
+ } else if (label.includes('Property, Plant')) {
2135
+ input.value = '350,000,000';
2136
+ } else if (label.includes('Accumulated Depreciation')) {
2137
+ input.value = '(120,000,000)';
2138
+ } else if (label.includes('Intangible')) {
2139
+ input.value = '75,000,000';
2140
+ } else if (label.includes('Goodwill')) {
2141
+ input.value = '95,000,000';
2142
+ } else if (label.includes('Other Non-Current Assets') && !label.includes('Total')) {
2143
+ input.value = '15,000,000';
2144
+ } else if (label.includes('Total Non-Current Assets')) {
2145
+ input.value = '415,000,000';
2146
+ input.readOnly = false;
2147
+ } else if (label.includes('TOTAL ASSETS')) {
2148
+ input.value = '690,000,000';
2149
+ input.readOnly = false;
2150
+ }
2151
+
2152
+ // Balance Sheet - Liabilities
2153
+ else if (label.includes('Accounts Payable')) {
2154
+ input.value = '65,000,000';
2155
+ } else if (label.includes('Accrued Expenses')) {
2156
+ input.value = '35,000,000';
2157
+ } else if (label.includes('Short-term Debt')) {
2158
+ input.value = '25,000,000';
2159
+ } else if (label.includes('Current Portion') && label.includes('Long-term')) {
2160
+ input.value = '15,000,000';
2161
+ } else if (label.includes('Unearned Revenue')) {
2162
+ input.value = '20,000,000';
2163
+ } else if (label.includes('Other Current Liabilities')) {
2164
+ input.value = '10,000,000';
2165
+ } else if (label.includes('Total Current Liabilities')) {
2166
+ input.value = '170,000,000';
2167
+ input.readOnly = false;
2168
+ } else if (label.includes('Long-term Debt') && !label.includes('Current')) {
2169
+ input.value = '200,000,000';
2170
+ } else if (label.includes('Deferred Tax')) {
2171
+ input.value = '18,000,000';
2172
+ } else if (label.includes('Other Non-Current Liabilities')) {
2173
+ input.value = '12,000,000';
2174
+ } else if (label.includes('Total Non-Current Liabilities')) {
2175
+ input.value = '230,000,000';
2176
+ input.readOnly = false;
2177
+ } else if (label.includes('TOTAL LIABILITIES')) {
2178
+ input.value = '400,000,000';
2179
+ input.readOnly = false;
2180
+ }
2181
+
2182
+ // Balance Sheet - Equity
2183
+ else if (label.includes('Common Stock')) {
2184
+ input.value = '50,000,000';
2185
+ } else if (label.includes('Additional Paid')) {
2186
+ input.value = '100,000,000';
2187
+ } else if (label.includes('Retained Earnings')) {
2188
+ input.value = '140,000,000';
2189
+ } else if (label.includes('Treasury Stock')) {
2190
+ input.value = '0';
2191
+ } else if (label.includes('TOTAL EQUITY') || label.includes("TOTAL SHAREHOLDERS' EQUITY")) {
2192
+ input.value = '290,000,000';
2193
+ input.readOnly = false;
2194
+ }
2195
+
2196
+ // Income Statement
2197
+ else if (label.includes('REVENUE') && !label.includes('Unearned') && !label.includes('NET')) {
2198
+ input.value = Number(financialData.revenue).toLocaleString();
2199
+ } else if (label.includes('REFUNDS')) {
2200
+ input.value = Number(financialData.refunds).toLocaleString();
2201
+ } else if (label.includes('NET REVENUE')) {
2202
+ input.value = Number(financialData.revenue).toLocaleString();
2203
+ input.readOnly = false;
2204
+ } else if (label.includes('COGS')) {
2205
+ input.value = Number(financialData.cogs).toLocaleString();
2206
+ } else if (label.includes('GROSS PROFIT')) {
2207
+ input.value = '1,676,000,000';
2208
+ input.readOnly = false;
2209
+ } else if (label.includes('SG&A')) {
2210
+ input.value = Number(financialData.sga).toLocaleString();
2211
+ } else if (label.includes('R&D')) {
2212
+ input.value = '0';
2213
+ } else if (label.includes('Other Operating')) {
2214
+ input.value = '0';
2215
+ } else if (label.includes('EBIT') && !label.includes('EBITDA')) {
2216
+ input.value = Number(financialData.ebit).toLocaleString();
2217
+ input.readOnly = false;
2218
+ } else if (label.includes('Interest Income')) {
2219
+ input.value = '5,000,000';
2220
+ } else if (label.includes('Interest Expense')) {
2221
+ input.value = '(18,000,000)';
2222
+ } else if (label.includes('Other Income')) {
2223
+ input.value = '2,000,000';
2224
+ } else if (label.includes('PRE-TAX INCOME')) {
2225
+ input.value = '481,000,000';
2226
+ input.readOnly = false;
2227
+ } else if (label.includes('Income Tax')) {
2228
+ input.value = '(133,000,000)';
2229
+ } else if (label.includes('NET INCOME')) {
2230
+ input.value = Number(financialData.netIncome).toLocaleString();
2231
+ input.readOnly = false;
2232
+ } else if (label.includes('Depreciation')) {
2233
+ input.value = '45,000,000';
2234
+ } else if (label.includes('Amortization')) {
2235
+ input.value = '13,000,000';
2236
+ } else if (label.includes('EBITDA') && !label.includes('ADJUSTED')) {
2237
+ input.value = Number(financialData.ebitda).toLocaleString();
2238
+ input.readOnly = false;
2239
+ } else if (label.includes('ADJUSTED EBITDA')) {
2240
+ input.value = Number(financialData.adjustedEbitda).toLocaleString();
2241
+ input.readOnly = false;
2242
+ }
2243
+ });
2244
+ }
2245
+ } else {
2246
+ // Clear form fields
2247
+ const inputTab = document.getElementById('input-content');
2248
+ if (inputTab) {
2249
+ const allInputs = inputTab.querySelectorAll('input[type="text"]:not([readonly]), input[type="date"]');
2250
+ allInputs.forEach(input => {
2251
+ input.value = '';
2252
+ });
2253
+ }
2254
+ }
2255
+ }
2256
+
2257
+ // Chat Widget Functions
2258
+ function toggleChat() {
2259
+ const chatWindow = document.getElementById('chatWindow');
2260
+ const chatButton = document.getElementById('chatButton');
2261
+
2262
+ chatWindow.classList.toggle('open');
2263
+ chatButton.classList.toggle('open');
2264
+
2265
+ if (chatWindow.classList.contains('open')) {
2266
+ document.getElementById('chatInput').focus();
2267
+ }
2268
+ }
2269
+
2270
+ function toggleExpand() {
2271
+ const chatWindow = document.getElementById('chatWindow');
2272
+ chatWindow.classList.toggle('expanded');
2273
+ }
2274
+
2275
+ function handleChatKeypress(event) {
2276
+ if (event.key === 'Enter') {
2277
+ sendMessage();
2278
+ }
2279
+ }
2280
+
2281
+ async function sendMessage() {
2282
+ console.log('sendMessage called');
2283
+ const input = document.getElementById('chatInput');
2284
+ const message = input.value.trim();
2285
+ console.log('Message:', message);
2286
+
2287
+ if (!message) {
2288
+ console.log('Empty message, returning');
2289
+ return;
2290
+ }
2291
+
2292
+ // Add user message
2293
+ console.log('Adding user message');
2294
+ addChatMessage('user', message);
2295
+ input.value = '';
2296
+
2297
+ // Add to conversation history
2298
+ window.conversationHistory.push({
2299
+ role: 'user',
2300
+ content: message
2301
+ });
2302
+
2303
+ // Show loading
2304
+ addLoadingMessage();
2305
+
2306
+ try {
2307
+ // Get AI response with streaming
2308
+ removeLoadingMessage();
2309
+ const streamingMessageId = addStreamingMessage();
2310
+
2311
+ const response = await generateAIResponseStreaming(message, streamingMessageId);
2312
+ console.log('Final response:', response);
2313
+
2314
+ // Add to conversation history
2315
+ window.conversationHistory.push({
2316
+ role: 'assistant',
2317
+ content: response
2318
+ });
2319
+ } catch (error) {
2320
+ console.error('Error getting AI response:', error);
2321
+ removeLoadingMessage();
2322
+ addChatMessage('assistant', 'I apologize, but I encountered an error. Please try again.');
2323
+ }
2324
+ }
2325
+
2326
+ function addChatMessage(role, content) {
2327
+ const messagesContainer = document.getElementById('chatMessages');
2328
+ const messageDiv = document.createElement('div');
2329
+ messageDiv.className = `chat-message ${role}`;
2330
+
2331
+ const contentDiv = document.createElement('div');
2332
+ contentDiv.className = 'chat-message-content';
2333
+ contentDiv.innerHTML = formatMessageContent(content);
2334
+
2335
+ messageDiv.appendChild(contentDiv);
2336
+ messagesContainer.appendChild(messageDiv);
2337
+
2338
+ // Scroll to bottom
2339
+ messagesContainer.scrollTop = messagesContainer.scrollHeight;
2340
+ }
2341
+
2342
+ function addLoadingMessage() {
2343
+ const messagesContainer = document.getElementById('chatMessages');
2344
+ const messageDiv = document.createElement('div');
2345
+ messageDiv.className = 'chat-message assistant';
2346
+ messageDiv.id = 'loading-message';
2347
+
2348
+ const contentDiv = document.createElement('div');
2349
+ contentDiv.className = 'chat-message-content';
2350
+ contentDiv.innerHTML = '<div class="chat-loading"><div class="chat-loading-dot"></div><div class="chat-loading-dot"></div><div class="chat-loading-dot"></div></div>';
2351
+
2352
+ messageDiv.appendChild(contentDiv);
2353
+ messagesContainer.appendChild(messageDiv);
2354
+ messagesContainer.scrollTop = messagesContainer.scrollHeight;
2355
+ }
2356
+
2357
+ function removeLoadingMessage() {
2358
+ const loadingMessage = document.getElementById('loading-message');
2359
+ if (loadingMessage) {
2360
+ loadingMessage.remove();
2361
+ }
2362
+ }
2363
+
2364
+ function addStreamingMessage() {
2365
+ const messagesContainer = document.getElementById('chatMessages');
2366
+ const messageDiv = document.createElement('div');
2367
+ const messageId = 'streaming-message-' + Date.now();
2368
+ messageDiv.className = 'chat-message assistant';
2369
+ messageDiv.id = messageId;
2370
+
2371
+ const contentDiv = document.createElement('div');
2372
+ contentDiv.className = 'chat-message-content';
2373
+ contentDiv.innerHTML = '';
2374
+
2375
+ messageDiv.appendChild(contentDiv);
2376
+ messagesContainer.appendChild(messageDiv);
2377
+ messagesContainer.scrollTop = messagesContainer.scrollHeight;
2378
+
2379
+ return messageId;
2380
+ }
2381
+
2382
+ function updateStreamingMessage(messageId, content) {
2383
+ const messageDiv = document.getElementById(messageId);
2384
+ if (messageDiv) {
2385
+ const contentDiv = messageDiv.querySelector('.chat-message-content');
2386
+ contentDiv.innerHTML = formatMessageContent(content);
2387
+
2388
+ // Auto-scroll to bottom
2389
+ const messagesContainer = document.getElementById('chatMessages');
2390
+ messagesContainer.scrollTop = messagesContainer.scrollHeight;
2391
+ }
2392
+ }
2393
+
2394
+ function formatMessageContent(content) {
2395
+ // Convert markdown-like formatting
2396
+ let formatted = content
2397
+ .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
2398
+ .replace(/\n/g, '<br>');
2399
+
2400
+ return formatted;
2401
+ }
2402
+
2403
+ // Tool Definitions for OpenAI Function Calling
2404
+ const tools = [
2405
+ {
2406
+ type: 'function',
2407
+ function: {
2408
+ name: 'get_account_info',
2409
+ description: 'Get information about the Enterprise Financial Group account',
2410
+ parameters: {
2411
+ type: 'object',
2412
+ properties: {},
2413
+ required: []
2414
+ }
2415
+ }
2416
+ },
2417
+ {
2418
+ type: 'function',
2419
+ function: {
2420
+ name: 'get_financial_data',
2421
+ description: 'Get financial statement data including income statement and balance sheet',
2422
+ parameters: {
2423
+ type: 'object',
2424
+ properties: {
2425
+ statement_type: {
2426
+ type: 'string',
2427
+ enum: ['income_statement', 'balance_sheet', 'both'],
2428
+ description: 'Which financial statement to retrieve'
2429
+ }
2430
+ },
2431
+ required: []
2432
+ }
2433
+ }
2434
+ },
2435
+ {
2436
+ type: 'function',
2437
+ function: {
2438
+ name: 'get_financial_analysis',
2439
+ description: 'Get financial ratio analysis and industry comparisons',
2440
+ parameters: {
2441
+ type: 'object',
2442
+ properties: {},
2443
+ required: []
2444
+ }
2445
+ }
2446
+ },
2447
+ {
2448
+ type: 'function',
2449
+ function: {
2450
+ name: 'get_opportunities',
2451
+ description: 'Get information about sales opportunities',
2452
+ parameters: {
2453
+ type: 'object',
2454
+ properties: {},
2455
+ required: []
2456
+ }
2457
+ }
2458
+ }
2459
+ ];
2460
+
2461
+ // Tool Execution Functions
2462
+ function executeToolCall(toolName, args) {
2463
+ console.log('Executing tool:', toolName, 'with args:', args);
2464
+
2465
+ const inputFinancialsChecked = document.getElementById('inputFinancialsToggle')?.checked;
2466
+
2467
+ switch(toolName) {
2468
+ case 'get_account_info':
2469
+ return {
2470
+ name: 'Enterprise Financial Group',
2471
+ type: 'Customer - Direct',
2472
+ annualRevenue: '$45,000,000',
2473
+ industry: 'Financial Services',
2474
+ pipelineValue: '$2,100,000',
2475
+ contact: 'Sarah Johnson - VP of Operations'
2476
+ };
2477
+
2478
+ case 'get_financial_data':
2479
+ if (!inputFinancialsChecked) {
2480
+ return { error: 'Financial data not available. Please enable Input Financials from the user menu.' };
2481
+ }
2482
+ return {
2483
+ incomeStatement: {
2484
+ revenue: 4489000000,
2485
+ cogs: -2813000000,
2486
+ sga: -1184000000,
2487
+ ebit: 492000000,
2488
+ ebitda: 550000000,
2489
+ adjustedEbitda: 550000000,
2490
+ netIncome: 348000000,
2491
+ grossProfit: 1676000000,
2492
+ period: '2025-03-29'
2493
+ },
2494
+ balanceSheet: {
2495
+ cash: 125000000,
2496
+ accountsReceivable: 85000000,
2497
+ inventory: 45000000,
2498
+ totalCurrentAssets: 275000000,
2499
+ ppe: 350000000,
2500
+ totalAssets: 690000000,
2501
+ totalLiabilities: 400000000,
2502
+ totalEquity: 290000000
2503
+ }
2504
+ };
2505
+
2506
+ case 'get_financial_analysis':
2507
+ if (!inputFinancialsChecked) {
2508
+ return { error: 'Financial analysis not available. Please enable Input Financials from the user menu.' };
2509
+ }
2510
+ return {
2511
+ ratios: {
2512
+ currentRatio: 2.1,
2513
+ quickRatio: 1.8,
2514
+ debtToEquity: 1.9,
2515
+ debtToEbitda: 2.8,
2516
+ dscr: 1.45,
2517
+ interestCoverage: 5.2,
2518
+ netProfitMargin: 0.124,
2519
+ grossMargin: 0.373,
2520
+ roa: 0.087,
2521
+ roe: 0.153
2522
+ },
2523
+ industryComparison: {
2524
+ currentRatio: '15% above industry standard',
2525
+ quickRatio: '12% above industry standard',
2526
+ debtToEquity: '10% below industry standard',
2527
+ dscr: '20% above industry standard',
2528
+ interestCoverage: '30% above industry standard',
2529
+ netProfitMargin: '18% above industry standard'
2530
+ }
2531
+ };
2532
+
2533
+ case 'get_opportunities':
2534
+ return {
2535
+ total: 8,
2536
+ totalValue: '$2,100,000',
2537
+ opportunities: [
2538
+ { name: 'Wealth Management Platform', amount: '$250,000', stage: 'Negotiation', probability: '75%' },
2539
+ { name: 'Investment Portfolio System', amount: '$180,000', stage: 'Proposal', probability: '50%' },
2540
+ { name: 'Risk Assessment Tools', amount: '$320,000', stage: 'Closed Won', probability: '100%' }
2541
+ ]
2542
+ };
2543
+
2544
+ default:
2545
+ return { error: 'Unknown tool: ' + toolName };
2546
+ }
2547
+ }
2548
+
2549
+ // Generate AI response using OpenAI with streaming
2550
+ async function generateAIResponseStreaming(userMessage, streamingMessageId) {
2551
+ console.log('generateAIResponseStreaming called with:', userMessage);
2552
+
2553
+ const systemPrompt = `You are Sea Assistant, a helpful AI assistant for a CRM system. You help users with:
2554
+ - Account information for Enterprise Financial Group
2555
+ - Financial data analysis (when available)
2556
+ - Sales opportunities and pipeline information
2557
+ - Contact details
2558
+ - Activity tracking
2559
+
2560
+ When financial data is available, you can access detailed income statements, balance sheets, and financial ratios.
2561
+
2562
+ Format your responses with HTML for better readability:
2563
+ - Use <strong> for emphasis
2564
+ - Use <br> for line breaks
2565
+ - Use bullet points with •
2566
+ - Keep responses concise but informative
2567
+
2568
+ Available data context:
2569
+ - Account: Enterprise Financial Group (Financial Services industry)
2570
+ - Current opportunities: 8 open deals worth $2.1M total
2571
+ - Primary contact: Sarah Johnson (VP of Operations)`;
2572
+
2573
+ const messages = [
2574
+ { role: 'system', content: systemPrompt },
2575
+ ...window.conversationHistory
2576
+ ];
2577
+
2578
+ try {
2579
+ console.log('Calling OpenAI API with streaming...');
2580
+ const stream = await window.openai.chat.completions.create({
2581
+ model: 'gpt-4o-mini',
2582
+ messages: messages,
2583
+ tools: tools,
2584
+ tool_choice: 'auto',
2585
+ stream: true
2586
+ });
2587
+
2588
+ console.log('Stream created');
2589
+ let fullContent = '';
2590
+ let toolCalls = [];
2591
+ let currentToolCall = null;
2592
+
2593
+ for await (const chunk of stream) {
2594
+ const delta = chunk.choices[0]?.delta;
2595
+
2596
+ // Handle tool calls
2597
+ if (delta?.tool_calls) {
2598
+ for (const toolCallDelta of delta.tool_calls) {
2599
+ if (toolCallDelta.index !== undefined) {
2600
+ if (!toolCalls[toolCallDelta.index]) {
2601
+ toolCalls[toolCallDelta.index] = {
2602
+ id: toolCallDelta.id || '',
2603
+ type: 'function',
2604
+ function: { name: '', arguments: '' }
2605
+ };
2606
+ }
2607
+
2608
+ const toolCall = toolCalls[toolCallDelta.index];
2609
+ if (toolCallDelta.id) toolCall.id = toolCallDelta.id;
2610
+ if (toolCallDelta.function?.name) toolCall.function.name = toolCallDelta.function.name;
2611
+ if (toolCallDelta.function?.arguments) toolCall.function.arguments += toolCallDelta.function.arguments;
2612
+ }
2613
+ }
2614
+ }
2615
+
2616
+ // Handle content
2617
+ if (delta?.content) {
2618
+ fullContent += delta.content;
2619
+ updateStreamingMessage(streamingMessageId, fullContent);
2620
+ }
2621
+ }
2622
+
2623
+ // If there were tool calls, execute them and get final response
2624
+ if (toolCalls.length > 0) {
2625
+ console.log('Tool calls detected:', toolCalls);
2626
+ updateStreamingMessage(streamingMessageId, fullContent + '<br><br><em>Fetching data...</em>');
2627
+
2628
+ // Add assistant message with tool calls to history
2629
+ messages.push({
2630
+ role: 'assistant',
2631
+ content: fullContent || null,
2632
+ tool_calls: toolCalls
2633
+ });
2634
+
2635
+ // Execute each tool call
2636
+ for (const toolCall of toolCalls) {
2637
+ const functionName = toolCall.function.name;
2638
+ const functionArgs = JSON.parse(toolCall.function.arguments);
2639
+
2640
+ console.log(`Executing tool: ${functionName}`);
2641
+ const toolResult = executeToolCall(functionName, functionArgs);
2642
+
2643
+ // Add tool result to messages
2644
+ messages.push({
2645
+ role: 'tool',
2646
+ tool_call_id: toolCall.id,
2647
+ content: JSON.stringify(toolResult)
2648
+ });
2649
+ }
2650
+
2651
+ // Get final response with tool results (streaming)
2652
+ console.log('Getting final response with tool results...');
2653
+ const finalStream = await window.openai.chat.completions.create({
2654
+ model: 'gpt-4o-mini',
2655
+ messages: messages,
2656
+ stream: true
2657
+ });
2658
+
2659
+ fullContent = '';
2660
+ for await (const chunk of finalStream) {
2661
+ const delta = chunk.choices[0]?.delta;
2662
+ if (delta?.content) {
2663
+ fullContent += delta.content;
2664
+ updateStreamingMessage(streamingMessageId, fullContent);
2665
+ }
2666
+ }
2667
+ }
2668
+
2669
+ console.log('Streaming complete. Final content:', fullContent);
2670
+ return fullContent;
2671
+ } catch (error) {
2672
+ console.error('Error in generateAIResponseStreaming:', error);
2673
+ throw error;
2674
+ }
2675
+ }
2676
+ </script>
2677
+ </body>
2678
+ </html>