gloomberb 0.16.0 → 0.16.2

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 (691) hide show
  1. package/README.md +2 -1
  2. package/package.json +2 -1
  3. package/src/api-client/beneficial-owners.ts +92 -0
  4. package/src/api-client/data.ts +44 -11
  5. package/src/api-client/errors.ts +12 -0
  6. package/src/api-client/geo.ts +363 -0
  7. package/src/api-client/index.ts +5 -0
  8. package/src/api-client/market-discovery.ts +10 -0
  9. package/src/api-client/members.ts +26 -0
  10. package/src/api-client/paths.ts +30 -1
  11. package/src/api-client/perps.ts +41 -0
  12. package/src/api-client/request.ts +5 -2
  13. package/src/api-client/types.ts +9 -1
  14. package/src/app/global-shortcuts.ts +14 -6
  15. package/src/app/keybindings/actions.ts +1 -1
  16. package/src/app/runtime/update.ts +38 -2
  17. package/src/app.tsx +10 -6
  18. package/src/brokers/account-cache.ts +24 -0
  19. package/src/cli/commands/command-utils.ts +8 -0
  20. package/src/cli/commands/crypto-hints.ts +75 -0
  21. package/src/cli/commands/market.ts +414 -106
  22. package/src/cli/commands/overview.ts +77 -32
  23. package/src/cli/commands/ticker.ts +101 -43
  24. package/src/cli/desktop-pane-shot.ts +34 -4
  25. package/src/cli/freshness.ts +61 -0
  26. package/src/cli/help.ts +1 -0
  27. package/src/cli/helpers.ts +4 -8
  28. package/src/cli/index.ts +12 -2
  29. package/src/cli/listing-arg.ts +321 -0
  30. package/src/cli/pane-functions/access-gate.ts +42 -0
  31. package/src/cli/pane-functions/catalog.ts +28 -1
  32. package/src/cli/pane-functions/data.ts +3 -1
  33. package/src/cli/pane-functions/dom.ts +20 -2
  34. package/src/cli/pane-functions/freshness.ts +400 -0
  35. package/src/cli/pane-functions/function-help.ts +36 -22
  36. package/src/cli/pane-functions/headless.ts +39 -11
  37. package/src/cli/pane-functions/index.ts +15 -4
  38. package/src/cli/pane-functions/options.ts +3 -0
  39. package/src/cli/pane-functions/report.ts +4 -0
  40. package/src/cli/pane-functions/resolver.ts +35 -7
  41. package/src/cli/pane-functions/screenshot-evidence.ts +2 -0
  42. package/src/cli/pane-functions/screenshot.ts +7 -3
  43. package/src/cli/result.ts +41 -27
  44. package/src/cli/ticker-resolution.ts +7 -5
  45. package/src/components/chart/composite/composite-chart.tsx +88 -2536
  46. package/src/components/chart/composite/drawing-store.ts +59 -0
  47. package/src/components/chart/composite/legend.tsx +319 -0
  48. package/src/components/chart/composite/panel-bitmap.ts +139 -0
  49. package/src/components/chart/composite/panel-gestures.ts +59 -0
  50. package/src/components/chart/composite/panel-labels.ts +107 -0
  51. package/src/components/chart/composite/panel-surface.tsx +876 -0
  52. package/src/components/chart/composite/tool-catalog.ts +98 -0
  53. package/src/components/chart/composite/toolbar.tsx +186 -0
  54. package/src/components/chart/composite/tools.ts +8 -0
  55. package/src/components/chart/composite/use-composite-chart-keyboard.ts +703 -0
  56. package/src/components/chart/composite/use-composite-viewport.ts +143 -0
  57. package/src/components/command-bar/commands/collection.ts +5 -1
  58. package/src/components/command-bar/list/model.ts +5 -0
  59. package/src/components/command-bar/list/view.tsx +16 -3
  60. package/src/components/command-bar/pane-templates/workflow.ts +1 -0
  61. package/src/components/command-bar/routes/root/command-items.ts +9 -2
  62. package/src/components/command-bar/routes/root/plugin-install.ts +2 -2
  63. package/src/components/command-bar/routes/root/provider-search.ts +19 -5
  64. package/src/components/command-bar/routes/root/runtime.ts +14 -5
  65. package/src/components/command-bar/routes/ticker-search/actions.ts +5 -0
  66. package/src/components/command-bar/routes/ticker-search/results.ts +31 -5
  67. package/src/components/command-bar/routes/ticker-search/route.ts +2 -2
  68. package/src/components/command-bar/routing/actions.ts +2 -0
  69. package/src/components/command-bar/selection-runtime.ts +38 -0
  70. package/src/components/command-bar/surface/index.tsx +7 -2
  71. package/src/components/command-bar/workflow/ops.ts +1 -1
  72. package/src/components/command-bar/workflow/tickers.ts +6 -0
  73. package/src/components/data-table/view.tsx +29 -10
  74. package/src/components/feedback-dialog.tsx +2 -1
  75. package/src/components/form-modal/field-row.tsx +2 -2
  76. package/src/components/index.ts +2 -2
  77. package/src/components/layout/detached-pane-shell.tsx +6 -3
  78. package/src/components/layout/floating-pane.tsx +6 -0
  79. package/src/components/layout/header.tsx +24 -7
  80. package/src/components/layout/missing-pane.tsx +2 -2
  81. package/src/components/layout/pane/content.tsx +23 -10
  82. package/src/components/layout/pane/error-boundary.tsx +103 -0
  83. package/src/components/layout/pane/footer/registration.tsx +68 -23
  84. package/src/components/layout/pane/header.tsx +61 -28
  85. package/src/components/layout/pane/index.tsx +6 -0
  86. package/src/components/layout/pane/title.ts +31 -7
  87. package/src/components/layout/shell/drag/index.ts +6 -5
  88. package/src/components/layout/shell/drag/runtime.ts +3 -0
  89. package/src/components/layout/shell/index.tsx +6 -0
  90. package/src/components/layout/shell/menu.ts +2 -1
  91. package/src/components/layout/shell/pane/actions.ts +2 -1
  92. package/src/components/layout/shell/pane/layers.tsx +29 -10
  93. package/src/components/layout/shell/terminal-pointer-runtime.ts +24 -3
  94. package/src/components/layout/shell/ticker-link-menu.ts +23 -9
  95. package/src/components/metric-treemap/heat-surface.tsx +745 -0
  96. package/src/components/metric-treemap/heat-tiles.ts +228 -0
  97. package/src/components/metric-treemap/index.tsx +2 -0
  98. package/src/components/metric-treemap/layout.ts +8 -0
  99. package/src/components/metric-treemap/scene.ts +432 -0
  100. package/src/components/onboarding/onboarding-keyboard.ts +311 -0
  101. package/src/components/onboarding/onboarding-wizard.tsx +101 -788
  102. package/src/components/onboarding/use-onboarding-broker-form.ts +263 -0
  103. package/src/components/onboarding/use-onboarding-progress.ts +298 -0
  104. package/src/components/onboarding/use-onboarding-upgrade.ts +83 -0
  105. package/src/components/pane-settings-dialog/field-dialogs.tsx +1 -0
  106. package/src/components/ticker/list-table-view.tsx +13 -1
  107. package/src/components/toggle-list.tsx +38 -12
  108. package/src/components/ui/country-flag-art.tsx +449 -0
  109. package/src/components/ui/country-flag.tsx +41 -0
  110. package/src/components/ui/data-table/types.ts +13 -0
  111. package/src/components/ui/fields.tsx +8 -0
  112. package/src/components/ui/icon.tsx +2 -0
  113. package/src/components/ui/index.ts +4 -0
  114. package/src/components/ui/multi-select/dialog.tsx +108 -22
  115. package/src/components/ui/range-track.tsx +53 -0
  116. package/src/components/ui/status.tsx +8 -2
  117. package/src/components/ui/tabs.tsx +11 -4
  118. package/src/components/ui/text-prompt-dialog.tsx +4 -2
  119. package/src/core/state/app/types.ts +10 -1
  120. package/src/data/config/store/normalize.ts +17 -1
  121. package/src/i18n/es.ts +24 -4
  122. package/src/i18n/ja.ts +24 -4
  123. package/src/i18n/ko.ts +24 -4
  124. package/src/i18n/zh-cn.ts +24 -4
  125. package/src/i18n/zh-tw.ts +24 -4
  126. package/src/layout/ticker-navigation.ts +28 -2
  127. package/src/market-data/coordinator/chart.ts +1 -1
  128. package/src/market-data/coordinator/quotes.ts +23 -4
  129. package/src/market-data/fx-closes.ts +72 -0
  130. package/src/market-data/market/freshness.ts +78 -6
  131. package/src/market-data/market/session-close-note.ts +57 -0
  132. package/src/market-data/market/status.ts +151 -0
  133. package/src/market-data/published-apac-sessions.ts +66 -0
  134. package/src/market-data/quotes/contributions.ts +8 -0
  135. package/src/market-data/quotes/freshness.ts +36 -0
  136. package/src/market-data/quotes/resolution.ts +24 -8
  137. package/src/market-data/quotes/screener-live-quotes.ts +49 -4
  138. package/src/market-data/quotes/time.ts +16 -0
  139. package/src/plugins/builtin/account-management/pane.tsx +4 -0
  140. package/src/plugins/builtin/alerts/cli.ts +10 -5
  141. package/src/plugins/builtin/alerts/index.tsx +1 -0
  142. package/src/plugins/builtin/analytics/metrics.ts +8 -3
  143. package/src/plugins/builtin/analytics/risk-client.ts +330 -79
  144. package/src/plugins/builtin/analytics/risk-fx.ts +102 -0
  145. package/src/plugins/builtin/analytics/risk-headless.ts +61 -49
  146. package/src/plugins/builtin/analytics/risk-math.ts +33 -13
  147. package/src/plugins/builtin/analytics/risk-model.ts +282 -64
  148. package/src/plugins/builtin/analytics/risk-pane.tsx +62 -30
  149. package/src/plugins/builtin/analytics/risk-test-data.ts +206 -0
  150. package/src/plugins/builtin/attention/headless.ts +6 -4
  151. package/src/plugins/builtin/attention/index.tsx +1 -1
  152. package/src/plugins/builtin/attention/pane.tsx +1 -1
  153. package/src/plugins/builtin/awards/headless.ts +1 -0
  154. package/src/plugins/builtin/awards/pane.tsx +1 -1
  155. package/src/plugins/builtin/backtest/headless.ts +1 -0
  156. package/src/plugins/builtin/bond-calculator/headless.ts +1 -0
  157. package/src/plugins/builtin/buildout/cells.tsx +15 -12
  158. package/src/plugins/builtin/buildout/detail/company.tsx +3 -3
  159. package/src/plugins/builtin/buildout/detail/index.tsx +0 -1
  160. package/src/plugins/builtin/buildout/detail/intel.tsx +6 -6
  161. package/src/plugins/builtin/buildout/detail/site.tsx +4 -7
  162. package/src/plugins/builtin/buildout/detail/ui.tsx +0 -19
  163. package/src/plugins/builtin/buildout/index.tsx +1 -0
  164. package/src/plugins/builtin/catalysts/headless.ts +3 -1
  165. package/src/plugins/builtin/catalysts/index.tsx +2 -2
  166. package/src/plugins/builtin/catalysts/pane.tsx +3 -1
  167. package/src/plugins/builtin/cds/headless.ts +2 -0
  168. package/src/plugins/builtin/cds/index.tsx +1 -0
  169. package/src/plugins/builtin/central-bank-rates/headless.ts +1 -0
  170. package/src/plugins/builtin/chart-composer/headless.ts +38 -3
  171. package/src/plugins/builtin/chart-composer/index.tsx +3 -1
  172. package/src/plugins/builtin/chart-composer/series-expression.ts +18 -2
  173. package/src/plugins/builtin/chat/channels.ts +19 -3
  174. package/src/plugins/builtin/chat/content/composer-runtime.ts +28 -13
  175. package/src/plugins/builtin/chat/content/footer.tsx +15 -6
  176. package/src/plugins/builtin/chat/content/index.tsx +120 -21
  177. package/src/plugins/builtin/chat/content/new-dm-dialog.tsx +261 -113
  178. package/src/plugins/builtin/chat/content/transcript.tsx +20 -2
  179. package/src/plugins/builtin/chat/direct-messages.ts +200 -0
  180. package/src/plugins/builtin/chat/index.tsx +1 -0
  181. package/src/plugins/builtin/chat/message/desktop.tsx +3 -0
  182. package/src/plugins/builtin/chat/message/header.tsx +16 -6
  183. package/src/plugins/builtin/chat/message/inline-tokens.tsx +72 -32
  184. package/src/plugins/builtin/chat/message/profile-popover.tsx +96 -12
  185. package/src/plugins/builtin/chat/message/terminal.tsx +3 -0
  186. package/src/plugins/builtin/chat/message/types.ts +14 -2
  187. package/src/plugins/builtin/chat/profile-popover.ts +18 -13
  188. package/src/plugins/builtin/clinical-trials/index.tsx +1 -0
  189. package/src/plugins/builtin/cloud/askg/executor.ts +2 -1
  190. package/src/plugins/builtin/cloud/plugin.tsx +1 -0
  191. package/src/plugins/builtin/cloud/team/module.tsx +1 -0
  192. package/src/plugins/builtin/cloud/thesis/module.tsx +1 -0
  193. package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
  194. package/src/plugins/builtin/comment-letters/index.tsx +1 -0
  195. package/src/plugins/builtin/company-attention/headless.ts +5 -1
  196. package/src/plugins/builtin/company-attention/pane.tsx +1 -1
  197. package/src/plugins/builtin/company-kpis/headless.ts +1 -0
  198. package/src/plugins/builtin/congress-trades/headless.ts +1 -0
  199. package/src/plugins/builtin/correlation/compute.ts +59 -16
  200. package/src/plugins/builtin/correlation/geo.ts +34 -0
  201. package/src/plugins/builtin/correlation/headless-schema.ts +4 -1
  202. package/src/plugins/builtin/correlation/headless.ts +42 -8
  203. package/src/plugins/builtin/correlation/history.ts +2 -0
  204. package/src/plugins/builtin/correlation/index.tsx +68 -14
  205. package/src/plugins/builtin/correlation/matrix/model.ts +17 -2
  206. package/src/plugins/builtin/correlation/matrix/selection.ts +5 -3
  207. package/src/plugins/builtin/correlation/relationship/model.ts +1 -1
  208. package/src/plugins/builtin/correlation/relationship/pane.tsx +4 -2
  209. package/src/plugins/builtin/correlation/relationship/view-model.ts +16 -1
  210. package/src/plugins/builtin/correlation/settings.ts +1 -1
  211. package/src/plugins/builtin/cot/headless.ts +6 -3
  212. package/src/plugins/builtin/cot/index.tsx +3 -3
  213. package/src/plugins/builtin/cot/model.ts +36 -3
  214. package/src/plugins/builtin/cpi/headless.ts +4 -0
  215. package/src/plugins/builtin/credit-boards/headless.ts +2 -0
  216. package/src/plugins/builtin/credit-conditions/headless.ts +1 -0
  217. package/src/plugins/builtin/credit-documents/gauge.tsx +5 -8
  218. package/src/plugins/builtin/credit-documents/headless.ts +2 -0
  219. package/src/plugins/builtin/crypto-board/headless.ts +3 -0
  220. package/src/plugins/builtin/custom-view/loader.ts +1 -1
  221. package/src/plugins/builtin/debt-maturities/headless.ts +4 -0
  222. package/src/plugins/builtin/debt-maturities/wall-bar.tsx +14 -41
  223. package/src/plugins/builtin/dividend-yield/client.ts +4 -2
  224. package/src/plugins/builtin/dividend-yield/headless.ts +1 -0
  225. package/src/plugins/builtin/doe/headless.ts +7 -0
  226. package/src/plugins/builtin/doe/range-bar.tsx +7 -37
  227. package/src/plugins/builtin/earnings/client.ts +2 -2
  228. package/src/plugins/builtin/earnings/headless.ts +5 -0
  229. package/src/plugins/builtin/earnings-calls/headless.ts +1 -0
  230. package/src/plugins/builtin/earnings-calls/index.tsx +1 -0
  231. package/src/plugins/builtin/earnings-ripple/client.ts +91 -18
  232. package/src/plugins/builtin/earnings-ripple/headless.ts +28 -8
  233. package/src/plugins/builtin/earnings-ripple/index.tsx +2 -2
  234. package/src/plugins/builtin/earnings-ripple/model.ts +97 -7
  235. package/src/plugins/builtin/earnings-ripple/pane.tsx +148 -23
  236. package/src/plugins/builtin/econ/index.tsx +1 -0
  237. package/src/plugins/builtin/econ-statistics/headless.ts +2 -0
  238. package/src/plugins/builtin/equity-screener/headless.ts +2 -0
  239. package/src/plugins/builtin/estimate-revisions/headless.ts +1 -0
  240. package/src/plugins/builtin/executives/index.tsx +1 -0
  241. package/src/plugins/builtin/exposure/headless.ts +3 -1
  242. package/src/plugins/builtin/fear-greed/headless.ts +2 -0
  243. package/src/plugins/builtin/filing-events/index.tsx +1 -0
  244. package/src/plugins/builtin/futures-curve/client.ts +12 -3
  245. package/src/plugins/builtin/futures-curve/headless.ts +39 -10
  246. package/src/plugins/builtin/futures-curve/index.tsx +3 -3
  247. package/src/plugins/builtin/futures-curve/model.ts +188 -4
  248. package/src/plugins/builtin/futures-curve/pane.tsx +51 -9
  249. package/src/plugins/builtin/fx-matrix/direction.ts +81 -0
  250. package/src/plugins/builtin/fx-matrix/index.tsx +71 -33
  251. package/src/plugins/builtin/fx-matrix/live-legs.ts +17 -0
  252. package/src/plugins/builtin/fx-matrix/pairs.ts +68 -14
  253. package/src/plugins/builtin/fx-matrix/settings.ts +62 -0
  254. package/src/plugins/builtin/gpu/headless.ts +7 -3
  255. package/src/plugins/builtin/gpu/ladder.tsx +26 -30
  256. package/src/plugins/builtin/gpu/model.ts +27 -1
  257. package/src/plugins/builtin/holders/beneficial-client.ts +209 -0
  258. package/src/plugins/builtin/holders/beneficial-model.ts +279 -0
  259. package/src/plugins/builtin/holders/beneficial-report.ts +126 -0
  260. package/src/plugins/builtin/holders/beneficial-view.tsx +241 -0
  261. package/src/plugins/builtin/holders/headless.ts +139 -5
  262. package/src/plugins/builtin/holders/index.tsx +10 -3
  263. package/src/plugins/builtin/holders/pane.tsx +20 -3
  264. package/src/plugins/builtin/holders/report-header.ts +95 -0
  265. package/src/plugins/builtin/holders/table-model.ts +20 -5
  266. package/src/plugins/builtin/holders/thirteenf-match.ts +29 -1
  267. package/src/plugins/builtin/holders/types.ts +2 -1
  268. package/src/plugins/builtin/insider/headless.ts +2 -0
  269. package/src/plugins/builtin/ipo-calendar/headless.ts +1 -0
  270. package/src/plugins/builtin/iv-history/headless.ts +4 -1
  271. package/src/plugins/builtin/jobs/headless.ts +1 -0
  272. package/src/plugins/builtin/jobs/index.tsx +1 -0
  273. package/src/plugins/builtin/jobs/share-bars.tsx +5 -28
  274. package/src/plugins/builtin/kelly-sizer/index.tsx +1 -0
  275. package/src/plugins/builtin/macro-day/headless.ts +2 -0
  276. package/src/plugins/builtin/market-halts/index.tsx +1 -0
  277. package/src/plugins/builtin/market-heatmap/data.ts +30 -2
  278. package/src/plugins/builtin/market-heatmap/headless.ts +135 -0
  279. package/src/plugins/builtin/market-heatmap/index.tsx +245 -81
  280. package/src/plugins/builtin/market-heatmap/live.ts +88 -0
  281. package/src/plugins/builtin/market-heatmap/model.ts +146 -0
  282. package/src/plugins/builtin/market-heatmap/portfolio.ts +50 -11
  283. package/src/plugins/builtin/market-movers/client.ts +3 -2
  284. package/src/plugins/builtin/market-movers/headless.ts +10 -1
  285. package/src/plugins/builtin/market-movers/screener.ts +18 -5
  286. package/src/plugins/builtin/market-valuation/headless.ts +2 -0
  287. package/src/plugins/builtin/members/client.ts +53 -0
  288. package/src/plugins/builtin/members/headless.ts +35 -0
  289. package/src/plugins/builtin/members/index.tsx +20 -0
  290. package/src/plugins/builtin/members/model.ts +68 -0
  291. package/src/plugins/builtin/members/pane.tsx +175 -0
  292. package/src/plugins/builtin/mna/distress/headless.ts +1 -0
  293. package/src/plugins/builtin/mna/headless.ts +1 -0
  294. package/src/plugins/builtin/mna/index.tsx +2 -1
  295. package/src/plugins/builtin/mna/pane.tsx +5 -2
  296. package/src/plugins/builtin/money-markets/headless.ts +1 -0
  297. package/src/plugins/builtin/news/headless.ts +2 -0
  298. package/src/plugins/builtin/news/wire/index.tsx +8 -1
  299. package/src/plugins/builtin/notes/cli.ts +14 -6
  300. package/src/plugins/builtin/notes/index.tsx +1 -0
  301. package/src/plugins/builtin/openfda/index.tsx +1 -0
  302. package/src/plugins/builtin/options/index.tsx +2 -1
  303. package/src/plugins/builtin/options-calculator/headless.ts +2 -0
  304. package/src/plugins/builtin/options-positioning/headless.ts +3 -0
  305. package/src/plugins/builtin/options-scenario/headless.ts +5 -0
  306. package/src/plugins/builtin/pe-band/client.ts +74 -2
  307. package/src/plugins/builtin/pe-band/headless.ts +26 -8
  308. package/src/plugins/builtin/pe-band/model.ts +102 -22
  309. package/src/plugins/builtin/pe-band/pane.tsx +34 -16
  310. package/src/plugins/builtin/pe-band/report-dates.ts +78 -0
  311. package/src/plugins/builtin/perps/client.ts +66 -5
  312. package/src/plugins/builtin/perps/equity-identity.ts +16 -0
  313. package/src/plugins/builtin/perps/equity-row.tsx +6 -4
  314. package/src/plugins/builtin/perps/headless.ts +144 -16
  315. package/src/plugins/builtin/perps/index.tsx +6 -6
  316. package/src/plugins/builtin/perps/model.ts +189 -12
  317. package/src/plugins/builtin/perps/pane.tsx +248 -47
  318. package/src/plugins/builtin/plugin-marketplace/activation.ts +19 -0
  319. package/src/plugins/builtin/plugin-marketplace/pane.tsx +2 -2
  320. package/src/plugins/builtin/plugin-marketplace/store.ts +2 -0
  321. package/src/plugins/builtin/portfolio-list/allocation.ts +245 -0
  322. package/src/plugins/builtin/portfolio-list/cached-account.ts +33 -0
  323. package/src/plugins/builtin/portfolio-list/cell-version.ts +19 -1
  324. package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +328 -29
  325. package/src/plugins/builtin/portfolio-list/cli/render.ts +230 -39
  326. package/src/plugins/builtin/portfolio-list/cli/shared.ts +67 -2
  327. package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +35 -31
  328. package/src/plugins/builtin/portfolio-list/column-values.ts +124 -47
  329. package/src/plugins/builtin/portfolio-list/headless.ts +98 -16
  330. package/src/plugins/builtin/portfolio-list/index.tsx +14 -3
  331. package/src/plugins/builtin/portfolio-list/live-valuation.ts +7 -5
  332. package/src/plugins/builtin/portfolio-list/mutations.ts +55 -1
  333. package/src/plugins/builtin/portfolio-list/pane/data.ts +6 -0
  334. package/src/plugins/builtin/portfolio-list/pane/index.tsx +47 -13
  335. package/src/plugins/builtin/portfolio-list/quick-add/index.tsx +43 -2
  336. package/src/plugins/builtin/portfolio-list/quick-add/resolution.ts +48 -5
  337. package/src/plugins/builtin/portfolio-list/settings.ts +33 -2
  338. package/src/plugins/builtin/portfolio-list/summary/index.tsx +24 -1
  339. package/src/plugins/builtin/portfolio-list/summary/totals.ts +26 -7
  340. package/src/plugins/builtin/power/headless.ts +3 -1
  341. package/src/plugins/builtin/rate-path/headless.ts +2 -0
  342. package/src/plugins/builtin/realized-vol/headless.ts +2 -0
  343. package/src/plugins/builtin/relative-rotation/headless.ts +2 -0
  344. package/src/plugins/builtin/research/analyst-headless.ts +3 -0
  345. package/src/plugins/builtin/research/events-headless.ts +2 -0
  346. package/src/plugins/builtin/research/headless.ts +2 -0
  347. package/src/plugins/builtin/research/index.tsx +1 -0
  348. package/src/plugins/builtin/research/relative-valuation-headless.ts +10 -5
  349. package/src/plugins/builtin/research/relative-valuation-model.ts +11 -3
  350. package/src/plugins/builtin/research/relative-valuation-pane.tsx +3 -3
  351. package/src/plugins/builtin/research-search/index.tsx +1 -0
  352. package/src/plugins/builtin/revenue-breakdown/headless.ts +2 -0
  353. package/src/plugins/builtin/reverse-dcf/headless.ts +2 -0
  354. package/src/plugins/builtin/risk-factors/headless.ts +2 -0
  355. package/src/plugins/builtin/scanner/flow-history.ts +2 -13
  356. package/src/plugins/builtin/scanner/headless.ts +14 -0
  357. package/src/plugins/builtin/scanner/hilo-bars.tsx +12 -70
  358. package/src/plugins/builtin/scanner/hilo-model.ts +0 -18
  359. package/src/plugins/builtin/seasonality/headless.ts +2 -0
  360. package/src/plugins/builtin/sec/command-bar-search.ts +14 -4
  361. package/src/plugins/builtin/sec/filing-content.ts +42 -17
  362. package/src/plugins/builtin/sec/forms.ts +12 -0
  363. package/src/plugins/builtin/sec/headless.ts +2 -0
  364. package/src/plugins/builtin/sectors/client.ts +1 -0
  365. package/src/plugins/builtin/sectors/headless.ts +9 -1
  366. package/src/plugins/builtin/sectors/move-bar.tsx +10 -32
  367. package/src/plugins/builtin/sectors/sector-model.ts +2 -0
  368. package/src/plugins/builtin/shared/crypto-pair.ts +14 -0
  369. package/src/plugins/builtin/shared/locked-rows.tsx +1 -1
  370. package/src/plugins/builtin/shared/report-freshness.ts +57 -0
  371. package/src/plugins/builtin/shared/research-cells.tsx +4 -9
  372. package/src/plugins/builtin/short-interest/headless.ts +2 -0
  373. package/src/plugins/builtin/short-interest/watch-headless.ts +1 -0
  374. package/src/plugins/builtin/short-volume/headless.ts +1 -0
  375. package/src/plugins/builtin/social-mentions/headless.ts +1 -0
  376. package/src/plugins/builtin/social-mentions/index.tsx +1 -1
  377. package/src/plugins/builtin/supply-chain/headless.ts +7 -1
  378. package/src/plugins/builtin/supply-chain/index.tsx +10 -1
  379. package/src/plugins/builtin/supply-chain/model.ts +27 -2
  380. package/src/plugins/builtin/supply-chain/pane.tsx +71 -32
  381. package/src/plugins/builtin/themes/headless.ts +3 -0
  382. package/src/plugins/builtin/thirteenf/headless.ts +110 -25
  383. package/src/plugins/builtin/thirteenf/index.tsx +2 -1
  384. package/src/plugins/builtin/thirteenf/report-notes.ts +149 -0
  385. package/src/plugins/builtin/ticker-detail/headless.ts +7 -1
  386. package/src/plugins/builtin/ticker-detail/index.tsx +1 -0
  387. package/src/plugins/builtin/ticker-detail/overview/components.tsx +5 -60
  388. package/src/plugins/builtin/ticker-detail/overview/model.ts +9 -2
  389. package/src/plugins/builtin/ticker-detail/overview/pane.tsx +1 -1
  390. package/src/plugins/builtin/ticker-detail/overview-tab.tsx +26 -26
  391. package/src/plugins/builtin/ticker-detail/pane.tsx +1 -1
  392. package/src/plugins/builtin/ticker-detail/quote-footer.ts +7 -1
  393. package/src/plugins/builtin/ticker-detail/quote-monitor/card.tsx +20 -4
  394. package/src/plugins/builtin/ticker-detail/quote-monitor/index.tsx +2 -2
  395. package/src/plugins/builtin/time-sales/headless.ts +5 -1
  396. package/src/plugins/builtin/treasury-auctions/headless.ts +1 -0
  397. package/src/plugins/builtin/vol-surface/index.tsx +1 -1
  398. package/src/plugins/builtin/volatility/headless.ts +6 -1
  399. package/src/plugins/builtin/world-indices/headless.ts +2 -0
  400. package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +157 -0
  401. package/src/plugins/builtin/world-venue-map/basemap.ts +214 -0
  402. package/src/plugins/builtin/world-venue-map/client.ts +45 -0
  403. package/src/plugins/builtin/world-venue-map/entity-detail.tsx +147 -0
  404. package/src/plugins/builtin/world-venue-map/entity-table.ts +59 -0
  405. package/src/plugins/builtin/world-venue-map/evidence.ts +77 -0
  406. package/src/plugins/builtin/world-venue-map/feed.ts +293 -0
  407. package/src/plugins/builtin/world-venue-map/geo-draw.tsx +248 -0
  408. package/src/plugins/builtin/world-venue-map/geo-series.ts +142 -0
  409. package/src/plugins/builtin/world-venue-map/geo-svg.tsx +447 -0
  410. package/src/plugins/builtin/world-venue-map/headless.ts +146 -0
  411. package/src/plugins/builtin/world-venue-map/ids.ts +1 -0
  412. package/src/plugins/builtin/world-venue-map/index.ts +67 -4
  413. package/src/plugins/builtin/world-venue-map/layered-pane.tsx +552 -0
  414. package/src/plugins/builtin/world-venue-map/layers.ts +348 -0
  415. package/src/plugins/builtin/world-venue-map/map-symbols.ts +220 -0
  416. package/src/plugins/builtin/world-venue-map/map.tsx +381 -45
  417. package/src/plugins/builtin/world-venue-map/model.ts +7 -4
  418. package/src/plugins/builtin/world-venue-map/natural-earth/index.chunk.ts +199 -0
  419. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n00.chunk.ts +4 -0
  420. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n15.chunk.ts +4 -0
  421. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n30.chunk.ts +4 -0
  422. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n45.chunk.ts +4 -0
  423. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n60.chunk.ts +4 -0
  424. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000n75.chunk.ts +4 -0
  425. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000s15.chunk.ts +4 -0
  426. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000s30.chunk.ts +4 -0
  427. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e000s60.chunk.ts +4 -0
  428. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n00.chunk.ts +4 -0
  429. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n15.chunk.ts +4 -0
  430. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n30.chunk.ts +4 -0
  431. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n45.chunk.ts +4 -0
  432. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n60.chunk.ts +4 -0
  433. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015n75.chunk.ts +4 -0
  434. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015s15.chunk.ts +4 -0
  435. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015s30.chunk.ts +4 -0
  436. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e015s45.chunk.ts +4 -0
  437. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n00.chunk.ts +4 -0
  438. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n15.chunk.ts +4 -0
  439. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n30.chunk.ts +4 -0
  440. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n45.chunk.ts +4 -0
  441. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n60.chunk.ts +4 -0
  442. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030n75.chunk.ts +4 -0
  443. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s15.chunk.ts +4 -0
  444. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s30.chunk.ts +4 -0
  445. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s45.chunk.ts +4 -0
  446. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e030s60.chunk.ts +4 -0
  447. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n00.chunk.ts +4 -0
  448. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n15.chunk.ts +4 -0
  449. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n30.chunk.ts +4 -0
  450. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n45.chunk.ts +4 -0
  451. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n60.chunk.ts +4 -0
  452. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045n75.chunk.ts +4 -0
  453. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045s15.chunk.ts +4 -0
  454. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045s30.chunk.ts +4 -0
  455. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e045s60.chunk.ts +4 -0
  456. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n00.chunk.ts +4 -0
  457. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n15.chunk.ts +4 -0
  458. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n30.chunk.ts +4 -0
  459. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n45.chunk.ts +4 -0
  460. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n60.chunk.ts +4 -0
  461. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060n75.chunk.ts +4 -0
  462. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060s15.chunk.ts +4 -0
  463. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060s30.chunk.ts +4 -0
  464. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e060s60.chunk.ts +4 -0
  465. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n00.chunk.ts +4 -0
  466. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n15.chunk.ts +4 -0
  467. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n30.chunk.ts +4 -0
  468. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n45.chunk.ts +4 -0
  469. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n60.chunk.ts +4 -0
  470. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075n75.chunk.ts +4 -0
  471. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e075s45.chunk.ts +4 -0
  472. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n00.chunk.ts +4 -0
  473. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n15.chunk.ts +4 -0
  474. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n30.chunk.ts +4 -0
  475. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n45.chunk.ts +4 -0
  476. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n60.chunk.ts +4 -0
  477. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090n75.chunk.ts +4 -0
  478. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e090s15.chunk.ts +4 -0
  479. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n00.chunk.ts +4 -0
  480. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n15.chunk.ts +4 -0
  481. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n30.chunk.ts +4 -0
  482. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n45.chunk.ts +4 -0
  483. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n60.chunk.ts +4 -0
  484. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105n75.chunk.ts +4 -0
  485. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105s15.chunk.ts +4 -0
  486. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105s30.chunk.ts +4 -0
  487. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e105s45.chunk.ts +4 -0
  488. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n00.chunk.ts +4 -0
  489. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n15.chunk.ts +4 -0
  490. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n30.chunk.ts +4 -0
  491. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n45.chunk.ts +4 -0
  492. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120n60.chunk.ts +4 -0
  493. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120s15.chunk.ts +4 -0
  494. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120s30.chunk.ts +4 -0
  495. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e120s45.chunk.ts +4 -0
  496. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n00.chunk.ts +4 -0
  497. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n15.chunk.ts +4 -0
  498. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n30.chunk.ts +4 -0
  499. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n45.chunk.ts +4 -0
  500. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n60.chunk.ts +4 -0
  501. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135n75.chunk.ts +4 -0
  502. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135s15.chunk.ts +4 -0
  503. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135s30.chunk.ts +4 -0
  504. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e135s45.chunk.ts +4 -0
  505. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n00.chunk.ts +4 -0
  506. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n15.chunk.ts +4 -0
  507. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n45.chunk.ts +4 -0
  508. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n60.chunk.ts +4 -0
  509. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150n75.chunk.ts +4 -0
  510. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s15.chunk.ts +4 -0
  511. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s30.chunk.ts +4 -0
  512. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s45.chunk.ts +4 -0
  513. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e150s60.chunk.ts +4 -0
  514. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n00.chunk.ts +4 -0
  515. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n15.chunk.ts +4 -0
  516. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n45.chunk.ts +4 -0
  517. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165n60.chunk.ts +4 -0
  518. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s15.chunk.ts +4 -0
  519. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s30.chunk.ts +4 -0
  520. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s45.chunk.ts +4 -0
  521. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/e165s60.chunk.ts +4 -0
  522. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n00.chunk.ts +4 -0
  523. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n15.chunk.ts +4 -0
  524. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n30.chunk.ts +4 -0
  525. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n45.chunk.ts +4 -0
  526. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n60.chunk.ts +4 -0
  527. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015n75.chunk.ts +4 -0
  528. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015s15.chunk.ts +4 -0
  529. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015s30.chunk.ts +4 -0
  530. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w015s45.chunk.ts +4 -0
  531. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n00.chunk.ts +4 -0
  532. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n15.chunk.ts +4 -0
  533. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n30.chunk.ts +4 -0
  534. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n60.chunk.ts +4 -0
  535. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030n75.chunk.ts +4 -0
  536. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030s30.chunk.ts +4 -0
  537. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w030s60.chunk.ts +4 -0
  538. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n30.chunk.ts +4 -0
  539. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n45.chunk.ts +4 -0
  540. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n60.chunk.ts +4 -0
  541. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045n75.chunk.ts +4 -0
  542. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045s15.chunk.ts +4 -0
  543. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045s30.chunk.ts +4 -0
  544. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w045s60.chunk.ts +4 -0
  545. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n00.chunk.ts +4 -0
  546. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n30.chunk.ts +4 -0
  547. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n45.chunk.ts +4 -0
  548. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n60.chunk.ts +4 -0
  549. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060n75.chunk.ts +4 -0
  550. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s15.chunk.ts +4 -0
  551. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s30.chunk.ts +4 -0
  552. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s45.chunk.ts +4 -0
  553. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w060s60.chunk.ts +4 -0
  554. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n00.chunk.ts +4 -0
  555. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n15.chunk.ts +4 -0
  556. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n30.chunk.ts +4 -0
  557. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n45.chunk.ts +4 -0
  558. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n60.chunk.ts +4 -0
  559. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075n75.chunk.ts +4 -0
  560. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s15.chunk.ts +4 -0
  561. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s30.chunk.ts +4 -0
  562. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s45.chunk.ts +4 -0
  563. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w075s60.chunk.ts +4 -0
  564. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n00.chunk.ts +4 -0
  565. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n15.chunk.ts +4 -0
  566. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n30.chunk.ts +4 -0
  567. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n45.chunk.ts +4 -0
  568. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n60.chunk.ts +4 -0
  569. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090n75.chunk.ts +4 -0
  570. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s15.chunk.ts +4 -0
  571. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s30.chunk.ts +4 -0
  572. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s45.chunk.ts +4 -0
  573. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w090s60.chunk.ts +4 -0
  574. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n00.chunk.ts +4 -0
  575. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n15.chunk.ts +4 -0
  576. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n30.chunk.ts +4 -0
  577. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n45.chunk.ts +4 -0
  578. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n60.chunk.ts +4 -0
  579. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105n75.chunk.ts +4 -0
  580. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w105s15.chunk.ts +4 -0
  581. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n00.chunk.ts +4 -0
  582. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n15.chunk.ts +4 -0
  583. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n30.chunk.ts +4 -0
  584. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n45.chunk.ts +4 -0
  585. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n60.chunk.ts +4 -0
  586. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120n75.chunk.ts +4 -0
  587. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w120s30.chunk.ts +4 -0
  588. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n30.chunk.ts +4 -0
  589. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n45.chunk.ts +4 -0
  590. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n60.chunk.ts +4 -0
  591. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135n75.chunk.ts +4 -0
  592. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w135s30.chunk.ts +4 -0
  593. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150n45.chunk.ts +4 -0
  594. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150n60.chunk.ts +4 -0
  595. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150s15.chunk.ts +4 -0
  596. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w150s30.chunk.ts +4 -0
  597. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n00.chunk.ts +4 -0
  598. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n15.chunk.ts +4 -0
  599. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n45.chunk.ts +4 -0
  600. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165n60.chunk.ts +4 -0
  601. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165s15.chunk.ts +4 -0
  602. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w165s30.chunk.ts +4 -0
  603. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n00.chunk.ts +4 -0
  604. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n15.chunk.ts +4 -0
  605. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n45.chunk.ts +4 -0
  606. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180n60.chunk.ts +4 -0
  607. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180s15.chunk.ts +4 -0
  608. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180s30.chunk.ts +4 -0
  609. package/src/plugins/builtin/world-venue-map/natural-earth/tiles/w180s45.chunk.ts +4 -0
  610. package/src/plugins/builtin/world-venue-map/natural-earth/world-50m.chunk.ts +4 -0
  611. package/src/plugins/builtin/world-venue-map/pane.tsx +28 -43
  612. package/src/plugins/builtin/world-venue-map/use-geo.ts +55 -0
  613. package/src/plugins/builtin/world-venue-map/venue-header.tsx +32 -0
  614. package/src/plugins/builtin/yield-curve/headless.ts +16 -0
  615. package/src/plugins/catalog-browser.ts +2 -0
  616. package/src/plugins/catalog-manifest.ts +1 -0
  617. package/src/plugins/catalog-ui.ts +3 -1
  618. package/src/plugins/catalog.ts +1 -1
  619. package/src/plugins/host-link.ts +33 -1
  620. package/src/plugins/installer.ts +48 -12
  621. package/src/plugins/loader.ts +30 -3
  622. package/src/plugins/manager-node.ts +15 -5
  623. package/src/plugins/registry/index.ts +1 -1
  624. package/src/plugins/registry/pane-settings.ts +26 -7
  625. package/src/public/__snapshots__/public-api.test.ts.snap +2 -0
  626. package/src/renderers/dom/build-assets.ts +81 -3
  627. package/src/renderers/dom/data-table/row.tsx +52 -16
  628. package/src/renderers/dom/desktop/controls.tsx +7 -3
  629. package/src/renderers/dom/desktop/icons.tsx +1 -0
  630. package/src/renderers/dom/desktop/list-view.tsx +35 -10
  631. package/src/renderers/dom/desktop/popover.tsx +73 -14
  632. package/src/renderers/dom/host/box.tsx +69 -26
  633. package/src/renderers/dom/host/input.tsx +14 -3
  634. package/src/renderers/dom/host/tabs.tsx +37 -1
  635. package/src/renderers/dom/styles.css +41 -7
  636. package/src/renderers/electrobun/bun/desktop/backend-requests.ts +11 -6
  637. package/src/renderers/electrobun/bun/desktop/backend.ts +1 -0
  638. package/src/renderers/electrobun/bun/desktop/update.ts +181 -87
  639. package/src/renderers/electrobun/bun/index.ts +73 -6
  640. package/src/renderers/electrobun/bun/window/remembered-frame.ts +122 -0
  641. package/src/renderers/electrobun/shared/protocol.ts +3 -0
  642. package/src/renderers/electrobun/view/backend-rpc.ts +10 -4
  643. package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +3 -1
  644. package/src/renderers/electrobun/view/main.tsx +7 -1
  645. package/src/renderers/electrobun/view/renderer-window-error.ts +18 -0
  646. package/src/renderers/electrobun/view/rpc-timeout.ts +14 -3
  647. package/src/renderers/electrobun/view/update-host.ts +45 -21
  648. package/src/renderers/opentui/host.tsx +5 -0
  649. package/src/sources/gloomberb-cloud/index.ts +25 -4
  650. package/src/sources/gloomberb-cloud/normalizers.ts +36 -5
  651. package/src/sources/provider-router/cached-routes.ts +4 -1
  652. package/src/sources/provider-router/financials.ts +11 -8
  653. package/src/sources/provider-router/history.ts +15 -10
  654. package/src/sources/sec-registrant.ts +75 -0
  655. package/src/state/app/context/index.tsx +24 -8
  656. package/src/state/hooks/quote-streaming.ts +41 -26
  657. package/src/sync/core-contributors.ts +4 -0
  658. package/src/telemetry/benign-window-error.ts +7 -0
  659. package/src/telemetry/crash-reports-dom.ts +2 -0
  660. package/src/telemetry/crash-reports.ts +4 -1
  661. package/src/test-support/cli-context.ts +10 -2
  662. package/src/test-support/daily-nav.ts +25 -0
  663. package/src/theme/heat-colors.ts +357 -2
  664. package/src/tickers/instrument-kind.ts +34 -7
  665. package/src/tickers/search/asset-classes.ts +24 -9
  666. package/src/tickers/search/index.ts +44 -11
  667. package/src/tickers/search/ranking.ts +23 -3
  668. package/src/time-series/resolve.ts +1 -1
  669. package/src/time-series/use-chart-resolution.ts +1 -1
  670. package/src/types/context-menu.ts +6 -0
  671. package/src/types/data-provider.ts +2 -0
  672. package/src/types/financials.ts +5 -0
  673. package/src/types/headless.ts +79 -2
  674. package/src/types/plugin.ts +38 -6
  675. package/src/types/ticker.ts +15 -0
  676. package/src/ui/context-menu.tsx +1 -0
  677. package/src/ui/host.tsx +16 -0
  678. package/src/updater/index.ts +38 -13
  679. package/src/utils/async-deadline.ts +21 -0
  680. package/src/utils/cli-output.ts +5 -1
  681. package/src/utils/crypto-pair.ts +41 -0
  682. package/src/utils/currency-units.ts +14 -0
  683. package/src/utils/depositary-receipt.ts +26 -0
  684. package/src/utils/exchanges.ts +72 -0
  685. package/src/utils/fire-and-forget.ts +24 -0
  686. package/src/utils/format.ts +13 -0
  687. package/src/utils/price-earnings.ts +70 -3
  688. package/src/utils/price-history.ts +58 -13
  689. package/src/utils/rpc-timeout-error.ts +27 -0
  690. package/src/utils/sec.ts +13 -1
  691. package/src/utils/utc-time.ts +79 -0
