gloomberb 0.18.2 → 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.
- package/README.md +8 -8
- package/README.zh-CN.md +11 -11
- package/bin/{gloomberb → gloom} +3 -1
- package/package.json +6 -2
- package/patches/electrobun@1.18.1.patch +106 -5
- package/src/account/checkout-handoff.tsx +225 -0
- package/src/account/device-signin-dialog.tsx +2 -2
- package/src/account/device-signin.ts +2 -2
- package/src/account/upgrade-dialog.tsx +1 -1
- package/src/api-client/askg.ts +2 -2
- package/src/api-client/auth.ts +2 -2
- package/src/api-client/central-bank-rates.ts +6 -0
- package/src/api-client/collections.ts +5 -1
- package/src/api-client/cot.ts +2 -0
- package/src/api-client/crypto-etf-flows.ts +37 -0
- package/src/api-client/crypto-markets.ts +60 -0
- package/src/api-client/data.ts +99 -5
- package/src/api-client/doe.ts +15 -0
- package/src/api-client/equity-screener.ts +28 -0
- package/src/api-client/exchange-announcements.ts +38 -0
- package/src/api-client/fund-facts.ts +39 -0
- package/src/api-client/futures-curve.ts +9 -1
- package/src/api-client/hiring.ts +301 -0
- package/src/api-client/index.ts +24 -5
- package/src/api-client/market-discovery.ts +14 -0
- package/src/api-client/members.ts +6 -0
- package/src/api-client/mna.ts +6 -0
- package/src/api-client/paths.ts +18 -1
- package/src/api-client/request.ts +26 -7
- package/src/api-client/short-side-publications.ts +37 -0
- package/src/api-client/socket.ts +64 -4
- package/src/api-client/swap-curve.ts +35 -0
- package/src/api-client/telemetry.ts +17 -0
- package/src/api-client/themes.ts +7 -1
- package/src/api-client/types.ts +90 -2
- package/src/app/global-shortcuts.ts +1 -16
- package/src/app/pane-runtime/plugin-bindings.ts +9 -2
- package/src/app/runtime/desktop-deeplink.ts +5 -5
- package/src/app/runtime/plugin-bindings.ts +2 -2
- package/src/app/runtime/startup.ts +13 -0
- package/src/app/runtime/update.ts +28 -8
- package/src/app/star-prompt/status-line.tsx +2 -2
- package/src/architecture/core-builtin-allowlist.json +5 -2
- package/src/architecture/pane-tabs-allowlist.json +65 -0
- package/src/architecture/ui-literals-allowlist.json +3 -3
- package/src/architecture/ui-tokens-allowlist.json +1 -1
- package/src/brokers/broker-portfolio-sync.ts +37 -0
- package/src/brokers/directory.ts +11 -0
- package/src/brokers/logos.ts +3 -1
- package/src/brokers/signed-in/adapter.ts +304 -26
- package/src/brokers/signed-in/client.ts +14 -2
- package/src/brokers/signed-in/connect.ts +10 -2
- package/src/brokers/sync-broker-instance.ts +9 -1
- package/src/capabilities/chart-series.ts +22 -6
- package/src/cli/bank-section.ts +1 -1
- package/src/cli/base-converter.ts +23 -14
- package/src/cli/central-bank-events.ts +1 -1
- package/src/cli/command-options.ts +59 -4
- package/src/cli/commands/api.ts +9 -6
- package/src/cli/commands/broker.ts +2 -2
- package/src/cli/commands/command-utils.ts +2 -2
- package/src/cli/commands/crypto-hints.ts +7 -20
- package/src/cli/commands/fred-series.ts +4 -2
- package/src/cli/commands/keybindings.ts +2 -2
- package/src/cli/commands/market.ts +1189 -296
- package/src/cli/commands/news-hints.ts +2 -2
- package/src/cli/commands/news-search.ts +59 -6
- package/src/cli/commands/options-leaps.ts +41 -26
- package/src/cli/commands/overview.ts +121 -48
- package/src/cli/commands/plugins.ts +9 -9
- package/src/cli/commands/remote.ts +13 -10
- package/src/cli/commands/search.ts +64 -44
- package/src/cli/commands/system.ts +27 -19
- package/src/cli/commands/themes.ts +1 -1
- package/src/cli/commands/ticker.ts +272 -70
- package/src/cli/context.ts +3 -2
- package/src/cli/desktop-pane-shot-view.ts +2 -2
- package/src/cli/desktop-pane-shot.ts +1 -1
- package/src/cli/earnings-calendar.ts +4 -4
- package/src/cli/entry.ts +18 -1
- package/src/cli/errors.ts +20 -2
- package/src/cli/exit-codes.ts +1 -1
- package/src/cli/export-source.ts +10 -4
- package/src/cli/freshness.ts +2 -8
- package/src/cli/fx-forward.ts +130 -0
- package/src/cli/fx-pair.ts +10 -9
- package/src/cli/glossary.ts +64 -20
- package/src/cli/help.ts +20 -14
- package/src/cli/history-export.ts +126 -0
- package/src/cli/history-rows.ts +196 -43
- package/src/cli/index-roots.ts +5 -45
- package/src/cli/index.ts +32 -18
- package/src/cli/issuer-membership.ts +103 -0
- package/src/cli/known-gaps.ts +118 -25
- package/src/cli/listing-arg.ts +315 -43
- package/src/cli/name-entries.ts +73 -22
- package/src/cli/native-smoke.ts +2 -0
- package/src/cli/not-a-ticker.ts +19 -9
- package/src/cli/opentui-libc.ts +5 -0
- package/src/cli/options.ts +12 -0
- package/src/cli/pane-functions/capabilities.ts +77 -20
- package/src/cli/pane-functions/catalog.ts +40 -23
- package/src/cli/pane-functions/discovery.ts +1 -1
- package/src/cli/pane-functions/dom.ts +12 -8
- package/src/cli/pane-functions/financial-ratio-shot.ts +2 -2
- package/src/cli/pane-functions/freshness.ts +174 -23
- package/src/cli/pane-functions/function-help.ts +66 -27
- package/src/cli/pane-functions/headless.ts +48 -16
- package/src/cli/pane-functions/index.ts +82 -21
- package/src/cli/pane-functions/options.ts +22 -2
- package/src/cli/pane-functions/report-notices.ts +12 -4
- package/src/cli/pane-functions/report.ts +5 -5
- package/src/cli/pane-functions/resolver.ts +65 -14
- package/src/cli/pane-functions/screenshot-assessment.ts +322 -0
- package/src/cli/pane-functions/screenshot-bridge.ts +152 -0
- package/src/cli/pane-functions/screenshot-chart-evidence.ts +396 -0
- package/src/cli/pane-functions/screenshot-data-evidence.ts +383 -0
- package/src/cli/pane-functions/screenshot-evidence.ts +1 -1
- package/src/cli/pane-functions/screenshot-payload.ts +453 -0
- package/src/cli/pane-functions/screenshot-render.ts +316 -0
- package/src/cli/pane-functions/screenshot-types.ts +162 -0
- package/src/cli/pane-functions/shot-options.ts +8 -3
- package/src/cli/peso-dollar-rates.ts +79 -0
- package/src/cli/quote-answer.ts +38 -3
- package/src/cli/report-tables.ts +190 -27
- package/src/cli/restore-plugins.ts +29 -14
- package/src/cli/result.ts +122 -25
- package/src/cli/series-search.ts +5 -5
- package/src/cli/statement-filings.ts +19 -0
- package/src/cli/suffixed-listing-rows.ts +49 -0
- package/src/cli/symbol-args.ts +50 -15
- package/src/cli/symbol-cells.ts +120 -0
- package/src/cli/symbol-list.ts +226 -60
- package/src/cli/symbol-rows.ts +131 -25
- package/src/cli/ticker-resolution.ts +108 -11
- package/src/cli/treasury-yields.ts +5 -5
- package/src/cli/types.ts +2 -0
- package/src/cli/uncovered-instrument.ts +3 -3
- package/src/cli/unknown-command.ts +6 -6
- package/src/components/chart/composite/chart-layout.ts +131 -0
- package/src/components/chart/composite/composite-chart.tsx +387 -21
- package/src/components/chart/composite/drawing-store.ts +26 -6
- package/src/components/chart/composite/interactions.ts +9 -3
- package/src/components/chart/composite/legend.tsx +75 -3
- package/src/components/chart/composite/levels.ts +5 -0
- package/src/components/chart/composite/panel-gestures.ts +41 -0
- package/src/components/chart/composite/panel-labels.ts +2 -1
- package/src/components/chart/composite/panel-surface.tsx +316 -11
- package/src/components/chart/composite/price-axis-labels.tsx +27 -3
- package/src/components/chart/composite/rasterizer.ts +44 -19
- package/src/components/chart/composite/scene.ts +16 -4
- package/src/components/chart/composite/text-renderer.ts +48 -21
- package/src/components/chart/composite/toolbar.tsx +52 -5
- package/src/components/chart/composite/types.ts +19 -0
- package/src/components/chart/composite/use-composite-chart-keyboard.ts +120 -13
- package/src/components/chart/composite/use-composite-value-scales.ts +44 -0
- package/src/components/chart/composite/use-composite-viewport.ts +12 -3
- package/src/components/chart/composite/value-scale.ts +149 -0
- package/src/components/chart/composite/volume-profile-paint.ts +6 -3
- package/src/components/chart/core/pointer.ts +2 -0
- package/src/components/chart-table/index.ts +2 -0
- package/src/components/chart-table/read.tsx +74 -0
- package/src/components/command-bar/commands/collection-list.ts +41 -19
- package/src/components/command-bar/commands/collection.ts +9 -3
- package/src/components/command-bar/commands/direct/index.ts +1 -1
- package/src/components/command-bar/commands/direct/runtime.ts +3 -2
- package/src/components/command-bar/pane-templates/items.ts +59 -6
- package/src/components/command-bar/pane-templates/workflow.ts +10 -1
- package/src/components/command-bar/routes/root/command-items.ts +32 -6
- package/src/components/command-bar/routes/root/plugin-install.ts +1 -1
- package/src/components/command-bar/routes/root/provider-search.ts +42 -11
- package/src/components/command-bar/routes/root/results.ts +18 -4
- package/src/components/command-bar/routes/root/runtime.ts +15 -3
- package/src/components/command-bar/routes/root/search-providers.ts +25 -2
- package/src/components/command-bar/routes/root/selection.ts +6 -1
- package/src/components/command-bar/routes/root/shortcut-feedback.ts +4 -1
- package/src/components/command-bar/routes/root/shortcuts.ts +30 -3
- package/src/components/command-bar/routes/ticker-search/results.ts +73 -4
- package/src/components/command-bar/selection-runtime.ts +50 -10
- package/src/components/command-bar/surface/index.tsx +24 -2
- package/src/components/command-bar/view-model.ts +7 -0
- package/src/components/command-bar/workflow/broker.ts +2 -2
- package/src/components/command-bar/workflow/collection-actions.ts +46 -7
- package/src/components/command-bar/workflow/collection-ticker.ts +32 -4
- package/src/components/command-bar/workflow/fields.ts +8 -2
- package/src/components/command-bar/workflow/ops.ts +18 -4
- package/src/components/command-bar/workflow/portfolio-position.ts +53 -4
- package/src/components/command-bar/workflow/submit.ts +3 -2
- package/src/components/command-bar/workflow/tickers.ts +5 -1
- package/src/components/company-logo.tsx +39 -0
- package/src/components/data-table/sections.ts +4 -2
- package/src/components/data-table/view.tsx +23 -3
- package/src/components/form-modal/confirm.tsx +2 -1
- package/src/components/form-modal/request.ts +5 -0
- package/src/components/form-modal/routes.ts +4 -1
- package/src/components/index.ts +13 -6
- package/src/components/layout/detached-pane-shell.tsx +1 -0
- package/src/components/layout/floating-pane.tsx +1 -0
- package/src/components/layout/header.tsx +234 -60
- package/src/components/layout/market-summary.ts +9 -6
- package/src/components/layout/pane/capture-status.ts +1 -1
- package/src/components/layout/pane/footer/model.ts +11 -5
- package/src/components/layout/pane/header.tsx +10 -3
- package/src/components/layout/pane/index.tsx +1 -0
- package/src/components/layout/pane/pane-tabs.tsx +9 -1
- package/src/components/layout/shell/chrome.ts +19 -6
- package/src/components/layout/shell/index.tsx +2 -1
- package/src/components/layout/shell/pane/layers.tsx +19 -1
- package/src/components/layout/status-bar.tsx +2 -2
- package/src/components/market-board/index.tsx +11 -3
- package/src/components/onboarding/onboarding-wizard.tsx +1 -0
- package/src/components/onboarding/portfolio-step/broker-setup-panel.tsx +2 -2
- package/src/components/onboarding/wizard-broker-sync.ts +4 -1
- package/src/components/pane-settings-dialog/desktop.tsx +20 -7
- package/src/components/pane-settings-dialog/tui.tsx +17 -9
- package/src/components/pane-settings-dialog/value.ts +8 -1
- package/src/components/pane-settings-dialog.tsx +44 -13
- package/src/components/sign-in-code-panel.tsx +27 -19
- package/src/components/ui/column-grid.tsx +48 -4
- package/src/components/ui/country-flag-art.tsx +180 -0
- package/src/components/ui/country-flag.tsx +118 -12
- package/src/components/ui/data-table/opentui/index.tsx +61 -2
- package/src/components/ui/data-table/opentui/model.ts +109 -2
- package/src/components/ui/data-table/types.ts +1 -1
- package/src/components/ui/display.tsx +5 -1
- package/src/components/ui/index.ts +3 -1
- package/src/components/ui/logo-mark.tsx +11 -2
- package/src/components/ui/query-bar.tsx +1 -1
- package/src/components/ui/row-notes.ts +79 -0
- package/src/components/ui/stat-grid.tsx +28 -3
- package/src/components/ui/status.tsx +3 -1
- package/src/core/app-services.ts +4 -0
- package/src/core/state/app/layout.ts +4 -4
- package/src/data/cached-query.ts +8 -1
- package/src/data/config/chart-settings.ts +3 -3
- package/src/data/config/home.ts +10 -2
- package/src/data/config/layout.ts +4 -1
- package/src/data/config/store/node.ts +4 -0
- package/src/data/config/store/normalize.ts +13 -3
- package/src/data/config/store/portfolio-as-of-column.ts +2 -2
- package/src/data/json-storage.ts +2 -0
- package/src/data/saved-copies.ts +84 -0
- package/src/docs/snapshot.json +65 -32
- package/src/i18n/es.ts +51 -12
- package/src/i18n/ja.ts +51 -12
- package/src/i18n/ko.ts +51 -12
- package/src/i18n/zh-cn.ts +51 -12
- package/src/i18n/zh-tw.ts +51 -12
- package/src/layout/desks.ts +1 -1
- package/src/layout/launch-layout.ts +1 -1
- package/src/layout/pane-manager/floating-actions.ts +5 -3
- package/src/layout/pane-manager/floating.ts +43 -1
- package/src/layout/pane-manager/index.ts +2 -0
- package/src/layout/selected-ticker.ts +74 -0
- package/src/market-data/depositary-pair.ts +251 -0
- package/src/market-data/futures-board.ts +1 -1
- package/src/market-data/futures-contract.ts +124 -40
- package/src/market-data/fx-closes.ts +17 -2
- package/src/market-data/hooks.tsx +19 -11
- package/src/market-data/market/change-basis.ts +49 -7
- package/src/market-data/market/freshness.ts +34 -5
- package/src/market-data/market/period-return.ts +163 -0
- package/src/market-data/market/trading-sessions.ts +13 -0
- package/src/market-data/market/year-to-date.ts +8 -13
- package/src/market-data/performance.ts +20 -14
- package/src/market-data/perpetual-premium.ts +32 -0
- package/src/market-data/published-apac-sessions.ts +2 -1
- package/src/market-data/published-futures-sessions.ts +69 -0
- package/src/market-data/quotes/contributions.ts +5 -1
- package/src/market-data/quotes/freshness.ts +42 -0
- package/src/market-data/quotes/intraday-bar.ts +37 -0
- package/src/market-data/quotes/regular-session-valuation.ts +13 -8
- package/src/market-data/quotes/resolution.ts +4 -2
- package/src/market-data/tax-equivalent.ts +1 -1
- package/src/market-data/ticker-price-returns.ts +3 -1
- package/src/news/aggregator.ts +5 -1
- package/src/news/news-model.ts +4 -0
- package/src/news/types.ts +11 -0
- package/src/notifications/app-notifier.ts +1 -1
- package/src/plugins/auto-update.ts +2 -2
- package/src/plugins/builtin/account-management/index.tsx +1 -0
- package/src/plugins/builtin/account-management/pane.tsx +9 -8
- package/src/plugins/builtin/alerts/alert-engine.ts +30 -18
- package/src/plugins/builtin/alerts/calendar-events.ts +378 -0
- package/src/plugins/builtin/alerts/cli.ts +485 -76
- package/src/plugins/builtin/alerts/command.ts +5 -10
- package/src/plugins/builtin/alerts/event-rows.ts +9 -5
- package/src/plugins/builtin/alerts/events-pane.tsx +71 -56
- package/src/plugins/builtin/alerts/events.ts +108 -5
- package/src/plugins/builtin/alerts/fired-log.ts +78 -0
- package/src/plugins/builtin/alerts/format.ts +2 -1
- package/src/plugins/builtin/alerts/headless.ts +100 -39
- package/src/plugins/builtin/alerts/history-pane.tsx +105 -62
- package/src/plugins/builtin/alerts/history-rows.ts +89 -0
- package/src/plugins/builtin/alerts/index.tsx +45 -18
- package/src/plugins/builtin/alerts/iv-level.ts +365 -0
- package/src/plugins/builtin/alerts/levels.ts +3 -3
- package/src/plugins/builtin/alerts/pane.tsx +97 -29
- package/src/plugins/builtin/alerts/price.ts +35 -0
- package/src/plugins/builtin/alerts/quotes.ts +24 -0
- package/src/plugins/builtin/alerts/research-builder.ts +84 -11
- package/src/plugins/builtin/alerts/research-rules.ts +77 -3
- package/src/plugins/builtin/alerts/scheduled-check.ts +206 -32
- package/src/plugins/builtin/alerts/scheduled-sources.ts +26 -3
- package/src/plugins/builtin/alerts/scheduled.ts +188 -29
- package/src/plugins/builtin/alerts/storage.ts +13 -10
- package/src/plugins/builtin/alerts/targets.ts +12 -3
- package/src/plugins/builtin/analytics/index.tsx +8 -2
- package/src/plugins/builtin/analytics/metrics.ts +1 -1
- package/src/plugins/builtin/analytics/risk-book.ts +215 -0
- package/src/plugins/builtin/analytics/risk-client.ts +13 -6
- package/src/plugins/builtin/analytics/risk-headless.ts +55 -21
- package/src/plugins/builtin/analytics/risk-math.ts +6 -3
- package/src/plugins/builtin/analytics/risk-model.ts +297 -104
- package/src/plugins/builtin/analytics/risk-options.ts +17 -2
- package/src/plugins/builtin/analytics/risk-pane.tsx +107 -43
- package/src/plugins/builtin/attention/pane.tsx +22 -16
- package/src/plugins/builtin/awards/headless.ts +7 -3
- package/src/plugins/builtin/awards/model.ts +18 -0
- package/src/plugins/builtin/awards/pane.tsx +12 -9
- package/src/plugins/builtin/backtest/export.ts +1 -1
- package/src/plugins/builtin/backtest/headless.ts +3 -3
- package/src/plugins/builtin/backtest/rules.ts +41 -5
- package/src/plugins/builtin/broker-manager/add-flow.tsx +12 -7
- package/src/plugins/builtin/broker-manager/detail.tsx +47 -19
- package/src/plugins/builtin/broker-manager/footer.ts +27 -11
- package/src/plugins/builtin/broker-manager/index.tsx +21 -12
- package/src/plugins/builtin/broker-manager/keyboard.ts +1 -1
- package/src/plugins/builtin/broker-manager/model.ts +12 -2
- package/src/plugins/builtin/broker-manager/pane-actions.tsx +183 -57
- package/src/plugins/builtin/broker-manager/table.ts +28 -12
- package/src/plugins/builtin/broker-trading/account-picker.tsx +2 -1
- package/src/plugins/builtin/broker-trading/chart-levels.ts +82 -13
- package/src/plugins/builtin/broker-trading/controller.ts +45 -13
- package/src/plugins/builtin/broker-trading/dock.tsx +24 -4
- package/src/plugins/builtin/broker-trading/headless.ts +2 -1
- package/src/plugins/builtin/broker-trading/index.tsx +7 -1
- package/src/plugins/builtin/broker-trading/linked-orders.ts +148 -0
- package/src/plugins/builtin/broker-trading/order-feed.ts +75 -7
- package/src/plugins/builtin/broker-trading/orders.tsx +109 -31
- package/src/plugins/builtin/broker-trading/overview-orders.tsx +9 -3
- package/src/plugins/builtin/broker-trading/pane-model.ts +30 -2
- package/src/plugins/builtin/broker-trading/pane.tsx +115 -26
- package/src/plugins/builtin/broker-trading/ticket-parts.tsx +36 -7
- package/src/plugins/builtin/broker-trading/ticket.tsx +122 -36
- package/src/plugins/builtin/buildout/cells.tsx +4 -0
- package/src/plugins/builtin/buildout/detail/index.tsx +5 -1
- package/src/plugins/builtin/buildout/detail/ui.tsx +7 -4
- package/src/plugins/builtin/buildout/pane/index.tsx +34 -18
- package/src/plugins/builtin/buildout/pane/status.tsx +0 -4
- package/src/plugins/builtin/builtin-plugin-meta.ts +1 -1
- package/src/plugins/builtin/catalysts/client.ts +2 -2
- package/src/plugins/builtin/catalysts/detail.tsx +3 -2
- package/src/plugins/builtin/catalysts/index.tsx +1 -1
- package/src/plugins/builtin/catalysts/model.ts +49 -4
- package/src/plugins/builtin/catalysts/pane.tsx +9 -11
- package/src/plugins/builtin/central-bank-rates/client.ts +5 -0
- package/src/plugins/builtin/central-bank-rates/headless.ts +36 -10
- package/src/plugins/builtin/central-bank-rates/model.ts +33 -8
- package/src/plugins/builtin/changelog/index.tsx +1 -0
- package/src/plugins/builtin/chart-composer/catalog-inventory.ts +1 -0
- package/src/plugins/builtin/chart-composer/chart-spec-edit.ts +2 -1
- package/src/plugins/builtin/chart-composer/chart-spec.ts +7 -0
- package/src/plugins/builtin/chart-composer/cli-options.ts +2 -5
- package/src/plugins/builtin/chart-composer/data-catalog-pane.tsx +2 -1
- package/src/plugins/builtin/chart-composer/editor/controller.ts +2 -0
- package/src/plugins/builtin/chart-composer/editor.tsx +4 -1
- package/src/plugins/builtin/chart-composer/headless-schema.ts +28 -26
- package/src/plugins/builtin/chart-composer/headless.ts +253 -35
- package/src/plugins/builtin/chart-composer/index.tsx +12 -2
- package/src/plugins/builtin/chart-composer/leverage-overlay.ts +142 -0
- package/src/plugins/builtin/chart-composer/pane.tsx +128 -28
- package/src/plugins/builtin/chart-composer/series-catalog.ts +1 -0
- package/src/plugins/builtin/chart-composer/series-expression.ts +65 -6
- package/src/plugins/builtin/chart-composer/session-history.ts +15 -21
- package/src/plugins/builtin/chart-composer/session-range.ts +4 -2
- package/src/plugins/builtin/chart-composer/settings.ts +31 -19
- package/src/plugins/builtin/chart-composer/use-series-catalog.ts +5 -6
- package/src/plugins/builtin/chart-composer/viewport-labels.ts +18 -8
- package/src/plugins/builtin/chat/attachments/model.ts +3 -1
- package/src/plugins/builtin/chat/content/index.tsx +1 -1
- package/src/plugins/builtin/chat/pane-links/open.ts +1 -1
- package/src/plugins/builtin/chat/people.ts +1 -1
- package/src/plugins/builtin/clinical-trials/client.ts +5 -2
- package/src/plugins/builtin/clinical-trials/model.ts +13 -4
- package/src/plugins/builtin/clinical-trials/pane.tsx +32 -12
- package/src/plugins/builtin/clinical-trials/ticker-sponsor.ts +17 -0
- package/src/plugins/builtin/cloud/askg/controller.ts +1 -1
- package/src/plugins/builtin/cloud/askg/lock-note.ts +1 -1
- package/src/plugins/builtin/cloud/askg/tool-display.ts +1 -1
- package/src/plugins/builtin/cloud/auth-commands.ts +3 -3
- package/src/plugins/builtin/cloud/team/pane-sections.tsx +105 -47
- package/src/plugins/builtin/cloud/team/pane-ui.tsx +42 -4
- package/src/plugins/builtin/cloud/team/pane.tsx +204 -64
- package/src/plugins/builtin/cloud/thesis/store.ts +45 -22
- package/src/plugins/builtin/cloud-tweets/registration.ts +1 -0
- package/src/plugins/builtin/commodities-energy/index.tsx +29 -2
- package/src/plugins/builtin/commodities-energy/view-state.ts +2 -0
- package/src/plugins/builtin/commodity-balances/pane.tsx +14 -8
- package/src/plugins/builtin/company-attention/app-rank.tsx +11 -10
- package/src/plugins/builtin/company-attention/building-model.ts +222 -0
- package/src/plugins/builtin/company-attention/building.tsx +172 -0
- package/src/plugins/builtin/company-attention/client.ts +117 -1
- package/src/plugins/builtin/company-attention/evidence.ts +16 -3
- package/src/plugins/builtin/company-attention/headless.ts +101 -5
- package/src/plugins/builtin/company-attention/index.tsx +6 -3
- package/src/plugins/builtin/company-attention/model.ts +33 -7
- package/src/plugins/builtin/company-attention/moves-model.ts +253 -0
- package/src/plugins/builtin/company-attention/moves.tsx +159 -0
- package/src/plugins/builtin/company-attention/pane.tsx +89 -31
- package/src/plugins/builtin/company-attention/signals-model.ts +229 -0
- package/src/plugins/builtin/company-attention/signals.tsx +160 -0
- package/src/plugins/builtin/company-kpis/headless.ts +3 -2
- package/src/plugins/builtin/company-kpis/model.ts +2 -2
- package/src/plugins/builtin/company-kpis/pane.tsx +5 -4
- package/src/plugins/builtin/composite-plugins.ts +2 -1
- package/src/plugins/builtin/congress-trades/headless.ts +1 -1
- package/src/plugins/builtin/connections/index.ts +1 -0
- package/src/plugins/builtin/correlation/headless-schema.ts +3 -2
- package/src/plugins/builtin/correlation/headless.ts +7 -4
- package/src/plugins/builtin/correlation/relationship/model.ts +1 -0
- package/src/plugins/builtin/correlation/settings.ts +1 -0
- package/src/plugins/builtin/cot/headless.ts +28 -6
- package/src/plugins/builtin/cot/model.ts +12 -0
- package/src/plugins/builtin/cot/pane.tsx +7 -5
- package/src/plugins/builtin/cpi/headless.ts +5 -1
- package/src/plugins/builtin/cpi/pane.tsx +11 -9
- package/src/plugins/builtin/credit-boards/model.ts +2 -0
- package/src/plugins/builtin/credit-documents/headless.ts +1 -1
- package/src/plugins/builtin/credit-documents/pane.tsx +8 -7
- package/src/plugins/builtin/crypto-board/client.ts +86 -0
- package/src/plugins/builtin/crypto-board/defi-view.tsx +218 -0
- package/src/plugins/builtin/crypto-board/defi.ts +239 -0
- package/src/plugins/builtin/crypto-board/headless.ts +117 -6
- package/src/plugins/builtin/crypto-board/index.tsx +8 -3
- package/src/plugins/builtin/crypto-board/model.ts +40 -8
- package/src/plugins/builtin/crypto-board/pane.tsx +55 -21
- package/src/plugins/builtin/crypto-board/series.ts +19 -1
- package/src/plugins/builtin/crypto-etf-flows/client.ts +60 -0
- package/src/plugins/builtin/crypto-etf-flows/headless.ts +132 -0
- package/src/plugins/builtin/crypto-etf-flows/index.tsx +44 -0
- package/src/plugins/builtin/crypto-etf-flows/model.ts +121 -0
- package/src/plugins/builtin/crypto-etf-flows/pane.tsx +193 -0
- package/src/plugins/builtin/debt-maturities/pane.tsx +4 -3
- package/src/plugins/builtin/debug/index.tsx +1 -0
- package/src/plugins/builtin/dividend-yield/index.tsx +1 -1
- package/src/plugins/builtin/docs/index.tsx +1 -1
- package/src/plugins/builtin/docs/pane.tsx +2 -2
- package/src/plugins/builtin/docs/targets.ts +1 -1
- package/src/plugins/builtin/doe/client.ts +5 -1
- package/src/plugins/builtin/doe/headless.ts +12 -6
- package/src/plugins/builtin/doe/model.ts +43 -6
- package/src/plugins/builtin/doe/pane.tsx +19 -12
- package/src/plugins/builtin/earnings/board-model.ts +13 -6
- package/src/plugins/builtin/earnings/board-table.ts +4 -1
- package/src/plugins/builtin/earnings/board.tsx +253 -50
- package/src/plugins/builtin/earnings/calendar-model.ts +188 -0
- package/src/plugins/builtin/earnings/calendar.tsx +338 -0
- package/src/plugins/builtin/earnings/client.ts +4 -3
- package/src/plugins/builtin/earnings/headless.ts +53 -15
- package/src/plugins/builtin/earnings/history-model.ts +53 -36
- package/src/plugins/builtin/earnings/index.tsx +15 -22
- package/src/plugins/builtin/earnings/model.ts +17 -12
- package/src/plugins/builtin/earnings/scope.ts +89 -0
- package/src/plugins/builtin/earnings-calls/calendar.tsx +310 -0
- package/src/plugins/builtin/earnings-calls/data.ts +146 -2
- package/src/plugins/builtin/earnings-calls/headless.ts +151 -9
- package/src/plugins/builtin/earnings-calls/index.tsx +3 -3
- package/src/plugins/builtin/earnings-calls/lock-note.ts +1 -1
- package/src/plugins/builtin/earnings-calls/pane.tsx +149 -31
- package/src/plugins/builtin/earnings-calls/upcoming.ts +195 -0
- package/src/plugins/builtin/earnings-ripple/pane.tsx +10 -5
- package/src/plugins/builtin/econ/calendar-model.ts +132 -20
- package/src/plugins/builtin/econ/detail-view.tsx +48 -10
- package/src/plugins/builtin/econ/fred-catalog.ts +23 -6
- package/src/plugins/builtin/econ/fred-series-map.ts +4 -0
- package/src/plugins/builtin/econ/index.tsx +112 -25
- package/src/plugins/builtin/econ/print-watch.ts +2 -1
- package/src/plugins/builtin/econ/types.ts +32 -1
- package/src/plugins/builtin/econ-statistics/client.ts +16 -3
- package/src/plugins/builtin/econ-statistics/defs.ts +4 -0
- package/src/plugins/builtin/econ-statistics/detail.tsx +2 -2
- package/src/plugins/builtin/econ-statistics/headless.ts +13 -2
- package/src/plugins/builtin/econ-statistics/index.tsx +3 -3
- package/src/plugins/builtin/econ-statistics/pane.tsx +2 -1
- package/src/plugins/builtin/econ-statistics/stats.ts +103 -0
- package/src/plugins/builtin/econ-statistics/view.ts +16 -1
- package/src/plugins/builtin/equity-screener/client.ts +21 -3
- package/src/plugins/builtin/equity-screener/headless.ts +77 -5
- package/src/plugins/builtin/equity-screener/live.ts +1 -1
- package/src/plugins/builtin/equity-screener/model.ts +34 -0
- package/src/plugins/builtin/equity-screener/pane.tsx +148 -106
- package/src/plugins/builtin/equity-screener/screen-check.ts +90 -0
- package/src/plugins/builtin/equity-screener/ticker-check.tsx +148 -0
- package/src/plugins/builtin/estimate-revisions/headless.ts +3 -1
- package/src/plugins/builtin/estimate-revisions/lock-note.ts +3 -3
- package/src/plugins/builtin/estimate-revisions/model.ts +8 -10
- package/src/plugins/builtin/exposure/headless.ts +51 -6
- package/src/plugins/builtin/exposure/index.tsx +28 -2
- package/src/plugins/builtin/exposure/model.ts +7 -0
- package/src/plugins/builtin/exposure/pane.tsx +16 -10
- package/src/plugins/builtin/fear-greed/index.tsx +1 -1
- package/src/plugins/builtin/filing-events/index.tsx +1 -1
- package/src/plugins/builtin/futures/model.ts +10 -9
- package/src/plugins/builtin/futures/returns.ts +8 -36
- package/src/plugins/builtin/futures/table.tsx +1 -1
- package/src/plugins/builtin/futures-curve/client.ts +40 -9
- package/src/plugins/builtin/futures-curve/headless.ts +39 -17
- package/src/plugins/builtin/futures-curve/model.ts +258 -69
- package/src/plugins/builtin/futures-curve/pane.tsx +46 -17
- package/src/plugins/builtin/fx-matrix/client.ts +15 -8
- package/src/plugins/builtin/fx-matrix/headless.ts +32 -14
- package/src/plugins/builtin/fx-matrix/index.tsx +13 -11
- package/src/plugins/builtin/fx-matrix/live-legs.ts +22 -0
- package/src/plugins/builtin/fx-matrix/settings.ts +2 -1
- package/src/plugins/builtin/gpu/board.tsx +4 -1
- package/src/plugins/builtin/gpu/changes.tsx +10 -10
- package/src/plugins/builtin/gpu/equities.tsx +4 -1
- package/src/plugins/builtin/gpu/headless.ts +9 -4
- package/src/plugins/builtin/gpu/history.tsx +4 -2
- package/src/plugins/builtin/gpu/pane.tsx +5 -3
- package/src/plugins/builtin/help/index.tsx +13 -3
- package/src/plugins/builtin/holders/beneficial-model.ts +8 -11
- package/src/plugins/builtin/holders/beneficial-report.ts +6 -5
- package/src/plugins/builtin/holders/beneficial-view.tsx +7 -3
- package/src/plugins/builtin/holders/client.ts +15 -2
- package/src/plugins/builtin/holders/format.ts +28 -17
- package/src/plugins/builtin/holders/headless.ts +48 -8
- package/src/plugins/builtin/holders/index-holders.ts +264 -0
- package/src/plugins/builtin/holders/pane.tsx +79 -15
- package/src/plugins/builtin/holders/report-rows.ts +35 -7
- package/src/plugins/builtin/holders/table-model.ts +2 -1
- package/src/plugins/builtin/holders/thirteenf-match.ts +3 -1
- package/src/plugins/builtin/holders/treemap.tsx +2 -2
- package/src/plugins/builtin/insider/base-values.ts +11 -7
- package/src/plugins/builtin/insider/client.ts +3 -0
- package/src/plugins/builtin/insider/headless.ts +20 -7
- package/src/plugins/builtin/insider/index.tsx +17 -8
- package/src/plugins/builtin/insider/issuer.ts +34 -4
- package/src/plugins/builtin/insider/signals-client.ts +3 -3
- package/src/plugins/builtin/insider/signals.tsx +1 -1
- package/src/plugins/builtin/insider/table-model.ts +35 -13
- package/src/plugins/builtin/insider/table.tsx +5 -2
- package/src/plugins/builtin/ipo-calendar/pane.tsx +7 -4
- package/src/plugins/builtin/iv-history/client.ts +20 -0
- package/src/plugins/builtin/iv-history/events.ts +145 -0
- package/src/plugins/builtin/iv-history/format.ts +3 -0
- package/src/plugins/builtin/iv-history/headless.ts +91 -7
- package/src/plugins/builtin/iv-history/index.tsx +1 -1
- package/src/plugins/builtin/iv-history/model.ts +13 -4
- package/src/plugins/builtin/iv-history/series.ts +3 -1
- package/src/plugins/builtin/jobs/lock-note.ts +1 -1
- package/src/plugins/builtin/jobs/model.ts +4 -15
- package/src/plugins/builtin/jobs/pane.tsx +7 -5
- package/src/plugins/builtin/jobs/share-bars.tsx +11 -5
- package/src/plugins/builtin/jodi/pane.tsx +14 -8
- package/src/plugins/builtin/layout-manager/index.tsx +1 -0
- package/src/plugins/builtin/macro-day/headless.ts +20 -7
- package/src/plugins/builtin/macro-day/index.tsx +3 -2
- package/src/plugins/builtin/macro-day/model.ts +29 -8
- package/src/plugins/builtin/macro-day/pane.tsx +46 -10
- package/src/plugins/builtin/macro-day/releases.ts +55 -13
- package/src/plugins/builtin/market-heatmap/data.ts +9 -2
- package/src/plugins/builtin/market-heatmap/evidence.ts +1 -1
- package/src/plugins/builtin/market-heatmap/headless.ts +9 -6
- package/src/plugins/builtin/market-heatmap/index.tsx +3 -3
- package/src/plugins/builtin/market-heatmap/model.ts +10 -7
- package/src/plugins/builtin/market-movers/client.ts +36 -21
- package/src/plugins/builtin/market-movers/headless.ts +8 -2
- package/src/plugins/builtin/market-movers/index.tsx +16 -10
- package/src/plugins/builtin/market-movers/screener.ts +33 -11
- package/src/plugins/builtin/market-movers/session-body.tsx +4 -2
- package/src/plugins/builtin/market-movers/session-table.ts +4 -2
- package/src/plugins/builtin/market-movers/table.ts +4 -1
- package/src/plugins/builtin/market-valuation/headless.ts +2 -0
- package/src/plugins/builtin/market-valuation/view.ts +5 -0
- package/src/plugins/builtin/members/headless.ts +6 -5
- package/src/plugins/builtin/members/pane.tsx +11 -4
- package/src/plugins/builtin/mna/client.ts +1 -0
- package/src/plugins/builtin/mna/detail.tsx +20 -32
- package/src/plugins/builtin/mna/distress/detail.tsx +16 -4
- package/src/plugins/builtin/mna/distress/model.ts +3 -2
- package/src/plugins/builtin/mna/distress/pane.tsx +7 -4
- package/src/plugins/builtin/mna/headless.ts +6 -13
- package/src/plugins/builtin/mna/model.ts +93 -15
- package/src/plugins/builtin/mna/pane.tsx +5 -4
- package/src/plugins/builtin/news/headless.ts +12 -6
- package/src/plugins/builtin/news/index.tsx +10 -1
- package/src/plugins/builtin/news/wire/index.tsx +3 -2
- package/src/plugins/builtin/news/wire/news/command-bar-search.ts +26 -10
- package/src/plugins/builtin/news/wire/news/query-presets.ts +6 -2
- package/src/plugins/builtin/news/wire/rss/cli.ts +3 -3
- package/src/plugins/builtin/notes/cli.ts +50 -15
- package/src/plugins/builtin/notes/export.ts +17 -6
- package/src/plugins/builtin/notes/files.ts +16 -5
- package/src/plugins/builtin/openfda/pane.tsx +1 -1
- package/src/plugins/builtin/options/carry.ts +2 -2
- package/src/plugins/builtin/options/enrichment-model.ts +10 -9
- package/src/plugins/builtin/options/index.tsx +1 -1
- package/src/plugins/builtin/options/model-spot.ts +70 -4
- package/src/plugins/builtin/options/view.tsx +51 -23
- package/src/plugins/builtin/options-calculator/headless.ts +46 -7
- package/src/plugins/builtin/options-calculator/pane.tsx +3 -2
- package/src/plugins/builtin/options-positioning/headless.ts +11 -3
- package/src/plugins/builtin/options-positioning/model.ts +24 -0
- package/src/plugins/builtin/options-positioning/pane.tsx +10 -12
- package/src/plugins/builtin/options-scenario/client.ts +142 -29
- package/src/plugins/builtin/options-scenario/collar.ts +8 -6
- package/src/plugins/builtin/options-scenario/csp-screen-headless.ts +127 -0
- package/src/plugins/builtin/options-scenario/csp-screen-pane.tsx +165 -0
- package/src/plugins/builtin/options-scenario/csp-screen.ts +258 -0
- package/src/plugins/builtin/options-scenario/csp.ts +101 -21
- package/src/plugins/builtin/options-scenario/headless.ts +49 -21
- package/src/plugins/builtin/options-scenario/hedge.ts +20 -14
- package/src/plugins/builtin/options-scenario/index.tsx +28 -3
- package/src/plugins/builtin/options-scenario/model.ts +13 -0
- package/src/plugins/builtin/options-scenario/pane.tsx +22 -10
- package/src/plugins/builtin/perps/equity-row.tsx +11 -3
- package/src/plugins/builtin/perps/freshness.ts +8 -5
- package/src/plugins/builtin/perps/headless.ts +3 -1
- package/src/plugins/builtin/perps/list-perpetuals.ts +25 -4
- package/src/plugins/builtin/perps/live-rows.ts +161 -0
- package/src/plugins/builtin/perps/markets-section.tsx +154 -0
- package/src/plugins/builtin/perps/pane.tsx +36 -17
- package/src/plugins/builtin/perps/venue-markets.ts +96 -0
- package/src/plugins/builtin/plugin-marketplace/index.tsx +2 -1
- package/src/plugins/builtin/plugin-marketplace/pane.tsx +145 -60
- package/src/plugins/builtin/portfolio-list/cli/bulk-symbols.ts +78 -27
- package/src/plugins/builtin/portfolio-list/cli/portfolio-command.ts +158 -141
- package/src/plugins/builtin/portfolio-list/cli/render.ts +49 -20
- package/src/plugins/builtin/portfolio-list/cli/shared.ts +3 -3
- package/src/plugins/builtin/portfolio-list/cli/watchlist-command.ts +29 -24
- package/src/plugins/builtin/portfolio-list/headless.ts +6 -3
- package/src/plugins/builtin/portfolio-list/income.ts +13 -2
- package/src/plugins/builtin/portfolio-list/index.tsx +9 -2
- package/src/plugins/builtin/portfolio-list/pane/index.tsx +21 -8
- package/src/plugins/builtin/portfolio-list/pane/purchase-date-fx.ts +46 -0
- package/src/plugins/builtin/portfolio-list/summary/live-accounts.ts +16 -9
- package/src/plugins/builtin/portfolio-list/summary/totals.ts +2 -15
- package/src/plugins/builtin/power/client.ts +6 -3
- package/src/plugins/builtin/power/evidence.ts +22 -7
- package/src/plugins/builtin/power/gas.tsx +5 -1
- package/src/plugins/builtin/power/pane.tsx +44 -32
- package/src/plugins/builtin/power/prices.tsx +10 -3
- package/src/plugins/builtin/research/analyst-headless.ts +25 -8
- package/src/plugins/builtin/research/analyst-model.ts +68 -3
- package/src/plugins/builtin/research/corporate-actions-pane.tsx +63 -14
- package/src/plugins/builtin/research/event-model.ts +3 -1
- package/src/plugins/builtin/research/event-sources.ts +12 -4
- package/src/plugins/builtin/research/index.tsx +2 -1
- package/src/plugins/builtin/research/relative-valuation-basis.ts +58 -0
- package/src/plugins/builtin/research/relative-valuation-columns.ts +31 -2
- package/src/plugins/builtin/research/relative-valuation-currency.ts +12 -5
- package/src/plugins/builtin/research/relative-valuation-headless.ts +84 -26
- package/src/plugins/builtin/research/relative-valuation-model.ts +88 -19
- package/src/plugins/builtin/research/relative-valuation-pane.tsx +76 -9
- package/src/plugins/builtin/research/relative-valuation-peers.ts +1 -1
- package/src/plugins/builtin/reverse-dcf/client.ts +2 -1
- package/src/plugins/builtin/reverse-dcf/model.ts +10 -5
- package/src/plugins/builtin/risk-factors/index.tsx +2 -2
- package/src/plugins/builtin/scanner/lock-note.ts +1 -1
- package/src/plugins/builtin/seasonality/client.ts +2 -1
- package/src/plugins/builtin/sec/forms.ts +13 -0
- package/src/plugins/builtin/sec/fund-abroad.ts +32 -0
- package/src/plugins/builtin/sec/fund-facts.ts +68 -8
- package/src/plugins/builtin/sec/headless.ts +85 -8
- package/src/plugins/builtin/sec/index.tsx +58 -12
- package/src/plugins/builtin/sectors/client.ts +6 -4
- package/src/plugins/builtin/sectors/sector-model.ts +11 -15
- package/src/plugins/builtin/series-inventory.ts +2 -0
- package/src/plugins/builtin/shared/broker-reconnect.ts +107 -22
- package/src/plugins/builtin/shared/cloud-resource.ts +15 -2
- package/src/plugins/builtin/shared/cloud-upgrade.ts +34 -6
- package/src/plugins/builtin/shared/earnings-calendar.ts +375 -0
- package/src/plugins/builtin/{earnings/estimate-basis.ts → shared/earnings-estimate-basis.ts} +1 -1
- package/src/plugins/builtin/shared/earnings-report.ts +3 -3
- package/src/plugins/builtin/shared/fx-rate-freshness.ts +23 -1
- package/src/plugins/builtin/shared/job-posting.ts +129 -0
- package/src/plugins/builtin/shared/pro-lock-note.ts +3 -3
- package/src/plugins/builtin/shared/report-freshness.ts +3 -0
- package/src/plugins/builtin/shared/research-trading.tsx +23 -0
- package/src/plugins/builtin/shared/series-cache.ts +2 -0
- package/src/plugins/builtin/shared/series-list-detail.tsx +3 -1
- package/src/plugins/builtin/shared/ticker-surface.ts +2 -1
- package/src/plugins/builtin/shared/volatility/options.ts +2 -1
- package/src/plugins/builtin/short-interest/client.ts +2 -0
- package/src/plugins/builtin/short-interest/headless.ts +41 -12
- package/src/plugins/builtin/short-interest/index.tsx +23 -1
- package/src/plugins/builtin/short-interest/model.ts +70 -19
- package/src/plugins/builtin/short-interest/pane.tsx +19 -2
- package/src/plugins/builtin/short-interest/publications-client.ts +82 -0
- package/src/plugins/builtin/short-interest/publications-headless.ts +29 -0
- package/src/plugins/builtin/short-interest/publications-model.ts +50 -0
- package/src/plugins/builtin/short-interest/publications-pane.tsx +66 -0
- package/src/plugins/builtin/short-interest/schedule.ts +35 -2
- package/src/plugins/builtin/short-interest/surface.tsx +11 -4
- package/src/plugins/builtin/short-interest/types.ts +9 -0
- package/src/plugins/builtin/short-interest/watch-client.ts +14 -8
- package/src/plugins/builtin/short-interest/watch-model.ts +12 -25
- package/src/plugins/builtin/short-interest/watch-pane.tsx +5 -1
- package/src/plugins/builtin/social-mentions/client.ts +2 -1
- package/src/plugins/builtin/supply-chain/flow.tsx +33 -9
- package/src/plugins/builtin/supply-chain/model.ts +51 -3
- package/src/plugins/builtin/supply-chain/pane.tsx +78 -39
- package/src/plugins/builtin/supply-chain/row-evidence.tsx +1 -1
- package/src/plugins/builtin/themes/headless.ts +8 -5
- package/src/plugins/builtin/themes/model.ts +14 -4
- package/src/plugins/builtin/themes/pane.tsx +24 -5
- package/src/plugins/builtin/thirteenf/headless.ts +5 -5
- package/src/plugins/builtin/thirteenf/signals.ts +3 -1
- package/src/plugins/builtin/ticker-detail/adr-pair/headless.ts +123 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/model.ts +132 -0
- package/src/plugins/builtin/ticker-detail/adr-pair/tab.tsx +87 -0
- package/src/plugins/builtin/ticker-detail/data-panes/historical-prices.tsx +40 -26
- package/src/plugins/builtin/ticker-detail/data-panes/history-bars.ts +8 -4
- package/src/plugins/builtin/ticker-detail/data-panes/returns-history.ts +67 -3
- package/src/plugins/builtin/ticker-detail/data-panes/returns-model.ts +112 -5
- package/src/plugins/builtin/ticker-detail/data-panes/returns-pane.tsx +17 -2
- package/src/plugins/builtin/ticker-detail/financials/aggregation.ts +21 -7
- package/src/plugins/builtin/ticker-detail/financials/model.ts +36 -1
- package/src/plugins/builtin/ticker-detail/financials/offerings.ts +56 -0
- package/src/plugins/builtin/ticker-detail/financials/ratios.ts +62 -13
- package/src/plugins/builtin/ticker-detail/financials/tab.tsx +30 -4
- package/src/plugins/builtin/ticker-detail/headless-schema.ts +14 -2
- package/src/plugins/builtin/ticker-detail/headless.ts +148 -35
- package/src/plugins/builtin/ticker-detail/index.tsx +37 -5
- package/src/plugins/builtin/ticker-detail/overview/model.ts +65 -10
- package/src/plugins/builtin/ticker-detail/overview/pane.tsx +9 -1
- package/src/plugins/builtin/ticker-detail/overview-tab.tsx +68 -11
- package/src/plugins/builtin/ticker-detail/pane.tsx +11 -0
- package/src/plugins/builtin/ticker-detail/quote-footer.ts +8 -3
- package/src/plugins/builtin/ticker-detail/research-tabs.ts +11 -0
- package/src/plugins/builtin/vol-surface/client.ts +28 -7
- package/src/plugins/builtin/vol-surface/headless.ts +43 -15
- package/src/plugins/builtin/vol-surface/model.ts +34 -12
- package/src/plugins/builtin/vol-surface/pane.tsx +33 -13
- package/src/plugins/builtin/vol-surface/stored.ts +34 -3
- package/src/plugins/builtin/vol-surface/tables.ts +14 -0
- package/src/plugins/builtin/volatility/model.ts +5 -10
- package/src/plugins/builtin/world-venue-map/basemap-layer.tsx +4 -3
- package/src/plugins/builtin/world-venue-map/basemap.ts +3 -1
- package/src/plugins/builtin/world-venue-map/chokepoint-chart.ts +40 -0
- package/src/plugins/builtin/world-venue-map/evidence.ts +1 -1
- package/src/plugins/builtin/world-venue-map/geo-series.ts +90 -11
- package/src/plugins/builtin/world-venue-map/headless.ts +1 -1
- package/src/plugins/builtin/world-venue-map/index.ts +3 -26
- package/src/plugins/builtin/world-venue-map/layers.ts +1 -1
- package/src/plugins/builtin/world-venue-map/map.tsx +2 -1
- package/src/plugins/builtin/world-venue-map/pane.tsx +4 -2
- package/src/plugins/builtin/world-venue-map/venue-header.tsx +15 -4
- package/src/plugins/builtin/yield-curve/client.ts +25 -0
- package/src/plugins/builtin/yield-curve/curves.ts +7 -4
- package/src/plugins/builtin/yield-curve/headless.ts +38 -4
- package/src/plugins/builtin/yield-curve/history.ts +4 -3
- package/src/plugins/builtin/yield-curve/index.tsx +12 -6
- package/src/plugins/builtin/yield-curve/swaps-model.ts +93 -0
- package/src/plugins/builtin/yield-curve/swaps.tsx +99 -0
- package/src/plugins/bundle.ts +1 -1
- package/src/plugins/catalog-browser.ts +2 -1
- package/src/plugins/compat.ts +3 -3
- package/src/plugins/dependencies.ts +75 -14
- package/src/plugins/extracted-plugins.ts +132 -34
- package/src/plugins/host-link.ts +149 -34
- package/src/plugins/installer.ts +35 -10
- package/src/plugins/loader.ts +206 -38
- package/src/plugins/manager-node.ts +2 -2
- package/src/plugins/marketplace/deactivation.ts +22 -0
- package/src/plugins/marketplace/model.ts +2 -2
- package/src/plugins/marketplace/packs.ts +1 -1
- package/src/plugins/ownership.ts +1 -1
- package/src/plugins/peer-retry.ts +155 -0
- package/src/plugins/registry/contributions.ts +3 -1
- package/src/plugins/registry/index.ts +4 -3
- package/src/plugins/registry/plugin-state.ts +3 -0
- package/src/plugins/seed-notice.ts +20 -0
- package/src/plugins/shortcut-argument.ts +39 -0
- package/src/portfolio/allocation.ts +1 -1
- package/src/portfolio/collection-name.ts +31 -0
- package/src/portfolio/column-values.ts +10 -8
- package/src/portfolio/cost-fx.ts +296 -19
- package/src/portfolio/manual-lots.ts +75 -0
- package/src/portfolio/mutations.ts +60 -22
- package/src/portfolio/suffixed-listings.ts +209 -0
- package/src/portfolio/totals-currency.ts +24 -0
- package/src/public/__snapshots__/public-api.test.ts.snap +14 -0
- package/src/public/time-series.ts +11 -8
- package/src/remote/schema.ts +1 -1
- package/src/renderers/browser/config-host.ts +3 -0
- package/src/renderers/browser/main.tsx +23 -3
- package/src/renderers/dom/boot-frame-page.ts +187 -0
- package/src/renderers/dom/boot-frame.ts +237 -0
- package/src/renderers/dom/build-assets.ts +46 -8
- package/src/renderers/dom/desktop/controls.tsx +1 -1
- package/src/renderers/dom/desktop/query-bar.tsx +2 -0
- package/src/renderers/dom/dom-ui-host.tsx +4 -29
- package/src/renderers/dom/host/ascii-text.ts +16 -2
- package/src/renderers/dom/host/box.tsx +43 -2
- package/src/renderers/dom/host/chart-surface.tsx +2 -0
- package/src/renderers/dom/host/hls.chunk.ts +3 -0
- package/src/renderers/dom/host/image-surface.tsx +49 -0
- package/src/renderers/dom/host/media-surface.tsx +24 -18
- package/src/renderers/dom/host/mouse.ts +30 -0
- package/src/renderers/dom/host/size-observer.ts +1 -1
- package/src/renderers/dom/host/style.ts +1 -1
- package/src/renderers/dom/host/tabs.tsx +16 -5
- package/src/renderers/dom/host/top-surface.ts +127 -0
- package/src/renderers/dom/styles.css +115 -0
- package/src/renderers/dom/test-utils.tsx +2 -1
- package/src/renderers/electrobun/bun/application-menu/index.ts +3 -3
- package/src/renderers/electrobun/bun/core-capabilities.ts +9 -1
- package/src/renderers/electrobun/bun/desktop/backend-requests.ts +3 -0
- package/src/renderers/electrobun/bun/desktop/backend.ts +56 -3
- package/src/renderers/electrobun/bun/desktop/detached-windows.ts +1 -1
- package/src/renderers/electrobun/bun/desktop/host-requests.ts +9 -3
- package/src/renderers/electrobun/bun/desktop/initialization.ts +81 -18
- package/src/renderers/electrobun/bun/desktop/update.ts +210 -30
- package/src/renderers/electrobun/bun/external-plugins.ts +29 -7
- package/src/renderers/electrobun/bun/index.ts +11 -1
- package/src/renderers/electrobun/bun/window/boot-frame.ts +67 -0
- package/src/renderers/electrobun/bun/window/create.ts +4 -1
- package/src/renderers/electrobun/shared/boot-frame.ts +7 -0
- package/src/renderers/electrobun/shared/protocol.ts +6 -1
- package/src/renderers/electrobun/view/cli-pane-shot-entry.tsx +1 -1
- package/src/renderers/electrobun/view/config-host.ts +3 -0
- package/src/renderers/electrobun/view/fatal-screen.tsx +1 -1
- package/src/renderers/electrobun/view/main.tsx +30 -4
- package/src/renderers/electrobun/view/news-source.ts +9 -7
- package/src/renderers/electrobun/view/remote/asset-data-client.ts +9 -2
- package/src/renderers/electrobun/view/ui-host.tsx +1 -1
- package/src/renderers/opentui/browser-open.ts +88 -0
- package/src/renderers/opentui/host.tsx +5 -14
- package/src/renderers/opentui/image/loader.ts +3 -2
- package/src/renderers/opentui/native-smoke.ts +10 -1
- package/src/renderers/opentui/pane-image/index.ts +2 -1
- package/src/renderers/opentui/render-lib.ts +253 -0
- package/src/renderers/opentui/render-timing-smoke.ts +1 -1
- package/src/renderers/opentui/start.tsx +8 -1
- package/src/renderers/share/layout-view.tsx +2 -2
- package/src/renderers/share/main.tsx +4 -4
- package/src/renderers/share/view.tsx +1 -1
- package/src/series/resolve.ts +22 -6
- package/src/series/standalone.ts +30 -2
- package/src/series/types.ts +8 -1
- package/src/shares/api.ts +4 -1
- package/src/shares/pane.ts +1 -1
- package/src/sources/gloomberb-cloud/fred-series.ts +46 -1
- package/src/sources/gloomberb-cloud/index.ts +39 -16
- package/src/sources/gloomberb-cloud/news.ts +39 -0
- package/src/sources/gloomberb-cloud/normalizers.ts +14 -1
- package/src/sources/gloomberb-cloud/perpetuals.ts +49 -1
- package/src/sources/listing-symbols.ts +37 -0
- package/src/sources/provider-errors.ts +16 -2
- package/src/sources/provider-router/financial-routes.ts +21 -3
- package/src/sources/provider-router/financials.ts +15 -2
- package/src/sources/provider-router/history.ts +30 -8
- package/src/sources/provider-router/index.ts +16 -0
- package/src/sources/provider-router/primary.ts +1 -1
- package/src/state/app/bootstrap.ts +23 -0
- package/src/state/hooks/inline-tickers.ts +30 -5
- package/src/sync/controller.ts +1 -1
- package/src/sync/core-contributors.ts +46 -14
- package/src/team/collections-sync.ts +2 -1
- package/src/team/collections.ts +178 -17
- package/src/telemetry/crash-reports.ts +21 -4
- package/src/telemetry/update-failures-node.ts +59 -0
- package/src/telemetry/update-failures.ts +307 -0
- package/src/test-support/builtin-panes.ts +1 -1
- package/src/theme/colors.ts +3 -30
- package/src/theme/ui-tokens.ts +37 -1
- package/src/tickers/company-name-listing.ts +215 -36
- package/src/tickers/company-name.ts +43 -0
- package/src/tickers/index-roots.ts +47 -0
- package/src/tickers/instrument-label.ts +5 -1
- package/src/tickers/listing-fate.ts +30 -0
- package/src/tickers/metadata.ts +10 -0
- package/src/tickers/perpetual-listing.ts +5 -2
- package/src/tickers/search/home-listing.ts +75 -0
- package/src/tickers/search/index.ts +76 -27
- package/src/tickers/search/ranking.ts +54 -4
- package/src/tickers/search/upsert.ts +29 -0
- package/src/tickers/terminal-codes.ts +416 -40
- package/src/time-series/bar-aggregation.ts +243 -0
- package/src/time-series/base-series.ts +307 -0
- package/src/time-series/chart-bounds.ts +349 -0
- package/src/time-series/chart-seed.ts +142 -0
- package/src/time-series/economic.ts +5 -0
- package/src/time-series/fundamentals.ts +18 -3
- package/src/time-series/history-acquisition.ts +499 -0
- package/src/time-series/leverage.ts +100 -0
- package/src/time-series/market-resolution.ts +4 -2
- package/src/time-series/market.ts +2 -1
- package/src/time-series/price-comparison.ts +175 -30
- package/src/time-series/range.ts +9 -1
- package/src/time-series/resolution.ts +174 -16
- package/src/time-series/resolve-context.ts +157 -0
- package/src/time-series/resolve.ts +126 -1577
- package/src/time-series/series-name.ts +38 -0
- package/src/time-series/series-presentation.ts +208 -0
- package/src/time-series/spec.ts +11 -6
- package/src/time-series/studies.ts +109 -12
- package/src/time-series/tail-reconcile.ts +121 -0
- package/src/time-series/types.ts +29 -2
- package/src/time-series/use-chart-resolution.ts +4 -5
- package/src/types/broker.ts +10 -0
- package/src/types/config.ts +14 -0
- package/src/types/data-provider.ts +20 -0
- package/src/types/exchange-rate.ts +6 -0
- package/src/types/financials.ts +104 -7
- package/src/types/headless.ts +83 -6
- package/src/types/instrument.ts +3 -0
- package/src/types/issuer-listings.ts +28 -0
- package/src/types/plugin.ts +65 -8
- package/src/types/price-history.ts +2 -0
- package/src/types/ticker.ts +13 -0
- package/src/types/trading.ts +59 -1
- package/src/ui/ascii-font.ts +13 -1
- package/src/ui/host.tsx +6 -1
- package/src/updater/command-names.ts +175 -0
- package/src/updater/failure.ts +163 -0
- package/src/updater/index.ts +97 -28
- package/src/utils/calendar-date.ts +32 -15
- package/src/utils/cash-runway.ts +241 -0
- package/src/utils/central-banks.ts +42 -0
- package/src/utils/cli-output.ts +259 -80
- package/src/utils/contract-month.ts +16 -0
- package/src/utils/crypto-pair.ts +61 -3
- package/src/utils/currency-pair.ts +26 -0
- package/src/utils/currency-units.ts +29 -0
- package/src/utils/datetime-format.ts +10 -0
- package/src/utils/debug-log.ts +1 -1
- package/src/utils/decimal-comma.ts +39 -6
- package/src/utils/exchange-announcements.ts +71 -0
- package/src/utils/exchange-rate-snapshot.ts +10 -0
- package/src/utils/financial-statements.ts +83 -4
- package/src/utils/format.ts +34 -16
- package/src/utils/fundamentals.ts +150 -34
- package/src/utils/fx-market-hours.ts +10 -1
- package/src/utils/latest-financial-period.ts +8 -0
- package/src/utils/linux-libc.ts +54 -0
- package/src/utils/market-capitalization.ts +111 -15
- package/src/utils/max-drawdown.ts +64 -0
- package/src/utils/network-failure.ts +83 -0
- package/src/utils/option-expiry.ts +139 -7
- package/src/utils/price-earnings.ts +11 -5
- package/src/utils/price-history.ts +18 -8
- package/src/utils/price-window.ts +131 -0
- package/src/utils/release-date.ts +47 -0
- package/src/utils/sec.ts +71 -0
- package/src/utils/throttled-fetch.ts +11 -4
- package/src/utils/trailing-eps.ts +67 -0
- package/src/utils/typed-text.ts +21 -0
- package/src/utils/utc-time.ts +24 -1
- package/src/version.ts +6 -0
- package/src/cli/pane-functions/screenshot.ts +0 -2122
|
@@ -59,6 +59,31 @@ export interface KeyboardToolDrag {
|
|
|
59
59
|
end: ChartDrawingPoint;
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
+
/** The chart's own layout: its tool bar, its legend and its panels' heights. */
|
|
63
|
+
export interface CompositeChartLayoutControls {
|
|
64
|
+
/** The bar is saved hidden; it still opens while a tool is in hand. */
|
|
65
|
+
toolbarHidden: boolean;
|
|
66
|
+
toggleToolbar: () => void;
|
|
67
|
+
/** The legend has more than one series, so it can fold to its first. */
|
|
68
|
+
legendCollapsible: boolean;
|
|
69
|
+
legendCollapsed: boolean;
|
|
70
|
+
toggleLegend: () => void;
|
|
71
|
+
/** Two or more panels share the plot, so the keys can move the line between them. */
|
|
72
|
+
panelsResizable: boolean;
|
|
73
|
+
stepTopPanel: (direction: 1 | -1) => void;
|
|
74
|
+
/** Heights were set by hand. */
|
|
75
|
+
panelHeightsSet: boolean;
|
|
76
|
+
resetPanelHeights: () => void;
|
|
77
|
+
/** A panel has the whole plot. */
|
|
78
|
+
panelMaximized: boolean;
|
|
79
|
+
restorePanels: () => void;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Shift with one of the arrows, and no other modifier. */
|
|
83
|
+
function isShiftedArrow(event: { name?: string; shift?: boolean; ctrl?: boolean; meta?: boolean; alt?: boolean }, ...names: string[]): boolean {
|
|
84
|
+
return event.shift === true && !event.ctrl && !event.meta && !event.alt && names.includes(event.name ?? "");
|
|
85
|
+
}
|
|
86
|
+
|
|
62
87
|
/** Shift and a letter, whether or not the terminal reports the shift itself. */
|
|
63
88
|
function isShiftedLetter(event: { name?: string; shift?: boolean; ctrl?: boolean; meta?: boolean; alt?: boolean }, letter: string): boolean {
|
|
64
89
|
if (event.ctrl || event.meta || event.alt) return false;
|
|
@@ -76,6 +101,7 @@ export function useCompositeChartKeyboard({
|
|
|
76
101
|
pin,
|
|
77
102
|
onActivate,
|
|
78
103
|
timePick,
|
|
104
|
+
pricePick,
|
|
79
105
|
levels,
|
|
80
106
|
visibleLegendSeries,
|
|
81
107
|
visibleSeriesIds,
|
|
@@ -83,6 +109,7 @@ export function useCompositeChartKeyboard({
|
|
|
83
109
|
isSeriesToggleable,
|
|
84
110
|
navigationFrame,
|
|
85
111
|
activeUserViewport,
|
|
112
|
+
scaledByHand,
|
|
86
113
|
panViewportByRatio,
|
|
87
114
|
zoomViewport,
|
|
88
115
|
setViewportRange,
|
|
@@ -94,6 +121,7 @@ export function useCompositeChartKeyboard({
|
|
|
94
121
|
addDrawing,
|
|
95
122
|
removeDrawing,
|
|
96
123
|
pickDrawColor,
|
|
124
|
+
layout,
|
|
97
125
|
}: {
|
|
98
126
|
focused: boolean;
|
|
99
127
|
interactive: boolean;
|
|
@@ -106,6 +134,7 @@ export function useCompositeChartKeyboard({
|
|
|
106
134
|
pin: { pinned: boolean; toggle: () => void } | null;
|
|
107
135
|
onActivate: CompositeChartProps["onActivate"];
|
|
108
136
|
timePick: CompositeChartProps["timePick"];
|
|
137
|
+
pricePick: CompositeChartProps["pricePick"];
|
|
109
138
|
levels: CompositeChartProps["levels"];
|
|
110
139
|
visibleLegendSeries: ResolvedSeries[];
|
|
111
140
|
visibleSeriesIds: ReadonlySet<string>;
|
|
@@ -113,6 +142,8 @@ export function useCompositeChartKeyboard({
|
|
|
113
142
|
isSeriesToggleable: CompositeChartProps["isSeriesToggleable"];
|
|
114
143
|
navigationFrame: CompositeNavigationFrame | null;
|
|
115
144
|
activeUserViewport: CompositeViewportRange | null;
|
|
145
|
+
/** A value axis was stretched or squeezed by hand, which `resetViewport` also fits again. */
|
|
146
|
+
scaledByHand: boolean;
|
|
116
147
|
panViewportByRatio: (shiftRatio: number) => void;
|
|
117
148
|
zoomViewport: (zoomFactor: number, anchorRatio?: number) => void;
|
|
118
149
|
setViewportRange: (range: CompositeViewportRange) => void;
|
|
@@ -124,6 +155,7 @@ export function useCompositeChartKeyboard({
|
|
|
124
155
|
addDrawing: (drawing: ChartDrawing) => void;
|
|
125
156
|
removeDrawing: () => void;
|
|
126
157
|
pickDrawColor: (color: string) => void;
|
|
158
|
+
layout: CompositeChartLayoutControls;
|
|
127
159
|
}) {
|
|
128
160
|
const [legendKeyboardIndex, setLegendKeyboardIndex] = useState<number | null>(null);
|
|
129
161
|
const [armedTool, setArmedTool] = useState<ChartToolKind | null>(null);
|
|
@@ -187,8 +219,8 @@ export function useCompositeChartKeyboard({
|
|
|
187
219
|
if (wasFocusedRef.current && !focused) setEntered(false);
|
|
188
220
|
wasFocusedRef.current = focused;
|
|
189
221
|
}, [focused]);
|
|
190
|
-
// A time is picked with the arrows and Enter.
|
|
191
|
-
const picking = !!timePick;
|
|
222
|
+
// A time or a price is picked with the arrows and Enter.
|
|
223
|
+
const picking = !!timePick || !!pricePick;
|
|
192
224
|
useEffect(() => {
|
|
193
225
|
if (picking) setEntered(true);
|
|
194
226
|
}, [picking]);
|
|
@@ -287,6 +319,8 @@ export function useCompositeChartKeyboard({
|
|
|
287
319
|
};
|
|
288
320
|
const stepLegend = (direction: -1 | 1) => {
|
|
289
321
|
onActivate?.();
|
|
322
|
+
// The series stepped to must be on screen.
|
|
323
|
+
if (layout.legendCollapsed) layout.toggleLegend();
|
|
290
324
|
setLegendKeyboardIndex((current) => (
|
|
291
325
|
current === null
|
|
292
326
|
? direction > 0 ? 0 : visibleLegendSeries.length - 1
|
|
@@ -298,9 +332,9 @@ export function useCompositeChartKeyboard({
|
|
|
298
332
|
onActivate?.();
|
|
299
333
|
onToggleSeries?.(legendEntry.id);
|
|
300
334
|
};
|
|
301
|
-
/**
|
|
302
|
-
const
|
|
303
|
-
if (!levels
|
|
335
|
+
/** The levels' series price at the keyboard cursor, or the last price without a cursor. */
|
|
336
|
+
const priceAtCursor = (): number | null => {
|
|
337
|
+
if (!levels || !levelHost || !scene) return null;
|
|
304
338
|
const { panel, domain } = levelHost;
|
|
305
339
|
const date = keyboardCursorDateRef.current ?? scene.dates.at(-1) ?? null;
|
|
306
340
|
// The levels' own series, not whichever one the panel lists first.
|
|
@@ -308,8 +342,13 @@ export function useCompositeChartKeyboard({
|
|
|
308
342
|
const value = (date ? resolveMeasureValueAt(pricePanel, date.getTime()) : null)
|
|
309
343
|
?? (panel.lastPrice?.seriesId === levels.seriesId ? panel.lastPrice.value : null)
|
|
310
344
|
?? unprojectCompositeValue(0.5, domain);
|
|
311
|
-
|
|
312
|
-
|
|
345
|
+
return value === null ? null : roundLevelValue(value, domain);
|
|
346
|
+
};
|
|
347
|
+
/** A level at the keyboard cursor's price, or the last price without a cursor. */
|
|
348
|
+
const addLevelAtCursor = () => {
|
|
349
|
+
if (!levels?.onEdit) return;
|
|
350
|
+
const rounded = priceAtCursor();
|
|
351
|
+
if (rounded === null) return;
|
|
313
352
|
onActivate?.();
|
|
314
353
|
// Enter again at the same cursor picks the level already there.
|
|
315
354
|
const existing = levelItems.find((level) => level.editable && level.value === rounded);
|
|
@@ -342,7 +381,8 @@ export function useCompositeChartKeyboard({
|
|
|
342
381
|
setSelectedLevelId(ordered[next]!.id);
|
|
343
382
|
};
|
|
344
383
|
const removeSelectedLevel = () => {
|
|
345
|
-
|
|
384
|
+
// An order's line moves here; it is cancelled where the order is.
|
|
385
|
+
if (!selectedLevel?.editable || selectedLevel.draggable) return;
|
|
346
386
|
levels?.onEdit?.({ kind: "remove", id: selectedLevel.id });
|
|
347
387
|
setSelectedLevelId(null);
|
|
348
388
|
};
|
|
@@ -403,6 +443,13 @@ export function useCompositeChartKeyboard({
|
|
|
403
443
|
else chartActionsRef.current.pick();
|
|
404
444
|
return;
|
|
405
445
|
}
|
|
446
|
+
// Esc ends a price pick even with nothing drawn yet; Enter needs a price at the cursor.
|
|
447
|
+
if (pricePick && (scene || isPlainKey(event, "escape")) && isPlainKey(event, "return", "enter", "escape")) {
|
|
448
|
+
consume();
|
|
449
|
+
if (event.name === "escape") pricePick.onCancel();
|
|
450
|
+
else chartActionsRef.current.pickPrice();
|
|
451
|
+
return;
|
|
452
|
+
}
|
|
406
453
|
if (zoned && !entered && isPlainKey(event, "down", "return", "enter")) {
|
|
407
454
|
consume();
|
|
408
455
|
enterChart();
|
|
@@ -424,7 +471,7 @@ export function useCompositeChartKeyboard({
|
|
|
424
471
|
stepLevel(event.name === "[" ? -1 : 1);
|
|
425
472
|
return;
|
|
426
473
|
}
|
|
427
|
-
if (toolsActive && selectedLevel?.editable && levelsEditable && isPlainKey(event, "backspace")) {
|
|
474
|
+
if (toolsActive && selectedLevel?.editable && !selectedLevel.draggable && levelsEditable && isPlainKey(event, "backspace", "delete")) {
|
|
428
475
|
consume();
|
|
429
476
|
removeSelectedLevel();
|
|
430
477
|
return;
|
|
@@ -453,6 +500,21 @@ export function useCompositeChartKeyboard({
|
|
|
453
500
|
setKeyboardPlacement((current) => current && moveKeyboardPlacement(current, { level }));
|
|
454
501
|
return;
|
|
455
502
|
}
|
|
503
|
+
if (toolsActive && isShiftedLetter(event, "t")) {
|
|
504
|
+
consume();
|
|
505
|
+
layout.toggleToolbar();
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
if (legendKeysActive && layout.legendCollapsible && isShiftedLetter(event, "l")) {
|
|
509
|
+
consume();
|
|
510
|
+
layout.toggleLegend();
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
if (toolsActive && layout.panelsResizable && isShiftedArrow(event, "up", "down")) {
|
|
514
|
+
consume();
|
|
515
|
+
layout.stepTopPanel(event.name === "up" ? 1 : -1);
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
456
518
|
if (isPlainKey(event, "[", "]") && (drawingKeysActive || legendKeysActive)) {
|
|
457
519
|
consume();
|
|
458
520
|
const direction = event.name === "[" ? -1 : 1;
|
|
@@ -579,6 +641,10 @@ export function useCompositeChartKeyboard({
|
|
|
579
641
|
const date = keyboardCursorDateRef.current ?? scene?.dates.at(-1) ?? null;
|
|
580
642
|
if (date) timePick?.onPick(date);
|
|
581
643
|
},
|
|
644
|
+
pickPrice: () => {
|
|
645
|
+
const value = priceAtCursor();
|
|
646
|
+
if (value !== null) pricePick?.onPick(value);
|
|
647
|
+
},
|
|
582
648
|
start: armedTool === "level" ? addLevelAtCursor : startKeyboardPlacement,
|
|
583
649
|
finish: finishKeyboardPlacement,
|
|
584
650
|
stepLevel,
|
|
@@ -596,6 +662,7 @@ export function useCompositeChartKeyboard({
|
|
|
596
662
|
},
|
|
597
663
|
leave: leaveChart,
|
|
598
664
|
togglePin: () => pin?.toggle(),
|
|
665
|
+
layout,
|
|
599
666
|
};
|
|
600
667
|
const chartActionsRef = useRef(chartActions);
|
|
601
668
|
chartActionsRef.current = chartActions;
|
|
@@ -608,17 +675,27 @@ export function useCompositeChartKeyboard({
|
|
|
608
675
|
const armedHints = armedTool ? KEYBOARD_TOOL_HINTS[armedTool] : null;
|
|
609
676
|
const placing = !!keyboardPlacement;
|
|
610
677
|
const legendEntryVisible = !!legendEntry && visibleSeriesIds.has(legendEntry.id);
|
|
611
|
-
const resettable = !!activeUserViewport;
|
|
612
|
-
const timePickLabel = timePick?.label ?? null;
|
|
678
|
+
const resettable = !!activeUserViewport || scaledByHand;
|
|
679
|
+
const timePickLabel = timePick?.label ?? (levelHost ? pricePick?.label : null) ?? null;
|
|
680
|
+
const pickingPrice = !timePick && !!pricePick;
|
|
613
681
|
const levelActionHint = selectedLevel?.actionable && levels?.action ? levels.action : null;
|
|
614
682
|
const levelToolKeys = toolsActive && armedTool === "level" && levelsEditable;
|
|
615
|
-
const canDeleteLevel = toolsActive && levelsEditable && !!selectedLevel?.editable;
|
|
683
|
+
const canDeleteLevel = toolsActive && levelsEditable && !!selectedLevel?.editable && !selectedLevel.draggable;
|
|
616
684
|
const pinState = pin ? pin.pinned : null;
|
|
685
|
+
// Hidden as it shows: a saved hidden bar is open while a tool is in hand.
|
|
686
|
+
const toolbarHidden = layout.toolbarHidden && armedTool === null;
|
|
687
|
+
const {
|
|
688
|
+
legendCollapsible,
|
|
689
|
+
legendCollapsed,
|
|
690
|
+
panelsResizable,
|
|
691
|
+
panelHeightsSet,
|
|
692
|
+
panelMaximized,
|
|
693
|
+
} = layout;
|
|
617
694
|
usePaneFooter(keyboardId, () => {
|
|
618
695
|
if (!keyboardActive || !scene) return null;
|
|
619
696
|
const hints: PaneHint[] = [];
|
|
620
697
|
if (timePickLabel) {
|
|
621
|
-
hints.push({ id: "chart-pick", key: "Enter", label: timePickLabel, onPress: () => chartActionsRef.current.pick() });
|
|
698
|
+
hints.push({ id: "chart-pick", key: "Enter", label: timePickLabel, onPress: () => pickingPrice ? chartActionsRef.current.pickPrice() : chartActionsRef.current.pick() });
|
|
622
699
|
} else if (toolsActive && armedHints) {
|
|
623
700
|
hints.push(placing
|
|
624
701
|
? { id: "chart-tool", key: "Enter", label: armedHints.finish, title: armedHints.finishTitle, onPress: () => chartActionsRef.current.finish() }
|
|
@@ -686,6 +763,29 @@ export function useCompositeChartKeyboard({
|
|
|
686
763
|
});
|
|
687
764
|
}
|
|
688
765
|
if (resettable) menu.push({ id: "chart-reset", label: "Reset Zoom", accelerator: "0", onSelect: () => chartActionsRef.current.reset() });
|
|
766
|
+
menu.push({
|
|
767
|
+
id: "chart-toolbar",
|
|
768
|
+
label: toolbarHidden ? "Show Drawing Tools" : "Hide Drawing Tools",
|
|
769
|
+
accelerator: "Shift+T",
|
|
770
|
+
onSelect: () => chartActionsRef.current.layout.toggleToolbar(),
|
|
771
|
+
});
|
|
772
|
+
if (panelsResizable) {
|
|
773
|
+
menu.push({ id: "chart-panel-taller", label: "Taller Top Panel", accelerator: "Shift+Up", onSelect: () => chartActionsRef.current.layout.stepTopPanel(1) });
|
|
774
|
+
menu.push({ id: "chart-panel-shorter", label: "Shorter Top Panel", accelerator: "Shift+Down", onSelect: () => chartActionsRef.current.layout.stepTopPanel(-1) });
|
|
775
|
+
}
|
|
776
|
+
if (panelMaximized) {
|
|
777
|
+
menu.push({ id: "chart-panels-restore", label: "Show All Panels", onSelect: () => chartActionsRef.current.layout.restorePanels() });
|
|
778
|
+
} else if (panelHeightsSet) {
|
|
779
|
+
menu.push({ id: "chart-panels-reset", label: "Reset Panel Heights", onSelect: () => chartActionsRef.current.layout.resetPanelHeights() });
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
if (legendKeysActive && legendCollapsible) {
|
|
783
|
+
menu.push({
|
|
784
|
+
id: "chart-legend",
|
|
785
|
+
label: legendCollapsed ? "Expand Legend" : "Collapse Legend",
|
|
786
|
+
accelerator: "Shift+L",
|
|
787
|
+
onSelect: () => chartActionsRef.current.layout.toggleLegend(),
|
|
788
|
+
});
|
|
689
789
|
}
|
|
690
790
|
if (legendKeysActive && anyLegendToggleable && !drawingKeysActive) {
|
|
691
791
|
menu.push({ id: "chart-series-next", label: "Next Series", accelerator: "]", onSelect: () => chartActionsRef.current.stepLegend(1) });
|
|
@@ -706,6 +806,7 @@ export function useCompositeChartKeyboard({
|
|
|
706
806
|
!!scene,
|
|
707
807
|
selectedDrawingId,
|
|
708
808
|
timePickLabel,
|
|
809
|
+
pickingPrice,
|
|
709
810
|
levelActionHint,
|
|
710
811
|
levelToolKeys,
|
|
711
812
|
levelItems.length,
|
|
@@ -713,6 +814,12 @@ export function useCompositeChartKeyboard({
|
|
|
713
814
|
levelsEditable,
|
|
714
815
|
toolsActive,
|
|
715
816
|
pinState,
|
|
817
|
+
toolbarHidden,
|
|
818
|
+
legendCollapsible,
|
|
819
|
+
legendCollapsed,
|
|
820
|
+
panelsResizable,
|
|
821
|
+
panelHeightsSet,
|
|
822
|
+
panelMaximized,
|
|
716
823
|
]);
|
|
717
824
|
|
|
718
825
|
return {
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { useCallback, useRef, useState } from "react";
|
|
2
|
+
import type { CompositeAxisSide } from "./types";
|
|
3
|
+
import { NO_VALUE_SCALES, valueScaleSlot, type CompositeValueRange, type CompositeValueScales } from "./value-scale";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The chart's manual value scales: set by a drag or the wheel on an axis, or
|
|
7
|
+
* a drag on the plot of a panel already scaled by hand; cleared per panel or
|
|
8
|
+
* all at once, and whenever `resetKey` changes (in the same render, so a new
|
|
9
|
+
* view never draws in the old one's scale).
|
|
10
|
+
*/
|
|
11
|
+
export function useCompositeValueScales(resetKey: unknown) {
|
|
12
|
+
const [state, setState] = useState<{ resetKey: unknown; scales: CompositeValueScales }>(() => ({ resetKey, scales: NO_VALUE_SCALES }));
|
|
13
|
+
const resetKeyRef = useRef(resetKey);
|
|
14
|
+
resetKeyRef.current = resetKey;
|
|
15
|
+
const scales = Object.is(state.resetKey, resetKey) ? state.scales : NO_VALUE_SCALES;
|
|
16
|
+
const update = useCallback((change: (scales: CompositeValueScales) => CompositeValueScales) => {
|
|
17
|
+
setState((current) => {
|
|
18
|
+
const key = resetKeyRef.current;
|
|
19
|
+
const fresh = Object.is(current.resetKey, key);
|
|
20
|
+
const base = fresh ? current.scales : NO_VALUE_SCALES;
|
|
21
|
+
const next = change(base);
|
|
22
|
+
return fresh && next === base ? current : { resetKey: key, scales: next };
|
|
23
|
+
});
|
|
24
|
+
}, []);
|
|
25
|
+
const setValueScale = useCallback((panelId: string, side: CompositeAxisSide, key: string, range: CompositeValueRange) => {
|
|
26
|
+
const slot = valueScaleSlot(panelId, side);
|
|
27
|
+
update((current) => {
|
|
28
|
+
const previous = current[slot];
|
|
29
|
+
if (previous && previous.key === key && previous.min === range.min && previous.max === range.max) return current;
|
|
30
|
+
return { ...current, [slot]: { key, min: range.min, max: range.max } };
|
|
31
|
+
});
|
|
32
|
+
}, [update]);
|
|
33
|
+
const resetPanelValueScale = useCallback((panelId: string) => {
|
|
34
|
+
update((current) => {
|
|
35
|
+
const slots = (["left", "right"] as const).map((side) => valueScaleSlot(panelId, side)).filter((slot) => slot in current);
|
|
36
|
+
if (slots.length === 0) return current;
|
|
37
|
+
const next = { ...current };
|
|
38
|
+
for (const slot of slots) delete next[slot];
|
|
39
|
+
return Object.keys(next).length === 0 ? NO_VALUE_SCALES : next;
|
|
40
|
+
});
|
|
41
|
+
}, [update]);
|
|
42
|
+
const resetValueScales = useCallback(() => update(() => NO_VALUE_SCALES), [update]);
|
|
43
|
+
return { valueScales: scales, setValueScale, resetPanelValueScale, resetValueScales };
|
|
44
|
+
}
|
|
@@ -99,9 +99,13 @@ export function useCompositeViewport({
|
|
|
99
99
|
);
|
|
100
100
|
}, [onViewportChange, userViewportEnd, userViewportStart]);
|
|
101
101
|
|
|
102
|
+
// Counts authored views, so what belongs to one (values scaled by hand) can
|
|
103
|
+
// go with it; `authoredViewportChanged` covers the render before it counts.
|
|
104
|
+
const [authoredGeneration, setAuthoredGeneration] = useState(0);
|
|
102
105
|
useEffect(() => {
|
|
103
106
|
previousAuthoredViewportRef.current = viewport ?? null;
|
|
104
107
|
previousViewportResetKeyRef.current = viewportResetKey;
|
|
108
|
+
if (authoredViewportChanged) setAuthoredGeneration((generation) => generation + 1);
|
|
105
109
|
if (authoredViewportChanged && userViewport) {
|
|
106
110
|
viewportInteractionRef.current = "reset";
|
|
107
111
|
setUserViewport(null);
|
|
@@ -154,8 +158,13 @@ export function useCompositeViewport({
|
|
|
154
158
|
if (!positions) return;
|
|
155
159
|
panViewport(shiftRatio * Math.max(positions.end - positions.start, Number.EPSILON));
|
|
156
160
|
}, [effectiveViewport, navigationFrame, panViewport]);
|
|
157
|
-
|
|
158
|
-
|
|
161
|
+
/** A gesture (a drag on the time axis) zooms from the view and frame it started in, by its whole travel so far. */
|
|
162
|
+
const zoomViewport = useCallback((
|
|
163
|
+
zoomFactor: number,
|
|
164
|
+
anchorRatio = 1,
|
|
165
|
+
gesture?: { frame: CompositeNavigationFrame; from: CompositeViewportRange },
|
|
166
|
+
) => {
|
|
167
|
+
navigate("zoom", (base, frame) => zoomCompositeViewport(frame, base, zoomFactor, anchorRatio), gesture);
|
|
159
168
|
}, [navigate]);
|
|
160
169
|
const setViewportRange = useCallback((range: CompositeViewportRange) => {
|
|
161
170
|
navigate("zoom", (_base, frame) => fitCompositeViewport(frame, range));
|
|
@@ -165,7 +174,7 @@ export function useCompositeViewport({
|
|
|
165
174
|
setUserViewport(null);
|
|
166
175
|
}, []);
|
|
167
176
|
return {
|
|
168
|
-
navigationFrame, activeUserViewport, effectiveViewport,
|
|
177
|
+
navigationFrame, activeUserViewport, effectiveViewport, authoredViewportChanged, authoredGeneration,
|
|
169
178
|
panViewport, panViewportByRatio, zoomViewport, setViewportRange, resetViewport,
|
|
170
179
|
};
|
|
171
180
|
}
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import type { PanelScale, ResolvedSeries } from "../../../time-series/types";
|
|
2
|
+
import type { CompositeAxisSide } from "./types";
|
|
3
|
+
import { clamp } from "../../../utils/math";
|
|
4
|
+
|
|
5
|
+
/** What a value axis shows, in its own values. */
|
|
6
|
+
export interface CompositeValueRange {
|
|
7
|
+
min: number;
|
|
8
|
+
max: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* A value axis stretched or squeezed by hand, and what it plots: a range set
|
|
13
|
+
* for one listing's prices means nothing for another's, so it holds only
|
|
14
|
+
* while the axis plots the same series in the same unit and scale.
|
|
15
|
+
*/
|
|
16
|
+
export interface CompositeManualValueScale extends CompositeValueRange {
|
|
17
|
+
key: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Manual value scales by panel and side (`valueScaleSlot`). */
|
|
21
|
+
export type CompositeValueScales = Readonly<Record<string, CompositeManualValueScale>>;
|
|
22
|
+
|
|
23
|
+
export const NO_VALUE_SCALES: CompositeValueScales = Object.freeze({});
|
|
24
|
+
|
|
25
|
+
export function valueScaleSlot(panelId: string, side: CompositeAxisSide): string {
|
|
26
|
+
return `${panelId}\u0000${side}`;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Identifies what an axis plots, for `CompositeManualValueScale.key`. */
|
|
30
|
+
export function valueScaleKey(scale: PanelScale, axisSeries: readonly ResolvedSeries[]): string {
|
|
31
|
+
return [
|
|
32
|
+
scale,
|
|
33
|
+
...axisSeries.map((entry) => [entry.id, entry.label, entry.unit, entry.listing?.symbol ?? ""].join("\u0001")),
|
|
34
|
+
].join("\u0000");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Pixels of drag along an axis that stretch or squeeze it by a factor of e. */
|
|
38
|
+
const AXIS_DRAG_PIXELS_PER_E = 200;
|
|
39
|
+
/** The finest and coarsest a linear axis may get, against the size of the values it shows. */
|
|
40
|
+
const MIN_LINEAR_SPAN_RATIO = 1e-9;
|
|
41
|
+
const MAX_LINEAR_SPAN = 1e15;
|
|
42
|
+
/** The same for a log axis, in natural-log units. */
|
|
43
|
+
const MIN_LOG_SPAN = 1e-9;
|
|
44
|
+
const MAX_LOG_SPAN = 60;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* How much a drag of `deltaPx` along an axis multiplies the span it shows.
|
|
48
|
+
* Down a value axis or right along the time axis shows more (a factor above
|
|
49
|
+
* one), the other way less, and the way back undoes it exactly.
|
|
50
|
+
*/
|
|
51
|
+
export function resolveAxisDragSpanFactor(deltaPx: number): number {
|
|
52
|
+
return Number.isFinite(deltaPx) ? Math.exp(deltaPx / AXIS_DRAG_PIXELS_PER_E) : 1;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function toAxis(value: number, scale: PanelScale): number {
|
|
56
|
+
return scale === "log" ? Math.log(value) : value;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function fromAxis(value: number, scale: PanelScale): number {
|
|
60
|
+
return scale === "log" ? Math.exp(value) : value;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/** The range as top and bottom in the axis's own space: values, or their logs. */
|
|
64
|
+
function axisEnds(range: CompositeValueRange, scale: PanelScale): { top: number; bottom: number } | null {
|
|
65
|
+
if (scale === "log" && (range.min <= 0 || range.max <= 0)) return null;
|
|
66
|
+
const top = toAxis(range.max, scale);
|
|
67
|
+
const bottom = toAxis(range.min, scale);
|
|
68
|
+
return Number.isFinite(top) && Number.isFinite(bottom) && top > bottom ? { top, bottom } : null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function rangeFromEnds(top: number, bottom: number, scale: PanelScale): CompositeValueRange {
|
|
72
|
+
return { min: fromAxis(bottom, scale), max: fromAxis(top, scale) };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* The range after multiplying its span by `spanFactor` (above one shows more)
|
|
77
|
+
* around the value at `anchorRatio`, 0 the top of the panel and 1 the bottom,
|
|
78
|
+
* which stays where it is. A log axis stretches in its own, logarithmic space.
|
|
79
|
+
*/
|
|
80
|
+
export function zoomValueRange(
|
|
81
|
+
range: CompositeValueRange,
|
|
82
|
+
scale: PanelScale,
|
|
83
|
+
spanFactor: number,
|
|
84
|
+
anchorRatio: number,
|
|
85
|
+
): CompositeValueRange {
|
|
86
|
+
const ends = axisEnds(range, scale);
|
|
87
|
+
if (!ends || !(spanFactor > 0) || !Number.isFinite(spanFactor)) return range;
|
|
88
|
+
const ratio = clamp(Number.isFinite(anchorRatio) ? anchorRatio : 0.5, 0, 1);
|
|
89
|
+
const span = ends.top - ends.bottom;
|
|
90
|
+
const anchor = ends.top - span * ratio;
|
|
91
|
+
const nextSpan = scale === "log"
|
|
92
|
+
? clamp(span * spanFactor, MIN_LOG_SPAN, MAX_LOG_SPAN)
|
|
93
|
+
: clamp(span * spanFactor, Math.max(Math.abs(anchor), Number.MIN_VALUE) * MIN_LINEAR_SPAN_RATIO, MAX_LINEAR_SPAN);
|
|
94
|
+
const top = anchor + nextSpan * ratio;
|
|
95
|
+
return rangeFromEnds(top, top - nextSpan, scale);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* The range moved with a drag of `deltaRatio` of the panel's height, positive
|
|
100
|
+
* downward: what was under the pointer stays under it.
|
|
101
|
+
*/
|
|
102
|
+
export function panValueRange(
|
|
103
|
+
range: CompositeValueRange,
|
|
104
|
+
scale: PanelScale,
|
|
105
|
+
deltaRatio: number,
|
|
106
|
+
): CompositeValueRange {
|
|
107
|
+
const ends = axisEnds(range, scale);
|
|
108
|
+
if (!ends || !Number.isFinite(deltaRatio) || deltaRatio === 0) return range;
|
|
109
|
+
const shift = (ends.top - ends.bottom) * deltaRatio;
|
|
110
|
+
return rangeFromEnds(ends.top + shift, ends.bottom + shift, scale);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** A manual range holds while some of the data is in it; pushed clear of the data it fits the data again. */
|
|
114
|
+
export function manualValueRangeApplies(
|
|
115
|
+
manual: CompositeValueRange,
|
|
116
|
+
data: CompositeValueRange,
|
|
117
|
+
scale: PanelScale,
|
|
118
|
+
): boolean {
|
|
119
|
+
const ends = axisEnds(manual, scale);
|
|
120
|
+
return !!ends && manual.max > data.min && manual.min < data.max;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Keeps an end of a segment that leaves the band from `minY` to `maxY` on the
|
|
125
|
+
* band's edge, along the segment: what is drawn of it inside stays exact and
|
|
126
|
+
* nothing is drawn far outside. Null when it misses the band.
|
|
127
|
+
*/
|
|
128
|
+
export function clipSegmentToBand(
|
|
129
|
+
x0: number,
|
|
130
|
+
y0: number,
|
|
131
|
+
x1: number,
|
|
132
|
+
y1: number,
|
|
133
|
+
minY: number,
|
|
134
|
+
maxY: number,
|
|
135
|
+
): [number, number, number, number] | null {
|
|
136
|
+
if ((y0 < minY && y1 < minY) || (y0 > maxY && y1 > maxY)) return null;
|
|
137
|
+
if (y0 >= minY && y0 <= maxY && y1 >= minY && y1 <= maxY) return [x0, y0, x1, y1];
|
|
138
|
+
const at = (y: number) => {
|
|
139
|
+
const t = (y - y0) / (y1 - y0);
|
|
140
|
+
return x0 + (x1 - x0) * t;
|
|
141
|
+
};
|
|
142
|
+
let startX = x0;
|
|
143
|
+
let startY = y0;
|
|
144
|
+
let endX = x1;
|
|
145
|
+
let endY = y1;
|
|
146
|
+
if (startY < minY) { startX = at(minY); startY = minY; } else if (startY > maxY) { startX = at(maxY); startY = maxY; }
|
|
147
|
+
if (endY < minY) { endX = at(minY); endY = minY; } else if (endY > maxY) { endX = at(maxY); endY = maxY; }
|
|
148
|
+
return [startX, startY, endX, endY];
|
|
149
|
+
}
|
|
@@ -27,7 +27,8 @@ export function paintVolumeProfile(
|
|
|
27
27
|
row.volume > (profile.rows[best]?.volume ?? -1) ? index : best
|
|
28
28
|
), 0);
|
|
29
29
|
profile.rows.forEach((row, index) => {
|
|
30
|
-
|
|
30
|
+
// Rows a hand-scaled axis leaves off the panel are not piled on its edge.
|
|
31
|
+
if (row.volume <= 0 || row.highRatio > 1 || row.lowRatio < 0) return;
|
|
31
32
|
const top = Math.round(clamp(row.highRatio, 0, 1) * maxY);
|
|
32
33
|
const edge = Math.round(clamp(row.lowRatio, 0, 1) * maxY);
|
|
33
34
|
// A pixel between rows keeps tall bars apart; thin ones would vanish.
|
|
@@ -36,7 +37,8 @@ export function paintVolumeProfile(
|
|
|
36
37
|
const opacity = index === pocRow ? POC_OPACITY : row.valueArea ? VALUE_AREA_OPACITY : OUTSIDE_OPACITY;
|
|
37
38
|
fillRect(data, width, height, width - length, top, width - 1, bottom, color, opacity);
|
|
38
39
|
});
|
|
39
|
-
|
|
40
|
+
if (profile.pocRatio < 0 || profile.pocRatio > 1) return;
|
|
41
|
+
const y = Math.round(profile.pocRatio * maxY);
|
|
40
42
|
for (let x = 0; x < width; x += 5) {
|
|
41
43
|
fillRect(data, width, height, x, y, Math.min(x + 1, width - 1), y, color, 0.7);
|
|
42
44
|
}
|
|
@@ -57,13 +59,14 @@ export function writeVolumeProfileText(
|
|
|
57
59
|
const volumes = new Array<number>(height).fill(0);
|
|
58
60
|
const valueArea = new Array<boolean>(height).fill(false);
|
|
59
61
|
for (const row of profile.rows) {
|
|
62
|
+
if (row.highRatio > 1 || row.lowRatio < 0) continue;
|
|
60
63
|
const line = clamp(Math.round(((row.highRatio + row.lowRatio) / 2) * (height - 1)), 0, height - 1);
|
|
61
64
|
volumes[line]! += row.volume;
|
|
62
65
|
if (row.valueArea) valueArea[line] = true;
|
|
63
66
|
}
|
|
64
67
|
const peak = Math.max(...volumes);
|
|
65
68
|
if (peak <= 0) return;
|
|
66
|
-
const pocLine =
|
|
69
|
+
const pocLine = profile.pocRatio < 0 || profile.pocRatio > 1 ? -1 : Math.round(profile.pocRatio * (height - 1));
|
|
67
70
|
const maxLength = Math.max(1, Math.floor(width * PROFILE_WIDTH_RATIO));
|
|
68
71
|
volumes.forEach((volume, line) => {
|
|
69
72
|
if (volume <= 0) return;
|
|
@@ -21,6 +21,8 @@ export interface ChartMouseEvent {
|
|
|
21
21
|
y: number;
|
|
22
22
|
/** DOM target on the desktop host; absent in the terminal. */
|
|
23
23
|
target?: { closest?: (selector: string) => unknown } | null;
|
|
24
|
+
/** The press's click count on the desktop host (2 on a double click); absent in the terminal. */
|
|
25
|
+
detail?: number;
|
|
24
26
|
preciseX?: number;
|
|
25
27
|
preciseY?: number;
|
|
26
28
|
pixelX?: number;
|
|
@@ -6,6 +6,8 @@ export {
|
|
|
6
6
|
fitChartTableColumns,
|
|
7
7
|
} from "./layout";
|
|
8
8
|
export type { ChartBandMode, ChartTableLayout } from "./layout";
|
|
9
|
+
export { ChartRead, useChartReadRows } from "./read";
|
|
10
|
+
export type { ChartReadProps } from "./read";
|
|
9
11
|
export { useChartTableSelection } from "./selection";
|
|
10
12
|
export type { ChartTableSelection } from "./selection";
|
|
11
13
|
export { formatBpAxis, formatCompactAxis, formatPercentAxis, spanAxisFormatter, spanDigits } from "./axis";
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { useThemeColors } from "../../theme/theme-context";
|
|
2
|
+
import { Box, Text, useUiCapabilities } from "../../ui";
|
|
3
|
+
import { displayWidth, truncateToDisplayWidth } from "../../utils/format";
|
|
4
|
+
import { wrapTextLines } from "../../utils/text-wrap";
|
|
5
|
+
import { ClippedText } from "../ui/display";
|
|
6
|
+
|
|
7
|
+
/** The terminal wraps a read onto at most this many rows; a longer one ends in an ellipsis on the last. */
|
|
8
|
+
export const CHART_READ_MAX_ROWS = 3;
|
|
9
|
+
/** The read's inset on each side, as on the query bar and the legend above it. */
|
|
10
|
+
const READ_INSET = 1;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The terminal's lines for a read under a chart at a pane `width`: the whole
|
|
14
|
+
* sentence on one row when it fits, otherwise wrapped at words onto up to
|
|
15
|
+
* `CHART_READ_MAX_ROWS` rows. None when there is no read or no room for one.
|
|
16
|
+
*/
|
|
17
|
+
export function chartReadLines(text: string | null | undefined, width: number): string[] {
|
|
18
|
+
const room = Math.floor(width) - 2 * READ_INSET;
|
|
19
|
+
const read = text?.trim();
|
|
20
|
+
if (!read || room <= 0) return [];
|
|
21
|
+
if (displayWidth(read) <= room) return [read];
|
|
22
|
+
const lines = wrapTextLines(read, room);
|
|
23
|
+
if (lines.length <= CHART_READ_MAX_ROWS) return lines;
|
|
24
|
+
return [
|
|
25
|
+
...lines.slice(0, CHART_READ_MAX_ROWS - 1),
|
|
26
|
+
truncateToDisplayWidth(lines.slice(CHART_READ_MAX_ROWS - 1).join(" "), room),
|
|
27
|
+
];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The rows the longest of these reads needs under a chart at a pane `width`
|
|
32
|
+
* (none when none has one). A pane puts it in `minRows` so the band does not
|
|
33
|
+
* flip between a chart and a strip as the selection moves between a short
|
|
34
|
+
* read and a long one. The desktop and the web cut a read by CSS on one row.
|
|
35
|
+
*/
|
|
36
|
+
export function useChartReadRows(texts: ReadonlyArray<string | null | undefined>, width: number): number {
|
|
37
|
+
const { nativePaneChrome } = useUiCapabilities();
|
|
38
|
+
let rows = 0;
|
|
39
|
+
for (const text of texts) {
|
|
40
|
+
const lines = chartReadLines(text, width).length;
|
|
41
|
+
rows = Math.max(rows, nativePaneChrome ? Math.min(1, lines) : lines);
|
|
42
|
+
}
|
|
43
|
+
return rows;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface ChartReadProps {
|
|
47
|
+
/** The plain sentence worked out from the numbers, as the server wrote it. */
|
|
48
|
+
text: string | null | undefined;
|
|
49
|
+
/** The pane's width: the read sits one cell in from each edge. */
|
|
50
|
+
width: number;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* The plain read under a chart's axis. In the terminal the whole sentence is
|
|
55
|
+
* wrapped onto up to `CHART_READ_MAX_ROWS` rows (take its rows from the chart
|
|
56
|
+
* with `useChartReadRows`); the desktop and the web keep one row and cut it
|
|
57
|
+
* by CSS where its box ends.
|
|
58
|
+
*/
|
|
59
|
+
export function ChartRead({ text, width }: ChartReadProps) {
|
|
60
|
+
const colors = useThemeColors();
|
|
61
|
+
const { nativePaneChrome } = useUiCapabilities();
|
|
62
|
+
const lines = chartReadLines(text, width);
|
|
63
|
+
if (lines.length === 0) return null;
|
|
64
|
+
if (nativePaneChrome) {
|
|
65
|
+
return <Box height={1} paddingX={READ_INSET}><ClippedText fg={colors.textMuted} text={text!.trim()} width={width - 2 * READ_INSET} /></Box>;
|
|
66
|
+
}
|
|
67
|
+
return (
|
|
68
|
+
<Box flexDirection="column" height={lines.length} flexShrink={0}>
|
|
69
|
+
{lines.map((line, index) => (
|
|
70
|
+
<Box key={index} height={1} paddingX={READ_INSET}><Text fg={colors.textMuted}>{line}</Text></Box>
|
|
71
|
+
))}
|
|
72
|
+
</Box>
|
|
73
|
+
);
|
|
74
|
+
}
|