gloomberb 0.16.4 → 0.16.6

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 (852) hide show
  1. package/README.md +14 -91
  2. package/package.json +5 -1
  3. package/src/{plugins/builtin/cloud → account}/auth-form.tsx +9 -9
  4. package/src/{plugins/builtin/cloud → account}/auth-model.ts +4 -4
  5. package/src/account/billing.ts +57 -0
  6. package/src/{plugins/builtin/cloud → account}/device-signin-dialog.tsx +18 -12
  7. package/src/{plugins/builtin/cloud → account}/device-signin.ts +2 -2
  8. package/src/{plugins/builtin/cloud → account}/email-auth-attempt.ts +2 -2
  9. package/src/account/session.ts +16 -0
  10. package/src/{plugins/builtin/cloud → account}/upgrade-dialog.tsx +16 -15
  11. package/src/{plugins/builtin/cloud → account}/upgrade-personalization.ts +7 -7
  12. package/src/{plugins/builtin/cloud → account}/upgrade-tickers.ts +6 -6
  13. package/src/{plugins/builtin/cloud → account}/verification-panel.tsx +6 -6
  14. package/src/api-client/central-bank-rates.ts +6 -1
  15. package/src/api-client/chat.ts +26 -0
  16. package/src/api-client/credit-boards.ts +2 -0
  17. package/src/api-client/data.ts +73 -3
  18. package/src/api-client/earnings.ts +6 -0
  19. package/src/api-client/europe-energy.ts +106 -0
  20. package/src/api-client/futures-curve.ts +56 -0
  21. package/src/api-client/index.ts +13 -1
  22. package/src/api-client/market-discovery.ts +13 -1
  23. package/src/api-client/normalizers.ts +32 -0
  24. package/src/api-client/paths.ts +7 -0
  25. package/src/api-client/perps.ts +8 -0
  26. package/src/api-client/request.ts +9 -2
  27. package/src/api-client/research-activity.ts +15 -10
  28. package/src/api-client/socket.ts +29 -0
  29. package/src/api-client/themes.ts +22 -1
  30. package/src/api-client/types.ts +78 -2
  31. package/src/api-client/yield-curves.ts +8 -0
  32. package/src/app/global-shortcuts.ts +50 -2
  33. package/src/app/keybindings/actions.ts +12 -1
  34. package/src/app/pane-runtime/plugin-bindings.ts +2 -2
  35. package/src/app/pane-runtime/ticker-open-runtime.ts +16 -6
  36. package/src/app/runtime/desktop-deeplink.ts +10 -5
  37. package/src/app/runtime/startup.ts +1 -1
  38. package/src/app.tsx +6 -0
  39. package/src/architecture/core-builtin-allowlist.json +8 -26
  40. package/src/ask-gloom/pane-context.ts +114 -0
  41. package/src/ask-gloom/pane-request.ts +70 -0
  42. package/src/ask-gloom/pane-text.ts +201 -0
  43. package/src/brokers/signed-in/sign-in-dialog.tsx +11 -5
  44. package/src/capabilities/chart-series.ts +19 -2
  45. package/src/capabilities/factories.ts +1 -0
  46. package/src/cli/central-bank-events.ts +23 -0
  47. package/src/cli/command-options.ts +17 -5
  48. package/src/cli/commands/crypto-hints.ts +35 -2
  49. package/src/cli/commands/fred-series.ts +146 -0
  50. package/src/cli/commands/market.ts +501 -115
  51. package/src/cli/commands/news-hints.ts +62 -0
  52. package/src/cli/commands/news-search.ts +53 -0
  53. package/src/cli/commands/options-leaps.ts +5 -2
  54. package/src/cli/commands/overview.ts +132 -26
  55. package/src/cli/commands/remote.ts +2 -1
  56. package/src/cli/commands/search.ts +317 -13
  57. package/src/cli/commands/system.ts +55 -8
  58. package/src/cli/commands/ticker.ts +155 -18
  59. package/src/cli/context.ts +45 -14
  60. package/src/cli/desktop-pane-shot.ts +76 -7
  61. package/src/cli/earnings-calendar.ts +71 -0
  62. package/src/cli/errors.ts +7 -5
  63. package/src/cli/exit-codes.ts +8 -0
  64. package/src/cli/export-source.ts +58 -0
  65. package/src/cli/freshness.ts +18 -7
  66. package/src/cli/glossary.ts +483 -0
  67. package/src/cli/help.ts +10 -0
  68. package/src/cli/helpers.ts +2 -5
  69. package/src/cli/history-rows.ts +118 -7
  70. package/src/cli/index-roots.ts +7 -0
  71. package/src/cli/index.ts +29 -9
  72. package/src/cli/known-gaps.ts +84 -0
  73. package/src/cli/listing-arg.ts +551 -97
  74. package/src/cli/not-a-ticker.ts +24 -9
  75. package/src/cli/pane-functions/access-gate.ts +13 -2
  76. package/src/cli/pane-functions/capabilities.ts +4 -3
  77. package/src/cli/pane-functions/catalog.ts +214 -40
  78. package/src/cli/pane-functions/data.ts +42 -8
  79. package/src/cli/pane-functions/discovery.ts +1 -0
  80. package/src/cli/pane-functions/dom.ts +37 -8
  81. package/src/cli/pane-functions/freshness.ts +393 -49
  82. package/src/cli/pane-functions/function-help.ts +31 -15
  83. package/src/cli/pane-functions/headless.ts +98 -30
  84. package/src/cli/pane-functions/index.ts +101 -19
  85. package/src/cli/pane-functions/market-session.ts +22 -8
  86. package/src/cli/pane-functions/options.ts +71 -22
  87. package/src/cli/pane-functions/report-notices.ts +25 -7
  88. package/src/cli/pane-functions/report.ts +15 -8
  89. package/src/cli/pane-functions/resolver.ts +74 -19
  90. package/src/cli/pane-functions/screenshot.ts +250 -27
  91. package/src/cli/perpetual-contract.ts +60 -0
  92. package/src/cli/registry.ts +3 -1
  93. package/src/cli/report-tables.ts +26 -7
  94. package/src/cli/result.ts +45 -11
  95. package/src/cli/series-search.ts +111 -0
  96. package/src/cli/staged-tickers.ts +52 -0
  97. package/src/cli/symbol-args.ts +27 -0
  98. package/src/cli/symbol-list.ts +154 -0
  99. package/src/cli/symbol-rows.ts +154 -0
  100. package/src/cli/ticker-resolution.ts +311 -27
  101. package/src/cli/types.ts +5 -0
  102. package/src/components/chart/composite/axis-overlays.tsx +14 -3
  103. package/src/components/chart/composite/composite-chart.tsx +71 -11
  104. package/src/components/chart/composite/crosshair-readout.tsx +150 -0
  105. package/src/components/chart/composite/downsample.ts +1 -1
  106. package/src/components/chart/composite/format.ts +29 -0
  107. package/src/components/chart/composite/interactions.ts +9 -2
  108. package/src/components/chart/composite/legend.tsx +100 -33
  109. package/src/components/chart/composite/panel-bitmap.ts +70 -35
  110. package/src/components/chart/composite/panel-labels.ts +18 -17
  111. package/src/components/chart/composite/panel-series.ts +1 -0
  112. package/src/components/chart/composite/panel-surface.tsx +46 -21
  113. package/src/components/chart/composite/price-axis-labels.tsx +3 -1
  114. package/src/components/chart/composite/rasterizer.ts +50 -8
  115. package/src/components/chart/composite/scene.ts +2 -1
  116. package/src/components/chart/composite/time-scale.ts +26 -9
  117. package/src/components/chart/composite/types.ts +18 -0
  118. package/src/components/chart/composite/use-composite-viewport.ts +30 -2
  119. package/src/components/chart/native/raster/crosshair.ts +8 -3
  120. package/src/components/chart/native/raster/primitives.ts +85 -21
  121. package/src/components/chart/native/surface/manager.ts +33 -8
  122. package/src/components/chart/surface3d/chart.tsx +1 -1
  123. package/src/components/command-bar/action-runtime.ts +1 -1
  124. package/src/components/command-bar/commands/collection-list.ts +210 -0
  125. package/src/components/command-bar/commands/collection.ts +40 -1
  126. package/src/components/command-bar/commands/direct/index.ts +4 -0
  127. package/src/components/command-bar/commands/registry.ts +8 -0
  128. package/src/components/command-bar/panel/index.tsx +11 -3
  129. package/src/components/command-bar/panel/runtime.ts +3 -0
  130. package/src/components/command-bar/panel/types.ts +2 -0
  131. package/src/components/command-bar/routes/root/plugin-install.ts +4 -4
  132. package/src/components/command-bar/routes/root/provider-search.ts +4 -3
  133. package/src/components/command-bar/routes/ticker-search/results.ts +12 -11
  134. package/src/components/command-bar/routes/ticker-search/route.ts +4 -3
  135. package/src/components/command-bar/routing/actions.ts +1 -1
  136. package/src/components/command-bar/workflow/tickers.ts +42 -17
  137. package/src/components/layout/detached-pane-shell.tsx +68 -39
  138. package/src/components/layout/floating-pane.tsx +10 -1
  139. package/src/components/layout/header.tsx +25 -5
  140. package/src/components/layout/missing-pane.tsx +3 -3
  141. package/src/components/layout/pane/capture-stamp.ts +41 -0
  142. package/src/components/layout/pane/capture-status.ts +12 -0
  143. package/src/components/layout/pane/content.tsx +7 -13
  144. package/src/components/layout/pane/footer/index.tsx +6 -2
  145. package/src/components/layout/pane/footer/keyboard.ts +3 -0
  146. package/src/components/layout/pane/footer/model.ts +41 -1
  147. package/src/components/layout/pane/header.tsx +50 -1
  148. package/src/components/layout/pane/index.tsx +21 -3
  149. package/src/components/layout/pane/sidebar.tsx +88 -21
  150. package/src/components/layout/shell/active-drag.ts +21 -5
  151. package/src/components/layout/shell/cursor-occlusion.ts +2 -1
  152. package/src/components/layout/shell/drag/index.ts +39 -9
  153. package/src/components/layout/shell/drag/live.ts +61 -51
  154. package/src/components/layout/shell/drag/runtime.ts +54 -12
  155. package/src/components/layout/shell/index.tsx +84 -65
  156. package/src/components/layout/shell/menu.ts +14 -1
  157. package/src/components/layout/shell/native/pointer-runtime.ts +3 -1
  158. package/src/components/layout/shell/pane/actions.ts +32 -10
  159. package/src/components/layout/shell/pane/ask.ts +131 -0
  160. package/src/components/layout/shell/pane/capture.ts +162 -0
  161. package/src/components/layout/shell/pane/layers.tsx +218 -50
  162. package/src/components/layout/shell/pane/management-shortcuts.ts +46 -1
  163. package/src/components/layout/shell/shortcuts.ts +21 -4
  164. package/src/components/layout/shell/terminal-pointer-runtime.ts +24 -0
  165. package/src/components/markdown-text.tsx +62 -20
  166. package/src/components/metric-treemap/heat-surface.tsx +8 -1
  167. package/src/components/onboarding/account-step/form-panel.tsx +1 -1
  168. package/src/components/onboarding/account-step/index.tsx +1 -1
  169. package/src/components/onboarding/account-step/qr-panel.tsx +1 -1
  170. package/src/components/onboarding/account-step/signed-in-panel.tsx +1 -1
  171. package/src/components/onboarding/onboarding-keyboard.ts +1 -1
  172. package/src/components/onboarding/onboarding-wizard.tsx +2 -2
  173. package/src/components/onboarding/use-onboarding-upgrade.ts +3 -3
  174. package/src/components/onboarding/wizard-account.ts +2 -2
  175. package/src/components/pane-template-wizard.tsx +9 -1
  176. package/src/components/price-selector-dialog.tsx +11 -2
  177. package/src/components/reader/article-reader.tsx +642 -0
  178. package/src/components/reader/article-text.ts +527 -0
  179. package/src/components/sign-in-gate.tsx +3 -3
  180. package/src/components/ticker/list-table-view.tsx +43 -2
  181. package/src/components/ui/action-row.tsx +2 -1
  182. package/src/components/ui/button.tsx +7 -1
  183. package/src/components/ui/choice-dialog.tsx +6 -4
  184. package/src/components/ui/confirm-dialog.tsx +28 -18
  185. package/src/components/ui/data-table/index.tsx +18 -6
  186. package/src/components/ui/data-table/opentui/index.tsx +37 -6
  187. package/src/components/ui/data-table/types.ts +12 -0
  188. package/src/components/ui/dialog-actions.tsx +64 -0
  189. package/src/components/ui/display.tsx +17 -3
  190. package/src/components/ui/frame.tsx +35 -2
  191. package/src/components/ui/icon.tsx +6 -1
  192. package/src/components/ui/query-bar.tsx +10 -1
  193. package/src/components/ui/text-prompt-dialog.tsx +11 -9
  194. package/src/data/cached-query.ts +2 -0
  195. package/src/data/config/store/migrations.ts +7 -0
  196. package/src/data/config/store/normalize.ts +7 -2
  197. package/src/data/config/store/portfolio-as-of-column.ts +57 -0
  198. package/src/data/ticker-repository.ts +5 -0
  199. package/src/data/ticker-store.ts +15 -0
  200. package/src/docs/content.ts +215 -0
  201. package/src/docs/load.ts +139 -0
  202. package/src/docs/requests.ts +39 -0
  203. package/src/docs/snapshot.chunk.ts +8 -0
  204. package/src/docs/snapshot.json +7555 -0
  205. package/src/docs/topics.ts +216 -0
  206. package/src/i18n/es.ts +65 -5
  207. package/src/i18n/ja.ts +65 -5
  208. package/src/i18n/ko.ts +65 -5
  209. package/src/i18n/zh-cn.ts +65 -5
  210. package/src/i18n/zh-tw.ts +65 -5
  211. package/src/layout/desks.ts +1 -1
  212. package/src/layout/pane-manager/dock-tree.ts +18 -0
  213. package/src/layout/pane-manager/index.ts +1 -0
  214. package/src/layout-marketplace/gallery.tsx +1 -1
  215. package/src/market-data/coordinator/chart.ts +10 -4
  216. package/src/market-data/coordinator/index.ts +6 -3
  217. package/src/{plugins/builtin/futures/contracts.ts → market-data/futures-board.ts} +81 -28
  218. package/src/market-data/futures-contract.ts +151 -0
  219. package/src/market-data/hooks.tsx +10 -2
  220. package/src/market-data/market/format.ts +39 -21
  221. package/src/market-data/market/freshness.ts +84 -20
  222. package/src/market-data/market/session-close-note.ts +3 -2
  223. package/src/market-data/market/status.ts +19 -23
  224. package/src/market-data/published-apac-sessions.ts +23 -1
  225. package/src/market-data/quotes/contributions.ts +5 -0
  226. package/src/market-data/quotes/metadata.ts +19 -24
  227. package/src/market-data/quotes/resolution.ts +5 -0
  228. package/src/market-data/quotes/screener-live-quotes.ts +5 -4
  229. package/src/market-data/result-types.ts +2 -0
  230. package/src/notifications/app-notifier.ts +17 -1
  231. package/src/notifications/notification-log.ts +180 -0
  232. package/src/plugins/auto-update-node.ts +2 -2
  233. package/src/plugins/auto-update.ts +2 -2
  234. package/src/plugins/builtin/account-management/index.tsx +1 -0
  235. package/src/plugins/builtin/account-management/model.ts +1 -56
  236. package/src/plugins/builtin/account-management/pane.tsx +6 -4
  237. package/src/plugins/builtin/account-management/password-dialog.tsx +1 -1
  238. package/src/plugins/builtin/alerts/catalysts.ts +1 -1
  239. package/src/plugins/builtin/alerts/cli.ts +313 -47
  240. package/src/plugins/builtin/alerts/events-pane.tsx +45 -7
  241. package/src/plugins/builtin/alerts/events.ts +23 -2
  242. package/src/plugins/builtin/alerts/focus.ts +27 -0
  243. package/src/plugins/builtin/alerts/history-pane.tsx +7 -2
  244. package/src/plugins/builtin/alerts/history.ts +2 -0
  245. package/src/plugins/builtin/alerts/index.tsx +47 -11
  246. package/src/plugins/builtin/alerts/pane.tsx +27 -1
  247. package/src/plugins/builtin/alerts/research-builder.ts +8 -3
  248. package/src/plugins/builtin/alerts/research-rules.ts +18 -2
  249. package/src/plugins/builtin/alerts/scheduled-check.ts +122 -0
  250. package/src/plugins/builtin/alerts/scheduled-sources.ts +25 -0
  251. package/src/plugins/builtin/alerts/scheduled.ts +254 -0
  252. package/src/plugins/builtin/alerts/targets.ts +92 -0
  253. package/src/plugins/builtin/analytics/index.tsx +8 -3
  254. package/src/plugins/builtin/analytics/risk-headless.ts +60 -27
  255. package/src/plugins/builtin/analytics/risk-math.ts +91 -27
  256. package/src/plugins/builtin/analytics/risk-model.ts +35 -5
  257. package/src/plugins/builtin/analytics/risk-pane.tsx +15 -8
  258. package/src/plugins/builtin/attention/headless.ts +1 -1
  259. package/src/plugins/builtin/attention/index.tsx +2 -0
  260. package/src/plugins/builtin/attention/pane.tsx +3 -1
  261. package/src/plugins/builtin/attention/series.ts +26 -0
  262. package/src/plugins/builtin/awards/headless.ts +88 -18
  263. package/src/plugins/builtin/awards/index.tsx +2 -0
  264. package/src/plugins/builtin/awards/model.ts +41 -1
  265. package/src/plugins/builtin/awards/pane.tsx +22 -13
  266. package/src/plugins/builtin/awards/series.ts +29 -0
  267. package/src/plugins/builtin/backtest/headless.ts +2 -2
  268. package/src/plugins/builtin/bond-calculator/model.ts +2 -1
  269. package/src/plugins/builtin/broker-manager/index.tsx +1 -0
  270. package/src/plugins/builtin/catalysts/headless.ts +1 -1
  271. package/src/plugins/builtin/catalysts/pane.tsx +3 -1
  272. package/src/plugins/builtin/cds/client.ts +49 -12
  273. package/src/plugins/builtin/cds/headless.ts +119 -19
  274. package/src/plugins/builtin/cds/index.tsx +3 -1
  275. package/src/plugins/builtin/cds/model.ts +214 -32
  276. package/src/plugins/builtin/cds/pane.tsx +58 -14
  277. package/src/plugins/builtin/cds/series.ts +19 -0
  278. package/src/plugins/builtin/central-bank-rates/client.ts +4 -0
  279. package/src/plugins/builtin/central-bank-rates/headless.ts +46 -16
  280. package/src/plugins/builtin/central-bank-rates/index.tsx +3 -1
  281. package/src/plugins/builtin/central-bank-rates/model.ts +99 -0
  282. package/src/plugins/builtin/central-bank-rates/pane.tsx +1 -1
  283. package/src/plugins/builtin/central-bank-rates/series.ts +36 -0
  284. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +193 -255
  285. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +84 -46
  286. package/src/plugins/builtin/chart-composer/editor.tsx +5 -4
  287. package/src/plugins/builtin/chart-composer/field-series.ts +40 -0
  288. package/src/plugins/builtin/chart-composer/headless-schema.ts +1 -1
  289. package/src/plugins/builtin/chart-composer/headless.ts +70 -5
  290. package/src/plugins/builtin/chart-composer/index.tsx +15 -3
  291. package/src/plugins/builtin/chart-composer/pane.tsx +81 -38
  292. package/src/plugins/builtin/chart-composer/series-catalog.ts +58 -50
  293. package/src/plugins/builtin/chart-composer/series-expression.ts +18 -10
  294. package/src/plugins/builtin/chart-composer/use-series-catalog.ts +59 -3
  295. package/src/plugins/builtin/chart-composer/user-series.ts +84 -0
  296. package/src/plugins/builtin/chat/content/composer-runtime.ts +6 -1
  297. package/src/plugins/builtin/chat/content/composer.tsx +5 -1
  298. package/src/plugins/builtin/chat/content/footer.tsx +12 -0
  299. package/src/plugins/builtin/chat/content/index.tsx +89 -5
  300. package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +10 -2
  301. package/src/plugins/builtin/chat/content/new-messages.tsx +89 -0
  302. package/src/plugins/builtin/chat/content/row-activity.ts +132 -0
  303. package/src/plugins/builtin/chat/content/scroll.ts +127 -27
  304. package/src/plugins/builtin/chat/content/shortcuts.ts +2 -2
  305. package/src/plugins/builtin/chat/content/transcript.tsx +145 -78
  306. package/src/plugins/builtin/chat/content/types.ts +1 -0
  307. package/src/plugins/builtin/chat/controller/fetch.ts +8 -2
  308. package/src/plugins/builtin/chat/controller/index.ts +123 -1
  309. package/src/plugins/builtin/chat/controller/message-loading.ts +3 -0
  310. package/src/plugins/builtin/chat/controller/messages.ts +7 -2
  311. package/src/plugins/builtin/chat/controller/realtime.ts +10 -1
  312. package/src/plugins/builtin/chat/controller/send.ts +61 -1
  313. package/src/plugins/builtin/chat/controller/state.ts +8 -0
  314. package/src/plugins/builtin/chat/ghost-user.ts +20 -0
  315. package/src/plugins/builtin/chat/index.tsx +23 -5
  316. package/src/plugins/builtin/chat/layout.ts +78 -5
  317. package/src/plugins/builtin/chat/message/ai-badge.tsx +18 -0
  318. package/src/plugins/builtin/chat/message/desktop.tsx +55 -6
  319. package/src/plugins/builtin/chat/message/header.tsx +16 -4
  320. package/src/plugins/builtin/chat/message/profile-popover.tsx +5 -1
  321. package/src/plugins/builtin/chat/message/reactions.tsx +210 -0
  322. package/src/plugins/builtin/chat/message/render-state.ts +18 -2
  323. package/src/plugins/builtin/chat/message/terminal.tsx +43 -4
  324. package/src/plugins/builtin/chat/message/types.ts +12 -0
  325. package/src/plugins/builtin/chat/reactions.ts +197 -0
  326. package/src/plugins/builtin/chat/share/flow.tsx +87 -0
  327. package/src/plugins/builtin/chat/share/targets.ts +27 -0
  328. package/src/plugins/builtin/chat/status-widget.tsx +6 -3
  329. package/src/plugins/builtin/chat/unread-inbox-pane.tsx +148 -27
  330. package/src/plugins/builtin/chat/unread-inbox.ts +22 -0
  331. package/src/plugins/builtin/cloud/askg/attached-pane.tsx +69 -0
  332. package/src/plugins/builtin/cloud/askg/controller.ts +111 -19
  333. package/src/plugins/builtin/cloud/askg/executor.ts +57 -3
  334. package/src/plugins/builtin/cloud/askg/manifest.ts +32 -7
  335. package/src/plugins/builtin/cloud/askg/model.ts +27 -8
  336. package/src/plugins/builtin/cloud/askg/pane-attachment.ts +94 -0
  337. package/src/plugins/builtin/cloud/askg/pane.tsx +141 -12
  338. package/src/plugins/builtin/cloud/askg/pending-question.ts +11 -0
  339. package/src/plugins/builtin/cloud/askg/protocol.ts +10 -1
  340. package/src/plugins/builtin/cloud/askg/tool-display.ts +3 -0
  341. package/src/plugins/builtin/cloud/askg/undo.ts +2 -0
  342. package/src/plugins/builtin/cloud/auth-actions.tsx +1 -1
  343. package/src/plugins/builtin/cloud/auth-commands.ts +1 -1
  344. package/src/plugins/builtin/cloud/auth-dialog.tsx +3 -3
  345. package/src/plugins/builtin/cloud/company-picker.tsx +1 -1
  346. package/src/plugins/builtin/cloud/mcp-connect/dialog.tsx +3 -0
  347. package/src/plugins/builtin/cloud/plugin.tsx +19 -2
  348. package/src/plugins/builtin/cloud/team/model.ts +5 -0
  349. package/src/plugins/builtin/cloud/team/module.tsx +1 -0
  350. package/src/plugins/builtin/cloud/team/store.ts +8 -3
  351. package/src/plugins/builtin/cloud/terminal-relay/engine.ts +77 -9
  352. package/src/plugins/builtin/cloud/terminal-relay/manifest.ts +6 -1
  353. package/src/plugins/builtin/cloud/terminal-relay/policy.ts +9 -0
  354. package/src/plugins/builtin/cloud/terminal-relay/prompts.tsx +35 -11
  355. package/src/plugins/builtin/cloud/thesis/exposure.ts +1 -1
  356. package/src/plugins/builtin/cloud/thesis/module.tsx +1 -0
  357. package/src/plugins/builtin/cloud/thesis/prompts.tsx +2 -1
  358. package/src/plugins/builtin/company-attention/app-rank.tsx +1 -1
  359. package/src/plugins/builtin/company-attention/headless.ts +21 -7
  360. package/src/plugins/builtin/company-attention/index.tsx +2 -0
  361. package/src/plugins/builtin/company-attention/model.ts +26 -7
  362. package/src/plugins/builtin/company-attention/pane.tsx +12 -9
  363. package/src/plugins/builtin/company-attention/series.ts +52 -0
  364. package/src/plugins/builtin/company-kpis/headless.ts +97 -10
  365. package/src/plugins/builtin/company-kpis/model.ts +24 -2
  366. package/src/plugins/builtin/company-kpis/pane.tsx +17 -16
  367. package/src/plugins/builtin/composite-plugins.ts +19 -13
  368. package/src/plugins/builtin/connections/index.ts +1 -0
  369. package/src/plugins/builtin/cot/headless.ts +1 -1
  370. package/src/plugins/builtin/cot/index.tsx +3 -1
  371. package/src/plugins/builtin/cot/model.ts +40 -11
  372. package/src/plugins/builtin/cot/series.ts +27 -0
  373. package/src/plugins/builtin/cpi/headless.ts +3 -3
  374. package/src/plugins/builtin/credit-boards/cdx-pane.tsx +10 -1
  375. package/src/plugins/builtin/credit-boards/client.ts +6 -2
  376. package/src/plugins/builtin/credit-boards/headless.ts +108 -31
  377. package/src/plugins/builtin/credit-boards/index.tsx +2 -0
  378. package/src/plugins/builtin/credit-boards/model.ts +11 -1
  379. package/src/plugins/builtin/credit-boards/series.ts +66 -0
  380. package/src/plugins/builtin/credit-conditions/client.ts +12 -9
  381. package/src/plugins/builtin/credit-conditions/headless.ts +13 -2
  382. package/src/plugins/builtin/credit-conditions/index.tsx +18 -9
  383. package/src/plugins/builtin/credit-conditions/model.ts +19 -11
  384. package/src/plugins/builtin/credit-conditions/series.ts +16 -0
  385. package/src/plugins/builtin/credit-documents/headless.ts +33 -3
  386. package/src/plugins/builtin/credit-documents/pane.tsx +3 -1
  387. package/src/plugins/builtin/crypto-board/headless.ts +2 -3
  388. package/src/plugins/builtin/crypto-board/index.tsx +2 -0
  389. package/src/plugins/builtin/crypto-board/model.ts +12 -0
  390. package/src/plugins/builtin/crypto-board/pane.tsx +19 -12
  391. package/src/plugins/builtin/crypto-board/series.ts +48 -0
  392. package/src/plugins/builtin/custom-view/live-quotes.ts +2 -2
  393. package/src/plugins/builtin/debt-maturities/headless.ts +17 -11
  394. package/src/plugins/builtin/debt-maturities/index.tsx +2 -0
  395. package/src/plugins/builtin/debt-maturities/series.ts +45 -0
  396. package/src/plugins/builtin/dividend-yield/client.ts +3 -0
  397. package/src/plugins/builtin/dividend-yield/headless.ts +7 -4
  398. package/src/plugins/builtin/dividend-yield/index.tsx +3 -1
  399. package/src/plugins/builtin/dividend-yield/pane.tsx +3 -1
  400. package/src/plugins/builtin/dividend-yield/series.ts +20 -0
  401. package/src/plugins/builtin/dividend-yield/types.ts +2 -0
  402. package/src/plugins/builtin/docs/blocks.tsx +181 -0
  403. package/src/plugins/builtin/docs/index.tsx +68 -0
  404. package/src/plugins/builtin/docs/pane.tsx +426 -0
  405. package/src/plugins/builtin/docs/targets.ts +72 -0
  406. package/src/plugins/builtin/docs/use-docs.ts +60 -0
  407. package/src/plugins/builtin/doe/headless.ts +12 -8
  408. package/src/plugins/builtin/doe/index.tsx +2 -0
  409. package/src/plugins/builtin/doe/series.ts +62 -0
  410. package/src/plugins/builtin/earnings/client.ts +3 -2
  411. package/src/plugins/builtin/earnings/format.ts +1 -5
  412. package/src/plugins/builtin/earnings/headless.ts +58 -6
  413. package/src/plugins/builtin/earnings/history-model.ts +15 -1
  414. package/src/plugins/builtin/earnings/history-table.ts +13 -2
  415. package/src/plugins/builtin/earnings/history.tsx +7 -3
  416. package/src/plugins/builtin/earnings/index.tsx +9 -0
  417. package/src/plugins/builtin/earnings-calls/headless.ts +28 -2
  418. package/src/plugins/builtin/earnings-calls/index.tsx +1 -1
  419. package/src/plugins/builtin/earnings-ripple/index.tsx +2 -0
  420. package/src/plugins/builtin/econ/fred-catalog.ts +198 -0
  421. package/src/plugins/builtin/econ/fred-series-map.ts +0 -46
  422. package/src/plugins/builtin/econ/index.tsx +2 -0
  423. package/src/plugins/builtin/econ-statistics/defs.ts +5 -0
  424. package/src/plugins/builtin/econ-statistics/headless.ts +19 -4
  425. package/src/plugins/builtin/econ-statistics/stats.ts +1 -0
  426. package/src/plugins/builtin/equity-screener/headless.ts +3 -3
  427. package/src/plugins/builtin/equity-screener/pane.tsx +4 -11
  428. package/src/plugins/builtin/estimate-revisions/headless.ts +3 -3
  429. package/src/plugins/builtin/exposure/drivers.ts +13 -0
  430. package/src/plugins/builtin/exposure/headless.ts +205 -13
  431. package/src/plugins/builtin/exposure/holdings.ts +1 -1
  432. package/src/plugins/builtin/exposure/index.tsx +1 -0
  433. package/src/plugins/builtin/exposure/model.ts +23 -3
  434. package/src/plugins/builtin/exposure/pane.tsx +14 -12
  435. package/src/plugins/builtin/fear-greed/index.tsx +18 -10
  436. package/src/plugins/builtin/fear-greed/series.ts +52 -0
  437. package/src/plugins/builtin/futures/index.tsx +43 -3
  438. package/src/plugins/builtin/futures/model.ts +1 -1
  439. package/src/plugins/builtin/futures/returns.ts +1 -1
  440. package/src/plugins/builtin/futures/series.ts +13 -0
  441. package/src/plugins/builtin/futures/table.tsx +1 -1
  442. package/src/plugins/builtin/futures/use-front-returns.ts +1 -1
  443. package/src/plugins/builtin/futures-curve/client.ts +12 -3
  444. package/src/plugins/builtin/futures-curve/headless.ts +71 -10
  445. package/src/plugins/builtin/futures-curve/index.tsx +1 -1
  446. package/src/plugins/builtin/futures-curve/model.ts +66 -11
  447. package/src/plugins/builtin/futures-curve/pane.tsx +52 -18
  448. package/src/plugins/builtin/fx-matrix/client.ts +63 -0
  449. package/src/plugins/builtin/fx-matrix/export.ts +2 -1
  450. package/src/plugins/builtin/fx-matrix/headless.ts +154 -0
  451. package/src/plugins/builtin/fx-matrix/index.tsx +4 -4
  452. package/src/plugins/builtin/gpu/board.tsx +13 -10
  453. package/src/plugins/builtin/gpu/changes.tsx +4 -4
  454. package/src/plugins/builtin/gpu/client.ts +19 -1
  455. package/src/plugins/builtin/gpu/equities.tsx +14 -10
  456. package/src/plugins/builtin/gpu/headless.ts +58 -27
  457. package/src/plugins/builtin/gpu/history.tsx +3 -3
  458. package/src/plugins/builtin/gpu/index.tsx +2 -0
  459. package/src/plugins/builtin/gpu/model.ts +101 -16
  460. package/src/plugins/builtin/gpu/pane.tsx +28 -12
  461. package/src/plugins/builtin/gpu/series.ts +38 -0
  462. package/src/plugins/builtin/help/function-card.tsx +25 -6
  463. package/src/plugins/builtin/help/function-index.ts +2 -0
  464. package/src/plugins/builtin/help/index.tsx +31 -9
  465. package/src/plugins/builtin/holders/beneficial-model.ts +90 -3
  466. package/src/plugins/builtin/holders/beneficial-report.ts +57 -5
  467. package/src/plugins/builtin/holders/beneficial-view.tsx +55 -11
  468. package/src/plugins/builtin/holders/client.ts +22 -3
  469. package/src/plugins/builtin/holders/format.ts +18 -3
  470. package/src/plugins/builtin/holders/headless.ts +36 -133
  471. package/src/plugins/builtin/holders/pane.tsx +11 -4
  472. package/src/plugins/builtin/holders/report-header.ts +40 -5
  473. package/src/plugins/builtin/holders/report-rows.ts +240 -0
  474. package/src/plugins/builtin/insider/client.ts +35 -20
  475. package/src/plugins/builtin/insider/headless.ts +41 -11
  476. package/src/plugins/builtin/insider/index.tsx +26 -9
  477. package/src/plugins/builtin/insider/insider-data.ts +10 -0
  478. package/src/plugins/builtin/insider/issuer.ts +49 -0
  479. package/src/plugins/builtin/insider/model.ts +3 -0
  480. package/src/plugins/builtin/ipo-calendar/headless.ts +1 -1
  481. package/src/plugins/builtin/iv-history/client.ts +20 -6
  482. package/src/plugins/builtin/iv-history/format.ts +9 -0
  483. package/src/plugins/builtin/iv-history/headless.ts +56 -21
  484. package/src/plugins/builtin/iv-history/index.tsx +2 -0
  485. package/src/plugins/builtin/iv-history/model.ts +143 -8
  486. package/src/plugins/builtin/iv-history/screen-pane.tsx +5 -9
  487. package/src/plugins/builtin/iv-history/series.ts +29 -0
  488. package/src/plugins/builtin/jobs/headless.ts +26 -3
  489. package/src/plugins/builtin/jobs/index.tsx +3 -1
  490. package/src/plugins/builtin/jobs/series.ts +19 -0
  491. package/src/plugins/builtin/kelly-sizer/index.tsx +2 -0
  492. package/src/plugins/builtin/kelly-sizer/pane.tsx +2 -1
  493. package/src/plugins/builtin/kelly-sizer/portfolio.ts +0 -39
  494. package/src/plugins/builtin/macro-day/client.ts +44 -3
  495. package/src/plugins/builtin/macro-day/headless.ts +13 -10
  496. package/src/plugins/builtin/macro-day/model.ts +56 -10
  497. package/src/plugins/builtin/macro-day/pane.tsx +30 -20
  498. package/src/plugins/builtin/market-heatmap/headless.ts +20 -5
  499. package/src/plugins/builtin/market-heatmap/index.tsx +6 -0
  500. package/src/plugins/builtin/market-heatmap/model.ts +19 -11
  501. package/src/plugins/builtin/market-heatmap/portfolio.ts +2 -2
  502. package/src/plugins/builtin/market-movers/client.ts +7 -5
  503. package/src/plugins/builtin/market-movers/index.tsx +3 -2
  504. package/src/plugins/builtin/market-movers/model.ts +30 -0
  505. package/src/plugins/builtin/market-movers/screener.ts +31 -0
  506. package/src/plugins/builtin/market-valuation/chart-series.ts +29 -69
  507. package/src/plugins/builtin/market-valuation/index.tsx +3 -3
  508. package/src/plugins/builtin/market-valuation/indicators.ts +0 -5
  509. package/src/plugins/builtin/members/headless.ts +8 -3
  510. package/src/plugins/builtin/members/model.ts +31 -3
  511. package/src/plugins/builtin/members/pane.tsx +6 -8
  512. package/src/plugins/builtin/mna/distress/headless.ts +4 -4
  513. package/src/plugins/builtin/mna/headless.ts +18 -6
  514. package/src/plugins/builtin/money-markets/headless.ts +5 -4
  515. package/src/plugins/builtin/money-markets/index.tsx +2 -0
  516. package/src/plugins/builtin/money-markets/series.ts +41 -0
  517. package/src/plugins/builtin/news/index.tsx +0 -2
  518. package/src/plugins/builtin/news/wire/news/detail-view.tsx +53 -104
  519. package/src/plugins/builtin/news/wire/news/footer.ts +2 -25
  520. package/src/plugins/builtin/news/wire/news/preset-pane.tsx +0 -2
  521. package/src/plugins/builtin/notes/cli.ts +12 -7
  522. package/src/plugins/builtin/notes/index.tsx +1 -0
  523. package/src/plugins/builtin/options/index.tsx +3 -0
  524. package/src/plugins/builtin/options/view.tsx +1 -1
  525. package/src/plugins/builtin/options-calculator/inputs.ts +2 -1
  526. package/src/plugins/builtin/options-positioning/client.ts +7 -3
  527. package/src/plugins/builtin/options-positioning/headless.ts +4 -3
  528. package/src/plugins/builtin/options-positioning/pane.tsx +2 -2
  529. package/src/plugins/builtin/options-scenario/client.ts +2 -1
  530. package/src/plugins/builtin/options-scenario/headless.ts +1 -0
  531. package/src/plugins/builtin/options-scenario/hedge.ts +2 -1
  532. package/src/plugins/builtin/perps/client.ts +90 -16
  533. package/src/plugins/builtin/perps/equity-row.tsx +52 -17
  534. package/src/plugins/builtin/perps/freshness.ts +66 -0
  535. package/src/plugins/builtin/perps/headless.ts +47 -32
  536. package/src/plugins/builtin/perps/index.tsx +23 -4
  537. package/src/plugins/builtin/perps/list-perpetuals.ts +118 -0
  538. package/src/plugins/builtin/perps/model.ts +20 -5
  539. package/src/plugins/builtin/perps/open-market.ts +15 -0
  540. package/src/plugins/builtin/perps/pane.tsx +76 -20
  541. package/src/plugins/builtin/perps/series.ts +76 -0
  542. package/src/plugins/builtin/plugin-marketplace/index.tsx +1 -1
  543. package/src/plugins/builtin/plugin-marketplace/pane.tsx +73 -67
  544. package/src/plugins/builtin/plugin-module.ts +3 -0
  545. package/src/plugins/builtin/portfolio-list/account-metrics.ts +1 -1
  546. package/src/plugins/builtin/portfolio-list/allocation.ts +5 -4
  547. package/src/plugins/builtin/portfolio-list/cell-version.ts +8 -1
  548. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +161 -0
  549. package/src/plugins/builtin/portfolio-list/cli/import-13f.ts +109 -0
  550. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +384 -74
  551. package/src/plugins/builtin/portfolio-list/cli/render.ts +437 -71
  552. package/src/plugins/builtin/portfolio-list/cli/shared.ts +21 -4
  553. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +121 -47
  554. package/src/plugins/builtin/portfolio-list/column-values.ts +104 -26
  555. package/src/plugins/builtin/portfolio-list/grid.tsx +1 -1
  556. package/src/plugins/builtin/portfolio-list/headless.ts +84 -18
  557. package/src/plugins/builtin/portfolio-list/imported-from.ts +8 -0
  558. package/src/plugins/builtin/portfolio-list/index.tsx +5 -1
  559. package/src/plugins/builtin/portfolio-list/live-valuation.ts +6 -2
  560. package/src/plugins/builtin/portfolio-list/mutations.ts +2 -9
  561. package/src/plugins/builtin/portfolio-list/pane/data.ts +5 -1
  562. package/src/plugins/builtin/portfolio-list/pane/index.tsx +52 -9
  563. package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +33 -11
  564. package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +21 -1
  565. package/src/plugins/builtin/portfolio-list/settings.ts +17 -0
  566. package/src/plugins/builtin/portfolio-list/summary/index.tsx +12 -0
  567. package/src/plugins/builtin/portfolio-list/summary/totals.ts +9 -4
  568. package/src/plugins/builtin/portfolio-list/table.tsx +37 -7
  569. package/src/plugins/builtin/power/client.ts +16 -0
  570. package/src/plugins/builtin/power/evidence.ts +63 -10
  571. package/src/plugins/builtin/power/headless.ts +77 -9
  572. package/src/plugins/builtin/power/index.tsx +28 -3
  573. package/src/plugins/builtin/power/model.ts +73 -2
  574. package/src/plugins/builtin/power/pane.tsx +37 -9
  575. package/src/plugins/builtin/power/prices-client.ts +139 -0
  576. package/src/plugins/builtin/power/prices-headless.ts +137 -0
  577. package/src/plugins/builtin/power/prices-model.ts +103 -0
  578. package/src/plugins/builtin/power/prices.tsx +179 -0
  579. package/src/plugins/builtin/rate-path/headless.ts +46 -18
  580. package/src/plugins/builtin/realized-vol/headless.ts +5 -0
  581. package/src/plugins/builtin/relative-rotation/headless.ts +3 -3
  582. package/src/plugins/builtin/research/corporate-actions-pane.tsx +5 -2
  583. package/src/plugins/builtin/research/event-model.ts +68 -24
  584. package/src/plugins/builtin/research/events-headless.ts +2 -1
  585. package/src/plugins/builtin/research/headless.ts +2 -1
  586. package/src/plugins/builtin/research/index.tsx +2 -0
  587. package/src/plugins/builtin/research-search/article.ts +65 -0
  588. package/src/plugins/builtin/research-search/document-view.tsx +33 -215
  589. package/src/plugins/builtin/research-search/model.ts +0 -9
  590. package/src/plugins/builtin/research-search/pane.tsx +41 -30
  591. package/src/plugins/builtin/research-search/snippet.ts +0 -29
  592. package/src/plugins/builtin/revenue-breakdown/headless.ts +18 -6
  593. package/src/plugins/builtin/seasonality/client.ts +15 -7
  594. package/src/plugins/builtin/seasonality/headless.ts +36 -12
  595. package/src/plugins/builtin/seasonality/index.tsx +2 -2
  596. package/src/plugins/builtin/seasonality/model.ts +119 -0
  597. package/src/plugins/builtin/seasonality/pane.tsx +108 -37
  598. package/src/plugins/builtin/sec/headless.ts +25 -3
  599. package/src/plugins/builtin/sec/index.tsx +2 -1
  600. package/src/plugins/builtin/series-inventory.ts +93 -0
  601. package/src/plugins/builtin/shared/cloud-denied.ts +15 -0
  602. package/src/plugins/builtin/shared/cloud-upgrade.ts +1 -1
  603. package/src/plugins/builtin/shared/command-tab.ts +30 -12
  604. package/src/plugins/builtin/shared/earnings-report.ts +55 -0
  605. package/src/plugins/builtin/shared/fred-points.ts +20 -0
  606. package/src/plugins/builtin/shared/free-preview.ts +47 -0
  607. package/src/plugins/builtin/shared/fx-rate-freshness.ts +101 -0
  608. package/src/plugins/builtin/shared/open-description.ts +29 -0
  609. package/src/plugins/builtin/shared/report-freshness.ts +12 -1
  610. package/src/plugins/builtin/shared/series-warning.ts +5 -0
  611. package/src/plugins/builtin/shared/volatility/options.ts +4 -1
  612. package/src/plugins/builtin/short-interest/headless.ts +1 -0
  613. package/src/plugins/builtin/short-interest/index.tsx +2 -0
  614. package/src/plugins/builtin/short-interest/series.ts +36 -0
  615. package/src/plugins/builtin/short-interest/watch-headless.ts +3 -2
  616. package/src/plugins/builtin/short-interest/watch-model.ts +9 -5
  617. package/src/plugins/builtin/short-volume/headless.ts +2 -1
  618. package/src/plugins/builtin/short-volume/index.tsx +2 -0
  619. package/src/plugins/builtin/short-volume/series.ts +23 -0
  620. package/src/plugins/builtin/social-mentions/headless.ts +1 -1
  621. package/src/plugins/builtin/social-mentions/index.tsx +2 -0
  622. package/src/plugins/builtin/social-mentions/series.ts +23 -0
  623. package/src/plugins/builtin/supply-chain/graph-pane.tsx +3 -2
  624. package/src/plugins/builtin/supply-chain/headless.ts +43 -11
  625. package/src/plugins/builtin/supply-chain/model.ts +13 -0
  626. package/src/plugins/builtin/supply-chain/pane.tsx +8 -6
  627. package/src/plugins/builtin/themes/headless.ts +74 -10
  628. package/src/plugins/builtin/themes/model.ts +71 -4
  629. package/src/plugins/builtin/themes/pane.tsx +22 -5
  630. package/src/plugins/builtin/thirteenf/api.ts +1 -0
  631. package/src/plugins/builtin/thirteenf/data.ts +6 -4
  632. package/src/plugins/builtin/thirteenf/headless.ts +217 -36
  633. package/src/plugins/builtin/thirteenf/model.ts +39 -1
  634. package/src/plugins/builtin/thirteenf/overlap.ts +75 -0
  635. package/src/plugins/builtin/thirteenf/pane.tsx +10 -1
  636. package/src/plugins/builtin/thirteenf/report-notes.ts +103 -1
  637. package/src/plugins/builtin/thirteenf/types.ts +2 -0
  638. package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +114 -0
  639. package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +57 -2
  640. package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +19 -55
  641. package/src/plugins/builtin/ticker-detail/headless-schema.ts +30 -0
  642. package/src/plugins/builtin/ticker-detail/headless.ts +86 -0
  643. package/src/plugins/builtin/ticker-detail/index.tsx +26 -11
  644. package/src/plugins/builtin/ticker-detail/overview/components.tsx +1 -1
  645. package/src/plugins/builtin/ticker-detail/overview/futures-contract.ts +31 -0
  646. package/src/plugins/builtin/ticker-detail/overview/model.ts +3 -3
  647. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +2 -1
  648. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +49 -5
  649. package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +13 -3
  650. package/src/plugins/builtin/time-sales/headless.ts +2 -1
  651. package/src/plugins/builtin/time-sales/index.tsx +2 -1
  652. package/src/plugins/builtin/treasury-auctions/headless.ts +16 -2
  653. package/src/plugins/builtin/treasury-auctions/index.tsx +1 -0
  654. package/src/plugins/builtin/treasury-auctions/model.ts +8 -0
  655. package/src/plugins/builtin/vol-surface/evidence.ts +7 -1
  656. package/src/plugins/builtin/vol-surface/headless.ts +51 -17
  657. package/src/plugins/builtin/vol-surface/heat-grid.tsx +113 -0
  658. package/src/plugins/builtin/vol-surface/model.ts +39 -6
  659. package/src/plugins/builtin/vol-surface/pane.tsx +14 -13
  660. package/src/plugins/builtin/vol-surface/stored.ts +63 -3
  661. package/src/plugins/builtin/vol-surface/surface.tsx +30 -2
  662. package/src/plugins/builtin/volatility/index.tsx +2 -0
  663. package/src/plugins/builtin/volatility/series.ts +84 -0
  664. package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +6 -5
  665. package/src/plugins/builtin/world-venue-map/basemap.ts +6 -3
  666. package/src/plugins/builtin/world-venue-map/geo-draw.tsx +2 -1
  667. package/src/plugins/builtin/world-venue-map/geo-series.ts +26 -1
  668. package/src/plugins/builtin/world-venue-map/geo-svg.tsx +6 -6
  669. package/src/plugins/builtin/world-venue-map/headless.ts +4 -1
  670. package/src/plugins/builtin/world-venue-map/index.ts +2 -1
  671. package/src/plugins/builtin/world-venue-map/layered-pane.tsx +24 -13
  672. package/src/plugins/builtin/world-venue-map/layers.ts +29 -0
  673. package/src/plugins/builtin/world-venue-map/map.tsx +144 -13
  674. package/src/plugins/builtin/world-venue-map/model.ts +56 -19
  675. package/src/plugins/builtin/world-venue-map/pane.tsx +5 -2
  676. package/src/plugins/builtin/yield-curve/chart.ts +2 -2
  677. package/src/plugins/builtin/yield-curve/curves.ts +21 -8
  678. package/src/plugins/builtin/yield-curve/headless.ts +71 -18
  679. package/src/plugins/builtin/yield-curve/index.tsx +4 -2
  680. package/src/plugins/builtin/yield-curve/series.ts +86 -0
  681. package/src/plugins/catalog-browser.ts +2 -1
  682. package/src/plugins/installer.ts +2 -2
  683. package/src/plugins/loader.ts +15 -0
  684. package/src/plugins/manager-node.ts +1 -1
  685. package/src/plugins/{builtin/plugin-marketplace → marketplace}/feed.ts +2 -2
  686. package/src/plugins/{builtin/plugin-marketplace → marketplace}/model.ts +6 -6
  687. package/src/plugins/{builtin/plugin-marketplace → marketplace}/store.ts +1 -1
  688. package/src/plugins/registry/host-actions.ts +11 -0
  689. package/src/plugins/registry/index.ts +89 -4
  690. package/src/portfolio/collection-name.ts +31 -0
  691. package/src/{plugins/builtin/portfolio-list → portfolio}/position-metrics.ts +6 -6
  692. package/src/portfolio/position-value.ts +40 -0
  693. package/src/portfolio/valuation-basis.ts +79 -0
  694. package/src/public/__snapshots__/public-api.test.ts.snap +7 -0
  695. package/src/public/time-series.ts +17 -0
  696. package/src/react/auto-refresh.ts +13 -3
  697. package/src/react/input.ts +33 -1
  698. package/src/react/key-repeat.ts +86 -0
  699. package/src/remote/app-host.tsx +20 -4
  700. package/src/remote/confirm-change.tsx +85 -0
  701. package/src/remote/controller-utils.ts +8 -1
  702. package/src/remote/controller.ts +144 -7
  703. package/src/remote/pane-screenshot.ts +47 -0
  704. package/src/remote/schema.ts +65 -2
  705. package/src/remote/types.ts +30 -0
  706. package/src/remote/watchlist.ts +306 -0
  707. package/src/renderers/browser/main.tsx +4 -3
  708. package/src/renderers/browser/research-entry.ts +4 -2
  709. package/src/renderers/cloudflare/worker.ts +1 -1
  710. package/src/renderers/dom/data-table/frozen-column.ts +3 -1
  711. package/src/renderers/dom/data-table/index.tsx +33 -6
  712. package/src/renderers/dom/data-table/row.tsx +30 -1
  713. package/src/renderers/dom/desktop/control-styles.ts +63 -1
  714. package/src/renderers/dom/desktop/controls.tsx +30 -23
  715. package/src/renderers/dom/desktop/dialog-actions.tsx +170 -0
  716. package/src/renderers/dom/desktop/icons.tsx +16 -0
  717. package/src/renderers/dom/dom-ui-host.tsx +3 -0
  718. package/src/renderers/dom/host/block-glyph-canvas.tsx +6 -3
  719. package/src/renderers/dom/host/box.tsx +8 -0
  720. package/src/renderers/dom/host/chart-surface.tsx +33 -2
  721. package/src/renderers/dom/host/live-frame.ts +6 -2
  722. package/src/renderers/dom/host/overflow-fade.ts +14 -1
  723. package/src/renderers/dom/host/scroll-box.tsx +32 -0
  724. package/src/renderers/dom/host/size-observer.ts +41 -0
  725. package/src/renderers/dom/host/sticky-scroll.ts +128 -0
  726. package/src/renderers/dom/host/style.ts +1 -1
  727. package/src/renderers/dom/host/surface-3d.tsx +19 -7
  728. package/src/renderers/dom/host/surface-fit.ts +406 -0
  729. package/src/renderers/dom/host/text.tsx +1 -1
  730. package/src/renderers/dom/input-host.tsx +1 -0
  731. package/src/renderers/dom/styles.css +102 -5
  732. package/src/renderers/electrobun/bun/application-menu/click.ts +18 -0
  733. package/src/renderers/electrobun/bun/index.ts +3 -2
  734. package/src/renderers/electrobun/shared/protocol.ts +1 -1
  735. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +29 -2
  736. package/src/renderers/electrobun/view/cli-pane-shot-frame.tsx +63 -20
  737. package/src/renderers/electrobun/view/cli-pane-shot-health.ts +10 -26
  738. package/src/renderers/electrobun/view/main.tsx +5 -3
  739. package/src/renderers/electrobun/view/remote/asset-data-client.ts +2 -0
  740. package/src/renderers/opentui/chart-surface.tsx +1 -0
  741. package/src/renderers/opentui/frame-capture.ts +33 -0
  742. package/src/renderers/opentui/host.tsx +10 -13
  743. package/src/renderers/opentui/pane-image/glyphs-license.txt +107 -0
  744. package/src/renderers/opentui/pane-image/glyphs.json +1 -0
  745. package/src/renderers/opentui/pane-image/index.ts +107 -0
  746. package/src/renderers/opentui/pane-image/raster.ts +428 -0
  747. package/src/renderers/opentui/start.tsx +3 -3
  748. package/src/renderers/opentui/test-utils.tsx +3 -0
  749. package/src/renderers/opentui/ui-host.tsx +29 -1
  750. package/src/series/capability.ts +75 -0
  751. package/src/series/csv.ts +160 -0
  752. package/src/series/files.ts +107 -0
  753. package/src/series/registry.ts +198 -0
  754. package/src/series/resolve.ts +108 -0
  755. package/src/series/standalone.ts +48 -0
  756. package/src/series/types.ts +153 -0
  757. package/src/series/validate.ts +171 -0
  758. package/src/shares/chat.ts +34 -0
  759. package/src/shares/dialog.tsx +295 -0
  760. package/src/shares/flow.tsx +56 -0
  761. package/src/shares/live.ts +14 -22
  762. package/src/shares/pane-image.ts +152 -0
  763. package/src/shares/personal-pane.ts +64 -0
  764. package/src/shares/portable-layout.ts +4 -2
  765. package/src/shares/prepare.ts +20 -0
  766. package/src/sources/gloomberb-cloud/index.ts +109 -10
  767. package/src/sources/gloomberb-cloud/normalizers.ts +3 -0
  768. package/src/sources/gloomberb-cloud/perpetuals.ts +249 -0
  769. package/src/sources/history-result.ts +1 -0
  770. package/src/sources/history-retention.ts +11 -0
  771. package/src/sources/listing-symbols.ts +4 -1
  772. package/src/sources/listing-target.ts +4 -0
  773. package/src/sources/provider-router/batches.ts +4 -1
  774. package/src/sources/provider-router/cache.ts +4 -2
  775. package/src/sources/provider-router/cached-routes.ts +1 -1
  776. package/src/sources/provider-router/financial-routes.ts +1 -0
  777. package/src/sources/provider-router/financials.ts +13 -0
  778. package/src/sources/provider-router/history.ts +43 -25
  779. package/src/sources/provider-router/index.ts +14 -0
  780. package/src/sources/provider-router/search.ts +1 -0
  781. package/src/state/hooks/inline-tickers.ts +49 -11
  782. package/src/sync/core-contributors.ts +1 -0
  783. package/src/test-support/shell-pane-keys.tsx +1 -0
  784. package/src/theme/theme-context.tsx +15 -1
  785. package/src/tickers/company-name.ts +75 -0
  786. package/src/tickers/instrument-kind.ts +34 -1
  787. package/src/tickers/listing-name.ts +34 -0
  788. package/src/tickers/listing-venues.ts +132 -0
  789. package/src/tickers/open-target.ts +13 -4
  790. package/src/tickers/perpetual-listing.ts +151 -0
  791. package/src/tickers/prediction-listing.ts +26 -0
  792. package/src/tickers/search/index.ts +72 -11
  793. package/src/tickers/search/ranking.ts +98 -20
  794. package/src/tickers/search/types.ts +7 -1
  795. package/src/tickers/ticker-changes.ts +213 -0
  796. package/src/tickers/us-listing.ts +34 -0
  797. package/src/time-series/economic.ts +2 -6
  798. package/src/time-series/hooks.ts +9 -0
  799. package/src/time-series/ice-credit.ts +39 -0
  800. package/src/time-series/resolve.ts +211 -29
  801. package/src/time-series/studies.ts +1 -0
  802. package/src/time-series/types.ts +12 -2
  803. package/src/time-series/use-chart-resolution.ts +32 -0
  804. package/src/types/config.ts +10 -2
  805. package/src/types/data-provider.ts +11 -0
  806. package/src/types/financials.ts +62 -1
  807. package/src/types/headless.ts +113 -0
  808. package/src/types/instrument.ts +4 -0
  809. package/src/types/plugin.ts +52 -2
  810. package/src/types/price-history.ts +7 -0
  811. package/src/types/ticker-changes.ts +26 -0
  812. package/src/types/ticker.ts +14 -0
  813. package/src/ui/context-menu.tsx +13 -1
  814. package/src/ui/host.tsx +57 -3
  815. package/src/ui/live-resize.ts +91 -0
  816. package/src/ui/live-stretch.ts +153 -0
  817. package/src/ui/measured-cells.ts +58 -0
  818. package/src/ui/sticky-scroll.ts +7 -0
  819. package/src/utils/basis-points.ts +17 -0
  820. package/src/utils/central-banks.ts +76 -0
  821. package/src/utils/cli-output.ts +131 -15
  822. package/src/utils/concurrency.ts +25 -0
  823. package/src/utils/crypto-pair.ts +20 -0
  824. package/src/utils/currency-pair.ts +19 -0
  825. package/src/utils/currency-units.ts +11 -0
  826. package/src/utils/datetime-format.ts +27 -6
  827. package/src/utils/decimal-comma.ts +19 -0
  828. package/src/utils/dom-screenshot-css.ts +265 -0
  829. package/src/utils/dom-screenshot-rasters.ts +276 -0
  830. package/src/utils/dom-screenshot.ts +439 -52
  831. package/src/utils/double-escape-close.ts +15 -1
  832. package/src/utils/exchange-rate-snapshot.ts +6 -2
  833. package/src/utils/exchanges.ts +143 -1
  834. package/src/utils/format.ts +35 -5
  835. package/src/utils/forward-dividend.ts +14 -0
  836. package/src/utils/fundamentals.ts +66 -0
  837. package/src/utils/futures-generic.ts +6 -12
  838. package/src/utils/fx-market-hours.ts +15 -5
  839. package/src/utils/fx-status.ts +6 -1
  840. package/src/utils/inline-content-tokenizer.ts +22 -3
  841. package/src/utils/market-capitalization.ts +8 -0
  842. package/src/utils/one-shot.ts +73 -0
  843. package/src/utils/options.ts +37 -8
  844. package/src/utils/price-history.ts +99 -42
  845. package/src/utils/sec-eps-basis.ts +24 -11
  846. package/src/utils/sec.ts +61 -7
  847. package/src/utils/utc-time.ts +63 -4
  848. package/src/plugins/builtin/fx-matrix/freshness.ts +0 -65
  849. /package/src/plugins/{builtin/plugin-marketplace → marketplace}/activation.ts +0 -0
  850. /package/src/plugins/{builtin/plugin-marketplace → marketplace}/ids.ts +0 -0
  851. /package/src/plugins/{builtin/plugin-marketplace → marketplace}/packs.ts +0 -0
  852. /package/src/{plugins/builtin/cloud → tickers}/starter-symbols.ts +0 -0
