gloomberb 0.18.3 → 0.18.4

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 (886) hide show
  1. package/README.md +8 -8
  2. package/README.zh-CN.md +11 -11
  3. package/bin/{gloomberb → gloom} +3 -1
  4. package/package.json +6 -2
  5. package/src/account/checkout-handoff.tsx +225 -0
  6. package/src/account/device-signin-dialog.tsx +2 -2
  7. package/src/account/device-signin.ts +2 -2
  8. package/src/account/upgrade-dialog.tsx +1 -1
  9. package/src/api-client/askg.ts +2 -2
  10. package/src/api-client/auth.ts +2 -2
  11. package/src/api-client/central-bank-rates.ts +6 -0
  12. package/src/api-client/collections.ts +5 -1
  13. package/src/api-client/cot.ts +2 -0
  14. package/src/api-client/crypto-etf-flows.ts +37 -0
  15. package/src/api-client/crypto-markets.ts +60 -0
  16. package/src/api-client/data.ts +84 -5
  17. package/src/api-client/doe.ts +15 -0
  18. package/src/api-client/equity-screener.ts +28 -0
  19. package/src/api-client/exchange-announcements.ts +38 -0
  20. package/src/api-client/fund-facts.ts +39 -0
  21. package/src/api-client/futures-curve.ts +9 -1
  22. package/src/api-client/hiring.ts +301 -0
  23. package/src/api-client/index.ts +22 -5
  24. package/src/api-client/market-discovery.ts +14 -0
  25. package/src/api-client/members.ts +6 -0
  26. package/src/api-client/mna.ts +6 -0
  27. package/src/api-client/paths.ts +18 -1
  28. package/src/api-client/request.ts +21 -4
  29. package/src/api-client/short-side-publications.ts +37 -0
  30. package/src/api-client/socket.ts +64 -4
  31. package/src/api-client/swap-curve.ts +35 -0
  32. package/src/api-client/themes.ts +7 -1
  33. package/src/api-client/types.ts +90 -2
  34. package/src/app/pane-runtime/plugin-bindings.ts +9 -2
  35. package/src/app/runtime/desktop-deeplink.ts +5 -5
  36. package/src/app/runtime/plugin-bindings.ts +2 -2
  37. package/src/app/runtime/startup.ts +13 -0
  38. package/src/app/star-prompt/status-line.tsx +2 -2
  39. package/src/architecture/core-builtin-allowlist.json +5 -2
  40. package/src/architecture/ui-literals-allowlist.json +3 -3
  41. package/src/architecture/ui-tokens-allowlist.json +1 -1
  42. package/src/brokers/broker-portfolio-sync.ts +37 -0
  43. package/src/brokers/directory.ts +11 -0
  44. package/src/brokers/logos.ts +3 -1
  45. package/src/brokers/signed-in/adapter.ts +304 -26
  46. package/src/brokers/signed-in/client.ts +14 -2
  47. package/src/brokers/signed-in/connect.ts +10 -2
  48. package/src/brokers/sync-broker-instance.ts +9 -1
  49. package/src/capabilities/chart-series.ts +22 -6
  50. package/src/cli/bank-section.ts +1 -1
  51. package/src/cli/base-converter.ts +23 -14
  52. package/src/cli/central-bank-events.ts +1 -1
  53. package/src/cli/command-options.ts +59 -4
  54. package/src/cli/commands/api.ts +9 -6
  55. package/src/cli/commands/broker.ts +2 -2
  56. package/src/cli/commands/command-utils.ts +2 -2
  57. package/src/cli/commands/crypto-hints.ts +7 -20
  58. package/src/cli/commands/fred-series.ts +4 -2
  59. package/src/cli/commands/keybindings.ts +2 -2
  60. package/src/cli/commands/market.ts +1117 -264
  61. package/src/cli/commands/news-hints.ts +2 -2
  62. package/src/cli/commands/news-search.ts +59 -6
  63. package/src/cli/commands/options-leaps.ts +41 -26
  64. package/src/cli/commands/overview.ts +121 -48
  65. package/src/cli/commands/plugins.ts +9 -9
  66. package/src/cli/commands/remote.ts +13 -10
  67. package/src/cli/commands/search.ts +64 -44
  68. package/src/cli/commands/system.ts +27 -19
  69. package/src/cli/commands/themes.ts +1 -1
  70. package/src/cli/commands/ticker.ts +192 -47
  71. package/src/cli/context.ts +3 -2
  72. package/src/cli/desktop-pane-shot-view.ts +2 -2
  73. package/src/cli/desktop-pane-shot.ts +1 -1
  74. package/src/cli/earnings-calendar.ts +4 -4
  75. package/src/cli/entry.ts +18 -1
  76. package/src/cli/errors.ts +20 -2
  77. package/src/cli/exit-codes.ts +1 -1
  78. package/src/cli/export-source.ts +10 -4
  79. package/src/cli/freshness.ts +2 -8
  80. package/src/cli/fx-forward.ts +130 -0
  81. package/src/cli/fx-pair.ts +10 -9
  82. package/src/cli/glossary.ts +64 -20
  83. package/src/cli/help.ts +19 -13
  84. package/src/cli/history-export.ts +126 -0
  85. package/src/cli/history-rows.ts +196 -43
  86. package/src/cli/index-roots.ts +5 -45
  87. package/src/cli/index.ts +24 -18
  88. package/src/cli/known-gaps.ts +118 -25
  89. package/src/cli/listing-arg.ts +300 -41
  90. package/src/cli/name-entries.ts +30 -18
  91. package/src/cli/native-smoke.ts +2 -0
  92. package/src/cli/not-a-ticker.ts +19 -9
  93. package/src/cli/opentui-libc.ts +5 -0
  94. package/src/cli/options.ts +12 -0
  95. package/src/cli/pane-functions/capabilities.ts +75 -20
  96. package/src/cli/pane-functions/catalog.ts +24 -23
  97. package/src/cli/pane-functions/discovery.ts +1 -1
  98. package/src/cli/pane-functions/dom.ts +10 -7
  99. package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
  100. package/src/cli/pane-functions/freshness.ts +174 -23
  101. package/src/cli/pane-functions/function-help.ts +66 -27
  102. package/src/cli/pane-functions/headless.ts +24 -11
  103. package/src/cli/pane-functions/index.ts +18 -16
  104. package/src/cli/pane-functions/options.ts +22 -2
  105. package/src/cli/pane-functions/report-notices.ts +12 -4
  106. package/src/cli/pane-functions/report.ts +5 -5
  107. package/src/cli/pane-functions/resolver.ts +47 -10
  108. package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
  109. package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
  110. package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
  111. package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
  112. package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
  113. package/src/cli/pane-functions/screenshot-payload.ts +453 -0
  114. package/src/cli/pane-functions/screenshot-render.ts +316 -0
  115. package/src/cli/pane-functions/screenshot-types.ts +162 -0
  116. package/src/cli/pane-functions/shot-options.ts +8 -3
  117. package/src/cli/peso-dollar-rates.ts +79 -0
  118. package/src/cli/quote-answer.ts +38 -3
  119. package/src/cli/report-tables.ts +61 -16
  120. package/src/cli/restore-plugins.ts +29 -14
  121. package/src/cli/result.ts +111 -22
  122. package/src/cli/series-search.ts +5 -5
  123. package/src/cli/statement-filings.ts +19 -0
  124. package/src/cli/suffixed-listing-rows.ts +49 -0
  125. package/src/cli/symbol-args.ts +50 -15
  126. package/src/cli/symbol-cells.ts +120 -0
  127. package/src/cli/symbol-list.ts +198 -68
  128. package/src/cli/symbol-rows.ts +131 -25
  129. package/src/cli/ticker-resolution.ts +108 -11
  130. package/src/cli/treasury-yields.ts +5 -5
  131. package/src/cli/types.ts +2 -0
  132. package/src/cli/uncovered-instrument.ts +3 -3
  133. package/src/cli/unknown-command.ts +6 -6
  134. package/src/components/chart/composite/chart-layout.ts +131 -0
  135. package/src/components/chart/composite/composite-chart.tsx +373 -16
  136. package/src/components/chart/composite/interactions.ts +7 -2
  137. package/src/components/chart/composite/legend.tsx +75 -3
  138. package/src/components/chart/composite/levels.ts +5 -0
  139. package/src/components/chart/composite/panel-gestures.ts +41 -0
  140. package/src/components/chart/composite/panel-labels.ts +2 -1
  141. package/src/components/chart/composite/panel-surface.tsx +305 -11
  142. package/src/components/chart/composite/price-axis-labels.tsx +27 -3
  143. package/src/components/chart/composite/rasterizer.ts +44 -19
  144. package/src/components/chart/composite/scene.ts +16 -4
  145. package/src/components/chart/composite/text-renderer.ts +48 -21
  146. package/src/components/chart/composite/toolbar.tsx +52 -5
  147. package/src/components/chart/composite/types.ts +13 -0
  148. package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
  149. package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
  150. package/src/components/chart/composite/use-composite-viewport.ts +12 -3
  151. package/src/components/chart/composite/value-scale.ts +149 -0
  152. package/src/components/chart/composite/volume-profile-paint.ts +6 -3
  153. package/src/components/chart/core/pointer.ts +2 -0
  154. package/src/components/chart-table/index.ts +2 -0
  155. package/src/components/chart-table/read.tsx +74 -0
  156. package/src/components/command-bar/commands/collection-list.ts +41 -19
  157. package/src/components/command-bar/commands/collection.ts +9 -3
  158. package/src/components/command-bar/commands/direct/index.ts +1 -1
  159. package/src/components/command-bar/commands/direct/runtime.ts +3 -2
  160. package/src/components/command-bar/pane-templates/items.ts +59 -6
  161. package/src/components/command-bar/pane-templates/workflow.ts +10 -1
  162. package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
  163. package/src/components/command-bar/routes/root/provider-search.ts +42 -11
  164. package/src/components/command-bar/routes/root/results.ts +18 -4
  165. package/src/components/command-bar/routes/root/runtime.ts +15 -3
  166. package/src/components/command-bar/routes/root/search-providers.ts +25 -2
  167. package/src/components/command-bar/routes/root/selection.ts +6 -1
  168. package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
  169. package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
  170. package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
  171. package/src/components/command-bar/selection-runtime.ts +50 -10
  172. package/src/components/command-bar/surface/index.tsx +24 -2
  173. package/src/components/command-bar/view-model.ts +7 -0
  174. package/src/components/command-bar/workflow/broker.ts +2 -2
  175. package/src/components/command-bar/workflow/collection-actions.ts +46 -7
  176. package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
  177. package/src/components/command-bar/workflow/fields.ts +8 -2
  178. package/src/components/command-bar/workflow/ops.ts +18 -4
  179. package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
  180. package/src/components/command-bar/workflow/submit.ts +3 -2
  181. package/src/components/command-bar/workflow/tickers.ts +5 -1
  182. package/src/components/company-logo.tsx +39 -0
  183. package/src/components/data-table/sections.ts +4 -2
  184. package/src/components/form-modal/confirm.tsx +2 -1
  185. package/src/components/form-modal/request.ts +5 -0
  186. package/src/components/form-modal/routes.ts +4 -1
  187. package/src/components/index.ts +12 -6
  188. package/src/components/layout/header.tsx +7 -6
  189. package/src/components/layout/market-summary.ts +9 -6
  190. package/src/components/layout/pane/capture-status.ts +1 -1
  191. package/src/components/layout/pane/footer/model.ts +11 -5
  192. package/src/components/layout/shell/chrome.ts +19 -6
  193. package/src/components/layout/shell/index.tsx +2 -1
  194. package/src/components/layout/shell/pane/layers.tsx +19 -1
  195. package/src/components/layout/status-bar.tsx +2 -2
  196. package/src/components/market-board/index.tsx +11 -3
  197. package/src/components/onboarding/onboarding-wizard.tsx +1 -0
  198. package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
  199. package/src/components/onboarding/wizard-broker-sync.ts +4 -1
  200. package/src/components/pane-settings-dialog/desktop.tsx +20 -7
  201. package/src/components/pane-settings-dialog/tui.tsx +17 -9
  202. package/src/components/pane-settings-dialog/value.ts +8 -1
  203. package/src/components/pane-settings-dialog.tsx +44 -13
  204. package/src/components/sign-in-code-panel.tsx +27 -19
  205. package/src/components/ui/column-grid.tsx +48 -4
  206. package/src/components/ui/country-flag-art.tsx +180 -0
  207. package/src/components/ui/country-flag.tsx +118 -12
  208. package/src/components/ui/data-table/opentui/index.tsx +61 -2
  209. package/src/components/ui/data-table/opentui/model.ts +109 -2
  210. package/src/components/ui/data-table/types.ts +1 -1
  211. package/src/components/ui/display.tsx +5 -1
  212. package/src/components/ui/index.ts +3 -1
  213. package/src/components/ui/logo-mark.tsx +11 -2
  214. package/src/components/ui/query-bar.tsx +1 -1
  215. package/src/components/ui/row-notes.ts +79 -0
  216. package/src/core/state/app/layout.ts +4 -4
  217. package/src/data/cached-query.ts +8 -1
  218. package/src/data/config/chart-settings.ts +3 -3
  219. package/src/data/config/home.ts +10 -2
  220. package/src/data/config/layout.ts +4 -1
  221. package/src/data/config/store/node.ts +4 -0
  222. package/src/data/config/store/normalize.ts +13 -3
  223. package/src/data/config/store/portfolio-as-of-column.ts +2 -2
  224. package/src/data/json-storage.ts +2 -0
  225. package/src/data/saved-copies.ts +84 -0
  226. package/src/docs/snapshot.json +65 -32
  227. package/src/i18n/es.ts +29 -12
  228. package/src/i18n/ja.ts +29 -12
  229. package/src/i18n/ko.ts +29 -12
  230. package/src/i18n/zh-cn.ts +29 -12
  231. package/src/i18n/zh-tw.ts +29 -12
  232. package/src/layout/desks.ts +1 -1
  233. package/src/layout/launch-layout.ts +1 -1
  234. package/src/layout/pane-manager/floating-actions.ts +5 -3
  235. package/src/layout/pane-manager/floating.ts +43 -1
  236. package/src/layout/pane-manager/index.ts +2 -0
  237. package/src/layout/selected-ticker.ts +74 -0
  238. package/src/market-data/depositary-pair.ts +251 -0
  239. package/src/market-data/futures-board.ts +1 -1
  240. package/src/market-data/futures-contract.ts +124 -40
  241. package/src/market-data/fx-closes.ts +17 -2
  242. package/src/market-data/hooks.tsx +19 -11
  243. package/src/market-data/market/change-basis.ts +49 -7
  244. package/src/market-data/market/freshness.ts +34 -5
  245. package/src/market-data/market/period-return.ts +163 -0
  246. package/src/market-data/market/trading-sessions.ts +13 -0
  247. package/src/market-data/market/year-to-date.ts +8 -13
  248. package/src/market-data/performance.ts +20 -14
  249. package/src/market-data/perpetual-premium.ts +32 -0
  250. package/src/market-data/published-apac-sessions.ts +2 -1
  251. package/src/market-data/published-futures-sessions.ts +69 -0
  252. package/src/market-data/quotes/contributions.ts +5 -1
  253. package/src/market-data/quotes/freshness.ts +42 -0
  254. package/src/market-data/quotes/intraday-bar.ts +37 -0
  255. package/src/market-data/quotes/regular-session-valuation.ts +13 -8
  256. package/src/market-data/quotes/resolution.ts +4 -2
  257. package/src/market-data/tax-equivalent.ts +1 -1
  258. package/src/market-data/ticker-price-returns.ts +3 -1
  259. package/src/news/aggregator.ts +5 -1
  260. package/src/news/news-model.ts +4 -0
  261. package/src/news/types.ts +11 -0
  262. package/src/notifications/app-notifier.ts +1 -1
  263. package/src/plugins/auto-update.ts +2 -2
  264. package/src/plugins/builtin/account-management/index.tsx +1 -0
  265. package/src/plugins/builtin/account-management/pane.tsx +9 -8
  266. package/src/plugins/builtin/alerts/alert-engine.ts +29 -19
  267. package/src/plugins/builtin/alerts/calendar-events.ts +378 -0
  268. package/src/plugins/builtin/alerts/cli.ts +485 -76
  269. package/src/plugins/builtin/alerts/command.ts +5 -10
  270. package/src/plugins/builtin/alerts/event-rows.ts +9 -5
  271. package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
  272. package/src/plugins/builtin/alerts/events.ts +107 -5
  273. package/src/plugins/builtin/alerts/fired-log.ts +78 -0
  274. package/src/plugins/builtin/alerts/format.ts +2 -1
  275. package/src/plugins/builtin/alerts/headless.ts +100 -39
  276. package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
  277. package/src/plugins/builtin/alerts/history-rows.ts +89 -0
  278. package/src/plugins/builtin/alerts/index.tsx +45 -18
  279. package/src/plugins/builtin/alerts/iv-level.ts +365 -0
  280. package/src/plugins/builtin/alerts/levels.ts +3 -3
  281. package/src/plugins/builtin/alerts/pane.tsx +97 -29
  282. package/src/plugins/builtin/alerts/price.ts +35 -0
  283. package/src/plugins/builtin/alerts/quotes.ts +24 -0
  284. package/src/plugins/builtin/alerts/research-builder.ts +84 -11
  285. package/src/plugins/builtin/alerts/research-rules.ts +76 -3
  286. package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
  287. package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
  288. package/src/plugins/builtin/alerts/scheduled.ts +188 -29
  289. package/src/plugins/builtin/alerts/storage.ts +13 -10
  290. package/src/plugins/builtin/alerts/targets.ts +12 -3
  291. package/src/plugins/builtin/analytics/index.tsx +8 -2
  292. package/src/plugins/builtin/analytics/metrics.ts +1 -1
  293. package/src/plugins/builtin/analytics/risk-book.ts +215 -0
  294. package/src/plugins/builtin/analytics/risk-client.ts +13 -6
  295. package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
  296. package/src/plugins/builtin/analytics/risk-math.ts +6 -3
  297. package/src/plugins/builtin/analytics/risk-model.ts +297 -104
  298. package/src/plugins/builtin/analytics/risk-options.ts +17 -2
  299. package/src/plugins/builtin/analytics/risk-pane.tsx +97 -36
  300. package/src/plugins/builtin/attention/pane.tsx +6 -2
  301. package/src/plugins/builtin/awards/headless.ts +7 -3
  302. package/src/plugins/builtin/awards/model.ts +18 -0
  303. package/src/plugins/builtin/awards/pane.tsx +6 -3
  304. package/src/plugins/builtin/backtest/headless.ts +3 -3
  305. package/src/plugins/builtin/backtest/rules.ts +41 -5
  306. package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
  307. package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
  308. package/src/plugins/builtin/broker-manager/footer.ts +27 -11
  309. package/src/plugins/builtin/broker-manager/index.tsx +21 -12
  310. package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
  311. package/src/plugins/builtin/broker-manager/model.ts +12 -2
  312. package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
  313. package/src/plugins/builtin/broker-manager/table.ts +28 -12
  314. package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
  315. package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
  316. package/src/plugins/builtin/broker-trading/controller.ts +45 -13
  317. package/src/plugins/builtin/broker-trading/dock.tsx +22 -4
  318. package/src/plugins/builtin/broker-trading/headless.ts +2 -1
  319. package/src/plugins/builtin/broker-trading/index.tsx +7 -1
  320. package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
  321. package/src/plugins/builtin/broker-trading/order-feed.ts +75 -7
  322. package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
  323. package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
  324. package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
  325. package/src/plugins/builtin/broker-trading/pane.tsx +110 -23
  326. package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
  327. package/src/plugins/builtin/broker-trading/ticket.tsx +112 -31
  328. package/src/plugins/builtin/buildout/cells.tsx +4 -0
  329. package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
  330. package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
  331. package/src/plugins/builtin/buildout/pane/index.tsx +25 -12
  332. package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
  333. package/src/plugins/builtin/builtin-plugin-meta.ts +1 -1
  334. package/src/plugins/builtin/catalysts/detail.tsx +3 -2
  335. package/src/plugins/builtin/catalysts/index.tsx +1 -1
  336. package/src/plugins/builtin/catalysts/model.ts +49 -4
  337. package/src/plugins/builtin/catalysts/pane.tsx +6 -8
  338. package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
  339. package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
  340. package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
  341. package/src/plugins/builtin/changelog/index.tsx +1 -0
  342. package/src/plugins/builtin/chart-composer/catalog-inventory.ts +1 -0
  343. package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +2 -1
  344. package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
  345. package/src/plugins/builtin/chart-composer/cli-options.ts +2 -5
  346. package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +2 -1
  347. package/src/plugins/builtin/chart-composer/editor/controller.ts +2 -0
  348. package/src/plugins/builtin/chart-composer/editor.tsx +4 -1
  349. package/src/plugins/builtin/chart-composer/headless-schema.ts +28 -26
  350. package/src/plugins/builtin/chart-composer/headless.ts +253 -35
  351. package/src/plugins/builtin/chart-composer/index.tsx +12 -2
  352. package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
  353. package/src/plugins/builtin/chart-composer/pane.tsx +127 -28
  354. package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
  355. package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
  356. package/src/plugins/builtin/chart-composer/session-history.ts +15 -21
  357. package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
  358. package/src/plugins/builtin/chart-composer/settings.ts +31 -19
  359. package/src/plugins/builtin/chart-composer/use-series-catalog.ts +5 -6
  360. package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
  361. package/src/plugins/builtin/chat/attachments/model.ts +3 -1
  362. package/src/plugins/builtin/chat/content/index.tsx +1 -1
  363. package/src/plugins/builtin/chat/pane-links/open.ts +1 -1
  364. package/src/plugins/builtin/chat/people.ts +1 -1
  365. package/src/plugins/builtin/clinical-trials/client.ts +5 -2
  366. package/src/plugins/builtin/clinical-trials/model.ts +13 -4
  367. package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
  368. package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
  369. package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
  370. package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
  371. package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
  372. package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
  373. package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
  374. package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
  375. package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
  376. package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
  377. package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
  378. package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
  379. package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
  380. package/src/plugins/builtin/commodity-balances/pane.tsx +11 -4
  381. package/src/plugins/builtin/company-attention/app-rank.tsx +7 -5
  382. package/src/plugins/builtin/company-attention/building-model.ts +222 -0
  383. package/src/plugins/builtin/company-attention/building.tsx +172 -0
  384. package/src/plugins/builtin/company-attention/client.ts +117 -1
  385. package/src/plugins/builtin/company-attention/evidence.ts +16 -3
  386. package/src/plugins/builtin/company-attention/headless.ts +101 -5
  387. package/src/plugins/builtin/company-attention/index.tsx +6 -3
  388. package/src/plugins/builtin/company-attention/model.ts +33 -7
  389. package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
  390. package/src/plugins/builtin/company-attention/moves.tsx +159 -0
  391. package/src/plugins/builtin/company-attention/pane.tsx +79 -23
  392. package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
  393. package/src/plugins/builtin/company-attention/signals.tsx +160 -0
  394. package/src/plugins/builtin/company-kpis/headless.ts +3 -2
  395. package/src/plugins/builtin/company-kpis/model.ts +2 -2
  396. package/src/plugins/builtin/company-kpis/pane.tsx +1 -1
  397. package/src/plugins/builtin/composite-plugins.ts +2 -1
  398. package/src/plugins/builtin/congress-trades/headless.ts +1 -1
  399. package/src/plugins/builtin/connections/index.ts +1 -0
  400. package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
  401. package/src/plugins/builtin/correlation/headless.ts +5 -3
  402. package/src/plugins/builtin/cot/headless.ts +28 -6
  403. package/src/plugins/builtin/cot/model.ts +12 -0
  404. package/src/plugins/builtin/cot/pane.tsx +3 -2
  405. package/src/plugins/builtin/cpi/headless.ts +5 -1
  406. package/src/plugins/builtin/cpi/pane.tsx +11 -9
  407. package/src/plugins/builtin/credit-boards/model.ts +2 -0
  408. package/src/plugins/builtin/credit-documents/headless.ts +1 -1
  409. package/src/plugins/builtin/crypto-board/client.ts +86 -0
  410. package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
  411. package/src/plugins/builtin/crypto-board/defi.ts +239 -0
  412. package/src/plugins/builtin/crypto-board/headless.ts +117 -6
  413. package/src/plugins/builtin/crypto-board/index.tsx +8 -3
  414. package/src/plugins/builtin/crypto-board/model.ts +40 -8
  415. package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
  416. package/src/plugins/builtin/crypto-board/series.ts +19 -1
  417. package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
  418. package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
  419. package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
  420. package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
  421. package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
  422. package/src/plugins/builtin/debug/index.tsx +1 -0
  423. package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
  424. package/src/plugins/builtin/docs/index.tsx +1 -1
  425. package/src/plugins/builtin/docs/pane.tsx +2 -2
  426. package/src/plugins/builtin/docs/targets.ts +1 -1
  427. package/src/plugins/builtin/doe/client.ts +5 -1
  428. package/src/plugins/builtin/doe/headless.ts +12 -6
  429. package/src/plugins/builtin/doe/model.ts +43 -6
  430. package/src/plugins/builtin/doe/pane.tsx +18 -11
  431. package/src/plugins/builtin/earnings/board-model.ts +13 -6
  432. package/src/plugins/builtin/earnings/board-table.ts +4 -1
  433. package/src/plugins/builtin/earnings/board.tsx +253 -50
  434. package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
  435. package/src/plugins/builtin/earnings/calendar.tsx +338 -0
  436. package/src/plugins/builtin/earnings/client.ts +4 -3
  437. package/src/plugins/builtin/earnings/headless.ts +53 -15
  438. package/src/plugins/builtin/earnings/history-model.ts +53 -36
  439. package/src/plugins/builtin/earnings/index.tsx +15 -22
  440. package/src/plugins/builtin/earnings/model.ts +17 -12
  441. package/src/plugins/builtin/earnings/scope.ts +89 -0
  442. package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
  443. package/src/plugins/builtin/earnings-calls/data.ts +146 -2
  444. package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
  445. package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
  446. package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
  447. package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
  448. package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
  449. package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
  450. package/src/plugins/builtin/econ/calendar-model.ts +132 -20
  451. package/src/plugins/builtin/econ/detail-view.tsx +48 -10
  452. package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
  453. package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
  454. package/src/plugins/builtin/econ/index.tsx +112 -25
  455. package/src/plugins/builtin/econ/print-watch.ts +2 -1
  456. package/src/plugins/builtin/econ/types.ts +32 -1
  457. package/src/plugins/builtin/econ-statistics/client.ts +16 -3
  458. package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
  459. package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
  460. package/src/plugins/builtin/econ-statistics/headless.ts +13 -2
  461. package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
  462. package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
  463. package/src/plugins/builtin/econ-statistics/stats.ts +103 -0
  464. package/src/plugins/builtin/econ-statistics/view.ts +16 -1
  465. package/src/plugins/builtin/equity-screener/client.ts +21 -3
  466. package/src/plugins/builtin/equity-screener/headless.ts +68 -6
  467. package/src/plugins/builtin/equity-screener/live.ts +1 -1
  468. package/src/plugins/builtin/equity-screener/model.ts +6 -0
  469. package/src/plugins/builtin/equity-screener/pane.tsx +45 -10
  470. package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
  471. package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
  472. package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
  473. package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
  474. package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
  475. package/src/plugins/builtin/exposure/headless.ts +51 -6
  476. package/src/plugins/builtin/exposure/index.tsx +28 -2
  477. package/src/plugins/builtin/exposure/model.ts +7 -0
  478. package/src/plugins/builtin/exposure/pane.tsx +6 -1
  479. package/src/plugins/builtin/fear-greed/index.tsx +1 -1
  480. package/src/plugins/builtin/filing-events/index.tsx +1 -1
  481. package/src/plugins/builtin/futures/model.ts +10 -9
  482. package/src/plugins/builtin/futures/returns.ts +8 -36
  483. package/src/plugins/builtin/futures/table.tsx +1 -1
  484. package/src/plugins/builtin/futures-curve/client.ts +40 -9
  485. package/src/plugins/builtin/futures-curve/headless.ts +39 -17
  486. package/src/plugins/builtin/futures-curve/model.ts +258 -69
  487. package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
  488. package/src/plugins/builtin/fx-matrix/client.ts +15 -8
  489. package/src/plugins/builtin/fx-matrix/headless.ts +32 -14
  490. package/src/plugins/builtin/fx-matrix/index.tsx +13 -11
  491. package/src/plugins/builtin/fx-matrix/live-legs.ts +22 -0
  492. package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
  493. package/src/plugins/builtin/gpu/headless.ts +9 -4
  494. package/src/plugins/builtin/help/index.tsx +13 -3
  495. package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
  496. package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
  497. package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
  498. package/src/plugins/builtin/holders/client.ts +13 -1
  499. package/src/plugins/builtin/holders/format.ts +28 -17
  500. package/src/plugins/builtin/holders/headless.ts +46 -7
  501. package/src/plugins/builtin/holders/index-holders.ts +264 -0
  502. package/src/plugins/builtin/holders/pane.tsx +79 -15
  503. package/src/plugins/builtin/holders/report-rows.ts +35 -7
  504. package/src/plugins/builtin/holders/table-model.ts +2 -1
  505. package/src/plugins/builtin/holders/treemap.tsx +2 -2
  506. package/src/plugins/builtin/insider/headless.ts +1 -1
  507. package/src/plugins/builtin/insider/signals-client.ts +1 -1
  508. package/src/plugins/builtin/insider/signals.tsx +1 -1
  509. package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
  510. package/src/plugins/builtin/iv-history/client.ts +20 -0
  511. package/src/plugins/builtin/iv-history/headless.ts +4 -4
  512. package/src/plugins/builtin/iv-history/index.tsx +1 -1
  513. package/src/plugins/builtin/iv-history/model.ts +13 -4
  514. package/src/plugins/builtin/iv-history/series.ts +3 -1
  515. package/src/plugins/builtin/jobs/lock-note.ts +1 -1
  516. package/src/plugins/builtin/jobs/model.ts +4 -15
  517. package/src/plugins/builtin/jobs/pane.tsx +7 -5
  518. package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
  519. package/src/plugins/builtin/jodi/pane.tsx +10 -4
  520. package/src/plugins/builtin/layout-manager/index.tsx +1 -0
  521. package/src/plugins/builtin/macro-day/headless.ts +20 -7
  522. package/src/plugins/builtin/macro-day/index.tsx +3 -2
  523. package/src/plugins/builtin/macro-day/model.ts +29 -8
  524. package/src/plugins/builtin/macro-day/pane.tsx +46 -10
  525. package/src/plugins/builtin/macro-day/releases.ts +55 -13
  526. package/src/plugins/builtin/market-heatmap/data.ts +9 -2
  527. package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
  528. package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
  529. package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
  530. package/src/plugins/builtin/market-heatmap/model.ts +10 -7
  531. package/src/plugins/builtin/market-movers/client.ts +33 -19
  532. package/src/plugins/builtin/market-movers/headless.ts +8 -2
  533. package/src/plugins/builtin/market-movers/index.tsx +16 -10
  534. package/src/plugins/builtin/market-movers/screener.ts +29 -8
  535. package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
  536. package/src/plugins/builtin/market-movers/session-table.ts +4 -2
  537. package/src/plugins/builtin/market-movers/table.ts +4 -1
  538. package/src/plugins/builtin/market-valuation/headless.ts +2 -0
  539. package/src/plugins/builtin/market-valuation/view.ts +5 -0
  540. package/src/plugins/builtin/members/headless.ts +6 -5
  541. package/src/plugins/builtin/members/pane.tsx +11 -4
  542. package/src/plugins/builtin/mna/client.ts +1 -0
  543. package/src/plugins/builtin/mna/detail.tsx +20 -32
  544. package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
  545. package/src/plugins/builtin/mna/distress/model.ts +3 -2
  546. package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
  547. package/src/plugins/builtin/mna/headless.ts +6 -13
  548. package/src/plugins/builtin/mna/model.ts +93 -15
  549. package/src/plugins/builtin/mna/pane.tsx +5 -4
  550. package/src/plugins/builtin/news/headless.ts +12 -6
  551. package/src/plugins/builtin/news/index.tsx +10 -1
  552. package/src/plugins/builtin/news/wire/index.tsx +3 -2
  553. package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
  554. package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
  555. package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
  556. package/src/plugins/builtin/notes/cli.ts +49 -14
  557. package/src/plugins/builtin/openfda/pane.tsx +1 -1
  558. package/src/plugins/builtin/options/carry.ts +2 -2
  559. package/src/plugins/builtin/options/index.tsx +1 -1
  560. package/src/plugins/builtin/options/view.tsx +10 -10
  561. package/src/plugins/builtin/options-calculator/headless.ts +46 -7
  562. package/src/plugins/builtin/options-scenario/client.ts +123 -28
  563. package/src/plugins/builtin/options-scenario/collar.ts +8 -6
  564. package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
  565. package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
  566. package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
  567. package/src/plugins/builtin/options-scenario/csp.ts +101 -21
  568. package/src/plugins/builtin/options-scenario/headless.ts +36 -15
  569. package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
  570. package/src/plugins/builtin/options-scenario/index.tsx +28 -3
  571. package/src/plugins/builtin/options-scenario/model.ts +13 -0
  572. package/src/plugins/builtin/options-scenario/pane.tsx +9 -5
  573. package/src/plugins/builtin/perps/equity-row.tsx +11 -3
  574. package/src/plugins/builtin/perps/freshness.ts +8 -5
  575. package/src/plugins/builtin/perps/headless.ts +3 -1
  576. package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
  577. package/src/plugins/builtin/perps/live-rows.ts +161 -0
  578. package/src/plugins/builtin/perps/markets-section.tsx +154 -0
  579. package/src/plugins/builtin/perps/pane.tsx +36 -17
  580. package/src/plugins/builtin/perps/venue-markets.ts +96 -0
  581. package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
  582. package/src/plugins/builtin/plugin-marketplace/pane.tsx +143 -59
  583. package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +72 -24
  584. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
  585. package/src/plugins/builtin/portfolio-list/cli/render.ts +49 -20
  586. package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
  587. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
  588. package/src/plugins/builtin/portfolio-list/headless.ts +6 -3
  589. package/src/plugins/builtin/portfolio-list/income.ts +13 -2
  590. package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
  591. package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
  592. package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
  593. package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
  594. package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
  595. package/src/plugins/builtin/power/client.ts +4 -1
  596. package/src/plugins/builtin/power/evidence.ts +22 -7
  597. package/src/plugins/builtin/power/gas.tsx +5 -1
  598. package/src/plugins/builtin/power/pane.tsx +8 -1
  599. package/src/plugins/builtin/power/prices.tsx +10 -3
  600. package/src/plugins/builtin/research/analyst-headless.ts +25 -8
  601. package/src/plugins/builtin/research/analyst-model.ts +68 -3
  602. package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
  603. package/src/plugins/builtin/research/event-model.ts +3 -1
  604. package/src/plugins/builtin/research/event-sources.ts +12 -4
  605. package/src/plugins/builtin/research/index.tsx +2 -1
  606. package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
  607. package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
  608. package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
  609. package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
  610. package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
  611. package/src/plugins/builtin/research/relative-valuation-pane.tsx +76 -9
  612. package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
  613. package/src/plugins/builtin/reverse-dcf/model.ts +6 -2
  614. package/src/plugins/builtin/risk-factors/index.tsx +2 -2
  615. package/src/plugins/builtin/scanner/lock-note.ts +1 -1
  616. package/src/plugins/builtin/sec/forms.ts +13 -0
  617. package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
  618. package/src/plugins/builtin/sec/fund-facts.ts +68 -8
  619. package/src/plugins/builtin/sec/headless.ts +85 -8
  620. package/src/plugins/builtin/sec/index.tsx +58 -12
  621. package/src/plugins/builtin/sectors/client.ts +2 -1
  622. package/src/plugins/builtin/sectors/sector-model.ts +11 -15
  623. package/src/plugins/builtin/series-inventory.ts +2 -0
  624. package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
  625. package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
  626. package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
  627. package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
  628. package/src/plugins/builtin/shared/earnings-report.ts +3 -3
  629. package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
  630. package/src/plugins/builtin/shared/job-posting.ts +129 -0
  631. package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
  632. package/src/plugins/builtin/shared/report-freshness.ts +3 -0
  633. package/src/plugins/builtin/shared/research-trading.tsx +21 -0
  634. package/src/plugins/builtin/shared/series-cache.ts +2 -0
  635. package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
  636. package/src/plugins/builtin/short-interest/client.ts +2 -0
  637. package/src/plugins/builtin/short-interest/headless.ts +41 -12
  638. package/src/plugins/builtin/short-interest/index.tsx +23 -1
  639. package/src/plugins/builtin/short-interest/model.ts +70 -19
  640. package/src/plugins/builtin/short-interest/pane.tsx +19 -2
  641. package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
  642. package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
  643. package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
  644. package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
  645. package/src/plugins/builtin/short-interest/schedule.ts +35 -2
  646. package/src/plugins/builtin/short-interest/surface.tsx +11 -4
  647. package/src/plugins/builtin/short-interest/types.ts +9 -0
  648. package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
  649. package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
  650. package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
  651. package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
  652. package/src/plugins/builtin/supply-chain/model.ts +51 -3
  653. package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
  654. package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
  655. package/src/plugins/builtin/themes/headless.ts +8 -5
  656. package/src/plugins/builtin/themes/model.ts +14 -4
  657. package/src/plugins/builtin/themes/pane.tsx +24 -5
  658. package/src/plugins/builtin/thirteenf/headless.ts +5 -5
  659. package/src/plugins/builtin/thirteenf/signals.ts +3 -1
  660. package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
  661. package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
  662. package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
  663. package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
  664. package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
  665. package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
  666. package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
  667. package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
  668. package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
  669. package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
  670. package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
  671. package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
  672. package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
  673. package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
  674. package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
  675. package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
  676. package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
  677. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
  678. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
  679. package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
  680. package/src/plugins/builtin/ticker-detail/quote-footer.ts +8 -3
  681. package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
  682. package/src/plugins/builtin/vol-surface/client.ts +5 -4
  683. package/src/plugins/builtin/vol-surface/headless.ts +12 -3
  684. package/src/plugins/builtin/vol-surface/model.ts +4 -2
  685. package/src/plugins/builtin/volatility/model.ts +5 -10
  686. package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
  687. package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
  688. package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
  689. package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
  690. package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
  691. package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
  692. package/src/plugins/builtin/world-venue-map/index.ts +3 -26
  693. package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
  694. package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
  695. package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
  696. package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
  697. package/src/plugins/builtin/yield-curve/client.ts +25 -0
  698. package/src/plugins/builtin/yield-curve/curves.ts +7 -4
  699. package/src/plugins/builtin/yield-curve/headless.ts +38 -4
  700. package/src/plugins/builtin/yield-curve/history.ts +4 -3
  701. package/src/plugins/builtin/yield-curve/index.tsx +12 -6
  702. package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
  703. package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
  704. package/src/plugins/bundle.ts +1 -1
  705. package/src/plugins/catalog-browser.ts +2 -1
  706. package/src/plugins/compat.ts +3 -3
  707. package/src/plugins/dependencies.ts +75 -14
  708. package/src/plugins/extracted-plugins.ts +132 -34
  709. package/src/plugins/host-link.ts +149 -34
  710. package/src/plugins/installer.ts +35 -10
  711. package/src/plugins/loader.ts +206 -38
  712. package/src/plugins/manager-node.ts +2 -2
  713. package/src/plugins/marketplace/deactivation.ts +22 -0
  714. package/src/plugins/marketplace/model.ts +2 -2
  715. package/src/plugins/marketplace/packs.ts +1 -1
  716. package/src/plugins/ownership.ts +1 -1
  717. package/src/plugins/peer-retry.ts +155 -0
  718. package/src/plugins/registry/contributions.ts +3 -1
  719. package/src/plugins/registry/index.ts +4 -3
  720. package/src/plugins/registry/plugin-state.ts +3 -0
  721. package/src/plugins/seed-notice.ts +20 -0
  722. package/src/plugins/shortcut-argument.ts +39 -0
  723. package/src/portfolio/allocation.ts +1 -1
  724. package/src/portfolio/collection-name.ts +31 -0
  725. package/src/portfolio/column-values.ts +10 -8
  726. package/src/portfolio/cost-fx.ts +296 -19
  727. package/src/portfolio/manual-lots.ts +75 -0
  728. package/src/portfolio/mutations.ts +60 -22
  729. package/src/portfolio/suffixed-listings.ts +209 -0
  730. package/src/portfolio/totals-currency.ts +24 -0
  731. package/src/public/__snapshots__/public-api.test.ts.snap +14 -0
  732. package/src/public/time-series.ts +11 -8
  733. package/src/remote/schema.ts +1 -1
  734. package/src/renderers/browser/config-host.ts +3 -0
  735. package/src/renderers/browser/main.tsx +23 -3
  736. package/src/renderers/dom/boot-frame-page.ts +187 -0
  737. package/src/renderers/dom/boot-frame.ts +237 -0
  738. package/src/renderers/dom/build-assets.ts +46 -8
  739. package/src/renderers/dom/dom-ui-host.tsx +4 -29
  740. package/src/renderers/dom/host/ascii-text.ts +16 -2
  741. package/src/renderers/dom/host/box.tsx +43 -2
  742. package/src/renderers/dom/host/chart-surface.tsx +2 -0
  743. package/src/renderers/dom/host/hls.chunk.ts +3 -0
  744. package/src/renderers/dom/host/image-surface.tsx +49 -0
  745. package/src/renderers/dom/host/media-surface.tsx +24 -18
  746. package/src/renderers/dom/host/mouse.ts +30 -0
  747. package/src/renderers/dom/host/size-observer.ts +1 -1
  748. package/src/renderers/dom/host/style.ts +1 -1
  749. package/src/renderers/dom/styles.css +76 -0
  750. package/src/renderers/dom/test-utils.tsx +2 -1
  751. package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
  752. package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
  753. package/src/renderers/electrobun/bun/desktop/backend.ts +46 -3
  754. package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
  755. package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
  756. package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
  757. package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
  758. package/src/renderers/electrobun/bun/index.ts +11 -1
  759. package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
  760. package/src/renderers/electrobun/bun/window/create.ts +4 -1
  761. package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
  762. package/src/renderers/electrobun/shared/protocol.ts +6 -1
  763. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
  764. package/src/renderers/electrobun/view/config-host.ts +3 -0
  765. package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
  766. package/src/renderers/electrobun/view/main.tsx +30 -4
  767. package/src/renderers/electrobun/view/news-source.ts +5 -5
  768. package/src/renderers/electrobun/view/remote/asset-data-client.ts +1 -1
  769. package/src/renderers/electrobun/view/ui-host.tsx +1 -1
  770. package/src/renderers/opentui/browser-open.ts +88 -0
  771. package/src/renderers/opentui/host.tsx +5 -14
  772. package/src/renderers/opentui/image/loader.ts +3 -2
  773. package/src/renderers/opentui/native-smoke.ts +10 -1
  774. package/src/renderers/opentui/pane-image/index.ts +2 -1
  775. package/src/renderers/opentui/render-lib.ts +253 -0
  776. package/src/renderers/opentui/render-timing-smoke.ts +1 -1
  777. package/src/renderers/opentui/start.tsx +1 -1
  778. package/src/renderers/share/layout-view.tsx +2 -2
  779. package/src/renderers/share/main.tsx +4 -4
  780. package/src/renderers/share/view.tsx +1 -1
  781. package/src/series/resolve.ts +22 -6
  782. package/src/series/standalone.ts +30 -2
  783. package/src/series/types.ts +8 -1
  784. package/src/shares/api.ts +4 -1
  785. package/src/shares/pane.ts +1 -1
  786. package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
  787. package/src/sources/gloomberb-cloud/index.ts +32 -16
  788. package/src/sources/gloomberb-cloud/news.ts +39 -0
  789. package/src/sources/gloomberb-cloud/normalizers.ts +14 -1
  790. package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
  791. package/src/sources/listing-symbols.ts +37 -0
  792. package/src/sources/provider-errors.ts +16 -2
  793. package/src/sources/provider-router/financial-routes.ts +21 -3
  794. package/src/sources/provider-router/financials.ts +15 -2
  795. package/src/sources/provider-router/history.ts +30 -8
  796. package/src/sources/provider-router/primary.ts +1 -1
  797. package/src/state/app/bootstrap.ts +23 -0
  798. package/src/state/hooks/inline-tickers.ts +30 -5
  799. package/src/sync/controller.ts +1 -1
  800. package/src/sync/core-contributors.ts +46 -14
  801. package/src/team/collections-sync.ts +2 -1
  802. package/src/team/collections.ts +178 -17
  803. package/src/telemetry/crash-reports.ts +17 -4
  804. package/src/test-support/builtin-panes.ts +1 -1
  805. package/src/theme/colors.ts +3 -30
  806. package/src/theme/ui-tokens.ts +37 -1
  807. package/src/tickers/company-name-listing.ts +210 -33
  808. package/src/tickers/index-roots.ts +47 -0
  809. package/src/tickers/instrument-label.ts +5 -1
  810. package/src/tickers/metadata.ts +10 -0
  811. package/src/tickers/perpetual-listing.ts +5 -2
  812. package/src/tickers/search/home-listing.ts +75 -0
  813. package/src/tickers/search/index.ts +76 -27
  814. package/src/tickers/search/ranking.ts +54 -4
  815. package/src/tickers/search/upsert.ts +29 -0
  816. package/src/tickers/terminal-codes.ts +416 -40
  817. package/src/time-series/bar-aggregation.ts +243 -0
  818. package/src/time-series/base-series.ts +307 -0
  819. package/src/time-series/chart-bounds.ts +349 -0
  820. package/src/time-series/chart-seed.ts +142 -0
  821. package/src/time-series/economic.ts +5 -0
  822. package/src/time-series/fundamentals.ts +18 -3
  823. package/src/time-series/history-acquisition.ts +499 -0
  824. package/src/time-series/leverage.ts +100 -0
  825. package/src/time-series/market-resolution.ts +4 -2
  826. package/src/time-series/market.ts +2 -1
  827. package/src/time-series/price-comparison.ts +175 -30
  828. package/src/time-series/range.ts +9 -1
  829. package/src/time-series/resolution.ts +174 -16
  830. package/src/time-series/resolve-context.ts +157 -0
  831. package/src/time-series/resolve.ts +126 -1577
  832. package/src/time-series/series-name.ts +38 -0
  833. package/src/time-series/series-presentation.ts +208 -0
  834. package/src/time-series/spec.ts +11 -6
  835. package/src/time-series/studies.ts +109 -12
  836. package/src/time-series/tail-reconcile.ts +121 -0
  837. package/src/time-series/types.ts +29 -2
  838. package/src/time-series/use-chart-resolution.ts +4 -5
  839. package/src/types/broker.ts +10 -0
  840. package/src/types/config.ts +14 -0
  841. package/src/types/data-provider.ts +14 -0
  842. package/src/types/exchange-rate.ts +6 -0
  843. package/src/types/financials.ts +104 -7
  844. package/src/types/headless.ts +76 -6
  845. package/src/types/instrument.ts +3 -0
  846. package/src/types/plugin.ts +65 -8
  847. package/src/types/price-history.ts +2 -0
  848. package/src/types/ticker.ts +13 -0
  849. package/src/types/trading.ts +59 -1
  850. package/src/ui/ascii-font.ts +13 -1
  851. package/src/ui/host.tsx +6 -1
  852. package/src/updater/command-names.ts +175 -0
  853. package/src/updater/index.ts +10 -5
  854. package/src/utils/calendar-date.ts +32 -15
  855. package/src/utils/cash-runway.ts +241 -0
  856. package/src/utils/central-banks.ts +42 -0
  857. package/src/utils/cli-output.ts +259 -80
  858. package/src/utils/contract-month.ts +16 -0
  859. package/src/utils/crypto-pair.ts +61 -3
  860. package/src/utils/currency-units.ts +29 -0
  861. package/src/utils/datetime-format.ts +10 -0
  862. package/src/utils/debug-log.ts +1 -1
  863. package/src/utils/decimal-comma.ts +39 -6
  864. package/src/utils/exchange-announcements.ts +71 -0
  865. package/src/utils/exchange-rate-snapshot.ts +10 -0
  866. package/src/utils/financial-statements.ts +83 -4
  867. package/src/utils/format.ts +34 -16
  868. package/src/utils/fundamentals.ts +150 -34
  869. package/src/utils/fx-market-hours.ts +10 -1
  870. package/src/utils/latest-financial-period.ts +8 -0
  871. package/src/utils/linux-libc.ts +54 -0
  872. package/src/utils/market-capitalization.ts +111 -15
  873. package/src/utils/max-drawdown.ts +64 -0
  874. package/src/utils/network-failure.ts +83 -0
  875. package/src/utils/option-expiry.ts +139 -7
  876. package/src/utils/price-earnings.ts +11 -5
  877. package/src/utils/price-history.ts +18 -8
  878. package/src/utils/price-window.ts +131 -0
  879. package/src/utils/release-date.ts +47 -0
  880. package/src/utils/sec.ts +3 -0
  881. package/src/utils/throttled-fetch.ts +11 -4
  882. package/src/utils/trailing-eps.ts +67 -0
  883. package/src/utils/typed-text.ts +21 -0
  884. package/src/utils/utc-time.ts +24 -1
  885. package/src/version.ts +6 -0
  886. package/src/cli/pane-functions/screenshot.ts +0 -2122