@@ -0,0 +1,143 @@
1
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
2
+ import type { ResolvedSeries } from "../../../time-series/types";
3
+ import {
4
+ buildCompositeNavigationFrame,
5
+ compositeNavigationDataViewport,
6
+ compositeViewportPositions,
7
+ fitCompositeViewport,
8
+ panCompositeViewport,
9
+ sameCompositeViewport,
10
+ shouldResetCompositeViewport,
11
+ zoomCompositeViewport,
12
+ type CompositeNavigationFrame,
13
+ type CompositeViewportRange,
14
+ } from "./interactions";
15
+ import type { CompositeChartProps } from "./types";
16
+
17
+ /** How far past the first loaded observation a backfilling chart may pan, as a fraction of the view. */
18
+ const HISTORICAL_PADDING_RATIO = 0.5;
19
+
20
+ export function useCompositeViewport({
21
+ viewport,
22
+ viewportResetKey,
23
+ visibleSeries,
24
+ marketTimelineSeries,
25
+ allowHistoricalBackfill,
26
+ onViewportChange,
27
+ }: {
28
+ viewport: CompositeChartProps["viewport"];
29
+ viewportResetKey: CompositeChartProps["viewportResetKey"];
30
+ visibleSeries: ResolvedSeries[];
31
+ marketTimelineSeries: ResolvedSeries[];
32
+ allowHistoricalBackfill: boolean;
33
+ onViewportChange: CompositeChartProps["onViewportChange"];
34
+ }) {
35
+ const previousAuthoredViewportRef = useRef<CompositeViewportRange | null>(viewport ?? null);
36
+ const previousViewportResetKeyRef = useRef(viewportResetKey);
37
+ // The user owns this once they navigate. Data refreshes never rewrite it;
38
+ // only the authored viewport changing or an explicit reset clears it.
39
+ const [userViewport, setUserViewport] = useState<CompositeViewportRange | null>(null);
40
+ const hasViewportResetKey = viewportResetKey !== undefined
41
+ || previousViewportResetKeyRef.current !== undefined;
42
+ const authoredViewportChanged = hasViewportResetKey
43
+ ? previousViewportResetKeyRef.current !== viewportResetKey
44
+ : shouldResetCompositeViewport(
45
+ previousAuthoredViewportRef.current,
46
+ viewport ?? null,
47
+ );
48
+ const navigationFrame = useMemo(
49
+ () => buildCompositeNavigationFrame(visibleSeries, marketTimelineSeries, {
50
+ historicalPaddingRatio: allowHistoricalBackfill ? HISTORICAL_PADDING_RATIO : 0,
51
+ }),
52
+ [allowHistoricalBackfill, marketTimelineSeries, visibleSeries],
53
+ );
54
+ const authoredViewport = useMemo(() => {
55
+ // The requested dates own the axis, including gaps in a cached or partial
56
+ // response. Fitting them to available observations silently changes the
57
+ // research period. User pan/zoom gestures retain their navigation limits.
58
+ if (viewport && Number.isFinite(viewport.start.getTime())
59
+ && Number.isFinite(viewport.end.getTime()) && viewport.start <= viewport.end) return viewport;
60
+ return navigationFrame ? compositeNavigationDataViewport(navigationFrame) : null;
61
+ }, [navigationFrame, viewport]);
62
+ const activeUserViewport = authoredViewportChanged ? null : userViewport;
63
+ const effectiveViewport = activeUserViewport ?? authoredViewport;
64
+ const userViewportStart = activeUserViewport?.start.getTime() ?? null;
65
+ const userViewportEnd = activeUserViewport?.end.getTime() ?? null;
66
+ const lastReportedViewportRef = useRef<string | null>(null);
67
+ const viewportInteractionRef = useRef<"pan" | "reset" | "zoom">("reset");
68
+ useEffect(() => {
69
+ if (!onViewportChange) return;
70
+ const key = userViewportStart === null || userViewportEnd === null
71
+ ? "none"
72
+ : `${userViewportStart}:${userViewportEnd}`;
73
+ // The callback drives adaptive data loading. Seed it from the authored
74
+ // viewport without echoing that controlled value back into the loader.
75
+ if (lastReportedViewportRef.current === null) {
76
+ lastReportedViewportRef.current = key;
77
+ return;
78
+ }
79
+ if (lastReportedViewportRef.current === key) return;
80
+ lastReportedViewportRef.current = key;
81
+ onViewportChange(
82
+ userViewportStart === null || userViewportEnd === null
83
+ ? null
84
+ : { start: new Date(userViewportStart), end: new Date(userViewportEnd) },
85
+ viewportInteractionRef.current,
86
+ );
87
+ }, [onViewportChange, userViewportEnd, userViewportStart]);
88
+
89
+ useEffect(() => {
90
+ previousAuthoredViewportRef.current = viewport ?? null;
91
+ previousViewportResetKeyRef.current = viewportResetKey;
92
+ if (authoredViewportChanged && userViewport) {
93
+ viewportInteractionRef.current = "reset";
94
+ setUserViewport(null);
95
+ }
96
+ }, [authoredViewportChanged, userViewport, viewport, viewportResetKey]);
97
+
98
+ const navigate = useCallback((
99
+ kind: "pan" | "zoom",
100
+ compute: (base: CompositeViewportRange, frame: CompositeNavigationFrame) => CompositeViewportRange,
101
+ gesture?: { frame: CompositeNavigationFrame; from: CompositeViewportRange },
102
+ ) => {
103
+ const frame = gesture?.frame ?? navigationFrame;
104
+ if (!frame) return;
105
+ viewportInteractionRef.current = kind;
106
+ setUserViewport((current) => {
107
+ const base = gesture?.from ?? current ?? authoredViewport;
108
+ if (!base) return current;
109
+ const next = compute(base, frame);
110
+ // Once navigated, the window is the user's until they reset it, even if
111
+ // a gesture happens to land back on the authored range: the owner may
112
+ // echo a navigated range back as the authored one, and dropping to null
113
+ // there would reload the original range under the pointer.
114
+ return sameCompositeViewport(next, current ?? base) ? current : next;
115
+ });
116
+ }, [authoredViewport, navigationFrame]);
117
+ const panViewport = useCallback((
118
+ deltaPositions: number,
119
+ gesture?: { frame: CompositeNavigationFrame; from: CompositeViewportRange },
120
+ ) => {
121
+ navigate("pan", (base, frame) => panCompositeViewport(frame, base, deltaPositions), gesture);
122
+ }, [navigate]);
123
+ const panViewportByRatio = useCallback((shiftRatio: number) => {
124
+ if (!navigationFrame || !effectiveViewport) return;
125
+ const positions = compositeViewportPositions(navigationFrame, effectiveViewport);
126
+ if (!positions) return;
127
+ panViewport(shiftRatio * Math.max(positions.end - positions.start, Number.EPSILON));
128
+ }, [effectiveViewport, navigationFrame, panViewport]);
129
+ const zoomViewport = useCallback((zoomFactor: number, anchorRatio = 1) => {
130
+ navigate("zoom", (base, frame) => zoomCompositeViewport(frame, base, zoomFactor, anchorRatio));
131
+ }, [navigate]);
132
+ const setViewportRange = useCallback((range: CompositeViewportRange) => {
133
+ navigate("zoom", (_base, frame) => fitCompositeViewport(frame, range));
134
+ }, [navigate]);
135
+ const resetViewport = useCallback(() => {
136
+ viewportInteractionRef.current = "reset";
137
+ setUserViewport(null);
138
+ }, []);
139
+ return {
140
+ navigationFrame, activeUserViewport, effectiveViewport,
141
+ panViewport, panViewportByRatio, zoomViewport, setViewportRange, resetViewport,
142
+ };
143
+ }
@@ -34,6 +34,8 @@ export async function executeCollectionCommandAction(options: {
34
34
  buildWorkflowDeps: () => WorkflowDeps;
35
35
  openModeRoute: (screen: "ticker-search", initialQuery?: string, payload?: Record<string, unknown>) => void;
36
36
  openAddToPortfolioWorkflow: (ticker: TickerRecord, preferredPortfolioId?: string | null) => void;
37
+ /** Join the named collection without the position form. */
38
+ directMembership?: boolean;
37
39
  pushRoute: (route: CommandBarRoute) => void;
38
40
  notify: (body: string, options?: { type?: "info" | "success" | "error" }) => void;
39
41
  closeAll: (options?: { revertThemePreview?: boolean }) => void;
@@ -73,7 +75,9 @@ export async function executeCollectionCommandAction(options: {
73
75
  };
74
76
  if (!selectSavedOwner(options.explicitTargetId ?? options.activeCollectionId)) return;
75
77
 
76
- if (kind === "portfolio" && action === "add") {
78
+ // A venue picked from the add row joins that collection directly. The AP
79
+ // command still asks for the position.
80
+ if (kind === "portfolio" && action === "add" && !options.directMembership) {
77
81
  const manualPortfolios = stateForCommand.config.portfolios.filter(isManualPortfolio);
78
82
  if (manualPortfolios.length === 0) {
79
83
  options.notify("Create a manual portfolio first.", { type: "info" });
@@ -24,6 +24,11 @@ export interface ResultItem {
24
24
  lines?: CommandBarResultLine[];
25
25
  /** Short tag drawn left of the label: a shortcut, an asset class, a document type. */
26
26
  badge?: string;
27
+ /**
28
+ * An instrument's name, drawn muted after the symbol. Listings that share a
29
+ * symbol (SAP on NYSE and XETRA, Saputo as SAP on TSX) differ only here.
30
+ */
31
+ name?: string;
27
32
  right?: string;
28
33
  /** Provider type retained for symbol/alias identity checks. */
29
34
  instrumentType?: string;
@@ -11,7 +11,7 @@ import {
11
11
  TextAttributes,
12
12
  type ScrollBoxRenderable,
13
13
  } from "../../../ui";
14
- import { truncateTextSegments, truncateToDisplayWidth } from "../../../utils/format";
14
+ import { displayWidth, truncateTextSegments, truncateToDisplayWidth } from "../../../utils/format";
15
15
  import { Spinner } from "../../ui";
16
16
  import { useCommandBarPalette } from "../panel/palette";
17
17
  import { getRowPresentation } from "../view-model";
@@ -37,6 +37,9 @@ export type CommandBarListScrollEvent = {
37
37
 
38
38
  /** Columns every row gives up to the badge column, badge or not. */
39
39
  const BADGE_INDENT = BADGE_COLUMN_WIDTH + BADGE_GAP;
40
+ const NAME_GAP = 2;
41
+ /** Below this a name is a few letters and an ellipsis, which tells nobody apart. */
42
+ const MIN_NAME_WIDTH = 6;
40
43
 
41
44
  interface CommandBarListItemRowProps {
42
45
  item: ResultItem;
@@ -79,7 +82,12 @@ const CommandBarListItemRow = memo(function CommandBarListItemRow({
79
82
  const labelColumnWidth = Math.max(1, labelWidth - BADGE_INDENT);
80
83
  // A long title stops one cell short of the right column, so its ellipsis
81
84
  // never runs into the date or shortcut sitting there.
82
- const label = truncateToDisplayWidth(presentation.label, Math.max(1, labelColumnWidth - (trailingWidth > 0 ? 1 : 0)));
85
+ const labelSpace = Math.max(1, labelColumnWidth - (trailingWidth > 0 ? 1 : 0));
86
+ const label = truncateToDisplayWidth(presentation.label, labelSpace);
87
+ // The name gives way before the symbol: it shrinks to its ellipsis and drops
88
+ // out once fewer than a few characters of it would show.
89
+ const nameSpace = labelSpace - displayWidth(label) - NAME_GAP;
90
+ const name = item.name && nameSpace >= MIN_NAME_WIDTH ? truncateToDisplayWidth(item.name, nameSpace) : "";
83
91
  // "current" outranks the shortcut on the right; otherwise a badge lifted from
84
92
  // `right` must not be repeated there.
85
93
  const trailing = badgeConsumesRight(item) && !item.current
@@ -152,10 +160,15 @@ const CommandBarListItemRow = memo(function CommandBarListItemRow({
152
160
  <Box width={BADGE_INDENT} flexDirection="row">
153
161
  {badge && <CommandBarRowBadge text={badge.text} tone={badge.tone} width={BADGE_COLUMN_WIDTH} />}
154
162
  </Box>
155
- <Box width={labelColumnWidth}>
163
+ <Box width={labelColumnWidth} flexDirection="row">
156
164
  <Text fg={isSelected ? palette.selectedText : presentation.primaryMuted ? palette.subtle : palette.text}>
157
165
  {label}
158
166
  </Text>
167
+ {name && (
168
+ <Text fg={isSelected ? palette.selectedText : palette.subtle}>
169
+ {" ".repeat(NAME_GAP) + name}
170
+ </Text>
171
+ )}
159
172
  </Box>
160
173
  <Box width={trailingWidth}>
161
174
  <Text
@@ -165,6 +165,7 @@ export function useCommandBarPaneTemplateActions({
165
165
  trimmedList,
166
166
  activeCollectionId,
167
167
  buildWorkflowDeps(),
168
+ template.shortcut?.keepArgToken,
168
169
  );
169
170
  const createOptions = {
170
171
  arg: trimmedList,
@@ -3,6 +3,7 @@ import type { TickerRecord } from "../../../../types/ticker";
3
3
  import { isManualPortfolio } from "../../../../plugins/builtin/portfolio-list/mutations";
4
4
  import type { Command } from "../../commands/registry";
5
5
  import type { ResultItem } from "../../list/model";
6
+ import { canRestartToApply } from "../../../../updater";
6
7
 
7
8
  interface RootCommandItemBuilderOptions {
8
9
  activeCollectionId: string | null;
@@ -84,6 +85,9 @@ export function createRootCommandItemBuilder({
84
85
  return activeTickerSymbol ? `Remove ${activeTickerSymbol} from Portfolio` : command.label;
85
86
  case "set-portfolio-position":
86
87
  return activeTickerSymbol ? `Set Position for ${activeTickerSymbol}` : command.label;
88
+ // The row only shows its label, so a downloaded update is announced there.
89
+ case "check-for-updates":
90
+ return state.updateProgress?.phase === "ready" ? "Update ready, restart to apply" : command.label;
87
91
  default:
88
92
  return command.label;
89
93
  }
@@ -128,8 +132,9 @@ export function createRootCommandItemBuilder({
128
132
  return `Downloading v${state.updateAvailable?.version}: ${state.updateProgress.percent ?? 0}%`;
129
133
  }
130
134
  if (state.updateProgress?.phase === "replacing") return "Installing update";
135
+ if (state.updateProgress?.phase === "ready") return "Update ready, restart to apply";
131
136
  if (state.updateProgress?.phase === "done") {
132
- return state.updateProgress.message ?? "Update installed - restart to apply";
137
+ return state.updateProgress.message ?? "Update ready, restart to apply";
133
138
  }
134
139
  if (state.updateProgress?.phase === "error") {
135
140
  return `Update failed: ${state.updateProgress.error}`;
@@ -178,6 +183,8 @@ export function createRootCommandItemBuilder({
178
183
  switch (command.id) {
179
184
  case "set-portfolio-position":
180
185
  return "edit position update position modify position manual position portfolio position";
186
+ case "check-for-updates":
187
+ return state.updateProgress?.phase === "ready" ? "check for updates restart relaunch" : "";
181
188
  default:
182
189
  return "";
183
190
  }
@@ -196,7 +203,7 @@ export function createRootCommandItemBuilder({
196
203
  searchText: smartSearchText(command),
197
204
  disabled:
198
205
  command.id === "check-for-updates" &&
199
- (state.updateCheckInProgress || !!state.updateProgress),
206
+ (state.updateCheckInProgress || (!!state.updateProgress && !canRestartToApply(state.updateProgress))),
200
207
  action: () => runDirectCommand(command, arg),
201
208
  };
202
209
  };
@@ -3,7 +3,7 @@ import type { PluginRegistry } from "../../../../plugins/registry";
3
3
  import { findAbsorbedPlugin } from "../../../../plugins/absorbed";
4
4
  import { isOfficialPluginRepo } from "../../../../plugins/auto-update";
5
5
  import { getCurrentPluginTarget, runsExternalPlugins } from "../../../../plugins/current-target";
6
- import { activateInstalledPlugin } from "../../../../plugins/builtin/plugin-marketplace/activation";
6
+ import { activateInstall } from "../../../../plugins/builtin/plugin-marketplace/activation";
7
7
  import { loadRegistry, registryPluginUrl } from "../../../../plugins/builtin/plugin-marketplace/feed";
8
8
  import {
9
9
  installConsent,
@@ -217,7 +217,7 @@ function buildPluginInstallItem(
217
217
  onConfirm: async () => {
218
218
  const result = await manager.install(repo, pin);
219
219
  if (!result.ok) throw new Error(`Could not install ${plugin.name}: ${result.error}`);
220
- const activated = await activateInstalledPlugin(result.directory, host, manager);
220
+ const activated = await activateInstall(result, host, manager);
221
221
  if (!activated.ok) throw new Error(`${plugin.name} installed but did not load: ${activated.error}`);
222
222
  if (activated.restart) {
223
223
  context.notify(`Restart to finish installing ${plugin.name}.`, "info");
@@ -8,6 +8,7 @@ import {
8
8
  mergePlainRootTickerResults,
9
9
  mergeTickerSearchResultItems,
10
10
  QUICK_LOOK_TICKER_SEARCH_OPTIONS,
11
+ venueDropdownResults,
11
12
  } from "../ticker-search/results";
12
13
  import { orderListResults, type ResultItem } from "../../list/model";
13
14
  import type { CommandBarCategoryPriorities, CommandBarSectionOrder } from "../../view-model";
@@ -27,6 +28,8 @@ export function useRootProviderSearch(options: {
27
28
  brokerInstanceId?: string | null,
28
29
  ) => TickerSearchCandidate[] | null;
29
30
  rootPlainTickerSearchArg: string | null;
31
+ /** Set when the query is `NET:` or `NET:N`. Empty string lists every venue. */
32
+ listingSuffix: string | null;
30
33
  rootResultItems: ResultItem[];
31
34
  rootTickerSearchArg: string | null;
32
35
  tickers: AppState["tickers"];
@@ -52,6 +55,7 @@ export function useRootProviderSearch(options: {
52
55
  portfolios,
53
56
  readTickerSearchCache,
54
57
  rootPlainTickerSearchArg,
58
+ listingSuffix,
55
59
  rootResultItems,
56
60
  rootTickerSearchArg,
57
61
  tickers,
@@ -181,6 +185,13 @@ export function useRootProviderSearch(options: {
181
185
  }, []);
182
186
 
183
187
  const rootResults = useMemo(() => {
188
+ if (listingSuffix != null) {
189
+ if (rootTickerSearchArg && rootProviderResultsQuery === rootTickerSearchArg && rootProviderResults) {
190
+ return venueDropdownResults(rootTickerSearchArg, rootProviderResults, listingSuffix);
191
+ }
192
+ // The venue list replaces commands. Nothing else shows while it loads.
193
+ return [];
194
+ }
184
195
  if (rootTickerSearchArg && rootProviderResultsQuery === rootTickerSearchArg && rootProviderResults) {
185
196
  if (rootPlainTickerSearchArg) {
186
197
  return mergePlainRootTickerResults(rootPlainTickerSearchArg, rootProviderResults, rootResultItems);
@@ -189,17 +200,20 @@ export function useRootProviderSearch(options: {
189
200
  }
190
201
  return rootResultItems;
191
202
  }, [
203
+ listingSuffix,
192
204
  rootPlainTickerSearchArg,
193
205
  rootProviderResults,
194
206
  rootProviderResultsQuery,
195
207
  rootResultItems,
196
208
  rootTickerSearchArg,
197
209
  ]);
198
- const rootSectionOrder: CommandBarSectionOrder = rootPlainTickerSearchArg
199
- ? "app-first"
200
- : rootTickerSearchArg
201
- ? "ranked"
202
- : "default";
210
+ const rootSectionOrder: CommandBarSectionOrder = listingSuffix != null
211
+ ? "ranked"
212
+ : rootPlainTickerSearchArg
213
+ ? "app-first"
214
+ : rootTickerSearchArg
215
+ ? "ranked"
216
+ : "default";
203
217
  const orderedRootResults = useMemo(
204
218
  () => orderListResults(rootResults, { sectionOrder: rootSectionOrder, categoryPriorities }),
205
219
  [categoryPriorities, rootResults, rootSectionOrder],
@@ -4,7 +4,7 @@ import type { AppState } from "../../../../state/app/context";
4
4
  import type { DataProvider } from "../../../../types/data-provider";
5
5
  import type { CommandDef, PaneTemplateCreateOptions, PaneTemplateDef } from "../../../../types/plugin";
6
6
  import type { TickerRecord } from "../../../../types/ticker";
7
- import type { TickerSearchCandidate } from "../../../../tickers/search";
7
+ import { listingChoiceQuery, symbolSearchQuery, type TickerSearchCandidate } from "../../../../tickers/search";
8
8
  import type { AssistRowHandlers } from "../../assist/model";
9
9
  import { matchPrefix, type Command } from "../../commands/registry";
10
10
  import type { ResultItem } from "../../list/model";
@@ -246,11 +246,19 @@ export function useCommandBarRootRuntime({
246
246
  // Free text that no prefix claims also goes to symbol search, so "nvidia"
247
247
  // finds NVDA without the backtick. Skipped when a local row already carries
248
248
  // that exact name, since an "Exact Match" symbol would otherwise outrank it.
249
+ // `NET:` is that symbol's venue dropdown. The search itself is the bare symbol.
250
+ const rootListingChoice = useMemo(() => {
251
+ if (currentRoute || activeMatch || rootShortcutIntent.kind !== "none") return null;
252
+ return listingChoiceQuery(rootQuery);
253
+ }, [activeMatch, currentRoute, rootQuery, rootShortcutIntent.kind]);
249
254
  const rootPlainTickerSearchArg = useMemo(() => {
250
255
  if (currentRoute || activeMatch || rootShortcutIntent.kind !== "none") return null;
256
+ // An explicit venue choice also searches one-letter symbols and names shared with local actions.
257
+ if (rootListingChoice) return rootListingChoice.symbol;
251
258
  const trimmed = rootQuery.trim();
252
- if (trimmed.length < 2) return null;
253
- const normalizedQuery = normalizeCommandTickerSearchText(trimmed);
259
+ const symbolQuery = symbolSearchQuery(trimmed);
260
+ if (symbolQuery.length < 2) return null;
261
+ const normalizedQuery = normalizeCommandTickerSearchText(symbolQuery);
254
262
  // The install row for "TV" is labelled TV, but it leads on purpose and
255
263
  // must not keep Grupo Televisa out of the list.
256
264
  const hasExactLocalRow = rootResultModel.items.some((item) => (
@@ -259,8 +267,8 @@ export function useCommandBarRootRuntime({
259
267
  && item.kind !== "search"
260
268
  && normalizeCommandTickerSearchText(item.label) === normalizedQuery
261
269
  ));
262
- return hasExactLocalRow ? null : trimmed;
263
- }, [activeMatch, currentRoute, pluginInstallItem, rootQuery, rootResultModel.items, rootShortcutIntent.kind]);
270
+ return hasExactLocalRow ? null : symbolQuery;
271
+ }, [activeMatch, currentRoute, pluginInstallItem, rootListingChoice, rootQuery, rootResultModel.items, rootShortcutIntent.kind]);
264
272
  const rootTickerSearchArg = rootSecurityDescriptionArg ?? rootPlainTickerSearchArg;
265
273
 
266
274
  const {
@@ -278,6 +286,7 @@ export function useCommandBarRootRuntime({
278
286
  portfolios: state.config.portfolios,
279
287
  readTickerSearchCache,
280
288
  rootPlainTickerSearchArg,
289
+ listingSuffix: rootPlainTickerSearchArg && rootListingChoice ? rootListingChoice.suffix : null,
281
290
  rootResultItems: rootResultModel.items,
282
291
  rootTickerSearchArg,
283
292
  tickers: state.tickers,
@@ -64,6 +64,9 @@ export function useCommandBarTickerSearchActions({
64
64
  // text goes quiet rather than repeating it.
65
65
  const badge = formatInstrumentBadge(candidate);
66
66
  const right = candidate.exchangeLabel || candidate.primaryExchangeLabel || candidate.right || undefined;
67
+ // The candidate's detail leads with the name; the rest repeats the badge or venue.
68
+ const leadingName = candidate.detail.split(" | ")[0]?.trim();
69
+ const name = leadingName && leadingName.toUpperCase() !== candidate.label.toUpperCase() ? leadingName : undefined;
67
70
 
68
71
  if (candidate.kind === "ticker" && candidate.ticker) {
69
72
  return {
@@ -74,6 +77,7 @@ export function useCommandBarTickerSearchActions({
74
77
  instrumentType: candidate.instrumentType,
75
78
  detail,
76
79
  badge,
80
+ name,
77
81
  right,
78
82
  category: candidate.category,
79
83
  kind: "ticker",
@@ -97,6 +101,7 @@ export function useCommandBarTickerSearchActions({
97
101
  instrumentType: candidate.instrumentType,
98
102
  detail,
99
103
  badge,
104
+ name,
100
105
  right,
101
106
  category: candidate.category,
102
107
  kind: "search",
@@ -10,7 +10,7 @@ import {
10
10
  parseAssetClassQuery,
11
11
  } from "../../../../tickers/search/asset-classes";
12
12
  import type { ResultItem } from "../../list/model";
13
- import { canonicalExchange, parsePublicTickerKey } from "../../../../utils/exchanges";
13
+ import { canonicalExchange, parsePublicTickerKey, publicExchange } from "../../../../utils/exchanges";
14
14
  import { compactSearchText, getIssuerGroupKey, isExplicitMarketSymbol } from "../../../../tickers/search/ranking";
15
15
 
16
16
  export const QUICK_LOOK_TICKER_SEARCH_OPTIONS = { includeOptionContracts: false } as const;
@@ -43,10 +43,10 @@ function rawInstrumentType(candidate: Pick<TickerSearchCandidate, "result" | "ti
43
43
  }
44
44
 
45
45
  /**
46
- * Class tag for the badge column: the class code a query can end with (EQ,
47
- * CUR, OPT, FUT, IDX, ETF), else FUND or DERIV. An unclassified instrument
48
- * gets none: the row lifts its exchange code there instead when the code is
49
- * short enough.
46
+ * Class tag for the badge column. A query can end with the same code: EQ,
47
+ * CUR, CRYP, OPT, FUT, IDX, ETF, FUND. A fund or derivative whose type string
48
+ * did not classify still badges FUND or DERIV. Anything else gets none, and
49
+ * the row shows its exchange code there when the code is short enough.
50
50
  */
51
51
  export function formatInstrumentBadge(
52
52
  candidate: Pick<TickerSearchCandidate, "instrumentClass" | "result" | "ticker">
@@ -167,6 +167,32 @@ export function mergePlainRootTickerResults(
167
167
  ];
168
168
  }
169
169
 
170
+ function venueMatchesSuffix(item: ResultItem, suffix: string): boolean {
171
+ if (!suffix) return true;
172
+ const displayed = (item.right ?? "").trim().toUpperCase();
173
+ const fromLabel = parsePublicTickerKey(item.label.trim().toUpperCase()).exchange ?? "";
174
+ const canonicalDisplayed = canonicalExchange(displayed);
175
+ const targets = [displayed, canonicalDisplayed, fromLabel, publicExchange(canonicalDisplayed || displayed)];
176
+ if (targets.some((value) => value.startsWith(suffix))) return true;
177
+ const aliased = canonicalExchange(suffix);
178
+ return aliased !== suffix && targets.some((value) => canonicalExchange(value) === aliased);
179
+ }
180
+
181
+ /**
182
+ * The colon query's dropdown: one row per exact venue, in ranked order. A
183
+ * typed exchange prefix keeps the rows it matches.
184
+ */
185
+ export function venueDropdownResults(symbol: string, items: ResultItem[], suffix: string): ResultItem[] {
186
+ const rows: ResultItem[] = [];
187
+ for (const item of items) {
188
+ if (item.kind !== "ticker" && item.kind !== "search") continue;
189
+ if (!isExactTickerResultMatch(item, symbol)) continue;
190
+ if (!venueMatchesSuffix(item, suffix)) continue;
191
+ rows.push(item.category === "Exact Match" ? item : { ...item, category: "Exact Match" });
192
+ }
193
+ return rows;
194
+ }
195
+
170
196
  /**
171
197
  * Up to the cap, in this order: the first exact row of each security, the
172
198
  * exact symbol's other exchanges, then looser hits. The rows keep their
@@ -2,7 +2,7 @@ import { useCallback, useEffect, useRef, useState } from "react";
2
2
  import type { AppState } from "../../../../state/app/context";
3
3
  import type { DataProvider } from "../../../../types/data-provider";
4
4
  import type { TickerSearchCandidate } from "../../../../tickers/search";
5
- import { searchTickerCandidates } from "../../../../tickers/search";
5
+ import { searchTickerCandidates, symbolSearchQuery } from "../../../../tickers/search";
6
6
  import {
7
7
  COMMAND_BAR_TICKER_SEARCH_LIMIT,
8
8
  mergeTickerSearchResultItems,
@@ -64,7 +64,7 @@ export function useTickerSearchRouteResults(options: {
64
64
  return;
65
65
  }
66
66
 
67
- const searchQuery = routeQuery.trim();
67
+ const searchQuery = symbolSearchQuery(routeQuery);
68
68
  if (!searchQuery) {
69
69
  searchRequestIdRef.current += 1;
70
70
  setTickerSearchPending(false);
@@ -122,12 +122,14 @@ export function useCommandBarRouteActions({
122
122
  rawInput?: string,
123
123
  explicitTargetId?: string | null,
124
124
  selectedTicker?: TickerRecord,
125
+ directMembership?: boolean,
125
126
  ) => executeCollectionCommandAction({
126
127
  activeCollectionId,
127
128
  activeTickerSymbol,
128
129
  buildWorkflowDeps: buildSharedWorkflowDeps,
129
130
  closeAll,
130
131
  commandId,
132
+ directMembership,
131
133
  explicitTargetId,
132
134
  getState: () => stateRef.current,
133
135
  notify,
@@ -1,5 +1,8 @@
1
1
  import { useCallback, type MutableRefObject } from "react";
2
2
  import type { AppState } from "../../state/app/context";
3
+ import type { TickerRecord } from "../../types/ticker";
4
+ import { t } from "../../i18n";
5
+ import { listingChoiceQuery } from "../../tickers/search";
3
6
  import type { PluginRegistry } from "../../plugins/registry";
4
7
  import type { Command } from "./commands/registry";
5
8
  import type {
@@ -30,6 +33,8 @@ type ExecuteCollectionCommandFn = (
30
33
  commandId: CollectionCommandId,
31
34
  rawInput?: string,
32
35
  explicitTargetId?: string | null,
36
+ selectedTicker?: TickerRecord,
37
+ directMembership?: boolean,
33
38
  ) => Promise<void>;
34
39
 
35
40
  interface UseCommandBarSelectionRuntimeOptions {
@@ -270,6 +275,38 @@ export function useCommandBarSelectionRuntime({
270
275
  const selected = options?.item ?? typed ?? listState.results[listState.selectedIdx];
271
276
  if (!selected || selected.disabled) return;
272
277
 
278
+ // Opened from an add row: a venue picked from the colon list joins that
279
+ // collection. Any other text or screen runs as usual.
280
+ const addListing = stateRef.current.commandBarLaunchRequest;
281
+ if (
282
+ !options?.secondary
283
+ && addListing?.kind === "add-listing"
284
+ && !currentRoute
285
+ && listingChoiceQuery(rootQueryRef.current)
286
+ && (selected.kind === "ticker" || selected.kind === "search")
287
+ && selected.resolveTicker
288
+ ) {
289
+ const launch = addListing;
290
+ void (async () => {
291
+ try {
292
+ const ticker = await selected.resolveTicker!();
293
+ await executeCollectionCommand(
294
+ launch.collectionKind === "watchlist" ? "add-watchlist" : "add-portfolio",
295
+ ticker.metadata.ticker,
296
+ launch.collectionId,
297
+ ticker,
298
+ true,
299
+ );
300
+ } catch (error) {
301
+ pluginRegistry.notify({
302
+ type: "error",
303
+ body: error instanceof Error ? error.message : t("Could not add the selected listing."),
304
+ });
305
+ }
306
+ })();
307
+ return;
308
+ }
309
+
273
310
  const run = () => {
274
311
  if (options?.secondary && selected.secondaryAction) {
275
312
  void selected.secondaryAction();
@@ -320,6 +357,7 @@ export function useCommandBarSelectionRuntime({
320
357
  rootQueryRef,
321
358
  runRootRow,
322
359
  stateConfigLayout,
360
+ stateRef,
323
361
  visibleListStateRef,
324
362
  ]);
325
363
 
@@ -20,6 +20,7 @@ import { useCommandBarRootRuntime } from "../routes/root/runtime";
20
20
  import { createQuickLookTickerCandidates } from "../routes/ticker-search/results";
21
21
  import { useCommandSearchReport } from "../routes/root/search-report";
22
22
  import { useAppStateRef } from "../../../state/app/context";
23
+ import { listingChoiceQuery } from "../../../tickers/search";
23
24
  import { parseRootShortcutIntent } from "../routes/root/shortcuts";
24
25
  import { useRootPluginInstallItem } from "../routes/root/plugin-install";
25
26
  import { useCommandBarThemePreview } from "../theme-preview";
@@ -230,6 +231,9 @@ export function CommandBar({
230
231
  paneTemplates: getAvailablePaneShortcutTemplates(rootQuery),
231
232
  activeTicker: activeTickerSymbol,
232
233
  }), [activeTickerSymbol, availableCommands, getAvailablePaneShortcutTemplates, getAvailablePluginCommands, rootQuery]);
234
+ const listingChoice = !currentRoute && rootShortcutIntent.kind === "none"
235
+ ? listingChoiceQuery(rootQuery)
236
+ : null;
233
237
 
234
238
  // Runs the typed text again once a plugin installed from the bar is in, the
235
239
  // way a key bound to it would. Not over a dialog opened since: the bar would
@@ -258,6 +262,7 @@ export function CommandBar({
258
262
  // Only the root list asks on its own, and only for text the prefix parser
259
263
  // could not claim — otherwise the user is mid-command, not mid-question.
260
264
  const assistAutoAsk = !currentRoute
265
+ && !listingChoice
261
266
  && planAccess.emailVerified
262
267
  && shouldAutoAskAssist({ query: rootQuery, hasShortcutIntent: rootShortcutIntent.kind !== "none" });
263
268
  // The server keeps a question unless told not to, so the answer always
@@ -373,8 +378,8 @@ export function CommandBar({
373
378
  providers: searchProviders,
374
379
  query: rootQuery,
375
380
  // A resolved prefix means the user is running a command, so free-text
376
- // providers neither ask the network nor add rows.
377
- enabled: !currentRoute && rootShortcutIntent.kind === "none",
381
+ // providers neither ask the network nor add rows. A colon is the venue list.
382
+ enabled: !currentRoute && rootShortcutIntent.kind === "none" && !listingChoice,
378
383
  context: searchProviderContext,
379
384
  onExecuted: closeAfterProviderResult,
380
385
  });
@@ -252,7 +252,7 @@ async function resolvePaneTemplateOptions(
252
252
  const rawInput = resolvedOptions?.arg ?? resolvedOptions?.values?.tickers ?? "";
253
253
  const symbols = !String(rawInput).trim() && template.shortcut?.openWithoutArg
254
254
  ? []
255
- : await resolveTickerListInput(rawInput, baseContext.activeCollectionId, deps);
255
+ : await resolveTickerListInput(rawInput, baseContext.activeCollectionId, deps, template.shortcut?.keepArgToken);
256
256
  resolvedOptions = {
257
257
  ...resolvedOptions,
258
258
  arg: rawInput,