@@ -11,6 +11,7 @@ import {
11
11
  import { colors as themeColors } from "../../../theme/colors";
12
12
  import { consumeChartMouseEvent, getGlobalMouseX, getLocalPlotPointer, type ChartMouseEvent } from "../core/pointer";
13
13
  import { useStaticChartBitmapSize } from "./bitmap";
14
+ import { useMeasuredCells } from "../../../ui/measured-cells";
14
15
  import { PriceAxisLabels } from "./price-axis-labels";
15
16
  import { formatCompositeCursorValue, type CompositeAxisValueFormatter } from "./format";
16
17
  import {
@@ -20,7 +21,6 @@ import {
20
21
  type CompositeNavigationFrame,
21
22
  type CompositeViewportRange,
22
23
  } from "./interactions";
23
- import { buildCompositeColumnLayout } from "./column-layout";
24
24
  import {
25
25
  fitAxisLabels,
26
26
  hitTestLevel,
@@ -122,6 +122,8 @@ interface CompositePanelSurfaceProps {
122
122
  onSelectLevel: (id: string | null) => void;
123
123
  }
124
124
 
125
+ const DESKTOP_PLOT_STYLE = { flex: "1 1 0px", width: "auto", minWidth: 0, height: "auto", alignSelf: "stretch" } as const;
126
+
125
127
  export function CompositePanelSurface({
126
128
  panel,
127
129
  scene,
@@ -190,20 +192,25 @@ export function CompositePanelSurface({
190
192
  | ChartToolDrag
191
193
  | null
192
194
  >(null);
193
- const plotAspect = (plotWidth * cellWidthPx) / Math.max(panel.height * cellHeightPx, 1);
195
+ // The plot's box as the browser lays it out: on the desktop a chart that
196
+ // fills its box has it a fraction of a cell past its columns and rows. The
197
+ // bitmap is drawn at that size, so it is 1:1 at rest, and the pointer is
198
+ // read back into the scene's columns and rows. Elsewhere, and in the
199
+ // terminal, it is the plot's cells.
200
+ const plotSize = useMeasuredCells(plotRef, { width: plotWidth, height: panel.height });
201
+ const plotAspect = (plotSize.width * cellWidthPx) / Math.max(plotSize.height * cellHeightPx, 1);
194
202
  // The plot is wider than the viewport by the reserved right offset. Gestures
195
203
  // read the pointer in plot space, so they convert through this.
196
204
  const plotSpanFactor = 1 + compositeRightOffsetRatio(scene.timeScale);
197
- const bitmapSize = useStaticChartBitmapSize(plotWidth, panel.height);
205
+ const bitmapSize = useStaticChartBitmapSize(plotSize.width, plotSize.height);
198
206
  const bitmap = useCompositePanelBitmap({ panel, bitmapSize, colors, isDesktopWeb });
199
- const columnLayout = useMemo(() => buildCompositeColumnLayout(panel), [panel]);
200
207
  // The level line follows the pointer only. A keyboard or shared cursor knows
201
208
  // its column, and the series markers and axis readout already say the value.
202
209
  // A tool placed from the keyboard is the exception: its end is a level.
203
210
  const pointerCursorYRatio = scene.cursorXRatio === null ? null : heldCursorYRatio;
204
211
  const crosshair = useMemo(
205
- () => resolvePanelCrosshair(panel, columnLayout, bitmap, scene.cursorXRatio, pointerCursorYRatio, colors.crosshair),
206
- [bitmap, colors.crosshair, columnLayout, panel, pointerCursorYRatio, scene.cursorXRatio],
212
+ () => resolvePanelCrosshair(panel, bitmap, scene, pointerCursorYRatio, colors.crosshair),
213
+ [bitmap, colors.crosshair, panel, pointerCursorYRatio, scene],
207
214
  );
208
215
  const measureDomain = useMemo(() => resolveMeasureAxisDomain(panel), [panel]);
209
216
  const toolReadout = useMemo(() => {
@@ -489,18 +496,26 @@ export function CompositePanelSurface({
489
496
  const leftAxisMarkers = buildAxisMarkers("left");
490
497
  const rightAxisMarkers = buildAxisMarkers("right");
491
498
 
499
+ /** Where the pointer is over the plot, in the scene's columns and rows. */
500
+ const plotPointer = useCallback((event: ChartMouseEvent) => {
501
+ const pointer = getLocalPlotPointer(event, plotRef.current as unknown as Parameters<typeof getLocalPlotPointer>[1], renderer);
502
+ if (!pointer || (plotSize.width === plotWidth && plotSize.height === panel.height)) return pointer;
503
+ return {
504
+ ...pointer,
505
+ cellX: plotSize.width > 0 ? pointer.cellX * (plotWidth / plotSize.width) : pointer.cellX,
506
+ cellY: plotSize.height > 0 ? pointer.cellY * (panel.height / plotSize.height) : pointer.cellY,
507
+ };
508
+ }, [panel.height, plotSize.height, plotSize.width, plotWidth, renderer]);
492
509
  const pointerRatios = useCallback((event: ChartMouseEvent) => {
493
- const pointerTarget = plotRef.current as unknown as Parameters<typeof getLocalPlotPointer>[1];
494
- const pointer = getLocalPlotPointer(event, pointerTarget, renderer);
510
+ const pointer = plotPointer(event);
495
511
  if (!pointer) return null;
496
512
  return {
497
513
  xRatio: plotWidth <= 1 ? 0 : Math.max(0, Math.min(1, pointer.cellX / (plotWidth - 1))),
498
514
  yRatio: panel.height <= 1 ? 0.5 : Math.max(0, Math.min(1, pointer.cellY / (panel.height - 1))),
499
515
  };
500
- }, [panel.height, plotWidth, renderer]);
516
+ }, [panel.height, plotPointer, plotWidth]);
501
517
  const updateCursor = useCallback((event: ChartMouseEvent): boolean => {
502
- const pointerTarget = plotRef.current as unknown as Parameters<typeof getLocalPlotPointer>[1];
503
- const pointer = getLocalPlotPointer(event, pointerTarget, renderer);
518
+ const pointer = plotPointer(event);
504
519
  if (!pointer) return false;
505
520
  const nextDate = resolveCompositeCursorDate(scene, pointer.cellX);
506
521
  if (!nextDate) return false;
@@ -511,7 +526,7 @@ export function CompositePanelSurface({
511
526
  onCursorDateChange(nextDate);
512
527
  consumeChartMouseEvent(event);
513
528
  return true;
514
- }, [onCursorDateChange, panel.height, renderer, scene]);
529
+ }, [onCursorDateChange, panel.height, plotPointer, scene]);
515
530
  const clearCursor = useCallback(() => {
516
531
  setCursorYRatio(null);
517
532
  onCursorDateChange(null);
@@ -525,7 +540,7 @@ export function CompositePanelSurface({
525
540
  if (isDesktopWeb) releaseEditableFocus(event);
526
541
  consumeChartMouseEvent(event);
527
542
  if (onPickTime) {
528
- const pointer = getLocalPlotPointer(event, plotRef.current as unknown as Parameters<typeof getLocalPlotPointer>[1], renderer);
543
+ const pointer = plotPointer(event);
529
544
  const date = pointer ? resolveCompositeCursorDate(scene, pointer.cellX) : null;
530
545
  if (date) onPickTime(date);
531
546
  return;
@@ -588,7 +603,7 @@ export function CompositePanelSurface({
588
603
  dragRef.current = startPanGesture(
589
604
  frame,
590
605
  viewport,
591
- plotWidth,
606
+ plotSize.width,
592
607
  getGlobalMouseX(event, renderer),
593
608
  plotSpanFactor,
594
609
  );
@@ -606,6 +621,8 @@ export function CompositePanelSurface({
606
621
  panel,
607
622
  plotAspect,
608
623
  projectedLevels,
624
+ plotPointer,
625
+ plotSize.width,
609
626
  plotSpanFactor,
610
627
  plotWidth,
611
628
  pointerRatios,
@@ -658,7 +675,7 @@ export function CompositePanelSurface({
658
675
  if (drag.frame !== frame) {
659
676
  // Data refreshed mid-drag. The new frame maps positions differently, so
660
677
  // continue from where the plot is now instead of replaying the drag.
661
- Object.assign(drag, startPanGesture(frame, viewport, plotWidth, globalX, plotSpanFactor));
678
+ Object.assign(drag, startPanGesture(frame, viewport, plotSize.width, globalX, plotSpanFactor));
662
679
  }
663
680
  onPanViewport(
664
681
  (globalX - drag.startGlobalX) * drag.positionsPerCell,
@@ -670,6 +687,7 @@ export function CompositePanelSurface({
670
687
  onEditDrawing,
671
688
  onPanViewport,
672
689
  panel,
690
+ plotSize.width,
673
691
  plotSpanFactor,
674
692
  plotWidth,
675
693
  pointerRatios,
@@ -745,8 +763,7 @@ export function CompositePanelSurface({
745
763
  if (!scroll) return;
746
764
  onActivate?.();
747
765
  consumeChartMouseEvent(event);
748
- const pointerTarget = plotRef.current as unknown as Parameters<typeof getLocalPlotPointer>[1];
749
- const pointer = getLocalPlotPointer(event, pointerTarget, renderer);
766
+ const pointer = plotPointer(event);
750
767
  updateCursor(event);
751
768
  const pending = pendingWheelRef.current ?? { panRatio: 0, zoomLog: 0, anchorRatio: 0.5 };
752
769
  if (event.modifiers.ctrl && pointer && isVerticalWheelDirection(scroll.direction)) {
@@ -758,7 +775,7 @@ export function CompositePanelSurface({
758
775
  pointer.cellX / Math.max(plotWidth - 1, 1) * plotSpanFactor,
759
776
  );
760
777
  } else {
761
- pending.panRatio += resolveCompositeWheelPan(scroll, plotWidth * cellWidthPx);
778
+ pending.panRatio += resolveCompositeWheelPan(scroll, plotSize.width * cellWidthPx);
762
779
  }
763
780
  pendingWheelRef.current = pending;
764
781
  if (!isDesktopWeb || typeof webFrame.requestAnimationFrame !== "function") {
@@ -773,9 +790,10 @@ export function CompositePanelSurface({
773
790
  flushWheel,
774
791
  isDesktopWeb,
775
792
  onActivate,
793
+ plotPointer,
794
+ plotSize.width,
776
795
  plotSpanFactor,
777
796
  plotWidth,
778
- renderer,
779
797
  updateCursor,
780
798
  ]);
781
799
 
@@ -785,6 +803,10 @@ export function CompositePanelSurface({
785
803
  height={panel.height}
786
804
  width={plotWidth + leftAxisWidth + rightAxisWidth + axisGap * ((leftAxisWidth ? 1 : 0) + (rightAxisWidth ? 1 : 0))}
787
805
  position="relative"
806
+ // Desktop: spans the chart's box and takes its share of the height, so
807
+ // when a resize draws the box at a new size between renders the plot
808
+ // follows it by CSS. At rest, the size the cells give it.
809
+ style={isDesktopWeb ? { width: "100%", flex: `${panel.height} 1 calc(${panel.height} * var(--cell-h))`, height: "auto", minHeight: 0 } : undefined}
788
810
  >
789
811
  {measureReadout ? (
790
812
  <Box
@@ -830,8 +852,11 @@ export function CompositePanelSurface({
830
852
  ) : null}
831
853
  <ChartSurface
832
854
  ref={plotRef}
833
- width={plotWidth}
834
- height={panel.height}
855
+ // Its measured box on the desktop, where pointer bounds read it; CSS lays it out.
856
+ width={plotSize.width}
857
+ height={plotSize.height}
858
+ // Desktop: the width the axes leave, and the row's height.
859
+ style={isDesktopWeb ? DESKTOP_PLOT_STYLE : undefined}
835
860
  flexDirection="column"
836
861
  bitmaps={bitmapLayers}
837
862
  crosshair={crosshair}
@@ -190,7 +190,9 @@ export function PriceAxisLabels({
190
190
  height={height}
191
191
  flexDirection="column"
192
192
  overflow="hidden"
193
- style={usePixelOverlay || usePixelTicks ? { position: "relative" } : undefined}
193
+ // Labels placed in percentages follow the row's height as a resize
194
+ // draws the chart at a new size between renders.
195
+ style={usePixelOverlay || usePixelTicks ? { position: "relative", height: "auto", alignSelf: "stretch" } : undefined}
194
196
  >
195
197
  {Array.from({ length: height }, (_, row) => {
196
198
  const isCursorRow = !usePixelOverlay && cursorLabel !== null && cursorRow === row;
@@ -1,5 +1,6 @@
1
1
  import type { NativeChartBitmap } from "../native/chart-rasterizer";
2
2
  import {
3
+ blendAt,
3
4
  blendPixel,
4
5
  drawCircle,
5
6
  drawLine,
@@ -104,20 +105,61 @@ function fillAreaGradient(
104
105
  const reachAbove = Math.max(1, floor - Math.max(0, peakAbove));
105
106
  const reachBelow = Math.max(1, Math.min(height - 1, peakBelow) - floor);
106
107
 
108
+ // A pixel's opacity depends on its row alone, so each row's is worked out
109
+ // once; the pixels a fill covers are inside the bitmap and blend unchecked.
110
+ const colorAlpha = color.a / 255;
111
+ const rowAlpha = new Float64Array(height);
112
+ // Over an opaque pixel a blend is `colour * alpha + pixel * (1 - alpha)`:
113
+ // the first term and the factor are worked out per row too.
114
+ const rowRed = new Float64Array(height);
115
+ const rowGreen = new Float64Array(height);
116
+ const rowBlue = new Float64Array(height);
117
+ const rowKeep = new Float64Array(height);
118
+ for (let y = 0; y < height; y += 1) {
119
+ const strength = y <= floor ? (floor - y) / reachAbove : (y - floor) / reachBelow;
120
+ const alpha = clamp(colorAlpha * (AREA_FILL_MIN_OPACITY + (AREA_FILL_MAX_OPACITY - AREA_FILL_MIN_OPACITY) * strength), 0, 1);
121
+ rowAlpha[y] = alpha;
122
+ rowRed[y] = color.r * alpha;
123
+ rowGreen[y] = color.g * alpha;
124
+ rowBlue[y] = color.b * alpha;
125
+ rowKeep[y] = 1 - alpha;
126
+ }
127
+ // Each column fills from the line to the baseline. Walking the buffer row
128
+ // by row, in memory order, is several times faster than column by column.
129
+ const fillFrom = new Float64Array(width).fill(Number.POSITIVE_INFINITY);
130
+ const fillTo = new Float64Array(width).fill(Number.NEGATIVE_INFINITY);
131
+ let firstRow = floor + 1;
132
+ let lastRow = floor;
107
133
  for (let x = 0; x < width; x += 1) {
108
134
  const top = above[x]!;
135
+ const bottom = below[x]!;
109
136
  if (!Number.isNaN(top)) {
110
- for (let y = Math.max(0, Math.ceil(top)); y <= floor; y += 1) {
111
- const strength = (floor - y) / reachAbove;
112
- blendPixel(data, width, height, x, y, color, AREA_FILL_MIN_OPACITY + (AREA_FILL_MAX_OPACITY - AREA_FILL_MIN_OPACITY) * strength);
113
- }
137
+ fillFrom[x] = Math.max(0, Math.ceil(top));
138
+ firstRow = Math.min(firstRow, fillFrom[x]!);
114
139
  }
115
- const bottom = below[x]!;
116
140
  if (!Number.isNaN(bottom)) {
117
- for (let y = floor + 1; y <= Math.min(height - 1, Math.floor(bottom)); y += 1) {
118
- const strength = (y - floor) / reachBelow;
119
- blendPixel(data, width, height, x, y, color, AREA_FILL_MIN_OPACITY + (AREA_FILL_MAX_OPACITY - AREA_FILL_MIN_OPACITY) * strength);
141
+ fillTo[x] = Math.min(height - 1, Math.floor(bottom));
142
+ lastRow = Math.max(lastRow, fillTo[x]!);
143
+ }
144
+ }
145
+ for (let y = firstRow; y <= lastRow; y += 1) {
146
+ const alpha = rowAlpha[y]!;
147
+ if (alpha <= 0) continue;
148
+ const keep = rowKeep[y]!;
149
+ const red = rowRed[y]!;
150
+ const green = rowGreen[y]!;
151
+ const blue = rowBlue[y]!;
152
+ const aboveBaseline = y <= floor;
153
+ for (let x = 0; x < width; x += 1) {
154
+ if (aboveBaseline ? y < fillFrom[x]! : y > fillTo[x]!) continue;
155
+ const index = (y * width + x) * 4;
156
+ if (data[index + 3] !== 255) {
157
+ blendAt(data, index, color, alpha);
158
+ continue;
120
159
  }
160
+ data[index] = Math.round(red + data[index]! * keep);
161
+ data[index + 1] = Math.round(green + data[index + 1]! * keep);
162
+ data[index + 2] = Math.round(blue + data[index + 2]! * keep);
121
163
  }
122
164
  }
123
165
  }
@@ -656,6 +656,7 @@ function buildCursorValues(
656
656
  unit: entry.source.unit,
657
657
  value: projected?.value ?? null,
658
658
  point: projected?.point ?? gap?.point ?? null,
659
+ ...(cursorDate && projected && projected.timestamp < cursorTime ? { carried: true } : {}),
659
660
  };
660
661
  }));
661
662
  }
@@ -681,7 +682,7 @@ export function applyCompositeChartCursor(
681
682
  ...scene,
682
683
  cursorDate,
683
684
  cursorXRatio,
684
- cursorValues: buildCursorValues(scene.panels, cursorDate, scene),
685
+ cursorValues: buildCursorValues(scene.cursorPanels ?? scene.panels, cursorDate, scene),
685
686
  };
686
687
  }
687
688
 
@@ -27,6 +27,7 @@ interface CachedMarketAnchors {
27
27
  timeZone: string;
28
28
  configuredCadence: number | undefined;
29
29
  cadenceMs: number;
30
+ historyMsPerSlot: number;
30
31
  anchors: MarketAnchors;
31
32
  }
32
33
 
@@ -113,7 +114,7 @@ function lowerBoundAnchor(
113
114
  }
114
115
 
115
116
  function positionForTimestamp(
116
- scale: Pick<Extract<CompositeTimeScale, { kind: "market" }>, "anchors" | "cadenceMs">,
117
+ scale: Pick<Extract<CompositeTimeScale, { kind: "market" }>, "anchors" | "cadenceMs" | "historyMsPerSlot">,
117
118
  timestamp: number,
118
119
  ): number {
119
120
  const { anchors, cadenceMs } = scale;
@@ -122,7 +123,7 @@ function positionForTimestamp(
122
123
  if (next?.timestamp === timestamp) return next.position;
123
124
  const previous = anchors[index - 1];
124
125
  if (!previous) {
125
- return anchors[0]!.position + (timestamp - anchors[0]!.timestamp) / cadenceMs;
126
+ return anchors[0]!.position + (timestamp - anchors[0]!.timestamp) / (scale.historyMsPerSlot ?? cadenceMs);
126
127
  }
127
128
  if (!next) {
128
129
  const last = anchors.at(-1)!;
@@ -134,8 +135,22 @@ function positionForTimestamp(
134
135
  + (next.position - previous.position) * ((timestamp - previous.timestamp) / elapsed);
135
136
  }
136
137
 
138
+ /**
139
+ * Wall-clock time per slot across the loaded bars, nights and weekends
140
+ * included. History not loaded yet is laid out at this rate: at the bar
141
+ * cadence instead, a view panned into it would hold a few days where it held
142
+ * weeks, and squeeze shut when the bars arrive.
143
+ */
144
+ function averageMsPerSlot(anchors: MarketAnchors, cadenceMs: number): number {
145
+ const first = anchors[0];
146
+ const last = anchors.at(-1);
147
+ if (!first || !last || last.position <= first.position) return cadenceMs;
148
+ return Math.max(cadenceMs, (last.timestamp - first.timestamp) / (last.position - first.position));
149
+ }
150
+
137
151
  function buildMarketAnchors(series: ResolvedSeries, timeZone: string): {
138
152
  cadenceMs: number;
153
+ historyMsPerSlot: number;
139
154
  anchors: MarketAnchors;
140
155
  } {
141
156
  const anchorTimestamps = uniqueSeriesTimestamps(series);
@@ -166,7 +181,7 @@ function buildMarketAnchors(series: ResolvedSeries, timeZone: string): {
166
181
  }
167
182
  anchors.push({ timestamp, position });
168
183
  });
169
- return { cadenceMs, anchors };
184
+ return { cadenceMs, historyMsPerSlot: averageMsPerSlot(anchors, cadenceMs), anchors };
170
185
  }
171
186
 
172
187
  /**
@@ -176,7 +191,7 @@ function buildMarketAnchors(series: ResolvedSeries, timeZone: string): {
176
191
  */
177
192
  function resolveMarketAnchors(
178
193
  series: ResolvedSeries,
179
- ): { cadenceMs: number; anchors: MarketAnchors; timeZone: string } | null {
194
+ ): { cadenceMs: number; historyMsPerSlot: number; anchors: MarketAnchors; timeZone: string } | null {
180
195
  if (!series.timeBasis || series.timeBasis.kind !== "market") return null;
181
196
  const { timeZone, cadenceMs: configuredCadence } = series.timeBasis;
182
197
  const lastTimestamp = series.points.length > 0
@@ -191,7 +206,7 @@ function resolveMarketAnchors(
191
206
  && cached.timeZone === timeZone
192
207
  && cached.configuredCadence === configuredCadence
193
208
  ) {
194
- return { cadenceMs: cached.cadenceMs, anchors: cached.anchors, timeZone };
209
+ return { cadenceMs: cached.cadenceMs, historyMsPerSlot: cached.historyMsPerSlot, anchors: cached.anchors, timeZone };
195
210
  }
196
211
  const built = buildMarketAnchors(series, timeZone);
197
212
  anchorCache.set(series, {
@@ -201,6 +216,7 @@ function resolveMarketAnchors(
201
216
  timeZone,
202
217
  configuredCadence,
203
218
  cadenceMs: built.cadenceMs,
219
+ historyMsPerSlot: built.historyMsPerSlot,
204
220
  anchors: built.anchors,
205
221
  });
206
222
  return { ...built, timeZone };
@@ -218,15 +234,16 @@ export function buildCompositeTimeScale(
218
234
  if (!anchorSeries || !resolved || resolved.anchors.length === 0) {
219
235
  return { kind: "calendar", startTime, endTime, rightOffsetRatio: offset };
220
236
  }
221
- const { cadenceMs, anchors } = resolved;
222
- const startPosition = positionForTimestamp({ anchors, cadenceMs }, startTime);
223
- const endPosition = positionForTimestamp({ anchors, cadenceMs }, endTime);
237
+ const { cadenceMs, historyMsPerSlot, anchors } = resolved;
238
+ const startPosition = positionForTimestamp({ anchors, cadenceMs, historyMsPerSlot }, startTime);
239
+ const endPosition = positionForTimestamp({ anchors, cadenceMs, historyMsPerSlot }, endTime);
224
240
  return {
225
241
  kind: "market",
226
242
  startTime,
227
243
  endTime,
228
244
  anchorSeriesId: anchorSeries.id,
229
245
  cadenceMs,
246
+ historyMsPerSlot,
230
247
  anchors,
231
248
  startPosition,
232
249
  endPosition: endPosition > startPosition ? endPosition : startPosition + 1,
@@ -267,7 +284,7 @@ export function compositeTimeAtPosition(scale: CompositeTimeScale, position: num
267
284
  const next = anchors[low];
268
285
  const previous = anchors[low - 1];
269
286
  if (!previous) {
270
- return anchors[0]!.timestamp + (position - anchors[0]!.position) * scale.cadenceMs;
287
+ return anchors[0]!.timestamp + (position - anchors[0]!.position) * (scale.historyMsPerSlot ?? scale.cadenceMs);
271
288
  }
272
289
  if (!next) {
273
290
  const last = anchors.at(-1)!;
@@ -70,6 +70,12 @@ interface CompositeMarketTimeScale {
70
70
  endTime: number;
71
71
  anchorSeriesId: string;
72
72
  cadenceMs: number;
73
+ /**
74
+ * Wall-clock time one slot stands for before the first observation: the
75
+ * loaded bars' own average, closed sessions included. Absent means
76
+ * `cadenceMs`.
77
+ */
78
+ historyMsPerSlot?: number;
73
79
  anchors: Array<{
74
80
  timestamp: number;
75
81
  position: number;
@@ -146,6 +152,12 @@ export interface CompositeCursorValue {
146
152
  unit: string;
147
153
  value: number | null;
148
154
  point: TimeSeriesPoint | null;
155
+ /**
156
+ * Under a cursor, the value is the series' last one before the cursor's
157
+ * time, which it has no observation at: another venue's hours, a coarser
158
+ * cadence, a dataset that lags.
159
+ */
160
+ carried?: boolean;
149
161
  }
150
162
 
151
163
  export interface CompositeChartScene {
@@ -161,6 +173,12 @@ export interface CompositeChartScene {
161
173
  cursorDate: Date | null;
162
174
  cursorXRatio: number | null;
163
175
  cursorValues: CompositeCursorValue[];
176
+ /**
177
+ * The panels before they were thinned to the plot's pixels, which the
178
+ * cursor reads values from: a thinned line or a bucket of candles has no
179
+ * point at most of the bars it stands for.
180
+ */
181
+ cursorPanels?: CompositePanelScene[];
164
182
  /** IANA zone the time axis and cursor read in: the venue's for intraday market bars, else UTC. */
165
183
  timeZone?: string;
166
184
  }
@@ -16,6 +16,17 @@ import type { CompositeChartProps } from "./types";
16
16
 
17
17
  /** How far past the first loaded observation a backfilling chart may pan, as a fraction of the view. */
18
18
  const HISTORICAL_PADDING_RATIO = 0.5;
19
+ /**
20
+ * Once the source has said its history starts at the first loaded bar, a pan
21
+ * stops there, with this much air before it rather than half an empty view.
22
+ */
23
+ const HISTORY_EDGE_PADDING_RATIO = 0.02;
24
+
25
+ /** True when every market listing on the chart has said nothing older exists. */
26
+ function reachesHistoryStart(series: readonly ResolvedSeries[]): boolean {
27
+ const market = series.filter((entry) => entry.observationKind === "market" && entry.points.length > 0);
28
+ return market.length > 0 && market.every((entry) => entry.historyStart !== undefined);
29
+ }
19
30
 
20
31
  export function useCompositeViewport({
21
32
  viewport,
@@ -45,11 +56,13 @@ export function useCompositeViewport({
45
56
  previousAuthoredViewportRef.current,
46
57
  viewport ?? null,
47
58
  );
59
+ const historyStartReached = allowHistoricalBackfill && reachesHistoryStart(visibleSeries);
48
60
  const navigationFrame = useMemo(
49
61
  () => buildCompositeNavigationFrame(visibleSeries, marketTimelineSeries, {
50
- historicalPaddingRatio: allowHistoricalBackfill ? HISTORICAL_PADDING_RATIO : 0,
62
+ historicalPaddingRatio: !allowHistoricalBackfill ? 0
63
+ : historyStartReached ? HISTORY_EDGE_PADDING_RATIO : HISTORICAL_PADDING_RATIO,
51
64
  }),
52
- [allowHistoricalBackfill, marketTimelineSeries, visibleSeries],
65
+ [allowHistoricalBackfill, historyStartReached, marketTimelineSeries, visibleSeries],
53
66
  );
54
67
  const authoredViewport = useMemo(() => {
55
68
  // The requested dates own the axis, including gaps in a cached or partial
@@ -95,6 +108,21 @@ export function useCompositeViewport({
95
108
  }
96
109
  }, [authoredViewportChanged, userViewport, viewport, viewportResetKey]);
97
110
 
111
+ // Once the source says it has nothing older, a view left in the space
112
+ // before the first bar (where a pan went while the answer was on its way)
113
+ // settles onto it, as it would have stopped there had the answer come first.
114
+ useEffect(() => {
115
+ if (!historyStartReached || !navigationFrame) return;
116
+ setUserViewport((current) => {
117
+ if (!current) return current;
118
+ const positions = compositeViewportPositions(navigationFrame, current);
119
+ const span = positions ? positions.end - positions.start : 0;
120
+ if (!positions || positions.start >= navigationFrame.dataStartPosition - span * HISTORY_EDGE_PADDING_RATIO - 1e-6) return current;
121
+ viewportInteractionRef.current = "pan";
122
+ return fitCompositeViewport(navigationFrame, current);
123
+ });
124
+ }, [historyStartReached, navigationFrame]);
125
+
98
126
  const navigate = useCallback((
99
127
  kind: "pan" | "zoom",
100
128
  compute: (base: CompositeViewportRange, frame: CompositeNavigationFrame) => CompositeViewportRange,
@@ -1,10 +1,12 @@
1
- import { drawCircle, drawLine, parseHex } from "./primitives";
1
+ import { drawCircle, drawLine, drawRing, parseHex } from "./primitives";
2
2
  import type { CellRect, NativeChartBitmap } from "./types";
3
3
  import { clamp } from "../../../../utils/math";
4
4
 
5
5
  interface CrosshairMarker {
6
6
  pixelY: number;
7
7
  color: string;
8
+ /** A ring rather than a dot: the series carries an earlier value here. */
9
+ hollow?: boolean;
8
10
  }
9
11
 
10
12
  export interface CrosshairStripsOptions {
@@ -56,15 +58,18 @@ export function renderCrosshairStrips(options: CrosshairStripsOptions): Crosshai
56
58
  const vertical = bitmap(verticalWidth, pixelHeight);
57
59
  const localX = clamp(x - verticalStart * cellWidth, 0, vertical.width - 1);
58
60
  drawLine(vertical.pixels, vertical.width, vertical.height, localX, 0, localX, vertical.height - 1, lineColor, 1.05);
61
+ let markerKey = "";
59
62
  for (const marker of options.markers ?? []) {
60
63
  const markerY = clamp(marker.pixelY, 0, Math.max(pixelHeight - 1, 0));
61
- drawCircle(vertical.pixels, vertical.width, vertical.height, localX, markerY, 2.6, parseHex(marker.color));
64
+ if (marker.hollow) drawRing(vertical.pixels, vertical.width, vertical.height, localX, markerY, 2.6, 1.2, parseHex(marker.color));
65
+ else drawCircle(vertical.pixels, vertical.width, vertical.height, localX, markerY, 2.6, parseHex(marker.color));
66
+ markerKey += `${markerY.toFixed(1)}${marker.hollow ? "o" : "."}${marker.color}`;
62
67
  }
63
68
  if (y !== null) drawCircle(vertical.pixels, vertical.width, vertical.height, localX, y, 2.1, focusColor);
64
69
  strips.push({
65
70
  rect: { x: verticalStart, y: 0, width: verticalCols, height: rows },
66
71
  bitmap: vertical,
67
- key: `v:${verticalStart}:${localX.toFixed(2)}:${y === null ? "-" : y.toFixed(2)}`,
72
+ key: `v:${verticalStart}:${localX.toFixed(2)}:${y === null ? "-" : y.toFixed(2)}:${markerKey}`,
68
73
  });
69
74
  if (y === null) return strips;
70
75