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
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The launch frame's format and the inline script that draws it, for the
|
|
3
|
+
* page builds and the desktop Bun process; the DOM side that records it is
|
|
4
|
+
* boot-frame.ts.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export interface BootFrame {
|
|
8
|
+
/** The build that drew it; markup only matches the stylesheet it was drawn with. */
|
|
9
|
+
build: string;
|
|
10
|
+
width: number;
|
|
11
|
+
height: number;
|
|
12
|
+
/** The root element's inline style: the theme's colours. */
|
|
13
|
+
rootStyle: string;
|
|
14
|
+
/** The body's inline style: cell metrics and text size. */
|
|
15
|
+
bodyStyle: string;
|
|
16
|
+
html: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** The element the page draws the frame in, over the app's root. */
|
|
20
|
+
export const BOOT_FRAME_ELEMENT_ID = "gloom-boot-frame";
|
|
21
|
+
/** Marks a copied box that was scrolled, as `top,left`, for the page to scroll it the same. */
|
|
22
|
+
export const BOOT_FRAME_SCROLL_ATTRIBUTE = "data-gloom-boot-scroll";
|
|
23
|
+
/** The page's build, which the inline script sets for the recorder to stamp frames with. */
|
|
24
|
+
export const BOOT_FRAME_BUILD_GLOBAL = "__gloomBootFrameBuild";
|
|
25
|
+
/** A frame's markup larger than this is not kept or drawn; a layout's chrome is a few dozen kilobytes. */
|
|
26
|
+
export const MAX_BOOT_FRAME_CHARS = 600_000;
|
|
27
|
+
/** The root and body styles: the theme's colours and the text metrics, a few kilobytes. */
|
|
28
|
+
const MAX_BOOT_FRAME_STYLE_CHARS = 20_000;
|
|
29
|
+
const MAX_BOOT_FRAME_BUILD_CHARS = 200;
|
|
30
|
+
|
|
31
|
+
function isPositiveSize(value: unknown): boolean {
|
|
32
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** A stored frame of the right shape and within the size limits. Anything else is not saved or drawn. */
|
|
36
|
+
export function isBootFrame(value: unknown): value is BootFrame {
|
|
37
|
+
if (!value || typeof value !== "object") return false;
|
|
38
|
+
const frame = value as Record<string, unknown>;
|
|
39
|
+
return typeof frame.build === "string" && frame.build.length <= MAX_BOOT_FRAME_BUILD_CHARS
|
|
40
|
+
&& isPositiveSize(frame.width)
|
|
41
|
+
&& isPositiveSize(frame.height)
|
|
42
|
+
&& typeof frame.rootStyle === "string" && frame.rootStyle.length <= MAX_BOOT_FRAME_STYLE_CHARS
|
|
43
|
+
&& typeof frame.bodyStyle === "string" && frame.bodyStyle.length <= MAX_BOOT_FRAME_STYLE_CHARS
|
|
44
|
+
&& typeof frame.html === "string" && frame.html.length <= MAX_BOOT_FRAME_CHARS;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Strips a frame's markup, in `container` and the container itself, of
|
|
49
|
+
* everything that could load, run, navigate, take focus or be found as the
|
|
50
|
+
* app's own: elements that load or run, event handlers, links and sources,
|
|
51
|
+
* form targets, styles that fetch, ids and names. The recorder runs it on the
|
|
52
|
+
* copy it stores, and the page again on the copy it reads back, which is only
|
|
53
|
+
* as trustworthy as the file or storage it was kept in.
|
|
54
|
+
*
|
|
55
|
+
* The page's inline script carries this function's source, so it is plain
|
|
56
|
+
* JavaScript that reads nothing outside itself.
|
|
57
|
+
*/
|
|
58
|
+
export function scrubBootFrame(container: ParentNode): void {
|
|
59
|
+
const droppedElements = [
|
|
60
|
+
"script", "noscript", "style", "link", "meta", "base", "title", "template", "slot",
|
|
61
|
+
"iframe", "frame", "frameset", "object", "embed", "applet", "param", "portal", "fencedframe",
|
|
62
|
+
"img", "image", "picture", "source", "track", "video", "audio", "canvas", "math",
|
|
63
|
+
"foreignobject", "use", "feimage", "animate", "animatemotion", "animatetransform", "animatecolor",
|
|
64
|
+
"set", "discard", "mpath", "handler", "listener",
|
|
65
|
+
];
|
|
66
|
+
const droppedAttributes = [
|
|
67
|
+
"src", "srcset", "srcdoc", "action", "formaction", "poster", "background", "ping", "lowsrc",
|
|
68
|
+
"dynsrc", "data", "codebase", "classid", "archive", "longdesc", "usemap", "manifest", "is",
|
|
69
|
+
"id", "name", "tabindex", "autofocus", "contenteditable", "value",
|
|
70
|
+
"data-gloom-pane-id", "data-gloom-remote-node-id",
|
|
71
|
+
];
|
|
72
|
+
// A style that could fetch: url(), image() and image-set() take addresses,
|
|
73
|
+
// and an escape could spell either past this check.
|
|
74
|
+
const fetchingStyle = /url\s*\(|image(-set)?\s*\(|\\|@import|expression\s*\(/i;
|
|
75
|
+
const scriptAddress = /^\s*(javascript|vbscript|data)\s*:/i;
|
|
76
|
+
const scrubElement = (element: Element) => {
|
|
77
|
+
for (const attribute of Array.from(element.attributes)) {
|
|
78
|
+
const name = attribute.name.toLowerCase();
|
|
79
|
+
const value = attribute.value;
|
|
80
|
+
if (
|
|
81
|
+
name.startsWith("on")
|
|
82
|
+
|| name.endsWith("href")
|
|
83
|
+
|| droppedAttributes.includes(name)
|
|
84
|
+
|| /url\s*\(/i.test(value)
|
|
85
|
+
|| scriptAddress.test(value)
|
|
86
|
+
|| (name === "style" && fetchingStyle.test(value))
|
|
87
|
+
) {
|
|
88
|
+
element.removeAttribute(attribute.name);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
const self = container as unknown as Element;
|
|
93
|
+
if (self.nodeType === 1) scrubElement(self);
|
|
94
|
+
for (const element of Array.from(container.querySelectorAll("*"))) {
|
|
95
|
+
if (droppedElements.includes(element.localName.toLowerCase())) element.remove();
|
|
96
|
+
else scrubElement(element);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Names the build a page comes from, from its script and stylesheet: a frame
|
|
102
|
+
* drawn by another build may not match the stylesheet it would be drawn with.
|
|
103
|
+
*/
|
|
104
|
+
export function bootFrameBuildId(script: string | Uint8Array, stylesheet: string): string {
|
|
105
|
+
return `${Bun.hash(script).toString(36)}-${Bun.hash(stylesheet).toString(36)}`;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** A JSON value safe inside an inline script. */
|
|
109
|
+
function scriptJson(value: unknown): string {
|
|
110
|
+
return JSON.stringify(value)
|
|
111
|
+
.replace(/</g, "\\u003c")
|
|
112
|
+
.replace(/\u2028/g, "\\u2028")
|
|
113
|
+
.replace(/\u2029/g, "\\u2029");
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
interface BootFrameScriptOptions {
|
|
117
|
+
build: string;
|
|
118
|
+
/** A JavaScript expression for the stored frame, evaluated inside a try. */
|
|
119
|
+
source: string;
|
|
120
|
+
/** A JavaScript expression that is true on a page that draws no frame, such as a window holding one popped-out pane. */
|
|
121
|
+
skip?: string;
|
|
122
|
+
/** The default theme's root style, for the bare shell drawn when there is no frame to redraw. */
|
|
123
|
+
shellStyle?: string;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* The inline script that draws the frame, placed right after the app's root.
|
|
128
|
+
* A stored frame from this build for this window size is drawn as it was,
|
|
129
|
+
* after the page scrubs it again. Otherwise the page draws the bare shell:
|
|
130
|
+
* the header and status bar, empty, in the stored frame's theme and text
|
|
131
|
+
* size when there is one, else the default theme's.
|
|
132
|
+
*/
|
|
133
|
+
export function bootFrameScript({ build, source, skip = "false", shellStyle = "" }: BootFrameScriptOptions): string {
|
|
134
|
+
return `(function () {
|
|
135
|
+
window.${BOOT_FRAME_BUILD_GLOBAL} = ${scriptJson(build)};
|
|
136
|
+
var root = document.getElementById("root");
|
|
137
|
+
var skip = false;
|
|
138
|
+
try { skip = !!(${skip}); } catch (error) { skip = false; }
|
|
139
|
+
if (!root || skip) return;
|
|
140
|
+
var frame = null;
|
|
141
|
+
try { frame = ${source}; } catch (error) { frame = null; }
|
|
142
|
+
var maxStyle = ${MAX_BOOT_FRAME_STYLE_CHARS};
|
|
143
|
+
if (!frame || typeof frame !== "object" || typeof frame.html !== "string" || frame.html.length > ${MAX_BOOT_FRAME_CHARS}
|
|
144
|
+
|| typeof frame.rootStyle !== "string" || frame.rootStyle.length > maxStyle
|
|
145
|
+
|| typeof frame.bodyStyle !== "string" || frame.bodyStyle.length > maxStyle) frame = null;
|
|
146
|
+
var scrub = ${scrubBootFrame.toString()};
|
|
147
|
+
// Parsed in a template, whose content is inert: nothing in it loads or runs before the scrub.
|
|
148
|
+
var template = document.createElement("template");
|
|
149
|
+
var safeStyle = function (style) {
|
|
150
|
+
var holder = template.content.ownerDocument.createElement("div");
|
|
151
|
+
holder.setAttribute("style", style);
|
|
152
|
+
scrub(holder);
|
|
153
|
+
return holder.getAttribute("style") || "";
|
|
154
|
+
};
|
|
155
|
+
var overlay = document.createElement("div");
|
|
156
|
+
overlay.id = ${scriptJson(BOOT_FRAME_ELEMENT_ID)};
|
|
157
|
+
// A picture of the app: nothing in it takes focus, a click or a screen reader.
|
|
158
|
+
overlay.setAttribute("inert", "");
|
|
159
|
+
overlay.setAttribute("aria-hidden", "true");
|
|
160
|
+
var rootStyle = frame ? safeStyle(frame.rootStyle) : "";
|
|
161
|
+
var bodyStyle = frame ? safeStyle(frame.bodyStyle) : "";
|
|
162
|
+
if (frame && frame.build === ${scriptJson(build)}
|
|
163
|
+
&& Math.abs(frame.width - window.innerWidth) <= 1 && Math.abs(frame.height - window.innerHeight) <= 1) {
|
|
164
|
+
if (rootStyle) document.documentElement.setAttribute("style", rootStyle);
|
|
165
|
+
if (bodyStyle) document.body.setAttribute("style", bodyStyle);
|
|
166
|
+
overlay.setAttribute("data-gloom-boot-frame", "layout");
|
|
167
|
+
template.innerHTML = frame.html;
|
|
168
|
+
scrub(template.content);
|
|
169
|
+
overlay.appendChild(template.content);
|
|
170
|
+
} else {
|
|
171
|
+
// The default theme first, so a stored theme that names fewer colours still leaves every one set.
|
|
172
|
+
var shellStyle = ${scriptJson(shellStyle)};
|
|
173
|
+
var themeStyle = [shellStyle, rootStyle].join(" ").trim();
|
|
174
|
+
if (themeStyle && !document.documentElement.getAttribute("style")) document.documentElement.setAttribute("style", themeStyle);
|
|
175
|
+
if (bodyStyle) document.body.setAttribute("style", bodyStyle);
|
|
176
|
+
overlay.setAttribute("data-gloom-boot-frame", "shell");
|
|
177
|
+
overlay.innerHTML = '<div class="gloom-boot-header"></div><div class="gloom-boot-status"></div>';
|
|
178
|
+
}
|
|
179
|
+
root.parentNode.insertBefore(overlay, root.nextSibling);
|
|
180
|
+
var scrolled = overlay.querySelectorAll("[${BOOT_FRAME_SCROLL_ATTRIBUTE}]");
|
|
181
|
+
for (var index = 0; index < scrolled.length; index += 1) {
|
|
182
|
+
var offset = scrolled[index].getAttribute("${BOOT_FRAME_SCROLL_ATTRIBUTE}").split(",");
|
|
183
|
+
scrolled[index].scrollTop = Number(offset[0]) || 0;
|
|
184
|
+
scrolled[index].scrollLeft = Number(offset[1]) || 0;
|
|
185
|
+
}
|
|
186
|
+
})();`;
|
|
187
|
+
}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The layout a launch draws before the app is up.
|
|
3
|
+
*
|
|
4
|
+
* Loading the app's script and starting it takes a second or more, and the
|
|
5
|
+
* page used to say "Loading Gloomberb..." for that time. Instead the app keeps
|
|
6
|
+
* a copy of its own frame: the header, every pane's chrome with its title and
|
|
7
|
+
* tabs, the dividers and the status bar, with each pane's body and footer
|
|
8
|
+
* left empty. The page draws that copy before its script loads, over the
|
|
9
|
+
* root the app renders into, and the app takes it down the first frame it
|
|
10
|
+
* has drawn its own layout. The copy is redrawn only from the same build, in
|
|
11
|
+
* a window of the same size: anything else could put panes where the app
|
|
12
|
+
* will not. The page's side, the stored format and the script that draws
|
|
13
|
+
* it, is boot-frame-page.ts.
|
|
14
|
+
*
|
|
15
|
+
* Each host keeps the copy where its page can read it before any script has
|
|
16
|
+
* loaded: the web app in localStorage, the desktop app beside the remembered
|
|
17
|
+
* window frame, handed to the window as it opens.
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
import {
|
|
21
|
+
BOOT_FRAME_BUILD_GLOBAL,
|
|
22
|
+
BOOT_FRAME_ELEMENT_ID,
|
|
23
|
+
BOOT_FRAME_SCROLL_ATTRIBUTE,
|
|
24
|
+
MAX_BOOT_FRAME_CHARS,
|
|
25
|
+
scrubBootFrame,
|
|
26
|
+
type BootFrame,
|
|
27
|
+
} from "./boot-frame-page";
|
|
28
|
+
|
|
29
|
+
/** What a frame keeps: these elements, and the elements on the way to them. */
|
|
30
|
+
const FRAME_ROLES = ["app-header", "pane-window", "dock-divider", "status-bar"];
|
|
31
|
+
const FRAME_SELECTOR = FRAME_ROLES.map((role) => `[data-gloom-role="${role}"]`).join(", ");
|
|
32
|
+
/**
|
|
33
|
+
* Kept empty: pane bodies and footers are most of the page and are the data
|
|
34
|
+
* the app fills from its cache as it starts. The market state and SPY quote in
|
|
35
|
+
* the header, an update status said last session ("Restart to update") and
|
|
36
|
+
* the status bar's widgets (an unread count, the account) are not true at the
|
|
37
|
+
* next launch.
|
|
38
|
+
*/
|
|
39
|
+
const EMPTIED_SELECTOR = [
|
|
40
|
+
"pane-body",
|
|
41
|
+
"pane-footer",
|
|
42
|
+
"header-market",
|
|
43
|
+
"header-update-status",
|
|
44
|
+
"status-widgets",
|
|
45
|
+
].map((role) => `[data-gloom-role="${role}"]`).join(", ");
|
|
46
|
+
|
|
47
|
+
/** The build this page says it is, or null where no frame script ran (tests, other pages). */
|
|
48
|
+
function currentBootFrameBuild(win: Window = window): string | null {
|
|
49
|
+
const build = (win as unknown as Record<string, unknown>)[BOOT_FRAME_BUILD_GLOBAL];
|
|
50
|
+
return typeof build === "string" && build ? build : null;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const ELEMENT_NODE = 1;
|
|
54
|
+
const TEXT_NODE = 3;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Copies what the frame keeps of `node`: frame elements whole but for their
|
|
58
|
+
* data, and the elements on the way to them bare. Walks the live tree rather
|
|
59
|
+
* than cloning it all, so pane bodies (most of the page) are never copied.
|
|
60
|
+
*/
|
|
61
|
+
function copyFrame(node: Node, insideFrame: boolean): Node | null {
|
|
62
|
+
if (node.nodeType === TEXT_NODE) return insideFrame ? node.cloneNode(false) : null;
|
|
63
|
+
if (node.nodeType !== ELEMENT_NODE) return null;
|
|
64
|
+
const element = node as Element;
|
|
65
|
+
const isFrame = insideFrame || element.matches(FRAME_SELECTOR);
|
|
66
|
+
if (!isFrame && element.querySelector(FRAME_SELECTOR) === null) return null;
|
|
67
|
+
const copy = element.cloneNode(false) as Element;
|
|
68
|
+
if (isFrame && element.matches(EMPTIED_SELECTOR)) return copy;
|
|
69
|
+
// A box scrolled by a pixel of overflow (the shell is) is drawn scrolled too.
|
|
70
|
+
if (element.scrollTop || element.scrollLeft) {
|
|
71
|
+
copy.setAttribute(BOOT_FRAME_SCROLL_ATTRIBUTE, `${Math.round(element.scrollTop)},${Math.round(element.scrollLeft)}`);
|
|
72
|
+
}
|
|
73
|
+
for (const child of element.childNodes) {
|
|
74
|
+
const childCopy = copyFrame(child, isFrame);
|
|
75
|
+
if (childCopy) copy.appendChild(childCopy);
|
|
76
|
+
}
|
|
77
|
+
return copy;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* The app's frame as it is drawn now, or null when there is none to keep: no
|
|
82
|
+
* layout drawn yet, or a frame too large to store. A layout with every pane
|
|
83
|
+
* closed is kept as it is, so the next launch does not draw panes the user
|
|
84
|
+
* closed.
|
|
85
|
+
*/
|
|
86
|
+
export function captureBootFrame(doc: Document, root: Element, build: string): BootFrame | null {
|
|
87
|
+
const view = doc.defaultView;
|
|
88
|
+
if (!view || !root.querySelector('[data-gloom-role="pane-window"], [data-gloom-role="status-bar"]')) return null;
|
|
89
|
+
const copy = copyFrame(root, false) as Element | null;
|
|
90
|
+
if (copy) scrubBootFrame(copy);
|
|
91
|
+
const html = copy?.innerHTML ?? "";
|
|
92
|
+
if (!html || html.length > MAX_BOOT_FRAME_CHARS) return null;
|
|
93
|
+
return {
|
|
94
|
+
build,
|
|
95
|
+
width: view.innerWidth,
|
|
96
|
+
height: view.innerHeight,
|
|
97
|
+
rootStyle: doc.documentElement.getAttribute("style") ?? "",
|
|
98
|
+
bodyStyle: doc.body.getAttribute("style") ?? "",
|
|
99
|
+
html,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/** The status bar's text but its widgets', which the frame leaves empty: a new unread count is not a new layout. */
|
|
104
|
+
function statusBarLabels(statusBar: Element): string {
|
|
105
|
+
return Array.from(statusBar.children)
|
|
106
|
+
.filter((child) => child.getAttribute("data-gloom-role") !== "status-widgets")
|
|
107
|
+
.map((child) => child.textContent ?? "")
|
|
108
|
+
.join("");
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* What would make a new frame differ from the last: the window, the theme
|
|
113
|
+
* and where each pane is and what it is called. Cheap enough to read every
|
|
114
|
+
* few seconds; the frame itself is only copied when this changes.
|
|
115
|
+
*/
|
|
116
|
+
export function bootFrameSignature(doc: Document, root: Element): string {
|
|
117
|
+
const view = doc.defaultView;
|
|
118
|
+
const parts: string[] = [
|
|
119
|
+
`${view?.innerWidth ?? 0}x${view?.innerHeight ?? 0}`,
|
|
120
|
+
doc.documentElement.getAttribute("style") ?? "",
|
|
121
|
+
doc.body.getAttribute("style") ?? "",
|
|
122
|
+
];
|
|
123
|
+
for (const element of root.querySelectorAll(
|
|
124
|
+
'[data-gloom-role="pane-window"], [data-gloom-role="dock-divider"], [data-gloom-role="status-bar"]',
|
|
125
|
+
)) {
|
|
126
|
+
const rect = element.getBoundingClientRect();
|
|
127
|
+
const role = element.getAttribute("data-gloom-role");
|
|
128
|
+
parts.push([
|
|
129
|
+
role,
|
|
130
|
+
Math.round(rect.x), Math.round(rect.y), Math.round(rect.width), Math.round(rect.height),
|
|
131
|
+
element.getAttribute("data-focused") ?? "",
|
|
132
|
+
role === "status-bar" ? statusBarLabels(element) : element.querySelector('[data-gloom-role="pane-header"]')?.textContent ?? "",
|
|
133
|
+
].join(":"));
|
|
134
|
+
}
|
|
135
|
+
return parts.join("|");
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const runningRecorders = new Set<() => void>();
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Stops every recorder on the page for good, before the data is reset: a
|
|
142
|
+
* frame saved after the reset, as the page closes, would draw the old layout
|
|
143
|
+
* at the next launch.
|
|
144
|
+
*/
|
|
145
|
+
export function stopBootFrameRecorders(): void {
|
|
146
|
+
for (const stop of [...runningRecorders]) stop();
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
interface BootFrameRecorderOptions {
|
|
150
|
+
doc: Document;
|
|
151
|
+
root: Element;
|
|
152
|
+
save(frame: BootFrame): void;
|
|
153
|
+
/** How often the layout is checked for a change. */
|
|
154
|
+
intervalMs?: number;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Keeps the stored frame current: shortly after the app is up, whenever the
|
|
159
|
+
* layout settles into something new, and as the page is hidden or closed.
|
|
160
|
+
* Does nothing on a page that drew no frame script, which is how a desktop
|
|
161
|
+
* pop-out window, a test or a share page stays out of it.
|
|
162
|
+
*/
|
|
163
|
+
export function startBootFrameRecorder({
|
|
164
|
+
doc,
|
|
165
|
+
root,
|
|
166
|
+
save,
|
|
167
|
+
intervalMs = 10_000,
|
|
168
|
+
}: BootFrameRecorderOptions): () => void {
|
|
169
|
+
const view = doc.defaultView;
|
|
170
|
+
const build = view ? currentBootFrameBuild(view) : null;
|
|
171
|
+
if (!view || !build) return () => {};
|
|
172
|
+
let lastSignature = "";
|
|
173
|
+
let stopped = false;
|
|
174
|
+
const record = () => {
|
|
175
|
+
if (stopped) return;
|
|
176
|
+
const signature = bootFrameSignature(doc, root);
|
|
177
|
+
if (signature === lastSignature) return;
|
|
178
|
+
const frame = captureBootFrame(doc, root, build);
|
|
179
|
+
if (!frame) return;
|
|
180
|
+
lastSignature = signature;
|
|
181
|
+
save(frame);
|
|
182
|
+
};
|
|
183
|
+
const recordWhenIdle = () => {
|
|
184
|
+
if (doc.visibilityState === "hidden") return;
|
|
185
|
+
const idle = (view as Window & { requestIdleCallback?: (callback: () => void, options?: { timeout: number }) => number }).requestIdleCallback;
|
|
186
|
+
if (idle) idle.call(view, record, { timeout: 2_000 });
|
|
187
|
+
else record();
|
|
188
|
+
};
|
|
189
|
+
const onHidden = () => {
|
|
190
|
+
if (doc.visibilityState === "hidden") record();
|
|
191
|
+
};
|
|
192
|
+
const first = view.setTimeout(recordWhenIdle, 3_000);
|
|
193
|
+
const interval = view.setInterval(recordWhenIdle, intervalMs);
|
|
194
|
+
doc.addEventListener("visibilitychange", onHidden);
|
|
195
|
+
view.addEventListener("pagehide", record);
|
|
196
|
+
const stop = () => {
|
|
197
|
+
stopped = true;
|
|
198
|
+
runningRecorders.delete(stop);
|
|
199
|
+
view.clearTimeout(first);
|
|
200
|
+
view.clearInterval(interval);
|
|
201
|
+
doc.removeEventListener("visibilitychange", onHidden);
|
|
202
|
+
view.removeEventListener("pagehide", record);
|
|
203
|
+
};
|
|
204
|
+
runningRecorders.add(stop);
|
|
205
|
+
return stop;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Takes the launch frame down as the app draws its own layout, or a failure
|
|
210
|
+
* screen, in `root`. Until then the frame covers the app, so the user never
|
|
211
|
+
* sees it half built. Mutation observers run before the page paints, so the
|
|
212
|
+
* frame goes in the paint that shows the layout, not a frame after it.
|
|
213
|
+
* Returns a function that takes the frame down now, for a page that gives
|
|
214
|
+
* up on starting.
|
|
215
|
+
*/
|
|
216
|
+
export function releaseBootFrameWhenDrawn(doc: Document, root: Element): () => void {
|
|
217
|
+
const view = doc.defaultView;
|
|
218
|
+
const frame = doc.getElementById(BOOT_FRAME_ELEMENT_ID);
|
|
219
|
+
if (!view || !frame) return () => {};
|
|
220
|
+
let released = false;
|
|
221
|
+
const release = () => {
|
|
222
|
+
if (released) return;
|
|
223
|
+
released = true;
|
|
224
|
+
observer.disconnect();
|
|
225
|
+
frame.remove();
|
|
226
|
+
};
|
|
227
|
+
const drawn = () => root.querySelector(
|
|
228
|
+
'[data-gloom-role="pane-window"], [data-gloom-role="status-bar"], .gloom-fatal',
|
|
229
|
+
) !== null;
|
|
230
|
+
const observer = new view.MutationObserver(() => {
|
|
231
|
+
if (drawn()) release();
|
|
232
|
+
});
|
|
233
|
+
observer.observe(root, { childList: true, subtree: true });
|
|
234
|
+
if (drawn()) release();
|
|
235
|
+
return release;
|
|
236
|
+
}
|
|
237
|
+
|
|
@@ -2,6 +2,10 @@ import { readFile, writeFile } from "fs/promises";
|
|
|
2
2
|
import { dirname, join, relative, resolve } from "path";
|
|
3
3
|
import type { BunPlugin } from "bun";
|
|
4
4
|
import { TITLEBAR_OVERLAY_HEIGHT_PX } from "../../components/layout/titlebar-overlay";
|
|
5
|
+
import { getThemeColors } from "../../theme/colors";
|
|
6
|
+
import { themeCssVariables } from "../../theme/ui-tokens";
|
|
7
|
+
import { DEFAULT_THEME } from "../../theme/themes";
|
|
8
|
+
import { bootFrameBuildId, bootFrameScript } from "./boot-frame-page";
|
|
5
9
|
|
|
6
10
|
/** Imports whose path ends with the first entry resolve to the second, relative to the view directory. */
|
|
7
11
|
type AliasRule = readonly [string, string];
|
|
@@ -12,10 +16,19 @@ type PageOptions = {
|
|
|
12
16
|
failureMessage: string;
|
|
13
17
|
missingEntryMessage: string;
|
|
14
18
|
title: string;
|
|
15
|
-
|
|
19
|
+
/** Text the page shows until its script draws, for a page with no launch frame. */
|
|
20
|
+
loadingText?: string;
|
|
16
21
|
bootstrapScript: string;
|
|
22
|
+
/** Draw the launch frame (boot-frame.ts) from where this host keeps it. */
|
|
23
|
+
bootFrame?: PageBootFrame;
|
|
17
24
|
};
|
|
18
25
|
|
|
26
|
+
/** Where a page reads its launch frame from: JavaScript expressions run before its script loads. */
|
|
27
|
+
export interface PageBootFrame {
|
|
28
|
+
source: string;
|
|
29
|
+
skip?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
19
32
|
interface ViewBundleOptions {
|
|
20
33
|
entrypoint: string;
|
|
21
34
|
outdir: string;
|
|
@@ -40,7 +53,7 @@ function minifyOption(keepNames: boolean | undefined) {
|
|
|
40
53
|
}
|
|
41
54
|
|
|
42
55
|
// From this file rather than the working directory, so a build started from
|
|
43
|
-
// any folder (`
|
|
56
|
+
// any folder (`gloom shot` run from a checkout or a package install) finds
|
|
44
57
|
// the sources.
|
|
45
58
|
const ELECTROBUN_VIEW_DIR = join(import.meta.dir, "..", "electrobun", "view");
|
|
46
59
|
|
|
@@ -109,7 +122,7 @@ export async function buildViewBundle({
|
|
|
109
122
|
}
|
|
110
123
|
|
|
111
124
|
export async function writeElectrobunViewPage(options: PageOptions): Promise<string> {
|
|
112
|
-
const { script } = await buildViewBundle({
|
|
125
|
+
const { script, stylesheet: bundledStylesheet } = await buildViewBundle({
|
|
113
126
|
entrypoint: options.entrypoint,
|
|
114
127
|
outdir: options.outdir,
|
|
115
128
|
aliasRules: options.aliasRules,
|
|
@@ -125,23 +138,48 @@ export async function writeElectrobunViewPage(options: PageOptions): Promise<str
|
|
|
125
138
|
const stylesheet = await readViewStylesheet();
|
|
126
139
|
const entrySrc = `./${relative(options.outdir, script).replaceAll("\\", "/")}`;
|
|
127
140
|
const htmlPath = join(options.outdir, "index.html");
|
|
128
|
-
|
|
141
|
+
const bootFrame = options.bootFrame
|
|
142
|
+
? { ...options.bootFrame, build: await pageBuildId(script, bundledStylesheet ?? null, stylesheet) }
|
|
143
|
+
: undefined;
|
|
144
|
+
await writeFile(htmlPath, renderElectrobunViewHtml({ ...options, stylesheet, entrySrc, bootFrame }));
|
|
129
145
|
return htmlPath;
|
|
130
146
|
}
|
|
131
147
|
|
|
148
|
+
/** Names a page's build for its launch frame, from the files that draw it. */
|
|
149
|
+
export async function pageBuildId(script: string, stylesheetPath: string | null, inlineStylesheet = ""): Promise<string> {
|
|
150
|
+
const css = (stylesheetPath ? await readFile(stylesheetPath, "utf8") : "") + inlineStylesheet;
|
|
151
|
+
return bootFrameBuildId(await readFile(script), css);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** The launch frame's inline script, with the default theme's colours for the bare shell. */
|
|
155
|
+
export function pageBootFrameScript(bootFrame: PageBootFrame & { build: string }): string {
|
|
156
|
+
const shellStyle = themeCssVariables(getThemeColors(DEFAULT_THEME)).map(([name, value]) => `${name}: ${value};`).join(" ");
|
|
157
|
+
return bootFrameScript({ ...bootFrame, shellStyle });
|
|
158
|
+
}
|
|
159
|
+
|
|
132
160
|
/** The DOM renderer's stylesheet, sized for the titlebar, which a view page inlines. */
|
|
133
161
|
export async function readViewStylesheet(): Promise<string> {
|
|
134
162
|
return withTitlebarOverlayHeight(await readFile(join(DOM_RENDERER_DIR, "styles.css"), "utf8"));
|
|
135
163
|
}
|
|
136
164
|
|
|
137
|
-
/**
|
|
165
|
+
/**
|
|
166
|
+
* A view page: the stylesheet inline, the bootstrap script, the launch frame
|
|
167
|
+
* when the page has one, then the bundle at `entrySrc`.
|
|
168
|
+
*/
|
|
138
169
|
export function renderElectrobunViewHtml({
|
|
139
170
|
title,
|
|
140
171
|
loadingText,
|
|
141
172
|
stylesheet,
|
|
142
173
|
bootstrapScript,
|
|
174
|
+
bootFrame,
|
|
143
175
|
entrySrc,
|
|
144
|
-
}: Pick<PageOptions, "title" | "loadingText" | "bootstrapScript"> & {
|
|
176
|
+
}: Pick<PageOptions, "title" | "loadingText" | "bootstrapScript"> & {
|
|
177
|
+
stylesheet: string;
|
|
178
|
+
entrySrc: string;
|
|
179
|
+
bootFrame?: PageBootFrame & { build: string };
|
|
180
|
+
}): string {
|
|
181
|
+
const loading = loadingText ? `<div class="gloom-loading">${loadingText}</div>` : "";
|
|
182
|
+
const frameScript = bootFrame ? `\n <script>\n${pageBootFrameScript(bootFrame)}\n </script>` : "";
|
|
145
183
|
return `<!doctype html>
|
|
146
184
|
<html lang="en">
|
|
147
185
|
<head>
|
|
@@ -151,10 +189,10 @@ export function renderElectrobunViewHtml({
|
|
|
151
189
|
<style>${stylesheet}</style>
|
|
152
190
|
</head>
|
|
153
191
|
<body style="margin:0;background:#000;">
|
|
154
|
-
<div id="root"
|
|
192
|
+
<div id="root">${loading}</div>
|
|
155
193
|
<script>
|
|
156
194
|
${bootstrapScript}
|
|
157
|
-
</script
|
|
195
|
+
</script>${frameScript}
|
|
158
196
|
<script type="module" src="${entrySrc}"></script>
|
|
159
197
|
</body>
|
|
160
198
|
</html>
|
|
@@ -670,7 +670,7 @@ export function WebPageStackView({
|
|
|
670
670
|
return (
|
|
671
671
|
<Box flexDirection="column" flexGrow={1} flexShrink={1} flexBasis={0} minWidth={0} minHeight={0} overflow="hidden">
|
|
672
672
|
{!headerAttached && (
|
|
673
|
-
<div className="gloom-stack-bar" data-gloom-role="page-stack-header">
|
|
673
|
+
<div className="gloom-stack-bar" data-gloom-role="page-stack-header" data-gloom-top-surface="">
|
|
674
674
|
<button
|
|
675
675
|
type="button"
|
|
676
676
|
className="gloom-stack-back"
|
|
@@ -290,6 +290,8 @@ export function WebQueryBar({ search, items, view, onClearAll, meta, leading, op
|
|
|
290
290
|
ref={rootRef}
|
|
291
291
|
className="gloom-qb"
|
|
292
292
|
data-gloom-role="query-bar"
|
|
293
|
+
// The active title-bar tab above takes this band's colour (top-surface.ts).
|
|
294
|
+
data-gloom-top-surface=""
|
|
293
295
|
// A search with nothing beside it may take the room the filters would.
|
|
294
296
|
data-search-only={search && items.length === 0 && !view ? "true" : undefined}
|
|
295
297
|
>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** @jsxImportSource react */
|
|
2
|
-
import {
|
|
2
|
+
import type { CSSProperties } from "react";
|
|
3
3
|
import type { UiHost } from "../../ui/host";
|
|
4
4
|
import { WEB_CELL_HEIGHT, WEB_CELL_WIDTH } from "../../theme/font-scale";
|
|
5
5
|
import { detectPlatform } from "../../utils/platform";
|
|
@@ -26,9 +26,10 @@ import { WebBox } from "./host/box";
|
|
|
26
26
|
import { WebChartSurface } from "./host/chart-surface";
|
|
27
27
|
import { WebSurface3D } from "./host/surface-3d";
|
|
28
28
|
import { WebInput, WebTextarea } from "./host/input";
|
|
29
|
+
import { WebImageSurface } from "./host/image-surface";
|
|
29
30
|
import { WebMediaSurface } from "./host/media-surface";
|
|
30
31
|
import { WebScrollBox } from "./host/scroll-box";
|
|
31
|
-
import { cleanDomProps
|
|
32
|
+
import { cleanDomProps } from "./host/style";
|
|
32
33
|
import { WebAsciiText, WebSpan, WebStrong, WebText, WebUnderline } from "./host/text";
|
|
33
34
|
import { WebTabs } from "./host/tabs";
|
|
34
35
|
|
|
@@ -97,33 +98,7 @@ export function createDomUiHost(
|
|
|
97
98
|
Tabs: WebTabs,
|
|
98
99
|
ChartSurface: WebChartSurface,
|
|
99
100
|
Surface3D: WebSurface3D,
|
|
100
|
-
ImageSurface:
|
|
101
|
-
const imageSrc = typeof src === "string" ? src.trim() : "";
|
|
102
|
-
const [failed, setFailed] = useState(false);
|
|
103
|
-
useEffect(() => setFailed(false), [imageSrc]);
|
|
104
|
-
const baseStyle = commonStyle(props);
|
|
105
|
-
return (
|
|
106
|
-
<div
|
|
107
|
-
{...cleanDomProps(props)}
|
|
108
|
-
style={{
|
|
109
|
-
...baseStyle,
|
|
110
|
-
overflow: baseStyle.overflow ?? "hidden",
|
|
111
|
-
...(props.style as CSSProperties | undefined),
|
|
112
|
-
}}
|
|
113
|
-
>
|
|
114
|
-
{imageSrc && !failed ? (
|
|
115
|
-
<img
|
|
116
|
-
key={imageSrc}
|
|
117
|
-
src={imageSrc}
|
|
118
|
-
alt={alt}
|
|
119
|
-
draggable={false}
|
|
120
|
-
onError={() => setFailed(true)}
|
|
121
|
-
style={{ width: "100%", height: "100%", display: "block", objectFit }}
|
|
122
|
-
/>
|
|
123
|
-
) : children as ReactNode}
|
|
124
|
-
</div>
|
|
125
|
-
);
|
|
126
|
-
},
|
|
101
|
+
ImageSurface: WebImageSurface,
|
|
127
102
|
MediaSurface: WebMediaSurface,
|
|
128
103
|
AudioPlayer: WebAudioPlayer,
|
|
129
104
|
SpinnerMark: ({ color, ...props }) => (
|
|
@@ -9,6 +9,20 @@ const WEB_GLOOMBERB_WORDMARK = [
|
|
|
9
9
|
" \\____|_|\\___/ \\___/|_| |_| |_|_.__/ \\___|_| |_.__/ ",
|
|
10
10
|
];
|
|
11
11
|
|
|
12
|
+
const WEB_GLOOM_WORDMARK = [
|
|
13
|
+
" ____ _ ",
|
|
14
|
+
" / ___| | ___ ___ _ __ ___ ",
|
|
15
|
+
"| | _| |/ _ \\ / _ \\| '_ ` _ \\ ",
|
|
16
|
+
"| |_| | | (_) | (_) | | | | | |",
|
|
17
|
+
" \\____|_|\\___/ \\___/|_| |_| |_|",
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
/** The web wordmarks, by the text they spell. */
|
|
21
|
+
const WEB_WORDMARKS = new Map<string, string[]>([
|
|
22
|
+
["gloom", WEB_GLOOM_WORDMARK],
|
|
23
|
+
["gloomberb", WEB_GLOOMBERB_WORDMARK],
|
|
24
|
+
]);
|
|
25
|
+
|
|
12
26
|
type WebWordmarkVariant = "legacy" | "compat" | null;
|
|
13
27
|
|
|
14
28
|
/**
|
|
@@ -22,7 +36,7 @@ export function webAsciiTextWordmarkVariant(
|
|
|
22
36
|
font: AsciiFontName = "tiny",
|
|
23
37
|
desktopPlatform?: string,
|
|
24
38
|
): WebWordmarkVariant {
|
|
25
|
-
if (font !== "wordmark" || text.trim().toLowerCase()
|
|
39
|
+
if (font !== "wordmark" || !WEB_WORDMARKS.has(text.trim().toLowerCase())) return null;
|
|
26
40
|
return detectPlatform(desktopPlatform) === "darwin" ? "legacy" : "compat";
|
|
27
41
|
}
|
|
28
42
|
|
|
@@ -32,6 +46,6 @@ export function webAsciiTextLines(
|
|
|
32
46
|
desktopPlatform?: string,
|
|
33
47
|
): string[] {
|
|
34
48
|
return webAsciiTextWordmarkVariant(text, font, desktopPlatform) === "compat"
|
|
35
|
-
?
|
|
49
|
+
? WEB_WORDMARKS.get(text.trim().toLowerCase())!
|
|
36
50
|
: renderAsciiText(text, font);
|
|
37
51
|
}
|