gloomberb 0.15.2 → 0.15.3

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 (1918) hide show
  1. package/README.md +31 -2
  2. package/README.zh-CN.md +12 -2
  3. package/package.json +20 -21
  4. package/src/api-client/auth.ts +7 -1
  5. package/src/api-client/chat.ts +1 -2
  6. package/src/api-client/collections.ts +1 -13
  7. package/src/api-client/credit-boards.ts +67 -0
  8. package/src/api-client/data.ts +93 -57
  9. package/src/api-client/earnings.ts +80 -0
  10. package/src/api-client/equity-screener.ts +25 -0
  11. package/src/api-client/errors.ts +42 -0
  12. package/src/api-client/feedback.ts +1 -2
  13. package/src/api-client/futures-curve.ts +30 -0
  14. package/src/api-client/index.ts +108 -100
  15. package/src/api-client/ipo.ts +99 -0
  16. package/src/api-client/market-movers.ts +60 -0
  17. package/src/api-client/mna.ts +118 -0
  18. package/src/api-client/normalizers.ts +0 -7
  19. package/src/api-client/notes.ts +20 -34
  20. package/src/api-client/paths.ts +21 -19
  21. package/src/api-client/plan-access.ts +27 -0
  22. package/src/api-client/plan-rules.ts +87 -0
  23. package/src/api-client/request.ts +40 -4
  24. package/src/api-client/research-activity.ts +17 -1
  25. package/src/api-client/revenue-breakdown.ts +36 -0
  26. package/src/api-client/session-cookie.ts +6 -0
  27. package/src/api-client/social-mentions.ts +63 -0
  28. package/src/api-client/teams.ts +1 -26
  29. package/src/api-client/telemetry.ts +180 -0
  30. package/src/api-client/theses.ts +9 -36
  31. package/src/api-client/types.ts +66 -61
  32. package/src/api-client/views.ts +22 -49
  33. package/src/app/app-bootstrap-state.ts +3 -14
  34. package/src/app/pane-runtime/plugin-bindings.ts +21 -1
  35. package/src/app/runtime/broker-import.ts +5 -1
  36. package/src/app/runtime/desktop-menu.ts +23 -12
  37. package/src/app/runtime/layout-warmup.ts +2 -2
  38. package/src/app/runtime/plugin-bindings.ts +27 -7
  39. package/src/app/runtime/startup.ts +55 -1
  40. package/src/app/runtime/ticker-refresh.ts +6 -6
  41. package/src/app/runtime/update.ts +4 -2
  42. package/src/app.tsx +15 -1
  43. package/src/assets/gloomberb-logo-windows.ico +0 -0
  44. package/src/assets/gloomberb-logo-windows.png +0 -0
  45. package/src/assets/gloomberb-logo.svg +1 -73
  46. package/src/assets/gloomberb-mark.ico +0 -0
  47. package/src/assets/gloomberb-mark.svg +1 -0
  48. package/src/brokers/broker-portfolio-sync.ts +75 -6
  49. package/src/brokers/broker-ticker-sync.ts +3 -1
  50. package/src/brokers/cloud-broker-link.ts +26 -0
  51. package/src/brokers/directory.ts +56 -0
  52. package/src/brokers/remote-broker-adapter.ts +4 -1
  53. package/src/brokers/signed-in/adapter.ts +259 -0
  54. package/src/brokers/signed-in/catalog.ts +129 -0
  55. package/src/brokers/signed-in/client.ts +54 -0
  56. package/src/brokers/signed-in/connect.ts +69 -0
  57. package/src/brokers/signed-in/profile.ts +18 -0
  58. package/src/brokers/signed-in/sign-in-dialog.tsx +187 -0
  59. package/src/brokers/signed-in/sign-in.ts +178 -0
  60. package/src/brokers/sync-broker-instance.ts +42 -24
  61. package/src/capabilities/index.ts +42 -6
  62. package/src/cli/commands/broker.ts +49 -0
  63. package/src/cli/commands/market.ts +5 -0
  64. package/src/cli/commands/overview.ts +2 -5
  65. package/src/cli/commands/plugins.ts +112 -428
  66. package/src/cli/commands/system.ts +26 -354
  67. package/src/cli/commands/ticker.ts +11 -34
  68. package/src/cli/desktop-pane-shot-routes.ts +7 -0
  69. package/src/cli/desktop-pane-shot.ts +7 -27
  70. package/src/cli/entry.ts +20 -23
  71. package/src/cli/helpers.ts +5 -19
  72. package/src/cli/index.ts +17 -23
  73. package/src/cli/pane-functions/capabilities.ts +0 -4
  74. package/src/cli/pane-functions/catalog.ts +30 -4
  75. package/src/cli/pane-functions/headless.ts +1 -4
  76. package/src/cli/pane-functions/index.ts +0 -23
  77. package/src/cli/pane-functions/options.ts +8 -5
  78. package/src/cli/pane-functions/screenshot-evidence.ts +106 -0
  79. package/src/cli/pane-functions/screenshot.ts +48 -291
  80. package/src/cli/restore-plugins.ts +10 -2
  81. package/src/components/chart/composite/axis-overlays.tsx +87 -22
  82. package/src/components/chart/composite/composite-chart.tsx +5 -6
  83. package/src/components/chart/composite/downsample.ts +4 -7
  84. package/src/components/chart/composite/format.ts +39 -3
  85. package/src/components/chart/composite/interactions.ts +1 -29
  86. package/src/components/chart/composite/price-axis-labels.tsx +1 -4
  87. package/src/components/chart/composite/rasterizer.ts +1 -19
  88. package/src/components/chart/composite/scene.ts +7 -10
  89. package/src/components/chart/composite/text-renderer.ts +5 -21
  90. package/src/components/chart/composite/time-axis.ts +1 -4
  91. package/src/components/chart/composite/tools.ts +2 -1
  92. package/src/components/chart/core/pointer.ts +1 -4
  93. package/src/components/chart/curve/curve-surface.tsx +180 -48
  94. package/src/components/chart/curve/index.ts +3 -2
  95. package/src/components/chart/curve/model.ts +200 -31
  96. package/src/components/chart/native/chart-rasterizer.ts +1 -0
  97. package/src/components/chart/native/kitty/protocol.ts +1 -1
  98. package/src/components/chart/native/raster/crosshair.ts +1 -2
  99. package/src/components/chart/native/raster/placement.ts +6 -0
  100. package/src/components/chart/native/raster/primitives.ts +5 -9
  101. package/src/components/chart/native/raster/types.ts +0 -7
  102. package/src/components/chart/native/renderer-selection.ts +4 -4
  103. package/src/components/chart/native/surface/manager.ts +7 -12
  104. package/src/components/chart/static/chart-surface.tsx +4 -7
  105. package/src/components/chart/static/index.ts +0 -1
  106. package/src/components/chart/static/trail-chart-surface.tsx +393 -66
  107. package/src/components/chart/surface3d/model.ts +2 -2
  108. package/src/components/chart/surface3d/software.ts +2 -1
  109. package/src/components/chart-table/axis.ts +29 -0
  110. package/src/components/chart-table/header.tsx +264 -0
  111. package/src/components/chart-table/index.ts +14 -0
  112. package/src/components/chart-table/layout.ts +139 -0
  113. package/src/components/chart-table/selection.ts +145 -0
  114. package/src/components/command-bar/action-runtime.ts +1 -2
  115. package/src/components/command-bar/assist/inventory.ts +83 -30
  116. package/src/components/command-bar/assist/model.ts +4 -0
  117. package/src/components/command-bar/assist/runtime.ts +79 -26
  118. package/src/components/command-bar/commands/collection.ts +1 -6
  119. package/src/components/command-bar/commands/direct/index.ts +26 -2
  120. package/src/components/command-bar/commands/direct/runtime.ts +1 -1
  121. package/src/components/command-bar/commands/plugin/actions.ts +2 -1
  122. package/src/components/command-bar/commands/plugin/items.ts +10 -0
  123. package/src/components/command-bar/commands/registry.ts +23 -0
  124. package/src/components/command-bar/helpers.ts +0 -1
  125. package/src/components/command-bar/layout-items/current-layout.ts +11 -9
  126. package/src/components/command-bar/layout-items/types.ts +0 -1
  127. package/src/components/command-bar/layout-items.ts +0 -3
  128. package/src/components/command-bar/list/model.ts +5 -0
  129. package/src/components/command-bar/list/navigation.ts +2 -5
  130. package/src/components/command-bar/list/view.tsx +7 -7
  131. package/src/components/command-bar/pane-actions.ts +3 -8
  132. package/src/components/command-bar/pane-templates/workflow.ts +5 -1
  133. package/src/components/command-bar/panel/index.tsx +5 -5
  134. package/src/components/command-bar/panel/runtime.ts +4 -1
  135. package/src/components/command-bar/picker-activation.ts +14 -4
  136. package/src/components/command-bar/routes/root/command-items.ts +19 -1
  137. package/src/components/command-bar/routes/root/plugin-install.ts +304 -0
  138. package/src/components/command-bar/routes/root/results.ts +10 -1
  139. package/src/components/command-bar/routes/root/runtime.ts +12 -8
  140. package/src/components/command-bar/routes/root/search-report.ts +246 -0
  141. package/src/components/command-bar/routes/root/selection.ts +14 -5
  142. package/src/components/command-bar/routes/root/shortcut-items.ts +2 -0
  143. package/src/components/command-bar/routing/actions.ts +2 -8
  144. package/src/components/command-bar/routing/confirm.ts +6 -1
  145. package/src/components/command-bar/routing/launch-request.ts +7 -0
  146. package/src/components/command-bar/routing/navigation-state.ts +24 -0
  147. package/src/components/command-bar/selection-runtime.ts +110 -65
  148. package/src/components/command-bar/surface/index.tsx +116 -19
  149. package/src/components/command-bar/theme-picker.tsx +11 -10
  150. package/src/components/command-bar/view-model.ts +10 -6
  151. package/src/components/command-bar/workflow/body.tsx +6 -5
  152. package/src/components/command-bar/workflow/broker.ts +113 -76
  153. package/src/components/command-bar/workflow/collection-actions.ts +39 -8
  154. package/src/components/command-bar/workflow/coordinator.ts +19 -10
  155. package/src/components/command-bar/workflow/field-row.tsx +3 -3
  156. package/src/components/command-bar/workflow/fields.ts +14 -5
  157. package/src/components/command-bar/workflow/ops.ts +14 -1
  158. package/src/components/command-bar/workflow/submit.ts +23 -9
  159. package/src/components/command-bar/workflow/types.ts +3 -0
  160. package/src/components/data-table/export.ts +103 -6
  161. package/src/components/data-table/stack-view.tsx +22 -2
  162. package/src/components/data-table/table-pane.ts +45 -0
  163. package/src/components/data-table/view.tsx +24 -10
  164. package/src/components/feed-data-table/stack-view.tsx +47 -130
  165. package/src/components/index.ts +49 -5
  166. package/src/components/layout/header.tsx +5 -12
  167. package/src/components/layout/market-summary.ts +1 -2
  168. package/src/components/layout/missing-pane.tsx +2 -7
  169. package/src/components/layout/pane/header-tabs.tsx +2 -1
  170. package/src/components/layout/pane/header.tsx +2 -6
  171. package/src/components/layout/pane/pane-tabs.tsx +41 -0
  172. package/src/components/layout/pane/status-footer.ts +92 -0
  173. package/src/components/layout/shell/action-menu-overlay.tsx +3 -3
  174. package/src/components/layout/shell/index.tsx +6 -10
  175. package/src/components/layout/shell/menu.ts +1 -5
  176. package/src/components/layout/shell/native/surfaces.ts +3 -4
  177. package/src/components/layout/shell/pane/actions.ts +8 -9
  178. package/src/components/layout/shell/shortcuts.ts +4 -1
  179. package/src/components/layout/shell/window-mode/overlays.tsx +3 -2
  180. package/src/components/layout/status-bar.tsx +34 -47
  181. package/src/components/layout/titlebar-overlay.ts +3 -14
  182. package/src/components/layout/window-edit/status.tsx +3 -9
  183. package/src/components/markdown-text.tsx +306 -2
  184. package/src/components/market-board/index.tsx +60 -16
  185. package/src/components/onboarding/account-step/form-panel.tsx +2 -2
  186. package/src/components/onboarding/account-step/qr-panel.tsx +13 -30
  187. package/src/components/onboarding/account-step/signed-in-panel.tsx +2 -2
  188. package/src/components/onboarding/first-run-workspace.ts +8 -6
  189. package/src/components/onboarding/onboarding-frame.tsx +11 -15
  190. package/src/components/onboarding/onboarding-wizard.tsx +51 -30
  191. package/src/components/onboarding/portfolio-step/broker-fields-panel.tsx +2 -2
  192. package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
  193. package/src/components/onboarding/portfolio-step/broker-sync-panel.tsx +2 -2
  194. package/src/components/onboarding/portfolio-step/choose-panel.tsx +2 -2
  195. package/src/components/onboarding/portfolio-step/positions-panel.tsx +2 -2
  196. package/src/components/onboarding/wizard-broker-sync.ts +122 -51
  197. package/src/components/onboarding/wizard-model.ts +20 -7
  198. package/src/components/onboarding/wizard-positions.ts +1 -1
  199. package/src/components/paged-rows.ts +217 -0
  200. package/src/components/pane-settings-dialog/field-dialogs.tsx +2 -2
  201. package/src/components/pane-settings-dialog.tsx +2 -2
  202. package/src/components/price-sparkline/model.ts +11 -8
  203. package/src/components/price-sparkline/view.tsx +10 -7
  204. package/src/components/sign-in-code-panel.tsx +128 -0
  205. package/src/components/sign-in-gate.tsx +8 -22
  206. package/src/components/speedometer-gauge/index.tsx +2 -2
  207. package/src/components/speedometer-gauge/model.ts +1 -4
  208. package/src/components/table-view-shared.tsx +0 -44
  209. package/src/components/ticker/badge/format.ts +0 -4
  210. package/src/components/ticker/list-table-view.tsx +6 -37
  211. package/src/components/toggle-list.tsx +2 -2
  212. package/src/components/ui/choice-dialog.tsx +4 -8
  213. package/src/components/ui/confirm-dialog.tsx +21 -1
  214. package/src/components/ui/data-table/hooks.ts +46 -0
  215. package/src/components/ui/data-table/opentui/index.tsx +21 -30
  216. package/src/components/ui/data-table/opentui/model.ts +0 -21
  217. package/src/components/ui/data-table/types.ts +20 -0
  218. package/src/components/ui/data-table/visible-range.ts +26 -2
  219. package/src/components/ui/detail-scroll-body.tsx +48 -0
  220. package/src/components/ui/disclosure-marker.tsx +2 -2
  221. package/src/components/ui/display.tsx +8 -4
  222. package/src/components/ui/field-grid.tsx +26 -2
  223. package/src/components/ui/field-ring.ts +125 -0
  224. package/src/components/ui/fields.tsx +65 -3
  225. package/src/components/ui/index.ts +18 -7
  226. package/src/components/ui/multi-select/dialog.tsx +3 -3
  227. package/src/components/ui/page-stack-view.tsx +2 -0
  228. package/src/components/ui/prose.tsx +52 -0
  229. package/src/components/ui/query-bar.tsx +37 -9
  230. package/src/components/ui/reveal-in-scroll-box.ts +34 -0
  231. package/src/components/ui/select-button.tsx +2 -2
  232. package/src/components/ui/split-bar.tsx +69 -0
  233. package/src/components/ui/stat-grid.tsx +38 -14
  234. package/src/components/ui/status.tsx +2 -0
  235. package/src/components/ui/text-prompt-dialog.tsx +128 -0
  236. package/src/core/app-runtime.ts +5 -0
  237. package/src/core/connection-health.ts +2 -4
  238. package/src/core/state/app/layout.ts +13 -0
  239. package/src/core/state/app/types.ts +16 -0
  240. package/src/core/state/session-persistence.ts +8 -14
  241. package/src/data/cached-query.ts +5 -0
  242. package/src/data/config/chart-settings.ts +14 -21
  243. package/src/data/config/layout.ts +0 -8
  244. package/src/data/config/store/migrations.ts +74 -141
  245. package/src/data/config/store/node.ts +29 -3
  246. package/src/data/config/store/normalize.ts +35 -63
  247. package/src/data/config/store/pane-state.ts +47 -0
  248. package/src/data/fred-series.ts +7 -18
  249. package/src/data/json-persistence.ts +1 -4
  250. package/src/data/json-ticker-repository.ts +1 -4
  251. package/src/i18n/es.ts +26 -5
  252. package/src/i18n/ja.ts +26 -5
  253. package/src/i18n/ko.ts +26 -5
  254. package/src/i18n/languages.ts +18 -0
  255. package/src/i18n/zh-cn.ts +26 -5
  256. package/src/i18n/zh-tw.ts +26 -5
  257. package/src/layout-marketplace/cloud.ts +11 -54
  258. package/src/layout-marketplace/gallery.tsx +32 -46
  259. package/src/layout-marketplace/linked-sync.ts +1 -2
  260. package/src/layout-marketplace/payload.ts +16 -19
  261. package/src/market-data/coordinator/chart.ts +5 -4
  262. package/src/market-data/coordinator/events.ts +15 -2
  263. package/src/market-data/coordinator/index.ts +37 -9
  264. package/src/market-data/coordinator/quotes.ts +2 -9
  265. package/src/market-data/history-session.ts +2 -9
  266. package/src/market-data/hooks.tsx +3 -3
  267. package/src/market-data/market/format.ts +26 -0
  268. package/src/market-data/market/freshness.ts +5 -34
  269. package/src/market-data/market/price-basis.ts +1 -1
  270. package/src/market-data/market/status.ts +1 -1
  271. package/src/market-data/query-store.ts +37 -31
  272. package/src/market-data/quotes/day-range.ts +2 -8
  273. package/src/market-data/quotes/freshness.ts +2 -4
  274. package/src/market-data/quotes/screener-live-quotes.ts +162 -0
  275. package/src/market-data/realized-volatility.ts +292 -0
  276. package/src/market-data/selectors.ts +27 -10
  277. package/src/market-data/snapshot-provider.ts +3 -2
  278. package/src/news/aggregator.ts +0 -35
  279. package/src/news/source-label.ts +22 -0
  280. package/src/news/types.ts +1 -0
  281. package/src/pane-settings.ts +0 -8
  282. package/src/plugins/absorbed.ts +33 -0
  283. package/src/plugins/auto-update-node.ts +113 -0
  284. package/src/plugins/auto-update.ts +281 -0
  285. package/src/plugins/builtin/account-management/form-components.tsx +8 -83
  286. package/src/plugins/builtin/account-management/index.tsx +26 -0
  287. package/src/plugins/builtin/account-management/keyboard.ts +50 -98
  288. package/src/plugins/builtin/account-management/model.ts +19 -53
  289. package/src/plugins/builtin/account-management/navigation.ts +6 -21
  290. package/src/plugins/builtin/account-management/pane.tsx +76 -187
  291. package/src/plugins/builtin/account-management/password-dialog.tsx +10 -8
  292. package/src/plugins/builtin/alerts/cli.ts +96 -0
  293. package/src/plugins/builtin/alerts/events-pane.tsx +22 -50
  294. package/src/plugins/builtin/alerts/history-pane.tsx +20 -59
  295. package/src/plugins/builtin/alerts/history.ts +1 -1
  296. package/src/plugins/builtin/alerts/index.tsx +2 -0
  297. package/src/plugins/builtin/alerts/pane.tsx +27 -65
  298. package/src/plugins/builtin/alerts/research-rules.ts +8 -3
  299. package/src/plugins/builtin/analytics/account-returns.ts +109 -0
  300. package/src/plugins/builtin/analytics/broker-performance.ts +4 -2
  301. package/src/plugins/builtin/analytics/display.ts +0 -32
  302. package/src/plugins/builtin/analytics/index.tsx +119 -88
  303. package/src/plugins/builtin/analytics/metrics.ts +0 -26
  304. package/src/plugins/builtin/analytics/pane-model.ts +25 -17
  305. package/src/plugins/builtin/analytics/risk-client.ts +11 -14
  306. package/src/plugins/builtin/analytics/risk-evidence.ts +45 -15
  307. package/src/plugins/builtin/analytics/risk-pane.tsx +134 -139
  308. package/src/plugins/builtin/analytics/sector-model.ts +0 -11
  309. package/src/plugins/builtin/analytics/view.tsx +92 -111
  310. package/src/plugins/builtin/backtest/client.ts +5 -6
  311. package/src/plugins/builtin/backtest/pane.tsx +35 -41
  312. package/src/plugins/builtin/backtest/rules.ts +0 -8
  313. package/src/plugins/builtin/bond-calculator/model.ts +0 -1
  314. package/src/plugins/builtin/bond-calculator/pane.tsx +8 -15
  315. package/src/plugins/builtin/broker-manager/detail.tsx +39 -76
  316. package/src/plugins/builtin/broker-manager/footer.ts +3 -3
  317. package/src/plugins/builtin/broker-manager/index.tsx +24 -4
  318. package/src/plugins/builtin/broker-manager/keyboard.ts +7 -30
  319. package/src/plugins/builtin/broker-manager/model.ts +4 -7
  320. package/src/plugins/builtin/broker-manager/pane-actions.tsx +74 -34
  321. package/src/plugins/builtin/broker-manager/table.ts +3 -12
  322. package/src/plugins/builtin/buildout/cells.tsx +34 -36
  323. package/src/plugins/builtin/buildout/detail/company.tsx +5 -4
  324. package/src/plugins/builtin/buildout/detail/site.tsx +6 -5
  325. package/src/plugins/builtin/buildout/detail/ui.tsx +10 -9
  326. package/src/plugins/builtin/buildout/format.ts +3 -8
  327. package/src/plugins/builtin/buildout/index.tsx +23 -0
  328. package/src/plugins/builtin/buildout/model/types.ts +0 -1
  329. package/src/plugins/builtin/buildout/pane/index.tsx +18 -40
  330. package/src/plugins/builtin/buildout/table-model.ts +1 -1
  331. package/src/plugins/builtin/builtin-plugin-meta.ts +51 -0
  332. package/src/plugins/builtin/cds/client.ts +33 -1
  333. package/src/plugins/builtin/cds/index.tsx +4 -4
  334. package/src/plugins/builtin/cds/model.ts +56 -10
  335. package/src/plugins/builtin/cds/pane.tsx +139 -49
  336. package/src/plugins/builtin/central-bank-rates/client.ts +5 -17
  337. package/src/plugins/builtin/central-bank-rates/headless.ts +1 -1
  338. package/src/plugins/builtin/central-bank-rates/index.tsx +1 -1
  339. package/src/plugins/builtin/central-bank-rates/pane.tsx +15 -20
  340. package/src/plugins/builtin/changelog/index.tsx +23 -105
  341. package/src/plugins/builtin/changelog/model.ts +2 -12
  342. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +3 -2
  343. package/src/plugins/builtin/chart-composer/chart-spec.ts +1 -4
  344. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +20 -71
  345. package/src/plugins/builtin/chart-composer/editor/controller.ts +8 -12
  346. package/src/plugins/builtin/chart-composer/editor.tsx +2 -2
  347. package/src/plugins/builtin/chart-composer/follow-binding.ts +6 -1
  348. package/src/plugins/builtin/chart-composer/index.tsx +6 -9
  349. package/src/plugins/builtin/chart-composer/pane.tsx +50 -3
  350. package/src/plugins/builtin/chart-composer/presets.ts +34 -0
  351. package/src/plugins/builtin/chart-composer/quick-add.tsx +17 -23
  352. package/src/plugins/builtin/chart-composer/semantic.ts +1 -0
  353. package/src/plugins/builtin/chart-composer/settings.ts +1 -1
  354. package/src/plugins/builtin/chat/channels.ts +0 -2
  355. package/src/plugins/builtin/chat/content/index.tsx +1 -1
  356. package/src/plugins/builtin/chat/content/layout-metrics.ts +3 -6
  357. package/src/plugins/builtin/chat/controller/fetch.ts +1 -14
  358. package/src/plugins/builtin/chat/controller/state.ts +4 -2
  359. package/src/plugins/builtin/chat/controller/utils.ts +0 -14
  360. package/src/plugins/builtin/chat/index.tsx +105 -0
  361. package/src/plugins/builtin/chat/message/desktop.tsx +22 -94
  362. package/src/plugins/builtin/chat/message/header.tsx +83 -0
  363. package/src/plugins/builtin/chat/message/profile-popover.tsx +1 -1
  364. package/src/plugins/builtin/chat/message/render-state.ts +10 -2
  365. package/src/plugins/builtin/chat/message/terminal.tsx +22 -78
  366. package/src/plugins/builtin/chat/pane.tsx +112 -124
  367. package/src/plugins/builtin/chat/sidebar.tsx +2 -18
  368. package/src/plugins/builtin/chat/status-widget.tsx +0 -3
  369. package/src/plugins/builtin/cloud/askg/executor.ts +14 -39
  370. package/src/plugins/builtin/cloud/askg/json.ts +31 -0
  371. package/src/plugins/builtin/cloud/askg/manifest.ts +1 -1
  372. package/src/plugins/builtin/cloud/askg/pane.tsx +10 -16
  373. package/src/plugins/builtin/cloud/askg/pending-question.ts +5 -27
  374. package/src/plugins/builtin/cloud/askg/protocol.ts +1 -15
  375. package/src/plugins/builtin/cloud/askg/undo.ts +4 -29
  376. package/src/plugins/builtin/cloud/auth-actions.tsx +28 -1
  377. package/src/plugins/builtin/cloud/browser.tsx +1 -7
  378. package/src/plugins/builtin/cloud/device-signin-dialog.tsx +64 -147
  379. package/src/plugins/builtin/cloud/index.tsx +2 -11
  380. package/src/plugins/builtin/cloud/plugin.tsx +13 -151
  381. package/src/plugins/builtin/cloud/team/collections-sync.ts +4 -2
  382. package/src/plugins/builtin/cloud/team/collections.ts +0 -4
  383. package/src/plugins/builtin/cloud/team/model.ts +0 -4
  384. package/src/plugins/builtin/cloud/team/module.tsx +0 -3
  385. package/src/plugins/builtin/cloud/team/pane-model.ts +0 -7
  386. package/src/plugins/builtin/cloud/team/pane-request.ts +5 -22
  387. package/src/plugins/builtin/cloud/team/pane-sections.tsx +1 -1
  388. package/src/plugins/builtin/cloud/team/pane-ui.tsx +15 -24
  389. package/src/plugins/builtin/cloud/team/pane.tsx +21 -58
  390. package/src/plugins/builtin/cloud/thesis/board-pane.tsx +31 -50
  391. package/src/plugins/builtin/cloud/thesis/detail.tsx +1 -1
  392. package/src/plugins/builtin/cloud/thesis/exposure.ts +1 -4
  393. package/src/plugins/builtin/cloud/thesis/flows.ts +8 -7
  394. package/src/plugins/builtin/cloud/thesis/model.ts +0 -7
  395. package/src/plugins/builtin/cloud/thesis/pane-request.ts +5 -22
  396. package/src/plugins/builtin/cloud/thesis/prompts.tsx +13 -125
  397. package/src/plugins/builtin/cloud/thesis/ticker-tab.tsx +1 -1
  398. package/src/plugins/builtin/cloud/upgrade-command.ts +1 -1
  399. package/src/plugins/builtin/cloud/upgrade-dialog.tsx +231 -0
  400. package/src/plugins/builtin/cloud/upgrade-status-widget.tsx +2 -4
  401. package/src/plugins/builtin/cloud/verification-status-widget.tsx +2 -4
  402. package/src/plugins/builtin/cloud-tweets/footer.ts +2 -2
  403. package/src/plugins/builtin/cloud-tweets/index.ts +6 -0
  404. package/src/plugins/builtin/cloud-tweets/keyboard.ts +1 -32
  405. package/src/plugins/builtin/cloud-tweets/model.ts +1 -5
  406. package/src/plugins/builtin/cloud-tweets/pane.tsx +10 -43
  407. package/src/plugins/builtin/cloud-tweets/registration.ts +5 -8
  408. package/src/plugins/builtin/cloud-tweets/search-bar.tsx +5 -20
  409. package/src/plugins/builtin/cloud-tweets/table.tsx +16 -23
  410. package/src/plugins/builtin/composite-plugins.ts +77 -37
  411. package/src/plugins/builtin/congress-trades/detail.tsx +28 -81
  412. package/src/plugins/builtin/congress-trades/footer.ts +1 -1
  413. package/src/plugins/builtin/congress-trades/headless.ts +22 -45
  414. package/src/plugins/builtin/congress-trades/keyboard.ts +9 -78
  415. package/src/plugins/builtin/congress-trades/model.ts +4 -27
  416. package/src/plugins/builtin/congress-trades/pane.tsx +17 -38
  417. package/src/plugins/builtin/congress-trades/table.tsx +29 -34
  418. package/src/plugins/builtin/connections/pane.tsx +5 -12
  419. package/src/plugins/builtin/correlation/index.tsx +3 -5
  420. package/src/plugins/builtin/correlation/relationship/pane.tsx +6 -7
  421. package/src/plugins/builtin/correlation/relationship/view-model.ts +7 -18
  422. package/src/plugins/builtin/cot/client.ts +14 -18
  423. package/src/plugins/builtin/cot/index.tsx +3 -2
  424. package/src/plugins/builtin/cot/model.ts +13 -10
  425. package/src/plugins/builtin/cot/pane.tsx +70 -45
  426. package/src/plugins/builtin/credit-boards/cdx-pane.tsx +140 -0
  427. package/src/plugins/builtin/credit-boards/client.ts +108 -0
  428. package/src/plugins/builtin/credit-boards/headless.ts +73 -0
  429. package/src/plugins/builtin/credit-boards/index.tsx +62 -0
  430. package/src/plugins/builtin/credit-boards/model.ts +221 -0
  431. package/src/plugins/builtin/credit-boards/sovr-pane.tsx +144 -0
  432. package/src/plugins/builtin/credit-conditions/index.tsx +33 -33
  433. package/src/plugins/builtin/crypto-board/client.ts +11 -34
  434. package/src/plugins/builtin/crypto-board/index.tsx +1 -1
  435. package/src/plugins/builtin/crypto-board/model.ts +14 -16
  436. package/src/plugins/builtin/crypto-board/pane.tsx +24 -50
  437. package/src/plugins/builtin/custom-view/index.tsx +1 -1
  438. package/src/plugins/builtin/custom-view/pane.tsx +1 -1
  439. package/src/plugins/builtin/custom-view/view-spec.ts +9 -12
  440. package/src/plugins/builtin/debt-maturities/client.ts +15 -42
  441. package/src/plugins/builtin/debt-maturities/model.ts +96 -31
  442. package/src/plugins/builtin/debt-maturities/pane.tsx +196 -223
  443. package/src/plugins/builtin/debt-maturities/wall-bar.tsx +63 -0
  444. package/src/plugins/builtin/debug/index.tsx +17 -46
  445. package/src/plugins/builtin/dividend-yield/client.ts +13 -33
  446. package/src/plugins/builtin/dividend-yield/model.ts +10 -22
  447. package/src/plugins/builtin/dividend-yield/pane.tsx +97 -143
  448. package/src/plugins/builtin/dividend-yield/trailing-cash.ts +3 -3
  449. package/src/plugins/builtin/dividend-yield/view.ts +2 -2
  450. package/src/plugins/builtin/earnings/board-model.ts +197 -0
  451. package/src/plugins/builtin/earnings/board-table.ts +84 -0
  452. package/src/plugins/builtin/earnings/board.tsx +236 -0
  453. package/src/plugins/builtin/earnings/client.ts +97 -0
  454. package/src/plugins/builtin/earnings/format.ts +62 -0
  455. package/src/plugins/builtin/earnings/headless.ts +134 -138
  456. package/src/plugins/builtin/earnings/history-model.ts +174 -0
  457. package/src/plugins/builtin/earnings/history-table.ts +84 -0
  458. package/src/plugins/builtin/earnings/history.tsx +107 -0
  459. package/src/plugins/builtin/earnings/index.tsx +70 -270
  460. package/src/plugins/builtin/earnings/model.ts +0 -99
  461. package/src/plugins/builtin/earnings-calls/data.ts +0 -5
  462. package/src/plugins/builtin/earnings-calls/format.ts +2 -8
  463. package/src/plugins/builtin/earnings-calls/index.tsx +0 -1
  464. package/src/plugins/builtin/earnings-calls/pane.tsx +16 -63
  465. package/src/plugins/builtin/earnings-calls/transcript-view.tsx +18 -61
  466. package/src/plugins/builtin/econ/calendar-model.ts +34 -1
  467. package/src/plugins/builtin/econ/detail-view.tsx +124 -139
  468. package/src/plugins/builtin/econ/fred-series-map.ts +1 -5
  469. package/src/plugins/builtin/econ/index.tsx +51 -90
  470. package/src/plugins/builtin/econ-statistics/client.ts +5 -4
  471. package/src/plugins/builtin/econ-statistics/defs.ts +1 -1
  472. package/src/plugins/builtin/econ-statistics/detail.tsx +32 -104
  473. package/src/plugins/builtin/econ-statistics/headless.ts +28 -50
  474. package/src/plugins/builtin/econ-statistics/index.tsx +1 -1
  475. package/src/plugins/builtin/econ-statistics/pane.tsx +36 -152
  476. package/src/plugins/builtin/econ-statistics/stats.ts +0 -5
  477. package/src/plugins/builtin/econ-statistics/view.ts +2 -4
  478. package/src/plugins/builtin/equity-screener/client.ts +2 -2
  479. package/src/plugins/builtin/equity-screener/live.ts +7 -9
  480. package/src/plugins/builtin/equity-screener/model.ts +67 -9
  481. package/src/plugins/builtin/equity-screener/pane.tsx +39 -58
  482. package/src/plugins/builtin/equity-screener/results.ts +2 -4
  483. package/src/plugins/builtin/estimate-revisions/client.ts +20 -49
  484. package/src/plugins/builtin/estimate-revisions/pane.tsx +71 -104
  485. package/src/plugins/builtin/executives/data.ts +3 -8
  486. package/src/plugins/builtin/executives/format.ts +3 -17
  487. package/src/plugins/builtin/executives/pane.tsx +33 -186
  488. package/src/plugins/builtin/fear-greed/cache.ts +100 -0
  489. package/src/plugins/builtin/fear-greed/charts.tsx +258 -0
  490. package/src/plugins/builtin/fear-greed/data.ts +376 -0
  491. package/src/plugins/builtin/fear-greed/format.ts +87 -0
  492. package/src/plugins/builtin/fear-greed/headless.ts +85 -0
  493. package/src/plugins/builtin/fear-greed/index.tsx +89 -0
  494. package/src/plugins/builtin/fear-greed/pane.tsx +112 -0
  495. package/src/plugins/builtin/filing-events/feed.ts +4 -14
  496. package/src/plugins/builtin/filing-events/pane.tsx +7 -21
  497. package/src/plugins/builtin/futures/contracts.ts +55 -33
  498. package/src/plugins/builtin/futures/index.tsx +61 -47
  499. package/src/plugins/builtin/futures/model.ts +39 -17
  500. package/src/plugins/builtin/futures/returns.ts +132 -0
  501. package/src/plugins/builtin/futures/table.tsx +72 -63
  502. package/src/plugins/builtin/futures/use-front-returns.ts +119 -0
  503. package/src/plugins/builtin/futures-curve/client.ts +30 -15
  504. package/src/plugins/builtin/futures-curve/headless.ts +10 -4
  505. package/src/plugins/builtin/futures-curve/index.tsx +2 -1
  506. package/src/plugins/builtin/futures-curve/model.ts +133 -18
  507. package/src/plugins/builtin/futures-curve/pane.tsx +141 -45
  508. package/src/plugins/builtin/fx-matrix/index.tsx +9 -17
  509. package/src/plugins/builtin/help/functions-table.tsx +2 -19
  510. package/src/plugins/builtin/help/index.tsx +6 -26
  511. package/src/plugins/builtin/help/shortcut-model.ts +7 -1
  512. package/src/plugins/builtin/holders/headless.ts +2 -2
  513. package/src/plugins/builtin/holders/index.tsx +0 -1
  514. package/src/plugins/builtin/holders/pane.tsx +43 -83
  515. package/src/plugins/builtin/holders/table-model.ts +1 -15
  516. package/src/plugins/builtin/holders/thirteenf-match.ts +4 -3
  517. package/src/plugins/builtin/holders/types.ts +1 -1
  518. package/src/plugins/builtin/insider/index.tsx +0 -1
  519. package/src/plugins/builtin/ipo-calendar/client.ts +93 -0
  520. package/src/plugins/builtin/ipo-calendar/headless.ts +159 -0
  521. package/src/plugins/builtin/ipo-calendar/index.tsx +47 -0
  522. package/src/plugins/builtin/ipo-calendar/model.ts +341 -0
  523. package/src/plugins/builtin/ipo-calendar/pane.tsx +233 -0
  524. package/src/plugins/builtin/iv-history/index.tsx +0 -1
  525. package/src/plugins/builtin/iv-history/pane.tsx +7 -4
  526. package/src/plugins/builtin/iv-history/rank.ts +0 -7
  527. package/src/plugins/builtin/iv-history/screen-pane.tsx +7 -12
  528. package/src/plugins/builtin/jobs/headless.ts +58 -76
  529. package/src/plugins/builtin/jobs/index.tsx +0 -1
  530. package/src/plugins/builtin/jobs/model.ts +7 -15
  531. package/src/plugins/builtin/jobs/pane.tsx +190 -154
  532. package/src/plugins/builtin/jobs/share-bars.tsx +2 -2
  533. package/src/plugins/builtin/kelly-sizer/fields.ts +1 -1
  534. package/src/plugins/builtin/kelly-sizer/model.ts +1 -26
  535. package/src/plugins/builtin/kelly-sizer/pane.tsx +22 -67
  536. package/src/plugins/builtin/kelly-sizer/sections.tsx +1 -1
  537. package/src/plugins/builtin/kelly-sizer/state.ts +2 -2
  538. package/src/plugins/builtin/kelly-sizer/test-support.tsx +18 -27
  539. package/src/plugins/builtin/layout-manager/index.tsx +13 -50
  540. package/src/plugins/builtin/macro-resources.ts +15 -0
  541. package/src/plugins/builtin/market-halts/client.ts +114 -0
  542. package/src/plugins/builtin/market-halts/index.tsx +41 -0
  543. package/src/plugins/builtin/market-halts/model.ts +323 -0
  544. package/src/plugins/builtin/market-halts/pane.tsx +239 -0
  545. package/src/plugins/builtin/market-heatmap/data.ts +305 -0
  546. package/src/plugins/builtin/market-heatmap/index.tsx +447 -0
  547. package/src/plugins/builtin/market-movers/client.ts +30 -3
  548. package/src/plugins/builtin/market-movers/footer.ts +19 -0
  549. package/src/plugins/builtin/market-movers/headless.ts +71 -5
  550. package/src/plugins/builtin/market-movers/index.tsx +135 -101
  551. package/src/plugins/builtin/market-movers/model.ts +11 -17
  552. package/src/plugins/builtin/market-movers/screener.ts +2 -8
  553. package/src/plugins/builtin/market-movers/session-body.tsx +237 -0
  554. package/src/plugins/builtin/market-movers/session-table.ts +96 -0
  555. package/src/plugins/builtin/market-movers/session.ts +233 -0
  556. package/src/plugins/builtin/market-movers/table.ts +15 -15
  557. package/src/plugins/builtin/market-valuation/cache.ts +2 -39
  558. package/src/plugins/builtin/market-valuation/chart-projection.ts +11 -34
  559. package/src/plugins/builtin/market-valuation/client.ts +4 -5
  560. package/src/plugins/builtin/market-valuation/defs.ts +0 -9
  561. package/src/plugins/builtin/market-valuation/detail.tsx +32 -89
  562. package/src/plugins/builtin/market-valuation/headless.ts +31 -51
  563. package/src/plugins/builtin/market-valuation/index.tsx +11 -1
  564. package/src/plugins/builtin/market-valuation/pane.tsx +37 -179
  565. package/src/plugins/builtin/market-valuation/view.ts +6 -7
  566. package/src/plugins/builtin/market-valuation/zone-scale/index.tsx +2 -2
  567. package/src/plugins/builtin/mna/client.ts +143 -0
  568. package/src/plugins/builtin/mna/detail.tsx +297 -0
  569. package/src/plugins/builtin/mna/headless.ts +82 -0
  570. package/src/plugins/builtin/mna/index.tsx +55 -0
  571. package/src/plugins/builtin/mna/model.ts +208 -0
  572. package/src/plugins/builtin/mna/pane.tsx +432 -0
  573. package/src/plugins/builtin/money-markets/client.ts +5 -17
  574. package/src/plugins/builtin/money-markets/model.ts +20 -0
  575. package/src/plugins/builtin/money-markets/pane.tsx +79 -46
  576. package/src/plugins/builtin/news/index.tsx +13 -14
  577. package/src/plugins/builtin/news/wire/categories.ts +35 -12
  578. package/src/plugins/builtin/news/wire/feed-config.ts +4 -13
  579. package/src/plugins/builtin/news/wire/index.tsx +43 -27
  580. package/src/plugins/builtin/news/wire/industry-pane.tsx +110 -105
  581. package/src/plugins/builtin/news/wire/news/detail-view.tsx +8 -25
  582. package/src/plugins/builtin/news/wire/news/footer.ts +2 -2
  583. package/src/plugins/builtin/news/wire/news/preset-pane.tsx +111 -61
  584. package/src/plugins/builtin/news/wire/news/query-presets.ts +66 -1
  585. package/src/plugins/builtin/news/wire/news/table.tsx +19 -62
  586. package/src/plugins/builtin/news/wire/read-state.ts +3 -17
  587. package/src/plugins/builtin/news/wire/rss/cli.ts +47 -0
  588. package/src/plugins/builtin/news/wire/rss/parser.ts +0 -4
  589. package/src/plugins/builtin/news/wire/rss/source.ts +2 -2
  590. package/src/plugins/builtin/notes/cli.ts +95 -0
  591. package/src/plugins/builtin/notes/files.ts +145 -88
  592. package/src/plugins/builtin/notes/index.tsx +4 -2
  593. package/src/plugins/builtin/notes/migration.ts +3 -1
  594. package/src/plugins/builtin/notes/quick-notes-pane.tsx +24 -40
  595. package/src/plugins/builtin/notes/ticker-notes-tab.tsx +4 -1
  596. package/src/plugins/builtin/options/analytics.ts +5 -7
  597. package/src/plugins/builtin/options/calc-seed.ts +2 -1
  598. package/src/plugins/builtin/options/enrichment-client.ts +10 -19
  599. package/src/plugins/builtin/options/enrichment-model.ts +1 -2
  600. package/src/plugins/builtin/options/footer.ts +2 -2
  601. package/src/plugins/builtin/options/index.tsx +1 -1
  602. package/src/plugins/builtin/options/live-quotes.ts +1 -4
  603. package/src/plugins/builtin/options/table.ts +15 -15
  604. package/src/plugins/builtin/options/types.ts +1 -1
  605. package/src/plugins/builtin/options/view.tsx +31 -9
  606. package/src/plugins/builtin/options-calculator/binomial.ts +17 -16
  607. package/src/plugins/builtin/options-calculator/evidence.ts +90 -24
  608. package/src/plugins/builtin/options-calculator/headless.ts +2 -1
  609. package/src/plugins/builtin/options-calculator/model.ts +2 -207
  610. package/src/plugins/builtin/options-calculator/pane.tsx +11 -39
  611. package/src/plugins/builtin/options-calculator/surface.ts +11 -21
  612. package/src/plugins/builtin/options-scenario/client.ts +9 -20
  613. package/src/plugins/builtin/options-scenario/evidence.ts +64 -8
  614. package/src/plugins/builtin/options-scenario/live.ts +2 -2
  615. package/src/plugins/builtin/options-scenario/model.ts +18 -28
  616. package/src/plugins/builtin/options-scenario/pane.tsx +18 -19
  617. package/src/plugins/builtin/plugin-marketplace/activation.ts +70 -0
  618. package/src/plugins/builtin/plugin-marketplace/feed.ts +12 -0
  619. package/src/plugins/builtin/plugin-marketplace/index.tsx +16 -4
  620. package/src/plugins/builtin/plugin-marketplace/model.ts +67 -9
  621. package/src/plugins/builtin/plugin-marketplace/pane.tsx +67 -101
  622. package/src/plugins/builtin/plugin-marketplace/store.ts +19 -1
  623. package/src/plugins/builtin/plugin-module.ts +4 -11
  624. package/src/plugins/builtin/portfolio-list/account-metrics.ts +17 -15
  625. package/src/plugins/builtin/portfolio-list/cli/render.ts +3 -4
  626. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +2 -1
  627. package/src/plugins/builtin/portfolio-list/column-values.ts +23 -34
  628. package/src/plugins/builtin/portfolio-list/index.tsx +1 -1
  629. package/src/plugins/builtin/portfolio-list/pane/index.tsx +19 -38
  630. package/src/plugins/builtin/portfolio-list/position-metrics.ts +0 -8
  631. package/src/plugins/builtin/portfolio-list/summary/index.tsx +20 -16
  632. package/src/plugins/builtin/rate-path/client.ts +7 -16
  633. package/src/plugins/builtin/rate-path/headless.ts +13 -9
  634. package/src/plugins/builtin/rate-path/model.ts +74 -17
  635. package/src/plugins/builtin/rate-path/pane.tsx +128 -63
  636. package/src/plugins/builtin/realized-vol/client.ts +13 -23
  637. package/src/plugins/builtin/realized-vol/evidence.ts +43 -20
  638. package/src/plugins/builtin/realized-vol/pane.tsx +13 -19
  639. package/src/plugins/builtin/relative-rotation/client.ts +9 -35
  640. package/src/plugins/builtin/relative-rotation/pane.tsx +46 -65
  641. package/src/plugins/builtin/research/analyst-model.ts +35 -32
  642. package/src/plugins/builtin/research/analyst-pane.tsx +124 -128
  643. package/src/plugins/builtin/research/corporate-actions-pane.tsx +23 -70
  644. package/src/plugins/builtin/research/equity-diagnostic-pane.tsx +7 -11
  645. package/src/plugins/builtin/research/event-sources.ts +64 -0
  646. package/src/plugins/builtin/research/events-headless.ts +7 -32
  647. package/src/plugins/builtin/research/headless.ts +11 -51
  648. package/src/plugins/builtin/research/index.tsx +0 -3
  649. package/src/plugins/builtin/research/relative-valuation-model.ts +0 -1
  650. package/src/plugins/builtin/research/relative-valuation-pane.tsx +50 -86
  651. package/src/plugins/builtin/research-search/data.ts +0 -4
  652. package/src/plugins/builtin/research-search/document-view.tsx +3 -9
  653. package/src/plugins/builtin/research-search/index.tsx +1 -0
  654. package/src/plugins/builtin/research-search/model.ts +4 -20
  655. package/src/plugins/builtin/research-search/pane.tsx +44 -131
  656. package/src/plugins/builtin/research-search/saved-view.tsx +10 -13
  657. package/src/plugins/builtin/revenue-breakdown/bars.tsx +113 -0
  658. package/src/plugins/builtin/revenue-breakdown/client.ts +114 -0
  659. package/src/plugins/builtin/revenue-breakdown/headless.ts +72 -0
  660. package/src/plugins/builtin/revenue-breakdown/index.tsx +58 -0
  661. package/src/plugins/builtin/revenue-breakdown/model.ts +157 -0
  662. package/src/plugins/builtin/revenue-breakdown/pane.tsx +290 -0
  663. package/src/plugins/builtin/risk-factors/data.ts +3 -8
  664. package/src/plugins/builtin/risk-factors/index.tsx +0 -1
  665. package/src/plugins/builtin/risk-factors/pane.tsx +29 -107
  666. package/src/plugins/builtin/scanner/denied.tsx +4 -16
  667. package/src/plugins/builtin/scanner/feed.ts +2 -2
  668. package/src/plugins/builtin/scanner/flow-pane.tsx +11 -18
  669. package/src/plugins/builtin/scanner/hilo-bars.tsx +31 -16
  670. package/src/plugins/builtin/scanner/hilo-model.ts +33 -0
  671. package/src/plugins/builtin/scanner/hilo-pane.tsx +8 -11
  672. package/src/plugins/builtin/scanner/index.ts +2 -3
  673. package/src/plugins/builtin/sec/filing-display.tsx +2 -6
  674. package/src/plugins/builtin/sec/index.tsx +2 -1
  675. package/src/plugins/builtin/sec/model.ts +8 -4
  676. package/src/plugins/builtin/sectors/index.tsx +19 -40
  677. package/src/plugins/builtin/sectors/move-bar.tsx +2 -2
  678. package/src/plugins/builtin/sectors/sector-model.ts +0 -5
  679. package/src/plugins/builtin/shared/cloud-resource.ts +56 -0
  680. package/src/plugins/builtin/shared/cloud-upgrade.ts +46 -11
  681. package/src/plugins/builtin/shared/filing-year-reader.tsx +123 -0
  682. package/src/plugins/builtin/shared/locked-rows.tsx +56 -0
  683. package/src/plugins/builtin/shared/pane-request.ts +35 -0
  684. package/src/plugins/builtin/shared/research-cloud-session.ts +1 -1
  685. package/src/plugins/builtin/shared/series-detail-chart.tsx +168 -0
  686. package/src/plugins/builtin/shared/series-list-detail.tsx +208 -0
  687. package/src/plugins/builtin/shared/stat-transform.ts +94 -0
  688. package/src/plugins/builtin/shared/ticker-request.ts +0 -6
  689. package/src/plugins/builtin/shared/trend.ts +81 -0
  690. package/src/plugins/builtin/shared/use-quote-board.ts +130 -4
  691. package/src/plugins/builtin/shared/volatility/index.ts +2 -1
  692. package/src/plugins/builtin/shared/volatility/options.ts +3 -3
  693. package/src/plugins/builtin/shared/volatility/pricing.ts +211 -0
  694. package/src/plugins/builtin/short-interest/client.ts +3 -12
  695. package/src/plugins/builtin/short-interest/index.tsx +0 -1
  696. package/src/plugins/builtin/short-interest/model.ts +51 -18
  697. package/src/plugins/builtin/short-interest/pane.tsx +64 -108
  698. package/src/plugins/builtin/short-interest/surface.tsx +9 -9
  699. package/src/plugins/builtin/short-interest/types.ts +0 -2
  700. package/src/plugins/builtin/short-volume/client.ts +8 -17
  701. package/src/plugins/builtin/short-volume/pane.tsx +28 -29
  702. package/src/plugins/builtin/social-mentions/client.ts +85 -0
  703. package/src/plugins/builtin/social-mentions/headless.ts +28 -0
  704. package/src/plugins/builtin/social-mentions/index.tsx +21 -0
  705. package/src/plugins/builtin/social-mentions/model.ts +92 -0
  706. package/src/plugins/builtin/social-mentions/pane.tsx +156 -0
  707. package/src/plugins/builtin/thirteenf/api.ts +13 -23
  708. package/src/plugins/builtin/thirteenf/data.ts +6 -8
  709. package/src/plugins/builtin/thirteenf/format.ts +3 -10
  710. package/src/plugins/builtin/thirteenf/headless.ts +9 -8
  711. package/src/plugins/builtin/thirteenf/index.tsx +0 -1
  712. package/src/plugins/builtin/thirteenf/model.ts +0 -31
  713. package/src/plugins/builtin/thirteenf/overlap-pane.tsx +12 -16
  714. package/src/plugins/builtin/thirteenf/pane.tsx +65 -255
  715. package/src/plugins/builtin/thirteenf/signals-pane.tsx +23 -44
  716. package/src/plugins/builtin/thirteenf/table.ts +58 -73
  717. package/src/plugins/builtin/thirteenf/types.ts +1 -1
  718. package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +25 -17
  719. package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +3 -7
  720. package/src/plugins/builtin/ticker-detail/financials/model.ts +121 -25
  721. package/src/plugins/builtin/ticker-detail/financials/period-end-history.ts +41 -0
  722. package/src/plugins/builtin/ticker-detail/financials/ratio-table.tsx +175 -0
  723. package/src/plugins/builtin/ticker-detail/financials/ratios.ts +669 -0
  724. package/src/plugins/builtin/ticker-detail/financials/tab.tsx +198 -111
  725. package/src/plugins/builtin/ticker-detail/headless-schema.ts +7 -2
  726. package/src/plugins/builtin/ticker-detail/headless.ts +86 -9
  727. package/src/plugins/builtin/ticker-detail/index.tsx +1 -1
  728. package/src/plugins/builtin/ticker-detail/overview/components.tsx +2 -2
  729. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +2 -5
  730. package/src/plugins/builtin/ticker-detail/pane.tsx +45 -15
  731. package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +3 -1
  732. package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +1 -1
  733. package/src/plugins/builtin/time-sales/client.ts +5 -5
  734. package/src/plugins/builtin/time-sales/model.ts +52 -0
  735. package/src/plugins/builtin/time-sales/pane.tsx +24 -19
  736. package/src/plugins/builtin/treasury-auctions/index.tsx +0 -1
  737. package/src/plugins/builtin/treasury-auctions/model.ts +3 -10
  738. package/src/plugins/builtin/treasury-auctions/pane.tsx +42 -101
  739. package/src/plugins/builtin/treasury-auctions/types.ts +0 -2
  740. package/src/plugins/builtin/vol-surface/client.ts +8 -22
  741. package/src/plugins/builtin/vol-surface/evidence.ts +45 -17
  742. package/src/plugins/builtin/vol-surface/model.ts +5 -8
  743. package/src/plugins/builtin/vol-surface/pane.tsx +24 -23
  744. package/src/plugins/builtin/vol-surface/raster.ts +1 -9
  745. package/src/plugins/builtin/vol-surface/stored.ts +3 -4
  746. package/src/plugins/builtin/vol-surface/surface.tsx +4 -3
  747. package/src/plugins/builtin/volatility/chart-model.ts +36 -0
  748. package/src/plugins/builtin/volatility/charts.tsx +3 -20
  749. package/src/plugins/builtin/volatility/client.ts +8 -16
  750. package/src/plugins/builtin/volatility/evidence.ts +37 -21
  751. package/src/plugins/builtin/volatility/index.tsx +0 -2
  752. package/src/plugins/builtin/volatility/model.ts +55 -0
  753. package/src/plugins/builtin/volatility/pane.tsx +71 -37
  754. package/src/plugins/builtin/world-indices/client.ts +1 -4
  755. package/src/plugins/builtin/world-indices/footer.ts +3 -26
  756. package/src/plugins/builtin/world-indices/index.tsx +8 -9
  757. package/src/plugins/builtin/world-indices/model.ts +0 -14
  758. package/src/plugins/builtin/world-indices/table.tsx +15 -73
  759. package/src/plugins/builtin/world-venue-map/map.tsx +2 -2
  760. package/src/plugins/builtin/world-venue-map/model.ts +1 -4
  761. package/src/plugins/builtin/world-venue-map/pane.tsx +21 -87
  762. package/src/plugins/builtin/yahoo/index.ts +4 -38
  763. package/src/plugins/builtin/yield-curve/chart.ts +100 -1
  764. package/src/plugins/builtin/yield-curve/headless.ts +2 -0
  765. package/src/plugins/builtin/yield-curve/history.ts +86 -12
  766. package/src/plugins/builtin/yield-curve/index.tsx +102 -27
  767. package/src/plugins/builtin/yield-curve/treasury-data.ts +12 -12
  768. package/src/plugins/bundle.ts +41 -41
  769. package/src/plugins/catalog-backend.ts +4 -1
  770. package/src/plugins/catalog-browser.ts +34 -53
  771. package/src/plugins/catalog-manifest.ts +10 -0
  772. package/src/plugins/catalog-ui.ts +9 -5
  773. package/src/plugins/compat.ts +216 -0
  774. package/src/plugins/current-target.ts +3 -9
  775. package/src/plugins/event-bus.ts +8 -3
  776. package/src/plugins/external-runtime.ts +0 -21
  777. package/src/plugins/host-link.ts +78 -45
  778. package/src/plugins/host-modules.ts +117 -3
  779. package/src/plugins/host-resolver.ts +1 -6
  780. package/src/plugins/installer.ts +566 -0
  781. package/src/plugins/loader.ts +120 -16
  782. package/src/plugins/manager-node.ts +28 -28
  783. package/src/plugins/ownership.ts +11 -12
  784. package/src/plugins/pane-manager/gridlock.ts +25 -8
  785. package/src/plugins/pane-manager.ts +1 -0
  786. package/src/plugins/plugin-export.ts +24 -0
  787. package/src/plugins/registry/contributions.ts +10 -4
  788. package/src/plugins/registry/index.ts +13 -12
  789. package/src/plugins/registry/pane-settings.ts +6 -3
  790. package/src/plugins/registry/shared.ts +0 -4
  791. package/src/plugins/registry/slots.ts +10 -13
  792. package/src/plugins/runtime/context.tsx +12 -34
  793. package/src/plugins/runtime/index.tsx +9 -9
  794. package/src/plugins/seed.ts +3 -7
  795. package/src/plugins/web-bundled.ts +3 -12
  796. package/src/public/__snapshots__/public-api.test.ts.snap +519 -0
  797. package/src/public/broker.ts +14 -9
  798. package/src/public/index.ts +3 -0
  799. package/src/public/market-data.ts +19 -2
  800. package/src/public/quotes.ts +4 -4
  801. package/src/public/react.ts +11 -6
  802. package/src/public/test-support.ts +10 -2
  803. package/src/public/time-series.ts +30 -3
  804. package/src/public/utils.ts +3 -4
  805. package/src/react/assign-ref.ts +10 -0
  806. package/src/react/async-resource.ts +16 -5
  807. package/src/react/auto-refresh.ts +97 -0
  808. package/src/react/plugins/plugin-slot.tsx +4 -1
  809. package/src/react/read-state.ts +104 -0
  810. package/src/react/ticker-source.ts +32 -0
  811. package/src/remote/controller-utils.ts +0 -4
  812. package/src/remote/controller.ts +18 -14
  813. package/src/remote/layout-helpers.ts +4 -9
  814. package/src/remote/resources.ts +34 -0
  815. package/src/remote/revision.ts +2 -15
  816. package/src/remote/schema.ts +1 -0
  817. package/src/renderers/browser/app-services.ts +1 -1
  818. package/src/renderers/browser/bundled-plugins.ts +8 -7
  819. package/src/renderers/browser/cloud-transport.ts +3 -11
  820. package/src/renderers/browser/config-host.ts +13 -8
  821. package/src/renderers/browser/http-proxy-transport.ts +17 -45
  822. package/src/renderers/browser/main.tsx +52 -25
  823. package/src/renderers/cloudflare/http-proxy.ts +14 -54
  824. package/src/renderers/cloudflare/worker.ts +25 -6
  825. package/src/renderers/electrobun/bun/application-menu/click.ts +8 -20
  826. package/src/renderers/electrobun/bun/application-menu/index.ts +3 -4
  827. package/src/renderers/electrobun/bun/context-menu/click.ts +7 -26
  828. package/src/renderers/electrobun/bun/context-menu/normalize.ts +4 -9
  829. package/src/renderers/electrobun/bun/core-capabilities.ts +16 -64
  830. package/src/renderers/electrobun/bun/desktop/detached-windows.ts +6 -35
  831. package/src/renderers/electrobun/bun/desktop/host-requests.ts +0 -9
  832. package/src/renderers/electrobun/bun/desktop/http-fetch.ts +15 -63
  833. package/src/renderers/electrobun/bun/desktop/http-stream.ts +6 -19
  834. package/src/renderers/electrobun/bun/desktop/initialization.ts +9 -0
  835. package/src/renderers/electrobun/bun/desktop/macos-dock-icon.ts +91 -0
  836. package/src/renderers/electrobun/bun/desktop/plugin-state.ts +0 -7
  837. package/src/renderers/electrobun/bun/external-plugins.ts +35 -95
  838. package/src/renderers/electrobun/bun/index.ts +57 -45
  839. package/src/renderers/electrobun/bun/menu-event.ts +17 -0
  840. package/src/renderers/electrobun/bun/window/controls.ts +69 -0
  841. package/src/renderers/electrobun/bun/window/create.ts +84 -0
  842. package/src/renderers/electrobun/bun/window/events.ts +49 -0
  843. package/src/renderers/electrobun/bun/window/windows-custom-chrome.ts +43 -0
  844. package/src/renderers/electrobun/bun/window/windows-icons.ts +55 -0
  845. package/src/renderers/electrobun/bun/window/windows-native.ts +96 -0
  846. package/src/renderers/electrobun/shared/protocol.ts +35 -48
  847. package/src/renderers/electrobun/shared/quote-event-batch.ts +3 -3
  848. package/src/renderers/electrobun/view/app-services.ts +1 -1
  849. package/src/renderers/electrobun/view/backend-rpc.ts +74 -141
  850. package/src/renderers/electrobun/view/broker-remote-client.ts +32 -46
  851. package/src/renderers/electrobun/view/build-assets.ts +61 -49
  852. package/src/renderers/electrobun/view/capability-stream-client.ts +5 -25
  853. package/src/renderers/electrobun/view/capability-subscription.ts +50 -0
  854. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +35 -93
  855. package/src/renderers/electrobun/view/context-menu.ts +6 -7
  856. package/src/renderers/electrobun/view/data-table/dom.ts +1 -2
  857. package/src/renderers/electrobun/view/data-table/index.tsx +17 -35
  858. package/src/renderers/electrobun/view/data-table/row.tsx +6 -2
  859. package/src/renderers/electrobun/view/desktop/controls.tsx +1 -1
  860. package/src/renderers/electrobun/view/desktop/popover.tsx +23 -0
  861. package/src/renderers/electrobun/view/desktop/window/bridge.ts +4 -4
  862. package/src/renderers/electrobun/view/dialog-host.tsx +21 -58
  863. package/src/renderers/electrobun/view/dom-host-providers.tsx +64 -0
  864. package/src/renderers/electrobun/view/dom-ui-host.tsx +5 -21
  865. package/src/renderers/electrobun/view/external-plugins.ts +17 -5
  866. package/src/renderers/electrobun/view/fatal-screen.tsx +1 -42
  867. package/src/renderers/electrobun/view/host/ascii-text.ts +6 -29
  868. package/src/renderers/electrobun/view/host/block-glyph-canvas.tsx +1 -1
  869. package/src/renderers/electrobun/view/host/focus-scope.ts +1 -1
  870. package/src/renderers/electrobun/view/host/input.tsx +95 -163
  871. package/src/renderers/electrobun/view/host/mouse.ts +1 -1
  872. package/src/renderers/electrobun/view/host/native.ts +2 -2
  873. package/src/renderers/electrobun/view/host/scroll-box.tsx +1 -1
  874. package/src/renderers/electrobun/view/host/style.ts +1 -1
  875. package/src/renderers/electrobun/view/host/surface-3d.tsx +2 -2
  876. package/src/renderers/electrobun/view/host/tabs.tsx +1 -1
  877. package/src/renderers/electrobun/view/host/text.tsx +1 -1
  878. package/src/renderers/electrobun/view/http-fetch.ts +13 -64
  879. package/src/renderers/electrobun/view/input-host.tsx +20 -35
  880. package/src/renderers/electrobun/view/key-event.ts +7 -5
  881. package/src/renderers/electrobun/view/main.tsx +76 -34
  882. package/src/renderers/electrobun/view/native-renderer.ts +6 -1
  883. package/src/renderers/electrobun/view/native-stubs/backend-rpc.ts +3 -58
  884. package/src/renderers/electrobun/view/remote/asset-data-client.ts +3 -6
  885. package/src/renderers/electrobun/view/remote/backend-quote-subscription.ts +34 -38
  886. package/src/renderers/electrobun/view/remote/connection-health.ts +14 -32
  887. package/src/renderers/electrobun/view/remote/persistence.ts +32 -63
  888. package/src/renderers/electrobun/view/remote/quote-subscription-registry.ts +2 -5
  889. package/src/renderers/electrobun/view/rpc-codec.ts +18 -20
  890. package/src/renderers/electrobun/view/screenshot-watermark.ts +1 -1
  891. package/src/renderers/electrobun/view/test-utils.tsx +4 -11
  892. package/src/renderers/electrobun/view/toast-host.tsx +29 -87
  893. package/src/renderers/electrobun/view/ui-host.tsx +8 -1
  894. package/src/renderers/electrobun/view/update-host.ts +2 -2
  895. package/src/renderers/opentui/chart-surface.tsx +11 -124
  896. package/src/renderers/opentui/dialog-host.tsx +45 -130
  897. package/src/renderers/opentui/host.tsx +3 -2
  898. package/src/renderers/opentui/image/surface.tsx +15 -174
  899. package/src/renderers/opentui/kitty-services.ts +15 -0
  900. package/src/renderers/opentui/native-surface.ts +176 -0
  901. package/src/renderers/opentui/start.tsx +57 -42
  902. package/src/renderers/opentui/test-utils.tsx +4 -20
  903. package/src/renderers/opentui/toast-host.tsx +7 -95
  904. package/src/renderers/opentui/ui-host.tsx +87 -2
  905. package/src/renderers/share/chart.ts +1 -1
  906. package/src/renderers/share/layout-view.tsx +2 -2
  907. package/src/shares/api.ts +0 -5
  908. package/src/shares/payload.ts +13 -16
  909. package/src/sources/gloomberb-cloud/index.ts +14 -15
  910. package/src/sources/gloomberb-cloud/news.ts +8 -4
  911. package/src/sources/gloomberb-cloud/normalizers.ts +34 -76
  912. package/src/sources/history-coverage.ts +25 -84
  913. package/src/sources/history-result.ts +2 -0
  914. package/src/sources/history-retention.ts +9 -11
  915. package/src/sources/provider-router/batches.ts +0 -4
  916. package/src/sources/provider-router/brokers.ts +2 -13
  917. package/src/sources/provider-router/cache.ts +38 -159
  918. package/src/sources/provider-router/cached-routes.ts +26 -1
  919. package/src/sources/provider-router/financial-routes.ts +3 -10
  920. package/src/sources/provider-router/financials.ts +2 -3
  921. package/src/sources/provider-router/history.ts +20 -70
  922. package/src/sources/provider-router/index.ts +8 -2
  923. package/src/sources/provider-router/news.ts +2 -1
  924. package/src/sources/provider-router/primary.ts +0 -8
  925. package/src/sources/provider-router/quote-route.ts +2 -2
  926. package/src/sources/provider-router/realtime-access.ts +10 -29
  927. package/src/sources/provider-router/search.ts +3 -12
  928. package/src/sources/provider-router/test-support.ts +0 -89
  929. package/src/sources/sec-edgar/acceptance-time.ts +11 -0
  930. package/src/sources/sec-edgar/fourth-quarter.ts +179 -0
  931. package/src/sources/sec-edgar.ts +47 -228
  932. package/src/sources/yahoo-finance/financials.ts +35 -13
  933. package/src/sources/yahoo-finance/history.ts +22 -58
  934. package/src/sources/yahoo-finance/http.ts +17 -25
  935. package/src/sources/yahoo-finance/mappers.ts +0 -23
  936. package/src/sources/yahoo-finance/options.ts +36 -44
  937. package/src/sources/yahoo-finance/quote-summary.ts +90 -141
  938. package/src/sources/yahoo-finance/requests.ts +22 -12
  939. package/src/sources/yahoo-finance/snapshots.ts +4 -6
  940. package/src/sources/yahoo-finance/symbols.ts +25 -0
  941. package/src/sources/yahoo-finance/yahoo-chart-interval.ts +1 -1
  942. package/src/sources/yahoo-finance.ts +80 -188
  943. package/src/state/app/bootstrap.ts +5 -5
  944. package/src/state/app/context/index.tsx +10 -13
  945. package/src/state/hooks/live-streaming.ts +60 -0
  946. package/src/state/hooks/quote-streaming.ts +16 -57
  947. package/src/state/hooks/session-snapshot.ts +0 -1
  948. package/src/state/pane-scroll-registry.tsx +9 -0
  949. package/src/sync/controller.ts +3 -1
  950. package/src/sync/core-contributors.ts +69 -37
  951. package/src/sync/profile-analytics.ts +5 -2
  952. package/src/telemetry/crash-reports-dom.ts +74 -0
  953. package/src/telemetry/crash-reports-node.ts +170 -0
  954. package/src/telemetry/crash-reports.ts +353 -0
  955. package/src/telemetry/live-config.ts +19 -0
  956. package/src/telemetry/usage-counts-dom.ts +22 -0
  957. package/src/telemetry/usage-counts.ts +391 -0
  958. package/src/test-support/app-store.ts +21 -0
  959. package/src/test-support/broker.ts +80 -0
  960. package/src/test-support/cli-context.ts +28 -0
  961. package/src/test-support/cloud-api.ts +85 -0
  962. package/src/test-support/console.ts +40 -0
  963. package/src/test-support/data-provider.ts +30 -0
  964. package/src/test-support/headless.ts +32 -0
  965. package/src/test-support/network-guard.ts +35 -0
  966. package/src/test-support/news.ts +21 -0
  967. package/src/test-support/pane.tsx +42 -22
  968. package/src/test-support/quote-store.ts +49 -0
  969. package/src/test-support/renderer-host.ts +10 -0
  970. package/src/test-support/rpc-loopback.ts +22 -0
  971. package/src/test-support/temp-db.ts +19 -0
  972. package/src/test-support/ticker.ts +15 -0
  973. package/src/test-support/time-series.ts +27 -0
  974. package/src/theme/app-icon.ts +127 -0
  975. package/src/theme/color-utils.ts +2 -1
  976. package/src/theme/themes.ts +3 -1
  977. package/src/time-series/alignment.ts +4 -7
  978. package/src/time-series/chart-data.ts +2 -3
  979. package/src/time-series/forward-valuation.ts +6 -9
  980. package/src/time-series/fundamentals.ts +34 -96
  981. package/src/time-series/live-bars.ts +12 -15
  982. package/src/time-series/live-quotes.ts +4 -26
  983. package/src/time-series/market.ts +6 -9
  984. package/src/time-series/parsed-history-cache.ts +0 -4
  985. package/src/time-series/resolution.ts +35 -1
  986. package/src/time-series/resolve.ts +28 -20
  987. package/src/time-series/session-history.ts +4 -23
  988. package/src/time-series/spec.ts +11 -16
  989. package/src/time-series/studies.ts +26 -15
  990. package/src/time-series/transforms.ts +6 -9
  991. package/src/time-series/types.ts +6 -3
  992. package/src/types/broker.ts +10 -0
  993. package/src/types/config.ts +24 -2
  994. package/src/types/data-provider.ts +13 -1
  995. package/src/types/desktop-menu.ts +3 -1
  996. package/src/types/financials.ts +71 -20
  997. package/src/types/instrument.ts +2 -1
  998. package/src/types/plugin.ts +30 -0
  999. package/src/types/price-history.ts +2 -0
  1000. package/src/types/trading.ts +21 -2
  1001. package/src/ui/dialog-stack.ts +80 -0
  1002. package/src/ui/dialog.tsx +33 -2
  1003. package/src/ui/host.tsx +17 -0
  1004. package/src/ui/index.tsx +3 -10
  1005. package/src/ui/toast.tsx +95 -0
  1006. package/src/updater/index.ts +472 -0
  1007. package/src/utils/async-deadline.ts +34 -0
  1008. package/src/utils/calendar-date.ts +20 -0
  1009. package/src/utils/csv.ts +19 -2
  1010. package/src/utils/datetime-format.ts +103 -6
  1011. package/src/utils/double-escape-close.ts +1 -23
  1012. package/src/utils/errors.ts +4 -0
  1013. package/src/utils/exchanges.ts +10 -0
  1014. package/src/utils/financial-statements.ts +6 -25
  1015. package/src/utils/format.ts +6 -17
  1016. package/src/utils/futures-generic.ts +159 -0
  1017. package/src/utils/guards.ts +37 -0
  1018. package/src/utils/hash.ts +17 -2
  1019. package/src/utils/http-proxy-response.ts +122 -4
  1020. package/src/utils/math.ts +12 -0
  1021. package/src/utils/platform.ts +34 -0
  1022. package/src/utils/plugin-proxy-hosts.json +1 -2
  1023. package/src/utils/plugin-proxy-hosts.ts +3 -0
  1024. package/src/utils/price-history-integrity.ts +5 -8
  1025. package/src/utils/price-history.ts +36 -11
  1026. package/src/utils/sec.ts +3 -8
  1027. package/src/utils/semver.ts +15 -0
  1028. package/src/utils/shortcut-labels.ts +4 -29
  1029. package/src/utils/sort-values.ts +28 -0
  1030. package/src/utils/statement-gaps.ts +94 -0
  1031. package/src/utils/zoned-date-time.ts +12 -0
  1032. package/src/api-client/askg.test.ts +0 -256
  1033. package/src/api-client/errors.test.ts +0 -11
  1034. package/src/api-client/index.test.ts +0 -1591
  1035. package/src/api-client/paths.test.ts +0 -32
  1036. package/src/api-client/request.test.ts +0 -153
  1037. package/src/api-client/research-activity.test.ts +0 -316
  1038. package/src/api-client/session-request-lifetime.test.ts +0 -184
  1039. package/src/api-client/socket-health.test.ts +0 -86
  1040. package/src/api-client/socket-lifetime.test.ts +0 -76
  1041. package/src/api-client/socket-protocol.test.ts +0 -90
  1042. package/src/api-client/tape-socket.test.ts +0 -44
  1043. package/src/api-client/teams.test.ts +0 -270
  1044. package/src/app/app-bootstrap-state.test.ts +0 -157
  1045. package/src/app/global-shortcuts.test.tsx +0 -468
  1046. package/src/app/keybindings/chord.test.ts +0 -131
  1047. package/src/app/keybindings/resolve.test.ts +0 -103
  1048. package/src/app/language-observer.test.tsx +0 -82
  1049. package/src/app/pane-runtime/layout-placement.test.ts +0 -27
  1050. package/src/app/pane-runtime/plugin-bindings.test.ts +0 -117
  1051. package/src/app/pane-runtime/ticker-navigation-runtime.test.ts +0 -144
  1052. package/src/app/pane-runtime/ticker-open-runtime.test.tsx +0 -170
  1053. package/src/app/pane-template-dialog-wizard.test.tsx +0 -36
  1054. package/src/app/runtime/broker-import.test.tsx +0 -89
  1055. package/src/app/runtime/desktop-deeplink.test.ts +0 -169
  1056. package/src/app/runtime/layout-warmup.test.ts +0 -73
  1057. package/src/app/runtime/ticker-refresh.test.tsx +0 -115
  1058. package/src/architecture/browser-entry-graph.test.ts +0 -97
  1059. package/src/architecture/import-boundaries.test.ts +0 -136
  1060. package/src/assets/gloomberb-logo.ico +0 -0
  1061. package/src/assets/gloomberb-logo.png +0 -0
  1062. package/src/brokers/bond-price-basis.test.ts +0 -35
  1063. package/src/brokers/legacy-contract.test.ts +0 -51
  1064. package/src/brokers/profile-form.test.ts +0 -71
  1065. package/src/brokers/sync-broker-instance.test.ts +0 -599
  1066. package/src/brokers/test-broker.ts +0 -68
  1067. package/src/capabilities/registry.test.ts +0 -297
  1068. package/src/cli/base-converter.test.ts +0 -16
  1069. package/src/cli/commands/automation.ts +0 -98
  1070. package/src/cli/commands/futures-price-precision.test.tsx +0 -65
  1071. package/src/cli/commands/keybindings.test.ts +0 -48
  1072. package/src/cli/commands/market-fx.test.ts +0 -77
  1073. package/src/cli/commands/market-options.test.ts +0 -44
  1074. package/src/cli/commands/plugins.test.ts +0 -29
  1075. package/src/cli/commands/quote-price-basis.test.ts +0 -88
  1076. package/src/cli/commands/ticker-financial-units.test.ts +0 -78
  1077. package/src/cli/commands/ticker-period.test.ts +0 -62
  1078. package/src/cli/context.test.ts +0 -63
  1079. package/src/cli/entry.test.ts +0 -58
  1080. package/src/cli/history-rows.test.ts +0 -47
  1081. package/src/cli/options.test.ts +0 -45
  1082. package/src/cli/pane-functions/cloud-session.test.ts +0 -77
  1083. package/src/cli/pane-functions/data.test.ts +0 -17
  1084. package/src/cli/pane-functions/discovery.test.ts +0 -36
  1085. package/src/cli/pane-functions/dom.test.ts +0 -69
  1086. package/src/cli/pane-functions/headless.test.ts +0 -314
  1087. package/src/cli/pane-functions/index.test.ts +0 -266
  1088. package/src/cli/pane-functions/intraday-shot.test.ts +0 -399
  1089. package/src/cli/pane-functions/report.test.ts +0 -107
  1090. package/src/cli/pane-functions/screenshot.test.ts +0 -927
  1091. package/src/cli/registry.test.ts +0 -256
  1092. package/src/cli/result.test.ts +0 -133
  1093. package/src/cli/ticker-resolution.test.ts +0 -39
  1094. package/src/cli/visible-key-values.test.ts +0 -23
  1095. package/src/cli.test.ts +0 -437
  1096. package/src/components/chart/composite/axis-overlays.test.tsx +0 -80
  1097. package/src/components/chart/composite/composite-chart.test.tsx +0 -2019
  1098. package/src/components/chart/composite/downsample.test.ts +0 -136
  1099. package/src/components/chart/composite/format.test.ts +0 -258
  1100. package/src/components/chart/composite/fx-precision.test.ts +0 -111
  1101. package/src/components/chart/composite/interactions.test.ts +0 -231
  1102. package/src/components/chart/composite/panel-series.test.ts +0 -66
  1103. package/src/components/chart/composite/price-axis-labels.test.ts +0 -50
  1104. package/src/components/chart/composite/price-series.test.ts +0 -39
  1105. package/src/components/chart/composite/renderers.test.ts +0 -823
  1106. package/src/components/chart/composite/scene-market-cursor.test.ts +0 -148
  1107. package/src/components/chart/composite/scene.test.ts +0 -845
  1108. package/src/components/chart/composite/scroll-surface.test.tsx +0 -153
  1109. package/src/components/chart/composite/time-axis.test.ts +0 -281
  1110. package/src/components/chart/composite/time-scale.test.ts +0 -88
  1111. package/src/components/chart/composite/tools.test.ts +0 -371
  1112. package/src/components/chart/curve/curve-surface.test.tsx +0 -53
  1113. package/src/components/chart/curve/model.test.ts +0 -115
  1114. package/src/components/chart/native/bitmap-support.test.ts +0 -27
  1115. package/src/components/chart/native/kitty/index.test.ts +0 -537
  1116. package/src/components/chart/static/chart-surface.test.tsx +0 -159
  1117. package/src/components/chart/static/multi-line-chart-surface.tsx +0 -105
  1118. package/src/components/chart/static/scatter-chart-surface.test.ts +0 -30
  1119. package/src/components/chart/static/trail-chart-model.test.ts +0 -36
  1120. package/src/components/chart/surface3d/model.test.ts +0 -117
  1121. package/src/components/chart/surface3d/software.test.ts +0 -32
  1122. package/src/components/command-bar/assist/inventory.test.ts +0 -93
  1123. package/src/components/command-bar/assist/model.test.ts +0 -185
  1124. package/src/components/command-bar/helpers.test.ts +0 -162
  1125. package/src/components/command-bar/layout-items/current-layout.test.ts +0 -165
  1126. package/src/components/command-bar/list/badge.test.ts +0 -54
  1127. package/src/components/command-bar/list/model.test.ts +0 -129
  1128. package/src/components/command-bar/list/view.test.tsx +0 -113
  1129. package/src/components/command-bar/pane-settings.test.ts +0 -141
  1130. package/src/components/command-bar/panel/layout.test.ts +0 -171
  1131. package/src/components/command-bar/routes/root/results.test.ts +0 -161
  1132. package/src/components/command-bar/routes/root/search-providers.test.tsx +0 -224
  1133. package/src/components/command-bar/routes/root/selection.test.ts +0 -54
  1134. package/src/components/command-bar/routes/root/shortcuts.test.ts +0 -193
  1135. package/src/components/command-bar/routes/ticker-search/results.test.ts +0 -128
  1136. package/src/components/command-bar/surface/assist.test.tsx +0 -341
  1137. package/src/components/command-bar/surface/index.test.tsx +0 -1208
  1138. package/src/components/command-bar/surface/listing-selection.test.tsx +0 -84
  1139. package/src/components/command-bar/surface/pane.test.tsx +0 -937
  1140. package/src/components/command-bar/surface/portfolio.test.tsx +0 -453
  1141. package/src/components/command-bar/surface/test-harness.tsx +0 -353
  1142. package/src/components/command-bar/view-model.test.ts +0 -228
  1143. package/src/components/command-bar/workflow/broker.test.ts +0 -22
  1144. package/src/components/command-bar/workflow/collection-actions.test.ts +0 -105
  1145. package/src/components/command-bar/workflow/collection-identity.test.ts +0 -180
  1146. package/src/components/command-bar/workflow/ops.test.ts +0 -804
  1147. package/src/components/command-bar/workflow/route-actions.test.ts +0 -34
  1148. package/src/components/command-bar/workflow/ticker-listing-picker.test.ts +0 -41
  1149. package/src/components/company-logo.test.ts +0 -19
  1150. package/src/components/data-table/export.test.ts +0 -21
  1151. package/src/components/data-table/frozen-column.test.tsx +0 -114
  1152. package/src/components/data-table/horizontal-navigation.test.tsx +0 -181
  1153. package/src/components/data-table/stack-view.test.tsx +0 -226
  1154. package/src/components/data-table/view.test.tsx +0 -343
  1155. package/src/components/feed-data-table/stack-view.test.tsx +0 -46
  1156. package/src/components/input-search-bar.test.tsx +0 -137
  1157. package/src/components/layout/header.test.tsx +0 -82
  1158. package/src/components/layout/market-summary.test.ts +0 -81
  1159. package/src/components/layout/pane/content.test.tsx +0 -103
  1160. package/src/components/layout/pane/cycle-order.test.ts +0 -29
  1161. package/src/components/layout/pane/footer/current-actions.test.tsx +0 -108
  1162. package/src/components/layout/pane/footer/index.test.tsx +0 -199
  1163. package/src/components/layout/pane/footer/keyboard.test.ts +0 -57
  1164. package/src/components/layout/pane/footer/notice.desktop.test.tsx +0 -57
  1165. package/src/components/layout/pane/keyboard-scroll.test.tsx +0 -146
  1166. package/src/components/layout/pane/sidebar.test.tsx +0 -187
  1167. package/src/components/layout/pane/sizing.test.ts +0 -46
  1168. package/src/components/layout/shell/index.test.tsx +0 -1377
  1169. package/src/components/layout/shell/layout-state.test.ts +0 -33
  1170. package/src/components/layout/shell/menu.test.ts +0 -89
  1171. package/src/components/layout/shell/pane-occlusion.test.ts +0 -52
  1172. package/src/components/layout/shell/ticker-link-menu.test.ts +0 -82
  1173. package/src/components/layout/status-bar-groups.test.ts +0 -92
  1174. package/src/components/layout/status-bar.test.tsx +0 -306
  1175. package/src/components/layout/window-edit/mode.test.ts +0 -167
  1176. package/src/components/metric-treemap/layout.test.ts +0 -77
  1177. package/src/components/metric-treemap/surface.test.tsx +0 -62
  1178. package/src/components/onboarding/first-run-workspace.test.ts +0 -81
  1179. package/src/components/onboarding/onboarding-wizard.test.tsx +0 -1097
  1180. package/src/components/onboarding/wizard-model.test.ts +0 -67
  1181. package/src/components/pane-settings-dialog.test.tsx +0 -278
  1182. package/src/components/pane-template-wizard.test.tsx +0 -51
  1183. package/src/components/price-sparkline/model.test.ts +0 -27
  1184. package/src/components/quote-flash.test.ts +0 -30
  1185. package/src/components/sign-in-gate.test.tsx +0 -60
  1186. package/src/components/table-view-shared.test.ts +0 -11
  1187. package/src/components/ticker/badge/format.test.ts +0 -66
  1188. package/src/components/ticker/badge/list.test.tsx +0 -84
  1189. package/src/components/ticker/badge/text.test.tsx +0 -223
  1190. package/src/components/ticker/list-table.test.tsx +0 -281
  1191. package/src/components/ui/data-table/opentui/model.test.ts +0 -47
  1192. package/src/components/ui/data-table/visible-range.test.ts +0 -29
  1193. package/src/components/ui/display.desktop.test.tsx +0 -55
  1194. package/src/components/ui/display.test.tsx +0 -36
  1195. package/src/components/ui/external-link.test.tsx +0 -54
  1196. package/src/components/ui/message-composer.test.tsx +0 -81
  1197. package/src/components/ui/page-stack-view.test.tsx +0 -126
  1198. package/src/components/ui/prose.desktop.test.tsx +0 -50
  1199. package/src/components/ui/prose.test.ts +0 -22
  1200. package/src/components/ui/row-value-cache.test.ts +0 -17
  1201. package/src/components/ui/table-layout.test.ts +0 -108
  1202. package/src/components/ui/tabs.test.tsx +0 -114
  1203. package/src/components/ui/ui.test.tsx +0 -984
  1204. package/src/components/use-pane-notice-footer.test.tsx +0 -116
  1205. package/src/core/app-runtime.test.ts +0 -144
  1206. package/src/core/app-services.test.ts +0 -66
  1207. package/src/core/connection-health.test.ts +0 -143
  1208. package/src/data/cached-query.test.ts +0 -95
  1209. package/src/data/config/home.test.ts +0 -70
  1210. package/src/data/config/store/index.test.ts +0 -1241
  1211. package/src/data/memory-resource-store.test.ts +0 -24
  1212. package/src/data/plugin-cache.test.ts +0 -46
  1213. package/src/data/sqlite/cache.test.ts +0 -330
  1214. package/src/data/sqlite/retry.test.ts +0 -84
  1215. package/src/feedback/diagnostics.test.ts +0 -30
  1216. package/src/feedback/redact.test.ts +0 -50
  1217. package/src/feedback/screenshot.test.ts +0 -22
  1218. package/src/i18n/index.test.ts +0 -134
  1219. package/src/i18n/languages.test.ts +0 -34
  1220. package/src/index.tsx +0 -6
  1221. package/src/layout-marketplace/api.test.ts +0 -54
  1222. package/src/layout-marketplace/cloud.test.ts +0 -154
  1223. package/src/layout-marketplace/gallery-desktop.test.tsx +0 -216
  1224. package/src/layout-marketplace/gallery.test.tsx +0 -149
  1225. package/src/layout-marketplace/geometry.test.ts +0 -47
  1226. package/src/layout-marketplace/mini-workspace.test.tsx +0 -69
  1227. package/src/layout-marketplace/model.test.ts +0 -118
  1228. package/src/layout-marketplace/name-dialog.tsx +0 -60
  1229. package/src/layout-marketplace/payload.test.ts +0 -419
  1230. package/src/market-data/coordinator/chart-session.test.ts +0 -152
  1231. package/src/market-data/coordinator/events.test.ts +0 -68
  1232. package/src/market-data/coordinator/fx-refresh.test.ts +0 -199
  1233. package/src/market-data/coordinator/index.test.ts +0 -1174
  1234. package/src/market-data/coordinator/options-sharing.test.ts +0 -79
  1235. package/src/market-data/coordinator/subscriptions.test.ts +0 -652
  1236. package/src/market-data/frame-scheduler.test.ts +0 -82
  1237. package/src/market-data/history-session.test.ts +0 -151
  1238. package/src/market-data/hooks.test.tsx +0 -263
  1239. package/src/market-data/legacy-contract-hooks.test.tsx +0 -49
  1240. package/src/market-data/legacy-contract.test.ts +0 -99
  1241. package/src/market-data/market/format.test.ts +0 -284
  1242. package/src/market-data/market/status.test.ts +0 -26
  1243. package/src/market-data/performance.test.ts +0 -83
  1244. package/src/market-data/portfolio-instrument.test.ts +0 -80
  1245. package/src/market-data/published-us-sessions.test.ts +0 -65
  1246. package/src/market-data/query-store.test.ts +0 -87
  1247. package/src/market-data/quote-subscription-target.test.ts +0 -56
  1248. package/src/market-data/quotes/day-range.test.ts +0 -84
  1249. package/src/market-data/quotes/freshness.test.ts +0 -277
  1250. package/src/market-data/quotes/observation-time.test.ts +0 -98
  1251. package/src/market-data/quotes/price-basis.test.ts +0 -44
  1252. package/src/market-data/quotes/resolution.test.ts +0 -612
  1253. package/src/market-data/quotes/time.test.ts +0 -41
  1254. package/src/market-data/request-types.test.ts +0 -110
  1255. package/src/market-data/snapshot-contract.test.ts +0 -110
  1256. package/src/market-data/snapshot-provider.test.ts +0 -251
  1257. package/src/market-data/ticker-price-returns.test.ts +0 -26
  1258. package/src/news/aggregator.test.ts +0 -596
  1259. package/src/news/hooks.test.tsx +0 -66
  1260. package/src/notifications/app-notifier.test.ts +0 -199
  1261. package/src/pane-settings.test.ts +0 -38
  1262. package/src/plugins/builtin/account-management/model.test.ts +0 -149
  1263. package/src/plugins/builtin/account-management/navigation.test.ts +0 -27
  1264. package/src/plugins/builtin/alerts/alert-engine.test.ts +0 -105
  1265. package/src/plugins/builtin/alerts/events.test.ts +0 -28
  1266. package/src/plugins/builtin/alerts/index.test.tsx +0 -459
  1267. package/src/plugins/builtin/alerts/research.test.ts +0 -75
  1268. package/src/plugins/builtin/analytics/broker-performance.test.ts +0 -79
  1269. package/src/plugins/builtin/analytics/index.test.tsx +0 -657
  1270. package/src/plugins/builtin/analytics/metrics.test.ts +0 -138
  1271. package/src/plugins/builtin/analytics/pane-model.test.ts +0 -191
  1272. package/src/plugins/builtin/analytics/portfolio-identity.test.tsx +0 -272
  1273. package/src/plugins/builtin/analytics/return-window.test.ts +0 -72
  1274. package/src/plugins/builtin/analytics/risk-client.test.ts +0 -100
  1275. package/src/plugins/builtin/analytics/risk-evidence.test.ts +0 -123
  1276. package/src/plugins/builtin/analytics/risk-headless.test.ts +0 -27
  1277. package/src/plugins/builtin/analytics/risk-math.test.ts +0 -95
  1278. package/src/plugins/builtin/analytics/risk-model.test.ts +0 -284
  1279. package/src/plugins/builtin/analytics/sector-model.test.ts +0 -56
  1280. package/src/plugins/builtin/analytics/sharpe-cadence.test.ts +0 -111
  1281. package/src/plugins/builtin/backtest/engine.test.ts +0 -71
  1282. package/src/plugins/builtin/bond-calculator/math.test.ts +0 -97
  1283. package/src/plugins/builtin/bond-calculator/model.test.ts +0 -56
  1284. package/src/plugins/builtin/bond-calculator/pane.test.tsx +0 -84
  1285. package/src/plugins/builtin/broker-manager/index.test.tsx +0 -173
  1286. package/src/plugins/builtin/broker-manager/model.test.ts +0 -145
  1287. package/src/plugins/builtin/buildout/cells.test.tsx +0 -31
  1288. package/src/plugins/builtin/buildout/pane/header.tsx +0 -30
  1289. package/src/plugins/builtin/cds/client.test.ts +0 -103
  1290. package/src/plugins/builtin/cds/headless.test.ts +0 -48
  1291. package/src/plugins/builtin/cds/model.test.ts +0 -242
  1292. package/src/plugins/builtin/cds/pane.test.tsx +0 -139
  1293. package/src/plugins/builtin/central-bank-rates/model.test.ts +0 -84
  1294. package/src/plugins/builtin/changelog/model.test.ts +0 -77
  1295. package/src/plugins/builtin/chart-composer/catalog-inventory.test.ts +0 -105
  1296. package/src/plugins/builtin/chart-composer/editor/model.test.ts +0 -85
  1297. package/src/plugins/builtin/chart-composer/editor.test.tsx +0 -341
  1298. package/src/plugins/builtin/chart-composer/financial-periods.fixture.json +0 -225
  1299. package/src/plugins/builtin/chart-composer/follow-binding.test.tsx +0 -253
  1300. package/src/plugins/builtin/chart-composer/headless.test.ts +0 -158
  1301. package/src/plugins/builtin/chart-composer/loading.test.tsx +0 -134
  1302. package/src/plugins/builtin/chart-composer/pane-share.test.ts +0 -144
  1303. package/src/plugins/builtin/chart-composer/presets.test.ts +0 -672
  1304. package/src/plugins/builtin/chart-composer/quick-add.test.tsx +0 -245
  1305. package/src/plugins/builtin/chart-composer/quote-metadata.test.ts +0 -176
  1306. package/src/plugins/builtin/chart-composer/series-catalog.test.ts +0 -104
  1307. package/src/plugins/builtin/chart-composer/served-cadence-snapshot.test.ts +0 -161
  1308. package/src/plugins/builtin/chart-composer/settings.test.ts +0 -200
  1309. package/src/plugins/builtin/chart-composer/shortcuts.test.ts +0 -44
  1310. package/src/plugins/builtin/chart-composer/use-series-catalog.test.tsx +0 -94
  1311. package/src/plugins/builtin/chart-composer/viewport-labels.test.ts +0 -13
  1312. package/src/plugins/builtin/chat/chat.test.tsx +0 -1481
  1313. package/src/plugins/builtin/chat/composer-commands.test.ts +0 -30
  1314. package/src/plugins/builtin/chat/content/composer-runtime.test.tsx +0 -144
  1315. package/src/plugins/builtin/chat/content/mentions.test.ts +0 -74
  1316. package/src/plugins/builtin/chat/controller/session-lifetime.test.ts +0 -182
  1317. package/src/plugins/builtin/chat/controller/session.test.ts +0 -25
  1318. package/src/plugins/builtin/chat/controller.test.ts +0 -1894
  1319. package/src/plugins/builtin/chat/message/desktop.test.tsx +0 -88
  1320. package/src/plugins/builtin/chat/message/profile-popover.test.tsx +0 -127
  1321. package/src/plugins/builtin/chat/pane-state.test.ts +0 -31
  1322. package/src/plugins/builtin/chat/sidebar.test.tsx +0 -830
  1323. package/src/plugins/builtin/chat/test-harness.test.ts +0 -46
  1324. package/src/plugins/builtin/chat/test-harness.tsx +0 -267
  1325. package/src/plugins/builtin/cloud/askg/controller.test.ts +0 -525
  1326. package/src/plugins/builtin/cloud/askg/conversation-store.test.ts +0 -230
  1327. package/src/plugins/builtin/cloud/askg/executor.test.ts +0 -160
  1328. package/src/plugins/builtin/cloud/askg/manifest.test.ts +0 -153
  1329. package/src/plugins/builtin/cloud/askg/model.test.ts +0 -349
  1330. package/src/plugins/builtin/cloud/askg/pane.test.tsx +0 -356
  1331. package/src/plugins/builtin/cloud/askg/protocol.test.ts +0 -190
  1332. package/src/plugins/builtin/cloud/askg/undo.test.ts +0 -44
  1333. package/src/plugins/builtin/cloud/auth-model.test.ts +0 -67
  1334. package/src/plugins/builtin/cloud/buildout-module.tsx +0 -23
  1335. package/src/plugins/builtin/cloud/device-signin.test.ts +0 -217
  1336. package/src/plugins/builtin/cloud/reveal-in-scroll-box.ts +0 -34
  1337. package/src/plugins/builtin/cloud/team/collections.test.ts +0 -126
  1338. package/src/plugins/builtin/cloud/team/model.test.ts +0 -174
  1339. package/src/plugins/builtin/cloud/team/pane-model.test.ts +0 -114
  1340. package/src/plugins/builtin/cloud/team/pane.test.tsx +0 -234
  1341. package/src/plugins/builtin/cloud/team/store.test.ts +0 -231
  1342. package/src/plugins/builtin/cloud/thesis/board-pane.test.tsx +0 -266
  1343. package/src/plugins/builtin/cloud/thesis/model.test.ts +0 -171
  1344. package/src/plugins/builtin/cloud-tweets/pane-share.test.ts +0 -56
  1345. package/src/plugins/builtin/cloud-tweets/table.test.tsx +0 -125
  1346. package/src/plugins/builtin/congress-trades/aggregates.test.ts +0 -27
  1347. package/src/plugins/builtin/congress-trades/headless.test.ts +0 -113
  1348. package/src/plugins/builtin/congress-trades/model.test.ts +0 -129
  1349. package/src/plugins/builtin/connections/pane.test.tsx +0 -84
  1350. package/src/plugins/builtin/correlation/colors.test.ts +0 -39
  1351. package/src/plugins/builtin/correlation/compute.test.ts +0 -97
  1352. package/src/plugins/builtin/correlation/headless.test.ts +0 -147
  1353. package/src/plugins/builtin/correlation/index.test.tsx +0 -155
  1354. package/src/plugins/builtin/correlation/relationship/history.test.tsx +0 -62
  1355. package/src/plugins/builtin/correlation/relationship/layout.test.ts +0 -17
  1356. package/src/plugins/builtin/cot/model.test.ts +0 -89
  1357. package/src/plugins/builtin/credit-conditions/client.test.ts +0 -122
  1358. package/src/plugins/builtin/credit-conditions/headless.test.ts +0 -35
  1359. package/src/plugins/builtin/credit-conditions/index.test.tsx +0 -136
  1360. package/src/plugins/builtin/credit-conditions/model.test.ts +0 -56
  1361. package/src/plugins/builtin/crypto-board/client.test.ts +0 -51
  1362. package/src/plugins/builtin/crypto-board/model.test.ts +0 -111
  1363. package/src/plugins/builtin/crypto-board/pane.test.tsx +0 -130
  1364. package/src/plugins/builtin/crypto-board/test-fixture.ts +0 -80
  1365. package/src/plugins/builtin/custom-view/live-quotes.test.ts +0 -53
  1366. package/src/plugins/builtin/custom-view/view-spec.test.ts +0 -134
  1367. package/src/plugins/builtin/debt-maturities/debt-maturities.test.ts +0 -317
  1368. package/src/plugins/builtin/dividend-yield/calendar.ts +0 -9
  1369. package/src/plugins/builtin/dividend-yield/client.test.ts +0 -260
  1370. package/src/plugins/builtin/dividend-yield/dividend-source-integrity.test.ts +0 -233
  1371. package/src/plugins/builtin/dividend-yield/headless.test.ts +0 -123
  1372. package/src/plugins/builtin/dividend-yield/pane.test.tsx +0 -351
  1373. package/src/plugins/builtin/dividend-yield/provider-client.test.ts +0 -61
  1374. package/src/plugins/builtin/dividend-yield/reference-price.test.ts +0 -115
  1375. package/src/plugins/builtin/dividend-yield/view.test.ts +0 -81
  1376. package/src/plugins/builtin/earnings/data/cache.test.ts +0 -117
  1377. package/src/plugins/builtin/earnings/detail-model.test.ts +0 -103
  1378. package/src/plugins/builtin/earnings/detail-model.ts +0 -165
  1379. package/src/plugins/builtin/earnings/detail-view.tsx +0 -136
  1380. package/src/plugins/builtin/earnings/estimate-basis.test.ts +0 -184
  1381. package/src/plugins/builtin/earnings/estimate-fixtures.test-data.ts +0 -327
  1382. package/src/plugins/builtin/earnings/headless.test.ts +0 -82
  1383. package/src/plugins/builtin/earnings/model.test.ts +0 -98
  1384. package/src/plugins/builtin/earnings/table.test.ts +0 -76
  1385. package/src/plugins/builtin/earnings/table.ts +0 -246
  1386. package/src/plugins/builtin/earnings-calls/data.test.ts +0 -252
  1387. package/src/plugins/builtin/earnings-calls/headless-freshness.test.ts +0 -41
  1388. package/src/plugins/builtin/earnings-calls/headless.test.ts +0 -258
  1389. package/src/plugins/builtin/earnings-calls/pane.test.tsx +0 -520
  1390. package/src/plugins/builtin/earnings-calls/prose.test.ts +0 -51
  1391. package/src/plugins/builtin/econ/calendar-model.test.ts +0 -82
  1392. package/src/plugins/builtin/econ/fred-cache.test.ts +0 -188
  1393. package/src/plugins/builtin/econ/fred-client.test.ts +0 -79
  1394. package/src/plugins/builtin/econ/index.test.tsx +0 -144
  1395. package/src/plugins/builtin/econ-statistics/client.test.ts +0 -122
  1396. package/src/plugins/builtin/econ-statistics/headless.test.ts +0 -54
  1397. package/src/plugins/builtin/econ-statistics/pane.test.tsx +0 -69
  1398. package/src/plugins/builtin/econ-statistics/transform.test.ts +0 -109
  1399. package/src/plugins/builtin/econ-statistics/transform.ts +0 -94
  1400. package/src/plugins/builtin/econ-statistics/trend.ts +0 -57
  1401. package/src/plugins/builtin/econ-statistics/view.test.ts +0 -43
  1402. package/src/plugins/builtin/equity-screener/headless.test.ts +0 -22
  1403. package/src/plugins/builtin/equity-screener/model.test.ts +0 -116
  1404. package/src/plugins/builtin/equity-screener/results.test.tsx +0 -44
  1405. package/src/plugins/builtin/equity-screener/test-fixture.ts +0 -63
  1406. package/src/plugins/builtin/estimate-revisions/model.test.ts +0 -253
  1407. package/src/plugins/builtin/estimate-revisions/sorting.test.ts +0 -91
  1408. package/src/plugins/builtin/executives/format.test.ts +0 -23
  1409. package/src/plugins/builtin/executives/pane.test.tsx +0 -339
  1410. package/src/plugins/builtin/filing-events/feed.test.ts +0 -143
  1411. package/src/plugins/builtin/filing-events/pane.test.tsx +0 -125
  1412. package/src/plugins/builtin/futures/model.test.ts +0 -151
  1413. package/src/plugins/builtin/futures/pane.test.tsx +0 -219
  1414. package/src/plugins/builtin/futures/table.test.ts +0 -155
  1415. package/src/plugins/builtin/futures-curve/model.test.ts +0 -90
  1416. package/src/plugins/builtin/fx-matrix/export.test.ts +0 -30
  1417. package/src/plugins/builtin/fx-matrix/pairs.test.ts +0 -16
  1418. package/src/plugins/builtin/fx-matrix/pane.test.tsx +0 -109
  1419. package/src/plugins/builtin/fx-matrix/refresh.test.tsx +0 -69
  1420. package/src/plugins/builtin/help/components.tsx +0 -44
  1421. package/src/plugins/builtin/help/keybindings-editor.test.tsx +0 -164
  1422. package/src/plugins/builtin/holders/headless.test.ts +0 -58
  1423. package/src/plugins/builtin/holders/index.test.ts +0 -12
  1424. package/src/plugins/builtin/holders/thirteenf-match.test.ts +0 -30
  1425. package/src/plugins/builtin/insider/amendments.test.ts +0 -112
  1426. package/src/plugins/builtin/insider/headless.test.ts +0 -136
  1427. package/src/plugins/builtin/insider/insider-data.test.ts +0 -66
  1428. package/src/plugins/builtin/insider/pane.test.tsx +0 -112
  1429. package/src/plugins/builtin/iv-history/client.test.ts +0 -18
  1430. package/src/plugins/builtin/iv-history/model.test.ts +0 -87
  1431. package/src/plugins/builtin/jobs/model.test.ts +0 -119
  1432. package/src/plugins/builtin/jobs/pages.test.tsx +0 -103
  1433. package/src/plugins/builtin/kelly-sizer/index.test.tsx +0 -202
  1434. package/src/plugins/builtin/kelly-sizer/model.test.ts +0 -158
  1435. package/src/plugins/builtin/kelly-sizer/view.test.tsx +0 -88
  1436. package/src/plugins/builtin/market-movers/headless.test.ts +0 -34
  1437. package/src/plugins/builtin/market-movers/integrity.test.ts +0 -119
  1438. package/src/plugins/builtin/market-movers/pane-research.test.tsx +0 -138
  1439. package/src/plugins/builtin/market-movers/screener.test.ts +0 -333
  1440. package/src/plugins/builtin/market-valuation/client.test.ts +0 -283
  1441. package/src/plugins/builtin/market-valuation/headless.test.ts +0 -75
  1442. package/src/plugins/builtin/market-valuation/model.test.ts +0 -405
  1443. package/src/plugins/builtin/market-valuation/pane.test.tsx +0 -235
  1444. package/src/plugins/builtin/market-valuation/trend.ts +0 -87
  1445. package/src/plugins/builtin/money-markets/model.test.ts +0 -61
  1446. package/src/plugins/builtin/news/headless.test.ts +0 -149
  1447. package/src/plugins/builtin/news/wire/breaking/filters.test.ts +0 -99
  1448. package/src/plugins/builtin/news/wire/breaking/notifications.test.ts +0 -204
  1449. package/src/plugins/builtin/news/wire/breaking/pane.test.tsx +0 -128
  1450. package/src/plugins/builtin/news/wire/breaking/pane.tsx +0 -89
  1451. package/src/plugins/builtin/news/wire/feed-config.test.ts +0 -109
  1452. package/src/plugins/builtin/news/wire/news/detail-view.test.tsx +0 -279
  1453. package/src/plugins/builtin/news/wire/news/table.test.tsx +0 -223
  1454. package/src/plugins/builtin/news/wire/read-state.test.ts +0 -37
  1455. package/src/plugins/builtin/news/wire/rss/parser.test.ts +0 -178
  1456. package/src/plugins/builtin/news/wire/rss/source.test.ts +0 -153
  1457. package/src/plugins/builtin/notes/files.test.ts +0 -18
  1458. package/src/plugins/builtin/notes/quick-notes-pane.test.tsx +0 -209
  1459. package/src/plugins/builtin/notes/store.test.ts +0 -245
  1460. package/src/plugins/builtin/notes/ticker-notes-tab.test.tsx +0 -350
  1461. package/src/plugins/builtin/options/analytics.test.ts +0 -234
  1462. package/src/plugins/builtin/options/calc-seed.test.ts +0 -130
  1463. package/src/plugins/builtin/options/chain-integrity.test.tsx +0 -284
  1464. package/src/plugins/builtin/options/enrichment-hook.test.tsx +0 -149
  1465. package/src/plugins/builtin/options/enrichment.test.ts +0 -257
  1466. package/src/plugins/builtin/options/expiry-selection.test.tsx +0 -370
  1467. package/src/plugins/builtin/options/footer.test.ts +0 -60
  1468. package/src/plugins/builtin/options/live-quotes.test.ts +0 -421
  1469. package/src/plugins/builtin/options/market-reference.test.ts +0 -36
  1470. package/src/plugins/builtin/options/table.test.ts +0 -100
  1471. package/src/plugins/builtin/options/view.test.tsx +0 -657
  1472. package/src/plugins/builtin/options-calculator/binomial.test.ts +0 -264
  1473. package/src/plugins/builtin/options-calculator/boundary-integrity.test.tsx +0 -114
  1474. package/src/plugins/builtin/options-calculator/evidence.test.ts +0 -138
  1475. package/src/plugins/builtin/options-calculator/headless.test.ts +0 -39
  1476. package/src/plugins/builtin/options-calculator/inputs.test.ts +0 -24
  1477. package/src/plugins/builtin/options-calculator/model.test.ts +0 -242
  1478. package/src/plugins/builtin/options-calculator/pane.test.tsx +0 -305
  1479. package/src/plugins/builtin/options-calculator/surface.test.ts +0 -164
  1480. package/src/plugins/builtin/options-scenario/client.test.ts +0 -143
  1481. package/src/plugins/builtin/options-scenario/evidence.test.ts +0 -34
  1482. package/src/plugins/builtin/options-scenario/live.test.ts +0 -34
  1483. package/src/plugins/builtin/options-scenario/model.test.ts +0 -222
  1484. package/src/plugins/builtin/options-scenario/pane.test.tsx +0 -195
  1485. package/src/plugins/builtin/options-scenario/state.test.ts +0 -62
  1486. package/src/plugins/builtin/plugin-marketplace/model.test.ts +0 -493
  1487. package/src/plugins/builtin/plugin-module.test.ts +0 -101
  1488. package/src/plugins/builtin/portfolio-list/account-metrics.test.ts +0 -243
  1489. package/src/plugins/builtin/portfolio-list/bond-price-basis.test.ts +0 -120
  1490. package/src/plugins/builtin/portfolio-list/cell-version.test.ts +0 -89
  1491. package/src/plugins/builtin/portfolio-list/cli/render.test.ts +0 -261
  1492. package/src/plugins/builtin/portfolio-list/index.test.ts +0 -248
  1493. package/src/plugins/builtin/portfolio-list/live-valuation.test.ts +0 -94
  1494. package/src/plugins/builtin/portfolio-list/metrics.test.ts +0 -562
  1495. package/src/plugins/builtin/portfolio-list/mutations.test.ts +0 -200
  1496. package/src/plugins/builtin/portfolio-list/pane/data.test.ts +0 -54
  1497. package/src/plugins/builtin/portfolio-list/pane/index.test.tsx +0 -1835
  1498. package/src/plugins/builtin/portfolio-list/position-cost-integrity.test.ts +0 -101
  1499. package/src/plugins/builtin/portfolio-list/summary/index.test.ts +0 -184
  1500. package/src/plugins/builtin/portfolio-list/summary/live-accounts.test.tsx +0 -90
  1501. package/src/plugins/builtin/portfolio-list/use-cursor-neighbor-prefetch.test.tsx +0 -96
  1502. package/src/plugins/builtin/portfolio-list/use-throttled-cursor-symbol.test.tsx +0 -166
  1503. package/src/plugins/builtin/portfolio-list/use-throttled-ticker-order.test.tsx +0 -76
  1504. package/src/plugins/builtin/rate-path/model.test.ts +0 -50
  1505. package/src/plugins/builtin/realized-vol/chart-model.test.ts +0 -24
  1506. package/src/plugins/builtin/realized-vol/client.test.ts +0 -193
  1507. package/src/plugins/builtin/realized-vol/model.test.ts +0 -155
  1508. package/src/plugins/builtin/relative-rotation/model.test.ts +0 -194
  1509. package/src/plugins/builtin/research/analyst-headless.test.ts +0 -88
  1510. package/src/plugins/builtin/research/analyst-model.test.ts +0 -125
  1511. package/src/plugins/builtin/research/analyst-pane.test.tsx +0 -162
  1512. package/src/plugins/builtin/research/corporate-actions-pane.test.tsx +0 -77
  1513. package/src/plugins/builtin/research/equity-diagnostic-pane.test.tsx +0 -303
  1514. package/src/plugins/builtin/research/event-model.test.ts +0 -165
  1515. package/src/plugins/builtin/research/events-headless.test.ts +0 -43
  1516. package/src/plugins/builtin/research/headless.test.ts +0 -111
  1517. package/src/plugins/builtin/research/index.test.ts +0 -442
  1518. package/src/plugins/builtin/research/relative-valuation-headless.test.ts +0 -192
  1519. package/src/plugins/builtin/research/relative-valuation-model.test.ts +0 -49
  1520. package/src/plugins/builtin/research/relative-valuation-pane.test.tsx +0 -99
  1521. package/src/plugins/builtin/research-search/command-bar-search.test.ts +0 -81
  1522. package/src/plugins/builtin/research-search/document-view.test.tsx +0 -75
  1523. package/src/plugins/builtin/research-search/model.test.ts +0 -40
  1524. package/src/plugins/builtin/research-search/pane.test.tsx +0 -256
  1525. package/src/plugins/builtin/research-search/snippet.test.ts +0 -78
  1526. package/src/plugins/builtin/risk-factors/data.test.ts +0 -63
  1527. package/src/plugins/builtin/risk-factors/headless.test.ts +0 -40
  1528. package/src/plugins/builtin/risk-factors/pane.test.tsx +0 -56
  1529. package/src/plugins/builtin/risk-factors/test-fixtures.ts +0 -4
  1530. package/src/plugins/builtin/scanner/flow-history.test.tsx +0 -138
  1531. package/src/plugins/builtin/scanner/flow-model.test.ts +0 -180
  1532. package/src/plugins/builtin/scanner/flow-pane.test.tsx +0 -159
  1533. package/src/plugins/builtin/scanner/headless.test.ts +0 -121
  1534. package/src/plugins/builtin/scanner/hilo-model.test.ts +0 -44
  1535. package/src/plugins/builtin/sec/filing-content.test.ts +0 -57
  1536. package/src/plugins/builtin/sec/headless.test.ts +0 -99
  1537. package/src/plugins/builtin/sec/pane.test.tsx +0 -152
  1538. package/src/plugins/builtin/sectors/client.test.ts +0 -228
  1539. package/src/plugins/builtin/sectors/headless.test.ts +0 -87
  1540. package/src/plugins/builtin/sectors/pane-cache.test.tsx +0 -78
  1541. package/src/plugins/builtin/sectors/sector-model.test.ts +0 -119
  1542. package/src/plugins/builtin/shared/auto-refresh.test.tsx +0 -95
  1543. package/src/plugins/builtin/shared/auto-refresh.ts +0 -97
  1544. package/src/plugins/builtin/shared/live-streaming.ts +0 -60
  1545. package/src/plugins/builtin/shared/pane-footer.ts +0 -93
  1546. package/src/plugins/builtin/shared/plan-access.test.ts +0 -69
  1547. package/src/plugins/builtin/shared/plan-access.ts +0 -109
  1548. package/src/plugins/builtin/shared/public-pane.test.ts +0 -12
  1549. package/src/plugins/builtin/shared/read-state.ts +0 -104
  1550. package/src/plugins/builtin/shared/research-cloud-session.test.tsx +0 -143
  1551. package/src/plugins/builtin/shared/screener-live-quotes.test.ts +0 -111
  1552. package/src/plugins/builtin/shared/screener-live-quotes.ts +0 -165
  1553. package/src/plugins/builtin/shared/series-cache.test.ts +0 -106
  1554. package/src/plugins/builtin/shared/table-pane.ts +0 -32
  1555. package/src/plugins/builtin/shared/ticker-request.test.ts +0 -18
  1556. package/src/plugins/builtin/shared/ticker-request.test.tsx +0 -137
  1557. package/src/plugins/builtin/shared/ticker-source.ts +0 -32
  1558. package/src/plugins/builtin/shared/ticker-surface.test.ts +0 -84
  1559. package/src/plugins/builtin/shared/use-quote-board.test.tsx +0 -325
  1560. package/src/plugins/builtin/shared/volatility/live-session.test.ts +0 -91
  1561. package/src/plugins/builtin/shared/volatility/options.test.ts +0 -127
  1562. package/src/plugins/builtin/shared/volatility/realized.test.ts +0 -201
  1563. package/src/plugins/builtin/shared/volatility/realized.ts +0 -292
  1564. package/src/plugins/builtin/shared/volatility/smile.test.ts +0 -209
  1565. package/src/plugins/builtin/short-interest/client.test.ts +0 -55
  1566. package/src/plugins/builtin/short-interest/headless.test.ts +0 -96
  1567. package/src/plugins/builtin/short-interest/pane.test.tsx +0 -57
  1568. package/src/plugins/builtin/short-volume/model.test.ts +0 -39
  1569. package/src/plugins/builtin/thirteenf/api.test.ts +0 -149
  1570. package/src/plugins/builtin/thirteenf/data.test.ts +0 -291
  1571. package/src/plugins/builtin/thirteenf/headless.test.ts +0 -182
  1572. package/src/plugins/builtin/thirteenf/model.test.ts +0 -230
  1573. package/src/plugins/builtin/thirteenf/overlap.test.ts +0 -29
  1574. package/src/plugins/builtin/thirteenf/pane.test.tsx +0 -407
  1575. package/src/plugins/builtin/thirteenf/signals.test.ts +0 -16
  1576. package/src/plugins/builtin/ticker-detail/chart-tab-switch.test.tsx +0 -275
  1577. package/src/plugins/builtin/ticker-detail/data-panes/historical-price-precision.test.tsx +0 -120
  1578. package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.test.tsx +0 -41
  1579. package/src/plugins/builtin/ticker-detail/financials/aggregation.test.ts +0 -79
  1580. package/src/plugins/builtin/ticker-detail/financials/model.test.ts +0 -276
  1581. package/src/plugins/builtin/ticker-detail/financials/period-integrity.test.tsx +0 -78
  1582. package/src/plugins/builtin/ticker-detail/fund-profile.test.tsx +0 -118
  1583. package/src/plugins/builtin/ticker-detail/headless.test.ts +0 -165
  1584. package/src/plugins/builtin/ticker-detail/index.test.tsx +0 -850
  1585. package/src/plugins/builtin/ticker-detail/overview/model.test.ts +0 -118
  1586. package/src/plugins/builtin/ticker-detail/overview-return-coverage.test.tsx +0 -71
  1587. package/src/plugins/builtin/ticker-detail/quote-monitor/card.test.tsx +0 -70
  1588. package/src/plugins/builtin/ticker-detail/quote-monitor/index.test.tsx +0 -261
  1589. package/src/plugins/builtin/ticker-detail/quote-monitor/retained-status.test.tsx +0 -134
  1590. package/src/plugins/builtin/ticker-detail/quote-status.test.tsx +0 -116
  1591. package/src/plugins/builtin/ticker-detail/quote-time-integrity.test.ts +0 -42
  1592. package/src/plugins/builtin/ticker-research-backend-plugin.ts +0 -10
  1593. package/src/plugins/builtin/ticker-research-plugin.ts +0 -61
  1594. package/src/plugins/builtin/time-sales/model.test.ts +0 -83
  1595. package/src/plugins/builtin/time-sales/snapshot-client.test.ts +0 -31
  1596. package/src/plugins/builtin/time-sales/test-fixture.ts +0 -12
  1597. package/src/plugins/builtin/time-sales/use-tape.test.tsx +0 -115
  1598. package/src/plugins/builtin/treasury-auctions/cache.test.ts +0 -215
  1599. package/src/plugins/builtin/treasury-auctions/client.test.ts +0 -207
  1600. package/src/plugins/builtin/treasury-auctions/headless.test.ts +0 -34
  1601. package/src/plugins/builtin/treasury-auctions/model.test.ts +0 -187
  1602. package/src/plugins/builtin/treasury-auctions/pane.test.tsx +0 -174
  1603. package/src/plugins/builtin/vol-surface/client.test.ts +0 -179
  1604. package/src/plugins/builtin/vol-surface/evidence.test.ts +0 -73
  1605. package/src/plugins/builtin/vol-surface/live.test.ts +0 -95
  1606. package/src/plugins/builtin/vol-surface/model.test.ts +0 -243
  1607. package/src/plugins/builtin/vol-surface/pane.test.tsx +0 -265
  1608. package/src/plugins/builtin/vol-surface/raster.test.ts +0 -28
  1609. package/src/plugins/builtin/vol-surface/stored.test.ts +0 -62
  1610. package/src/plugins/builtin/volatility/chart-model.test.ts +0 -61
  1611. package/src/plugins/builtin/volatility/client.test.ts +0 -207
  1612. package/src/plugins/builtin/volatility/evidence.test.ts +0 -49
  1613. package/src/plugins/builtin/volatility/headless.test.ts +0 -52
  1614. package/src/plugins/builtin/volatility/model.test.ts +0 -152
  1615. package/src/plugins/builtin/world-indices/headless.test.ts +0 -32
  1616. package/src/plugins/builtin/world-indices/pane.test.tsx +0 -156
  1617. package/src/plugins/builtin/world-venue-map/map.desktop.test.tsx +0 -45
  1618. package/src/plugins/builtin/world-venue-map/model.test.ts +0 -85
  1619. package/src/plugins/builtin/yield-curve/chart.test.ts +0 -23
  1620. package/src/plugins/builtin/yield-curve/headless.test.ts +0 -40
  1621. package/src/plugins/builtin/yield-curve/history.test.ts +0 -124
  1622. package/src/plugins/builtin/yield-curve/pane.test.tsx +0 -140
  1623. package/src/plugins/builtin/yield-curve/treasury-data.test.ts +0 -35
  1624. package/src/plugins/bundle.test.ts +0 -209
  1625. package/src/plugins/catalog-backend.test.ts +0 -47
  1626. package/src/plugins/catalog-browser.test.ts +0 -72
  1627. package/src/plugins/gridlock-notification.ts +0 -16
  1628. package/src/plugins/host-contract.ts +0 -72
  1629. package/src/plugins/host-link.test.ts +0 -133
  1630. package/src/plugins/host-module-imports.test.ts +0 -94
  1631. package/src/plugins/host-module-imports.ts +0 -73
  1632. package/src/plugins/host-resolver.test.ts +0 -96
  1633. package/src/plugins/launch-layout.test.ts +0 -131
  1634. package/src/plugins/loader.test.ts +0 -54
  1635. package/src/plugins/pane-manager.test.ts +0 -309
  1636. package/src/plugins/registry/index.test.ts +0 -601
  1637. package/src/plugins/registry/pane-settings.test.ts +0 -98
  1638. package/src/plugins/registry/setup-command.test.ts +0 -62
  1639. package/src/plugins/runtime/index.test.tsx +0 -328
  1640. package/src/plugins/seed.test.ts +0 -136
  1641. package/src/plugins/ticker-navigation.test.ts +0 -141
  1642. package/src/public/public-api.test.ts +0 -42
  1643. package/src/react/async-resource.test.tsx +0 -124
  1644. package/src/react/input.test.ts +0 -182
  1645. package/src/remote/controller.test.ts +0 -585
  1646. package/src/remote/json-patch.test.ts +0 -31
  1647. package/src/remote/schema.test.ts +0 -65
  1648. package/src/remote/semantic-tree.test.tsx +0 -105
  1649. package/src/remote/server.test.ts +0 -50
  1650. package/src/renderers/browser/bundled-plugins.test.ts +0 -41
  1651. package/src/renderers/browser/cloud-transport.test.ts +0 -68
  1652. package/src/renderers/browser/config-host.test.ts +0 -70
  1653. package/src/renderers/browser/deeplink-bridge.test.ts +0 -56
  1654. package/src/renderers/browser/error-boundary.tsx +0 -23
  1655. package/src/renderers/browser/http-proxy-transport.test.ts +0 -98
  1656. package/src/renderers/browser/research-entry.test.ts +0 -32
  1657. package/src/renderers/browser/storage.test.ts +0 -66
  1658. package/src/renderers/cloudflare/http-proxy.test.ts +0 -122
  1659. package/src/renderers/cloudflare/worker.test.ts +0 -155
  1660. package/src/renderers/electrobun/bun/application-menu/click.test.ts +0 -55
  1661. package/src/renderers/electrobun/bun/context-menu/click.test.ts +0 -67
  1662. package/src/renderers/electrobun/bun/context-menu/normalize.test.ts +0 -52
  1663. package/src/renderers/electrobun/bun/desktop/capability-bridge.test.ts +0 -112
  1664. package/src/renderers/electrobun/bun/desktop/http-fetch.test.ts +0 -89
  1665. package/src/renderers/electrobun/bun/desktop/http-stream.test.ts +0 -200
  1666. package/src/renderers/electrobun/bun/desktop/initialization.test.ts +0 -27
  1667. package/src/renderers/electrobun/bun/desktop/window-controls.test.ts +0 -53
  1668. package/src/renderers/electrobun/bun/desktop/window-controls.ts +0 -75
  1669. package/src/renderers/electrobun/bun/desktop/window-events.ts +0 -49
  1670. package/src/renderers/electrobun/bun/desktop/window-style.ts +0 -34
  1671. package/src/renderers/electrobun/bun/desktop/windows-custom-chrome.ts +0 -58
  1672. package/src/renderers/electrobun/bun/desktop/windows-icons.ts +0 -70
  1673. package/src/renderers/electrobun/bun/desktop/windows-native.ts +0 -75
  1674. package/src/renderers/electrobun/bun/desktop/workspace/index.test.ts +0 -147
  1675. package/src/renderers/electrobun/bun/window/frame.test.ts +0 -47
  1676. package/src/renderers/electrobun/view/application-menu-bridge.ts +0 -12
  1677. package/src/renderers/electrobun/view/cli-pane-shot-frame.test.tsx +0 -76
  1678. package/src/renderers/electrobun/view/cli-pane-shot-health.test.ts +0 -25
  1679. package/src/renderers/electrobun/view/context-menu.test.ts +0 -146
  1680. package/src/renderers/electrobun/view/data-table/frozen-column.test.tsx +0 -73
  1681. package/src/renderers/electrobun/view/data-table/horizontal-navigation.test.tsx +0 -82
  1682. package/src/renderers/electrobun/view/data-table/index.test.tsx +0 -127
  1683. package/src/renderers/electrobun/view/desktop/controls.test.tsx +0 -161
  1684. package/src/renderers/electrobun/view/desktop/list-view.test.tsx +0 -37
  1685. package/src/renderers/electrobun/view/desktop/window/snapshot.test.ts +0 -57
  1686. package/src/renderers/electrobun/view/desktop-deeplink-bridge.ts +0 -10
  1687. package/src/renderers/electrobun/view/dialog-host.test.ts +0 -25
  1688. package/src/renderers/electrobun/view/dialog-stack.test.tsx +0 -73
  1689. package/src/renderers/electrobun/view/external-plugins.test.ts +0 -57
  1690. package/src/renderers/electrobun/view/history-metadata-rpc.test.ts +0 -62
  1691. package/src/renderers/electrobun/view/host/ascii-text.test.ts +0 -48
  1692. package/src/renderers/electrobun/view/host/box.test.tsx +0 -171
  1693. package/src/renderers/electrobun/view/host/focus-scope.test.ts +0 -37
  1694. package/src/renderers/electrobun/view/host/scroll-box.desktop.test.tsx +0 -46
  1695. package/src/renderers/electrobun/view/host/style.test.ts +0 -15
  1696. package/src/renderers/electrobun/view/host/surface-3d.test.ts +0 -33
  1697. package/src/renderers/electrobun/view/input-host.test.tsx +0 -104
  1698. package/src/renderers/electrobun/view/key-event.test.ts +0 -34
  1699. package/src/renderers/electrobun/view/native-stubs/chart/kitty-support.ts +0 -19
  1700. package/src/renderers/electrobun/view/native-stubs/chart/surface-manager.ts +0 -36
  1701. package/src/renderers/electrobun/view/native-stubs/ibkr-native-loader.ts +0 -3
  1702. package/src/renderers/electrobun/view/native-stubs/native-stubs.test.ts +0 -42
  1703. package/src/renderers/electrobun/view/notes-files.ts +0 -56
  1704. package/src/renderers/electrobun/view/remote/backend-quote-subscription.test.ts +0 -87
  1705. package/src/renderers/electrobun/view/remote/capability-invoker.test.ts +0 -96
  1706. package/src/renderers/electrobun/view/remote/connection-health-backend.ts +0 -19
  1707. package/src/renderers/electrobun/view/remote/connection-health.test.ts +0 -44
  1708. package/src/renderers/electrobun/view/remote/quote-subscription-registry.test.ts +0 -86
  1709. package/src/renderers/electrobun/view/rpc-codec.test.ts +0 -112
  1710. package/src/renderers/electrobun/view/screenshot-watermark.test.ts +0 -48
  1711. package/src/renderers/electrobun/view/toast-host.test.tsx +0 -61
  1712. package/src/renderers/opentui/chart-surface.test.tsx +0 -147
  1713. package/src/renderers/opentui/image/loader.test.ts +0 -25
  1714. package/src/renderers/opentui/interaction-performance.test.ts +0 -79
  1715. package/src/renderers/opentui/terminal-media.test.ts +0 -173
  1716. package/src/renderers/share/chart.test.ts +0 -52
  1717. package/src/renderers/share/layout-view.test.tsx +0 -58
  1718. package/src/renderers/share/view.test.tsx +0 -120
  1719. package/src/shares/api.test.ts +0 -120
  1720. package/src/shares/location.test.ts +0 -19
  1721. package/src/shares/pane.test.ts +0 -110
  1722. package/src/sources/asml-earnings.test.ts +0 -197
  1723. package/src/sources/fixtures/sec-operating-expenses.json +0 -163
  1724. package/src/sources/fixtures/shop-20251231-quarterly-summary.html +0 -1
  1725. package/src/sources/fixtures/shop-20260630-quarterly-summary.html +0 -1
  1726. package/src/sources/fixtures/shop-operating-provider.json +0 -141
  1727. package/src/sources/fixtures/shop-quarterly-summary-provenance.json +0 -24
  1728. package/src/sources/fixtures/shop-submissions-20260922.json +0 -31
  1729. package/src/sources/gloomberb-cloud/history-coverage.test.ts +0 -119
  1730. package/src/sources/gloomberb-cloud/history-retention.test.ts +0 -207
  1731. package/src/sources/gloomberb-cloud/history-session.test.ts +0 -76
  1732. package/src/sources/gloomberb-cloud/index.test.ts +0 -1116
  1733. package/src/sources/gloomberb-cloud/normalizers.test.ts +0 -135
  1734. package/src/sources/gloomberb-cloud/quote-metadata.test.ts +0 -50
  1735. package/src/sources/gloomberb-cloud/valuation-observations.ts +0 -29
  1736. package/src/sources/history-coverage.test.ts +0 -40
  1737. package/src/sources/listing-history.ts +0 -52
  1738. package/src/sources/provider-router/arca-cache.test.ts +0 -97
  1739. package/src/sources/provider-router/asml-earnings-cache.test.ts +0 -158
  1740. package/src/sources/provider-router/broker-session.test.ts +0 -52
  1741. package/src/sources/provider-router/cache.test.ts +0 -133
  1742. package/src/sources/provider-router/cached-financials.test.ts +0 -711
  1743. package/src/sources/provider-router/cached-listing-identity.test.ts +0 -159
  1744. package/src/sources/provider-router/cached-routes.test.ts +0 -232
  1745. package/src/sources/provider-router/connection-health.test.ts +0 -28
  1746. package/src/sources/provider-router/financials.test.ts +0 -209
  1747. package/src/sources/provider-router/fixtures/quarterly-source-disagreements.json +0 -438
  1748. package/src/sources/provider-router/fixtures/shop-nasdaqgs.json +0 -137
  1749. package/src/sources/provider-router/history-boundary-cache.test.ts +0 -72
  1750. package/src/sources/provider-router/history-calendar-cache.test.ts +0 -301
  1751. package/src/sources/provider-router/history-exact-window.test.ts +0 -187
  1752. package/src/sources/provider-router/history-gap-cache.test.ts +0 -84
  1753. package/src/sources/provider-router/history-gaps.test.ts +0 -141
  1754. package/src/sources/provider-router/history-retention.test.ts +0 -239
  1755. package/src/sources/provider-router/history-session.test.ts +0 -138
  1756. package/src/sources/provider-router/history.test.ts +0 -780
  1757. package/src/sources/provider-router/index.test.ts +0 -1990
  1758. package/src/sources/provider-router/listing-history.test.ts +0 -139
  1759. package/src/sources/provider-router/listing-identity.test.ts +0 -128
  1760. package/src/sources/provider-router/nasdaqgs-listing.test.ts +0 -78
  1761. package/src/sources/provider-router/news.test.ts +0 -34
  1762. package/src/sources/provider-router/non-company-metadata.test.ts +0 -95
  1763. package/src/sources/provider-router/o-income-basis.test.ts +0 -64
  1764. package/src/sources/provider-router/operating-result-cache.test.ts +0 -44
  1765. package/src/sources/provider-router/operating-result-retry.test.ts +0 -221
  1766. package/src/sources/provider-router/profile-enrichment.test.ts +0 -168
  1767. package/src/sources/provider-router/quote-completion.test.ts +0 -62
  1768. package/src/sources/provider-router/quote-domain.test.ts +0 -92
  1769. package/src/sources/provider-router/quote-route.test.ts +0 -255
  1770. package/src/sources/provider-router/realtime-access.test.ts +0 -22
  1771. package/src/sources/provider-router/routing.test.ts +0 -39
  1772. package/src/sources/provider-router/search.test.ts +0 -191
  1773. package/src/sources/provider-router/shell-history-cache.test.ts +0 -131
  1774. package/src/sources/provider-router/statement-history.test.ts +0 -71
  1775. package/src/sources/provider-router/statement-observations.test.ts +0 -162
  1776. package/src/sources/provider-router/valuation-retractions.test.ts +0 -280
  1777. package/src/sources/reported-operating-results.test.ts +0 -286
  1778. package/src/sources/sec-bank-revenue.test.ts +0 -79
  1779. package/src/sources/sec-edgar-shares.fixture.json +0 -188
  1780. package/src/sources/sec-edgar-shares.test.ts +0 -66
  1781. package/src/sources/sec-edgar.test.ts +0 -924
  1782. package/src/sources/sec-income-attribution.test.ts +0 -93
  1783. package/src/sources/sec-operating-expenses.test.ts +0 -42
  1784. package/src/sources/yahoo-finance/fixtures/aapl-final-observation.json +0 -20
  1785. package/src/sources/yahoo-finance/history-session.test.ts +0 -120
  1786. package/src/sources/yahoo-finance/history.test.ts +0 -47
  1787. package/src/sources/yahoo-finance/mappers.test.ts +0 -176
  1788. package/src/sources/yahoo-finance/options.test.ts +0 -23
  1789. package/src/sources/yahoo-finance/requests.test.ts +0 -119
  1790. package/src/sources/yahoo-finance/snapshots.test.ts +0 -225
  1791. package/src/sources/yahoo-finance/symbols.test.ts +0 -18
  1792. package/src/sources/yahoo-finance.test.ts +0 -330
  1793. package/src/state/app/activity.test.ts +0 -54
  1794. package/src/state/app/bootstrap.test.ts +0 -664
  1795. package/src/state/app/context/index.test.ts +0 -604
  1796. package/src/state/app/context/index.test.tsx +0 -347
  1797. package/src/state/app/context/selector.test.tsx +0 -424
  1798. package/src/state/hooks/inline-ticker-failures.test.ts +0 -77
  1799. package/src/state/hooks/inline-tickers.test.tsx +0 -253
  1800. package/src/state/hooks/live-ticker-financials.test.tsx +0 -120
  1801. package/src/state/hooks/quote-streaming.test.ts +0 -44
  1802. package/src/state/hooks/quote-streaming.test.tsx +0 -442
  1803. package/src/state/persist-scheduler.test.ts +0 -151
  1804. package/src/state/selectors-ui.ts +0 -47
  1805. package/src/state/selectors.ts +0 -27
  1806. package/src/state/session-persistence.test.ts +0 -187
  1807. package/src/state/ticker-refresh-queue.test.ts +0 -46
  1808. package/src/sync/auth-transition.test.ts +0 -36
  1809. package/src/sync/controller.test.ts +0 -527
  1810. package/src/sync/core-contributors.test.ts +0 -643
  1811. package/src/test-support/fixtures/asml-earnings.json +0 -993
  1812. package/src/theme/colors.test.ts +0 -85
  1813. package/src/theme/font-scale.test.ts +0 -14
  1814. package/src/theme/theme-context.test.tsx +0 -67
  1815. package/src/theme/themes.test.ts +0 -100
  1816. package/src/tickers/instrument-kind.test.ts +0 -21
  1817. package/src/tickers/instrument-label.test.ts +0 -13
  1818. package/src/tickers/list.test.ts +0 -17
  1819. package/src/tickers/open-target.test.ts +0 -86
  1820. package/src/tickers/search/index.test.ts +0 -950
  1821. package/src/tickers/search-contract-context.test.tsx +0 -161
  1822. package/src/tickers/search-contract-templates.test.ts +0 -83
  1823. package/src/tickers/search-issuer-grouping.test.ts +0 -74
  1824. package/src/tickers/search-listing-ranking.test.tsx +0 -122
  1825. package/src/tickers/tokenizer.test.ts +0 -31
  1826. package/src/time-series/bond-price-history.test.ts +0 -52
  1827. package/src/time-series/calendar-month-end-resolution.test.ts +0 -106
  1828. package/src/time-series/calendar-window-resolution.test.ts +0 -133
  1829. package/src/time-series/chart-data.test.ts +0 -288
  1830. package/src/time-series/date-window.test.ts +0 -113
  1831. package/src/time-series/economic.test.ts +0 -44
  1832. package/src/time-series/financial-history-request.test.ts +0 -20
  1833. package/src/time-series/financial-period-coverage.test.ts +0 -37
  1834. package/src/time-series/financial-period-gaps.test.ts +0 -128
  1835. package/src/time-series/fixtures/q4-reported-common-income.json +0 -394
  1836. package/src/time-series/fixtures/q4-reported-per-share.json +0 -305
  1837. package/src/time-series/fixtures/quote-store.ts +0 -55
  1838. package/src/time-series/forward-valuation.test.ts +0 -131
  1839. package/src/time-series/fundamentals.test.ts +0 -592
  1840. package/src/time-series/history-retention.test.ts +0 -141
  1841. package/src/time-series/history-session-cache.test.ts +0 -250
  1842. package/src/time-series/hooks.test.ts +0 -59
  1843. package/src/time-series/legacy-contract-live.test.ts +0 -22
  1844. package/src/time-series/live-bars.test.ts +0 -290
  1845. package/src/time-series/live-quotes.test.ts +0 -208
  1846. package/src/time-series/market-price-units.test.ts +0 -75
  1847. package/src/time-series/parsed-history-identity.test.tsx +0 -142
  1848. package/src/time-series/price-comparison.test.ts +0 -233
  1849. package/src/time-series/price-history-integrity-window.test.ts +0 -137
  1850. package/src/time-series/price-history-integrity.test.ts +0 -195
  1851. package/src/time-series/q4-common-income.test.ts +0 -63
  1852. package/src/time-series/q4-per-share.test.ts +0 -144
  1853. package/src/time-series/realized-vol-study.test.ts +0 -189
  1854. package/src/time-series/reporting-currency.test.ts +0 -99
  1855. package/src/time-series/resolution.test.ts +0 -132
  1856. package/src/time-series/resolve.test.ts +0 -2471
  1857. package/src/time-series/sec-eps-research.test.ts +0 -55
  1858. package/src/time-series/seed-cadence.test.tsx +0 -219
  1859. package/src/time-series/served-cadence-consumers.test.ts +0 -52
  1860. package/src/time-series/session-history-domain.test.ts +0 -160
  1861. package/src/time-series/spec-studies.test.ts +0 -619
  1862. package/src/time-series/transforms.test.ts +0 -216
  1863. package/src/time-series/use-chart-resolution.test.tsx +0 -632
  1864. package/src/time-series/valuation-currency.test.ts +0 -129
  1865. package/src/time-series/valuation-denominator.test.ts +0 -240
  1866. package/src/time-series/valuation-live-status.test.ts +0 -64
  1867. package/src/time-series/valuation-price.test.ts +0 -267
  1868. package/src/types/config.test.ts +0 -161
  1869. package/src/ui/context-menu.test.ts +0 -95
  1870. package/src/ui/qr.test.ts +0 -79
  1871. package/src/updater/github-releases.test.ts +0 -41
  1872. package/src/updater.test.ts +0 -561
  1873. package/src/updater.ts +0 -480
  1874. package/src/utils/calendar-date.test.ts +0 -18
  1875. package/src/utils/cli-output.test.ts +0 -43
  1876. package/src/utils/csv.test.ts +0 -13
  1877. package/src/utils/currency-units.test.ts +0 -66
  1878. package/src/utils/dom-screenshot.test.ts +0 -52
  1879. package/src/utils/double-escape-close.test.ts +0 -33
  1880. package/src/utils/earnings-result.ts +0 -35
  1881. package/src/utils/exchange-rate-map.ts +0 -9
  1882. package/src/utils/exchange-rate-snapshot.test.ts +0 -33
  1883. package/src/utils/exchanges.test.ts +0 -62
  1884. package/src/utils/external-url.test.ts +0 -32
  1885. package/src/utils/financial-statements.test.ts +0 -211
  1886. package/src/utils/format.test.ts +0 -61
  1887. package/src/utils/fuzzy-search.test.ts +0 -94
  1888. package/src/utils/fx-market-hours.test.ts +0 -28
  1889. package/src/utils/fx-status.test.ts +0 -16
  1890. package/src/utils/html-entities.test.ts +0 -8
  1891. package/src/utils/inline-content-tokenizer.test.ts +0 -31
  1892. package/src/utils/instrument-identity.test.ts +0 -26
  1893. package/src/utils/latest-financial-period.test.ts +0 -19
  1894. package/src/utils/link-tokenizer.test.ts +0 -27
  1895. package/src/utils/main-thread-monitor.ts +0 -127
  1896. package/src/utils/main-thread-stall.test.ts +0 -59
  1897. package/src/utils/market-capitalization-consumers.test.ts +0 -59
  1898. package/src/utils/market-capitalization.test.ts +0 -38
  1899. package/src/utils/operating-result-aggregation.ts +0 -106
  1900. package/src/utils/operating-result-consumers.test.ts +0 -212
  1901. package/src/utils/operating-result.ts +0 -100
  1902. package/src/utils/options.test.ts +0 -20
  1903. package/src/utils/price-earnings.test.ts +0 -39
  1904. package/src/utils/price-history.test.ts +0 -230
  1905. package/src/utils/relative-time.ts +0 -8
  1906. package/src/utils/reported-earnings-result.ts +0 -336
  1907. package/src/utils/reported-money.test.ts +0 -25
  1908. package/src/utils/reported-operating-result.ts +0 -271
  1909. package/src/utils/save-text-file.test.ts +0 -24
  1910. package/src/utils/sec-eps-basis.test.ts +0 -82
  1911. package/src/utils/sec.test.ts +0 -60
  1912. package/src/utils/semver.test.ts +0 -31
  1913. package/src/utils/shop-operating-table.ts +0 -230
  1914. package/src/utils/shortcut-labels.test.ts +0 -20
  1915. package/src/utils/sort-values.test.ts +0 -11
  1916. package/src/utils/statement-observations.ts +0 -129
  1917. package/src/utils/throttled-fetch.test.ts +0 -186
  1918. package/src/utils/tweet-text.test.ts +0 -13
