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
@@ -53,11 +53,16 @@ function surfaceSunkenColour(palette: Palette): string {
53
53
  return palette.bg;
54
54
  }
55
55
 
56
+ /** A row or control under the pointer: halfway from the background to the selection. */
57
+ export function hoverColour(palette: Palette): string {
58
+ return blendHex(palette.bg, palette.selected, 0.5);
59
+ }
60
+
56
61
  /**
57
62
  * The colour roles the palette names indirectly, as `--gloom-*` variables:
58
63
  * styles.css and inline styles read these, never a blend of their own.
59
64
  */
60
- export function roleColours(palette: Palette): Array<[string, string]> {
65
+ function roleColours(palette: Palette): Array<[string, string]> {
61
66
  return [
62
67
  ["--gloom-surface-raised", surfaceRaisedColour(palette)],
63
68
  ["--gloom-surface-sunken", surfaceSunkenColour(palette)],
@@ -69,3 +74,34 @@ export function roleColours(palette: Palette): Array<[string, string]> {
69
74
  ["--gloom-locked", palette.textDim],
70
75
  ];
71
76
  }
77
+
78
+ /** The palette entries styles.css reads as they are. */
79
+ const PALETTE_VARIABLES: Array<[keyof Palette, string]> = [
80
+ ["bg", "--gloom-bg"],
81
+ ["panel", "--gloom-panel"],
82
+ ["border", "--gloom-border"],
83
+ ["borderFocused", "--gloom-border-focused"],
84
+ ["text", "--gloom-text"],
85
+ ["textDim", "--gloom-text-dim"],
86
+ ["textBright", "--gloom-text-bright"],
87
+ ["textMuted", "--gloom-text-muted"],
88
+ ["positive", "--gloom-positive"],
89
+ ["negative", "--gloom-negative"],
90
+ ["neutral", "--gloom-neutral"],
91
+ ["warning", "--gloom-warning"],
92
+ ["header", "--gloom-header"],
93
+ ["headerText", "--gloom-header-text"],
94
+ ["selected", "--gloom-selected"],
95
+ ["selectedText", "--gloom-selected-text"],
96
+ ["commandBg", "--gloom-command-bg"],
97
+ ["commandBorder", "--gloom-command-border"],
98
+ ];
99
+
100
+ /** Every custom property a theme sets on the document root, which the desktop and web stylesheet draws with. */
101
+ export function themeCssVariables(palette: Palette): Array<[string, string]> {
102
+ return [
103
+ ...PALETTE_VARIABLES.map(([key, name]): [string, string] => [name, palette[key]]),
104
+ ["--gloom-hover-bg", hoverColour(palette)],
105
+ ...roleColours(palette),
106
+ ];
107
+ }
@@ -2,11 +2,13 @@ import { logFailure } from "../utils/log-failure";
2
2
  import type { DataProvider } from "../types/data-provider";
3
3
  import type { InstrumentSearchResult } from "../types/instrument";
4
4
  import { canonicalExchange, isUsListingExchange, parsePublicTickerKey } from "../utils/exchanges";
5
- import { companyNameMatch, shortCompanyName } from "./company-name";
5
+ import { companyNameMatch, sameCompany, shortCompanyName } from "./company-name";
6
6
  import { LISTING_SEARCH_LIMIT } from "./search";
7
- import { classifyInstrumentKind } from "./search/ranking";
7
+ import { lineDistance } from "./search/home-listing";
8
+ import { classifyInstrumentKind, isCryptoInstrumentType } from "./search/ranking";
8
9
  import { isProviderBusy, type ProviderBusyError } from "../sources/provider-errors";
9
- import { readTerminalListingCode, type TerminalListingCode } from "./terminal-codes";
10
+ import { readTerminalListingCode, type TerminalListing, type TerminalListingCode } from "./terminal-codes";
11
+ import { hasNonLatinLetters } from "../utils/typed-text";
10
12
 
11
13
  export interface CompanyNameListing {
12
14
  symbol: string;
@@ -14,6 +16,12 @@ export interface CompanyNameListing {
14
16
  exchange: string;
15
17
  /** The listing's name as search gives it. */
16
18
  name: string;
19
+ /**
20
+ * When the listing is a fund or an index carrying the name ("JP Morgan" read
21
+ * as ^JTEK, JP MORGAN ETF TRUS), the company's common stock the name says
22
+ * run together (JPM, JPMorgan Chase & Co.), which the reader is asked about.
23
+ */
24
+ meant?: Omit<CompanyNameListing, "meant">;
17
25
  }
18
26
 
19
27
  /** Share lines that are not the company's common stock, though search may type them as such. */
@@ -33,65 +41,234 @@ export function isCompanyNameInput(input: string): boolean {
33
41
  * is also searched without its legal form, which can find more), the company
34
42
  * whose name says no more than the one typed goes first, so a subsidiary that
35
43
  * shares the word (Whirlpool of India) does not, and of those a name matched
36
- * word for word before one a short form matched; then its line on a US
37
- * exchange, then a plain line before a depositary receipt, the shortest
38
- * symbol (WHR before WHR-A) and search's order. Contracts, preferred shares
39
- * and notes are never the listing. Null when none matches; when none does
40
- * because search was too busy to answer, `ProviderBusyError`.
44
+ * word for word before one a short form matched; then a company's shares
45
+ * (its stock or a receipt) before a fund or an index named alike; then its
46
+ * primary listing, the line the service marks as its home (SIE on XETRA for
47
+ * "SIEMENS AG"), before
48
+ * its other plain lines, those before a line that only quotes shares listed
49
+ * elsewhere (4SIE in Milan, OTC, a regional German venue) and those before a
50
+ * depositary receipt (SAP's NYSE line for "SAP SE"), so a receipt is the
51
+ * listing only of a company listed by receipts alone (PDD); then the row the
52
+ * service marks with the name, a US line, the shortest symbol (WHR before
53
+ * WHR-A) and search's order. The row the service marks with the name as typed
54
+ * (`searchAliases`: JPM for "JP Morgan", SIE for "SIEMENS AG", though its name
55
+ * is Siemens Aktiengesellschaft) is named by it exactly. Contracts, preferred
56
+ * shares and notes are never the listing. With `quoted`, a listing with no
57
+ * quote (a line search keeps for a venue that no longer prices it) gives way
58
+ * to the next of the same company's lines that has one, never to another
59
+ * company's home line; when none has, or the source is too busy to say, the
60
+ * first stands. With `meant`, a fund or an index found for a name its
61
+ * company's stock says run together ("JP Morgan" for JPMorgan Chase & Co.)
62
+ * names that stock as `meant`, searched under the run-together name when the
63
+ * answer lacks it. With `oneWord`, for a name typed as one word, which many
64
+ * listings' names have ("oil", "steel"): only search's top result, a row the
65
+ * service marks with the word, or a name that is the word and nothing more
66
+ * (Apple Inc. for "apple") is the listing, never a short form ("grp" for any
67
+ * Group) or a coin, whose name is the crypto board's. Null when none matches;
68
+ * when none does because search was too busy to answer, `ProviderBusyError`.
41
69
  */
42
70
  export async function findListingOfCompanyName(
43
- dataProvider: Pick<DataProvider, "search">,
71
+ dataProvider: Pick<DataProvider, "search"> & Partial<Pick<DataProvider, "getQuote">>,
44
72
  typed: string,
73
+ options: { meant?: boolean; oneWord?: boolean; quoted?: boolean } = {},
45
74
  ): Promise<CompanyNameListing | null> {
46
75
  const name = typed.trim();
47
76
  if (!name) return null;
48
77
  const queries = [...new Set([name, shortCompanyName(name)])].filter(Boolean);
49
- const answers = await Promise.all(queries.map((query) => dataProvider.search(query, { limit: LISTING_SEARCH_LIMIT })
50
- .catch((error: unknown): InstrumentSearchResult[] | ProviderBusyError => {
51
- if (isProviderBusy(error)) return error;
52
- logFailure("tickers-company-name-listing", "Could not search company listings")(error);
53
- return [];
54
- })));
78
+ const answers = await Promise.all(queries.map((query) => searchListings(dataProvider, query)));
55
79
  const busy = answers.find(isProviderBusy);
56
80
  const results = answers.flatMap((answer) => Array.isArray(answer) ? answer : []);
57
81
  const ranked = results.flatMap((result, order) => {
58
- const exchange = canonicalExchange(result.exchange === "SMART" ? result.primaryExchange : result.exchange || result.primaryExchange);
59
- const type = result.brokerContract?.secType || result.type || "";
60
- const match = companyNameMatch(name, result.name);
82
+ const exchange = listedExchange(result);
83
+ const type = listedType(result);
84
+ const named = namedByService(name, result);
85
+ const match = named ? { extra: 0, abbreviated: 0 } : companyNameMatch(name, result.name);
61
86
  if (!exchange || match == null || classifyInstrumentKind(type) === "derivative" || NOT_COMMON.test(type)
62
87
  || parsePublicTickerKey(result.symbol).exchange) return [];
63
- return [{ result, exchange, rank: [match.extra, match.abbreviated, isUsListingExchange(exchange) ? 0 : 1, RECEIPT.test(type) ? 1 : 0, result.symbol.length, order] }];
88
+ if (options.oneWord && (match.abbreviated > 0 || isCryptoInstrumentType(type) || !(order === 0 || named || match.extra === 0))) return [];
89
+ // A receipt is a company's shares too, however search types it ("Depositary Receipt" or "American Depositary Receipt").
90
+ const stock = classifyInstrumentKind(type) === "equity" || RECEIPT.test(type) ? 0 : 1;
91
+ const home = result.homeListing === true;
92
+ const line = home ? 0 : 1 + lineDistance(type, exchange, result.symbol);
93
+ return [{
94
+ result, exchange, stock, home,
95
+ rank: [match.extra, match.abbreviated, stock, line, named ? 0 : 1, isUsListingExchange(exchange) ? 0 : 1, result.symbol.length, order],
96
+ }];
64
97
  }).sort((left, right) => {
65
98
  const at = left.rank.findIndex((value, index) => value !== right.rank[index]);
66
99
  return at < 0 ? 0 : left.rank[at]! - right.rank[at]!;
67
100
  });
68
- const best = ranked[0];
69
- if (!best && busy) throw busy;
70
- return best ? { symbol: best.result.symbol.toUpperCase(), exchange: best.exchange, name: best.result.name } : null;
101
+ const first = ranked[0];
102
+ // Listings are named in Latin letters: a name in another script ("任天堂 ソニー") names none, answered or not.
103
+ if (!first && busy && !hasNonLatinLetters(name)) throw busy;
104
+ if (!first) return null;
105
+ // The first may give way to its company's other lines: as near the name and of its kind. Another line the
106
+ // service marks as a home is another company's (Siemens Ltd. on NSE, for "SIEMENS AG"), and so is a line
107
+ // named as that one is (Siemens Ltd. on BSE).
108
+ const otherHomes = new Set(ranked.filter((listing) => listing.home && listing !== first).map(({ result }) => plainName(result.name)));
109
+ otherHomes.delete(plainName(first.result.name));
110
+ const lines = ranked.filter((listing) => listing === first || (!listing.home && !otherHomes.has(plainName(listing.result.name))
111
+ && sameCompany(first.result.name, listing.result.name)
112
+ && listing.rank.slice(0, NAME_RANKS).every((value, index) => value === first.rank[index])));
113
+ const best = options.quoted ? await firstQuoted(dataProvider, lines) : first;
114
+ const found = { symbol: best.result.symbol.toUpperCase(), exchange: best.exchange, name: best.result.name };
115
+ const meant = best.stock && options.meant ? await stockNamedRunTogether(dataProvider, name, results) : null;
116
+ return meant ? { ...found, meant } : found;
117
+ }
118
+
119
+ /** The ranks that say how near a listing's name is to the one typed, and whether it is a stock: one company's lines share them. */
120
+ const NAME_RANKS = 3;
121
+
122
+ /** Lines past the first a name's listing is asked a quote for, at once, when the first has none. */
123
+ const QUOTE_FALLBACKS = 4;
124
+
125
+ interface RankedListing {
126
+ result: InstrumentSearchResult;
127
+ exchange: string;
128
+ }
129
+
130
+ /**
131
+ * The first of a company's lines, in their order, that has a quote: the first
132
+ * itself, or when it has none, the first of the next few that does, asked
133
+ * together. The first stands when none has a quote, when the source is too
134
+ * busy to say, and when nothing here can ask for quotes.
135
+ */
136
+ async function firstQuoted<T extends RankedListing>(dataProvider: Partial<Pick<DataProvider, "getQuote">>, lines: readonly T[]): Promise<T> {
137
+ const first = lines[0]!;
138
+ if (!dataProvider.getQuote) return first;
139
+ const quoted = ({ result, exchange }: RankedListing) => dataProvider.getQuote!(result.symbol.toUpperCase(), exchange).then(hasPrice);
140
+ try {
141
+ if (await quoted(first)) return first;
142
+ } catch (error) {
143
+ // A busy source says nothing of the listing; any other failure is a listing with no quote.
144
+ if (isProviderBusy(error)) return first;
145
+ }
146
+ const keys = new Set([listingKey(first)]);
147
+ const next: T[] = [];
148
+ for (const line of lines) {
149
+ if (next.length === QUOTE_FALLBACKS) break;
150
+ if (keys.has(listingKey(line))) continue;
151
+ keys.add(listingKey(line));
152
+ next.push(line);
153
+ }
154
+ const priced = await Promise.all(next.map((line) => quoted(line).catch(() => {
155
+ // Intentional ignore: a line whose quote fails is a line with no quote.
156
+ return false;
157
+ })));
158
+ return next.find((_, index) => priced[index]) ?? first;
159
+ }
160
+
161
+ /** A name as two venues may spell it alike: "SIEMENS LTD" for Siemens Ltd. */
162
+ function plainName(name: string | null | undefined): string {
163
+ return (name ?? "").normalize("NFKD").replace(/\p{M}/gu, "").toUpperCase().replace(/[^\p{L}\p{N}]+/gu, " ").trim();
164
+ }
165
+
166
+ function listingKey({ result, exchange }: RankedListing): string {
167
+ return `${result.symbol.toUpperCase()}:${exchange}`;
168
+ }
169
+
170
+ function hasPrice(quote: { price?: number } | null | undefined): boolean {
171
+ return !!quote && Number.isFinite(quote.price) && quote.price !== 0;
172
+ }
173
+
174
+ function searchListings(dataProvider: Pick<DataProvider, "search">, query: string): Promise<InstrumentSearchResult[] | ProviderBusyError> {
175
+ return dataProvider.search(query, { limit: LISTING_SEARCH_LIMIT })
176
+ .catch((error: unknown): InstrumentSearchResult[] | ProviderBusyError => {
177
+ if (isProviderBusy(error)) return error;
178
+ logFailure("tickers-company-name-listing", "Could not search company listings")(error);
179
+ return [];
180
+ });
181
+ }
182
+
183
+ function listedExchange(result: InstrumentSearchResult): string {
184
+ return canonicalExchange(result.exchange === "SMART" ? result.primaryExchange : result.exchange || result.primaryExchange);
185
+ }
186
+
187
+ function listedType(result: InstrumentSearchResult): string {
188
+ return result.brokerContract?.secType || result.type || "";
189
+ }
190
+
191
+ /** Letters and digits only, in capitals: "JP Morgan" and "JPMorgan" are JPMORGAN. */
192
+ function runTogether(text: string): string {
193
+ return text.normalize("NFKD").replace(/\p{M}/gu, "").toUpperCase().replace(/[^\p{L}\p{N}]/gu, "");
194
+ }
195
+
196
+ /** Whether the service marked the row with the name as typed: the company it means by it. */
197
+ export function namedByService(typed: string, result: InstrumentSearchResult): boolean {
198
+ const wanted = runTogether(typed);
199
+ return !!wanted && Array.isArray(result.searchAliases)
200
+ && result.searchAliases.some((alias) => typeof alias === "string" && runTogether(alias) === wanted);
201
+ }
202
+
203
+ /**
204
+ * The company's common stock on a US exchange whose name starts with the
205
+ * typed words run together ("JPMorgan Chase & Co." for "JP Morgan"), first in
206
+ * search's order; the answer at hand is searched first, then the run-together
207
+ * name itself. Null when none is, or when a single word was typed.
208
+ */
209
+ async function stockNamedRunTogether(
210
+ dataProvider: Pick<DataProvider, "search">,
211
+ typed: string,
212
+ results: readonly InstrumentSearchResult[],
213
+ ): Promise<Omit<CompanyNameListing, "meant"> | null> {
214
+ const wanted = runTogether(typed);
215
+ if (wanted.length < 4 || !/\s/.test(typed.trim())) return null;
216
+ const stockOf = (rows: readonly InstrumentSearchResult[]) => rows.find((result) => {
217
+ const type = listedType(result);
218
+ return classifyInstrumentKind(type) === "equity" && !NOT_COMMON.test(type) && !RECEIPT.test(type)
219
+ && isUsListingExchange(listedExchange(result)) && !parsePublicTickerKey(result.symbol).exchange
220
+ && (runTogether(result.name).startsWith(wanted) || namedByService(typed, result));
221
+ });
222
+ let stock = stockOf(results);
223
+ if (!stock) {
224
+ const answer = await searchListings(dataProvider, typed.trim().replace(/\s+/g, ""));
225
+ stock = Array.isArray(answer) ? stockOf(answer) : undefined;
226
+ }
227
+ return stock ? { symbol: stock.symbol.toUpperCase(), exchange: listedExchange(stock), name: stock.name } : null;
71
228
  }
72
229
 
73
230
  /** `BRK.B`, `BRK-B` and `BRK/B` alike. */
74
231
  const shareClassSymbol = (symbol: string) => symbol.trim().toUpperCase().replace(/[-/]/g, ".");
75
232
 
76
233
  /**
77
- * A terminal's code for a US listing typed where a symbol goes, when it is
78
- * one. A Reuters code (WFC.N) always is. A Bloomberg code is words, which a
79
- * fund's name can be too ("Putnam US Equity", "Global US Equity"), so it is
80
- * one only when search lists its root as a US ticker (JPM, in any case);
81
- * otherwise it is the name it reads as, and is searched as one. A search that
82
- * fails says nothing either way, and the code stands. Null for anything else.
234
+ * A terminal's code typed where a symbol goes, when it is one, on the listing
235
+ * search knows it by. A Reuters code (WFC.N), an index, a currency and a
236
+ * future always are. A Bloomberg equity code is words, which a fund's name can
237
+ * be too ("Putnam US Equity", "Global US Equity"), so one for the US, or typed
238
+ * in lower case, is one only when search lists its root there (JPM on a US
239
+ * exchange, VOD on LSE); otherwise it is the name it reads as, and is searched
240
+ * as one. One in capitals naming a venue abroad (`MC FP`) is one as typed: the
241
+ * venue's own check speaks when the symbol is not there. A code that can name
242
+ * several listings (`VOLVB SS` is VOLVB or VOLV.B in Stockholm, `RY CN`
243
+ * Toronto or the Venture exchange) is the first of them search lists. A
244
+ * search that fails says nothing either way, and the code stands. Null for
245
+ * anything else.
83
246
  */
84
247
  export async function readTerminalCodeArg(
85
248
  dataProvider: Pick<DataProvider, "search">,
86
249
  typed: string,
87
250
  ): Promise<TerminalListingCode | null> {
88
251
  const code = readTerminalListingCode(typed);
89
- if (!code || code.terminal !== "bloomberg") return code;
252
+ if (!code?.market) return code;
253
+ const us = !code.exchange || isUsListingExchange(code.exchange);
254
+ const verify = us || /\p{Ll}/u.test(code.typed.split(" ")[0]!);
255
+ if (!verify && !code.alternatives) return code;
256
+ const listings: TerminalListing[] = [code, ...code.alternatives ?? []];
90
257
  try {
91
- const results = await dataProvider.search(code.symbol, { limit: LISTING_SEARCH_LIMIT });
92
- return results.some((result) => shareClassSymbol(result.symbol) === code.symbol
93
- && isUsListingExchange(result.exchange === "SMART" ? result.primaryExchange : result.exchange || result.primaryExchange))
94
- ? code : null;
258
+ const searched = new Set<string>();
259
+ for (const { symbol } of listings) {
260
+ if (searched.has(shareClassSymbol(symbol))) continue;
261
+ searched.add(shareClassSymbol(symbol));
262
+ const results = await dataProvider.search(symbol, { limit: LISTING_SEARCH_LIMIT });
263
+ for (const listing of listings) {
264
+ const listed = results.find((result) => shareClassSymbol(result.symbol) === shareClassSymbol(listing.symbol)
265
+ && (us ? isUsListingExchange(listedExchange(result)) : listedExchange(result) === listing.exchange));
266
+ // Abroad, the listing goes by search's own spelling of it, as the venue lists it.
267
+ const symbol = listed && !us ? listed.symbol.toUpperCase() : listing.symbol;
268
+ if (listed) return { ...code, symbol, exchange: listing.exchange, key: listing.exchange ? `${symbol}:${listing.exchange}` : symbol };
269
+ }
270
+ }
271
+ return verify ? null : code;
95
272
  } catch (error) {
96
273
  if (!isProviderBusy(error)) logFailure("tickers-company-name-listing", "Could not search a terminal code's root")(error);
97
274
  return code;
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Well-known index roots that people type bare. As a bare symbol each one is
3
+ * another instrument (MOVE is Corvex, MID a fund) or nothing at all (VIX); the
4
+ * index itself is quoted as ^ROOT. Every entry is offered as a command to run,
5
+ * so only roots whose ^ symbol returns a quote belong here.
6
+ */
7
+ const INDEX_ROOTS = new Map([
8
+ ["VIX", "Cboe Volatility Index"],
9
+ ["VVIX", "Cboe VIX of VIX Index"],
10
+ ["VIX9D", "Cboe S&P 500 9-Day Volatility Index"],
11
+ ["VIX3M", "Cboe S&P 500 3-Month Volatility Index"],
12
+ ["VXN", "Cboe Nasdaq-100 Volatility Index"],
13
+ ["OVX", "Cboe Crude Oil ETF Volatility Index"],
14
+ ["GVZ", "Cboe Gold ETF Volatility Index"],
15
+ ["SKEW", "Cboe SKEW Index"],
16
+ ["TNX", "Cboe 10-Year Treasury Yield Index"],
17
+ ["SPX", "S&P 500 Index"],
18
+ ["OEX", "S&P 100 Index"],
19
+ ["MID", "S&P MidCap 400 Index"],
20
+ ["DJI", "Dow Jones Industrial Average"],
21
+ ["NDX", "Nasdaq-100 Index"],
22
+ ["SOX", "PHLX Semiconductor Index"],
23
+ ["RUT", "Russell 2000 Index"],
24
+ ["RUI", "Russell 1000 Index"],
25
+ ["RUA", "Russell 3000 Index"],
26
+ ["MOVE", "ICE BofA MOVE Index"],
27
+ ["NYA", "NYSE Composite Index"],
28
+ ]);
29
+
30
+ export interface IndexRoot {
31
+ /** The index's own symbol: ^VIX. */
32
+ symbol: string;
33
+ name: string;
34
+ }
35
+
36
+ /** The index a bare root names (VIX is ^VIX); null for any other symbol, ^VIX included. */
37
+ export function indexRootFor(symbol: string): IndexRoot | null {
38
+ const root = symbol.trim().toUpperCase();
39
+ const name = INDEX_ROOTS.get(root);
40
+ return name ? { symbol: `^${root}`, name } : null;
41
+ }
42
+
43
+ /** "Did you mean ^VIX (Cboe Volatility Index)?" after a bare root that is not a ticker; null for any other symbol. */
44
+ export function indexRootSuggestion(symbol: string): string | null {
45
+ const root = indexRootFor(symbol);
46
+ return root ? `Did you mean ${root.symbol} (${root.name})?` : null;
47
+ }
@@ -1,4 +1,5 @@
1
1
  import type { BrokerContractRef } from "../types/instrument";
2
+ import { deliveryMonthLabel } from "../utils/contract-month";
2
3
 
3
4
  /** Identifying contract terms belong in the existing title, never in a new toolbar. */
4
5
  export function tickerInstrumentLabel(symbol: string, contract?: BrokerContractRef | null): string {
@@ -6,6 +7,9 @@ export function tickerInstrumentLabel(symbol: string, contract?: BrokerContractR
6
7
  const label = contract.localSymbol || symbol;
7
8
  // Brokers report strike 0 (and no expiry) on stocks; only a real strike identifies a derivative.
8
9
  const strike = typeof contract.strike === "number" && Number.isFinite(contract.strike) && contract.strike > 0 ? String(contract.strike) : undefined;
9
- const terms = [contract.lastTradeDateOrContractMonth, contract.right, strike].filter(Boolean);
10
+ // A future's month (IBKR's "202612") reads as every contract month does, "Dec 2026"; a dated expiry stays as the broker writes it.
11
+ const month = contract.secType === "FUT" && /^\d{6}$/.test(contract.lastTradeDateOrContractMonth ?? "")
12
+ ? deliveryMonthLabel(contract.lastTradeDateOrContractMonth) : null;
13
+ const terms = [month ?? contract.lastTradeDateOrContractMonth, contract.right, strike].filter(Boolean);
10
14
  return terms.length ? [label, ...terms].join(" ") : label;
11
15
  }
@@ -60,5 +60,15 @@ export function hydrateTickerMetadata(data: Record<string, unknown>): TickerMeta
60
60
  broker_contracts: Array.isArray(data.broker_contracts) ? [...data.broker_contracts] : [],
61
61
  custom: data.custom && typeof data.custom === "object" ? { ...(data.custom as Record<string, unknown>) } : {},
62
62
  tags: Array.isArray(data.tags) ? [...data.tags] : [],
63
+ ...hydrateMergedLots(data.mergedLots),
63
64
  };
64
65
  }
66
+
67
+ /** The merged-lots record, kept only as a map of keys to lists of strings. */
68
+ function hydrateMergedLots(raw: unknown): Pick<TickerMetadata, "mergedLots"> {
69
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return {};
70
+ const entries = Object.entries(raw as Record<string, unknown>)
71
+ .filter((entry): entry is [string, string[]] => Array.isArray(entry[1]) && entry[1].every((lot) => typeof lot === "string"))
72
+ .map(([key, lots]): [string, string[]] => [key, [...lots]]);
73
+ return entries.length > 0 ? { mergedLots: Object.fromEntries(entries) } : {};
74
+ }
@@ -37,6 +37,9 @@ export const PERPETUAL_TYPE = "PERP";
37
37
  /** Exchange codes of the perpetual venues, which trade around the clock. */
38
38
  export const PERPETUAL_EXCHANGES: readonly string[] = Object.keys(VENUE_BY_EXCHANGE);
39
39
 
40
+ /** Venues with no spot market, where a coin pair names a contract. */
41
+ const PERPETUALS_ONLY: ReadonlySet<string> = new Set(["hyperliquid", "dydx"]);
42
+
40
43
  /** A venue symbol: letters (any script), digits, dash, underscore and dot; no colon or space. */
41
44
  const VENUE_SYMBOL = /^[\p{L}\p{N}_.-]{1,64}$/u;
42
45
 
@@ -96,8 +99,8 @@ export function perpetualListing(symbol: string, exchange?: string | null): Perp
96
99
  const venue = VENUE_BY_EXCHANGE[venueCode];
97
100
  if (!venue || !VENUE_SYMBOL.test(parsed.symbol) || parsed.symbol.startsWith("-")) return null;
98
101
  // A coin pair (BTC-USD, as BTC/USD on Binance is read) is the venue's spot market; contracts there have no dash
99
- // before their quote currency. Hyperliquid's dash is its dex.
100
- if (venue !== "hyperliquid" && isCryptoPairSymbol(parsed.symbol)) return null;
102
+ // before their quote currency. Hyperliquid's dash is its dex, and dYdX trades only perpetuals, each named as a pair.
103
+ if (!PERPETUALS_ONLY.has(venue) && isCryptoPairSymbol(parsed.symbol)) return null;
101
104
  const marketId = venue === "hyperliquid"
102
105
  ? (() => {
103
106
  const dash = parsed.symbol.indexOf("-");
@@ -0,0 +1,75 @@
1
+ import { canonicalExchange } from "../../utils/exchanges";
2
+ import { companyNameExtraWords, sameCompany } from "../company-name";
3
+ import { answersOnlyByKeyword, isQualifiedTickerQuery } from "./ranking";
4
+ import type { TickerSearchCandidate } from "./types";
5
+
6
+ /** Venues that only quote shares listed elsewhere: the OTC tiers, Frankfurt's open market and Germany's regional exchanges. */
7
+ const SECONDARY_VENUES = new Set(["OTC", "PNK", "OTCQX", "OTCQB", "FWB2", "MUNICH", "XMUN", "XSTU", "XDUS", "XBER", "XHAM", "HANOVER", "XHAN"]);
8
+ const RECEIPT_TYPE = /depositary|^(?:ADR|ADS|GDR|CDR|BDR)$/i;
9
+
10
+ /** The venue a row lists on; broker routing (SMART) names its primary exchange. */
11
+ export function candidateExchange(candidate: TickerSearchCandidate): string {
12
+ return canonicalExchange(candidate.result?.exchange === "SMART"
13
+ ? candidate.result.primaryExchange
14
+ : candidate.result?.exchange || candidate.result?.primaryExchange || candidate.ticker?.metadata.exchange || candidate.right);
15
+ }
16
+
17
+ /**
18
+ * How far a listing is from being its company's own line: 0 a plain one, 1 a
19
+ * line that only quotes shares listed elsewhere (a regional venue, OTC, a
20
+ * Milan 4MSFT or London 0XXX code), 2 a depositary receipt.
21
+ */
22
+ export function listingDistance(candidate: TickerSearchCandidate): 0 | 1 | 2 {
23
+ return lineDistance(candidate.instrumentType ?? "", candidateExchange(candidate), candidate.symbol);
24
+ }
25
+
26
+ /** `listingDistance` of a line by its type, its canonical venue and its symbol. */
27
+ export function lineDistance(type: string, exchange: string, symbol: string): 0 | 1 | 2 {
28
+ if (RECEIPT_TYPE.test(type)) return 2;
29
+ return SECONDARY_VENUES.has(exchange) || /\d/.test(symbol) && /[A-Za-z]/.test(symbol) ? 1 : 0;
30
+ }
31
+
32
+ function candidateName(candidate: TickerSearchCandidate): string {
33
+ return candidate.result?.name || candidate.detail.split(" | ")[0] || "";
34
+ }
35
+
36
+ /** How many words two names of one company differ by: Sony Group Corp. is nearer Sony Group ADR than Sony Financial Group. */
37
+ function nameGap(left: string, right: string): number {
38
+ return companyNameExtraWords(left, right) ?? companyNameExtraWords(right, left) ?? Number.MAX_SAFE_INTEGER;
39
+ }
40
+
41
+ function isListedEquity(candidate: TickerSearchCandidate): boolean {
42
+ return candidate.kind === "search" && !candidate.saved
43
+ && (candidate.instrumentClass === "equity" || candidate.instrumentClass === "other");
44
+ }
45
+
46
+ /**
47
+ * The company search lists first is listed under its home line, its common
48
+ * stock on its home exchange, ahead of its depositary receipts: "Sony" and
49
+ * "LVMH" match receipts' tickers (SONY in New York, LVMH in Toronto), and a
50
+ * provider can file Toyota's NYSE receipt before Tokyo's 7203. The line the
51
+ * service marks as the company's home (`homeListing`) takes the lead from
52
+ * the company's first row. Without that mark, a receipt in the lead gives
53
+ * way to the company's own shares on an exchange (`listingDistance` 0, not
54
+ * an OTC or regional line), the name nearest the receipt's first. A query that names a venue (LVMH:TSX,
55
+ * 7203.T) asked for that line, and a saved row keeps the lead.
56
+ */
57
+ export function withHomeListingLead<T extends TickerSearchCandidate>(items: T[], query: string): T[] {
58
+ if (isQualifiedTickerQuery(query)) return items;
59
+ const lead = items.find((item) => item.instrumentClass !== "fund" && item.instrumentClass !== "derivative"
60
+ && !answersOnlyByKeyword(item, query));
61
+ if (!lead || !isListedEquity(lead)) return items;
62
+ const name = candidateName(lead);
63
+ const lines = items.filter((item) => item !== lead && isListedEquity(item) && sameCompany(name, candidateName(item)));
64
+ const nearest = (candidates: T[]) => [...candidates].sort((a, b) => nameGap(name, candidateName(a)) - nameGap(name, candidateName(b))
65
+ || items.indexOf(a) - items.indexOf(b))[0];
66
+ const marked = lines.filter((item) => item.result?.homeListing === true);
67
+ const home = lead.result?.homeListing === true ? undefined
68
+ : marked.length ? nearest(marked)
69
+ : listingDistance(lead) === 2 ? nearest(lines.filter((item) => listingDistance(item) === 0))
70
+ : undefined;
71
+ if (!home) return items;
72
+ const rest = items.filter((item) => item !== home);
73
+ const at = rest.indexOf(lead);
74
+ return [...rest.slice(0, at), home, ...rest.slice(at)];
75
+ }