@@ -1,16 +1,27 @@
1
- import { useCallback, useEffect, useId, useMemo, useRef, useState, useSyncExternalStore } from "react";
1
+ import { useCallback, useEffect, useId, useMemo, useRef, useState, useSyncExternalStore, type ReactNode } from "react";
2
2
  import { useCompositeChartKeyboard } from "./use-composite-chart-keyboard";
3
3
  import { useCompositeViewport } from "./use-composite-viewport";
4
4
  import { CompositePanelSurface } from "./panel-surface";
5
5
  import { MINIMUM_AXIS_LABEL_WIDTH, compositeAxisLabelWidth } from "./panel-labels";
6
- import { isVerticalWheelDirection } from "./panel-gestures";
6
+ import { AXIS_DOUBLE_PRESS_MS, isVerticalWheelDirection } from "./panel-gestures";
7
7
  import { type ChartToolSpan, CHART_DRAWING_COLORS, isDrawingTool, type ChartDrawing } from "./tools";
8
8
  import { ChartDrawingStore, NO_DRAWINGS } from "./drawing-store";
9
9
  import { CompositeLegend } from "./legend";
10
10
  import { ChartToolbar, CHART_TOOLBAR_WIDTH } from "./toolbar";
11
11
  import { AsciiText, Box, ChartSurface, Text, useUiCapabilities, type BoxRenderable } from "../../../ui";