@@ -1,2019 +0,0 @@
1
- import { afterEach, describe, expect, test } from "bun:test";
2
- import {
3
- act,
4
- createElement,
5
- forwardRef,
6
- useMemo,
7
- useState,
8
- type ForwardedRef,
9
- type ReactNode,
10
- } from "react";
11
- import type { ResolvedSeries, TimeSeriesPoint } from "../../../time-series/types";
12
- import { testRender } from "../../../renderers/opentui/test-utils";
13
- import {
14
- Box,
15
- Text,
16
- UiHostProvider,
17
- useNativeRenderer,
18
- useRendererHost,
19
- useUiHost,
20
- type BoxRenderable,
21
- } from "../../../ui";
22
- import {
23
- InputHostProvider,
24
- type InputHost,
25
- type KeyEventLike,
26
- } from "../../../react/input";
27
- import { CompositeChart } from "./composite-chart";
28
- import { createDefaultConfig } from "../../../types/config";
29
- import { AppContext, createInitialState, PaneInstanceProvider } from "../../../state/app/context";
30
- import {
31
- buildCompositeNavigationFrame,
32
- zoomCompositeViewport,
33
- } from "./interactions";
34
- import { COMPOSITE_RIGHT_OFFSET_RATIO } from "./time-scale";
35
- import { getThemeColors, syncTheme } from "../../../theme/colors";
36
- import { ThemeProvider } from "../../../theme/theme-context";
37
- import { DEFAULT_THEME } from "../../../theme/themes";
38
-
39
- let testSetup: Awaited<ReturnType<typeof testRender>> | undefined;
40
- let chartShortcut: ((event: KeyEventLike) => void) | null = null;
41
- let capturedSurfaceProps: Record<string, any> | null = null;
42
- let capturedSurfaceNode: BoxRenderable | null = null;
43
-
44
- const chartInputHost: InputHost = {
45
- useShortcut(handler) {
46
- chartShortcut = handler;
47
- },
48
- useViewport() {
49
- return { width: 80, height: 24 };
50
- },
51
- };
52
-
53
- function assignRef(ref: ForwardedRef<any>, value: any) {
54
- if (typeof ref === "function") ref(value);
55
- else if (ref) ref.current = value;
56
- }
57
-
58
- function CaptureChartSurfaceProvider({
59
- children,
60
- canvasCharts = false,
61
- }: {
62
- children: ReactNode;
63
- canvasCharts?: boolean;
64
- }) {
65
- const baseUi = useUiHost();
66
- const renderer = useRendererHost();
67
- const nativeRenderer = useNativeRenderer();
68
- const CapturingChartSurface = useMemo(() => {
69
- const BaseChartSurface = baseUi.ChartSurface;
70
- return forwardRef<any, Record<string, any>>(function CapturingSurface(props, ref) {
71
- capturedSurfaceProps = props;
72
- return createElement(BaseChartSurface as any, {
73
- ...props,
74
- ref: (node: BoxRenderable | null) => {
75
- capturedSurfaceNode = node;
76
- assignRef(ref, node);
77
- },
78
- });
79
- });
80
- }, [baseUi]);
81
- const ui = useMemo(
82
- () => ({
83
- ...baseUi,
84
- ChartSurface: CapturingChartSurface,
85
- capabilities: canvasCharts
86
- ? { ...baseUi.capabilities, canvasCharts: true, nativeCharts: false }
87
- : baseUi.capabilities,
88
- }),
89
- [CapturingChartSurface, baseUi, canvasCharts],
90
- );
91
- return (
92
- <UiHostProvider ui={ui} renderer={renderer} nativeRenderer={nativeRenderer}>
93
- {children}
94
- </UiHostProvider>
95
- );
96
- }
97
-
98
- function pointerEvent(
99
- localX: number,
100
- localY: number,
101
- options: {
102
- ctrl?: boolean;
103
- shift?: boolean;
104
- alt?: boolean;
105
- scroll?: { direction: "up" | "down" | "left" | "right"; delta: number };
106
- } = {},
107
- ) {
108
- const node = capturedSurfaceNode!;
109
- return {
110
- x: (node.x as number) + localX,
111
- y: (node.y as number) + localY,
112
- modifiers: {
113
- shift: options.shift === true,
114
- alt: options.alt === true,
115
- ctrl: options.ctrl === true,
116
- },
117
- scroll: options.scroll,
118
- preventDefault() {},
119
- stopPropagation() {},
120
- };
121
- }
122
-
123
- function keyEvent(name: string, shift = false): KeyEventLike {
124
- let defaultPrevented = false;
125
- let propagationStopped = false;
126
- return {
127
- key: name,
128
- name,
129
- sequence: name,
130
- ctrl: false,
131
- shift,
132
- alt: false,
133
- meta: false,
134
- get defaultPrevented() {
135
- return defaultPrevented;
136
- },
137
- get propagationStopped() {
138
- return propagationStopped;
139
- },
140
- preventDefault() {
141
- defaultPrevented = true;
142
- },
143
- stopPropagation() {
144
- propagationStopped = true;
145
- },
146
- };
147
- }
148
-
149
- afterEach(async () => {
150
- if (testSetup) await act(async () => testSetup!.renderer.destroy());
151
- testSetup = undefined;
152
- chartShortcut = null;
153
- capturedSurfaceProps = null;
154
- capturedSurfaceNode = null;
155
- syncTheme(DEFAULT_THEME);
156
- });
157
-
158
- function point(date: string, value: number): TimeSeriesPoint {
159
- const observedAt = new Date(`${date}T00:00:00.000Z`);
160
- return { date: observedAt, observedAt, value };
161
- }
162
-
163
- function timestampPoint(timestamp: string, value: number): TimeSeriesPoint {
164
- const observedAt = new Date(timestamp);
165
- return { date: observedAt, observedAt, value };
166
- }
167
-
168
- function series(id: string, panelId: string, axis: ResolvedSeries["axis"], unit: string, values: number[]): ResolvedSeries {
169
- return {
170
- id,
171
- label: id === "price" ? "ACME Price" : "OTHER Revenue",
172
- color: id === "price" ? "#00ff66" : "#ffaa00",
173
- unit,
174
- unitGroup: unit === "USD" ? "currency" : "percent",
175
- nativeFrequency: id === "price" ? "daily" : "quarterly",
176
- dataShape: "scalar",
177
- style: id === "price" ? "line" : "step",
178
- transform: "raw",
179
- axis,
180
- panelId,
181
- interpolation: id === "price" ? "none" : "step-after",
182
- points: values.map((value, index) => point(`2025-01-0${index + 1}`, value)),
183
- };
184
- }
185
-
186
- function twoSessionCandles(): ResolvedSeries {
187
- const points = [
188
- ...Array.from({ length: 7 }, (_, index) => (
189
- Date.UTC(2025, 0, 2, 17, index * 30)
190
- )),
191
- ...Array.from({ length: 8 }, (_, index) => (
192
- Date.UTC(2025, 0, 3, 13, 30 + index * 30)
193
- )),
194
- ].map((timestamp, index) => {
195
- const date = new Date(timestamp);
196
- const value = 100 + index * 0.1;
197
- return {
198
- date,
199
- observedAt: date,
200
- value,
201
- open: value,
202
- high: value + 1,
203
- low: value - 1,
204
- close: value,
205
- volume: 100,
206
- };
207
- });
208
- return {
209
- ...series("price", "main", "left", "USD", []),
210
- nativeFrequency: "intraday",
211
- dataShape: "ohlc",
212
- style: "candles",
213
- timeBasis: {
214
- kind: "market",
215
- timeZone: "America/New_York",
216
- cadenceMs: 30 * 60_000,
217
- },
218
- points,
219
- };
220
- }
221
-
222
- describe("CompositeChart", () => {
223
- test("repaints cached chart rasters when the theme changes", async () => {
224
- let setThemeId: ((themeId: string) => void) | null = null;
225
- const chartSeries = [series("price", "main", "left", "USD", [100, 101, 102])];
226
-
227
- function ThemedChart() {
228
- const [themeId, setTheme] = useState(DEFAULT_THEME);
229
- setThemeId = setTheme;
230
- return (
231
- <ThemeProvider themeId={themeId}>
232
- <CaptureChartSurfaceProvider>
233
- <CompositeChart
234
- width={60}
235
- height={12}
236
- series={chartSeries}
237
- panels={[{ id: "main" }]}
238
- />
239
- </CaptureChartSurfaceProvider>
240
- </ThemeProvider>
241
- );
242
- }
243
-
244
- testSetup = await testRender(<ThemedChart />, { width: 62, height: 14 });
245
- await act(async () => {
246
- await testSetup!.renderOnce();
247
- await testSetup!.renderOnce();
248
- });
249
-
250
- const nextThemeId = "github-light";
251
- await act(async () => {
252
- setThemeId?.(nextThemeId);
253
- await testSetup!.renderOnce();
254
- await testSetup!.renderOnce();
255
- });
256
-
257
- const bitmap = capturedSurfaceProps!.bitmaps[0] as { pixels: Uint8Array };
258
- const expectedBackground = getThemeColors(nextThemeId).bg;
259
- const expectedRgb = [1, 3, 5].map((offset) => parseInt(expectedBackground.slice(offset, offset + 2), 16));
260
- expect(Array.from(bitmap.pixels.slice(0, 3))).toEqual(expectedRgb);
261
- });
262
-
263
- test("does not allocate a native raster when braille rendering is forced", async () => {
264
- const config = createDefaultConfig("/tmp/gloomberb-composite-braille");
265
- config.chartPreferences.renderer = "braille";
266
-
267
- testSetup = await testRender(
268
- <AppContext value={{ state: createInitialState(config), dispatch: () => {} }}>
269
- <CaptureChartSurfaceProvider>
270
- <CompositeChart
271
- width={60}
272
- height={12}
273
- series={[series("price", "main", "left", "USD", [100, 101, 102])]}
274
- panels={[{ id: "main" }]}
275
- />
276
- </CaptureChartSurfaceProvider>
277
- </AppContext>,
278
- { width: 62, height: 14 },
279
- );
280
- await act(async () => {
281
- await testSetup!.renderOnce();
282
- await testSetup!.renderOnce();
283
- });
284
-
285
- expect(capturedSurfaceProps!.bitmaps).toBeNull();
286
- });
287
-
288
- test("shows the regular-session move beside the latest intraday value", async () => {
289
- testSetup = await testRender(
290
- <CompositeChart
291
- width={60}
292
- height={12}
293
- series={[{
294
- ...series("price", "main", "left", "USD", [100, 110]),
295
- latestChangePercent: 10.65,
296
- }]}
297
- panels={[{ id: "main" }]}
298
- showLatestChangePercent
299
- />,
300
- { width: 62, height: 14 },
301
- );
302
-
303
- await act(async () => testSetup!.renderOnce());
304
-
305
- expect(testSetup.captureCharFrame()).toContain("ACME Price $110 +10.65%");
306
- });
307
-
308
- test("holds a lower panel's rows while its series has no observations in view", async () => {
309
- const price: ResolvedSeries = {
310
- ...series("price", "main", "left", "USD", []),
311
- points: [
312
- point("2025-01-01", 100),
313
- point("2025-01-02", 103),
314
- point("2025-01-03", 101),
315
- point("2025-01-04", 104),
316
- point("2025-01-05", 102),
317
- ],
318
- };
319
- const volume: ResolvedSeries = {
320
- ...series("volume", "volume", "left", "shares", []),
321
- label: "Volume",
322
- unitGroup: "volume",
323
- style: "columns",
324
- points: [point("2025-01-01", 4_000), point("2025-01-02", 6_000)],
325
- };
326
- const panels = [{ id: "main", height: 3 }, { id: "volume", height: 1 }];
327
- const renderChart = async (
328
- volumeSeries: ResolvedSeries,
329
- viewport?: { start: Date; end: Date },
330
- ) => {
331
- testSetup = await testRender(
332
- <CompositeChart
333
- width={78}
334
- height={18}
335
- series={[price, volumeSeries]}
336
- panels={panels}
337
- viewport={viewport}
338
- />,
339
- { width: 80, height: 20 },
340
- );
341
- await act(async () => {
342
- await testSetup!.renderOnce();
343
- await testSetup!.renderOnce();
344
- });
345
- const frame = testSetup!.captureCharFrame();
346
- await act(async () => testSetup!.renderer.destroy());
347
- testSetup = undefined;
348
- return frame;
349
- };
350
- // Price labels and the price line stay above the lower panel's first row,
351
- // and would spill into it the moment the lower panel gave up its rows.
352
- const lastPriceRow = (frame: string) => frame
353
- .split("\n")
354
- .reduce((row, line, index) => /[$•]/.test(line) ? index : row, -1);
355
- const volumeTop = (frame: string) => frame.split("\n").findIndex((line) => /^\s+[\d.]+K /.test(line));
356
-
357
- const loaded = await renderChart(volume);
358
- // Panned to a window the upper panel covers and the lower panel has no bars in.
359
- const panned = await renderChart(volume, {
360
- start: new Date("2025-01-03T00:00:00.000Z"),
361
- end: new Date("2025-01-05T00:00:00.000Z"),
362
- });
363
- // The same chart before the lower panel's data has loaded at all.
364
- const loading = await renderChart({ ...volume, points: [] });
365
-
366
- const lowerPanelTop = volumeTop(loaded);
367
- expect(lowerPanelTop).toBeGreaterThan(0);
368
- expect(volumeTop(panned)).toBe(lowerPanelTop);
369
- expect(lastPriceRow(panned)).toBeLessThan(lowerPanelTop);
370
- expect(lastPriceRow(loading)).toBe(lastPriceRow(loaded));
371
- expect(lastPriceRow(loaded)).toBe(lowerPanelTop - 1);
372
- // A panel with loaded history keeps its axis while the window holds no bars.
373
- expect(panned).toMatch(/\dK/);
374
- });
375
-
376
- test("lays out mixed panels with one shared legend and time axis", async () => {
377
- testSetup = await testRender(
378
- <CompositeChart
379
- width={78}
380
- height={18}
381
- series={[
382
- series("price", "main", "left", "USD", [100, 103, 101]),
383
- series("revenue", "fundamentals", "right", "%", [4, 6, 8]),
384
- ]}
385
- panels={[{ id: "main", height: 2 }, { id: "fundamentals", height: 1 }]}
386
- cursorDate={new Date("2025-01-02T00:00:00.000Z")}
387
- />,
388
- { width: 80, height: 20 },
389
- );
390
-
391
- await act(async () => {
392
- await testSetup!.renderOnce();
393
- await testSetup!.renderOnce();
394
- });
395
-
396
- const frame = testSetup.captureCharFrame();
397
- expect(frame).toContain("2025-01-02");
398
- expect(frame).toContain("ACME Price");
399
- expect(frame).toContain("OTHER Revenue");
400
- expect(frame).toContain("$103");
401
- expect(frame.match(/Jan 1/g)).toHaveLength(1);
402
- expect(frame.match(/Jan 3/g)).toHaveLength(1);
403
- });
404
-
405
- test("keeps legend items compact and anchors an accessory to the right edge", async () => {
406
- testSetup = await testRender(
407
- <CompositeChart
408
- width={78}
409
- height={12}
410
- series={[
411
- series("price", "main", "left", "USD", [100, 103, 101]),
412
- series("revenue", "main", "right", "%", [4, 6, 8]),
413
- ]}
414
- panels={[{ id: "main" }]}
415
- cursorDate={new Date("2025-01-02T00:00:00.000Z")}
416
- legendAccessory={(
417
- <Box width={14} height={1} overflow="hidden">
418
- <Text>+ add series</Text>
419
- </Box>
420
- )}
421
- />,
422
- { width: 80, height: 14 },
423
- );
424
-
425
- await act(async () => {
426
- await testSetup!.renderOnce();
427
- await testSetup!.renderOnce();
428
- });
429
-
430
- const legend = testSetup.captureCharFrame()
431
- .split("\n")
432
- .find((line) => line.includes("+ add series"));
433
- expect(legend).toBeDefined();
434
- expect(legend).toContain("ACME Price $103");
435
- expect(legend).toContain("OTHER Revenue 6.00%");
436
- const accessoryStart = legend!.indexOf("+ add series");
437
- const lastLegendEnd = legend!.indexOf("6.00%") + "6.00%".length;
438
- expect(accessoryStart).toBe(78 - 14);
439
- expect(accessoryStart - lastLegendEnd).toBeGreaterThan(1);
440
- });
441
-
442
- test("shortens long comparison names before clipping yield precision or units at 80 columns", async () => {
443
- testSetup = await testRender(
444
- <CompositeChart width={78} height={12}
445
- series={[
446
- { ...series("ig", "main", "left", "%", [5.68]), label: "ICE BofA US Corporate Index Effective Yield" },
447
- { ...series("hy", "main", "left", "%", [7.42]), label: "ICE BofA US High Yield Index Effective Yield" },
448
- ]}
449
- panels={[{ id: "main" }]}
450
- legendAccessory={<Box width={14} height={1}><Text>+ add series</Text></Box>}
451
- legendAccessoryWidth={14}
452
- />, { width: 80, height: 14 },
453
- );
454
- await act(async () => { await testSetup!.renderOnce(); await testSetup!.renderOnce(); });
455
- const legend = testSetup.captureCharFrame().split("\n").find((line) => line.includes("+ add series"))!;
456
- expect(legend).toContain("5.68%");
457
- expect(legend).toContain("7.42%");
458
- expect(legend.indexOf("7.42%") + 5).toBeLessThan(legend.indexOf("+ add series"));
459
- });
460
-
461
- test("leaving a historical chart restores its window's legend value instead of the navigation buffer", async () => {
462
- let setCursor: (date: Date | null) => void = () => {};
463
- const margin: ResolvedSeries = {
464
- ...series("margin", "main", "left", "%", []), label: "MSFT Operating Margin",
465
- style: "line", interpolation: "none",
466
- points: [point("2024-06-30", 44.64), point("2025-06-30", 45.62), point("2026-06-30", 46.78)],
467
- };
468
- function HistoricalChart() {
469
- const [cursor, updateCursor] = useState<Date | null>(null);
470
- setCursor = updateCursor;
471
- return <CompositeChart width={100} height={12} panels={[{ id: "main" }]} series={[margin]} clipToViewport
472
- viewport={{ start: new Date("2016-01-01"), end: new Date("2025-12-31T23:59:59.999Z") }} cursorDate={cursor} />;
473
- }
474
- testSetup = await testRender(<HistoricalChart />, { width: 102, height: 14 });
475
- await act(async () => { await testSetup!.renderOnce(); await testSetup!.renderOnce(); });
476
- const legend = () => testSetup!.captureCharFrame().split("\n")[0]!;
477
- expect(legend()).toContain("45.6%");
478
- expect(legend()).not.toContain("46.8%");
479
- await act(async () => { setCursor(new Date("2024-06-30")); });
480
- await act(async () => { await testSetup!.renderOnce(); });
481
- expect(legend()).toContain("44.6%");
482
- await act(async () => { setCursor(null); });
483
- await act(async () => { await testSetup!.renderOnce(); });
484
- expect(legend()).toContain("45.6%");
485
- expect(legend()).not.toContain("46.8%");
486
- });
487
-
488
- test("retains financial values and negative signs when long legend names need truncation", async () => {
489
- testSetup = await testRender(
490
- <CompositeChart width={100} height={12} panels={[{ id: "main" }]} series={[
491
- { ...series("revenue", "main", "left", "USD", [90_007_000_000]), label: "MSFT:XNAS Revenue", unitGroup: "currency-total:USD" },
492
- { ...series("margin", "main", "right", "%", [-49.612]), label: "Very long issuer Operating Margin", unitGroup: "percent" },
493
- { ...series("hk-revenue", "main", "left", "USD", [90_007_000_000]), label: "腾讯控股腾讯控股 Revenue", unitGroup: "currency-total:USD" },
494
- ]} />,
495
- { width: 102, height: 14 },
496
- );
497
- await act(async () => { await testSetup!.renderOnce(); await testSetup!.renderOnce(); });
498
- const legend = testSetup.captureCharFrame().split("\n")[0]!;
499
- expect(legend).toContain("MSFT:XNAS Revenue $90.01B");
500
- expect(legend).toContain("... -49.6%");
501
- expect(legend).toContain("腾讯控股腾讯控股");
502
- expect(legend.match(/\$90\.01B/g)).toHaveLength(2);
503
- });
504
-
505
- test("gives legend names the row's room and drops the listing exchange before cutting a name", async () => {
506
- const legendAt = async (width: number) => {
507
- if (testSetup) await act(async () => testSetup!.renderer.destroy());
508
- testSetup = await testRender(
509
- <CompositeChart width={width} height={10} panels={[{ id: "main" }]} series={[
510
- { ...series("price", "main", "left", "USD", [101]), label: "AAPL:XNAS Price" },
511
- { ...series("volume", "main", "left", "%", [8]), label: "Volume AAPL:XNAS Price" },
512
- ]} />,
513
- { width: width + 2, height: 12 },
514
- );
515
- await act(async () => { await testSetup!.renderOnce(); await testSetup!.renderOnce(); });
516
- return testSetup.captureCharFrame().split("\n")[0]!;
517
- };
518
- expect(await legendAt(60)).toContain("Volume AAPL:XNAS Price 8.00%");
519
- const narrow = await legendAt(50);
520
- expect(narrow).toContain("AAPL:XNAS Price $101");
521
- expect(narrow).toContain("Volume AAPL Price 8.00%");
522
- expect(narrow).not.toContain("...");
523
- });
524
-
525
- test("keeps non-plotted legend series available for restoring", async () => {
526
- const price = series("price", "main", "left", "USD", [100, 103, 101]);
527
- const hiddenRevenue = series("revenue", "main", "right", "%", [4, 6, 8]);
528
- testSetup = await testRender(
529
- <CompositeChart
530
- width={78}
531
- height={12}
532
- series={[price]}
533
- legendSeries={[price, hiddenRevenue]}
534
- panels={[{ id: "main" }]}
535
- cursorDate={new Date("2025-01-02T00:00:00.000Z")}
536
- />,
537
- { width: 80, height: 14 },
538
- );
539
-
540
- await act(async () => {
541
- await testSetup!.renderOnce();
542
- await testSetup!.renderOnce();
543
- });
544
-
545
- expect(testSetup.captureCharFrame()).toContain("OTHER Revenue");
546
- });
547
-
548
- test("uses buffered market anchors so closed sessions do not create chart holes", async () => {
549
- const candles = twoSessionCandles();
550
- const currentSession = {
551
- ...candles,
552
- points: candles.points.filter((point) => point.date.getUTCDate() === 3),
553
- };
554
- testSetup = await testRender(
555
- <CompositeChart
556
- width={72}
557
- height={12}
558
- series={[candles]}
559
- legendSeries={[currentSession]}
560
- panels={[{ id: "main" }]}
561
- viewport={{
562
- start: new Date("2025-01-02T17:00:00.000Z"),
563
- end: new Date("2025-01-03T17:00:00.000Z"),
564
- }}
565
- showLegend={false}
566
- />,
567
- { width: 74, height: 14 },
568
- );
569
- await act(async () => testSetup!.renderOnce());
570
-
571
- const bodyColumns = [...new Set(testSetup.captureCharFrame()
572
- .split("\n")
573
- .flatMap((line) => [...line].flatMap((cell, index) => cell === "█" ? [index] : [])))]
574
- .sort((left, right) => left - right);
575
- const largestGap = bodyColumns.slice(1).reduce(
576
- (largest, column, index) => Math.max(largest, column - bodyColumns[index]!),
577
- 0,
578
- );
579
-
580
- expect(bodyColumns.length).toBeGreaterThan(10);
581
- expect(largestGap).toBeLessThan(10);
582
- });
583
-
584
- test("toggles a series from its legend entry", async () => {
585
- const toggled: string[] = [];
586
- testSetup = await testRender(
587
- <CompositeChart
588
- width={58}
589
- height={10}
590
- series={[
591
- series("price", "main", "left", "USD", [100, 103, 101]),
592
- series("revenue", "main", "right", "%", [4, 6, 8]),
593
- ]}
594
- panels={[{ id: "main" }]}
595
- onToggleSeries={(seriesId) => toggled.push(seriesId)}
596
- />,
597
- { width: 60, height: 12 },
598
- );
599
-
600
- await act(async () => {
601
- await testSetup!.renderOnce();
602
- });
603
- const priceColumn = testSetup.captureCharFrame().split("\n")[0]!.indexOf("ACME Price");
604
- expect(priceColumn).toBeGreaterThan(0);
605
-
606
- await act(async () => {
607
- await testSetup!.mockMouse.click(priceColumn, 0);
608
- await testSetup!.renderOnce();
609
- });
610
- expect(toggled).toEqual(["price"]);
611
- });
612
-
613
- test("scrolls an overflowing legend horizontally", async () => {
614
- const labels = ["FIRST LONG SERIES", "SECOND LONG SERIES", "THIRD LONG SERIES", "LAST LONG SERIES"];
615
- const overflowingSeries = labels.map((label, index) => ({
616
- ...series(`series-${index}`, "main", "left", "USD", [index + 1, index + 2]),
617
- label,
618
- }));
619
- testSetup = await testRender(
620
- <CompositeChart
621
- width={38}
622
- height={10}
623
- series={overflowingSeries}
624
- panels={[{ id: "main" }]}
625
- />,
626
- { width: 40, height: 12 },
627
- );
628
-
629
- await act(async () => {
630
- await testSetup!.renderOnce();
631
- });
632
- expect(testSetup.captureCharFrame().split("\n")[0]).toContain("FIRST LONG SERIES");
633
- expect(testSetup.captureCharFrame().split("\n")[0]).not.toContain("LAST LONG SERIES");
634
-
635
- await act(async () => {
636
- for (let index = 0; index < 120; index += 1) {
637
- await testSetup!.mockMouse.scroll(20, 0, "down");
638
- }
639
- await testSetup!.renderOnce();
640
- });
641
- expect(testSetup.captureCharFrame().split("\n")[0]).toContain("LAST LONG SERIES");
642
- });
643
-
644
- test("reaches and toggles overflowing legend series from the keyboard", async () => {
645
- const toggled: string[] = [];
646
- const labels = ["FIRST LONG SERIES", "SECOND LONG SERIES", "THIRD LONG SERIES", "LAST LONG SERIES"];
647
- const overflowingSeries = labels.map((label, index) => ({
648
- ...series(`series-${index}`, "main", "left", "USD", [index + 1, index + 2]),
649
- label,
650
- }));
651
- testSetup = await testRender(
652
- <InputHostProvider host={chartInputHost}>
653
- <CompositeChart
654
- width={38}
655
- height={10}
656
- focused
657
- series={overflowingSeries}
658
- panels={[{ id: "main" }]}
659
- onToggleSeries={(seriesId) => toggled.push(seriesId)}
660
- />
661
- </InputHostProvider>,
662
- { width: 40, height: 12 },
663
- );
664
-
665
- await act(async () => {
666
- await testSetup!.renderOnce();
667
- for (let index = 0; index < overflowingSeries.length; index += 1) {
668
- chartShortcut?.(keyEvent("]"));
669
- }
670
- await testSetup!.renderOnce();
671
- await testSetup!.renderOnce();
672
- });
673
- expect(testSetup.captureCharFrame().split("\n")[0]).toContain("LAST LONG SERIES");
674
-
675
- await act(async () => {
676
- chartShortcut?.(keyEvent("space"));
677
- await testSetup!.renderOnce();
678
- });
679
- expect(toggled).toEqual(["series-3"]);
680
- });
681
-
682
- test("keeps the legend accessory visible when the pane is narrower than its legend", async () => {
683
- testSetup = await testRender(
684
- <CompositeChart
685
- width={20}
686
- height={10}
687
- series={[series("price", "main", "left", "USD", [100, 103, 101])]}
688
- panels={[{ id: "main" }]}
689
- legendAccessory={(
690
- <Box width={14} height={1} overflow="hidden">
691
- <Text>+ add series</Text>
692
- </Box>
693
- )}
694
- legendAccessoryWidth={14}
695
- />,
696
- { width: 22, height: 12 },
697
- );
698
-
699
- await act(async () => {
700
- await testSetup!.renderOnce();
701
- await testSetup!.renderOnce();
702
- });
703
-
704
- const legend = testSetup.captureCharFrame()
705
- .split("\n")
706
- .find((line) => line.includes("+ add series"));
707
- expect(legend).toBeDefined();
708
- expect(legend).toContain("●");
709
- });
710
-
711
- test("moves and clears the shared cursor from the keyboard while focused", async () => {
712
- const cursorChanges: Array<string | null> = [];
713
- testSetup = await testRender(
714
- <InputHostProvider host={chartInputHost}>
715
- <CompositeChart
716
- width={60}
717
- height={12}
718
- focused
719
- series={[series("price", "main", "left", "USD", [100, 103, 101])]}
720
- panels={[{ id: "main" }]}
721
- onCursorDateChange={(date) => cursorChanges.push(date?.toISOString() ?? null)}
722
- />
723
- </InputHostProvider>,
724
- { width: 62, height: 14 },
725
- );
726
-
727
- await act(async () => testSetup!.renderOnce());
728
- await act(async () => chartShortcut?.(keyEvent("left")));
729
- await act(async () => testSetup!.renderOnce());
730
- expect(cursorChanges).toEqual(["2025-01-03T00:00:00.000Z"]);
731
- const firstCursorFrame = testSetup.captureCharFrame();
732
- expect(firstCursorFrame).toContain("2025-01-03");
733
- // A keyboard cursor knows its column, not a level: the axis reads the
734
- // series value and no horizontal line crosses the plot.
735
- expect(firstCursorFrame).toContain("│");
736
- expect(firstCursorFrame).toContain("$101");
737
- expect(firstCursorFrame).not.toContain("────────");
738
-
739
- await act(async () => chartShortcut?.(keyEvent("left")));
740
- await act(async () => testSetup!.renderOnce());
741
- expect(cursorChanges).toEqual([
742
- "2025-01-03T00:00:00.000Z",
743
- "2025-01-02T00:00:00.000Z",
744
- ]);
745
- expect(testSetup.captureCharFrame()).toContain("2025-01-02");
746
-
747
- await act(async () => chartShortcut?.(keyEvent("escape")));
748
- await act(async () => testSetup!.renderOnce());
749
- // Escape drops the cursor, so its date leaves the time axis with it.
750
- expect(testSetup.captureCharFrame()).not.toContain("2025-01-02");
751
- });
752
-
753
- test("does not emit the same snapped cursor timestamp twice", async () => {
754
- const cursorChanges: string[] = [];
755
- testSetup = await testRender(
756
- <InputHostProvider host={chartInputHost}>
757
- <CompositeChart
758
- width={60}
759
- height={12}
760
- focused
761
- series={[series("price", "main", "left", "USD", [100, 103, 101])]}
762
- panels={[{ id: "main" }]}
763
- onCursorDateChange={(date) => {
764
- if (date) cursorChanges.push(date.toISOString());
765
- }}
766
- />
767
- </InputHostProvider>,
768
- { width: 62, height: 14 },
769
- );
770
-
771
- await act(async () => testSetup!.renderOnce());
772
- await act(async () => chartShortcut?.(keyEvent("right")));
773
- await act(async () => chartShortcut?.(keyEvent("left")));
774
-
775
- expect(cursorChanges).toEqual(["2025-01-01T00:00:00.000Z"]);
776
- });
777
-
778
- test("zooms with plus and resets the interaction viewport with zero", async () => {
779
- const viewportChanges: Array<{ start: string; end: string } | null> = [];
780
- const viewportInteractions: string[] = [];
781
- testSetup = await testRender(
782
- <InputHostProvider host={chartInputHost}>
783
- <CompositeChart
784
- width={60}
785
- height={12}
786
- focused
787
- series={[series("price", "main", "left", "USD", [100, 101, 102, 103, 104, 105, 106, 107, 108])]}
788
- panels={[{ id: "main" }]}
789
- viewport={{
790
- start: new Date("2025-01-01T00:00:00.000Z"),
791
- end: new Date("2025-01-09T00:00:00.000Z"),
792
- }}
793
- onViewportChange={(next, interaction) => {
794
- viewportInteractions.push(interaction);
795
- viewportChanges.push(next
796
- ? { start: next.start.toISOString(), end: next.end.toISOString() }
797
- : null);
798
- }}
799
- />
800
- </InputHostProvider>,
801
- { width: 62, height: 14 },
802
- );
803
-
804
- await act(async () => testSetup!.renderOnce());
805
- expect(testSetup.captureCharFrame()).toContain("Jan 1");
806
- expect(viewportChanges).toEqual([]);
807
-
808
- const zoomIn = keyEvent("=");
809
- zoomIn.sequence = "+";
810
- zoomIn.shift = true;
811
- await act(async () => chartShortcut?.(zoomIn));
812
- await act(async () => testSetup!.renderOnce());
813
-
814
- expect(zoomIn.defaultPrevented).toBe(true);
815
- expect(testSetup.captureCharFrame()).not.toContain("Jan 1");
816
- expect(viewportChanges.at(-1)?.start).not.toBe("2025-01-01T00:00:00.000Z");
817
- expect(viewportInteractions.at(-1)).toBe("zoom");
818
-
819
- await act(async () => chartShortcut?.(keyEvent("0")));
820
- await act(async () => testSetup!.renderOnce());
821
- expect(testSetup.captureCharFrame()).toContain("Jan 1");
822
- expect(viewportChanges.at(-1)).toBeNull();
823
- expect(viewportInteractions.at(-1)).toBe("reset");
824
- });
825
-
826
- test("keeps ownership of the window when zoom returns to the authored range", async () => {
827
- const viewportChanges: Array<{ start: string; end: string } | null> = [];
828
- testSetup = await testRender(
829
- <InputHostProvider host={chartInputHost}>
830
- <CompositeChart
831
- width={60}
832
- height={12}
833
- focused
834
- series={[series("price", "main", "left", "USD", [100, 101, 102, 103, 104, 105, 106, 107, 108])]}
835
- panels={[{ id: "main" }]}
836
- viewport={{
837
- start: new Date("2025-01-01T00:00:00.000Z"),
838
- end: new Date("2025-01-09T00:00:00.000Z"),
839
- }}
840
- onViewportChange={(next) => viewportChanges.push(next
841
- ? { start: next.start.toISOString(), end: next.end.toISOString() }
842
- : null)}
843
- />
844
- </InputHostProvider>,
845
- { width: 62, height: 14 },
846
- );
847
-
848
- await act(async () => testSetup!.renderOnce());
849
- const zoomIn = keyEvent("=");
850
- zoomIn.sequence = "+";
851
- zoomIn.shift = true;
852
- await act(async () => chartShortcut?.(zoomIn));
853
- await act(async () => testSetup!.renderOnce());
854
- expect(viewportChanges.at(-1)).not.toBeNull();
855
-
856
- await act(async () => chartShortcut?.(keyEvent("-")));
857
- await act(async () => testSetup!.renderOnce());
858
-
859
- // Reporting null here would make an owner that echoes navigated ranges
860
- // back as the authored viewport reload its original range instead.
861
- expect(viewportChanges.at(-1)).toEqual({
862
- start: "2025-01-01T00:00:00.000Z",
863
- end: "2025-01-09T00:00:00.000Z",
864
- });
865
- });
866
-
867
- test("preserves a zoomed viewport when adaptive data refreshes its buffer", async () => {
868
- const viewportChanges: Array<{ start: string; end: string } | null> = [];
869
- let replacePoints: ((points: TimeSeriesPoint[]) => void) | null = null;
870
- const initialPoints = series(
871
- "price",
872
- "main",
873
- "left",
874
- "USD",
875
- [100, 101, 102, 103, 104, 105, 106, 107, 108],
876
- ).points;
877
- function Harness() {
878
- const [points, setPoints] = useState(initialPoints);
879
- replacePoints = setPoints;
880
- return (
881
- <InputHostProvider host={chartInputHost}>
882
- <CompositeChart
883
- width={60}
884
- height={12}
885
- focused
886
- series={[{
887
- ...series("price", "main", "left", "USD", []),
888
- points,
889
- }]}
890
- panels={[{ id: "main" }]}
891
- viewport={{
892
- start: new Date("2025-01-01T00:00:00.000Z"),
893
- end: new Date("2025-01-09T00:00:00.000Z"),
894
- }}
895
- onViewportChange={(next) => viewportChanges.push(next
896
- ? { start: next.start.toISOString(), end: next.end.toISOString() }
897
- : null)}
898
- />
899
- </InputHostProvider>
900
- );
901
- }
902
-
903
- testSetup = await testRender(
904
- <Harness />,
905
- { width: 62, height: 14 },
906
- );
907
- await act(async () => testSetup!.renderOnce());
908
-
909
- for (let index = 0; index < 2; index += 1) {
910
- const zoomIn = keyEvent("=");
911
- zoomIn.sequence = "+";
912
- zoomIn.shift = true;
913
- await act(async () => chartShortcut?.(zoomIn));
914
- await act(async () => testSetup!.renderOnce());
915
- }
916
- const zoomedViewport = viewportChanges.at(-1);
917
- expect(zoomedViewport?.start).not.toBe("2025-01-01T00:00:00.000Z");
918
- const changeCount = viewportChanges.length;
919
-
920
- await act(async () => replacePoints?.(initialPoints.slice(2)));
921
- await act(async () => {
922
- await testSetup!.renderOnce();
923
- await testSetup!.renderOnce();
924
- });
925
-
926
- expect(viewportChanges).toHaveLength(changeCount);
927
- expect(viewportChanges.at(-1)).toEqual(zoomedViewport);
928
- });
929
-
930
- test("keeps a panned viewport exactly where it was when backfill replaces the data", async () => {
931
- const viewportChanges: Array<{ start: string; end: string } | null> = [];
932
- const viewportInteractions: string[] = [];
933
- let replacePoints: ((points: TimeSeriesPoint[]) => void) | null = null;
934
- const initialPoints = series(
935
- "price",
936
- "main",
937
- "left",
938
- "USD",
939
- [100, 101, 102, 103, 104, 105, 106, 107, 108],
940
- ).points;
941
- const olderPoints = Array.from({ length: 11 }, (_, index) => {
942
- const date = new Date(
943
- Date.UTC(2024, 11, 25 + index) - (index === 10 ? 60_000 : 0),
944
- );
945
- return { date, observedAt: date, value: 90 + index };
946
- });
947
- function Harness() {
948
- const [points, setPoints] = useState(initialPoints);
949
- replacePoints = setPoints;
950
- return (
951
- <InputHostProvider host={chartInputHost}>
952
- <CompositeChart
953
- width={60}
954
- height={12}
955
- focused
956
- series={[{
957
- ...series("price", "main", "left", "USD", []),
958
- points,
959
- }]}
960
- panels={[{ id: "main" }]}
961
- viewport={{
962
- start: new Date("2025-01-06T00:00:00.000Z"),
963
- end: new Date("2025-01-09T00:00:00.000Z"),
964
- }}
965
- onViewportChange={(next, interaction) => {
966
- viewportInteractions.push(interaction);
967
- viewportChanges.push(next
968
- ? { start: next.start.toISOString(), end: next.end.toISOString() }
969
- : null);
970
- }}
971
- />
972
- </InputHostProvider>
973
- );
974
- }
975
-
976
- testSetup = await testRender(<Harness />, { width: 62, height: 14 });
977
- await act(async () => testSetup!.renderOnce());
978
- for (let index = 0; index < 120; index += 1) {
979
- const panOlder = keyEvent("left");
980
- panOlder.shift = true;
981
- await act(async () => chartShortcut?.(panOlder));
982
- await act(async () => testSetup!.renderOnce());
983
- }
984
- const pannedViewport = viewportChanges.at(-1);
985
- expect(pannedViewport).toEqual({
986
- start: "2025-01-01T00:00:00.000Z",
987
- end: "2025-01-04T00:00:00.000Z",
988
- });
989
-
990
- const changeCount = viewportChanges.length;
991
- await act(async () => replacePoints?.(olderPoints));
992
- await act(async () => {
993
- await testSetup!.renderOnce();
994
- await testSetup!.renderOnce();
995
- });
996
-
997
- // The refreshed buffer ends a minute before the window does. The window
998
- // stays put and simply shows what is loaded; nothing is echoed upward.
999
- expect(viewportChanges).toHaveLength(changeCount);
1000
- expect(viewportChanges.at(-1)).toEqual(pannedViewport);
1001
- expect(viewportInteractions).not.toContain("sync");
1002
- expect(testSetup.captureCharFrame()).not.toContain("No chart data");
1003
- expect(testSetup.captureCharFrame()).not.toContain("Jan 9");
1004
- });
1005
-
1006
- test("keeps the latest pan through delayed adaptive viewport and series echoes", async () => {
1007
- const viewportChanges: Array<{ start: string; end: string } | null> = [];
1008
- let publishViewport: ((
1009
- next: { start: string; end: string },
1010
- showSecondary?: boolean,
1011
- ) => void) | null = null;
1012
- let publishExternalViewport: (() => void) | null = null;
1013
- function Harness() {
1014
- const [viewport, setViewport] = useState({
1015
- start: new Date("2025-01-05T00:00:00.000Z"),
1016
- end: new Date("2025-01-09T00:00:00.000Z"),
1017
- });
1018
- const [showSecondary, setShowSecondary] = useState(false);
1019
- const [viewportResetKey, setViewportResetKey] = useState("price:1D:auto");
1020
- publishViewport = (next, nextShowSecondary = showSecondary) => {
1021
- setViewport({
1022
- start: new Date(next.start),
1023
- end: new Date(next.end),
1024
- });
1025
- setShowSecondary(nextShowSecondary);
1026
- };
1027
- publishExternalViewport = () => {
1028
- setViewport({
1029
- start: new Date("2025-01-01T00:00:00.000Z"),
1030
- end: new Date("2025-01-09T00:00:00.000Z"),
1031
- });
1032
- setViewportResetKey("price:1W:auto");
1033
- };
1034
- return (
1035
- <CompositeChart
1036
- width={60}
1037
- height={12}
1038
- interactive
1039
- series={[
1040
- series("price", "main", "left", "USD", [100, 101, 102, 103, 104, 105, 106, 107, 108]),
1041
- series("secondary", "main", "left", "USD", showSecondary ? [90, 91, 92] : []),
1042
- ]}
1043
- panels={[{ id: "main" }]}
1044
- viewport={viewport}
1045
- viewportResetKey={viewportResetKey}
1046
- onViewportChange={(next) => {
1047
- viewportChanges.push(next
1048
- ? { start: next.start.toISOString(), end: next.end.toISOString() }
1049
- : null);
1050
- }}
1051
- />
1052
- );
1053
- }
1054
-
1055
- testSetup = await testRender(
1056
- <CaptureChartSurfaceProvider>
1057
- <Harness />
1058
- </CaptureChartSurfaceProvider>,
1059
- { width: 62, height: 14 },
1060
- );
1061
- await act(async () => testSetup!.renderOnce());
1062
-
1063
- for (let index = 0; index < 10; index += 1) {
1064
- await act(async () => {
1065
- capturedSurfaceProps!.onMouseScroll(pointerEvent(25, 3, {
1066
- scroll: { direction: "up", delta: 1 },
1067
- }));
1068
- });
1069
- await act(async () => {
1070
- await testSetup!.renderOnce();
1071
- await testSetup!.renderOnce();
1072
- });
1073
- }
1074
- const firstPan = viewportChanges[0]!;
1075
- const latestPan = viewportChanges.at(-1)!;
1076
- expect(firstPan).not.toBeNull();
1077
- expect(latestPan).not.toBeNull();
1078
- expect(latestPan).not.toEqual(firstPan);
1079
-
1080
- await act(async () => publishViewport!(firstPan, true));
1081
- await act(async () => {
1082
- await testSetup!.renderOnce();
1083
- await testSetup!.renderOnce();
1084
- await testSetup!.renderOnce();
1085
- });
1086
- expect(viewportChanges).not.toContain(null);
1087
- expect(viewportChanges.at(-1)).toEqual(latestPan);
1088
-
1089
- await act(async () => publishViewport!(latestPan));
1090
- await act(async () => {
1091
- await testSetup!.renderOnce();
1092
- await testSetup!.renderOnce();
1093
- await testSetup!.renderOnce();
1094
- });
1095
- expect(viewportChanges).not.toContain(null);
1096
- expect(viewportChanges.at(-1)).toEqual(latestPan);
1097
-
1098
- for (let index = 0; index < 32; index += 1) {
1099
- await act(async () => {
1100
- capturedSurfaceProps!.onMouseScroll(pointerEvent(25, 3, {
1101
- scroll: { direction: "up", delta: 100 },
1102
- }));
1103
- });
1104
- await act(async () => {
1105
- await testSetup!.renderOnce();
1106
- await testSetup!.renderOnce();
1107
- });
1108
- }
1109
- const boundaryViewport = viewportChanges.at(-1)!;
1110
- expect(boundaryViewport).not.toBeNull();
1111
-
1112
- await act(async () => publishViewport!(boundaryViewport));
1113
- await act(async () => {
1114
- await testSetup!.renderOnce();
1115
- await testSetup!.renderOnce();
1116
- });
1117
- const boundaryChangeCount = viewportChanges.length;
1118
-
1119
- await act(async () => {
1120
- capturedSurfaceProps!.onMouseScroll(pointerEvent(25, 3, {
1121
- scroll: { direction: "up", delta: 100 },
1122
- }));
1123
- });
1124
- await act(async () => {
1125
- await testSetup!.renderOnce();
1126
- await testSetup!.renderOnce();
1127
- });
1128
- expect(viewportChanges).toHaveLength(boundaryChangeCount);
1129
- expect(viewportChanges).not.toContain(null);
1130
-
1131
- await act(async () => publishExternalViewport!());
1132
- await act(async () => {
1133
- await testSetup!.renderOnce();
1134
- await testSetup!.renderOnce();
1135
- });
1136
- expect(viewportChanges.at(-1)).toBeNull();
1137
- });
1138
-
1139
- test("activates and navigates a buffered viewport from the first mouse gesture", async () => {
1140
- let activations = 0;
1141
- const cursorChanges: string[] = [];
1142
- testSetup = await testRender(
1143
- <CaptureChartSurfaceProvider>
1144
- <CompositeChart
1145
- width={60}
1146
- height={12}
1147
- focused={false}
1148
- interactive
1149
- series={[series("price", "main", "left", "USD", [100, 101, 102, 103, 104, 105, 106, 107, 108])]}
1150
- panels={[{ id: "main" }]}
1151
- viewport={{
1152
- start: new Date("2025-01-05T00:00:00.000Z"),
1153
- end: new Date("2025-01-09T00:00:00.000Z"),
1154
- }}
1155
- onActivate={() => { activations += 1; }}
1156
- onCursorDateChange={(date) => {
1157
- if (date) cursorChanges.push(date.toISOString());
1158
- }}
1159
- />
1160
- </CaptureChartSurfaceProvider>,
1161
- { width: 62, height: 14 },
1162
- );
1163
-
1164
- await act(async () => testSetup!.renderOnce());
1165
- expect(testSetup.captureCharFrame()).toContain("Jan 5");
1166
-
1167
- await act(async () => {
1168
- capturedSurfaceProps!.onMouseDown(pointerEvent(10, 3));
1169
- capturedSurfaceProps!.onMouseDrag(pointerEvent(30, 3));
1170
- capturedSurfaceProps!.onMouseUp(pointerEvent(30, 3));
1171
- });
1172
- await act(async () => testSetup!.renderOnce());
1173
-
1174
- expect(activations).toBe(1);
1175
- expect(cursorChanges.length).toBeGreaterThan(0);
1176
- expect(testSetup.captureCharFrame()).toContain("Jan 3");
1177
- });
1178
-
1179
- test("zooms to a shift-drag selection instead of panning", async () => {
1180
- const viewportChanges: Array<{ start: string; end: string } | null> = [];
1181
- testSetup = await testRender(
1182
- <CaptureChartSurfaceProvider>
1183
- <CompositeChart
1184
- width={60}
1185
- height={12}
1186
- interactive
1187
- series={[series("price", "main", "left", "USD", [100, 101, 102, 103, 104, 105, 106, 107, 108])]}
1188
- panels={[{ id: "main" }]}
1189
- onViewportChange={(next) => {
1190
- viewportChanges.push(next
1191
- ? { start: next.start.toISOString(), end: next.end.toISOString() }
1192
- : null);
1193
- }}
1194
- />
1195
- </CaptureChartSurfaceProvider>,
1196
- { width: 62, height: 14 },
1197
- );
1198
- await act(async () => testSetup!.renderOnce());
1199
-
1200
- await act(async () => {
1201
- capturedSurfaceProps!.onMouseDown(pointerEvent(10, 3, { shift: true }));
1202
- capturedSurfaceProps!.onMouseDrag(pointerEvent(30, 3, { shift: true }));
1203
- });
1204
- await act(async () => testSetup!.renderOnce());
1205
- // The selection must not pan the way an unmodified drag would, and the
1206
- // range has to read as text for renderers that cannot draw the band.
1207
- expect(viewportChanges).toHaveLength(0);
1208
- expect(testSetup.captureCharFrame()).toContain("→");
1209
-
1210
- await act(async () => {
1211
- capturedSurfaceProps!.onMouseUp(pointerEvent(30, 3, { shift: true }));
1212
- });
1213
- await act(async () => testSetup!.renderOnce());
1214
-
1215
- const zoomed = viewportChanges.at(-1);
1216
- expect(zoomed).toBeTruthy();
1217
- expect(new Date(zoomed!.start).getTime()).toBeGreaterThan(Date.parse("2025-01-01T00:00:00.000Z"));
1218
- expect(new Date(zoomed!.end).getTime()).toBeLessThan(Date.parse("2025-01-09T00:00:00.000Z"));
1219
- });
1220
-
1221
- test("reports an alt-drag measurement without moving the viewport", async () => {
1222
- const viewportChanges: Array<{ start: string; end: string } | null> = [];
1223
- testSetup = await testRender(
1224
- <CaptureChartSurfaceProvider>
1225
- <CompositeChart
1226
- width={60}
1227
- height={12}
1228
- interactive
1229
- series={[series("price", "main", "left", "USD", [100, 101, 102, 103, 104, 105, 106, 107, 108])]}
1230
- panels={[{ id: "main" }]}
1231
- onViewportChange={(next) => {
1232
- viewportChanges.push(next
1233
- ? { start: next.start.toISOString(), end: next.end.toISOString() }
1234
- : null);
1235
- }}
1236
- />
1237
- </CaptureChartSurfaceProvider>,
1238
- { width: 62, height: 14 },
1239
- );
1240
- await act(async () => testSetup!.renderOnce());
1241
-
1242
- await act(async () => {
1243
- capturedSurfaceProps!.onMouseDown(pointerEvent(8, 6, { alt: true }));
1244
- capturedSurfaceProps!.onMouseDrag(pointerEvent(34, 1, { alt: true }));
1245
- });
1246
- await act(async () => testSetup!.renderOnce());
1247
-
1248
- const measuringFrame = testSetup.captureCharFrame();
1249
- // The readout sits in the middle of the box it measures, not in the legend.
1250
- expect(measuringFrame).toContain("Δ");
1251
- expect(measuringFrame).toContain("bars");
1252
- expect(measuringFrame.split("\n")[0]).not.toContain("Δ");
1253
- expect(viewportChanges).toHaveLength(0);
1254
-
1255
- await act(async () => {
1256
- capturedSurfaceProps!.onMouseUp(pointerEvent(34, 1, { alt: true }));
1257
- });
1258
- await act(async () => testSetup!.renderOnce());
1259
- expect(testSetup.captureCharFrame()).not.toContain("Δ");
1260
- expect(viewportChanges).toHaveLength(0);
1261
- });
1262
-
1263
- test("arms a measurement from the keyboard when a modifier drag cannot reach the app", async () => {
1264
- testSetup = await testRender(
1265
- <InputHostProvider host={chartInputHost}>
1266
- <CaptureChartSurfaceProvider>
1267
- <CompositeChart
1268
- width={60}
1269
- height={12}
1270
- focused
1271
- interactive
1272
- series={[series("price", "main", "left", "USD", [100, 101, 102, 103, 104, 105, 106, 107, 108])]}
1273
- panels={[{ id: "main" }]}
1274
- />
1275
- </CaptureChartSurfaceProvider>
1276
- </InputHostProvider>,
1277
- { width: 62, height: 14 },
1278
- );
1279
- await act(async () => testSetup!.renderOnce());
1280
-
1281
- await act(async () => chartShortcut?.(keyEvent("m", true)));
1282
- await act(async () => testSetup!.renderOnce());
1283
-
1284
- // No modifier on the drag: the armed tool is what makes it a measurement.
1285
- await act(async () => {
1286
- capturedSurfaceProps!.onMouseDown(pointerEvent(8, 6));
1287
- capturedSurfaceProps!.onMouseDrag(pointerEvent(34, 1));
1288
- });
1289
- await act(async () => testSetup!.renderOnce());
1290
- expect(testSetup.captureCharFrame()).toContain("Δ");
1291
-
1292
- await act(async () => {
1293
- capturedSurfaceProps!.onMouseUp(pointerEvent(34, 1));
1294
- });
1295
- await act(async () => testSetup!.renderOnce());
1296
- expect(testSetup.captureCharFrame()).not.toContain("Δ");
1297
-
1298
- // Sticky: the tool still owns the next drag until it is dismissed.
1299
- await act(async () => {
1300
- capturedSurfaceProps!.onMouseDown(pointerEvent(8, 6));
1301
- capturedSurfaceProps!.onMouseDrag(pointerEvent(30, 2));
1302
- });
1303
- await act(async () => testSetup!.renderOnce());
1304
- expect(testSetup.captureCharFrame()).toContain("Δ");
1305
- });
1306
-
1307
- test("arms and disarms a chart tool from the toolbar", async () => {
1308
- testSetup = await testRender(
1309
- <CaptureChartSurfaceProvider>
1310
- <CompositeChart
1311
- width={60}
1312
- height={12}
1313
- interactive
1314
- series={[series("price", "main", "left", "USD", [100, 101, 102, 103, 104, 105, 106, 107, 108])]}
1315
- panels={[{ id: "main" }]}
1316
- />
1317
- </CaptureChartSurfaceProvider>,
1318
- { width: 62, height: 14 },
1319
- );
1320
- await act(async () => testSetup!.renderOnce());
1321
-
1322
- // Pressing the ruler icon has to arm the tool for an unmodified drag.
1323
- const toolbarRow = testSetup.captureCharFrame().split("\n").findIndex((line) => line.includes("↔"));
1324
- const rulerX = testSetup.captureCharFrame().split("\n")[toolbarRow]!.indexOf("↔");
1325
- await act(async () => {
1326
- await testSetup!.mockMouse.moveTo(rulerX, toolbarRow);
1327
- await testSetup!.mockMouse.click(rulerX, toolbarRow);
1328
- });
1329
- await act(async () => testSetup!.renderOnce());
1330
- await act(async () => {
1331
- capturedSurfaceProps!.onMouseDown(pointerEvent(8, 6));
1332
- capturedSurfaceProps!.onMouseDrag(pointerEvent(30, 2));
1333
- });
1334
- await act(async () => testSetup!.renderOnce());
1335
- expect(testSetup.captureCharFrame()).toContain("Δ");
1336
-
1337
- await act(async () => {
1338
- capturedSurfaceProps!.onMouseUp(pointerEvent(30, 2));
1339
- await testSetup!.mockMouse.click(rulerX, toolbarRow);
1340
- });
1341
- await act(async () => testSetup!.renderOnce());
1342
- await act(async () => {
1343
- capturedSurfaceProps!.onMouseDown(pointerEvent(8, 6));
1344
- capturedSurfaceProps!.onMouseDrag(pointerEvent(30, 2));
1345
- });
1346
- await act(async () => testSetup!.renderOnce());
1347
- expect(testSetup.captureCharFrame()).not.toContain("Δ");
1348
- });
1349
-
1350
- test("draws a line, then grabs its end to reshape it", async () => {
1351
- testSetup = await testRender(
1352
- <InputHostProvider host={chartInputHost}>
1353
- <CaptureChartSurfaceProvider>
1354
- <CompositeChart
1355
- width={60}
1356
- height={12}
1357
- focused
1358
- interactive
1359
- series={[series("price", "main", "left", "USD", [100, 101, 102, 103, 104, 105, 106, 107, 108])]}
1360
- panels={[{ id: "main" }]}
1361
- />
1362
- </CaptureChartSurfaceProvider>
1363
- </InputHostProvider>,
1364
- { width: 62, height: 14 },
1365
- );
1366
- await act(async () => testSetup!.renderOnce());
1367
- await act(async () => chartShortcut?.(keyEvent("d", true)));
1368
- await act(async () => testSetup!.renderOnce());
1369
- const base = capturedSurfaceProps!.bitmaps?.[0] as { pixels: Uint8Array } | undefined;
1370
-
1371
- await act(async () => {
1372
- capturedSurfaceProps!.onMouseDown(pointerEvent(8, 6));
1373
- capturedSurfaceProps!.onMouseDrag(pointerEvent(30, 2));
1374
- capturedSurfaceProps!.onMouseUp(pointerEvent(30, 2));
1375
- });
1376
- await act(async () => testSetup!.renderOnce());
1377
- const drawn = capturedSurfaceProps!.bitmaps?.[0] as { pixels: Uint8Array } | undefined;
1378
- expect(Buffer.from(drawn!.pixels).equals(Buffer.from(base!.pixels))).toBe(false);
1379
-
1380
- // Grabbing the endpoint that was just dropped has to reshape, not redraw.
1381
- await act(async () => {
1382
- capturedSurfaceProps!.onMouseDown(pointerEvent(8, 6));
1383
- capturedSurfaceProps!.onMouseDrag(pointerEvent(14, 8));
1384
- capturedSurfaceProps!.onMouseUp(pointerEvent(14, 8));
1385
- });
1386
- await act(async () => testSetup!.renderOnce());
1387
- const reshaped = capturedSurfaceProps!.bitmaps?.[0] as { pixels: Uint8Array } | undefined;
1388
- expect(reshaped).toBeTruthy();
1389
- expect(Buffer.from(reshaped!.pixels).equals(Buffer.from(drawn!.pixels))).toBe(false);
1390
- });
1391
-
1392
- test("places a trend line from the keyboard and leaves Backspace to the pane when nothing is picked", async () => {
1393
- testSetup = await testRender(
1394
- <InputHostProvider host={chartInputHost}>
1395
- <CaptureChartSurfaceProvider>
1396
- <CompositeChart
1397
- width={60}
1398
- height={12}
1399
- focused
1400
- interactive
1401
- series={[series("price", "main", "left", "USD", [100, 101, 102, 103, 104, 105, 106, 107, 108])]}
1402
- panels={[{ id: "main" }]}
1403
- />
1404
- </CaptureChartSurfaceProvider>
1405
- </InputHostProvider>,
1406
- { width: 62, height: 14 },
1407
- );
1408
- await act(async () => testSetup!.renderOnce());
1409
- const bitmap = () => Buffer.from((capturedSurfaceProps!.bitmaps?.[0] as { pixels: Uint8Array }).pixels);
1410
- const press = async (name: string, shift = false) => {
1411
- const event = keyEvent(name, shift);
1412
- await act(async () => chartShortcut?.(event));
1413
- await act(async () => testSetup!.renderOnce());
1414
- return event;
1415
- };
1416
- const base = bitmap();
1417
-
1418
- await press("d", true);
1419
- // Enter anchors at the newest bar; Left walks the end back along the price.
1420
- expect((await press("return")).defaultPrevented).toBe(true);
1421
- await press("left");
1422
- await press("left");
1423
- await press("left");
1424
- expect(testSetup.captureCharFrame()).toContain("Δ -$3.00");
1425
- await press("return");
1426
- expect(testSetup.captureCharFrame()).not.toContain("Δ");
1427
- const drawn = bitmap();
1428
- expect(drawn.equals(base)).toBe(false);
1429
-
1430
- // Nothing picked and no tool in hand: Backspace is the pane's back key.
1431
- await press("escape");
1432
- expect((await press("backspace")).defaultPrevented).toBeFalsy();
1433
- expect(bitmap().equals(base)).toBe(false);
1434
-
1435
- // With the line tool, ] picks the drawing and Backspace deletes it.
1436
- await press("d", true);
1437
- await press("]");
1438
- expect((await press("backspace")).defaultPrevented).toBe(true);
1439
- expect(bitmap().equals(base)).toBe(true);
1440
- });
1441
-
1442
- test("steps the cursor of a focused chart that does not navigate", async () => {
1443
- const cursorChanges: Array<string | null> = [];
1444
- testSetup = await testRender(
1445
- <InputHostProvider host={chartInputHost}>
1446
- <CompositeChart
1447
- width={60}
1448
- height={12}
1449
- focused
1450
- navigable={false}
1451
- series={[series("price", "main", "left", "USD", [100, 103, 101])]}
1452
- panels={[{ id: "main" }]}
1453
- onCursorDateChange={(date) => cursorChanges.push(date?.toISOString() ?? null)}
1454
- />
1455
- </InputHostProvider>,
1456
- { width: 62, height: 14 },
1457
- );
1458
- await act(async () => testSetup!.renderOnce());
1459
-
1460
- await act(async () => chartShortcut?.(keyEvent("left")));
1461
- expect(cursorChanges).toEqual(["2025-01-03T00:00:00.000Z"]);
1462
- // Panning stays with charts that navigate, so the key is left alone.
1463
- const pan = keyEvent("a");
1464
- await act(async () => chartShortcut?.(pan));
1465
- expect(pan.defaultPrevented).toBe(false);
1466
- });
1467
-
1468
- test("disarms a chart tool with escape", async () => {
1469
- testSetup = await testRender(
1470
- <InputHostProvider host={chartInputHost}>
1471
- <CaptureChartSurfaceProvider>
1472
- <CompositeChart
1473
- width={60}
1474
- height={12}
1475
- focused
1476
- interactive
1477
- series={[series("price", "main", "left", "USD", [100, 101, 102, 103, 104, 105, 106, 107, 108])]}
1478
- panels={[{ id: "main" }]}
1479
- />
1480
- </CaptureChartSurfaceProvider>
1481
- </InputHostProvider>,
1482
- { width: 62, height: 14 },
1483
- );
1484
- await act(async () => testSetup!.renderOnce());
1485
-
1486
- await act(async () => chartShortcut?.(keyEvent("z", true)));
1487
- await act(async () => chartShortcut?.(keyEvent("escape")));
1488
- await act(async () => testSetup!.renderOnce());
1489
-
1490
- // Disarmed: an unmodified drag pans instead of selecting a range.
1491
- await act(async () => {
1492
- capturedSurfaceProps!.onMouseDown(pointerEvent(8, 6));
1493
- capturedSurfaceProps!.onMouseDrag(pointerEvent(30, 2));
1494
- });
1495
- await act(async () => testSetup!.renderOnce());
1496
- expect(testSetup.captureCharFrame()).not.toContain("→");
1497
- });
1498
-
1499
- test("keeps a measurement readable in a narrow pane", async () => {
1500
- testSetup = await testRender(
1501
- <CaptureChartSurfaceProvider>
1502
- <CompositeChart
1503
- width={28}
1504
- height={12}
1505
- interactive
1506
- series={[series("price", "main", "left", "USD", [100, 101, 102, 103, 104, 105, 106, 107, 108])]}
1507
- panels={[{ id: "main" }]}
1508
- />
1509
- </CaptureChartSurfaceProvider>,
1510
- { width: 30, height: 14 },
1511
- );
1512
- await act(async () => testSetup!.renderOnce());
1513
-
1514
- await act(async () => {
1515
- capturedSurfaceProps!.onMouseDown(pointerEvent(2, 6, { alt: true }));
1516
- capturedSurfaceProps!.onMouseDrag(pointerEvent(14, 1, { alt: true }));
1517
- });
1518
- await act(async () => testSetup!.renderOnce());
1519
-
1520
- // Too narrow for the whole summary, but the change still has to be visible.
1521
- expect(testSetup.captureCharFrame()).toContain("Δ");
1522
- });
1523
-
1524
- test("ends a tool drag whose release landed on another pane", async () => {
1525
- testSetup = await testRender(
1526
- <CaptureChartSurfaceProvider>
1527
- <CompositeChart
1528
- width={60}
1529
- height={12}
1530
- interactive
1531
- series={[series("price", "main", "left", "USD", [100, 101, 102, 103, 104, 105, 106, 107, 108])]}
1532
- panels={[{ id: "main" }]}
1533
- />
1534
- </CaptureChartSurfaceProvider>,
1535
- { width: 62, height: 14 },
1536
- );
1537
- await act(async () => testSetup!.renderOnce());
1538
-
1539
- await act(async () => {
1540
- capturedSurfaceProps!.onMouseDown(pointerEvent(8, 6, { alt: true }));
1541
- capturedSurfaceProps!.onMouseDrag(pointerEvent(34, 1, { alt: true }));
1542
- });
1543
- await act(async () => testSetup!.renderOnce());
1544
- expect(testSetup.captureCharFrame()).toContain("Δ");
1545
-
1546
- // No mouse-up arrives: the pointer was released over a floating pane. The
1547
- // next plain move only happens with the button already up.
1548
- await act(async () => {
1549
- capturedSurfaceProps!.onMouseMove(pointerEvent(20, 4));
1550
- });
1551
- await act(async () => testSetup!.renderOnce());
1552
- expect(testSetup.captureCharFrame()).not.toContain("Δ");
1553
- });
1554
-
1555
- test("maps the pointer crosshair level through both axes and labels its date", async () => {
1556
- testSetup = await testRender(
1557
- <CaptureChartSurfaceProvider>
1558
- <CompositeChart
1559
- width={60}
1560
- height={12}
1561
- showLegend={false}
1562
- interactive
1563
- series={[
1564
- series("price", "main", "left", "USD", [100, 200, 100, 100]),
1565
- series("revenue", "main", "right", "%", [0, 200, 0, 0]),
1566
- ]}
1567
- panels={[{ id: "main" }]}
1568
- />
1569
- </CaptureChartSurfaceProvider>,
1570
- { width: 62, height: 14 },
1571
- );
1572
-
1573
- await act(async () => testSetup!.renderOnce());
1574
- const plotWidth = capturedSurfaceNode!.width as number;
1575
- const plotHeight = capturedSurfaceNode!.height as number;
1576
- await act(async () => {
1577
- capturedSurfaceProps!.onMouseMove(pointerEvent(
1578
- (plotWidth - 1) * (2 / 3),
1579
- (plotHeight - 1) / 2,
1580
- ));
1581
- });
1582
- await act(async () => testSetup!.renderOnce());
1583
-
1584
- const frame = testSetup.captureCharFrame();
1585
- expect(frame).toContain("$150");
1586
- expect(frame).toContain("106%");
1587
- expect(frame).toContain("2025-01-03");
1588
- expect(frame).toContain("────────");
1589
- });
1590
-
1591
- test.each([
1592
- ["USD", "currency-total:USD", 90_007_000_000, "$90.01B"],
1593
- ["EUR", "currency-total:EUR", -12_345_600_000, "-€12.35B"],
1594
- ["CAD", "currency-total:CAD", 123_456_000, "123.46M CAD"],
1595
- ["USD", "price:USD", 1_234_567.89, "$1,234,567.89"],
1596
- ["USD", "price:USD", 0.0123, "$0.0123"],
1597
- ["USD", "price:USD", 1e30, "…"],
1598
- ] as const)("renders a complete cursor marker for %s %s %s", async (unit, unitGroup, value, label) => {
1599
- testSetup = await testRender(
1600
- <CaptureChartSurfaceProvider>
1601
- <CompositeChart
1602
- width={60}
1603
- height={12}
1604
- showLegend={false}
1605
- series={[{
1606
- ...series("price", "main", "left", unit, [value * 0.8, value, value * 1.2]),
1607
- unitGroup,
1608
- }]}
1609
- panels={[{ id: "main" }]}
1610
- cursorDate={new Date("2025-01-02T00:00:00.000Z")}
1611
- />
1612
- </CaptureChartSurfaceProvider>,
1613
- { width: 62, height: 14 },
1614
- );
1615
- await act(async () => testSetup!.renderOnce());
1616
- expect(testSetup.captureCharFrame()).toContain(label);
1617
- expect(capturedSurfaceNode!.width).toBeGreaterThanOrEqual(30);
1618
- });
1619
-
1620
- test("static overview charts reserve the complete tiny-price marker without losing the plot", async () => {
1621
- testSetup = await testRender(
1622
- <CaptureChartSurfaceProvider>
1623
- <CompositeChart width={60} height={12} showLegend={false} interactive={false}
1624
- series={[{ ...series("price", "main", "right", "USD", [0.000005, 0.0000051, 0.00000526]), unitGroup: "price:USD", timeBasis: { kind: "market", timeZone: "UTC" } }]}
1625
- panels={[{ id: "main" }]} />
1626
- </CaptureChartSurfaceProvider>,
1627
- { width: 62, height: 14 },
1628
- );
1629
- await act(async () => testSetup!.renderOnce());
1630
- expect(testSetup.captureCharFrame()).toContain("$0.00000526");
1631
- expect(capturedSurfaceNode!.width).toBeGreaterThanOrEqual(30);
1632
- });
1633
-
1634
- test("preserves integer-domain cursor decimals without moving the plot and honors hidden axes", async () => {
1635
- let setAxisWidth: ((value: number) => void) | null = null;
1636
- function Harness() {
1637
- const [axisWidth, setWidth] = useState(9);
1638
- setAxisWidth = setWidth;
1639
- return <CaptureChartSurfaceProvider>
1640
- <CompositeChart width={60} height={12} showLegend={false} axisWidth={axisWidth}
1641
- series={[series("price", "main", "left", "USD", [100, 200, 100])]}
1642
- panels={[{ id: "main" }]}
1643
- />
1644
- </CaptureChartSurfaceProvider>;
1645
- }
1646
- testSetup = await testRender(<Harness />, { width: 62, height: 14 });
1647
- await act(async () => testSetup!.renderOnce());
1648
- const plotWidth = capturedSurfaceNode!.width as number;
1649
- const plotHeight = capturedSurfaceNode!.height as number;
1650
- await act(async () => capturedSurfaceProps!.onMouseMove(pointerEvent(
1651
- (plotWidth - 1) / 2, (plotHeight - 1) * 0.4975,
1652
- )));
1653
- await act(async () => testSetup!.renderOnce());
1654
- expect(testSetup.captureCharFrame()).toContain("$150.28");
1655
- expect(capturedSurfaceNode!.width).toBe(plotWidth);
1656
- await act(async () => setAxisWidth?.(0));
1657
- await act(async () => testSetup!.renderOnce());
1658
- expect(capturedSurfaceNode!.width).toBe(60);
1659
- expect(testSetup.captureCharFrame()).not.toContain("$");
1660
- });
1661
-
1662
- test("keeps the requested window while older cached observations partially overlap it", async () => {
1663
- testSetup = await testRender(
1664
- <CompositeChart
1665
- width={90}
1666
- height={14}
1667
- series={[{
1668
- ...series("price", "main", "left", "USD", []),
1669
- points: [point("2026-07-31", 100), point("2026-08-15", 110), point("2026-08-31", 105)],
1670
- }]}
1671
- panels={[{ id: "main" }]}
1672
- viewport={{ start: new Date("2026-08-10"), end: new Date("2026-09-10") }}
1673
- />,
1674
- { width: 92, height: 16 },
1675
- );
1676
- await act(async () => testSetup!.renderOnce());
1677
- const frame = testSetup.captureCharFrame();
1678
- expect(frame).toContain("Aug 10");
1679
- expect(frame).toContain("Sep 10");
1680
- expect(frame).not.toContain("Jul 31");
1681
- });
1682
-
1683
- test("zooms around the mouse pointer with control-wheel", async () => {
1684
- testSetup = await testRender(
1685
- <CaptureChartSurfaceProvider>
1686
- <CompositeChart
1687
- width={60}
1688
- height={12}
1689
- interactive
1690
- series={[series("price", "main", "left", "USD", [100, 101, 102, 103, 104, 105, 106, 107, 108])]}
1691
- panels={[{ id: "main" }]}
1692
- viewport={{
1693
- start: new Date("2025-01-05T00:00:00.000Z"),
1694
- end: new Date("2025-01-09T00:00:00.000Z"),
1695
- }}
1696
- />
1697
- </CaptureChartSurfaceProvider>,
1698
- { width: 62, height: 14 },
1699
- );
1700
-
1701
- await act(async () => testSetup!.renderOnce());
1702
- expect(testSetup.captureCharFrame()).toContain("Jan 9");
1703
-
1704
- await act(async () => {
1705
- capturedSurfaceProps!.onMouseScroll(pointerEvent(25, 3, {
1706
- ctrl: true,
1707
- scroll: { direction: "up", delta: 4 },
1708
- }));
1709
- });
1710
- await act(async () => testSetup!.renderOnce());
1711
-
1712
- expect(testSetup.captureCharFrame()).not.toContain("Jan 9");
1713
- });
1714
-
1715
- test("uses a supplied market timeline to keep control-wheel zoom under the pointer", async () => {
1716
- const anchor = twoSessionCandles();
1717
- const display = {
1718
- ...anchor,
1719
- id: "secondary",
1720
- label: "Secondary",
1721
- timeBasis: undefined,
1722
- };
1723
- const viewport = {
1724
- start: new Date(anchor.points[0]!.date.getTime()),
1725
- end: new Date(anchor.points.at(-1)!.date.getTime()),
1726
- };
1727
- const viewportChanges: Array<{ start: string; end: string } | null> = [];
1728
- testSetup = await testRender(
1729
- <CaptureChartSurfaceProvider>
1730
- <CompositeChart
1731
- width={60}
1732
- height={12}
1733
- interactive
1734
- series={[display]}
1735
- timelineSeries={[anchor]}
1736
- panels={[{ id: "main" }]}
1737
- viewport={viewport}
1738
- onViewportChange={(next) => viewportChanges.push(next
1739
- ? { start: next.start.toISOString(), end: next.end.toISOString() }
1740
- : null)}
1741
- />
1742
- </CaptureChartSurfaceProvider>,
1743
- { width: 62, height: 14 },
1744
- );
1745
-
1746
- await act(async () => testSetup!.renderOnce());
1747
- const pointerX = 35;
1748
- const plotWidth = capturedSurfaceNode!.width as number;
1749
- const frame = buildCompositeNavigationFrame([display], [anchor])!;
1750
- const expected = zoomCompositeViewport(
1751
- frame,
1752
- viewport,
1753
- 1 + 4 * 0.04,
1754
- // The pointer reads in plot space, which is wider than the viewport by
1755
- // the reserved right offset.
1756
- pointerX / Math.max(plotWidth - 1, 1) * (1 + COMPOSITE_RIGHT_OFFSET_RATIO),
1757
- );
1758
-
1759
- await act(async () => {
1760
- capturedSurfaceProps!.onMouseScroll(pointerEvent(pointerX, 3, {
1761
- ctrl: true,
1762
- scroll: { direction: "up", delta: 4 },
1763
- }));
1764
- });
1765
- await act(async () => {
1766
- await testSetup!.renderOnce();
1767
- await testSetup!.renderOnce();
1768
- });
1769
-
1770
- expect(viewportChanges.at(-1)).toEqual({
1771
- start: expected.start.toISOString(),
1772
- end: expected.end.toISOString(),
1773
- });
1774
- });
1775
-
1776
- test("returns a drag to its origin without handing the window back", async () => {
1777
- const viewportChanges: Array<{ start: string; end: string } | null> = [];
1778
- const interactions: string[] = [];
1779
- testSetup = await testRender(
1780
- <CaptureChartSurfaceProvider>
1781
- <CompositeChart
1782
- width={60}
1783
- height={12}
1784
- interactive
1785
- series={[series("price", "main", "left", "USD", [100, 101, 102, 103, 104, 105, 106, 107, 108])]}
1786
- panels={[{ id: "main" }]}
1787
- viewport={{
1788
- start: new Date("2025-01-05T00:00:00.000Z"),
1789
- end: new Date("2025-01-09T00:00:00.000Z"),
1790
- }}
1791
- onViewportChange={(next, interaction) => {
1792
- interactions.push(interaction);
1793
- viewportChanges.push(next
1794
- ? { start: next.start.toISOString(), end: next.end.toISOString() }
1795
- : null);
1796
- }}
1797
- />
1798
- </CaptureChartSurfaceProvider>,
1799
- { width: 62, height: 14 },
1800
- );
1801
-
1802
- await act(async () => testSetup!.renderOnce());
1803
- await act(async () => {
1804
- capturedSurfaceProps!.onMouseDown(pointerEvent(20, 3));
1805
- capturedSurfaceProps!.onMouseDrag(pointerEvent(30, 3));
1806
- });
1807
- await act(async () => testSetup!.renderOnce());
1808
- expect(viewportChanges.at(-1)).not.toBeNull();
1809
-
1810
- await act(async () => {
1811
- capturedSurfaceProps!.onMouseDrag(pointerEvent(20, 3));
1812
- capturedSurfaceProps!.onMouseUp(pointerEvent(20, 3));
1813
- });
1814
- await act(async () => {
1815
- await testSetup!.renderOnce();
1816
- await testSetup!.renderOnce();
1817
- });
1818
-
1819
- expect(viewportChanges.at(-1)).toEqual({
1820
- start: "2025-01-05T00:00:00.000Z",
1821
- end: "2025-01-09T00:00:00.000Z",
1822
- });
1823
- expect(interactions.at(-1)).toBe("pan");
1824
- });
1825
-
1826
- test("always treats horizontal control-wheel movement as a pan", async () => {
1827
- const interactions: string[] = [];
1828
- testSetup = await testRender(
1829
- <CaptureChartSurfaceProvider>
1830
- <CompositeChart
1831
- width={60}
1832
- height={12}
1833
- interactive
1834
- series={[twoSessionCandles()]}
1835
- panels={[{ id: "main" }]}
1836
- viewport={{
1837
- start: new Date("2025-01-03T13:30:00.000Z"),
1838
- end: new Date("2025-01-03T17:00:00.000Z"),
1839
- }}
1840
- onViewportChange={(_next, interaction) => interactions.push(interaction)}
1841
- />
1842
- </CaptureChartSurfaceProvider>,
1843
- { width: 62, height: 14 },
1844
- );
1845
-
1846
- await act(async () => testSetup!.renderOnce());
1847
- await act(async () => {
1848
- capturedSurfaceProps!.onMouseScroll(pointerEvent(25, 3, {
1849
- ctrl: true,
1850
- scroll: { direction: "left", delta: 4 },
1851
- }));
1852
- });
1853
- await act(async () => {
1854
- await testSetup!.renderOnce();
1855
- await testSetup!.renderOnce();
1856
- });
1857
-
1858
- expect(interactions.at(-1)).toBe("pan");
1859
- });
1860
-
1861
- test("keeps the date axis and mouse recovery when refreshed data misses the zoomed window", async () => {
1862
- let replacePoints: ((points: TimeSeriesPoint[]) => void) | null = null;
1863
- let lastWindow: { start: Date; end: Date } | null = null;
1864
- function Harness() {
1865
- const [points, setPoints] = useState(
1866
- series("price", "main", "left", "USD", [100, 101, 102, 103, 104, 105, 106, 107, 108]).points,
1867
- );
1868
- replacePoints = setPoints;
1869
- return (
1870
- <CompositeChart
1871
- width={60}
1872
- height={12}
1873
- interactive
1874
- series={[{
1875
- ...series("price", "main", "left", "USD", []),
1876
- points,
1877
- }]}
1878
- panels={[{ id: "main" }]}
1879
- viewport={{
1880
- start: new Date("2025-01-01T00:00:00.000Z"),
1881
- end: new Date("2025-01-09T00:00:00.000Z"),
1882
- }}
1883
- onViewportChange={(next) => { lastWindow = next; }}
1884
- />
1885
- );
1886
- }
1887
-
1888
- testSetup = await testRender(
1889
- <CaptureChartSurfaceProvider>
1890
- <Harness />
1891
- </CaptureChartSurfaceProvider>,
1892
- { width: 62, height: 14 },
1893
- );
1894
- await act(async () => testSetup!.renderOnce());
1895
-
1896
- for (let index = 0; index < 8; index += 1) {
1897
- await act(async () => {
1898
- capturedSurfaceProps!.onMouseScroll(pointerEvent(25, 3, {
1899
- ctrl: true,
1900
- scroll: { direction: "up", delta: 8 },
1901
- }));
1902
- });
1903
- await act(async () => testSetup!.renderOnce());
1904
- }
1905
-
1906
- await act(async () => {
1907
- replacePoints?.([
1908
- point("2025-01-01", 100),
1909
- point("2025-01-09", 108),
1910
- ]);
1911
- });
1912
- await act(async () => testSetup!.renderOnce());
1913
-
1914
- // An observation-free window keeps the chart frame and its axes; only the
1915
- // plotted points go away.
1916
- const emptyFrame = testSetup.captureCharFrame();
1917
- expect(emptyFrame).not.toContain("No chart data");
1918
- expect(emptyFrame).not.toContain("•");
1919
- expect(emptyFrame).toContain("$108");
1920
- expect(emptyFrame).toContain("Jan ");
1921
- expect(typeof capturedSurfaceProps!.onMouseScroll).toBe("function");
1922
-
1923
- await act(async () => {
1924
- capturedSurfaceProps!.onMouseScroll(pointerEvent(25, 3, {
1925
- ctrl: true,
1926
- scroll: { direction: "down", delta: 4 },
1927
- }));
1928
- });
1929
- await act(async () => testSetup!.renderOnce());
1930
-
1931
- const recoveredFrame = testSetup.captureCharFrame();
1932
- expect(recoveredFrame).toContain("•");
1933
- expect(lastWindow!.start.getTime()).toBeLessThanOrEqual(Date.parse("2025-01-01"));
1934
- expect(lastWindow!.end.getTime()).toBeGreaterThanOrEqual(Date.parse("2025-01-09"));
1935
- });
1936
-
1937
- test("restores persisted drawings from pane settings on mount", async () => {
1938
- const renderWithSettings = async (settings: Record<string, unknown>) => {
1939
- const config = createDefaultConfig("/tmp/gloomberb-composite-drawings");
1940
- config.layout.instances.push({
1941
- instanceId: "chart:test",
1942
- paneId: "chart-composer",
1943
- title: "Chart",
1944
- binding: { kind: "fixed", symbol: "ACME" },
1945
- settings,
1946
- });
1947
- testSetup = await testRender(
1948
- <AppContext value={{ state: createInitialState(config), dispatch: () => {} }}>
1949
- <PaneInstanceProvider paneId="chart:test">
1950
- <CaptureChartSurfaceProvider canvasCharts>
1951
- <CompositeChart
1952
- width={60}
1953
- height={12}
1954
- series={[series("price", "main", "left", "USD", [100, 101, 102, 103, 104, 105, 106, 107, 108])]}
1955
- panels={[{ id: "main" }]}
1956
- />
1957
- </CaptureChartSurfaceProvider>
1958
- </PaneInstanceProvider>
1959
- </AppContext>,
1960
- { width: 62, height: 14 },
1961
- );
1962
- await act(async () => {
1963
- await testSetup!.renderOnce();
1964
- await testSetup!.renderOnce();
1965
- });
1966
- const bitmap = capturedSurfaceProps!.bitmaps?.[0] as { pixels: Uint8Array };
1967
- const pixels = Buffer.from(bitmap.pixels);
1968
- await act(async () => testSetup!.renderer.destroy());
1969
- testSetup = undefined;
1970
- return pixels;
1971
- };
1972
-
1973
- const blank = await renderWithSettings({});
1974
- const restored = await renderWithSettings({
1975
- chartDrawings: [{
1976
- id: "drawing-1",
1977
- panelId: "main",
1978
- color: "#f5a524",
1979
- points: [
1980
- { time: Date.UTC(2025, 0, 2), value: 101 },
1981
- { time: Date.UTC(2025, 0, 8), value: 107 },
1982
- ],
1983
- }],
1984
- });
1985
-
1986
- expect(restored.equals(blank)).toBe(false);
1987
- });
1988
-
1989
- test("shows useful UTC times for an intraday shared cursor and time axis", async () => {
1990
- const intraday = {
1991
- ...series("price", "main", "left", "USD", []),
1992
- points: [
1993
- timestampPoint("2025-01-02T09:30:00.000Z", 100),
1994
- timestampPoint("2025-01-02T12:05:00.000Z", 103),
1995
- timestampPoint("2025-01-02T16:00:00.000Z", 101),
1996
- ],
1997
- };
1998
- testSetup = await testRender(
1999
- <CompositeChart
2000
- width={78}
2001
- height={12}
2002
- series={[intraday]}
2003
- panels={[{ id: "main" }]}
2004
- cursorDate={new Date("2025-01-02T12:05:00.000Z")}
2005
- />,
2006
- { width: 80, height: 14 },
2007
- );
2008
-
2009
- await act(async () => {
2010
- await testSetup!.renderOnce();
2011
- await testSetup!.renderOnce();
2012
- });
2013
-
2014
- const frame = testSetup.captureCharFrame();
2015
- expect(frame).toContain("12:05 UTC");
2016
- expect(frame).toContain("09:30 UTC");
2017
- expect(frame).toContain("16:00 UTC");
2018
- });
2019
- });