12
+ import { Button } from "../../ui/button";
12
13
  import { useLiveStretch } from "../../../ui/live-stretch";
13
- import { useOptionalPaneInstanceId } from "../../../state/app/context";
14
+ import { useOptionalPaneInstanceId, usePaneSettingValue } from "../../../state/app/context";
15
+ import {
16
+ CHART_LAYOUT_SETTING_KEY,
17
+ NO_CHART_LAYOUT,
18
+ draggedPanelWeights,
19
+ minimumPanelRows,
20
+ parseChartLayoutPrefs,
21
+ patchChartLayout,
22
+ stepTopPanel,
23
+ type ChartLayoutPrefs,
24
+ } from "./chart-layout";
14
25
  import { usePaneFocused } from "../../../state/app/activity";
15
26
  import { useTabCursorLink } from "../../../state/app/tab-cursor";
16
27
  import { useThemeColors, useThemeId } from "../../../theme/theme-context";
@@ -27,7 +38,14 @@ import { useChartViewResetListener } from "../core/view-reset";
27
38
  import { useShowChartTextFallback } from "../native/use-chart-text-fallback";
28
39
  import { StaticXAxisLabels, StaticXMarkerLabels, StaticXMarkerOverlay } from "./axis-overlays";
29
40
  import { formatCompositeCursorAxisDate } from "./format";
30
- import { resolveCompositeWheelPan, resolveCompositeWheelZoom } from "./interactions";
41
+ import {
42
+ resolveCompositeWheelPan,
43
+ resolveCompositeWheelZoom,
44
+ type CompositeNavigationFrame,
45
+ type CompositeViewportRange,
46
+ } from "./interactions";
47
+ import { NO_VALUE_SCALES, resolveAxisDragSpanFactor } from "./value-scale";
48
+ import { useCompositeValueScales } from "./use-composite-value-scales";
31
49
  import { COMPOSITE_RIGHT_OFFSET_RATIO } from "./time-scale";
32
50
  import {
33
51
  allocateCompositePanelHeights,
@@ -81,6 +99,10 @@ const holdsNothing = () => false;
81
99
  */
82
100
  const DESKTOP_FULL_ROW = { width: "100%" } as const;
83
101
  const DESKTOP_PLOT_COLUMN = { flex: "1 1 0px", width: "auto", minWidth: 0 } as const;
102
+ /** The button on a panel that has the whole plot. */
103
+ const RESTORE_PANELS_LABEL = "All panels";
104
+ /** The time axis row where a drag on it zooms time. */
105
+ const TIME_AXIS_ROW = { ...DESKTOP_FULL_ROW, cursor: "ew-resize" } as const;
84
106
 
85
107
  /** Default-palette series in the theme's own palette, where it has one; the same list otherwise. */
86
108
  function useThemedSeriesList(list: ResolvedSeries[], themeId: string): ResolvedSeries[];
@@ -106,11 +128,42 @@ function centeredLines(text: string, width: number): string[] {
106
128
  return lines;
107
129
  }
108
130
 
131
+ type ChartLayoutUpdate = (update: (layout: ChartLayoutPrefs) => ChartLayoutPrefs) => void;
132
+ type ChartLayoutChild = (layout: ChartLayoutPrefs, update: ChartLayoutUpdate) => ReactNode;
133
+
134
+ /** A chart in a pane keeps its layout in the pane's settings, read as it renders so it never paints twice. */
135
+ function PaneChartLayout({ paneInstanceId, children }: { paneInstanceId: string; children: ChartLayoutChild }) {
136
+ const [stored, setStored] = usePaneSettingValue<unknown>(CHART_LAYOUT_SETTING_KEY, undefined, paneInstanceId);
137
+ const layout = useMemo(() => parseChartLayoutPrefs(stored), [stored]);
138
+ const update = useCallback<ChartLayoutUpdate>((change) => {
139
+ setStored((current: unknown) => {
140
+ const previous = parseChartLayoutPrefs(current);
141
+ const next = change(previous);
142
+ if (next === previous) return current;
143
+ return next === NO_CHART_LAYOUT ? undefined : next;
144
+ });
145
+ }, [setStored]);
146
+ return <>{children(layout, update)}</>;
147
+ }
148
+
149
+ /** A chart outside a pane (a share page) keeps its layout while it is mounted. */
150
+ function LocalChartLayout({ children }: { children: ChartLayoutChild }) {
151
+ const [layout, setLayout] = useState<ChartLayoutPrefs>(NO_CHART_LAYOUT);
152
+ const update = useCallback<ChartLayoutUpdate>((change) => setLayout(change), []);
153
+ return <>{children(layout, update)}</>;
154
+ }
155
+
109
156
  export function CompositeChart(props: CompositeChartProps) {
110
157
  const themeId = useThemeId();
111
158
  const series = useThemedSeriesList(props.series, themeId);
112
159
  const legendSeries = useThemedSeriesList(props.legendSeries, themeId);
113
- return <ThemedCompositeChart {...props} series={series} legendSeries={legendSeries} />;
160
+ const paneInstanceId = useOptionalPaneInstanceId();
161
+ const chart: ChartLayoutChild = (layout, update) => (
162
+ <ThemedCompositeChart {...props} series={series} legendSeries={legendSeries} chartLayout={layout} onChartLayoutChange={update} />
163
+ );
164
+ return paneInstanceId
165
+ ? <PaneChartLayout paneInstanceId={paneInstanceId}>{chart}</PaneChartLayout>
166
+ : <LocalChartLayout>{chart}</LocalChartLayout>;
114
167
  }
115
168
 
116
169
  function ThemedCompositeChart({
@@ -149,8 +202,11 @@ function ThemedCompositeChart({
149
202
  onToggleSeries,
150
203
  isSeriesToggleable,
151
204
  timePick,
205
+ pricePick,
152
206
  levels,
153
- }: CompositeChartProps) {
207
+ chartLayout,
208
+ onChartLayoutChange,
209
+ }: CompositeChartProps & { chartLayout: ChartLayoutPrefs; onChartLayoutChange: ChartLayoutUpdate }) {
154
210
  const activeThemeColors = useThemeColors();
155
211
  const { cellWidthPx = 8, cellHeightPx = 18, pixelRatio = 1, fractionalViewport = false } = useUiCapabilities();
156
212
  const isDesktopWeb = useUiCapabilities().nativePaneChrome === true;
@@ -235,14 +291,24 @@ function ThemedCompositeChart({
235
291
  return assignSeriesLineCues(cueSourceRef.current);
236
292
  }, [cueKey]);
237
293
  const {
238
- navigationFrame, activeUserViewport, effectiveViewport,
294
+ navigationFrame, activeUserViewport, effectiveViewport, authoredViewportChanged, authoredGeneration,
239
295
  panViewport, panViewportByRatio, zoomViewport, setViewportRange, resetViewport,
240
296
  } = useCompositeViewport({
241
297
  viewport, viewportResetKey, visibleSeries, marketTimelineSeries,
242
298
  allowHistoricalBackfill, onViewportChange,
243
299
  });
300
+ // Values scaled by hand belong to the view they were scaled in: a new
301
+ // authored view (another range, another listing) fits them again.
302
+ const { valueScales: heldValueScales, setValueScale, resetPanelValueScale, resetValueScales } = useCompositeValueScales(authoredGeneration);
303
+ const valueScales = authoredViewportChanged ? NO_VALUE_SCALES : heldValueScales;
304
+ const scaledByHand = valueScales !== NO_VALUE_SCALES && Object.keys(valueScales).length > 0;
305
+ // `0`, Reset Zoom and choosing the range again put both axes back.
306
+ const resetView = useCallback(() => {
307
+ resetViewport();
308
+ resetValueScales();
309
+ }, [resetValueScales, resetViewport]);
244
310
  // The pane's range control asks for this when its selected range is chosen again.
245
- useChartViewResetListener(resetViewport, interactive && navigable);
311
+ useChartViewResetListener(resetView, interactive);
246
312
  const timeAxisRows = showTimeAxis ? 1 : 0;
247
313
  const xMarkers = xAxis?.markers ?? NO_X_MARKERS;
248
314
  const xMarkerRows = xMarkers.some((marker) => marker.label) ? 1 : 0;
@@ -284,6 +350,7 @@ function ThemedCompositeChart({
284
350
  clipToViewport,
285
351
  timelineSeries: marketTimelineSeries,
286
352
  rightOffsetRatio,
353
+ valueScales,
287
354
  });
288
355
  }, [
289
356
  clipToViewport,
@@ -294,6 +361,7 @@ function ThemedCompositeChart({
294
361
  panelSeries,
295
362
  panels,
296
363
  rightOffsetRatio,
364
+ valueScales,
297
365
  ]);
298
366
  // Gutters follow the axes the scene actually built. Reading the series list
299
367
  // instead drops a gutter the moment its series has no observation in view,
@@ -314,22 +382,43 @@ function ThemedCompositeChart({
314
382
  const availableAxisWidth = axisCount > 0
315
383
  ? Math.max(0, Math.floor((totalWidth - minimumPlotWidth) / axisCount) - 1)
316
384
  : 0;
385
+ // Heights a drag is setting, shown before they are kept.
386
+ const [draftPanelWeights, setDraftPanelWeights] = useState<Readonly<Record<string, number>> | null>(null);
387
+ const panelWeights = draftPanelWeights ?? chartLayout.panelWeights;
388
+ useEffect(() => setDraftPanelWeights(null), [chartLayout.panelWeights]);
389
+ // A panel given the whole plot, while the chart still has it and another.
390
+ const maximizedPanelId = projectedScene && projectedScene.panels.length > 1
391
+ && projectedScene.panels.some((panel) => panel.id === chartLayout.maximizedPanelId)
392
+ ? chartLayout.maximizedPanelId ?? null
393
+ : null;
317
394
  const layoutPanels = useMemo<CompositePanelScene[] | null>(() => {
318
395
  if (!projectedScene) return null;
319
396
  const panelSpecById = new Map(panels.map((panel) => [panel.id, panel] as const));
397
+ const shown = maximizedPanelId
398
+ ? projectedScene.panels.filter((panel) => panel.id === maximizedPanelId)
399
+ : projectedScene.panels;
320
400
  const panelHeights = allocateCompositePanelHeights(
321
- projectedScene.panels.map((panel) => ({
401
+ shown.map((panel) => ({
322
402
  id: panel.id,
323
- height: panelSpecById.get(panel.id)?.height,
403
+ height: panelWeights?.[panel.id] ?? panelSpecById.get(panel.id)?.height,
324
404
  })),
325
405
  plotHeight,
326
406
  );
327
407
  // Terminal labels snap to rows; a fractional viewport places them exactly.
328
- return projectedScene.panels.map((panel) => {
408
+ return shown.map((panel) => {
329
409
  const resized = resizeCompositePanel(panel, panelHeights.get(panel.id) ?? 1, !fractionalViewport);
330
410
  return lineCues.size > 0 ? { ...resized, lineCues } : resized;
331
411
  });
332
- }, [fractionalViewport, lineCues, panels, plotHeight, projectedScene]);
412
+ }, [fractionalViewport, lineCues, maximizedPanelId, panelWeights, panels, plotHeight, projectedScene]);
413
+ // What a resize starts from: each shown panel's rows, and the weights they share.
414
+ const panelLayoutRef = useRef<{ rows: { id: string; rows: number; weight: number }[]; weightTotal: number }>({ rows: [], weightTotal: 0 });
415
+ {
416
+ const rows = (layoutPanels ?? []).map((panel) => {
417
+ const weight = panelWeights?.[panel.id] ?? panels.find((spec) => spec.id === panel.id)?.height;
418
+ return { id: panel.id, rows: panel.height, weight: typeof weight === "number" && Number.isFinite(weight) && weight > 0 ? weight : 1 };
419
+ });
420
+ panelLayoutRef.current = { rows, weightTotal: rows.reduce((sum, entry) => sum + entry.weight, 0) };
421
+ }
333
422
  // Static overview charts also pin the latest price with cursor precision.
334
423
  const includeCursorLabels = interactive || cursorDate !== undefined || !!scenePanels?.some((panel) => panel.lastPrice);
335
424
  const includeSeriesTags = isDesktopWeb && (interactive || cursorDate !== undefined);
@@ -369,9 +458,11 @@ function ThemedCompositeChart({
369
458
  width: plotWidth,
370
459
  height: layoutPanels.reduce((sum, panel) => sum + panel.height, 0),
371
460
  panels: layoutPanels,
461
+ // A panel with the whole plot still leaves the legend every series' value.
462
+ ...(maximizedPanelId ? { cursorPanels: projectedScene.panels } : {}),
372
463
  };
373
464
  return downsampleCompositeChartScene(laidOut, downsampleWidth);
374
- }, [downsampleWidth, layoutPanels, plotWidth, projectedScene]);
465
+ }, [downsampleWidth, layoutPanels, maximizedPanelId, plotWidth, projectedScene]);
375
466
  const resolvedCursorTimestamp = resolvedCursorDate?.getTime() ?? null;
376
467
  const normalizedCursorTimestamp = resolvedCursorTimestamp !== null && Number.isFinite(resolvedCursorTimestamp)
377
468
  ? resolvedCursorTimestamp
@@ -487,6 +578,94 @@ function ThemedCompositeChart({
487
578
  if (date) link.pin(compositeCursorAsOf(baseScene, date));
488
579
  }, [baseScene, link]);
489
580
 
581
+ // The layout the user leaves the chart in: kept with the pane, through the
582
+ // latest values, so a handler bound once still acts on what is on screen.
583
+ const layoutStateRef = useRef({ chartLayout, maximizedPanelId, onChartLayoutChange });
584
+ layoutStateRef.current = { chartLayout, maximizedPanelId, onChartLayoutChange };
585
+ const patchLayout = useCallback((patch: ChartLayoutPrefs | ((layout: ChartLayoutPrefs) => ChartLayoutPrefs)) => {
586
+ layoutStateRef.current.onChartLayoutChange((layout) => patchChartLayout(layout, typeof patch === "function" ? patch(layout) : patch));
587
+ }, []);
588
+ // The tool in hand, read when the bar is toggled (the keyboard hook below holds it).
589
+ const toolInHandRef = useRef<{ armed: boolean; putDown: () => void }>({ armed: false, putDown: () => {} });
590
+ // Shift+T and the chevrons act on the bar as it shows: a bar open only for
591
+ // the tool in hand folds again, the tool put down, and stays hidden.
592
+ const toggleToolbar = useCallback(() => {
593
+ const tool = toolInHandRef.current;
594
+ const hidden = layoutStateRef.current.chartLayout.toolbarHidden === true && !tool.armed;
595
+ if (!hidden && tool.armed) tool.putDown();
596
+ patchLayout({ toolbarHidden: !hidden });
597
+ }, [patchLayout]);
598
+ const toggleLegendCollapsed = useCallback(() => patchLayout((layout) => ({ legendCollapsed: !layout.legendCollapsed })), [patchLayout]);
599
+ const resetPanelHeights = useCallback(() => {
600
+ setDraftPanelWeights(null);
601
+ patchLayout({ panelWeights: undefined });
602
+ }, [patchLayout]);
603
+ const resetPanelMaximized = useCallback(() => patchLayout({ maximizedPanelId: undefined }), [patchLayout]);
604
+ const togglePanelMaximized = useCallback((panelId: string) => {
605
+ const maximized = layoutStateRef.current.maximizedPanelId;
606
+ patchLayout({ maximizedPanelId: maximized === panelId ? undefined : panelId });
607
+ }, [patchLayout]);
608
+ // A panel given the whole plot is let go once the chart no longer has it, so
609
+ // it never comes back maximized, and when a panel is added beside it, so the
610
+ // new one shows. The chart's panels are the ones it is given and the ones
611
+ // its series bring; a panel whose data is loading is still given.
612
+ const chartPanelIds = useMemo(() => {
613
+ const ids = new Set(panels.map((panel) => panel.id));
614
+ for (const panel of projectedScene?.panels ?? []) ids.add(panel.id);
615
+ return [...ids].join("\u0000");
616
+ }, [panels, projectedScene]);
617
+ const seenPanelIdsRef = useRef<readonly string[] | null>(null);
618
+ const savedMaximizedPanelId = chartLayout.maximizedPanelId;
619
+ const chartDrawn = projectedScene !== null;
620
+ useEffect(() => {
621
+ const ids = chartPanelIds ? chartPanelIds.split("\u0000") : [];
622
+ const previous = seenPanelIdsRef.current;
623
+ seenPanelIdsRef.current = ids;
624
+ if (!savedMaximizedPanelId) return;
625
+ const gone = chartDrawn && !ids.includes(savedMaximizedPanelId);
626
+ const added = !!previous && previous.length > 1 && previous.includes(savedMaximizedPanelId)
627
+ && ids.some((id) => !previous.includes(id));
628
+ if (gone || added) patchLayout({ maximizedPanelId: undefined });
629
+ }, [chartDrawn, chartPanelIds, patchLayout, savedMaximizedPanelId]);
630
+ // Shift+Up and Shift+Down: the top panel a row taller or shorter.
631
+ const stepTopPanelRows = useCallback((direction: 1 | -1) => {
632
+ const { rows } = panelLayoutRef.current;
633
+ const plotRows = rows.reduce((sum, entry) => sum + entry.rows, 0);
634
+ const weight = stepTopPanel(rows, direction, minimumPanelRows(plotRows, rows.length));
635
+ const top = rows[0];
636
+ if (weight === null || !top) return;
637
+ patchLayout((layout) => ({ panelWeights: { ...layout.panelWeights, [top.id]: weight } }));
638
+ }, [patchLayout]);
639
+ const legendCollapsible = showLegend && visibleLegendSeries.length > 1;
640
+ const legendCollapsed = legendCollapsible && chartLayout.legendCollapsed === true;
641
+ const projectedPanelCount = projectedScene?.panels.length ?? 0;
642
+ const layoutControls = useMemo(() => ({
643
+ toolbarHidden: chartLayout.toolbarHidden === true,
644
+ toggleToolbar,
645
+ legendCollapsible,
646
+ legendCollapsed,
647
+ toggleLegend: toggleLegendCollapsed,
648
+ panelsResizable: (layoutPanels?.length ?? 0) > 1,
649
+ stepTopPanel: stepTopPanelRows,
650
+ panelHeightsSet: projectedPanelCount > 1 && !!chartLayout.panelWeights,
651
+ resetPanelHeights,
652
+ panelMaximized: !!maximizedPanelId,
653
+ restorePanels: resetPanelMaximized,
654
+ }), [
655
+ chartLayout.panelWeights,
656
+ chartLayout.toolbarHidden,
657
+ layoutPanels?.length,
658
+ legendCollapsed,
659
+ legendCollapsible,
660
+ maximizedPanelId,
661
+ projectedPanelCount,
662
+ resetPanelHeights,
663
+ resetPanelMaximized,
664
+ stepTopPanelRows,
665
+ toggleLegendCollapsed,
666
+ toggleToolbar,
667
+ ]);
668
+
490
669
  const {
491
670
  armedTool,
492
671
  armTool,
@@ -509,6 +688,7 @@ function ThemedCompositeChart({
509
688
  pin: pinnable ? { pinned: pinnedCursor, toggle: togglePin } : null,
510
689
  onActivate,
511
690
  timePick,
691
+ pricePick,
512
692
  levels,
513
693
  visibleLegendSeries,
514
694
  visibleSeriesIds,
@@ -516,10 +696,11 @@ function ThemedCompositeChart({
516
696
  isSeriesToggleable,
517
697
  navigationFrame,
518
698
  activeUserViewport,
699
+ scaledByHand,
519
700
  panViewportByRatio,
520
701
  zoomViewport,
521
702
  setViewportRange,
522
- resetViewport,
703
+ resetViewport: resetView,
523
704
  drawings,
524
705
  selectedDrawingId,
525
706
  setSelectedDrawingId,
@@ -527,7 +708,9 @@ function ThemedCompositeChart({
527
708
  addDrawing,
528
709
  removeDrawing,
529
710
  pickDrawColor,
711
+ layout: layoutControls,
530
712
  });
713
+ toolInHandRef.current = { armed: armedTool !== null, putDown: () => armTool(null) };
531
714
  const pressFromPointer = useCallback(() => {
532
715
  onPress?.();
533
716
  activateFromPointer();
@@ -562,6 +745,116 @@ function ThemedCompositeChart({
562
745
  zoomViewport,
563
746
  ]);
564
747
 
748
+ // The time axis under the pointer: a drag zooms time from the newest bar
749
+ // in view, in (left) or out (right), as +/- do; a double click resets it.
750
+ const timeScalable = interactive && navigable && !!navigationFrame && !xAxis;
751
+ const timeAxisGestureRef = useRef<{
752
+ startColumn: number;
753
+ frame: CompositeNavigationFrame;
754
+ from: CompositeViewportRange;
755
+ moved: boolean;
756
+ } | null>(null);
757
+ const lastTimeAxisPressRef = useRef<number | null>(null);
758
+ const latestTimeAxisRef = useRef({ navigationFrame, effectiveViewport, resetViewport, zoomViewport, activateFromPointer, cellWidthPx });
759
+ latestTimeAxisRef.current = { navigationFrame, effectiveViewport, resetViewport, zoomViewport, activateFromPointer, cellWidthPx };
760
+ const timeAxisGestures = useMemo(() => {
761
+ if (!timeScalable) return undefined;
762
+ const column = (event: ChartMouseEvent) => typeof event.preciseX === "number" ? event.preciseX : event.x;
763
+ const release = () => {
764
+ timeAxisGestureRef.current = null;
765
+ };
766
+ return {
767
+ onMouseDown: (event: ChartMouseEvent) => {
768
+ const latest = latestTimeAxisRef.current;
769
+ latest.activateFromPointer();
770
+ consumeChartMouseEvent(event);
771
+ const now = Date.now();
772
+ const last = lastTimeAxisPressRef.current;
773
+ const double = typeof event.detail === "number"
774
+ ? event.detail >= 2
775
+ : last !== null && now - last < AXIS_DOUBLE_PRESS_MS;
776
+ if (double) {
777
+ lastTimeAxisPressRef.current = null;
778
+ timeAxisGestureRef.current = null;
779
+ latest.resetViewport();
780
+ return;
781
+ }
782
+ lastTimeAxisPressRef.current = now;
783
+ timeAxisGestureRef.current = latest.navigationFrame && latest.effectiveViewport
784
+ ? { startColumn: column(event), frame: latest.navigationFrame, from: latest.effectiveViewport, moved: false }
785
+ : null;
786
+ },
787
+ onMouseDrag: (event: ChartMouseEvent) => {
788
+ const gesture = timeAxisGestureRef.current;
789
+ if (!gesture) return;
790
+ consumeChartMouseEvent(event);
791
+ const latest = latestTimeAxisRef.current;
792
+ const deltaPx = (column(event) - gesture.startColumn) * latest.cellWidthPx;
793
+ if (!gesture.moved && Math.abs(deltaPx) < 1) return;
794
+ gesture.moved = true;
795
+ lastTimeAxisPressRef.current = null;
796
+ latest.zoomViewport(1 / resolveAxisDragSpanFactor(deltaPx), 1, { frame: gesture.frame, from: gesture.from });
797
+ },
798
+ onMouseUp: release,
799
+ onMouseDragEnd: release,
800
+ };
801
+ }, [timeScalable]);
802
+
803
+ // The line between two panels on the desktop and the web: a drag moves it a
804
+ // row at a time, the panel above taking what the one below gives, and a
805
+ // double click puts back the split the chart was made with.
806
+ const [resizingPanelIndex, setResizingPanelIndex] = useState<number | null>(null);
807
+ const panelResizeRef = useRef<{
808
+ index: number;
809
+ startPixelY: number;
810
+ rows: { id: string; rows: number }[];
811
+ weightTotal: number;
812
+ weights: Readonly<Record<string, number>> | null;
813
+ } | null>(null);
814
+ const latestPanelResizeRef = useRef({ activateFromPointer, cellHeightPx });
815
+ latestPanelResizeRef.current = { activateFromPointer, cellHeightPx };
816
+ const panelsResizableByPointer = interactive && isDesktopWeb && !maximizedPanelId && (layoutPanels?.length ?? 0) > 1;
817
+ const panelDividerGestures = useMemo(() => {
818
+ if (!panelsResizableByPointer) return null;
819
+ const release = () => {
820
+ const gesture = panelResizeRef.current;
821
+ panelResizeRef.current = null;
822
+ setResizingPanelIndex(null);
823
+ const weights = gesture?.weights;
824
+ if (weights) patchLayout((layout) => ({ panelWeights: { ...layout.panelWeights, ...weights } }));
825
+ };
826
+ return (index: number) => ({
827
+ onMouseDown: (event: ChartMouseEvent) => {
828
+ latestPanelResizeRef.current.activateFromPointer();
829
+ consumeChartMouseEvent(event);
830
+ if ((event.detail ?? 0) >= 2) {
831
+ panelResizeRef.current = null;
832
+ setResizingPanelIndex(null);
833
+ resetPanelHeights();
834
+ return;
835
+ }
836
+ const { rows, weightTotal } = panelLayoutRef.current;
837
+ panelResizeRef.current = { index, startPixelY: event.pixelY ?? 0, rows, weightTotal, weights: null };
838
+ setResizingPanelIndex(index);
839
+ },
840
+ onMouseDrag: (event: ChartMouseEvent) => {
841
+ const gesture = panelResizeRef.current;
842
+ if (!gesture) return;
843
+ consumeChartMouseEvent(event);
844
+ const deltaRows = ((event.pixelY ?? gesture.startPixelY) - gesture.startPixelY) / Math.max(1, latestPanelResizeRef.current.cellHeightPx);
845
+ const plotRows = gesture.rows.reduce((sum, entry) => sum + entry.rows, 0);
846
+ // Back where it started, or never a row away, the line saves nothing.
847
+ const weights = draggedPanelWeights(gesture, gesture.index, deltaRows, minimumPanelRows(plotRows, gesture.rows.length));
848
+ gesture.weights = weights;
849
+ setDraftPanelWeights(weights
850
+ ? (current) => ({ ...(current ?? layoutStateRef.current.chartLayout.panelWeights), ...weights })
851
+ : null);
852
+ },
853
+ onMouseUp: release,
854
+ onMouseDragEnd: release,
855
+ });
856
+ }, [panelsResizableByPointer, patchLayout, resetPanelHeights]);
857
+
565
858
  const leftPadding = leftAxisWidth + (leftAxisWidth ? axisGap : 0);
566
859
  const rightPadding = rightAxisWidth + (rightAxisWidth ? axisGap : 0);
567
860
  // The axis's ticks do not move with the cursor, so they are laid out once per chart, not per move.
@@ -668,6 +961,9 @@ function ThemedCompositeChart({
668
961
  // drawing. A chart outside a pane (a share page) keeps them.
669
962
  const toolbarWanted = paneFocused !== false || armedTool !== null || pointerDragging || toolSpan !== null;
670
963
  const showToolbar = interactive && navigable && toolbarWanted && plotWidth > CHART_TOOLBAR_WIDTH + 4;
964
+ // Hidden, the bar folds to the button that brings it back, and opens again
965
+ // while a tool picked from the keys is in hand, so the plot says which one.
966
+ const toolbarFolded = showToolbar && chartLayout.toolbarHidden === true && armedTool === null;
671
967
  // Bars shorter than a day carry a time of day the cursor reads out.
672
968
  const intradayBars = scene.timeZone !== undefined || visibleSeries.some((entry) => (
673
969
  !!entry.historyResolution && isIntradayResolution(entry.historyResolution)
@@ -731,6 +1027,11 @@ function ThemedCompositeChart({
731
1027
  keyboardIndex={legendKeyboardIndex}
732
1028
  rows={legendRows}
733
1029
  onWantedRowsChange={setLegendWantedRows}
1030
+ collapsed={legendCollapsed}
1031
+ onToggleCollapsed={legendCollapsible && interactive ? () => {
1032
+ pressFromPointer();
1033
+ toggleLegendCollapsed();
1034
+ } : undefined}
734
1035
  />
735
1036
  ) : null}
736
1037
  {showToolbar ? (
@@ -742,6 +1043,11 @@ function ThemedCompositeChart({
742
1043
  drawColor={drawColor}
743
1044
  showColors={isDrawingTool(armedTool) || !!selectedDrawingId}
744
1045
  levelTool={levelsEditable}
1046
+ folded={toolbarFolded}
1047
+ onToggleFolded={() => {
1048
+ pressFromPointer();
1049
+ toggleToolbar();
1050
+ }}
745
1051
  onArmTool={(tool) => {
746
1052
  pressFromPointer();
747
1053
  armTool(tool);
@@ -752,6 +1058,41 @@ function ThemedCompositeChart({
752
1058
  }}
753
1059
  />
754
1060
  ) : null}
1061
+ {maximizedPanelId && interactive ? (
1062
+ // A panel with the whole plot says so at its corner, as a value axis
1063
+ // scaled by hand does at its foot, and that is the way back.
1064
+ <Box
1065
+ position="absolute"
1066
+ left={leftPadding + Math.max(0, plotWidth - RESTORE_PANELS_LABEL.length - 1)}
1067
+ top={legendRows}
1068
+ width={RESTORE_PANELS_LABEL.length}
1069
+ height={1}
1070
+ zIndex={30}
1071
+ style={isDesktopWeb
1072
+ ? {
1073
+ left: "auto",
1074
+ right: `calc(${rightPadding} * var(--cell-w) + var(--gloom-space-xs))`,
1075
+ top: `calc(${legendRows} * var(--cell-h) + var(--gloom-space-xs))`,
1076
+ width: "auto",
1077
+ height: "auto",
1078
+ }
1079
+ : undefined}
1080
+ data-gloom-role="composite-chart-panels-restore"
1081
+ >
1082
+ <Button
1083
+ label="Show All Panels"
1084
+ displayLabel={RESTORE_PANELS_LABEL}
1085
+ title="One panel has the chart. Show every panel again (or double-click the plot)."
1086
+ variant="secondary"
1087
+ compact
1088
+ stopPropagation
1089
+ onPress={() => {
1090
+ pressFromPointer();
1091
+ resetPanelMaximized();
1092
+ }}
1093
+ />
1094
+ </Box>
1095
+ ) : null}
755
1096
  {paneInstanceId ? (
756
1097
  <ChartDrawingStore
757
1098
  paneInstanceId={paneInstanceId}
@@ -759,7 +1100,7 @@ function ThemedCompositeChart({
759
1100
  onRestore={setDrawings}
760
1101
  />
761
1102
  ) : null}
762
- {scene.panels.map((panel) => (
1103
+ {scene.panels.map((panel, index) => (
763
1104
  <CompositePanelSurface
764
1105
  key={panel.id}
765
1106
  panel={panel}
@@ -794,9 +1135,17 @@ function ThemedCompositeChart({
794
1135
  onPointerPress={pressPlot}
795
1136
  showTextFallback={showTextFallback}
796
1137
  onPickTime={timePick?.onPick}
1138
+ onPickPrice={pricePick?.onPick}
797
1139
  levels={levelHost?.panel.id === panel.id ? levels ?? null : null}
798
1140
  selectedLevelId={selectedLevelId}
799
1141
  onSelectLevel={setSelectedLevelId}
1142
+ valueScalable={interactive}
1143
+ onSetValueScale={setValueScale}
1144
+ onResetValueScale={resetPanelValueScale}
1145
+ dividerAbove={index > 0 && panelDividerGestures
1146
+ ? { active: resizingPanelIndex === index, gestures: panelDividerGestures(index) }
1147
+ : null}
1148
+ onToggleMaximized={interactive && navigable && projectedPanelCount > 1 ? () => togglePanelMaximized(panel.id) : undefined}
800
1149
  />
801
1150
  ))}
802
1151
  {watermarkScale ? (
@@ -836,7 +1185,15 @@ function ThemedCompositeChart({
836
1185
  </Box>
837
1186
  ) : null}
838
1187
  {timeAxisLayout ? (
839
- <Box flexDirection="row" width={totalWidth} height={1} style={isDesktopWeb ? DESKTOP_FULL_ROW : undefined}>
1188
+ <Box
1189
+ flexDirection="row"
1190
+ width={totalWidth}
1191
+ height={1}
1192
+ style={isDesktopWeb ? timeAxisGestures ? TIME_AXIS_ROW : DESKTOP_FULL_ROW : undefined}
1193
+ {...timeAxisGestures}
1194
+ data-gloom-interactive={timeAxisGestures ? "true" : undefined}
1195
+ data-gloom-role="composite-chart-time-scale"
1196
+ >
840
1197
  {leftPadding > 0 ? <Box width={leftPadding} /> : null}
841
1198
  <StaticXAxisLabels
842
1199
  labels={xAxis?.ticks ? [] : xAxis?.labels ? [...xAxis.labels] : [timeAxisLayout.text]}
@@ -31,8 +31,13 @@ export type CompositeChartInteraction =
31
31
 
32
32
  export const COMPOSITE_ZOOM_STEP_FACTOR = 1.2;
33
33
  export const COMPOSITE_KEYBOARD_PAN_RATIO = 0.02;
34
- /** Pixels of trackpad or wheel travel that zoom the viewport by a factor of e. */
35
- const WHEEL_ZOOM_PIXELS_PER_E = 160;
34
+ /**
35
+ * Pixels of trackpad or wheel travel that zoom the viewport by a factor of e.
36
+ * Chromium sends a trackpad pinch as Ctrl+wheel with `deltaY = -100 ln(scale)`
37
+ * (the desktop host turns WebKit's pinch into the same), so at 100 the bars
38
+ * follow the fingers.
39
+ */
40
+ const WHEEL_ZOOM_PIXELS_PER_E = 100;
36
41
  /** Bound on one wheel event so a coarse mouse notch cannot zoom by more than this. */
37
42
  const WHEEL_ZOOM_STEP_LIMIT = 1.5;
38
43