{"version":3,"file":"4388.6d0d7ce7.js","mappings":"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","sources":["webpack://@finviz/website/../config/colors.js","webpack://@finviz/website/../charts/app/lib/shims.ts","webpack://@finviz/website/../charts/app/logger.js","webpack://@finviz/website/../charts/app/chart-events/chart-event.ts","webpack://@finviz/website/../charts/app/chart-events/dividends.ts","webpack://@finviz/website/../charts/app/chart-events/earnings.ts","webpack://@finviz/website/../charts/app/chart-events/split.ts","webpack://@finviz/website/../charts/app/chart-events/index.ts","webpack://@finviz/website/../charts/app/helpers/get-canvas-element-by-type.ts","webpack://@finviz/website/../charts/app/models/chart.ts","webpack://@finviz/website/../charts/app/controllers/chart-events/async-modules.ts","webpack://@finviz/website/../charts/app/models/chart-event-element.ts","webpack://@finviz/website/../charts/app/models/chart_layout.ts","webpack://@finviz/website/../charts/app/utils/hlc.ts","webpack://@finviz/website/../charts/app/models/drawings-internal-store.ts","webpack://@finviz/website/../charts/app/models/indicator.ts","webpack://@finviz/website/../charts/app/models/overlay.ts","webpack://@finviz/website/../charts/app/models/relationships.ts","webpack://@finviz/website/../charts/app/index.ts","webpack://@finviz/website/../charts/app/modals/background.tsx","webpack://@finviz/website/../charts/app/modals/color_range_row.tsx","webpack://@finviz/website/../charts/app/modals/border.tsx","webpack://@finviz/website/../charts/app/modals/checkbox.tsx","webpack://@finviz/website/../charts/app/modals/font.tsx","webpack://@finviz/website/../charts/app/modals/line.tsx","webpack://@finviz/website/../charts/app/modals/multiline_string.tsx","webpack://@finviz/website/../charts/app/modals/number.tsx","webpack://@finviz/website/../charts/app/modals/string.tsx","webpack://@finviz/website/../charts/app/modals/trend.tsx","webpack://@finviz/website/../charts/app/modals/visibility/visibility-input.tsx","webpack://@finviz/website/../charts/app/modals/visibility/index.tsx","webpack://@finviz/website/../charts/app/modals/element_style.tsx","webpack://@finviz/website/../charts/app/controllers/autosave/utils.ts","webpack://@finviz/website/../charts/app/controllers/autosave/constants.ts","webpack://@finviz/website/../charts/app/controllers/autosave/use-drawing-autosave-api.tsx","webpack://@finviz/website/../charts/app/utils/string-byte-length.ts","webpack://@finviz/website/../charts/app/controllers/autosave/use-drawing-auto-save-controls.ts","webpack://@finviz/website/../charts/app/controllers/autosave/use-is-auto-save-active.ts","webpack://@finviz/website/../charts/app/controllers/autosave/with-auto-save.tsx","webpack://@finviz/website/../charts/app/utils/use-prev-state.ts","webpack://@finviz/website/../charts/app/modals/ideas/utils.ts","webpack://@finviz/website/../charts/app/modals/ideas/IdeaItem.tsx","webpack://@finviz/website/../charts/app/modals/ideas/IdeasTabs.tsx","webpack://@finviz/website/../charts/app/modals/ideas/Ideas.tsx","webpack://@finviz/website/../charts/app/controllers/header/ideas_dropdown.tsx","webpack://@finviz/website/../charts/app/modals/publish/async-modules.ts","webpack://@finviz/website/../charts/app/controllers/header/publish.tsx","webpack://@finviz/website/../charts/app/controllers/header/tour_button.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/chart-type-select.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/use-chart-types.ts","webpack://@finviz/website/../charts/app/controllers/chart-controls/daily-change-display.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/draw-button.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/fullscreen-button.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/search.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/settings-button.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/use-chart-controls.ts","webpack://@finviz/website/../charts/app/model-hooks/useModelRef.ts","webpack://@finviz/website/../charts/app/controllers/chart-controls/chart-controls.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/constants.ts","webpack://@finviz/website/../charts/app/models/context_menu.ts","webpack://@finviz/website/../charts/app/controllers/context_menu.tsx","webpack://@finviz/website/../charts/app/controllers/pane/chart-event-popover-with-state.tsx","webpack://@finviz/website/../charts/app/utils/use-click-away.ts","webpack://@finviz/website/../charts/app/controllers/pane/load-latest-data-button.tsx","webpack://@finviz/website/../charts/app/utils/use-is-mounted.ts","webpack://@finviz/website/../charts/app/controllers/pane/zoom_controls.tsx","webpack://@finviz/website/../charts/app/controllers/pane/pane.tsx","webpack://@finviz/website/../charts/app/controllers/pane/with-pane-model.tsx","webpack://@finviz/website/../charts/app/controllers/chart/chart-spinner-overlay.tsx","webpack://@finviz/website/../charts/app/controllers/chart/constants.ts","webpack://@finviz/website/../charts/app/controllers/chart/chart.tsx","webpack://@finviz/website/../charts/app/controllers/chart/with-chart-init.tsx","webpack://@finviz/website/../charts/app/controllers/chart/with-watched-panes-on-chart-model.tsx","webpack://@finviz/website/../charts/app/controllers/sidebar/modules/module-load-failed.tsx","webpack://@finviz/website/../charts/app/controllers/sidebar/modules/portfolio-watchlist/async-modules.ts","webpack://@finviz/website/../charts/app/controllers/sidebar/modules/modules.ts","webpack://@finviz/website/../charts/app/controllers/sidebar/modules/with-module-async-load.tsx","webpack://@finviz/website/../charts/app/controllers/sidebar/sidebar-content.tsx","webpack://@finviz/website/../charts/app/controllers/sidebar/sidebar-tabs.tsx","webpack://@finviz/website/../charts/app/controllers/sidebar/sidebar.tsx","webpack://@finviz/website/../charts/app/creators/async-modules.ts","webpack://@finviz/website/../charts/app/controllers/toolbar/drawingActions.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/drawingSettings.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/drawingTools.ts","webpack://@finviz/website/../charts/app/controllers/toolbar/toolbar.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/index.ts","webpack://@finviz/website/../charts/app/controllers/toolbar/auto-save-notes/auto-save-notes.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/auto-save-notes/auto-save-notes-dialog.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/confirmation_dialog.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/mobile/tool-button.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/mobile/toolbar-mobile.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/auto-save-state-indicator.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/chart-layout-auto-save-note.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/publish_old_button_click_listener.tsx","webpack://@finviz/website/../charts/app/controllers/autosave/idea-leave-dialog.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/with-chart-route-change.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/with-complete-layout-model-init.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/with-quote-cache-management.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/with-quote-polling.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/chart_layout_component.tsx","webpack://@finviz/website/../charts/app/controllers/with_dialog_state_hook.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/with-chart-page-title.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/with-idea-model-state.tsx","webpack://@finviz/website/../charts/app/controllers/chart_layout/chart_layout.tsx","webpack://@finviz/website/../charts/app/controllers/header/fullscreen_button.tsx","webpack://@finviz/website/../charts/app/controllers/header/layout_dropdown.tsx","webpack://@finviz/website/../charts/app/helpers/sorter.ts","webpack://@finviz/website/../charts/app/controllers/header/theme_toggle_button.tsx","webpack://@finviz/website/../charts/app/controllers/header/index.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/stock-detail-timeframe-bar.tsx","webpack://@finviz/website/../charts/app/utils/convert_ta.ts","webpack://@finviz/website/./js/app/charts-lib.ts","webpack://@finviz/website/./js/app/quote/create-alert/async-modules.ts","webpack://@finviz/website/./js/app/quote/save-to-portfolio/async-modules.ts","webpack://@finviz/website/./js/app/shared/documentVisibility.ts","webpack://@finviz/website/./js/app/shared/tracking.ts","webpack://@finviz/website/./js/main/components/portfolio/async-modules.ts","webpack://@finviz/website/./js/charts_lib_entry_do_not_directly_use_in_website.ts","webpack://@finviz/website/./js/main/components/checkbox.tsx","webpack://@finviz/website/./js/main/components/color-picker/draggable.tsx","webpack://@finviz/website/./js/main/components/color-picker/pointer.tsx","webpack://@finviz/website/./js/main/components/color-picker/util.ts","webpack://@finviz/website/./js/main/components/color-picker/alpha.tsx","webpack://@finviz/website/./js/main/components/color-picker/color-palette.tsx","webpack://@finviz/website/./js/main/components/color-picker/hue-saturation.tsx","webpack://@finviz/website/./js/main/components/color-picker/lightness.tsx","webpack://@finviz/website/./js/main/components/color-picker/color-preview.tsx","webpack://@finviz/website/./js/main/components/color-picker/picker-input.tsx","webpack://@finviz/website/./js/main/components/color-picker/picker.tsx","webpack://@finviz/website/./js/main/components/color-picker/picker-button.tsx","webpack://@finviz/website/./js/main/components/copy-to-clipboard/copy-to-clipboard.tsx","webpack://@finviz/website/./js/main/components/date-picker/index.tsx","webpack://@finviz/website/./js/main/components/context-menu/context-menu.tsx","webpack://@finviz/website/./js/main/components/grid/grid.tsx","webpack://@finviz/website/./js/main/components/inner-state/inner-state.tsx","webpack://@finviz/website/./js/main/components/range.tsx","webpack://@finviz/website/./js/main/components/toolbar/interfaces.ts","webpack://@finviz/website/./js/main/components/toolbar/hooks.ts","webpack://@finviz/website/./js/main/components/toolbar/toolbar.tsx","webpack://@finviz/website/./js/main/components/toolbar/toolbar-button.tsx","webpack://@finviz/website/./js/main/components/toolbar/toolbar-group.tsx","webpack://@finviz/website/./js/main/components/toolbar/toolbar-item.tsx","webpack://@finviz/website/./js/main/components/toolbar/toolbar-divider.tsx","webpack://@finviz/website/./js/main/components/tour/step-content.tsx","webpack://@finviz/website/./js/main/components/tour/utils.ts","webpack://@finviz/website/./js/main/components/tour/hooks.tsx","webpack://@finviz/website/./js/main/components/tabs/tabs.tsx","webpack://@finviz/website/./js/main/components/tabs/tab.tsx","webpack://@finviz/website/./js/main/components/tabs/tab-list.tsx","webpack://@finviz/website/./js/main/components/tabs/tab-panel.tsx","webpack://@finviz/website/./js/main/components/badge.tsx","webpack://@finviz/website/./js/main/components/popover/popover.tsx","webpack://@finviz/website/./js/main/components/popover/hooks.ts","webpack://@finviz/website/./js/main/components/popover/popover-trigger.tsx","webpack://@finviz/website/./js/main/components/select/NativeSelect.tsx","webpack://@finviz/website/./js/main/components/select/ItemsGroup.tsx","webpack://@finviz/website/./js/main/components/select/SelectOption.tsx","webpack://@finviz/website/./js/main/components/select/SelectItems.tsx","webpack://@finviz/website/./js/main/components/select/SelectList.tsx","webpack://@finviz/website/./js/main/components/select/SelectTooltipWrapper.tsx","webpack://@finviz/website/./js/main/components/select/DesktopSelect.tsx","webpack://@finviz/website/./js/main/components/select/SelectButton.tsx","webpack://@finviz/website/./js/main/components/select/Select.tsx","webpack://@finviz/website/./js/main/components/select/utils.ts","webpack://@finviz/website/./js/main/components/timeframe-bar/daterange-select.tsx","webpack://@finviz/website/./js/main/components/timeframe-bar/label-with-delayed-spinner.tsx","webpack://@finviz/website/./js/main/components/timeframe-bar/timeframe-select.tsx","webpack://@finviz/website/./js/main/components/timeframe-bar/timeframe-bar.tsx","webpack://@finviz/website/./js/main/components/timeframe-bar/utils.ts","webpack://@finviz/website/./js/main/components/timeframe-bar/custom-date-range-utils.ts","webpack://@finviz/website/./js/main/components/timeframe-bar/custom-date-range.tsx","webpack://@finviz/website/./js/main/components/timeframe-bar/use-custom-date-range-dialog.tsx","webpack://@finviz/website/./js/main/components/timeframe-bar/use-favorite-timeframes.tsx","webpack://@finviz/website/./js/main/hooks/use-sync-local-storage.ts","webpack://@finviz/website/./js/main/components/tooltip-input.tsx","webpack://@finviz/website/./js/main/hooks/use-popover-maxHeight.ts","webpack://@finviz/website/./js/main/hooks/use-track-pageview.ts","webpack://@finviz/website/./js/main/hooks/use-window-size.tsx","webpack://@finviz/website/./js/main/modules/portfolio/types.tsx","webpack://@finviz/website/./js/main/services/async-modules-utils.tsx","webpack://@finviz/website/./js/main/services/import-with-retry.ts","webpack://@finviz/website/./js/main/services/local-storage.ts","webpack://@finviz/website/./js/main/services/wait-for-previous-promise.ts","webpack://@finviz/website/../charts/app/canvas/arrow.ts","webpack://@finviz/website/../charts/app/canvas/brush/brush_v1.ts","webpack://@finviz/website/../charts/app/canvas/callout/callout_utils.ts","webpack://@finviz/website/../charts/app/canvas/callout/callout_v1.ts","webpack://@finviz/website/../charts/app/canvas/curve.ts","webpack://@finviz/website/../charts/app/canvas/ellipse.ts","webpack://@finviz/website/../charts/app/canvas/rotated_rectangle.ts","webpack://@finviz/website/../charts/app/canvas/symbol.ts","webpack://@finviz/website/../charts/app/canvas/drawingTools.ts","webpack://@finviz/website/../charts/app/canvas/element.ts","webpack://@finviz/website/../charts/app/canvas/elliott_waves/elliott_waves.ts","webpack://@finviz/website/../charts/app/canvas/ellipse/ellipse_v1.ts","webpack://@finviz/website/../charts/app/canvas/fibonacci_retracements.ts","webpack://@finviz/website/../charts/app/canvas/horizontal_line.ts","webpack://@finviz/website/../charts/app/canvas/line.ts","webpack://@finviz/website/../charts/app/canvas/measure.ts","webpack://@finviz/website/../charts/app/canvas/pitchfork/pitchfork_utils.ts","webpack://@finviz/website/../charts/app/canvas/pitchfork/pitchfork_v1.ts","webpack://@finviz/website/../charts/app/canvas/polygon.ts","webpack://@finviz/website/../charts/app/canvas/position.ts","webpack://@finviz/website/../charts/app/canvas/rectangle.ts","webpack://@finviz/website/../charts/app/canvas/rotated_rectangle/rotated_rectangle_v1.ts","webpack://@finviz/website/../charts/app/canvas/scaled_line.ts","webpack://@finviz/website/../charts/app/canvas/scaled_text.ts","webpack://@finviz/website/../charts/app/canvas/text.ts","webpack://@finviz/website/../charts/app/canvas/thumb.ts","webpack://@finviz/website/../charts/app/canvas/triangle.ts","webpack://@finviz/website/../charts/app/canvas/vertical_line.ts","webpack://@finviz/website/../charts/app/canvas/xabcd.ts","webpack://@finviz/website/../charts/app/canvas/cache.js","webpack://@finviz/website/../charts/app/models/chart_settings/interfaces.ts","webpack://@finviz/website/../charts/app/charts/utils.ts","webpack://@finviz/website/../charts/app/charts/base_chart.ts","webpack://@finviz/website/../charts/app/charts/candle_stick.ts","webpack://@finviz/website/../charts/app/charts/candle_stick_hollow.ts","webpack://@finviz/website/../charts/app/charts/heikin_ashi.ts","webpack://@finviz/website/../charts/app/charts/line_chart.ts","webpack://@finviz/website/../charts/app/charts/market_sentiment.ts","webpack://@finviz/website/../charts/app/charts/multi_line_chart.ts","webpack://@finviz/website/../charts/app/charts/ohlc_chart.ts","webpack://@finviz/website/../charts/app/charts/perf_chart.ts","webpack://@finviz/website/../charts/app/charts/charts.ts","webpack://@finviz/website/../charts/app/constants/common.ts","webpack://@finviz/website/../charts/app/controllers/chart-controls/use-chart-model-custom-date-range-values.tsx","webpack://@finviz/website/../charts/app/controllers/chart-controls/use-charts-path-location.ts","webpack://@finviz/website/../charts/app/controllers/chart-controls/utils.ts","webpack://@finviz/website/../charts/app/controllers/chart-settings/async-modules.ts","webpack://@finviz/website/../charts/app/utils/chart-date-range-utils.ts","webpack://@finviz/website/../charts/app/controllers/renderUtils.ts","webpack://@finviz/website/../charts/app/controllers/sidebar/constants.ts","webpack://@finviz/website/../charts/app/controllers/sidebar/hooks/sidebar-context.tsx","webpack://@finviz/website/../charts/app/controllers/toolbar/interfaces.ts","webpack://@finviz/website/../charts/app/controllers/utils.ts","webpack://@finviz/website/../charts/app/helpers/atr.ts","webpack://@finviz/website/../charts/app/helpers/math.ts","webpack://@finviz/website/../charts/app/indicator-calculation/ema.ts","webpack://@finviz/website/../charts/app/indicator-calculation/main.ts","webpack://@finviz/website/../charts/app/indicators/indicator.ts","webpack://@finviz/website/../charts/app/utils/canvas-render.ts","webpack://@finviz/website/../charts/app/indicators/adx.ts","webpack://@finviz/website/../charts/app/indicator-calculation/aroon.ts","webpack://@finviz/website/../charts/app/indicators/aro.ts","webpack://@finviz/website/../charts/app/indicators/aroosc.ts","webpack://@finviz/website/../charts/app/indicators/atr.ts","webpack://@finviz/website/../charts/app/indicators/cci.ts","webpack://@finviz/website/../charts/app/indicators/cot.ts","webpack://@finviz/website/../charts/app/indicator-calculation/fi.ts","webpack://@finviz/website/../charts/app/indicators/fi.ts","webpack://@finviz/website/../charts/app/indicator-calculation/macd.ts","webpack://@finviz/website/../charts/app/indicators/macd.ts","webpack://@finviz/website/../charts/app/indicators/mfi.ts","webpack://@finviz/website/../charts/app/indicators/none.ts","webpack://@finviz/website/../charts/app/indicators/obv.ts","webpack://@finviz/website/../charts/app/indicators/perf.ts","webpack://@finviz/website/../charts/app/indicators/rmi.ts","webpack://@finviz/website/../charts/app/indicators/roc.ts","webpack://@finviz/website/../charts/app/indicator-calculation/rsi.ts","webpack://@finviz/website/../charts/app/indicators/rsi.ts","webpack://@finviz/website/../charts/app/indicators/rvol.ts","webpack://@finviz/website/../charts/app/indicators/rwi.ts","webpack://@finviz/website/../charts/app/indicators/stofu.ts","webpack://@finviz/website/../charts/app/indicators/stofa.ts","webpack://@finviz/website/../charts/app/indicators/stosl.ts","webpack://@finviz/website/../charts/app/indicator-calculation/trix.ts","webpack://@finviz/website/../charts/app/indicators/trix.ts","webpack://@finviz/website/../charts/app/indicators/ult.ts","webpack://@finviz/website/../charts/app/indicators/vol.ts","webpack://@finviz/website/../charts/app/indicators/wr.ts","webpack://@finviz/website/../charts/app/indicators/indicators.ts","webpack://@finviz/website/../charts/app/model-hooks/use-model-state.ts","webpack://@finviz/website/../charts/app/models/chart/contstants.ts","webpack://@finviz/website/../charts/app/models/chart_settings/index.ts","webpack://@finviz/website/../charts/app/models/constants.ts","webpack://@finviz/website/../charts/app/models/element.ts","webpack://@finviz/website/../charts/app/models/mouse/mouse-utils.ts","webpack://@finviz/website/../charts/app/models/mouse/mouse.ts","webpack://@finviz/website/../charts/app/models/pane.ts","webpack://@finviz/website/../charts/app/models/quoteCache.ts","webpack://@finviz/website/../charts/app/models/quote.ts","webpack://@finviz/website/../charts/app/models/quote/constants.ts","webpack://@finviz/website/../charts/app/models/chart_settings/constants.ts","webpack://@finviz/website/../charts/app/models/chart_settings/interactive_chart_settings.ts","webpack://@finviz/website/../charts/app/models/settings.ts","webpack://@finviz/website/../charts/app/models/utils.ts","webpack://@finviz/website/../charts/app/indicator-calculation/bb.ts","webpack://@finviz/website/../charts/app/overlays/overlay.ts","webpack://@finviz/website/../charts/app/overlays/bb.ts","webpack://@finviz/website/../charts/app/overlays/dch.ts","webpack://@finviz/website/../charts/app/overlays/ema.ts","webpack://@finviz/website/../charts/app/overlays/ema2.ts","webpack://@finviz/website/../charts/app/overlays/hilo.ts","webpack://@finviz/website/../charts/app/overlays/hline.ts","webpack://@finviz/website/../charts/app/overlays/ic.ts","webpack://@finviz/website/../charts/app/overlays/icf.ts","webpack://@finviz/website/../charts/app/overlays/kch.ts","webpack://@finviz/website/../charts/app/overlays/none.ts","webpack://@finviz/website/../charts/app/overlays/patterns.ts","webpack://@finviz/website/../charts/app/overlays/pp.ts","webpack://@finviz/website/../charts/app/overlays/sar.ts","webpack://@finviz/website/../charts/app/indicator-calculation/sma.ts","webpack://@finviz/website/../charts/app/overlays/sma.ts","webpack://@finviz/website/../charts/app/overlays/sma2.ts","webpack://@finviz/website/../charts/app/overlays/str.ts","webpack://@finviz/website/../charts/app/overlays/vp.ts","webpack://@finviz/website/../charts/app/indicator-calculation/vwap.ts","webpack://@finviz/website/../charts/app/overlays/vwap.ts","webpack://@finviz/website/../charts/app/overlays/overlays.ts","webpack://@finviz/website/../charts/app/utils.ts","webpack://@finviz/website/../charts/app/utils/abort_controller.ts","webpack://@finviz/website/../charts/app/utils/async-modules-utils.ts","webpack://@finviz/website/../charts/app/utils/canvas.ts","webpack://@finviz/website/../charts/app/utils/chart-events-utils.ts","webpack://@finviz/website/../charts/app/utils/chart.ts","webpack://@finviz/website/../charts/app/utils/colors.ts","webpack://@finviz/website/../charts/app/utils/cursor.ts","webpack://@finviz/website/../charts/app/utils/draw_in_visible_area.ts","webpack://@finviz/website/../charts/app/utils/fetch_api.ts","webpack://@finviz/website/../charts/app/utils/force-update.ts","webpack://@finviz/website/../charts/app/utils/helpers.ts","webpack://@finviz/website/../charts/app/utils/useChartLayoutGlobalModelAsync.ts","webpack://@finviz/website/../charts/types/shared.ts"],"sourcesContent":["// Keep in sync with charts repository colors.js file in: app/constants/colors.js\r\n\r\nmodule.exports = {\r\n white: '#fff',\r\n black: '#000',\r\n inherit: 'inherit',\r\n transparent: 'transparent',\r\n current: 'currentColor',\r\n finviz: {\r\n 'blue-gray': '#262931',\r\n blue: '#4fa4f4',\r\n },\r\n gray: {\r\n 50: '#f3f3f5',\r\n 100: '#dedfe5',\r\n 200: '#c3c6d0',\r\n 300: '#a3a8b9',\r\n 400: '#868ea5',\r\n 500: '#676f85',\r\n 600: '#4c5263',\r\n 700: '#353945',\r\n 750: '#2c303b',\r\n 800: '#22262f',\r\n 900: '#14161d',\r\n },\r\n red: {\r\n 50: '#fef0f0',\r\n 100: '#fcd6d6',\r\n 200: '#fbb4b4',\r\n 300: '#fd8487',\r\n 400: '#fb5057',\r\n 500: '#d91e2b',\r\n 600: '#9f1f2a',\r\n 700: '#691f24',\r\n 800: '#45171a',\r\n 900: '#280e0f',\r\n },\r\n orange: {\r\n 50: '#fef2eb',\r\n 100: '#fdd9c5',\r\n 200: '#fab889',\r\n 300: '#ef9323',\r\n 400: '#ca7b14',\r\n 500: '#a0600e',\r\n 600: '#79460a',\r\n 700: '#583006',\r\n 800: '#3d1e03',\r\n 900: '#261101',\r\n },\r\n amber: {\r\n 50: '#fef2e7',\r\n 100: '#fedab5',\r\n 200: '#fbba56',\r\n 300: '#de9c1a',\r\n 400: '#bb830f',\r\n 500: '#956600',\r\n 600: '#704b00',\r\n 700: '#4f3400',\r\n 800: '#372200',\r\n 900: '#211300',\r\n },\r\n yellow: {\r\n 50: '#fdf2df',\r\n 100: '#fcdc86',\r\n 200: '#f3c736',\r\n 300: '#cda30b',\r\n 400: '#b08900',\r\n 500: '#8b6a00',\r\n 600: '#664e21',\r\n 700: '#46371e',\r\n 800: '#2f2516',\r\n 900: '#1b150d',\r\n },\r\n brightYellow: {\r\n 50: '#fff699',\r\n 100: '#fff200',\r\n },\r\n lime: {\r\n 50: '#ebfad6',\r\n 100: '#caec90',\r\n 200: '#aad547',\r\n 300: '#8db61e',\r\n 400: '#769913',\r\n 500: '#5b7800',\r\n 600: '#435900',\r\n 700: '#2e3e00',\r\n 800: '#1e2a00',\r\n 900: '#111900',\r\n },\r\n green: {\r\n 50: '#e7f7e8',\r\n 100: '#beeac1',\r\n 200: '#86d895',\r\n 300: '#34c062',\r\n 400: '#00a449',\r\n 500: '#19803d',\r\n 600: '#265d35',\r\n 700: '#1e4027',\r\n 800: '#162b1b',\r\n 900: '#0d1810',\r\n },\r\n emerald: {\r\n 50: '#ddfaee',\r\n 100: '#a2f0d2',\r\n 200: '#4dddaf',\r\n 300: '#25be93',\r\n 400: '#1d9f7b',\r\n 500: '#157e60',\r\n 600: '#035d47',\r\n 700: '#004139',\r\n 800: '#002c22',\r\n 900: '#001a13',\r\n },\r\n teal: {\r\n 50: '#e0f8fc',\r\n 100: '#9beef7',\r\n 200: '#4fd8e5',\r\n 300: '#27b9c4',\r\n 400: '#109ba5',\r\n 500: '#007c83',\r\n 600: '#005b62',\r\n 700: '#004045',\r\n 800: '#002b2e',\r\n 900: '#00191b',\r\n },\r\n blue: {\r\n 50: '#ebf4fe',\r\n 100: '#cae2fc',\r\n 200: '#9bcbfa',\r\n 300: '#57aefb',\r\n 400: '#2f91ef',\r\n 500: '#306dca',\r\n 600: '#2f5091',\r\n 700: '#263766',\r\n 800: '#1b2542',\r\n 900: '#101527',\r\n },\r\n violet: {\r\n 50: '#f4f2fe',\r\n 100: '#e1dbfd',\r\n 200: '#c9befc',\r\n 300: '#ad9bfb',\r\n 400: '#9978f9',\r\n 500: '#7c51e7',\r\n 600: '#5e36b8',\r\n 700: '#402979',\r\n 800: '#2a1e4e',\r\n 900: '#18122c',\r\n },\r\n purple: {\r\n 50: '#f9f1fe',\r\n 100: '#eed8fd',\r\n 200: '#e1b6fc',\r\n 300: '#d38bfb',\r\n 400: '#c85bf9',\r\n 500: '#ae27e0',\r\n 600: '#8514ac',\r\n 700: '#60077e',\r\n 800: '#44005a',\r\n 900: '#2a003a',\r\n },\r\n pink: {\r\n 50: '#fef1f4',\r\n 100: '#fdd6e1',\r\n 200: '#fcb2c7',\r\n 300: '#f984aa',\r\n 400: '#f25090',\r\n 500: '#cd2a74',\r\n 600: '#9d1658',\r\n 700: '#700c42',\r\n 800: '#4e052b',\r\n 900: '#32011a',\r\n },\r\n}\r\n","import Spine from '@finviz/spine'\r\n\r\n// eslint-disable-next-line no-extend-native\r\nArray.prototype.last = function () {\r\n return this[this.length - 1]\r\n}\r\n\r\n// eslint-disable-next-line no-extend-native\r\nString.prototype.padLeft = function (paddingValue) {\r\n return String(paddingValue + this).slice(-paddingValue.length)\r\n}\r\n\r\n// eslint-disable-next-line no-extend-native\r\nString.prototype.startsWith = function (str) {\r\n return this.indexOf(str) === 0\r\n}\r\n\r\ninterface CallbackCacheItem {\r\n newCb: (...args: any[]) => any\r\n origCb: (...args: any[]) => any\r\n}\r\n\r\nconst _callbackCache: CallbackCacheItem[] = []\r\nSpine.Collection.prototype.bind = function (ev, callback) {\r\n // eslint-disable-next-line @typescript-eslint/no-this-alias\r\n const that = this\r\n const cb = (record: Spine.Model, ...rest: any[]) => {\r\n if (record[that.fkey as keyof Spine.Model] === that.record.id) {\r\n return callback(record, ...rest)\r\n }\r\n }\r\n _callbackCache.push({ newCb: cb, origCb: callback })\r\n this.model.bind(ev, cb)\r\n return this\r\n}\r\n\r\nSpine.Collection.prototype.unbind = function (ev, callback) {\r\n let cb\r\n for (const item of _callbackCache) {\r\n if (item.origCb === callback) {\r\n cb = item.newCb\r\n break\r\n }\r\n }\r\n return this.model.unbind(ev, cb)\r\n}\r\n\r\nSpine.Model.findIndex = function (element) {\r\n const iterable = this.all()\r\n for (let index = 0; index < iterable.length; index++) {\r\n const el = iterable[index]\r\n if (element.eql(el)) {\r\n return index\r\n }\r\n }\r\n}\r\n","import Spine from '@finviz/spine'\r\n\r\nexport const defaults = {\r\n enabled: false,\r\n collapsed: true,\r\n duration: false,\r\n timestamp: true,\r\n logErrors: true,\r\n withStackTrace: false,\r\n level: 'log',\r\n logger: console,\r\n filterChanges: (model, attrs) => {\r\n const props = Object.keys(attrs)\r\n return (\r\n model.constructor.name === 'Mouse' ||\r\n model.constructor.name === 'Quote' ||\r\n (props.length === 1 && (props[0] === 'scale' || props[0] === 'leftOffset'))\r\n )\r\n },\r\n errorTransformer: (error) => error,\r\n titleFormatter: ({ timestamp, duration }, title, time, took) => {\r\n const parts = ['model']\r\n parts.push(`%c${String(title)}`)\r\n if (timestamp) {\r\n parts.push(`%c@ ${time}`)\r\n }\r\n if (duration) {\r\n parts.push(`%c(in ${took.toFixed(2)} ms)`)\r\n }\r\n return parts.join(' ')\r\n },\r\n colors: {\r\n title: () => 'inherit',\r\n prevState: () => '#9E9E9E',\r\n action: () => '#03A9F4',\r\n nextState: () => '#4CAF50',\r\n error: () => '#F20404',\r\n },\r\n}\r\n\r\nconst repeat = (str, times) => new Array(times + 1).join(str)\r\nconst pad = (num, maxLength = 2) => repeat('0', maxLength - num.toString().length) + num\r\nconst formatTime = (time) =>\r\n `${pad(time.getHours())}:${pad(time.getMinutes())}:${pad(time.getSeconds())}.${pad(time.getMilliseconds(), 3)}`\r\n\r\nexport const printLogEntry = (logEntry, options = {}) => {\r\n const { logger, logErrors, titleFormatter, collapsed, timestamp, duration, withStackTrace, colors, level } = {\r\n ...defaults,\r\n ...options,\r\n }\r\n const { startedTime, title, prevState, data, error, nextState, took } = logEntry\r\n\r\n const formattedTime = formatTime(startedTime)\r\n const titleCSS = colors.title ? `color: ${colors.title(title)};` : ''\r\n const headerCSS = ['color: gray; font-weight: lighter;']\r\n headerCSS.push(titleCSS)\r\n if (timestamp) {\r\n headerCSS.push('color: gray; font-weight: lighter;')\r\n }\r\n if (duration) {\r\n headerCSS.push('color: gray; font-weight: lighter;')\r\n }\r\n const formattedTitle = titleFormatter(defaults, title, formattedTime, took)\r\n\r\n try {\r\n if (collapsed) {\r\n if (colors.title) {\r\n logger.groupCollapsed(`%c ${formattedTitle}`, ...headerCSS)\r\n } else {\r\n logger.groupCollapsed(formattedTitle)\r\n }\r\n } else if (colors.title) {\r\n logger.group(`%c ${formattedTitle}`, ...headerCSS)\r\n } else {\r\n logger.group(formattedTitle)\r\n }\r\n } catch (e) {\r\n logger.log(formattedTitle)\r\n }\r\n\r\n if (colors.prevState) {\r\n const styles = `color: ${colors.prevState(prevState)}; font-weight: bold`\r\n logger[level]('%c prev state', styles, prevState)\r\n } else {\r\n logger[level]('prev state', prevState)\r\n }\r\n\r\n if (colors.action) {\r\n const styles = `color: ${colors.action(data)}; font-weight: bold`\r\n logger[level]('%c arguments ', styles, data)\r\n } else {\r\n logger[level]('arguments ', data)\r\n }\r\n\r\n if (error && logErrors) {\r\n if (colors.error) {\r\n const styles = `color: ${colors.error(error, prevState)}; font-weight: bold;`\r\n logger['error']('%c error ', styles, error)\r\n } else {\r\n logger['error']('error ', error)\r\n }\r\n }\r\n\r\n if (colors.nextState) {\r\n const styles = `color: ${colors.nextState(nextState)}; font-weight: bold`\r\n logger[level]('%c next state', styles, nextState)\r\n } else {\r\n logger[level]('next state', nextState)\r\n }\r\n\r\n if (withStackTrace) {\r\n logger.groupCollapsed('TRACE')\r\n logger.trace()\r\n logger.groupEnd()\r\n }\r\n\r\n try {\r\n logger.groupEnd()\r\n } catch (e) {\r\n logger.log('—— log end ——')\r\n }\r\n}\r\n\r\nexport const initialize = () => {\r\n window['logger'] = defaults\r\n\r\n const protoModelLoad = Spine.Model.prototype.load\r\n Spine.Model.prototype.load = function (attrs) {\r\n if (defaults.enabled && !defaults.filterChanges(this, attrs)) {\r\n const started = Date.now()\r\n const logEntry = {\r\n title: `${this.constructor.name}[#${this.id || this.cid}]`,\r\n started: started,\r\n startedTime: new Date(started),\r\n prevState: this.attributes(),\r\n data: attrs,\r\n }\r\n\r\n let returnedValue\r\n try {\r\n returnedValue = protoModelLoad.apply(this, arguments)\r\n } catch (e) {\r\n logEntry.error = e\r\n }\r\n\r\n logEntry.nextState = this.attributes()\r\n logEntry.took = Date.now() - logEntry.started\r\n\r\n printLogEntry(logEntry)\r\n return returnedValue\r\n } else {\r\n return protoModelLoad.apply(this, arguments)\r\n }\r\n }\r\n}\r\n","import { PaneArea } from '../../types/shared'\r\nimport Element, { DefaultAttrs } from '../canvas/element'\r\nimport BaseChart from '../charts/base_chart'\r\nimport { ChartEventBadgeType, ChartEventType, TIMEFRAME } from '../constants/common'\r\nimport { getRoundedObject } from '../controllers/renderUtils'\r\nimport Chart from '../models/chart'\r\nimport ChartEventElement from '../models/chart-event-element'\r\nimport { CHART_EVENT_BADGE_SIZE } from '../models/constants'\r\nimport type PaneModel from '../models/pane'\r\nimport { ChartEventBadgeState } from '../utils/chart-events-utils'\r\n\r\ninterface ChartEventAttrs extends DefaultAttrs {\r\n x: number\r\n}\r\n\r\nfunction getChartEventState(chartEvent: ChartEvent): ChartEventBadgeState {\r\n if (chartEvent.isOpen) {\r\n return ChartEventBadgeState.selected\r\n }\r\n if (chartEvent.isHovered) {\r\n return ChartEventBadgeState.hover\r\n }\r\n return ChartEventBadgeState.default\r\n}\r\n\r\nclass ChartEvent extends Element {\r\n static type = ChartEventType.ChartEvent\r\n static label = 'ChartEvent'\r\n\r\n declare scaled: Pick\r\n\r\n declare chart: BaseChart\r\n\r\n declare model: PaneModel\r\n\r\n declare chartEventModel: ChartEventElement | undefined\r\n\r\n isOpen = false\r\n\r\n left = 0\r\n top = 0\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x'], y: [] })\r\n\r\n get type() {\r\n return (this.constructor as typeof ChartEvent).type\r\n }\r\n\r\n get label() {\r\n return (this.constructor as typeof ChartEvent).label\r\n }\r\n\r\n getChartEvenBadgeType(): ChartEventBadgeType {\r\n switch (this.type) {\r\n case ChartEventType.Dividends:\r\n return ChartEventBadgeType.Dividends\r\n case ChartEventType.Split:\r\n return ChartEventBadgeType.Split\r\n }\r\n\r\n return ChartEventBadgeType.EarningsNeutral\r\n }\r\n\r\n getChartEventModel(): ChartEventElement | undefined {\r\n if (!this.chartEventModel) {\r\n this.chartEventModel = this.model.chartEvents()?.findByAttribute('instance', this)\r\n }\r\n\r\n return this.chartEventModel\r\n }\r\n\r\n getXYPosition() {\r\n const { top, bottom } = this.getChartLayoutSettings().ChartSettings\r\n const chartEventModel = this.getChartEventModel()\r\n const { x } = this.scaled\r\n const roundedXY = getRoundedObject({ x })\r\n const y =\r\n (this.model as PaneModel).height -\r\n top.height -\r\n bottom.height -\r\n CHART_EVENT_BADGE_SIZE -\r\n (chartEventModel?.yIndex ?? 0) * CHART_EVENT_BADGE_SIZE\r\n\r\n return { x: roundedXY.x - CHART_EVENT_BADGE_SIZE / 2, y }\r\n }\r\n\r\n getIsVisible() {\r\n return ![TIMEFRAME.w, TIMEFRAME.m].includes(this.model.chart().quote()?.timeframe)\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n if (!this.getIsVisible() || !this.chartEventModel) return\r\n\r\n this.attrs.x = Math.round(this.attrs.x)\r\n const chart = this.model.chart()\r\n const chartLayout = chart.chart_layout()\r\n const { x, y } = this.getXYPosition()\r\n const buffer = 10 + CHART_EVENT_BADGE_SIZE\r\n if (x + chart.leftOffset < -buffer || x + chart.leftOffset > chart.width + buffer) {\r\n return\r\n }\r\n const item = this.chartEventModel.getChartEventBadgeImage({\r\n theme: chartLayout.theme,\r\n state: getChartEventState(this),\r\n badgeType: this.getChartEvenBadgeType(),\r\n })\r\n\r\n if (!item) return\r\n\r\n const { left, top } = this.getChartLayoutSettings().ChartSettings\r\n this.left = x + chart.leftOffset + left.width + CHART_EVENT_BADGE_SIZE / 2\r\n this.top = y + top.height\r\n context.drawImage(item, x, y, CHART_EVENT_BADGE_SIZE, CHART_EVENT_BADGE_SIZE)\r\n }\r\n\r\n setIsHovered(isHovered: boolean) {\r\n if (!this.getIsVisible()) return\r\n\r\n this.isHovered = isHovered\r\n this.model.updateChartEventsZIndexes()\r\n this.trigger('change')\r\n }\r\n\r\n // If isOpenOverride is undefined, the function works as toggle\r\n toggleIsOpen(isOpenOverride?: boolean) {\r\n const chartLayout = this.model.chart().chart_layout()\r\n const chartEventModel = this.getChartEventModel()\r\n\r\n const isCurrentEventActive = chartLayout.activeChartEvent?.elementId === chartEventModel?.elementId\r\n const isOpen = isOpenOverride ?? (isCurrentEventActive ? !chartEventModel?.instance.isOpen : true)\r\n this.isOpen = isOpen\r\n if (chartLayout.activeChartEvent?.instance.isOpen && !isCurrentEventActive) {\r\n chartLayout.activeChartEvent?.instance.toggleIsOpen(false)\r\n }\r\n if (isOpen || isCurrentEventActive) {\r\n chartLayout.updateAttribute('activeChartEvent', !isOpen && isCurrentEventActive ? undefined : chartEventModel)\r\n }\r\n\r\n this.model.updateChartEventsZIndexes()\r\n this.trigger('change')\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (!this.getIsVisible()) return false\r\n\r\n const scaledArea = area.scaled\r\n const { x, y } = this.getXYPosition()\r\n const isInArea =\r\n x <= scaledArea.x &&\r\n x + CHART_EVENT_BADGE_SIZE >= scaledArea.x &&\r\n y <= scaledArea.y &&\r\n y + CHART_EVENT_BADGE_SIZE >= scaledArea.y\r\n return isInArea\r\n }\r\n\r\n getIsInChartView(chart: Chart) {\r\n if (!this.getIsVisible()) return false\r\n\r\n const { x } = this.getXYPosition()\r\n const isInView = x + CHART_EVENT_BADGE_SIZE >= -chart.leftOffset && x <= -chart.leftOffset + chart.width\r\n return isInView\r\n }\r\n}\r\n\r\nexport default ChartEvent\r\n","import { ChartEventLabels, ChartEventType } from '../constants/common'\r\nimport ChartEvent from './chart-event'\r\n\r\nclass Dividends extends ChartEvent {\r\n static type = ChartEventType.Dividends\r\n static label = ChartEventLabels[ChartEventType.Dividends]\r\n}\r\n\r\nexport default Dividends\r\n","import { ChartEventBadgeType, ChartEventLabels, ChartEventType } from '../constants/common'\r\nimport { IEarnings } from '../utils/chart-events-utils'\r\nimport ChartEvent from './chart-event'\r\n\r\nclass Earnings extends ChartEvent {\r\n static type = ChartEventType.Earnings\r\n static label = ChartEventLabels[ChartEventType.Earnings]\r\n\r\n getChartEvenBadgeType(): ChartEventBadgeType {\r\n const eventItem = this.getChartEventModel()?.getChartEventData() as IEarnings | undefined\r\n\r\n if (!eventItem) {\r\n return ChartEventBadgeType.EarningsNeutral\r\n }\r\n\r\n if (eventItem.epsActual === undefined || eventItem.epsEstimate === undefined) {\r\n const now = Date.now() / 1000\r\n return eventItem.dateTimestamp > now ? ChartEventBadgeType.EarningsFuture : ChartEventBadgeType.EarningsNeutral\r\n }\r\n return eventItem.epsActual - eventItem.epsEstimate < 0\r\n ? ChartEventBadgeType.EarningsNegative\r\n : ChartEventBadgeType.EarningsPositive\r\n }\r\n}\r\n\r\nexport default Earnings\r\n","import { ChartEventLabels, ChartEventType } from '../constants/common'\r\nimport ChartEvent from './chart-event'\r\n\r\nclass Split extends ChartEvent {\r\n static type = ChartEventType.Split\r\n static label = ChartEventLabels[ChartEventType.Split]\r\n}\r\n\r\nexport default Split\r\n","import { ChartEventType } from '../constants/common'\r\nimport chartEvent from './chart-event'\r\nimport dividends from './dividends'\r\nimport earnings from './earnings'\r\nimport split from './split'\r\n\r\nexport const chartEventsByType = Object.freeze({\r\n [ChartEventType.ChartEvent]: chartEvent,\r\n [ChartEventType.Dividends]: dividends,\r\n [ChartEventType.Split]: split,\r\n [ChartEventType.Earnings]: earnings,\r\n})\r\n","import { ChartConfigChartPaneElement } from '../../types/shared'\r\nimport { drawingToolsByType } from '../canvas/drawingTools'\r\nimport { chartEventsByType } from '../chart-events'\r\nimport { chartsByType } from '../charts/charts'\r\nimport { indicatorsByType } from '../indicators/indicators'\r\nimport { overlaysByType } from '../overlays/overlays'\r\n\r\nconst canvasElements = {\r\n ...overlaysByType,\r\n ...indicatorsByType,\r\n ...drawingToolsByType,\r\n ...chartsByType,\r\n ...chartEventsByType,\r\n}\r\n\r\nexport function getCanvasElementByType(elementType: ChartConfigChartPaneElement['type']) {\r\n return canvasElements[elementType]\r\n}\r\n","import Spine, { Collection } from '@finviz/spine'\r\nimport omit from 'lodash.omit'\r\n\r\nimport {\r\n ChartConfigChartPane,\r\n CustomSpineEvents,\r\n Instrument,\r\n ObjectHash,\r\n TodoObjectHashAnyType,\r\n} from '../../types/shared'\r\nimport BaseChart from '../charts/base_chart'\r\nimport PerfChart from '../charts/perf_chart'\r\nimport {\r\n DateRangeType,\r\n IndicatorType,\r\n QuotePollingIntervalInMs,\r\n ScaleType,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n} from '../constants/common'\r\nimport { getCanvasElementByType } from '../helpers/get-canvas-element-by-type'\r\nimport COT from '../indicators/cot'\r\nimport PricePerformance from '../indicators/perf'\r\nimport { getChartLayoutSettings } from '../models/settings'\r\nimport Utils from '../utils'\r\nimport { IDividends, IEarnings, ISplit } from '../utils/chart-events-utils'\r\nimport ChartEventElement from './chart-event-element'\r\nimport { ChartPartToAttrsSyncMap, ChartSyncablePart } from './chart/contstants'\r\nimport ChartLayout from './chart_layout'\r\nimport Pane from './pane'\r\nimport Quote from './quote'\r\n\r\nclass Chart extends Spine.Model {\r\n static initClass(paneModel: typeof Pane, quoteModel: typeof Quote, chartLayoutModel: typeof ChartLayout) {\r\n this.configure(\r\n 'Chart',\r\n 'width',\r\n 'height',\r\n 'timeframe',\r\n 'dateRange',\r\n 'scale',\r\n 'leftOffset',\r\n 'ticker',\r\n 'instrument',\r\n 'fx',\r\n 'fy',\r\n 'zoomFactor',\r\n 'refreshData',\r\n 'stretch',\r\n 'isHideDrawingsActive',\r\n 'isScrolled',\r\n 'firstBarClose',\r\n 'premarket',\r\n 'aftermarket',\r\n 'hasChartEvents'\r\n )\r\n this.hasMany('panes', paneModel)\r\n this.belongsTo('quote', quoteModel)\r\n this.belongsTo('chart_layout', chartLayoutModel)\r\n }\r\n\r\n declare stretch: boolean\r\n declare chart_layout_id: string\r\n declare chart_layout: () => ChartLayout\r\n declare quote_id: string\r\n declare quote: () => Quote\r\n declare panes: () => Collection\r\n declare refreshData: boolean | number\r\n declare dateRange: DateRangeType\r\n declare width: number\r\n declare height: number\r\n declare timeframe: TIMEFRAME\r\n declare leftOffset: number\r\n declare ticker: string\r\n declare instrument: Instrument\r\n declare fx: (x: number) => number\r\n declare fy: (x: number) => number\r\n declare zoomFactor: number\r\n declare isHideDrawingsActive: boolean\r\n declare isScrolled: boolean\r\n declare scale: ScaleType\r\n declare firstBarClose: number\r\n declare premarket: boolean\r\n declare aftermarket: boolean\r\n declare hasChartEvents: boolean\r\n\r\n getChartPane() {\r\n return this.panes()\r\n .all()\r\n .find((pane: Pane) =>\r\n pane\r\n .elements()\r\n .all()\r\n .some((el) => el.isChart())\r\n )\r\n }\r\n\r\n getChartElement() {\r\n for (const pane of this.panes().all()) {\r\n for (const el of pane.elements().all()) {\r\n if (el.isChart()) {\r\n return el\r\n }\r\n }\r\n }\r\n }\r\n\r\n getChartType() {\r\n return this.getChartElement()?.instance.type\r\n }\r\n\r\n getRefreshInterval() {\r\n let defaultRefreshInterval: number | null = null\r\n if (typeof this.refreshData === 'number') {\r\n defaultRefreshInterval = this.refreshData\r\n } else if (this.refreshData === true) {\r\n defaultRefreshInterval = QuotePollingIntervalInMs.Default\r\n }\r\n\r\n const isStock = this.instrument === Instrument.Stock\r\n const isPremium = window.FinvizSettings.hasUserPremium\r\n let customRefreshInterval = QuotePollingIntervalInMs.Elite\r\n if (!isPremium) {\r\n customRefreshInterval = QuotePollingIntervalInMs.Free\r\n } else if (isStock && !Utils.isStockFastRefreshAvailable()) {\r\n customRefreshInterval = QuotePollingIntervalInMs.EliteStocksReduced\r\n }\r\n\r\n return defaultRefreshInterval && Math.max(defaultRefreshInterval, customRefreshInterval)\r\n }\r\n\r\n toObject() {\r\n const panes = this.panes()\r\n .all()\r\n .map((pane) => pane.toObject())\r\n return {\r\n width: this.width,\r\n dateRange: this.dateRange,\r\n height: this.height,\r\n timeframe: this.timeframe,\r\n scale: this.scale,\r\n leftOffset: this.leftOffset,\r\n ticker: this.ticker,\r\n instrument: this.instrument,\r\n zoomFactor: this.zoomFactor,\r\n refreshData: this.refreshData,\r\n stretch: this.stretch,\r\n chartId: this.cid,\r\n panes,\r\n isHideDrawingsActive: this.isHideDrawingsActive,\r\n isScrolled: this.isScrolled,\r\n premarket: this.premarket,\r\n aftermarket: this.aftermarket,\r\n hasChartEvents: this.hasChartEvents,\r\n }\r\n }\r\n\r\n toConfig(omitKeys = [] as string[]) {\r\n const panes = this.panes()\r\n .all()\r\n .map((pane) => pane.toConfig(omitKeys))\r\n return omit(\r\n {\r\n width: this.width,\r\n height: this.height,\r\n timeframe: this.timeframe,\r\n scale: this.scale,\r\n leftOffset: this.leftOffset,\r\n ticker: this.ticker,\r\n instrument: this.instrument,\r\n zoomFactor: this.zoomFactor,\r\n refreshData: this.refreshData,\r\n stretch: this.stretch,\r\n chartId: this.cid,\r\n panes,\r\n isHideDrawingsActive: this.isHideDrawingsActive,\r\n isScrolled: this.isScrolled,\r\n premarket: this.premarket,\r\n aftermarket: this.aftermarket,\r\n hasChartEvents: this.hasChartEvents,\r\n },\r\n omitKeys\r\n )\r\n }\r\n\r\n destroyCascade(options?: TodoObjectHashAnyType) {\r\n this.panes()\r\n .all()\r\n .forEach((pane) => {\r\n pane.destroyCascade()\r\n })\r\n return this.destroy(options)\r\n }\r\n\r\n getChartLayoutSettings() {\r\n return getChartLayoutSettings(this.chart_layout())\r\n }\r\n\r\n getIsDisabled() {\r\n return this.quote()?.close.length === 0\r\n }\r\n\r\n getIsScrollable() {\r\n return this.chart_layout().scrollable\r\n }\r\n\r\n getAllPanes() {\r\n return this.panes().all()\r\n }\r\n\r\n getAllValidPanes() {\r\n const cotKeys = Object.keys(this.quote().COTs ?? {})\r\n return this.getAllPanes().filter((pane) => {\r\n const mainElement = pane.mainElement()\r\n if (mainElement?.instance.type === IndicatorType.Cot) {\r\n // Type of mainElement is `Element` but it can be an indicator too\r\n return cotKeys.includes((mainElement.instance as unknown as COT).attrs.code)\r\n }\r\n return true\r\n })\r\n }\r\n\r\n getAllElements() {\r\n return this.getAllPanes().flatMap((pane) => pane.getAllElements())\r\n }\r\n\r\n getAllQuotes(): Quote[] {\r\n const perfQuotes = this.getAllElements()\r\n .filter(({ instance }) => instance.type === IndicatorType.Perf)\r\n .flatMap(({ instance }) => Object.values((instance as unknown as PricePerformance).quotes))\r\n\r\n let quotePerfTickers: Quote[] = []\r\n if (this.chart_layout().specificChartFunctionality === SpecificChartFunctionality.quotePerf) {\r\n const perfChart = this.getChartElement()?.instance as PerfChart | undefined\r\n if (perfChart) {\r\n quotePerfTickers = Quote.select(\r\n (q: Quote) => perfChart.attrs.tickers.includes(q.ticker) && [TIMEFRAME.d, TIMEFRAME.m].includes(q.timeframe)\r\n )\r\n }\r\n }\r\n\r\n return [...perfQuotes, ...quotePerfTickers, this.quote()].filter(\r\n (quote, index, quotes) => quote && quotes.findIndex((q) => q?.id === quote.id) === index\r\n )\r\n }\r\n\r\n createPaneCascade(paneProperties: ChartConfigChartPane) {\r\n const paneModel = this.panes().create(paneProperties)\r\n\r\n paneProperties.elements?.forEach(({ zIndex, elementId, ...element }) => {\r\n const instance = getCanvasElementByType(element.type).fromObject(element, paneModel)\r\n paneModel.elements().create({ instance, zIndex, elementId })\r\n paneModel.chart().trigger(CustomSpineEvents.IndicatorsChange)\r\n })\r\n\r\n const chartOrIndicator = paneModel.getChartOrIndicatorElement()\r\n if (paneModel.mainElement()?.elementId !== chartOrIndicator?.elementId) {\r\n paneModel.updateAttributes({ mainElement: chartOrIndicator })\r\n }\r\n\r\n return paneModel\r\n }\r\n\r\n updateAttributesAndSync(value: T) {\r\n const attrsInSync = Object.entries(ChartPartToAttrsSyncMap)\r\n .filter(([key]) => this.getIsChartPartInSync(key as unknown as ChartSyncablePart))\r\n .flatMap(([_, modelAttr]) => modelAttr)\r\n this.updateAttributes(value)\r\n\r\n if (attrsInSync.length > 0) {\r\n this.chart_layout()\r\n .getAllCharts()\r\n .forEach((chartModel) => {\r\n if (this.eql(chartModel)) {\r\n return\r\n }\r\n const newAttrs: ObjectHash = {}\r\n attrsInSync.forEach((modelAttr) => {\r\n if (value.hasOwnProperty(modelAttr)) {\r\n newAttrs[modelAttr] = value[modelAttr]\r\n }\r\n })\r\n chartModel.updateAttributes(newAttrs)\r\n })\r\n }\r\n }\r\n\r\n setSyncChartParts(chartParts: ChartSyncablePart | ChartSyncablePart[], isInSync: boolean) {\r\n this.chart_layout().setSyncChartParts(chartParts, isInSync)\r\n }\r\n\r\n getIsChartPartInSync(chartPart: ChartSyncablePart) {\r\n return this.chart_layout().getIsChartPartInSync(chartPart)\r\n }\r\n\r\n getHasPatterns() {\r\n return this.getAllElements().some((element) => {\r\n if ('hasOverlay' in element.instance) {\r\n return (element.instance as BaseChart).hasOverlay?.('patterns')\r\n }\r\n\r\n return false\r\n })\r\n }\r\n\r\n getQuoteRawTicker(): string | null {\r\n return this.quote()?.getRawTicker() ?? null\r\n }\r\n\r\n setChartEvents(chartEvents?: Array, shouldClear = false) {\r\n const chartPane = this.getChartPane()\r\n if (!chartPane) {\r\n return\r\n }\r\n const allChartEvents = chartPane.chartEvents().all()\r\n if (shouldClear) {\r\n allChartEvents.forEach((chartEvent) => chartEvent.destroyCascade())\r\n }\r\n\r\n const events = shouldClear\r\n ? chartEvents\r\n : chartEvents?.filter((chartEvent) => !allChartEvents.some(({ elementId }) => chartEvent.elementId === elementId))\r\n\r\n events?.forEach(({ elementId, eventType, dateTimestamp }) => {\r\n const newChartEvent = chartPane.chartEvents().create({\r\n instance: getCanvasElementByType(eventType).fromObject({ positionTimestamps: { x: dateTimestamp } }, chartPane),\r\n elementId,\r\n })\r\n newChartEvent.instance.updateScales()\r\n })\r\n\r\n chartPane.updateChartEventsZIndexes()\r\n }\r\n}\r\n\r\nexport default Chart\r\n","export const chartEventsAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"chart-events\" */ './module-entry'),\r\n cacheKey: 'chart-events',\r\n}\r\n","import { ObjectHash } from '../../types/shared'\r\nimport { Theme } from '../../types/shared'\r\nimport ChartEvent from '../chart-events/chart-event'\r\nimport { ChartEventBadgeType } from '../constants/common'\r\nimport { chartEventsAsyncModule } from '../controllers/chart-events/async-modules'\r\nimport ElementModel from '../models/element'\r\nimport { ChartEventBadgeState, IChartEventBadgeProps } from '../utils/chart-events-utils'\r\nimport { captureException } from '../utils/helpers'\r\nimport { CHART_EVENT_BADGE_SIZE } from './constants'\r\nimport Pane from './pane'\r\n\r\nconst badgeImages = {} as ObjectHash<{ image: HTMLImageElement; isLoaded?: boolean }, string>\r\n\r\ntype ChartEventBadgeCommonType = Omit & { badgeType: ChartEventBadgeType }\r\n\r\nfunction getSvgImageCacheKey(props: Pick) {\r\n return `${props.badgeType}-${props.theme}-${props.state}`\r\n}\r\n\r\nasync function fetchAndCacheChartEventBadges({ onBadgeInitLoad }: { onBadgeInitLoad: () => void }) {\r\n // Currently node charts don't render badges and if the code below is executed on server it will crash because of missing file which is not transpiled\r\n if (typeof window === 'undefined') {\r\n return\r\n }\r\n\r\n // Temp workaround to prevent node charts from crashing\r\n const { importWithRetry } = await import('@finviz/website')\r\n const { chartBadgeSvgByType } = await importWithRetry(chartEventsAsyncModule.importFn)\r\n\r\n const handleImageResolve = () => {\r\n const hasSomeUnresolvedImages = Object.values(badgeImages).some(({ isLoaded }) => isLoaded === undefined)\r\n if (!hasSomeUnresolvedImages) {\r\n onBadgeInitLoad()\r\n }\r\n }\r\n\r\n Object.values(ChartEventBadgeState).forEach((badgeState) => {\r\n Object.values(ChartEventBadgeType).forEach((badgeType) => {\r\n Object.values(Theme).forEach((theme) => {\r\n const cacheKey = getSvgImageCacheKey({\r\n badgeType,\r\n state: badgeState,\r\n theme,\r\n })\r\n const svgHTML = chartBadgeSvgByType[badgeType]({\r\n state: badgeState,\r\n theme,\r\n width: CHART_EVENT_BADGE_SIZE,\r\n })\r\n const img = new Image()\r\n img.src = `data:image/svg+xml,${encodeURIComponent(svgHTML)}`\r\n img.onload = () => {\r\n badgeImages[cacheKey].isLoaded = true\r\n handleImageResolve()\r\n }\r\n img.onerror = () => {\r\n badgeImages[cacheKey].isLoaded = false\r\n handleImageResolve()\r\n captureException(new Error(`Image with cache key ${cacheKey} is invalid`), { extra: { src: img.src } })\r\n }\r\n badgeImages[cacheKey] = {\r\n image: img,\r\n }\r\n })\r\n })\r\n })\r\n}\r\n\r\nclass ChartEventElement extends ElementModel {\r\n static initClass(paneModel: typeof Pane) {\r\n this.configure('ChartEventElement', 'instance', 'lastChange', 'zIndex', 'yIndex', 'elementId')\r\n this.belongsTo('pane', paneModel)\r\n }\r\n\r\n declare instance: ChartEvent\r\n yIndex = 0\r\n\r\n getChartEventBadgeImage(props: ChartEventBadgeCommonType) {\r\n const cacheKey = getSvgImageCacheKey(props)\r\n const badgeImage = badgeImages[cacheKey]\r\n if (badgeImage) {\r\n // Possible fix for https://finvizcom.sentry.io/issues/4737062163\r\n if (badgeImage.isLoaded && badgeImage.image.width > 0 && badgeImage.image.height > 0) {\r\n return badgeImage.image\r\n }\r\n return undefined\r\n }\r\n\r\n void fetchAndCacheChartEventBadges({\r\n onBadgeInitLoad: () => this.trigger('change', this),\r\n })\r\n }\r\n\r\n getChartEventData() {\r\n return this.instance.model\r\n .chart()\r\n .quote()\r\n ?.chartEvents?.find((stockEvent) => stockEvent.elementId === this?.elementId)\r\n }\r\n\r\n toObject() {\r\n return {\r\n ...super.toObject(),\r\n yIndex: this.yIndex,\r\n }\r\n }\r\n\r\n toConfig() {\r\n return {\r\n ...super.toConfig(),\r\n yIndex: this.yIndex,\r\n }\r\n }\r\n}\r\n\r\nexport default ChartEventElement\r\n","import Spine, { Collection } from '@finviz/spine'\r\nimport omit from 'lodash.omit'\r\n\r\nimport { IIdea, RootChartConfigObject, Theme, TodoObjectHashAnyType } from '../../types/shared'\r\nimport { ChartEditorEnum, IndicatorType, LayoutType, SpecificChartFunctionality } from '../constants/common'\r\nimport Indicator from '../indicators/indicator'\r\nimport Chart from './chart'\r\nimport ChartEventElement from './chart-event-element'\r\nimport { ChartSyncablePart } from './chart/contstants'\r\nimport { ISettings } from './chart_settings/interfaces'\r\nimport DrawingsInternalStore from './drawings-internal-store'\r\nimport Pane from './pane'\r\nimport { QuoteFetchType } from './quote/constants'\r\n\r\nclass ChartLayout extends Spine.Model {\r\n static initClass(chartModel: typeof Chart, drawingsInternalStoreModel: typeof DrawingsInternalStore) {\r\n this.configure(\r\n 'ChartLayout',\r\n 'layout',\r\n 'activeChart',\r\n 'activePane',\r\n 'activeChartEvent',\r\n 'width',\r\n 'height',\r\n 'editable',\r\n 'canChangeTicker',\r\n 'scrollable',\r\n 'initialScrollable',\r\n 'cross',\r\n 'editors',\r\n 'theme',\r\n 'settings',\r\n 'isWheelZoomEnabled',\r\n 'specificChartFunctionality',\r\n 'isLargeChart',\r\n 'isHideDrawingsActive',\r\n 'isPreserveDrawingsActive',\r\n 'isLockDrawingsActive',\r\n 'isDrawingModeContinuousActive',\r\n 'uuid',\r\n 'isTouchCrossActive',\r\n 'defaultZoomFactor',\r\n 'syncChartParts',\r\n 'isInit',\r\n 'idea'\r\n )\r\n this.hasMany('charts', chartModel)\r\n this.belongsTo('drawingsInternalStore', drawingsInternalStoreModel)\r\n }\r\n\r\n declare layout: LayoutType\r\n declare activeChart: Chart\r\n declare activePane?: Pane\r\n declare activeChartEvent?: ChartEventElement\r\n declare width: number\r\n declare height: number\r\n declare editable: boolean\r\n declare canChangeTicker: boolean\r\n declare scrollable: boolean\r\n declare readonly initialScrollable: boolean\r\n declare cross: boolean\r\n declare editors: ChartEditorEnum[]\r\n declare theme: Theme\r\n declare settings: ISettings\r\n declare isWheelZoomEnabled: boolean\r\n declare specificChartFunctionality: SpecificChartFunctionality\r\n declare isLargeChart?: boolean\r\n declare charts: () => Collection\r\n declare isHideDrawingsActive: boolean\r\n declare isPreserveDrawingsActive: boolean\r\n declare isLockDrawingsActive: boolean\r\n declare isDrawingModeContinuousActive: boolean\r\n declare uuid: string\r\n declare isTouchCrossActive?: boolean\r\n declare defaultZoomFactor: number\r\n declare syncChartParts: ChartSyncablePart[]\r\n declare idea?: IIdea\r\n declare isInit?: boolean\r\n declare drawingsInternalStore: () => DrawingsInternalStore\r\n\r\n getPaneWithSelection() {\r\n for (const pane of this.getAllPanes()) {\r\n if (pane.selection) {\r\n return pane\r\n }\r\n }\r\n }\r\n\r\n toObject() {\r\n const charts = this.getAllCharts().map((chart) => chart.toObject())\r\n return {\r\n layout: this.layout,\r\n width: this.width,\r\n height: this.height,\r\n charts,\r\n isHideDrawingsActive: this.isHideDrawingsActive,\r\n isPreserveDrawingsActive: this.isPreserveDrawingsActive,\r\n }\r\n }\r\n\r\n toConfig = RootChartConfigObject>(omitKeys = [] as string[]): T {\r\n const charts = this.getAllCharts().map((chart) => chart.toConfig(omitKeys))\r\n return JSON.parse(\r\n JSON.stringify(\r\n omit(\r\n {\r\n ...this.settings.ChartSettings.center,\r\n layout: this.layout,\r\n width: this.width,\r\n height: this.height,\r\n charts,\r\n isHideDrawingsActive: this.isHideDrawingsActive,\r\n isPreserveDrawingsActive: this.isPreserveDrawingsActive,\r\n colors: this.settings.ChartSettings.general.Colors,\r\n specificChartFunctionality: this.specificChartFunctionality,\r\n editors: this.editors,\r\n editable: this.editable,\r\n scrollable: this.scrollable,\r\n theme: this.theme,\r\n newCharts: /\\bcharts\\b/.test(window.location.pathname),\r\n },\r\n omitKeys\r\n )\r\n )\r\n )\r\n }\r\n\r\n destroyCascade(options?: TodoObjectHashAnyType) {\r\n this.getAllCharts().forEach((chart) => {\r\n chart.destroyCascade()\r\n })\r\n return this.destroy(options)\r\n }\r\n\r\n getAllCharts() {\r\n return this.charts().all()\r\n }\r\n\r\n getAllPanes() {\r\n return this.getAllCharts().flatMap((chart) => chart.getAllPanes())\r\n }\r\n\r\n getAllElements() {\r\n return this.getAllCharts().flatMap((chart) => chart.getAllElements())\r\n }\r\n\r\n setSyncChartParts(chartParts: ChartSyncablePart | ChartSyncablePart[], isInSync: boolean) {\r\n const chartPartsToSync = Array.isArray(chartParts) ? chartParts : [chartParts]\r\n\r\n const newSyncedChartParts = this.syncChartParts?.filter((chartPart) => !chartPartsToSync.includes(chartPart)) ?? []\r\n\r\n if (isInSync) {\r\n newSyncedChartParts.push(...chartPartsToSync)\r\n }\r\n\r\n this.updateAttributes({ syncChartParts: newSyncedChartParts })\r\n }\r\n\r\n getIsChartPartInSync(chartPart: ChartSyncablePart) {\r\n return !!this.syncChartParts?.includes(chartPart)\r\n }\r\n\r\n getIsIndicatorPresent(type: IndicatorType) {\r\n return !!this.charts()\r\n .first()\r\n ?.getAllElements()\r\n .some((element) => element.isIndicator() && (element.instance as unknown as Indicator).type === type)\r\n }\r\n\r\n getHTMLElementId() {\r\n return `chart-layout-${this.id}`\r\n }\r\n\r\n exitIdea() {\r\n this.updateAttribute('idea', undefined)\r\n this.getAllCharts().forEach((chart) => {\r\n // Change all idea quotes to non idea quotes and refetch because we don't need them anymore, but they may cause inconsistencies if they are in cache\r\n chart.getAllQuotes().forEach((quote) => {\r\n if (quote.ideaID) {\r\n quote.updateAttributes({ ideaID: undefined })\r\n quote.fetchData({ fetchType: QuoteFetchType.Refetch })\r\n }\r\n })\r\n\r\n chart.updateAttributes({ refreshData: true })\r\n })\r\n }\r\n\r\n isIdeaId(id: number | null = null) {\r\n return (this.idea?.id ?? null) === id\r\n }\r\n}\r\n\r\nexport default ChartLayout\r\n","export type HLC = {\r\n ts: number\r\n count: number\r\n uuid: string\r\n}\r\n\r\nexport const serializeHlc = ({ ts, count, uuid }: HLC) =>\r\n ts.toString().padStart(15, '0') + ':' + count.toString(36).padStart(5, '0') + ':' + uuid\r\n\r\nexport const parseHlc = (serialized: string) => {\r\n const [ts, count, uuid] = serialized.split(':')\r\n return {\r\n ts: Number.parseInt(ts),\r\n count: Number.parseInt(count, 36),\r\n uuid,\r\n }\r\n}\r\n\r\nexport const initHlc = (uuid: string, now: number): HLC => ({\r\n ts: now,\r\n count: 0,\r\n uuid,\r\n})\r\n\r\nexport const compareHlc = (one: HLC, two: HLC) => {\r\n if (one.ts === two.ts) {\r\n if (one.count === two.count) {\r\n if (one.uuid === two.uuid) {\r\n return 0\r\n }\r\n return one.uuid < two.uuid ? -1 : 1\r\n }\r\n return one.count - two.count\r\n }\r\n return one.ts - two.ts\r\n}\r\n\r\nexport const incrementHlc = (local: HLC, now: number): HLC => {\r\n if (now > local.ts) {\r\n return { ts: now, count: 0, uuid: local.uuid }\r\n }\r\n\r\n return { ...local, count: local.count + 1 }\r\n}\r\n\r\nexport const receiveHlc = (local: HLC, remote: HLC): HLC => {\r\n if (compareHlc(local, remote) >= 0) {\r\n return local\r\n }\r\n return { ...local, ts: remote.ts, count: remote.count }\r\n}\r\n","import Spine from '@finviz/spine'\r\n\r\nimport { AutoSaveElement } from '../controllers/autosave/constants'\r\nimport { getUuid } from '../utils/helpers'\r\nimport { HLC, initHlc } from '../utils/hlc'\r\nimport { AutoSaveState } from './constants'\r\n\r\ninterface DrawingsInternalStateAttrs {\r\n elements: AutoSaveElement[]\r\n latestRemoteUpdateTimestamp: HLC\r\n latestLocalUpdateTimestamp: HLC\r\n instanceUUID: string\r\n autoSaveState: AutoSaveState\r\n}\r\n\r\nclass DrawingsInternalStore extends Spine.Model {\r\n static initClass() {\r\n this.configure(\r\n 'DrawingsInternalState',\r\n 'elements',\r\n 'latestRemoteUpdateTimestamp',\r\n 'latestLocalUpdateTimestamp',\r\n 'autoSaveState',\r\n 'instanceUUID'\r\n )\r\n }\r\n\r\n elements: AutoSaveElement[]\r\n latestRemoteUpdateTimestamp: HLC\r\n latestLocalUpdateTimestamp: HLC\r\n instanceUUID: string\r\n autoSaveState: AutoSaveState\r\n\r\n constructor(attrs: Partial = {}) {\r\n super(attrs)\r\n\r\n this.elements = attrs.elements ?? []\r\n this.instanceUUID = attrs.instanceUUID ?? getUuid()\r\n this.latestLocalUpdateTimestamp = attrs.latestLocalUpdateTimestamp ?? initHlc(this.instanceUUID, 0)\r\n this.latestRemoteUpdateTimestamp = attrs.latestRemoteUpdateTimestamp ?? initHlc(this.instanceUUID, 0)\r\n this.autoSaveState = attrs.autoSaveState ?? AutoSaveState.Off\r\n }\r\n\r\n setAutoSaveState = (newAutoSaveState: AutoSaveState) => {\r\n if (this.autoSaveState !== newAutoSaveState) {\r\n this.updateAttributes({ autoSaveState: newAutoSaveState })\r\n }\r\n }\r\n}\r\n\r\nexport default DrawingsInternalStore\r\n","import Spine from '@finviz/spine'\r\n\r\nimport Chart from './chart'\r\n\r\nclass Indicator extends Spine.Model {\r\n static initClass(chartModel: typeof Chart) {\r\n this.configure('Indicator', 'instance')\r\n this.belongsTo('chart', chartModel)\r\n }\r\n\r\n declare chart: () => Chart\r\n\r\n // instance - todo - not sure what instance type to put here\r\n}\r\n\r\nexport default Indicator\r\n","import Spine from '@finviz/spine'\r\n\r\nimport Chart from './chart'\r\n\r\nclass Overlay extends Spine.Model {\r\n static initClass(chartModel: typeof Chart) {\r\n this.configure('Overlay', 'overlay')\r\n this.belongsTo('chart', chartModel)\r\n }\r\n\r\n declare overlay: any\r\n declare chart: () => Chart\r\n}\r\n\r\nexport default Overlay\r\n","/**\r\n * This file sets up the relationships between models and solves circular dependencies\r\n * This file needs to be imported in the index file so that the relationships are\r\n * called in time for instantiation.\r\n */\r\nimport Chart from './chart'\r\nimport ChartEventElement from './chart-event-element'\r\nimport ChartLayout from './chart_layout'\r\nimport DrawingsInternalStore from './drawings-internal-store'\r\nimport Element from './element'\r\nimport Indicator from './indicator'\r\nimport Overlay from './overlay'\r\nimport Pane from './pane'\r\nimport Quote from './quote'\r\n\r\nChart.initClass(Pane, Quote, ChartLayout)\r\nChartLayout.initClass(Chart, DrawingsInternalStore)\r\nDrawingsInternalStore.initClass()\r\nElement.initClass(Pane)\r\nChartEventElement.initClass(Pane)\r\nIndicator.initClass(Chart)\r\nOverlay.initClass(Chart)\r\nPane.initClass(Element, ChartEventElement, Chart)\r\n","import './lib/shims'\r\nimport { initialize } from './logger'\r\nimport './models/relationships'\r\n\r\nif (document.location.hostname === 'localhost') {\r\n initialize()\r\n}\r\n","import { InputColorPicker, convertColorToHEX } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\ninterface BackgroundInputProps {\r\n label: string\r\n value: string\r\n onChange: (color: string) => void\r\n}\r\n\r\nexport function BackgroundInput({ label = 'Background', value, onChange }: BackgroundInputProps) {\r\n return (\r\n \r\n )\r\n}\r\n","import { InputColorPicker, Paragraph, RangeSlider } from '@finviz/website'\r\nimport React, { useCallback } from 'react'\r\n\r\nimport { ObjectHash } from '../../types/shared'\r\n\r\ninterface ColorRangeRowInputProps {\r\n label: string\r\n colorValue: string\r\n colorTestId: string\r\n rangeValue: string\r\n rangeTestId: string\r\n rangeLabel: string\r\n rangeProps: ObjectHash\r\n onChange: (colorValue: string, value: string) => void\r\n}\r\n\r\nexport function ColorRangeRowInput({\r\n label,\r\n colorValue,\r\n colorTestId,\r\n rangeValue,\r\n rangeTestId,\r\n rangeLabel,\r\n rangeProps,\r\n onChange,\r\n}: ColorRangeRowInputProps) {\r\n const handleRangeChange = useCallback(\r\n (ev) => {\r\n const value = ev.currentTarget.value\r\n onChange(colorValue, value)\r\n },\r\n [onChange, colorValue]\r\n )\r\n const handleColorChange = useCallback(\r\n (color) => {\r\n onChange(color, rangeValue)\r\n },\r\n [onChange, rangeValue]\r\n )\r\n return (\r\n
\r\n
\r\n \r\n
\r\n
\r\n \r\n {rangeValue}\r\n \r\n }\r\n onChange={handleRangeChange}\r\n value={Number(rangeValue)}\r\n data-testid={rangeTestId}\r\n />\r\n
\r\n
\r\n )\r\n}\r\n","import { convertColorToHEX } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport { ColorRangeRowInput } from './color_range_row'\r\n\r\ninterface Value {\r\n color: string\r\n width: string\r\n}\r\n\r\ninterface BorderInputProps {\r\n label: string\r\n value: Value\r\n min: number\r\n max: number\r\n onChange: (value: Value) => void\r\n}\r\n\r\nexport function BorderInput({ label = 'Border', value, onChange, min, max }: BorderInputProps) {\r\n return (\r\n onChange({ color, width })}\r\n />\r\n )\r\n}\r\n","import { Checkbox } from '@finviz/website'\r\nimport React from 'react'\r\n\r\ninterface CheckBoxProps {\r\n label: string\r\n value: boolean\r\n onChange: (isChecked: boolean) => void\r\n}\r\n\r\nexport function CheckBox({ label, value, onChange }: CheckBoxProps) {\r\n return (\r\n ) => onChange(ev.currentTarget.checked)}\r\n data-testid=\"chart-modal-checkbox\"\r\n >\r\n {label}\r\n \r\n )\r\n}\r\n","import { Checkbox, Input, Label, Select } from '@finviz/website'\r\nimport React, { useCallback, useState } from 'react'\r\n\r\nconst FONT_VALUES = [\r\n { value: 'Arial', label: 'Arial' },\r\n { value: 'Verdana', label: 'Verdana' },\r\n]\r\n\r\ninterface InputProps {\r\n family: string\r\n size: string\r\n style: string\r\n weight: string\r\n}\r\n\r\ninterface FontInputProps {\r\n value: InputProps\r\n onChange: (values: InputProps) => void\r\n}\r\n\r\nexport function FontInput({ value, onChange }: FontInputProps) {\r\n const [family, setFamily] = useState(value.family)\r\n const [size, setSize] = useState(value.size)\r\n const [style, setStyle] = useState(value.style)\r\n const [weight, setWeight] = useState(value.weight)\r\n\r\n const setValue = useCallback(\r\n (key, valueSetter, value) => {\r\n valueSetter(value)\r\n onChange({ family, size, style, weight, [key]: value })\r\n },\r\n [family, size, style, weight, onChange]\r\n )\r\n\r\n return (\r\n
\r\n
\r\n \r\n ) => setValue('size', setSize, ev.currentTarget.value)}\r\n value={size}\r\n data-testid=\"chart-modal-font-size\"\r\n />\r\n\r\n ) =>\r\n setValue('weight', setWeight, ev.currentTarget.checked ? 'bold' : 'normal')\r\n }\r\n data-testid=\"chart-modal-font-weight\"\r\n >\r\n Bold\r\n \r\n ) =>\r\n setValue('style', setStyle, ev.currentTarget.checked ? 'italic' : 'normal')\r\n }\r\n data-testid=\"chart-modal-font-style\"\r\n >\r\n Italic\r\n \r\n
\r\n
\r\n )\r\n}\r\n","import { convertColorToHEX } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport { ColorRangeRowInput } from './color_range_row'\r\n\r\ninterface LineInputValue {\r\n color: string\r\n width: string\r\n}\r\n\r\ninterface LineInputProps {\r\n label: string\r\n value: LineInputValue\r\n onChange: (value: LineInputValue) => void\r\n}\r\n\r\nexport function LineInput({ label = 'Line', value, onChange }: LineInputProps) {\r\n return (\r\n onChange({ color, width })}\r\n />\r\n )\r\n}\r\n","import { Textarea } from '@finviz/website'\r\nimport React from 'react'\r\n\r\ninterface MultilineStringInputProps {\r\n label: string\r\n value: string\r\n required: boolean\r\n onChange: (value: string) => void\r\n}\r\n\r\nexport function MultilineStringInput({ label, value, required, onChange }: MultilineStringInputProps) {\r\n return (\r\n ) => onChange(e.target.value)}\r\n value={value}\r\n autoFocus\r\n data-testid=\"chart-modal-multiline-string-textarea\"\r\n />\r\n )\r\n}\r\n","import { Input } from '@finviz/website'\r\nimport React from 'react'\r\n\r\ninterface NumberInputProps {\r\n label: string\r\n name: string\r\n value: number\r\n required: boolean\r\n min?: number\r\n max?: number\r\n allowDecimal?: boolean\r\n step?: number\r\n onChange: (value: number) => void\r\n}\r\n\r\nexport function NumberInput(props: NumberInputProps) {\r\n const { label, name, value, required, min, max, step, allowDecimal = false } = props\r\n\r\n return (\r\n ) =>\r\n props.onChange(allowDecimal ? parseFloat(e.target.value) : parseInt(e.target.value, 10))\r\n }\r\n data-testid=\"chart-modal-number-input\"\r\n />\r\n )\r\n}\r\n","import { Input } from '@finviz/website'\r\nimport React from 'react'\r\n\r\ninterface StringInputProps {\r\n label: string\r\n name: string\r\n value: string\r\n required: boolean\r\n onChange: (value: string) => void\r\n}\r\n\r\nexport function StringInput(props: StringInputProps) {\r\n const { label, name, value, required } = props\r\n\r\n return (\r\n ) => props.onChange(e.target.value)}\r\n data-testid=\"chart-modal-string-textinput\"\r\n />\r\n )\r\n}\r\n","import { Checkbox, Input, InputColorPicker, convertColorToHEX } from '@finviz/website'\r\nimport React from 'react'\r\n\r\ninterface InputProps {\r\n active: boolean\r\n trend: number\r\n color: string\r\n}\r\n\r\ninterface trendInputProps {\r\n value: InputProps\r\n onChange: (values: InputProps) => void\r\n}\r\n\r\nexport function Trend({ value, onChange }: trendInputProps) {\r\n return (\r\n
\r\n ) => onChange({ ...value, active: ev.currentTarget.checked })}\r\n data-testid=\"chart-modal-trend-active\"\r\n />\r\n ) =>\r\n onChange({ ...value, trend: ev.currentTarget.valueAsNumber })\r\n }\r\n value={value.trend}\r\n data-testid=\"chart-modal-trend-value\"\r\n />\r\n onChange({ ...value, color: color })}\r\n inputDataTestId=\"chart-modal-trend-color\"\r\n />\r\n
\r\n )\r\n}\r\n","import { Checkbox, Input, Paragraph } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { MacroTimeframe } from '../../constants/common'\r\nimport { DEFAULTS } from './index'\r\n\r\nexport interface InputProps {\r\n macroKey: MacroTimeframe\r\n isOff: boolean\r\n from: number\r\n to: number\r\n}\r\n\r\ninterface VisibilityInputProps {\r\n value: InputProps\r\n onChange: (value: InputProps) => void\r\n isCheckboxOnly: boolean\r\n}\r\n\r\nexport function VisibilityInput({ value, onChange, isCheckboxOnly }: VisibilityInputProps) {\r\n const [isOff, setIsOff] = React.useState(value.isOff)\r\n const [from, setFrom] = React.useState(value.from)\r\n const [to, setTo] = React.useState(value.to)\r\n const { macroKey } = value\r\n const macroLabel = macroKey.charAt(0).toUpperCase() + macroKey.slice(1)\r\n\r\n const setValue = React.useCallback(\r\n (key, valueSetter, value) => {\r\n valueSetter(value)\r\n onChange({ macroKey, isOff, from, to, [key]: value })\r\n },\r\n [macroKey, isOff, from, to, onChange]\r\n )\r\n return (\r\n
\r\n
\r\n ) => setValue('isOff', setIsOff, !e.target.checked)}\r\n >\r\n {isCheckboxOnly && macroLabel}\r\n \r\n {!isCheckboxOnly && (\r\n <>\r\n ) =>\r\n setValue('from', setFrom, Number(ev.currentTarget.value))\r\n }\r\n data-testid={`visibility-input-${macroKey}-from`}\r\n />\r\n -\r\n ) =>\r\n setValue('to', setTo, Number(ev.currentTarget.value))\r\n }\r\n data-testid={`visibility-input-${macroKey}-to`}\r\n />\r\n {macroLabel}\r\n \r\n )}\r\n
\r\n
\r\n )\r\n}\r\n","import merge from 'lodash.merge'\r\nimport React from 'react'\r\n\r\nimport { IVisibility, MacroTimeframe, MicroTimeframeRange } from '../../constants/common'\r\nimport { isInRange } from '../../utils/helpers'\r\nimport { InputProps, VisibilityInput } from './visibility-input'\r\n\r\ninterface VisibilityProps {\r\n label: string\r\n name: string\r\n value: IVisibility\r\n onChange: (value: IVisibility) => void\r\n handleDisableSubmit: (value: string | false) => void\r\n}\r\n\r\ntype Micro = { isOff: boolean; from: number; to: number }\r\nexport type DEFAULTS_TYPE = { [key in MacroTimeframe]: Micro }\r\n\r\nexport const DEFAULTS: DEFAULTS_TYPE = {\r\n // [MacroTimeframe.seconds]: { isOff: false, from: 1, to: 59 },\r\n [MacroTimeframe.minutes]: { isOff: false, from: 1, to: 59 },\r\n [MacroTimeframe.hours]: { isOff: false, from: 1, to: 24 },\r\n [MacroTimeframe.days]: { isOff: false, from: 1, to: 366 },\r\n [MacroTimeframe.weeks]: { isOff: false, from: 1, to: 52 },\r\n [MacroTimeframe.months]: { isOff: false, from: 1, to: 12 },\r\n}\r\n\r\nconst INPUTS_AVAILABLE = [MacroTimeframe.minutes, MacroTimeframe.hours]\r\n\r\nconst getInitialState = (value: IVisibility) => {\r\n const visibilities = merge({}, DEFAULTS)\r\n for (const visibility in visibilities) {\r\n const macroTimeframe = visibility as MacroTimeframe\r\n const valueMacroTimeframe = value?.[macroTimeframe]\r\n if (!valueMacroTimeframe) continue\r\n if (Object.keys(valueMacroTimeframe).length === 0) {\r\n visibilities[macroTimeframe] = { ...visibilities[macroTimeframe], isOff: true }\r\n } else {\r\n visibilities[macroTimeframe] = { ...visibilities[macroTimeframe], ...valueMacroTimeframe }\r\n }\r\n }\r\n return visibilities\r\n}\r\n\r\nconst getIsVisibilityOutsideAvailableTimeframes = (value: IVisibility) => {\r\n const result = Object.keys(MacroTimeframe).every((macrotimeframe) => {\r\n const macroRange = value[macrotimeframe as MacroTimeframe]\r\n\r\n return (\r\n macroRange &&\r\n (Object.keys(macroRange).length === 0 ||\r\n !MicroTimeframeRange[macrotimeframe as MacroTimeframe].some((item) =>\r\n isInRange({\r\n value: item,\r\n min: macroRange?.from ?? DEFAULTS[macrotimeframe as MacroTimeframe].from,\r\n max: macroRange?.to ?? DEFAULTS[macrotimeframe as MacroTimeframe].to,\r\n })\r\n ))\r\n )\r\n })\r\n return result\r\n}\r\n\r\nexport function Visibility(props: VisibilityProps) {\r\n const initialVisibilityRef = React.useRef(getInitialState(props.value))\r\n\r\n const handleChange = (value: InputProps) => {\r\n const result: IVisibility = props.value ? merge({}, props.value) : {}\r\n result[value.macroKey] = {}\r\n\r\n if (value.isOff) {\r\n props.onChange(result)\r\n } else if (value.from === DEFAULTS[value.macroKey].from && value.to === DEFAULTS[value.macroKey].to) {\r\n delete result[value.macroKey]\r\n props.onChange(result)\r\n } else {\r\n if (value.from !== DEFAULTS[value.macroKey].from) {\r\n result[value.macroKey]!.from = value.from\r\n }\r\n if (value.to !== DEFAULTS[value.macroKey].to) {\r\n result[value.macroKey]!.to = value.to\r\n }\r\n props.onChange(result)\r\n }\r\n\r\n props.handleDisableSubmit(\r\n getIsVisibilityOutsideAvailableTimeframes(result)\r\n ? 'The chosen timeframes would make the drawing invisible on all supported timeframes.'\r\n : false\r\n )\r\n }\r\n\r\n return Object.keys(initialVisibilityRef.current).map((macroKey) => (\r\n \r\n ))\r\n}\r\n","import { Button, ButtonGroup, Dialog, DialogBody, DialogFooter, DialogHeader, useDialogState } from '@finviz/website'\r\nimport debounce from 'lodash.debounce'\r\nimport * as React from 'react'\r\n\r\nimport { ObjectHash } from '../../types/shared'\r\nimport CanvasElement from '../canvas/element'\r\nimport { BackgroundInput } from './background'\r\nimport { BorderInput } from './border'\r\nimport { CheckBox } from './checkbox'\r\nimport { FontInput } from './font'\r\nimport { LineInput } from './line'\r\nimport { MultilineStringInput } from './multiline_string'\r\nimport { NumberInput } from './number'\r\nimport { StringInput } from './string'\r\nimport { Trend } from './trend'\r\nimport { Visibility } from './visibility'\r\n\r\n/**\r\n * Dialogs require element to restore focus when closing. Restore focus to the\r\n * currently selected chart or body\r\n */\r\nfunction getElementToFocus(): HTMLElement {\r\n return document.querySelector('.chart.active') ?? document.body\r\n}\r\n\r\nfunction getInputForType(type: string) {\r\n switch (type) {\r\n case 'number':\r\n return NumberInput\r\n case 'string':\r\n return StringInput\r\n case 'text':\r\n return StringInput\r\n case 'background':\r\n return BackgroundInput\r\n case 'border':\r\n return BorderInput\r\n case 'line':\r\n return LineInput\r\n case 'multiline_string':\r\n return MultilineStringInput\r\n case 'font':\r\n return FontInput\r\n case 'checkbox':\r\n return CheckBox\r\n case 'trend':\r\n return Trend\r\n case 'visibility':\r\n return Visibility\r\n default:\r\n return () =>
ERROR: Unknown input type
\r\n }\r\n}\r\n\r\nconst TAB_BUTTON_COMMON_PROPS = { type: 'button' as const, className: 'flex-1', contentClass: 'text-center' }\r\n\r\ntype OnSubmitType = ((value: ObjectHash) => void) | null\r\ntype OnDismissType = (() => void) | null\r\n\r\nexport interface ElementStyleDialogProps {\r\n state: any\r\n element: ElementType\r\n onSubmit: ((values: ElementType['attrs']) => void) | null\r\n onDismiss: (() => void) | null\r\n onHide: () => void\r\n}\r\n\r\nexport type StyleDialogOpener = (\r\n element: ElementType,\r\n onSubmit: ElementStyleDialogProps['onSubmit'],\r\n onDismiss: ElementStyleDialogProps['onDismiss']\r\n) => void\r\n\r\nfunction getValuesFromFormState(formState: ObjectHash) {\r\n return formState.reduce((acc: ObjectHash, cur: ObjectHash) => {\r\n acc[cur.name] = cur.value\r\n return acc\r\n }, {} as ObjectHash)\r\n}\r\n\r\nenum DialogTabs {\r\n Style,\r\n Visibility,\r\n}\r\n\r\nexport function ElementStyleDialog(props: ElementStyleDialogProps) {\r\n const config = props.element.getModalConfig()\r\n const initialFormStateRef = React.useRef[]>(JSON.parse(JSON.stringify(config.inputs)))\r\n const [formState, setFormState] = React.useState[]>(config.inputs)\r\n const finalFocusRef = React.useRef(getElementToFocus())\r\n const [selectedTab, setSelectedTab] = React.useState(DialogTabs.Style)\r\n const [isSubmitDisabled, setIsSubmitDisabled] = React.useState(false) // If string, the value is used as title for disabled button.\r\n\r\n const isDrawingElement = props.element.getIsDrawing()\r\n\r\n React.useEffect(() => {\r\n props.element.isEditInProgress = true\r\n return () => {\r\n props.element.isEditInProgress = false\r\n props.element.trigger('change', props.element)\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n const handleValuesChange = React.useCallback(\r\n ({\r\n values,\r\n shouldSubmit = false,\r\n shouldDismiss = false,\r\n }: {\r\n values: ObjectHash\r\n shouldSubmit?: boolean\r\n shouldDismiss?: boolean\r\n }) => {\r\n const hasOnSubmit = typeof props.onSubmit === 'function'\r\n const hasOnDismiss = typeof props.onDismiss === 'function'\r\n\r\n props.element.set(values)\r\n if (shouldSubmit && hasOnSubmit) {\r\n props.onSubmit!(values)\r\n } else if (shouldDismiss && hasOnDismiss) {\r\n props.onDismiss!()\r\n }\r\n\r\n if (shouldSubmit || shouldDismiss) {\r\n props.state.hide()\r\n }\r\n },\r\n [props]\r\n )\r\n\r\n const handleValuesChangeDebounceRef = React.useRef(\r\n debounce(\r\n (newFormState) => {\r\n const values = getValuesFromFormState(newFormState)\r\n handleValuesChange({ values })\r\n },\r\n 50,\r\n { maxWait: 100 }\r\n )\r\n )\r\n\r\n React.useEffect(\r\n () => () => {\r\n handleValuesChangeDebounceRef.current.cancel()\r\n },\r\n []\r\n )\r\n\r\n const onSubmit: React.FormEventHandler = React.useCallback(\r\n (ev: React.FormEvent) => {\r\n ev.preventDefault()\r\n if (ev.currentTarget.checkValidity()) {\r\n const values = getValuesFromFormState(formState)\r\n handleValuesChange({ values, shouldSubmit: true })\r\n }\r\n },\r\n [formState, handleValuesChange]\r\n )\r\n\r\n const handleCloseDialog = React.useCallback(() => {\r\n const values = getValuesFromFormState(initialFormStateRef.current)\r\n handleValuesChange({ values, shouldDismiss: true })\r\n }, [handleValuesChange])\r\n\r\n const getShouldRenderInputForTab = (inputType: string) => {\r\n if (selectedTab === DialogTabs.Visibility && inputType === 'visibility') return true\r\n if (selectedTab !== DialogTabs.Visibility && inputType !== 'visibility') return true\r\n return false\r\n }\r\n\r\n return (\r\n \r\n {config.title}\r\n
\r\n \r\n {isDrawingElement && (\r\n \r\n setSelectedTab(DialogTabs.Style)}\r\n data-testid=\"dialog-tab-button-style\"\r\n >\r\n Style\r\n \r\n setSelectedTab(DialogTabs.Visibility)}\r\n data-testid=\"dialog-tab-button-visibility\"\r\n >\r\n Visibility\r\n \r\n \r\n )}\r\n\r\n {formState.map((input) => {\r\n const InputComponent = getInputForType(input.type) as React.FC<{\r\n onChange: (value: string) => void\r\n handleDisableSubmit?: typeof setIsSubmitDisabled\r\n }>\r\n return (\r\n getShouldRenderInputForTab(input.type) && (\r\n {\r\n setFormState((prevState) => {\r\n const newFormState = prevState.map((stateInput) => {\r\n if (stateInput.name === input.name) {\r\n return { ...stateInput, value }\r\n }\r\n return stateInput\r\n })\r\n handleValuesChangeDebounceRef.current(newFormState)\r\n return newFormState\r\n })\r\n }}\r\n handleDisableSubmit={setIsSubmitDisabled}\r\n />\r\n )\r\n )\r\n })}\r\n \r\n \r\n \r\n Close\r\n \r\n \r\n Save\r\n \r\n \r\n
\r\n \r\n )\r\n}\r\n\r\nexport const ElementStyleDialogContext = React.createContext>(() => {})\r\n\r\nexport function withElementStyleDialogState

(Component: React.ComponentType

) {\r\n return function WrappedComponent(props: P) {\r\n const context = React.useContext(ElementStyleDialogContext)\r\n\r\n return \r\n }\r\n}\r\n\r\nexport function ElementStyleDialogWrapper(props: { children: React.ReactNode }) {\r\n const [element, setElement] = React.useState(null)\r\n const [onSubmit, setOnSubmit] = React.useState(null)\r\n const [onDismiss, setOnDismiss] = React.useState(null)\r\n const dialog = useDialogState({ modal: false })\r\n\r\n const openDialog = (element: CanvasElement, onSubmit?: OnSubmitType, onDismiss?: OnDismissType) => {\r\n if (onSubmit) {\r\n setOnSubmit(() => onSubmit)\r\n }\r\n if (onDismiss) {\r\n setOnDismiss(() => onDismiss)\r\n }\r\n\r\n setElement(element)\r\n dialog.show()\r\n }\r\n\r\n const onHide = () => {\r\n setElement(null)\r\n setOnSubmit(null)\r\n setOnDismiss(null)\r\n }\r\n\r\n return (\r\n \r\n {props.children}\r\n {element && (\r\n \r\n )}\r\n \r\n )\r\n}\r\n","import { ChartConfigChartPane } from '../../../types/shared'\r\nimport { IndicatorType } from '../../constants/common'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport Element from '../../models/element'\r\nimport PaneModel from '../../models/pane'\r\nimport { HLC, compareHlc, incrementHlc, receiveHlc } from '../../utils/hlc'\r\nimport {\r\n AutoSaveChangeType,\r\n AutoSaveElement,\r\n AutoSaveElementDBRecord,\r\n DrawingChangeTimestamp,\r\n DrawingContainerType,\r\n} from './constants'\r\n\r\nexport function getContainerTypeFromPaneConfig(pane: ChartConfigChartPane) {\r\n const indicatorElement = pane.elements.find((el) => el.type.startsWith('indicators/'))\r\n if (indicatorElement) {\r\n return indicatorElement.type as DrawingContainerType\r\n }\r\n const chartElement = pane.elements.find((el) => el.type.startsWith('charts/'))\r\n if (chartElement) {\r\n return 'chart'\r\n }\r\n return null\r\n}\r\n\r\nexport function getContainerType(model: PaneModel) {\r\n const mainElement = model.mainElement()\r\n const indicatorType = mainElement?.instance?.type ?? null\r\n if (mainElement?.isIndicator() && indicatorType !== IndicatorType.None) {\r\n return indicatorType as DrawingContainerType\r\n }\r\n if (mainElement?.isChart()) {\r\n return 'chart'\r\n }\r\n return null\r\n}\r\n\r\nexport function updateInternalStoreWithChangedElement({\r\n element,\r\n changeType,\r\n currentInternalStore,\r\n lastUpdateTimestamp,\r\n}: {\r\n element: Element\r\n changeType: AutoSaveChangeType\r\n currentInternalStore: AutoSaveElement[]\r\n lastUpdateTimestamp: HLC\r\n}) {\r\n const paneModel = element.pane()\r\n const ticker = paneModel.getQuoteRawTicker()\r\n const containerType = getContainerType(paneModel)\r\n if (ticker && paneModel && containerType && (!element.destroyed || changeType === 'destroy')) {\r\n const instanceJson = element.instance.toAutosaveConfig()\r\n const newDrawing: AutoSaveElement = {\r\n elementId: element.elementId!,\r\n zIndex: element.zIndex,\r\n ticker,\r\n lastChange: lastUpdateTimestamp,\r\n changeType,\r\n containerType,\r\n elementAttrs: JSON.stringify(instanceJson),\r\n }\r\n\r\n const newInternalStore = [...currentInternalStore]\r\n const updateDrawingIndex = newInternalStore.findIndex(\r\n (drawingElement) => drawingElement.elementId === newDrawing.elementId\r\n )\r\n\r\n let shouldSyncAndSave = false\r\n if (updateDrawingIndex > -1) {\r\n const updatedRecord = newInternalStore[updateDrawingIndex]\r\n const hasChangedZIndex = updatedRecord.zIndex !== newDrawing.zIndex\r\n const hasChangedType = updatedRecord.changeType !== newDrawing.changeType\r\n const hasChangedAttrs = updatedRecord.elementAttrs !== newDrawing.elementAttrs\r\n const hasChange = hasChangedType || hasChangedAttrs || hasChangedZIndex\r\n if (\r\n !element.instance.isEditInProgress &&\r\n updatedRecord.ticker === ticker &&\r\n hasChange &&\r\n updatedRecord.changeType !== 'destroy'\r\n ) {\r\n newInternalStore[updateDrawingIndex] = newDrawing\r\n shouldSyncAndSave = true\r\n }\r\n } else {\r\n newInternalStore.push(newDrawing)\r\n shouldSyncAndSave = true\r\n }\r\n\r\n return {\r\n newInternalStore,\r\n shouldSyncAndSave,\r\n newDrawing,\r\n }\r\n }\r\n}\r\n\r\nexport function getTickersAndContainerTypesInLayoutModel(chartLayout: ChartLayout) {\r\n const tickers: string[] = []\r\n const containerTypes: Array = ['note']\r\n\r\n chartLayout.getAllPanes().forEach((paneModel) => {\r\n const ticker = paneModel.getQuoteRawTicker()\r\n const containerType = getContainerType(paneModel)\r\n if (ticker && !tickers.includes(ticker)) {\r\n tickers.push(ticker)\r\n }\r\n if (containerType && !containerTypes.includes(containerType)) {\r\n containerTypes.push(containerType)\r\n }\r\n })\r\n return { tickers, containerTypes }\r\n}\r\n\r\nexport function mergeUpdatedDrawingsToInternalStore({\r\n updatedDrawings,\r\n currentInternalStore,\r\n lastUpdateTimestamp,\r\n isRefetchAll,\r\n}: {\r\n updatedDrawings: AutoSaveElement[]\r\n currentInternalStore: AutoSaveElement[]\r\n lastUpdateTimestamp: DrawingChangeTimestamp\r\n isRefetchAll: boolean\r\n}) {\r\n let newLastUpdateTimestamp = lastUpdateTimestamp\r\n const newInternalStore = [...currentInternalStore]\r\n const updatedElementIds: string[] = []\r\n\r\n updatedDrawings.forEach((drawing) => {\r\n newLastUpdateTimestamp = receiveHlc(newLastUpdateTimestamp, drawing.lastChange)\r\n const drawingIndex = newInternalStore.findIndex(({ elementId }) => drawing.elementId === elementId)\r\n const currentDrawing = drawingIndex > -1 ? newInternalStore[drawingIndex] : null\r\n if (currentDrawing === null) {\r\n newInternalStore.push(drawing)\r\n updatedElementIds.push(drawing.elementId)\r\n } else if (currentDrawing.containerType === 'note' && isRefetchAll) {\r\n const currentNote = getElementNoteText(currentDrawing)\r\n const autoSavedNote = getElementNoteText(drawing)\r\n if (currentNote !== autoSavedNote) {\r\n newInternalStore[drawingIndex] = {\r\n ...drawing,\r\n lastChange: incrementHlc(receiveHlc(currentDrawing.lastChange, drawing.lastChange), Date.now()),\r\n elementAttrs: JSON.stringify({\r\n ...JSON.parse(drawing.elementAttrs),\r\n text: `${currentNote}\\r\\n${autoSavedNote}`,\r\n }),\r\n }\r\n }\r\n updatedElementIds.push(drawing.elementId)\r\n } else if (compareHlc(newInternalStore[drawingIndex].lastChange, drawing.lastChange) < 0) {\r\n newInternalStore[drawingIndex] = drawing\r\n updatedElementIds.push(drawing.elementId)\r\n }\r\n })\r\n return { newLastUpdateTimestamp, newInternalStore, updatedElementIds }\r\n}\r\n\r\nexport function getInitialStoreDrawings(): null | AutoSaveElement[] {\r\n const initialDrawings = (\r\n window.FinvizSettings?.initialDrawingsStore ?? window.FinvizChartsSettings?.initialDrawingsStore\r\n )?.drawings as null | AutoSaveElementDBRecord[]\r\n\r\n return initialDrawings?.map((item) => getAutosaveElementFromDBRecord(item)) ?? null\r\n}\r\n\r\nexport function handleCallMethodOnAllDrawings({\r\n chartLayoutModel,\r\n elementMethod,\r\n}: {\r\n chartLayoutModel: ChartLayout\r\n elementMethod: keyof Pick\r\n}) {\r\n chartLayoutModel.getAllElements().forEach((element) => {\r\n if (element.isDrawing()) {\r\n element[elementMethod]()\r\n }\r\n })\r\n}\r\n\r\nexport function getNoteElementId(ticker: string) {\r\n return `note-${ticker}`\r\n}\r\n\r\nexport function getElementNoteText(noteElement?: AutoSaveElement) {\r\n return (noteElement ? JSON.parse(noteElement.elementAttrs)?.text : '') ?? ''\r\n}\r\n\r\nexport function getTickerNoteText({ ticker, elements }: { ticker: string; elements: AutoSaveElement[] }) {\r\n const noteElement = elements.find(({ elementId }) => elementId === getNoteElementId(ticker))\r\n return getElementNoteText(noteElement)\r\n}\r\n\r\nexport function getAutosaveElementFromDBRecord(item: AutoSaveElementDBRecord): AutoSaveElement {\r\n return {\r\n elementId: item.elementId,\r\n ticker: item.ticker,\r\n zIndex: item.zIndex,\r\n changeType: item.changeType,\r\n containerType: item.containerType,\r\n elementAttrs: item.elementAttrs,\r\n lastChange: {\r\n ts: item.lastChangeTimestamp,\r\n count: item.lastChangeCounter,\r\n uuid: item.lastChangeNodeUUID,\r\n },\r\n }\r\n}\r\n\r\nexport function getDBRecordFromAutosaveElement(item: AutoSaveElement): Omit {\r\n return {\r\n elementId: item.elementId,\r\n ticker: item.ticker,\r\n zIndex: item.zIndex,\r\n changeType: item.changeType,\r\n containerType: item.containerType,\r\n elementAttrs: JSON.stringify(item.elementAttrs),\r\n lastChangeTimestamp: item.lastChange.ts,\r\n lastChangeCounter: item.lastChange.count,\r\n lastChangeNodeUUID: item.lastChange.uuid,\r\n }\r\n}\r\n","import { IndicatorType } from '../../constants/common'\r\nimport { HLC } from '../../utils/hlc'\r\n\r\nexport type DrawingChangeTimestamp = HLC\r\nexport type DrawingContainerType = IndicatorType | 'chart' | 'note' | null\r\nexport type AutoSaveChangeType = 'update' | 'destroy'\r\n\r\nexport interface AutoSaveElement {\r\n elementId: string\r\n ticker: string\r\n zIndex: number\r\n lastChange: DrawingChangeTimestamp\r\n changeType: AutoSaveChangeType\r\n containerType: DrawingContainerType\r\n elementAttrs: string\r\n}\r\n\r\nexport type AutoSaveElementDBRecord = Omit & { lastChange: string } & {\r\n lastChangeTimestamp: number\r\n lastChangeCounter: number\r\n lastChangeNodeUUID: string\r\n}\r\n\r\nexport const DRAWINGS_UPDATE_INTERVAL_MS = process.env.IS_E2E_TESTING ? 3000 : 15000\r\nexport const DRAWINGS_SAVE_INTERVAL_MS = 250\r\n","import { Notification, Paragraph, useNotification } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport fetchApi, {\r\n ContentType,\r\n ForbiddenError,\r\n GenericStatusCodeError,\r\n GoneError,\r\n InternalServerError,\r\n} from '../../utils/fetch_api'\r\nimport { HLC, compareHlc, incrementHlc } from '../../utils/hlc'\r\nimport { getByteLengthOfString } from '../../utils/string-byte-length'\r\nimport { AutoSaveElement, AutoSaveElementDBRecord, DrawingContainerType } from './constants'\r\nimport { getAutosaveElementFromDBRecord, getDBRecordFromAutosaveElement } from './utils'\r\n\r\nconst RETRY_LIMIT = 5\r\n\r\nexport function useDrawingAutoSaveApi() {\r\n const postRetryCountRef = React.useRef(0)\r\n const deleteRetryCountRef = React.useRef(0)\r\n const notificationContext = useNotification()\r\n\r\n const fetchDrawings = React.useCallback(\r\n async ({\r\n tickers,\r\n containerTypes,\r\n lastChange,\r\n }: {\r\n tickers: string[]\r\n containerTypes: DrawingContainerType[]\r\n lastChange: HLC\r\n }) => {\r\n try {\r\n const data = await fetchApi<{\r\n drawings: AutoSaveElementDBRecord[]\r\n }>({\r\n location: '/api/auto_save.ashx',\r\n queryParameters: {\r\n ticker: tickers.join(','),\r\n containerTypes: containerTypes.join(',') || undefined,\r\n lastChangeTimestamp: lastChange.ts,\r\n lastChangeCounter: lastChange.count,\r\n lastChangeNodeUUID: lastChange.uuid,\r\n },\r\n throwOnStatusCodes: [403, 404],\r\n })\r\n return data.drawings.map((drawing) => getAutosaveElementFromDBRecord(drawing))\r\n } catch {\r\n // ignore error\r\n }\r\n\r\n return []\r\n },\r\n []\r\n )\r\n\r\n const saveDrawings = React.useCallback(\r\n async (drawings: AutoSaveElement[]): Promise => {\r\n if (drawings.length === 0) {\r\n return undefined\r\n }\r\n\r\n try {\r\n const bodyJsonString = JSON.stringify(drawings.map((item) => getDBRecordFromAutosaveElement(item)))\r\n let keepalive = false\r\n try {\r\n keepalive = getByteLengthOfString(bodyJsonString) < 64000\r\n } catch (error: any) {\r\n window.Sentry?.captureException(error)\r\n }\r\n await fetchApi({\r\n location: '/api/auto_save.ashx',\r\n method: 'POST',\r\n throwOnStatusCodes: [400, 403, 404, 410, 500],\r\n contentType: ContentType.ApplicationJson,\r\n body: bodyJsonString,\r\n keepalive,\r\n })\r\n const [latestChangeHlc] = [...drawings].sort((a, b) => compareHlc(b.lastChange, a.lastChange))\r\n postRetryCountRef.current = 0\r\n return latestChangeHlc.lastChange\r\n } catch (error) {\r\n if (error instanceof InternalServerError) {\r\n // try again\r\n if (postRetryCountRef.current < RETRY_LIMIT) {\r\n postRetryCountRef.current = postRetryCountRef.current + 1\r\n await new Promise((r) => setTimeout(r, 1000))\r\n return saveDrawings(drawings)\r\n } else {\r\n // continue to report to Sentry\r\n postRetryCountRef.current = 0\r\n }\r\n } else if (error instanceof ForbiddenError) {\r\n // ignore error\r\n return undefined\r\n } else if (error instanceof GoneError) {\r\n const newTicker = (error.response as ObjectHash).newTicker\r\n const message = newTicker\r\n ? `Ticker \"${drawings[0].ticker}\" was renamed to \"${newTicker}\"`\r\n : `Ticker \"${drawings[0].ticker}\" no longer exists.`\r\n notificationContext.show(\r\n } timeoutInMs={6000}>\r\n {message}\r\n \r\n )\r\n return undefined\r\n }\r\n\r\n // report error to Sentry\r\n window.Sentry?.captureException(error, {\r\n extra: (error instanceof GenericStatusCodeError\r\n ? (error.response as ObjectHash).invalidItems\r\n : drawings\r\n ).reduce(\r\n (acc: ObjectHash, cur: ObjectHash, index: number) => ({ ...acc, [`item-${index}`]: JSON.stringify(cur) }),\r\n {} as ObjectHash\r\n ),\r\n })\r\n\r\n return undefined\r\n }\r\n },\r\n [notificationContext]\r\n )\r\n\r\n const deleteAllDrawings = React.useCallback(\r\n async ({ tickers, lastLocalChange }: { tickers: string[]; lastLocalChange: HLC }): Promise => {\r\n try {\r\n const newHlc = incrementHlc(lastLocalChange, Date.now())\r\n await fetchApi({\r\n location: `/api/auto_save.ashx?ticker=${tickers.join(',')}&lastChangeTimestamp=${\r\n newHlc.ts\r\n }&lastChangeCounter=${newHlc.count}&lastChangeNodeUUID=${newHlc.uuid}`,\r\n method: 'DELETE',\r\n throwOnStatusCodes: [403, 404, 500],\r\n keepalive: true,\r\n })\r\n deleteRetryCountRef.current = 0\r\n } catch (error) {\r\n if (error instanceof InternalServerError) {\r\n // try again\r\n if (deleteRetryCountRef.current < RETRY_LIMIT) {\r\n deleteRetryCountRef.current = deleteRetryCountRef.current + 1\r\n await new Promise((r) => setTimeout(r, 1000))\r\n return deleteAllDrawings({ tickers, lastLocalChange })\r\n } else {\r\n // continue to report to Sentry\r\n deleteRetryCountRef.current = 0\r\n }\r\n } else if (error instanceof ForbiddenError) {\r\n // ignore error\r\n return\r\n }\r\n\r\n // report error to Sentry\r\n window.Sentry?.captureException(error)\r\n }\r\n },\r\n []\r\n )\r\n\r\n return { fetchDrawings, saveDrawings, deleteAllDrawings }\r\n}\r\n","// byteLengthCharCode2 from https://stackoverflow.com/a/63893237\r\n\r\nexport function getByteLengthOfString(s: string) {\r\n //assuming the String is UCS-2(aka UTF-16) encoded\r\n let n = 0\r\n for (let i = 0, l = s.length; i < l; i++) {\r\n const hi = s.charCodeAt(i)\r\n if (hi < 0x0080) {\r\n n += 1\r\n } else if (hi < 0x0800) {\r\n n += 2\r\n } else if (hi < 0xd800) {\r\n n += 3\r\n } else if (hi < 0xdc00) {\r\n const lo = s.charCodeAt(++i)\r\n if (i < l && lo >= 0xdc00 && lo <= 0xdfff) {\r\n n += 4\r\n } else {\r\n throw new Error('UCS-2 String malformed')\r\n }\r\n } else if (hi < 0xe000) {\r\n throw new Error('UCS-2 String malformed')\r\n } else {\r\n n += 3\r\n }\r\n }\r\n return n\r\n}\r\n","import React from 'react'\r\n\r\nimport { DrawingSpineOptions, DrawingSpineOptionsEvent } from '../../../types/shared'\r\nimport ElementCanvas from '../../canvas/element'\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport { getCanvasElementByType } from '../../helpers/get-canvas-element-by-type'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { AutoSaveState } from '../../models/constants'\r\nimport Element from '../../models/element'\r\nimport { compareHlc, incrementHlc, initHlc, receiveHlc } from '../../utils/hlc'\r\nimport { AutoSaveChangeType, AutoSaveElement, DRAWINGS_SAVE_INTERVAL_MS } from './constants'\r\nimport { useDrawingAutoSaveApi } from './use-drawing-autosave-api'\r\nimport { useIsAutoSaveActive } from './use-is-auto-save-active'\r\nimport {\r\n getContainerType,\r\n getNoteElementId,\r\n getTickerNoteText,\r\n getTickersAndContainerTypesInLayoutModel,\r\n mergeUpdatedDrawingsToInternalStore,\r\n updateInternalStoreWithChangedElement,\r\n} from './utils'\r\n\r\nexport function useDrawingAutoSaveControls(chartLayout: ChartLayout) {\r\n const { fetchDrawings, saveDrawings, deleteAllDrawings } = useDrawingAutoSaveApi()\r\n const isAutoSaveActive = useIsAutoSaveActive(chartLayout)\r\n const drawingsInternalStore = React.useMemo(() => chartLayout.drawingsInternalStore(), [chartLayout])\r\n const saveTimeoutRef = React.useRef()\r\n\r\n React.useEffect(\r\n () => () => {\r\n if (saveTimeoutRef.current) {\r\n clearTimeout(saveTimeoutRef.current)\r\n }\r\n },\r\n []\r\n )\r\n\r\n const saveLatestChanges = React.useCallback(\r\n (\r\n withDelayInMs = DRAWINGS_SAVE_INTERVAL_MS,\r\n saveQueueExtraFilterCallback: ((item: AutoSaveElement) => boolean) | null = null\r\n ) => {\r\n if (saveTimeoutRef.current) {\r\n clearTimeout(saveTimeoutRef.current)\r\n }\r\n const saveQueue = drawingsInternalStore.elements.filter(\r\n (item) =>\r\n compareHlc(item.lastChange, drawingsInternalStore.latestLocalUpdateTimestamp) > 0 &&\r\n item.lastChange.uuid === drawingsInternalStore.instanceUUID &&\r\n (saveQueueExtraFilterCallback === null || saveQueueExtraFilterCallback(item))\r\n )\r\n if (saveQueue.length === 0) {\r\n return\r\n }\r\n\r\n drawingsInternalStore.setAutoSaveState(AutoSaveState.Unsaved)\r\n\r\n const save = async () => {\r\n drawingsInternalStore.setAutoSaveState(AutoSaveState.Saving)\r\n const result = await saveDrawings(saveQueue)\r\n if (result) {\r\n drawingsInternalStore.updateAttributes({\r\n latestLocalUpdateTimestamp: receiveHlc(drawingsInternalStore.latestLocalUpdateTimestamp, result),\r\n })\r\n }\r\n drawingsInternalStore.setAutoSaveState(AutoSaveState.Saved)\r\n\r\n return result\r\n }\r\n\r\n if (withDelayInMs === 0) {\r\n return save()\r\n }\r\n\r\n saveTimeoutRef.current = setTimeout(save, withDelayInMs)\r\n },\r\n [saveDrawings, drawingsInternalStore]\r\n )\r\n\r\n const syncChartLayoutDrawings = React.useCallback(\r\n (drawing: AutoSaveElement) => {\r\n if (drawing.containerType === 'note') {\r\n return\r\n }\r\n const isRemove = drawing.changeType === 'destroy'\r\n\r\n chartLayout.getAllPanes().forEach((paneModel) => {\r\n const ticker = paneModel.getQuoteRawTicker()\r\n const paneContainerType = getContainerType(paneModel)\r\n if (!paneContainerType || drawing.ticker !== ticker) {\r\n return\r\n }\r\n const paneInternalStoreElements = drawingsInternalStore.elements.filter(\r\n (autoSaveElement) => autoSaveElement.ticker === ticker && autoSaveElement.containerType === paneContainerType\r\n )\r\n const paneElements = paneModel.getAllElements()\r\n let element: Element | undefined\r\n paneElements.forEach((paneElement) => {\r\n if (paneElement.isDrawing() && !paneElement.instance.isCreator) {\r\n const paneDrawing = paneInternalStoreElements.find(({ elementId }) => elementId === paneElement.elementId)\r\n if (!paneDrawing || paneDrawing.changeType === 'destroy') {\r\n paneElement.destroyCascade()\r\n } else if (paneElement.elementId && paneElement.elementId === drawing.elementId) {\r\n element = paneElement\r\n }\r\n }\r\n })\r\n\r\n const parsedElementAttrs = JSON.parse(drawing.elementAttrs)\r\n if (element) {\r\n if (drawing.elementAttrs !== JSON.stringify(element.instance.toAutosaveConfig())) {\r\n if (element.pane().selection !== element.instance && !element.hasOngoingInteraction()) {\r\n element.instance.set(parsedElementAttrs)\r\n element.instance.updateScales()\r\n }\r\n }\r\n if (drawing.zIndex !== element.zIndex) {\r\n element.updateAttributes({ zIndex: drawing.zIndex })\r\n }\r\n if (isRemove || paneContainerType !== drawing.containerType) {\r\n element.destroyCascade()\r\n }\r\n } else if (!isRemove && paneContainerType === drawing.containerType) {\r\n const instance = getCanvasElementByType(parsedElementAttrs.type).fromObject(\r\n parsedElementAttrs,\r\n paneModel\r\n ) as ElementCanvas\r\n paneModel.elements().create({ elementId: drawing.elementId, instance, zIndex: drawing.zIndex })\r\n instance.updateScales()\r\n }\r\n })\r\n },\r\n [chartLayout, drawingsInternalStore]\r\n )\r\n\r\n const handleAutoSaveNoteChange = React.useCallback(\r\n (note: string, ticker?: string) => {\r\n if (ticker) {\r\n const newNoteElement: AutoSaveElement = {\r\n elementId: getNoteElementId(ticker),\r\n zIndex: 0,\r\n ticker: ticker,\r\n lastChange: incrementHlc(drawingsInternalStore.latestLocalUpdateTimestamp, Date.now()),\r\n changeType: 'update',\r\n containerType: 'note',\r\n elementAttrs: JSON.stringify({ text: note }),\r\n }\r\n\r\n drawingsInternalStore.updateAttributes({\r\n elements: [\r\n ...drawingsInternalStore.elements.filter(({ elementId }) => elementId !== newNoteElement.elementId),\r\n newNoteElement,\r\n ],\r\n })\r\n }\r\n },\r\n [drawingsInternalStore]\r\n )\r\n\r\n const handleIdeaNoteChange = React.useCallback(\r\n (note: string) => {\r\n if (chartLayout.idea?.note !== note && (chartLayout.idea || note)) {\r\n chartLayout.updateAttribute('idea', { ...chartLayout.idea, note })\r\n handleAutoSaveNoteChange(note, chartLayout.activeChart?.getQuoteRawTicker() ?? undefined)\r\n }\r\n },\r\n [chartLayout, handleAutoSaveNoteChange]\r\n )\r\n\r\n const checkDrawingUpdate = React.useCallback(\r\n async (isRefetchAll = false) => {\r\n const { tickers, containerTypes } = getTickersAndContainerTypesInLayoutModel(chartLayout)\r\n if (isRefetchAll) {\r\n drawingsInternalStore.updateAttributes({\r\n latestRemoteUpdateTimestamp: initHlc(drawingsInternalStore.instanceUUID, 0),\r\n })\r\n }\r\n\r\n const updatedDrawings = await fetchDrawings({\r\n tickers,\r\n containerTypes,\r\n lastChange: drawingsInternalStore.latestRemoteUpdateTimestamp,\r\n })\r\n const { newLastUpdateTimestamp, updatedElementIds, newInternalStore } = mergeUpdatedDrawingsToInternalStore({\r\n updatedDrawings,\r\n currentInternalStore: drawingsInternalStore.elements,\r\n lastUpdateTimestamp: drawingsInternalStore.latestRemoteUpdateTimestamp,\r\n isRefetchAll,\r\n })\r\n\r\n drawingsInternalStore.updateAttributes({\r\n // Even if there are no changes in elements, newInternalStore is new array with the same content which may cause unnecessary rerenders\r\n ...(updatedElementIds.length > 0 ? { elements: newInternalStore } : {}),\r\n latestRemoteUpdateTimestamp: newLastUpdateTimestamp,\r\n latestLocalUpdateTimestamp:\r\n isRefetchAll && newInternalStore.length > 0\r\n ? receiveHlc(drawingsInternalStore.latestLocalUpdateTimestamp, newLastUpdateTimestamp)\r\n : drawingsInternalStore.latestLocalUpdateTimestamp,\r\n })\r\n\r\n if (updatedElementIds.length > 0 || isRefetchAll) {\r\n saveLatestChanges(0)\r\n const allElements = chartLayout.getAllElements()\r\n updatedElementIds.forEach((elementId) => {\r\n const element = allElements.find((element) => element.elementId === elementId)\r\n\r\n if (element && element.isDrawing() && !element.hasOngoingInteraction()) {\r\n element.destroyCascade()\r\n }\r\n })\r\n\r\n drawingsInternalStore.elements.forEach(syncChartLayoutDrawings)\r\n chartLayout.getAllPanes().forEach((paneModel) => {\r\n paneModel.normalizeZIndexes()\r\n })\r\n\r\n if (chartLayout.specificChartFunctionality === SpecificChartFunctionality.quotePage) {\r\n const activeTicker = chartLayout.activeChart?.getQuoteRawTicker() ?? ''\r\n handleIdeaNoteChange(getTickerNoteText({ ticker: activeTicker, elements: newInternalStore }))\r\n }\r\n }\r\n },\r\n [\r\n chartLayout,\r\n drawingsInternalStore,\r\n syncChartLayoutDrawings,\r\n fetchDrawings,\r\n handleIdeaNoteChange,\r\n saveLatestChanges,\r\n ]\r\n )\r\n\r\n const updateInternalStoreWithElement = React.useCallback(\r\n (element: Element, changeType: AutoSaveChangeType) => {\r\n const updateResult = updateInternalStoreWithChangedElement({\r\n element,\r\n changeType,\r\n currentInternalStore: drawingsInternalStore.elements,\r\n lastUpdateTimestamp: incrementHlc(\r\n receiveHlc(\r\n drawingsInternalStore.latestLocalUpdateTimestamp,\r\n drawingsInternalStore.latestRemoteUpdateTimestamp\r\n ),\r\n Date.now()\r\n ),\r\n })\r\n\r\n if (updateResult) {\r\n const { shouldSyncAndSave, newInternalStore, newDrawing } = updateResult\r\n if (shouldSyncAndSave) {\r\n drawingsInternalStore.updateAttributes({ elements: newInternalStore })\r\n syncChartLayoutDrawings(newDrawing)\r\n }\r\n }\r\n },\r\n [syncChartLayoutDrawings, drawingsInternalStore]\r\n )\r\n\r\n const deleteAllAutoSavedElements = React.useCallback(async () => {\r\n const { tickers } = getTickersAndContainerTypesInLayoutModel(chartLayout)\r\n\r\n await deleteAllDrawings({ tickers, lastLocalChange: drawingsInternalStore.latestLocalUpdateTimestamp })\r\n await checkDrawingUpdate()\r\n }, [chartLayout, deleteAllDrawings, drawingsInternalStore, checkDrawingUpdate])\r\n\r\n const onElementChange = React.useCallback(\r\n (element: Element, _?: any, options?: DrawingSpineOptions) => {\r\n const elementPane = element.pane()\r\n // This may happen if pane had been removed already, in most cases \"element.destroyed\" should be true,\r\n // but we would need to check if it was destroyed by delete drawing action or not, and checking if pane exists covers all cases\r\n if (!element.isDrawing() || element.instance.isCreator || !elementPane) {\r\n return\r\n }\r\n const elementContainerType = getContainerType(elementPane)\r\n const elementPaneTicker = elementPane.getQuoteRawTicker()\r\n const isElementInCurrentChartLayout = chartLayout\r\n .getAllPanes()\r\n .some(\r\n (model) => getContainerType(model) === elementContainerType && model.getQuoteRawTicker() === elementPaneTicker\r\n )\r\n if (isElementInCurrentChartLayout) {\r\n const isRemove = options?.eventType === DrawingSpineOptionsEvent.Remove\r\n updateInternalStoreWithElement(element, isRemove ? 'destroy' : 'update')\r\n }\r\n },\r\n [updateInternalStoreWithElement, chartLayout]\r\n )\r\n\r\n return {\r\n drawingsInternalStore,\r\n onElementChange,\r\n handleIdeaNoteChange,\r\n deleteAllAutoSavedElements,\r\n isAutoSaveActive,\r\n handleAutoSaveNoteChange,\r\n syncChartLayoutDrawings,\r\n saveLatestChanges,\r\n checkDrawingUpdate,\r\n }\r\n}\r\n","import React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { getIsPreserveDrawingsAndAutosaveAvailable } from '../../utils/chart'\r\n\r\nexport function useIsAutoSaveActive(chartLayout: ChartLayout) {\r\n const chartLayoutModel = useModelState(chartLayout, {\r\n watchProperties: ['isInit', 'isPreserveDrawingsActive', 'idea'],\r\n })\r\n const { idea, isInit, isPreserveDrawingsActive } = chartLayoutModel\r\n return React.useMemo(\r\n () =>\r\n getIsPreserveDrawingsAndAutosaveAvailable(chartLayoutModel) && isPreserveDrawingsActive && !!isInit && !idea?.id,\r\n [isPreserveDrawingsActive, isInit, idea?.id, chartLayoutModel]\r\n )\r\n}\r\n","import React from 'react'\r\n\r\nimport { CustomSpineEvents } from '../../../types/shared'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartModel from '../../models/chart'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { AutoSaveState } from '../../models/constants'\r\nimport Element from '../../models/element'\r\nimport { usePrevious } from '../../utils/use-prev-state'\r\nimport { DRAWINGS_UPDATE_INTERVAL_MS } from './constants'\r\nimport { useDrawingAutoSaveControls } from './use-drawing-auto-save-controls'\r\nimport { getTickersAndContainerTypesInLayoutModel } from './utils'\r\n\r\nfunction useDrawingAutoSave(chartLayout: ChartLayout) {\r\n const {\r\n onElementChange,\r\n deleteAllAutoSavedElements,\r\n checkDrawingUpdate,\r\n syncChartLayoutDrawings,\r\n saveLatestChanges,\r\n isAutoSaveActive,\r\n } = useDrawingAutoSaveControls(chartLayout)\r\n\r\n const drawingsInternalStoreUnwatched = React.useMemo(() => chartLayout.drawingsInternalStore(), [chartLayout])\r\n const drawingsInternalStore = useModelState(drawingsInternalStoreUnwatched, { watchProperties: ['elements'] })\r\n const prevIsAutoSaveActive = usePrevious(isAutoSaveActive)\r\n\r\n const runInitialSaveAndRefetchUpdate = React.useCallback(async () => {\r\n chartLayout.getAllElements().forEach((element) => {\r\n // Adds drawings to internal store if isAutoSaveActive and they are not in the store yet\r\n if (!drawingsInternalStore.elements.some((drawing) => drawing.elementId === element.elementId)) {\r\n onElementChange(element)\r\n }\r\n })\r\n\r\n // We want to save everything except notes because saving notes can overwrite those already saved in db. Each drawing has different id but there is only one note per ticker\r\n // Notes are merged in checkDrawingUpdate fn\r\n await saveLatestChanges(0, (item) => item.containerType !== 'note')\r\n\r\n checkDrawingUpdate(true)\r\n }, [checkDrawingUpdate, chartLayout, onElementChange, drawingsInternalStore.elements, saveLatestChanges])\r\n\r\n React.useEffect(() => {\r\n if (isAutoSaveActive) {\r\n saveLatestChanges()\r\n }\r\n }, [saveLatestChanges, drawingsInternalStore.elements, isAutoSaveActive])\r\n\r\n React.useEffect(() => {\r\n if (!isAutoSaveActive) {\r\n chartLayout.drawingsInternalStore().setAutoSaveState(AutoSaveState.Off)\r\n return\r\n }\r\n chartLayout.drawingsInternalStore().setAutoSaveState(AutoSaveState.Saved)\r\n if (!prevIsAutoSaveActive && isAutoSaveActive) {\r\n runInitialSaveAndRefetchUpdate()\r\n }\r\n\r\n let { tickers, containerTypes } = getTickersAndContainerTypesInLayoutModel(chartLayout)\r\n\r\n const onChartOrIndicatorChange = () => {\r\n const { tickers: newTickers, containerTypes: newContainerTypes } =\r\n getTickersAndContainerTypesInLayoutModel(chartLayout)\r\n if (\r\n JSON.stringify(tickers) !== JSON.stringify(newTickers) ||\r\n JSON.stringify(containerTypes) !== JSON.stringify(newContainerTypes)\r\n ) {\r\n tickers = newTickers\r\n containerTypes = newContainerTypes\r\n checkDrawingUpdate(true)\r\n }\r\n }\r\n\r\n ChartModel.bind(`${CustomSpineEvents.IndicatorsChange} change`, onChartOrIndicatorChange)\r\n Element.bind('change', onElementChange)\r\n\r\n drawingsInternalStore.elements.forEach(syncChartLayoutDrawings)\r\n const checkDrawingUpdateInterval = setInterval(checkDrawingUpdate, DRAWINGS_UPDATE_INTERVAL_MS)\r\n\r\n return () => {\r\n clearInterval(checkDrawingUpdateInterval)\r\n ChartModel.unbind(`${CustomSpineEvents.IndicatorsChange} change`, onChartOrIndicatorChange)\r\n Element.unbind('change', onElementChange)\r\n }\r\n }, [\r\n chartLayout,\r\n drawingsInternalStore,\r\n checkDrawingUpdate,\r\n onElementChange,\r\n syncChartLayoutDrawings,\r\n isAutoSaveActive,\r\n prevIsAutoSaveActive,\r\n runInitialSaveAndRefetchUpdate,\r\n ])\r\n\r\n return { deleteAllAutoSavedElements, isAutoSaveActive }\r\n}\r\n\r\ninterface Props {\r\n chartLayoutModel: ChartLayout\r\n}\r\n\r\nexport const withDrawingsAutoSave = (Component: any) => (props: Props) => {\r\n const { deleteAllAutoSavedElements, isAutoSaveActive } = useDrawingAutoSave(props.chartLayoutModel)\r\n\r\n return (\r\n \r\n )\r\n}\r\n","import React from 'react'\r\n\r\nexport function usePrevious(value: any) {\r\n const ref = React.useRef()\r\n React.useEffect(() => {\r\n ref.current = value\r\n }, [value])\r\n return ref.current\r\n}\r\n","import omit from 'lodash.omit'\r\nimport queryString from 'query-string'\r\n\r\nimport { Instrument, ObjectHash } from '../../../types/shared'\r\nimport { LayoutType } from '../../constants/common'\r\nimport { getTickerNoteText } from '../../controllers/autosave/utils'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport Quote from '../../models/quote'\r\nimport fetchApi, { getFormDataFromObject } from '../../utils/fetch_api'\r\nimport { captureException } from '../../utils/helpers'\r\n\r\nexport interface IIdea {\r\n ticker: string\r\n instrument: string\r\n period: string\r\n company?: string\r\n date: string\r\n time: string\r\n note: string\r\n id: string\r\n}\r\n\r\nexport interface IIdeaCategory {\r\n ticker: string\r\n ideas: IIdea[]\r\n}\r\n\r\nexport function getIdeaUrl({ ticker, instrument, period, id }: Pick) {\r\n const searchObject = { t: ticker, p: period, i: id }\r\n const isStock = instrument === Instrument.Stock\r\n const isQuotePage = /\\/quote\\b/.test(window.location.pathname)\r\n const isStockOnQute = isQuotePage && isStock\r\n const path = !isQuotePage || isStock ? window.location.pathname : '/charts.ashx'\r\n\r\n return `${path}?${queryString.stringify({ ...searchObject, ...(isStockOnQute ? { ta: '2' } : { l: '1h1v' }) })}`\r\n}\r\n\r\nexport async function saveIdea(layoutModel: ChartLayout) {\r\n const activeChart = layoutModel.activeChart\r\n const activeChartQuote = activeChart.quote().toJSON()\r\n const { ticker, instrument, cid } = activeChart\r\n const period = activeChartQuote.timeframe\r\n const { ChartSettings } = layoutModel.settings\r\n const layout: ObjectHash = layoutModel.toObject()\r\n layout.layout = LayoutType['1h1v']\r\n layout.barWidth = ChartSettings.center.barWidth\r\n layout.barMargin = ChartSettings.center.barMargin\r\n layout.charts = layout.charts\r\n .filter((c: ObjectHash) => c.chartId === cid)\r\n .map((c: ObjectHash) => ({ ...c, dateRange: null, refreshData: false }))\r\n\r\n delete layout.charts[0].chartId\r\n\r\n // TODO: replace with better solution after indicators overhaul\r\n const getChartTickers = (layoutModelObjectPanes: { elements: { type: string; tickers: string }[] }[]) => {\r\n let tickers = []\r\n let tickersString = ''\r\n for (const pane of layoutModelObjectPanes) {\r\n for (const element of pane.elements) {\r\n if (element.type === 'indicators/perf') {\r\n tickersString = element.tickers\r\n }\r\n }\r\n }\r\n tickers = tickersString.split(',').filter((item) => item)\r\n if (!tickers.includes(ticker)) {\r\n tickers.push(ticker.replace('@', ''))\r\n }\r\n return tickers\r\n }\r\n const tickers = getChartTickers(layout.charts[0].panes)\r\n const quotes = Quote.select(\r\n (quote: Quote) =>\r\n tickers.includes(quote.ticker) && quote.timeframe === activeChart.timeframe && layoutModel.isIdeaId(quote.ideaID)\r\n ).filter((element, index, array) => array.findIndex((t) => t.ticker === element.ticker) === index)\r\n const quotesJsonString = JSON.stringify(quotes.map((q) => omit(q.toJSON(), ['ideaID', 'chartUuid'])))\r\n\r\n const chart = JSON.stringify(layout)\r\n const note =\r\n layoutModel.idea?.note ||\r\n getTickerNoteText({ ticker, elements: layoutModel.drawingsInternalStore().elements }) ||\r\n ''\r\n window.gtag?.('event', 'save', { event_category: 'ideas' })\r\n\r\n if (tickers.length !== quotes.length) {\r\n captureException(new Error('Idea saved with inconsistent quotes data'), {\r\n extra: {\r\n tickers,\r\n quoteTickersTimeframes: quotes.map((quote) => ({ ticker: quote.ticker, timeframe: quote.timeframe })),\r\n chartLayout: layoutModel.toConfig(['colors', 'panes']),\r\n },\r\n })\r\n }\r\n\r\n const data = await fetchApi<{ id: string }>({\r\n location: '/api/idea_save.ashx',\r\n method: 'POST',\r\n body: getFormDataFromObject({ ticker, period, chart, quotes: quotesJsonString, note }),\r\n })\r\n\r\n const ideaUrl = getIdeaUrl({\r\n ticker,\r\n period,\r\n instrument,\r\n id: data.id,\r\n })\r\n\r\n if (process.env.IS_E2E_TESTING) {\r\n window.location.href = ideaUrl\r\n } else {\r\n // need to be in setTimeout because Safari block any call to window.open made in async,\r\n // this is hack to force run window.open in main thread\r\n setTimeout(() => {\r\n window.open(ideaUrl, 'FinvizSavedIdea')\r\n })\r\n }\r\n}\r\n\r\nexport function categorizeIdeas(ideas: IIdea[], tickers: string[]) {\r\n if (ideas.length <= 0) return []\r\n\r\n const categorizedIdeas = ideas.reduce((processed, idea) => {\r\n const tickerIdeas = processed.find((i) => i.ticker === idea.ticker)\r\n\r\n if (tickerIdeas) {\r\n tickerIdeas.ideas.push(idea)\r\n } else if (tickers.includes(idea.ticker)) {\r\n processed.push({\r\n ticker: idea.ticker,\r\n ideas: [idea],\r\n })\r\n }\r\n\r\n return processed\r\n }, [] as IIdeaCategory[])\r\n categorizedIdeas.unshift({\r\n ticker: 'All Ideas',\r\n ideas: ideas,\r\n })\r\n\r\n return categorizedIdeas\r\n}\r\n","import { Button, Icon, decodeQueryString } from '@finviz/website'\r\nimport classNames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { ChartsOrQuotePageQueryParams, TIMEFRAME, TimeframeLabelShort } from '../../constants/common'\r\nimport { IIdea, getIdeaUrl } from './utils'\r\n\r\ntype IdeasListProps = {\r\n idea: IIdea\r\n onIdeaDeleted: (idea: IIdea) => void\r\n}\r\n\r\nexport default function IdeaItem({ idea, onIdeaDeleted }: IdeasListProps) {\r\n const [isDeleting, setIsDeleting] = React.useState(false)\r\n const [isConfirmDelete, setIsConfirmDelete] = React.useState(false)\r\n const { i: currentIdea } = decodeQueryString()\r\n\r\n const onDeleteIdeaClick = React.useRef(async (idea: IIdea) => {\r\n setIsDeleting(true)\r\n\r\n const body = [\r\n ['id', idea.id],\r\n ['ticker', idea.ticker],\r\n ['queryString', document.location.search],\r\n ['locationPathname', document.location.pathname],\r\n ['currentIdea', currentIdea],\r\n ]\r\n .map((row) => row.join('='))\r\n .join('&')\r\n\r\n const response = await fetch('/api/idea_delete.ashx', {\r\n body,\r\n headers: {\r\n 'Content-Type': 'application/x-www-form-urlencoded',\r\n },\r\n method: 'post',\r\n })\r\n\r\n if (currentIdea === String(idea.id)) {\r\n window.location.href = response.url\r\n return\r\n }\r\n\r\n // Check if the page was loaded with the idea which is going to be deleted here\r\n // If that's the case, refresh the page to remove idea data from the page so when user navigates back to idea page it shows idea 404\r\n const configIdeaId = window.FinvizChartsSettings?.ideaChart?.idea?.id ?? window.globalChartConfig?.idea?.id\r\n if (configIdeaId === idea.id) {\r\n window.location.reload()\r\n return\r\n }\r\n\r\n onIdeaDeleted(idea)\r\n })\r\n\r\n return (\r\n (document.location = getIdeaUrl(idea))}\r\n data-testid=\"charts-notice-idea-item\"\r\n >\r\n <>\r\n

\r\n

\r\n {idea.ticker}\r\n {idea.company && {idea.company}}\r\n

\r\n \r\n {idea.date}\r\n {idea.time}\r\n \r\n \r\n {TimeframeLabelShort[idea.period as TIMEFRAME]}\r\n \r\n \r\n {idea.note !== '' ? (\r\n

{idea.note}

\r\n ) : null}\r\n
\r\n\r\n ) => {\r\n ev.stopPropagation()\r\n setIsConfirmDelete(true)\r\n }}\r\n />\r\n \r\n\r\n {isConfirmDelete && (\r\n
\r\n
\r\n

\r\n Delete {idea.ticker} Idea from {idea.date}?\r\n

\r\n
\r\n\r\n
\r\n {\r\n setIsConfirmDelete(false)\r\n }}\r\n >\r\n Cancel\r\n \r\n {\r\n onDeleteIdeaClick.current(idea)\r\n }}\r\n >\r\n Delete\r\n \r\n
\r\n
\r\n )}\r\n \r\n )\r\n}\r\n","import { Badge, Tab, TabList, TabPanel, Tabs } from '@finviz/website'\r\nimport React from 'react'\r\nimport { useSearchParams } from 'react-router-dom'\r\n\r\nimport { getInstrument } from '../../utils/chart'\r\nimport fetchApi from '../../utils/fetch_api'\r\nimport IdeaItem from './IdeaItem'\r\nimport { IIdea, IIdeaCategory, categorizeIdeas } from './utils'\r\n\r\nexport default function IdeasTabs() {\r\n const [hasError, setHasError] = React.useState(false)\r\n const [hasFetched, setHasFetched] = React.useState(false)\r\n const [categorizedIdeas, setCategorizedIdeas] = React.useState([])\r\n const [params] = useSearchParams()\r\n const queryTickers = params.get('t')!.split(',') // there always be some t param defined\r\n\r\n React.useEffect(() => {\r\n async function fetchIdeas() {\r\n window.gtag?.('event', 'load', { event_category: 'ideas' })\r\n try {\r\n const data = await fetchApi({ location: '/api/ideas_load.ashx', throwOnStatusCodes: [404] })\r\n const ideas = data.ideas.map((idea: IIdea) => {\r\n const dateParts = idea.date.split(' ')\r\n return {\r\n ...idea,\r\n instrument: getInstrument(idea.ticker),\r\n date: dateParts[0].replace('-', ' ').replace('-', ', '),\r\n time: dateParts[1],\r\n }\r\n })\r\n\r\n setCategorizedIdeas(categorizeIdeas(ideas, queryTickers))\r\n setHasFetched(true)\r\n } catch {\r\n setHasError(true)\r\n }\r\n }\r\n\r\n fetchIdeas()\r\n\r\n // run only on mount\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n const handleIdeaDeleted = (idea: IIdea) => {\r\n setCategorizedIdeas((prev) => {\r\n const modifiedCategories = [...prev]\r\n\r\n // remove from specific ticker category\r\n const categoryIndex = modifiedCategories.findIndex((c) => c.ticker === idea.ticker)\r\n if (categoryIndex >= 0) {\r\n const updatedCategory = {\r\n ...modifiedCategories[categoryIndex],\r\n ideas: modifiedCategories[categoryIndex].ideas.filter((i) => i.ticker !== idea.ticker),\r\n }\r\n modifiedCategories[categoryIndex] = updatedCategory\r\n }\r\n\r\n // remove from all\r\n const updatedAll = {\r\n ...modifiedCategories[0],\r\n ideas: modifiedCategories[0].ideas.filter((i) => i.ticker !== idea.ticker),\r\n }\r\n modifiedCategories[0] = updatedAll\r\n\r\n // remove empty categories\r\n return modifiedCategories.filter((c) => c.ideas.length !== 0)\r\n })\r\n }\r\n\r\n if (!hasFetched || hasError) {\r\n return (\r\n
\r\n {hasError ? 'Unexpected error occurred, please refresh the page.' : 'Loading…'}\r\n
\r\n )\r\n }\r\n\r\n if (categorizedIdeas.length === 0) {\r\n return (\r\n \r\n No saved ideas.\r\n \r\n )\r\n }\r\n\r\n return (\r\n \r\n \r\n {categorizedIdeas.map((category) => (\r\n {category.ideas.length}}>\r\n {category.ticker}\r\n \r\n ))}\r\n \r\n {categorizedIdeas.map((category) => (\r\n \r\n
\r\n {category.ideas.map((idea) => (\r\n \r\n ))}\r\n
\r\n
\r\n ))}\r\n
\r\n )\r\n}\r\n","import { Dialog, DialogBody, DialogHeader, DialogStateReturn } from '@finviz/website'\r\n\r\nimport IdeasTabs from './IdeasTabs'\r\n\r\ntype IdeasDialogProps = {\r\n state: DialogStateReturn\r\n}\r\n\r\nexport default function IdeasDialog({ state }: IdeasDialogProps) {\r\n return (\r\n \r\n state.hide()}>Your Ideas\r\n \r\n \r\n \r\n \r\n )\r\n}\r\n","import {\r\n Button,\r\n ButtonComponentProps,\r\n ButtonProps,\r\n DialogTrigger,\r\n Dropdown,\r\n DropdownItem,\r\n Spinner,\r\n Tooltip,\r\n TooltipTrigger,\r\n useDialogState,\r\n useDropdownState,\r\n useTooltipState,\r\n} from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport IdeasDialog from '../../modals/ideas/Ideas'\r\nimport { saveIdea } from '../../modals/ideas/utils'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport Quote from '../../models/quote'\r\nimport { getIsMobileScreenSize } from '../../utils'\r\nimport { encodeQueryString } from '../../utils/query_string'\r\n\r\ninterface IdeaDropdownProps {\r\n model: ChartLayout\r\n rounding?: 'none' | 'regular'\r\n theme?: ButtonProps['theme']\r\n size?: ButtonProps['size']\r\n dropdownButtonClassName?: string\r\n}\r\n\r\nexport function IdeasDropdown({\r\n model,\r\n rounding,\r\n dropdownButtonClassName,\r\n ...props\r\n}: React.PropsWithChildren) {\r\n const tooltipState = useTooltipState({ placement: 'right-start' })\r\n const [isAnyQuoteLoading, setIsAnyQuoteLoading] = React.useState(false)\r\n const ref = React.useRef(null)\r\n const dialog = useDialogState()\r\n const dropdown = useDropdownState()\r\n const hideTooltip = tooltipState.hide\r\n\r\n const dropdownItemProps = isAnyQuoteLoading\r\n ? ({\r\n as: TooltipTrigger,\r\n state: tooltipState,\r\n } as ButtonComponentProps)\r\n : ({} as ButtonComponentProps)\r\n\r\n React.useEffect(() => {\r\n const checkIfAnyQuoteIsLoading = () => {\r\n const fetchingQuotes = Quote.select((quote) => quote.isFetching && quote.fetchedAt === -1)\r\n setIsAnyQuoteLoading(fetchingQuotes.length > 0)\r\n }\r\n\r\n Quote.bind('change', checkIfAnyQuoteIsLoading)\r\n return () => {\r\n Quote.unbind('change', checkIfAnyQuoteIsLoading)\r\n }\r\n }, [])\r\n\r\n React.useEffect(() => {\r\n if (!isAnyQuoteLoading || !dropdown.visible) {\r\n hideTooltip()\r\n }\r\n }, [isAnyQuoteLoading, dropdown.visible, hideTooltip])\r\n\r\n if (!window.FinvizSettings.hasUserPremium) {\r\n return (\r\n \r\n )\r\n }\r\n\r\n return (\r\n <>\r\n \r\n }\r\n >\r\n {\r\n if (isAnyQuoteLoading) {\r\n tooltipState.show()\r\n return\r\n }\r\n saveIdea(model)\r\n }}\r\n >\r\n Save idea\r\n \r\n \r\n Load idea\r\n \r\n \r\n \r\n {isAnyQuoteLoading && (\r\n \r\n
\r\n \r\n
\r\n \r\n Some data is still loading. Please wait.\r\n \r\n
\r\n )}\r\n \r\n )\r\n}\r\n","export const publishModalAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"modals-publish\" */ './module-entry'),\r\n cacheKey: 'modals-publish',\r\n}\r\n","import { Button, ButtonComponentProps, Delayed, DialogTrigger, Icon, Spinner, useDialogState } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { publishModalAsyncModule } from '../../modals/publish/async-modules'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { useAsyncModule } from '../../utils/async-modules-utils'\r\n\r\ninterface PublishProps extends Pick {\r\n model: ChartLayout\r\n}\r\n\r\nexport function Publish({ model, ...props }: React.PropsWithChildren) {\r\n const dialog = useDialogState()\r\n const [publishModalModule, { isLoading }] = useAsyncModule({\r\n ...publishModalAsyncModule,\r\n shouldLoadModule: dialog.visible,\r\n errorSeverity: 'medium',\r\n onError: () => dialog.hide(),\r\n })\r\n const PublishDialog = publishModalModule?.default\r\n const buttonProps = isLoading\r\n ? ({\r\n leftContent: (\r\n \r\n }\r\n >\r\n \r\n \r\n ),\r\n } as ButtonComponentProps)\r\n : ({\r\n as: DialogTrigger,\r\n state: dialog,\r\n leftContent: 'share',\r\n } as ButtonComponentProps)\r\n\r\n return (\r\n <>\r\n \r\n {PublishDialog && }\r\n \r\n )\r\n}\r\n","import {\r\n Button,\r\n ButtonSizeType,\r\n ButtonThemeType,\r\n Delayed,\r\n Icon,\r\n Spinner,\r\n TourDefinition,\r\n useTour,\r\n} from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport { getRequestFullscreen, isRedesignEnabled } from '../../utils'\r\nimport { encodeQueryString } from '../../utils/query_string'\r\n\r\nconst isPremium = window.FinvizSettings.hasUserPremium\r\n\r\n// If we need to update / discontinue some tour we can use skip flag on legacy version to ensure that it won't reset users tour but won't include it in new tours\r\nfunction getTour(page: SpecificChartFunctionality): TourDefinition[] {\r\n return [\r\n {\r\n id: 'chart-tour',\r\n steps: [\r\n {\r\n title: 'Chart Tour',\r\n body: 'Discover powerful Chart features in the 2-min tour to master your analysis of trading opportunities.',\r\n },\r\n ...(isPremium\r\n ? [\r\n {\r\n title: 'Scale the Timeline',\r\n body: 'Grab the timeline to zoom it in and out. Double-click the timeline to reset the scaling.',\r\n target: '[data-testid=\"chart-0-pane-0-zoomer\"]',\r\n },\r\n {\r\n title: 'Scale the Price Axis',\r\n body: 'Grab the Price Axis to zoom it in and out. Move the chart around freely in any direction when Price Axis has custom scale. Double-click the Price Axis to reset the scaling.',\r\n target: '[data-testid=\"chart-0-pane-0-scaler\"]',\r\n },\r\n {\r\n title: 'Drawing tools & settings',\r\n body: 'Pick any Drawing Tool to analyze the market. Tailor your drawing experience with additional settings.',\r\n target: '#toolbar',\r\n },\r\n {\r\n title: 'Fine-tune Drawings',\r\n body: 'Double-click on a chart drawing to tweak its color and style. Right-click on a drawing to access other options, such as changing its visibility, order, and more.',\r\n target: '[data-testid=\"chart-0-pane-0\"]',\r\n },\r\n ]\r\n : [\r\n {\r\n title: 'Enable Drawing mode',\r\n body: (\r\n <>\r\n \r\n Finviz*Elite\r\n {' '}\r\n subscribers get access a whole suite of drawing tools which allow them to draw on and annotate the\r\n chart.
\r\n While in drawing mode, you can also pan the chart, scale the timeline and price axis and much more.\r\n \r\n ),\r\n target: '[data-testid=\"quote-toggle-draw-btn\"]',\r\n placement: 'bottom-start',\r\n },\r\n ]),\r\n {\r\n title: 'Save your best Ideas',\r\n body: isPremium\r\n ? 'Besides your drawings being autosaved, you can manually save ideas that you wish to revisit later.'\r\n : 'Your drawings will be saved automatically, but you can also manually save ideas that you wish to revisit later.',\r\n target: '[data-testid=\"chart-toolbar-ideas\"]',\r\n placement: 'bottom-start',\r\n },\r\n ...(page === SpecificChartFunctionality.quotePage\r\n ? []\r\n : [\r\n {\r\n title: 'Chart Layouts & Charts Sync',\r\n body: 'Switch between Chart Layouts to view multiple charts on your screen. Synchronize Ticker, Timeframe or Crosshair position across your charts.',\r\n target: '[data-testid=\"chart-layout-layout\"]',\r\n },\r\n ]),\r\n ...(!getRequestFullscreen(document.documentElement) && page === SpecificChartFunctionality.chartPage\r\n ? []\r\n : [\r\n {\r\n title: 'Fullscreen mode',\r\n body:\r\n page === SpecificChartFunctionality.quotePage\r\n ? 'Open the chart in an expanded view for full-page display and split-screen charts.'\r\n : 'Toggle the window to fill your entire screen.',\r\n target: '[data-testid=\"chart-layout-fullscreen\"]',\r\n placement: page === SpecificChartFunctionality.chartPage ? 'bottom' : 'bottom-end',\r\n },\r\n ]),\r\n {\r\n title: 'Share chart',\r\n body: 'Share a chart together with your analysis and ideas.',\r\n target: '[data-testid=\"chart-toolbar-publish\"]',\r\n overlayPadding: page === SpecificChartFunctionality.quotePage ? 3 : undefined,\r\n placement: 'bottom',\r\n },\r\n ...(isRedesignEnabled() || page === SpecificChartFunctionality.chartPage\r\n ? [\r\n {\r\n title: 'Theme',\r\n body: 'Switch between the Light and Dark theme.',\r\n target: '[data-testid=\"chart-layout-theme\"]',\r\n },\r\n ]\r\n : []),\r\n {\r\n title: 'Study Settings',\r\n body: 'Customize the Chart Type and appearance. Add Overlays, Indicators and toggle Extended Hours.',\r\n target: '[data-testid=\"chart-settings-open-btn\"]',\r\n placement: page === SpecificChartFunctionality.chartPage ? 'bottom' : 'bottom-end',\r\n },\r\n ],\r\n },\r\n page === SpecificChartFunctionality.chartPage && {\r\n id: 'sidebar-watchlist',\r\n steps: [\r\n {\r\n title: 'Explore Your Portfolios',\r\n body: 'Effortlessly navigate through your portfolio holdings. With just a click, visualize individual stock charts, gain insights, and stay updated on your investments.',\r\n target: '[data-testid=\"sidebar-portfolio-btn\"]',\r\n placement: 'left-start',\r\n },\r\n ],\r\n },\r\n ].filter(Boolean) as TourDefinition[]\r\n}\r\n\r\ninterface TourButtonProps {\r\n page: SpecificChartFunctionality\r\n rounding?: 'none' | 'regular'\r\n size?: ButtonSizeType\r\n theme?: ButtonThemeType\r\n className?: string\r\n}\r\n\r\nexport function TourButton({ page, className, theme, ...props }: React.PropsWithChildren) {\r\n const tour = useTour()\r\n const pageTours = getTour(page)\r\n const [userTour, setCurrentTour] = React.useState(tour.getStepsForUser(pageTours))\r\n const buttonTheme: ButtonThemeType = userTour.hasNewTours ? 'blue' : theme ?? 'headerItem'\r\n\r\n return (\r\n \r\n }\r\n >\r\n \r\n \r\n ) : (\r\n \r\n )\r\n }\r\n className={className}\r\n contentClass={page !== SpecificChartFunctionality.quotePage ? 'hidden lg:flex' : ''}\r\n title=\"Explore new features\"\r\n onClick={async () => {\r\n if (userTour) {\r\n const activeTour = await tour.startTour(userTour.tour)\r\n activeTour?.once('inactive', () => {\r\n setCurrentTour(tour.getStepsForUser(pageTours))\r\n })\r\n }\r\n }}\r\n />\r\n )\r\n}\r\n","import { ButtonComponentProps, Icon, Select, SelectListProps } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { useChartTypes } from './use-chart-types'\r\n\r\ninterface Props extends Pick {\r\n isPremium: boolean\r\n model: ChartLayout\r\n rounding: SelectListProps['rounding']\r\n}\r\n\r\nexport function ChartTypesSelect({ isPremium, model, ...props }: Props) {\r\n const { chartTypes, getCurrentType } = useChartTypes({ isPremium, model })\r\n const currentType = getCurrentType()\r\n const [selectedType, setSelectedType] = React.useState(currentType)\r\n const icon = chartTypes.find((item) => item.value === selectedType)?.icon\r\n\r\n React.useEffect(() => {\r\n setSelectedType(currentType)\r\n }, [currentType])\r\n\r\n return (\r\n item.value === selectedType)?.icon} className=\"text-gray-300\" />\r\n )\r\n }\r\n nativeSelect=\"mobile\"\r\n onChange={(item) => setSelectedType(item.value)}\r\n />\r\n )\r\n}\r\n","import * as React from 'react'\r\nimport { useLocation } from 'react-router-dom'\r\n\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { decodeQueryString, encodeQueryString } from '../../utils/query_string'\r\nimport {\r\n DEFAULT_TYPES,\r\n FREE_TYPES_QUOTE,\r\n FREE_TYPES_QUOTE_VALUES,\r\n QuoteLongToShortType,\r\n QuoteNodeChartTypes,\r\n QuoteShortToLongType,\r\n QuoteUrlChartTypes,\r\n TypeBaseOption,\r\n} from './utils'\r\n\r\nexport function useChartTypes({ isPremium, model }: { isPremium: boolean; model: ChartLayout }) {\r\n const location = useLocation()\r\n const { b, t, ta, ty, p = 'd', r } = decodeQueryString(location.search)\r\n const taInt = ta ? Number.parseInt(ta) : 1\r\n const isQuotePage = model.specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n\r\n const getCurrentType = React.useCallback(() => {\r\n const defaultType =\r\n ((ty as QuoteUrlChartTypes | undefined) && QuoteShortToLongType[ty as QuoteUrlChartTypes]) ??\r\n (window.FinvizQuoteTypeCurrent as QuoteNodeChartTypes)\r\n\r\n return !isPremium && defaultType === QuoteNodeChartTypes.candlestick && taInt === 0\r\n ? QuoteNodeChartTypes.candlesticksimple\r\n : defaultType\r\n }, [isPremium, taInt, ty])\r\n\r\n const generateRouterPath = React.useCallback(\r\n (type: QuoteNodeChartTypes) => {\r\n if (isPremium || FREE_TYPES_QUOTE_VALUES.includes(type)) {\r\n return `${location.pathname}?${encodeQueryString({\r\n b,\r\n t,\r\n r,\r\n ty:\r\n type === QuoteNodeChartTypes.candlesticksimple\r\n ? QuoteLongToShortType.candlestick\r\n : QuoteLongToShortType[type],\r\n ta: type === QuoteNodeChartTypes.candlestick ? '1' : '0',\r\n p,\r\n })}`\r\n }\r\n return `/elite.ashx?${encodeQueryString({\r\n utm_source: 'finviz',\r\n utm_medium: 'banner',\r\n utm_campaign: 'quote-chart-type-select',\r\n })}`\r\n },\r\n [isPremium, location.pathname, b, t, r, p]\r\n )\r\n\r\n const chartTypes = React.useMemo(() => {\r\n const options = isPremium || !isQuotePage ? DEFAULT_TYPES : FREE_TYPES_QUOTE\r\n\r\n return options.map((item) => ({\r\n ...item,\r\n href: generateRouterPath(item.value as QuoteNodeChartTypes),\r\n reloadDocument: !isPremium,\r\n })) as TypeBaseOption[]\r\n }, [generateRouterPath, isPremium, isQuotePage])\r\n\r\n return { getCurrentType, chartTypes }\r\n}\r\n","import { Paragraph, withSuspense } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport math from '../../helpers/math'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport { QuoteFetchType } from '../../models/quote/constants'\r\nimport { getTickerChange } from '../../utils/chart'\r\nimport { useChartLayoutGlobalModelAsync } from '../../utils/useChartLayoutGlobalModelAsync'\r\n\r\ninterface Props {\r\n chartIndex: number\r\n}\r\n\r\ninterface ChangeLabelProps {\r\n children: React.ReactNode\r\n changePoints: number\r\n isTiny: boolean\r\n}\r\n\r\nconst CHANGE_UPATE_EVENTS = ['change', 'update']\r\nconst QUOTE_MODEL_CHANGE_EVENTS = [...CHANGE_UPATE_EVENTS, ...Object.values(QuoteFetchType)]\r\n\r\nfunction ChangeLabel({ children, changePoints, isTiny }: ChangeLabelProps) {\r\n return (\r\n 0,\r\n 'text-red-400': changePoints < 0,\r\n })}\r\n >\r\n {children}\r\n \r\n )\r\n}\r\n\r\nexport function DailyChangeDisplayComponent({ chartIndex }: Props) {\r\n const { chartLayoutModel } = useChartLayoutGlobalModelAsync()\r\n const chartModel = useModelState(chartLayoutModel?.getAllCharts()[chartIndex] ?? null, {\r\n watchProperties: ['quote'],\r\n listenOnEvents: CHANGE_UPATE_EVENTS,\r\n })\r\n const quoteModel = useModelState(chartModel?.quote() ?? null, {\r\n watchProperties: ['lastClose', 'prevClose', 'afterClose'],\r\n listenOnEvents: QUOTE_MODEL_CHANGE_EVENTS,\r\n })\r\n\r\n const tickerChange = quoteModel && getTickerChange({ data: quoteModel })\r\n const isTiny =\r\n !!tickerChange?.tickerChange &&\r\n math.getInstrumentDecimalPlaces({\r\n instrument: quoteModel!.instrument,\r\n value: quoteModel!.lastClose,\r\n }) >= 6\r\n\r\n return (\r\n
\r\n {tickerChange?.tickerChange && (\r\n <>\r\n {tickerChange.tickerAfterChange && (\r\n \r\n {tickerChange.tickerAfterChange.string}\r\n \r\n )}\r\n \r\n {tickerChange.tickerChange.string}\r\n \r\n \r\n )}\r\n
\r\n )\r\n}\r\n\r\nexport const DailyChangeDisplay = React.memo(\r\n withSuspense(DailyChangeDisplayComponent),\r\n (prevProps, nextProps) => prevProps.chartIndex === nextProps.chartIndex\r\n)\r\n","import { Button, ButtonComponentProps, setCookieRequest } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport utils from '../../utils'\r\nimport { DRAWING_COOKIE_NAME, getIsDrawingEnabled } from '../../utils/chart'\r\nimport { decodeQueryString, encodeQueryString } from '../../utils/query_string'\r\n\r\nconst utmCampaign: Partial> = {\r\n [SpecificChartFunctionality.quotePage]: 'quote-draw-button',\r\n [SpecificChartFunctionality.futuresPage]: 'futures-interactive-chart',\r\n [SpecificChartFunctionality.forexPage]: 'forex-interactive-chart',\r\n [SpecificChartFunctionality.cryptoPage]: 'crypto-interactive-chart',\r\n}\r\n\r\nconst testId: Partial> = {\r\n [SpecificChartFunctionality.quotePage]: 'quote-toggle-draw-btn',\r\n [SpecificChartFunctionality.futuresPage]: 'futures-interactive',\r\n [SpecificChartFunctionality.forexPage]: 'forex-interactive',\r\n [SpecificChartFunctionality.cryptoPage]: 'crypto-interactive',\r\n}\r\n\r\ninterface DrawButtonProps extends Pick {\r\n isPremium: boolean\r\n specificChartFunctionality: SpecificChartFunctionality\r\n active?: boolean\r\n}\r\n\r\nexport function DrawButton({\r\n isPremium,\r\n specificChartFunctionality,\r\n ...props\r\n}: React.PropsWithChildren) {\r\n const buttonProps = React.useMemo(() => {\r\n if (!isPremium) {\r\n return {\r\n as: 'a' as const,\r\n href: `/elite.ashx?${encodeQueryString({\r\n utm_source: 'finviz',\r\n utm_medium: 'banner',\r\n utm_campaign: utmCampaign[specificChartFunctionality],\r\n })}`,\r\n }\r\n }\r\n\r\n return {\r\n onClick: (ev: React.MouseEvent) => {\r\n ev.preventDefault()\r\n const newValue = getIsDrawingEnabled() ? 'off' : 'on'\r\n\r\n setCookieRequest(DRAWING_COOKIE_NAME, newValue)\r\n .catch(() => {\r\n // fallback to JS otherwise draw toggle won't work if API don't work\r\n const expires = new Date()\r\n expires.setMonth(expires.getMonth() + 1)\r\n utils.setCookie(DRAWING_COOKIE_NAME, newValue, expires)\r\n })\r\n .finally(() => {\r\n const { i: idea, ...rest } = decodeQueryString()\r\n if (idea) {\r\n document.location = `quote.ashx?${encodeQueryString(rest)}`\r\n } else {\r\n document.location.reload()\r\n }\r\n })\r\n },\r\n }\r\n }, [isPremium, specificChartFunctionality])\r\n\r\n return (\r\n \r\n )\r\n}\r\n","import { Button, ButtonComponentProps } from '@finviz/website'\r\nimport * as React from 'react'\r\nimport { useLocation } from 'react-router-dom'\r\n\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { decodeQueryString, encodeQueryString } from '../../utils/query_string'\r\n\r\nfunction getTickersString(tickers: string[], tickersCount: number) {\r\n return Array.from({ length: Math.min(tickersCount, 6) })\r\n .map((_, index) => tickers[index] ?? tickers[tickers.length - 1])\r\n .join(',')\r\n}\r\n\r\nfunction getLayoutType(tickersCount: number) {\r\n switch (tickersCount) {\r\n case 0: // shouldn't happen\r\n case 1:\r\n return '1h1v'\r\n case 2:\r\n return '2h1v'\r\n case 3:\r\n return '3h1v'\r\n case 4:\r\n return '2h2v'\r\n case 5:\r\n default:\r\n // 6 and more\r\n return '3h2v'\r\n }\r\n}\r\n\r\nconst utmCampaign: Partial> = {\r\n [SpecificChartFunctionality.quotePage]: 'quote-fullscreen-button',\r\n [SpecificChartFunctionality.futuresPage]: 'futures-fullscreen-button',\r\n [SpecificChartFunctionality.forexPage]: 'forex-fullscreen-button',\r\n [SpecificChartFunctionality.cryptoPage]: 'crypto-fullscreen-button',\r\n}\r\n\r\ninterface FullscreenButtonProps extends Pick {\r\n model: ChartLayout\r\n isPremium: boolean\r\n title?: string\r\n}\r\n\r\nexport function FullscreenButton({ model, isPremium, ...props }: React.PropsWithChildren) {\r\n const location = useLocation()\r\n const { i, p = 'd', r } = decodeQueryString(location.search)\r\n const urlTickers = model\r\n .charts()\r\n .all()\r\n .map((chart) => chart.quote().getRawTicker())\r\n\r\n return (\r\n p).join(','),\r\n l: getLayoutType(urlTickers.length),\r\n r,\r\n })}`\r\n : `/elite.ashx?${encodeQueryString({\r\n utm_source: 'finviz',\r\n utm_medium: 'banner',\r\n utm_campaign: utmCampaign[model.specificChartFunctionality],\r\n })}`\r\n }\r\n />\r\n )\r\n}\r\n","import {\r\n Button,\r\n Dialog,\r\n DialogTrigger,\r\n Dropdown,\r\n DropdownItem,\r\n Icon,\r\n Spinner,\r\n Search as WebsiteSearchComponent,\r\n createAlertAsyncModule,\r\n saveToPortfolioAsyncModule,\r\n useDialogState,\r\n useDropdownState,\r\n} from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { Instrument } from '../../../types/shared'\r\nimport { useAsyncModule } from '../../utils/async-modules-utils'\r\n\r\ninterface SearchProps {\r\n ticker: string\r\n instrument: Instrument\r\n onTickerSelected: (ticker: string) => void\r\n chartIndex: number\r\n}\r\n\r\nexport default function Search({ ticker, instrument, onTickerSelected, chartIndex }: SearchProps) {\r\n const dropdownState = useDropdownState({ placement: 'bottom-end' })\r\n const saveToPortfolioDialogState = useDialogState()\r\n const createAlertDialogState = useDialogState()\r\n const [saveToPortfolioModule, { isLoading: isLoadingSaveToPortfolio }] = useAsyncModule({\r\n ...saveToPortfolioAsyncModule,\r\n shouldLoadModule: saveToPortfolioDialogState.visible,\r\n onError: () => saveToPortfolioDialogState.hide(),\r\n })\r\n const [createAlertModule, { isLoading: isLoadingCreateAlert }] = useAsyncModule({\r\n ...createAlertAsyncModule,\r\n shouldLoadModule: createAlertDialogState.visible,\r\n onError: () => createAlertDialogState.hide(),\r\n })\r\n const SaveToPortfolio = saveToPortfolioModule?.SaveToPortfolio\r\n const CreateAlert = createAlertModule?.CreateAlert\r\n\r\n const detailLink = React.useMemo(() => {\r\n const formattedTicker = ticker.replace('@', '')\r\n\r\n switch (instrument) {\r\n case Instrument.Stock:\r\n return `/quote.ashx?t=${formattedTicker}`\r\n case Instrument.Futures:\r\n return `/futures_charts.ashx?t=${formattedTicker}`\r\n case Instrument.Forex:\r\n return `/forex_charts.ashx?t=${formattedTicker}`\r\n case Instrument.Crypto:\r\n return `/crypto_charts.ashx?t=${formattedTicker}`\r\n }\r\n }, [ticker, instrument])\r\n\r\n return (\r\n
\r\n }\r\n />\r\n }\r\n >\r\n {\r\n window.gtag?.('event', 'click', { event_category: 'open-stock-detail' })\r\n }}\r\n >\r\n {instrument === Instrument.Stock ? 'Open Stock Detail' : 'Open Detail'}\r\n \r\n {instrument === Instrument.Stock && (\r\n {\r\n window.gtag?.('event', 'click', { event_category: 'save-to-portfolio' })\r\n }}\r\n >\r\n Save to Portfolio\r\n \r\n )}\r\n {instrument === Instrument.Stock && (\r\n {\r\n window.gtag?.('event', 'click', { event_category: 'create-alert' })\r\n }}\r\n >\r\n Create Alert\r\n \r\n )}\r\n \r\n }\r\n />\r\n \r\n {isLoadingSaveToPortfolio && (\r\n
\r\n \r\n
\r\n )}\r\n {SaveToPortfolio && }\r\n
\r\n \r\n {isLoadingCreateAlert && (\r\n
\r\n \r\n
\r\n )}\r\n {CreateAlert && }\r\n
\r\n
\r\n )\r\n}\r\n","import {\r\n Button,\r\n ButtonComponentProps,\r\n Delayed,\r\n Popover,\r\n PopoverPlacement,\r\n PopoverTrigger,\r\n Spinner,\r\n getExtendedDialogState,\r\n useElementMeasure,\r\n usePopoverState,\r\n} from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport {\r\n chartSettingsAsyncModule,\r\n preventClosingUnsavedChangesAsyncModule,\r\n} from '../../controllers/chart-settings/async-modules'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { useAsyncModule } from '../../utils/async-modules-utils'\r\nimport { encodeQueryString } from '../../utils/query_string'\r\n\r\nconst SETTINGS_WIDTH = 580 // w-145\r\nconst BUTTON_POPOVER_GUTTER = 16\r\nconst SETTINGS_POPOVER_ID = 'settings-popover'\r\n\r\nconst utmCampaign: Partial> = {\r\n [SpecificChartFunctionality.quotePage]: 'quote-settings-button',\r\n [SpecificChartFunctionality.futuresPage]: 'futures-settings-button',\r\n [SpecificChartFunctionality.forexPage]: 'forex-settings-button',\r\n [SpecificChartFunctionality.cryptoPage]: 'crypto-settings-button',\r\n}\r\n\r\ntype PopoverStylesType = { body?: React.CSSProperties; wrapper?: React.CSSProperties }\r\n\r\nexport function ScrollableChartSettingsPopover({ state, model }: { state: any; model: ChartLayout }) {\r\n const { elementWidth: bodyWidth } = useElementMeasure(document.body)\r\n const [chartSettingsModule] = useAsyncModule({\r\n ...chartSettingsAsyncModule,\r\n shouldLoadModule: state.visible,\r\n errorSeverity: 'medium',\r\n onError: () => state.hide(),\r\n })\r\n const [preventClosingUnsavedChangesModule] = useAsyncModule({\r\n ...preventClosingUnsavedChangesAsyncModule,\r\n shouldLoadModule: state.visible,\r\n errorSeverity: 'medium',\r\n onError: () => state.hide(),\r\n })\r\n\r\n /**\r\n * The reason for this workaround is that the popover with a loader while fetching async modules remounts and resets\r\n * all animations when all async modules are loaded and the popover is rerendered inside PreventClosingUnsavedChanges\r\n * */\r\n const checkForUnsavedChangesAndCloseRef = React.useRef(() => {})\r\n\r\n const { ChartSettings } = chartSettingsModule ?? {}\r\n const { PreventClosingUnsavedChanges } = preventClosingUnsavedChangesModule ?? {}\r\n const { isFullyClosed } = getExtendedDialogState(state)\r\n const chartElement = document.getElementById('chart')\r\n const popoverContentElement = document.getElementById(SETTINGS_POPOVER_ID)\r\n const settingsButton: HTMLButtonElement = state.unstable_referenceRef.current\r\n\r\n const popoverStyles = React.useMemo(() => {\r\n const newPopoverStyles: PopoverStylesType = {}\r\n if (!settingsButton || !chartElement) {\r\n return newPopoverStyles\r\n }\r\n const buttonRect = settingsButton.getBoundingClientRect()\r\n const topOffset = buttonRect.top + buttonRect.height\r\n newPopoverStyles.body = {\r\n maxHeight: window.innerHeight - topOffset - BUTTON_POPOVER_GUTTER * 2,\r\n position: 'sticky',\r\n top: -topOffset + BUTTON_POPOVER_GUTTER - window.scrollY,\r\n }\r\n if (!popoverContentElement) {\r\n return newPopoverStyles\r\n }\r\n const chartHeight = chartElement.clientHeight\r\n const popoverContentHeight = popoverContentElement.offsetHeight\r\n const emptySpaceDiff = bodyWidth - model.width\r\n const maxOffset = SETTINGS_WIDTH - buttonRect.width\r\n\r\n let rightOffset = emptySpaceDiff > 150 ? (emptySpaceDiff / 2) * -1 : 0\r\n if (emptySpaceDiff / 2 > maxOffset) rightOffset = maxOffset * -1\r\n\r\n newPopoverStyles.wrapper = {\r\n height: popoverContentHeight < chartHeight ? chartHeight : undefined,\r\n marginRight: rightOffset,\r\n }\r\n\r\n return newPopoverStyles\r\n }, [settingsButton, chartElement, popoverContentElement, model.width, bodyWidth])\r\n\r\n const hasAsyncModules = !!(PreventClosingUnsavedChanges && ChartSettings)\r\n\r\n return (\r\n \r\n {hasAsyncModules ? (\r\n \r\n {({ checkForUnsavedChangesAndClose }) => {\r\n checkForUnsavedChangesAndCloseRef.current = checkForUnsavedChangesAndClose\r\n return !isFullyClosed ? : null\r\n }}\r\n \r\n ) : (\r\n \r\n
\r\n \r\n
\r\n
\r\n )}\r\n \r\n )\r\n}\r\n\r\ninterface ChartSettingsButtonProps extends Pick {\r\n isPremium: boolean\r\n placement?: PopoverPlacement\r\n model: ChartLayout\r\n}\r\n\r\nexport function ChartSettingsButton({\r\n isPremium,\r\n model,\r\n placement,\r\n ...props\r\n}: React.PropsWithChildren) {\r\n const settingsPopoverState = usePopoverState({ placement: placement ?? 'bottom-end' })\r\n\r\n const buttonProps = React.useMemo(() => {\r\n if (model.specificChartFunctionality !== SpecificChartFunctionality.quotePage && !isPremium) {\r\n return {\r\n as: 'a',\r\n href: `/elite.ashx?${encodeQueryString({\r\n utm_source: 'finviz',\r\n utm_medium: 'banner',\r\n utm_campaign: utmCampaign[model.specificChartFunctionality],\r\n })}`,\r\n } as ButtonComponentProps<'a'>\r\n }\r\n\r\n return {\r\n as: PopoverTrigger,\r\n state: settingsPopoverState,\r\n active: settingsPopoverState.visible,\r\n } as ButtonComponentProps\r\n }, [model, isPremium, settingsPopoverState])\r\n\r\n return (\r\n <>\r\n \r\n \r\n \r\n )\r\n}\r\n","import * as React from 'react'\r\nimport { useLocation, useNavigate } from 'react-router-dom'\r\n\r\nimport { ChartsOrQuotePageQueryParams, SpecificChartFunctionality } from '../../constants/common'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport { useModelRef } from '../../model-hooks/useModelRef'\r\nimport Chart from '../../models/chart'\r\nimport Quote from '../../models/quote'\r\nimport { QuoteFetchType } from '../../models/quote/constants'\r\nimport { createRequestAbortController, removeFromAbortCache } from '../../utils/abort_controller'\r\nimport { decodeQueryString, encodeQueryString } from '../../utils/query_string'\r\nimport { getLeftOffset } from '../renderUtils'\r\n\r\nconst getQuoteRequestKey = (chartModel: Chart) =>\r\n `quoteReq-${chartModel.ticker}-${chartModel.instrument}-${chartModel.id}`\r\n\r\nexport function useChartControls({\r\n chartModel: unwatchedChartModel,\r\n isInteractive,\r\n}: {\r\n chartModel: Chart | null\r\n isInteractive: boolean\r\n}) {\r\n const location = useLocation()\r\n const navigate = useNavigate()\r\n const chartModel = useModelState(unwatchedChartModel, {\r\n watchProperties: ['ticker', 'timeframe', 'dateRange'],\r\n })\r\n const chartLayoutModel = useModelState(chartModel?.chart_layout() ?? null, {\r\n watchProperties: ['idea', 'settings'],\r\n })\r\n const chartModelRef = useModelRef(chartModel)\r\n const [isLoading, setIsLoading] = React.useState(false)\r\n const abortControllerKeyRef = React.useRef('')\r\n const isIdeaChart = !!chartLayoutModel?.idea?.id\r\n\r\n const updateChartModelWithNewQuote = React.useCallback((quote: Quote) => {\r\n const chart = chartModelRef.current\r\n if (!chart) {\r\n return\r\n }\r\n\r\n const chartLayoutModel = chart.chart_layout()\r\n const isSameTicker = chart.getQuoteRawTicker() === quote.getRawTicker()\r\n\r\n chart.getAllPanes().forEach((pane) => {\r\n if (!!pane.getChartOrIndicatorElement()) {\r\n pane.updateAttribute('scaleRange', null)\r\n }\r\n })\r\n\r\n chart.updateAttributes({ leftOffset: getLeftOffset({ quote, chartModel: chart }), quote, isScrolled: true })\r\n\r\n // Refetch all other chart quotes as the main one is already refetched so we can filter it out but other quotes (from perf for example) should be refetched as well\r\n chart\r\n .getAllQuotes()\r\n .filter((chartQuote) => !chartQuote.eql(quote))\r\n .forEach((quote) => {\r\n quote.fetchData({ fetchType: QuoteFetchType.NewerData })\r\n })\r\n\r\n const chartPane = chart.getChartPane()\r\n chartLayoutModel.activeChartEvent?.instance.toggleIsOpen(false)\r\n\r\n const elements = [...chart.getAllElements(), ...(chartPane?.getAllChartEvents(false) ?? [])]\r\n for (const element of elements) {\r\n const isDrawing = element.isDrawing()\r\n const isChartEvent = element.isChartEvent()\r\n if (isDrawing || isChartEvent) {\r\n // We want to remove all drawings on ticker change but if autosave is enabled we let the autosave hook take care of that\r\n if (isSameTicker && (isChartEvent || chartLayoutModel.isPreserveDrawingsActive)) {\r\n element.instance.updateScales()\r\n } else {\r\n element.destroyCascade()\r\n }\r\n }\r\n }\r\n\r\n chart.setChartEvents(quote.chartEvents, true)\r\n\r\n chartPane?.updateChartEventsZIndexes()\r\n\r\n // The only dependency here is a ref , so no need to add it to dependencies\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n const fetchQuote = React.useCallback(async () => {\r\n if (!isInteractive || !chartModel || isIdeaChart) {\r\n return\r\n }\r\n setIsLoading(true)\r\n\r\n const { ticker, instrument, timeframe, hasChartEvents } = chartModel\r\n const { premarket, aftermarket } = Quote.first()\r\n const patterns = chartModel.getHasPatterns()\r\n const currentQuote = chartModel.quote()\r\n if (currentQuote.getRawTicker() !== ticker || currentQuote.timeframe !== timeframe) {\r\n abortControllerKeyRef.current = getQuoteRequestKey(chartModel)\r\n const abortController = createRequestAbortController({\r\n key: abortControllerKeyRef.current,\r\n shouldAbortRunningRequest: !Quote.select(\r\n (quote) =>\r\n quote.ticker === ticker &&\r\n quote.timeframe === timeframe &&\r\n quote.isFetching &&\r\n chartModel.chart_layout().isIdeaId(quote.ideaID)\r\n ),\r\n })\r\n\r\n const quote = await Quote.get({\r\n ticker,\r\n instrument,\r\n timeframe,\r\n options: {\r\n premarket,\r\n aftermarket,\r\n events: hasChartEvents,\r\n patterns,\r\n cachePredicate: (quote) => quote.ideaID === undefined,\r\n fetchNewDataOnCachedQuote: true,\r\n },\r\n abortController,\r\n })\r\n\r\n if (quote.wasFetchAborted) {\r\n // Check if the quote is also used in other chars, as the quote may be reused if we already have a quote with the same options\r\n const isQuoteUsedInOtherCharts = chartModel\r\n .chart_layout()\r\n .getAllCharts()\r\n .filter((chart) => !chartModel.eql(chart))\r\n .some((chart) => quote.eql(chart.quote()))\r\n\r\n // If the quote hasn't been fetched yet and is not anywhere else we can destroy the model\r\n if (quote.fetchedAt === -1 && !isQuoteUsedInOtherCharts) {\r\n quote.destroy()\r\n }\r\n\r\n return\r\n }\r\n\r\n removeFromAbortCache(abortControllerKeyRef.current)\r\n\r\n updateChartModelWithNewQuote(quote)\r\n }\r\n\r\n setIsLoading(false)\r\n\r\n // We don't want to create new function on any chartModel change as it may be the same chart with different object instance\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [\r\n chartModel?.id,\r\n chartModel?.ticker,\r\n chartModel?.timeframe,\r\n chartModel?.instrument,\r\n isIdeaChart,\r\n updateChartModelWithNewQuote,\r\n isInteractive,\r\n ])\r\n\r\n React.useEffect(() => {\r\n fetchQuote()\r\n }, [fetchQuote])\r\n\r\n // There are several ways how to turn off dateRange, e.g. moving the charts\r\n // This effect listens to dateRange changes on chartmodel and updates the url if there's a change\r\n // Consider refactoring this part so we only update chart models on route changes not the other way around\r\n React.useEffect(() => {\r\n if (chartModel) {\r\n const decodedQueryString = decodeQueryString(location.search)\r\n const rangesArray = chartModel\r\n .chart_layout()\r\n .getAllCharts()\r\n .map((chart) => chart.dateRange)\r\n const ranges = rangesArray.every((i) => !i) ? undefined : rangesArray.join(',')\r\n\r\n if (decodedQueryString.r !== ranges) {\r\n navigate({\r\n search: `?${encodeQueryString({\r\n ...decodedQueryString,\r\n r: ranges,\r\n })}`,\r\n })\r\n }\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [chartModel?.dateRange])\r\n\r\n // https://github.com/finvizhq/charts/pull/1253/files#r1052266805\r\n // React.useEffect(\r\n // () => () => {\r\n // if (isInteractive && abortControllerKeyRef.current !== '') {\r\n // abortRequest(abortControllerKeyRef.current)\r\n // }\r\n // },\r\n // [isInteractive]\r\n // )\r\n\r\n React.useEffect(() => {\r\n const chart = chartModelRef.current\r\n const quote = chart?.quote()\r\n\r\n let shouldRecalculateOnCharts = false\r\n if (chartLayoutModel?.specificChartFunctionality === SpecificChartFunctionality.chartPage && !isIdeaChart) {\r\n const settings = chartLayoutModel?.settings\r\n const barWidth = 3\r\n const barMargin = 1\r\n if (settings) {\r\n const hasSameBarWidth = [\r\n settings.ChartSettings.center.barWidth,\r\n settings.IndicatorSettings.center.barWidth,\r\n ].every((value) => value === barWidth)\r\n const hasSameBarMargin = [\r\n settings.ChartSettings.center.barMargin,\r\n settings.IndicatorSettings.center.barMargin,\r\n ].every((value) => value === barMargin)\r\n\r\n shouldRecalculateOnCharts = !hasSameBarWidth || !hasSameBarMargin\r\n if (shouldRecalculateOnCharts) {\r\n settings.ChartSettings.center.barWidth = barWidth\r\n settings.IndicatorSettings.center.barWidth = barWidth\r\n settings.ChartSettings.center.barMargin = barMargin\r\n settings.IndicatorSettings.center.barMargin = barMargin\r\n\r\n chartLayoutModel.updateAttributes({ settings })\r\n }\r\n }\r\n }\r\n\r\n if (\r\n chart &&\r\n quote &&\r\n (chartLayoutModel?.specificChartFunctionality === SpecificChartFunctionality.quotePage ||\r\n shouldRecalculateOnCharts) &&\r\n !isIdeaChart\r\n ) {\r\n const leftOffset = getLeftOffset({ quote, chartModel: chart })\r\n chart.updateAttributes({ leftOffset })\r\n }\r\n // This effect should run only on timeframe change & idea change\r\n // The reason we need to recalculate the left offset is that quote timeframe change changes chart and chart bars sizes\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [chartModel?.quote()?.timeframe, chartLayoutModel?.settings, isIdeaChart])\r\n\r\n return { isLoading }\r\n}\r\n","import Spine from '@finviz/spine'\r\nimport * as React from 'react'\r\n\r\nexport function useModelRef(model: Model | null) {\r\n const modelRef = React.useRef(model)\r\n\r\n React.useEffect(() => {\r\n modelRef.current = model\r\n }, [model])\r\n\r\n return modelRef\r\n}\r\n","import {\r\n ButtonRoundingType,\r\n ButtonSizeType,\r\n CustomDateRange,\r\n Heading,\r\n TimeframeBar,\r\n useCustomDateRangeDialog,\r\n useFavoriteTimeframes,\r\n} from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport React from 'react'\r\nimport { useNavigate } from 'react-router-dom'\r\n\r\nimport { ChartEditorEnum, SpecificChartFunctionality, TIMEFRAME } from '../../constants/common'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport Chart from '../../models/chart'\r\nimport { IdeasDropdown } from '../header/ideas_dropdown'\r\nimport { Publish } from '../header/publish'\r\nimport { TourButton } from '../header/tour_button'\r\nimport { ChartTypesSelect } from './chart-type-select'\r\nimport { DailyChangeDisplay } from './daily-change-display'\r\nimport { DrawButton } from './draw-button'\r\nimport { FullscreenButton } from './fullscreen-button'\r\nimport Search from './search'\r\nimport { ChartSettingsButton } from './settings-button'\r\nimport { useChartControls } from './use-chart-controls'\r\nimport { IDateRange, useChartModelCustomDateRangeValues } from './use-chart-model-custom-date-range-values'\r\n\r\ninterface SettingsComponentProps {\r\n chartModel: Chart\r\n chartIndex: number\r\n}\r\n\r\nconst isPremium = window.FinvizSettings.hasUserPremium\r\nconst hasRedesignEnabled = window.FinvizSettings.hasRedesignEnabled\r\n\r\nexport function ChartControls({ chartIndex, chartModel: unwatchedChartModel }: SettingsComponentProps) {\r\n const rounding: ButtonRoundingType | undefined = hasRedesignEnabled ? undefined : 'none'\r\n // This memo is required for publish, otherwise it ends up in a loop\r\n const chartLayout = React.useMemo(() => unwatchedChartModel.chart_layout(), [unwatchedChartModel])\r\n const chartModel = useModelState(unwatchedChartModel, {\r\n watchProperties: ['ticker', 'quote', 'dateRange'],\r\n })\r\n const { instrument } = chartModel?.quote() || {}\r\n const isQuotePage = chartLayout.specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n\r\n const navigate = useNavigate()\r\n const { favoriteTimeframes, toggleFavoriteTimeframe } = useFavoriteTimeframes()\r\n const { isLoading } = useChartControls({\r\n chartModel,\r\n isInteractive: true,\r\n })\r\n const {\r\n anchorDate,\r\n generateChartLayoutRouterPath,\r\n timeframeGroupsWithHref,\r\n dateRangeGroupsWithHref,\r\n isFetching,\r\n handleCustomDateRangeValidation,\r\n } = useChartModelCustomDateRangeValues({ chartModel, isPremium })\r\n const { onDialogSubmit, customDateRangeDialogState, handleDateRangeSelect, getDateRangeTimeframe } =\r\n useCustomDateRangeDialog({\r\n instrument,\r\n anchorDate,\r\n pathGenerator: generateChartLayoutRouterPath,\r\n })\r\n\r\n const handleTickerSelect = React.useCallback(\r\n (ticker: string) => {\r\n const upperCaseTicker = ticker.toUpperCase()\r\n\r\n navigate(\r\n generateChartLayoutRouterPath({\r\n ticker: upperCaseTicker,\r\n timeframe: chartModel.timeframe,\r\n dateRange: chartModel.dateRange,\r\n })\r\n )\r\n },\r\n [chartModel, generateChartLayoutRouterPath, navigate]\r\n )\r\n\r\n async function handleCustomRangeSubmit(values: { dateRange: string | null }) {\r\n const dateRangeTimeframe = getDateRangeTimeframe(values.dateRange) as IDateRange | null\r\n if (!dateRangeTimeframe) return\r\n\r\n const isValid = await handleCustomDateRangeValidation(dateRangeTimeframe)\r\n if (isValid) onDialogSubmit(dateRangeTimeframe)\r\n }\r\n\r\n const timeframeBarProps = React.useMemo(\r\n () => ({\r\n size: 'medium' as ButtonSizeType,\r\n chartIndex: chartIndex,\r\n timeFrameGroups: timeframeGroupsWithHref(isPremium),\r\n dateRangeGroups: dateRangeGroupsWithHref({ isPremium, customRange: chartModel.dateRange, instrument }),\r\n selectedTimeframe: chartModel.timeframe,\r\n onTimeframeSelect: () => {},\r\n selectedDateRange: chartModel.dateRange,\r\n favoriteTimeframes: favoriteTimeframes,\r\n loadingTimeframe: isLoading ? chartModel.timeframe : undefined,\r\n onDateRangeSelect: handleDateRangeSelect,\r\n isFavoritesEnabled: isPremium,\r\n onFavoriteTimeframeToggle: ({ value }: { value: TIMEFRAME | 'intraday' }) => {\r\n toggleFavoriteTimeframe(value)\r\n },\r\n }),\r\n [\r\n chartIndex,\r\n chartModel.dateRange,\r\n chartModel.timeframe,\r\n dateRangeGroupsWithHref,\r\n favoriteTimeframes,\r\n handleDateRangeSelect,\r\n instrument,\r\n isLoading,\r\n timeframeGroupsWithHref,\r\n toggleFavoriteTimeframe,\r\n ]\r\n )\r\n\r\n if (chartLayout.specificChartFunctionality === SpecificChartFunctionality.chartPage) {\r\n return (\r\n
\r\n {chartModel.chart_layout().canChangeTicker && (\r\n \r\n )}\r\n\r\n \r\n\r\n \r\n\r\n \r\n
\r\n )\r\n }\r\n\r\n const hasTimeframe = chartLayout.editors.includes(ChartEditorEnum.timeframe)\r\n\r\n return (\r\n \r\n
\r\n {!isQuotePage && (\r\n \r\n {chartModel.quote().name ?? chartModel.ticker}\r\n \r\n )}\r\n {chartLayout.editors.includes(ChartEditorEnum.tools) && (\r\n \r\n Draw\r\n \r\n )}\r\n {chartLayout.editors.includes(ChartEditorEnum.ideas) && (\r\n \r\n Ideas\r\n \r\n )}\r\n {!hasTimeframe && (\r\n
\r\n \r\n
\r\n )}\r\n
\r\n\r\n {hasTimeframe && (\r\n
\r\n
\r\n
\r\n \r\n
\r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n )}\r\n\r\n
\r\n {chartLayout.editors.includes(ChartEditorEnum.publish) && (\r\n \r\n Share\r\n \r\n )}\r\n {isQuotePage && (\r\n \r\n )}\r\n \r\n {!isQuotePage && 'Fullscreen'}\r\n \r\n {chartLayout.editors.includes(ChartEditorEnum.settings) && (\r\n \r\n {!isQuotePage && 'Settings'}\r\n \r\n )}\r\n {!isQuotePage && (\r\n
\r\n \r\n
\r\n )}\r\n
\r\n \r\n )\r\n}\r\n","export const CHART_LAYOUT_CHILD_CHANGE_EVENT = 'chartLayoutChildChange'\r\n","import Spine from '@finviz/spine'\r\nimport { ContextMenuItem } from '@finviz/website'\r\n\r\nclass ContextMenu extends Spine.Model {\r\n static initClass() {\r\n this.configure('ContextMenu', 'shown', 'config', 'top', 'left')\r\n }\r\n\r\n declare shown: boolean\r\n declare config: ContextMenuItem[]\r\n declare top: number\r\n declare left: number\r\n}\r\n\r\nContextMenu.initClass()\r\n\r\nconst contextMenu = ContextMenu.create() as ContextMenu\r\ncontextMenu.save()\r\n\r\nexport default contextMenu\r\n","import { ContextMenu as ContextMenuComponent } from '@finviz/website'\r\nimport React from 'react'\r\nimport * as ReactDOM from 'react-dom'\r\n\r\nimport { ObjectHash } from '../../types/shared'\r\nimport model from '../models/context_menu'\r\nimport { ready } from '../utils'\r\n\r\nconst selector = '.context-menu'\r\n\r\nclass ContextMenu extends React.Component {\r\n componentDidMount() {\r\n model.bind('update', this.update)\r\n }\r\n\r\n componentWillUnmount() {\r\n model.unbind('update', this.update)\r\n }\r\n\r\n update = () => {\r\n this.forceUpdate()\r\n }\r\n\r\n render() {\r\n if (model.shown) {\r\n document.querySelector(selector)?.classList.remove('hidden')\r\n } else {\r\n document.querySelector(selector)?.classList.add('hidden')\r\n return null\r\n }\r\n\r\n return (\r\n <>\r\n this.hide()}\r\n onContextMenu={(e) => e.preventDefault()}\r\n data-testid=\"charts-context-menu-overlay\"\r\n >\r\n \r\n \r\n )\r\n }\r\n\r\n hide() {\r\n model.updateAttribute('shown', false)\r\n }\r\n}\r\nready(() => {\r\n const el = document.querySelector(selector)\r\n if (el) {\r\n ReactDOM.render(, el)\r\n }\r\n})\r\n\r\nconst contextMenuControl = {\r\n show: (event: MouseEvent | React.MouseEvent, config: ObjectHash) => {\r\n model.updateAttributes({\r\n shown: true,\r\n config: config,\r\n top: event.clientY + window.pageYOffset,\r\n left: event.clientX,\r\n })\r\n },\r\n}\r\n\r\nexport default contextMenuControl\r\n","import {\r\n Delayed,\r\n DialogBody,\r\n Popover,\r\n PopoverTrigger,\r\n Spinner,\r\n ZIndexContext,\r\n getExtendedDialogState,\r\n usePopoverState,\r\n} from '@finviz/website'\r\nimport classNames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { ChartEventBadgeType } from '../../constants/common'\r\nimport { chartEventsAsyncModule } from '../../controllers/chart-events/async-modules'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartModel from '../../models/chart'\r\nimport { useAsyncModule } from '../../utils/async-modules-utils'\r\nimport { useClickAway } from '../../utils/use-click-away'\r\n\r\ninterface ChartEventPopoverWithStateProps {\r\n chartModel: ChartModel\r\n}\r\n\r\nconst POPOVER_ID = 'badge-popover'\r\n\r\nexport function ChartEventPopoverWithState({ chartModel }: ChartEventPopoverWithStateProps) {\r\n const unwatchedChartLayout = React.useMemo(() => chartModel.chart_layout() ?? null, [chartModel])\r\n const { activeChartEvent, theme } = useModelState(unwatchedChartLayout, { watchProperties: ['activeChartEvent'] })\r\n const popoverState = usePopoverState({ placement: 'top' })\r\n const { isFullyClosed } = getExtendedDialogState(popoverState)\r\n const [style, setStyle] = React.useState({\r\n top: 0,\r\n left: 0,\r\n })\r\n const [chartEventsModule] = useAsyncModule({\r\n ...chartEventsAsyncModule,\r\n shouldLoadModule: !isFullyClosed,\r\n errorSeverity: 'medium',\r\n onError: () => popoverState.hide(),\r\n })\r\n const elementId = activeChartEvent?.elementId\r\n const isChartEventOfThisChart = activeChartEvent?.pane().chart().eql(chartModel)\r\n const [data, setData] = React.useState(null)\r\n const clickAwayRef = useClickAway(() => {\r\n const isAnyBadgeHovered = !!chartModel\r\n .getChartPane()\r\n ?.getAllChartEvents()\r\n .some((chartEvent) => chartEvent.instance.isHovered)\r\n\r\n if (!isAnyBadgeHovered && activeChartEvent && isChartEventOfThisChart) {\r\n activeChartEvent.instance.toggleIsOpen(false)\r\n }\r\n }, !!activeChartEvent && isChartEventOfThisChart)\r\n // This is intentional, it doesn't need to be in useEffect, it would just call effect function which is redundant\r\n clickAwayRef.current = popoverState.unstable_popoverRef.current\r\n const popoverShow = popoverState.show\r\n const popoverHide = popoverState.hide\r\n\r\n React.useEffect(() => {\r\n if (!activeChartEvent?.instance.isOpen || !isChartEventOfThisChart) {\r\n if (isFullyClosed) {\r\n return setData(null)\r\n }\r\n return popoverHide()\r\n }\r\n if (!isChartEventOfThisChart) return\r\n const { top, left } = activeChartEvent.instance\r\n const newData = activeChartEvent.getChartEventData()\r\n if (newData?.elementId !== data?.elementId) {\r\n setData({\r\n ...newData,\r\n badgeType: activeChartEvent.instance.getChartEvenBadgeType(),\r\n })\r\n }\r\n\r\n if (style.top !== top || style.left !== left) {\r\n popoverHide()\r\n setStyle({\r\n top,\r\n left,\r\n })\r\n }\r\n if (!popoverState.visible) {\r\n popoverShow()\r\n }\r\n }, [\r\n elementId,\r\n isFullyClosed,\r\n data,\r\n style,\r\n popoverShow,\r\n popoverHide,\r\n popoverState.visible,\r\n activeChartEvent,\r\n chartModel,\r\n isChartEventOfThisChart,\r\n ])\r\n\r\n return (\r\n <>\r\n \r\n {data && !isFullyClosed && (\r\n \r\n \r\n \r\n {chartEventsModule ? (\r\n \r\n ) : (\r\n
\r\n \r\n \r\n \r\n
\r\n )}\r\n \r\n \r\n
\r\n )}\r\n \r\n )\r\n}\r\n","import React from 'react'\r\n\r\nimport Utils from '../utils'\r\n\r\nexport function useClickAway(callback: (event: MouseEvent | TouchEvent) => void, isListening = true) {\r\n const ref = React.useRef(null)\r\n const refCallback = React.useRef(callback)\r\n\r\n React.useLayoutEffect(() => {\r\n refCallback.current = callback\r\n })\r\n\r\n React.useEffect(() => {\r\n if (!isListening) {\r\n return\r\n }\r\n const isMobile = Utils.isMobile()\r\n const handler = (e: MouseEvent | TouchEvent) => {\r\n const element = ref.current\r\n if (element && e.target && !element.contains(e.target as HTMLElement)) {\r\n refCallback.current(e)\r\n }\r\n }\r\n\r\n document.addEventListener(isMobile ? 'touchstart' : 'mousedown', handler)\r\n\r\n return () => {\r\n document.removeEventListener(isMobile ? 'touchstart' : 'mousedown', handler)\r\n }\r\n }, [callback, isListening])\r\n\r\n return ref\r\n}\r\n","import { Button, ButtonGroup, Delayed, Icon, Spinner } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport Chart from '../../models/chart'\r\nimport { QuoteFetchType } from '../../models/quote/constants'\r\nimport { useIsMounted } from '../../utils/use-is-mounted'\r\n\r\ninterface LoadLatestDataButtonProps {\r\n chartModel: Chart\r\n}\r\n\r\nexport function LoadLatestDataButton({ chartModel: chartModelUnwatched }: LoadLatestDataButtonProps) {\r\n const getIsMounted = useIsMounted()\r\n const chartModel = useModelState(chartModelUnwatched, { watchProperties: ['quote'] })\r\n const quoteModel = useModelState(chartModel.quote(), { watchProperties: ['isFetching'] })\r\n const [hasNewDataAvailable, setHasNewDataAvailable] = React.useState(false)\r\n\r\n React.useEffect(() => {\r\n if (!chartModel.getRefreshInterval()) {\r\n // We will do a check here if we have correct new data\r\n chartModel\r\n .quote()\r\n .isPossibleToFetchSequentialData()\r\n .then((hasNewData) => {\r\n if (getIsMounted()) {\r\n setHasNewDataAvailable(hasNewData)\r\n }\r\n })\r\n }\r\n // We need to run it only on mount\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n const handleLoadLatestData = async () => {\r\n const promises = chartModel\r\n .getAllQuotes()\r\n .map(async (quote) => quote.fetchData({ fetchType: QuoteFetchType.NewerData }))\r\n chartModel.updateAttributes({ refreshData: true })\r\n await Promise.all(promises)\r\n if (getIsMounted()) {\r\n setHasNewDataAvailable(false)\r\n window.gtag?.('event', 'load-latest-data', { event_category: 'ideas' })\r\n }\r\n }\r\n\r\n if (!hasNewDataAvailable) {\r\n return null\r\n }\r\n\r\n return (\r\n \r\n }>\r\n \r\n \r\n ) : (\r\n 'refresh'\r\n )\r\n }\r\n disabled={quoteModel?.isFetching}\r\n title=\"Load latest data\"\r\n onClick={handleLoadLatestData}\r\n data-testid=\"load-latest-data-button\"\r\n >\r\n Load latest data\r\n \r\n \r\n )\r\n}\r\n","// Copy if this file is in Website repo in Website/js/main/hooks/ folder\r\nimport * as React from 'react'\r\n\r\nexport function useIsMounted() {\r\n const isMountedRef = React.useRef(false)\r\n const getIsMounted = React.useCallback(() => isMountedRef.current, [])\r\n\r\n React.useEffect(() => {\r\n isMountedRef.current = true\r\n return () => {\r\n isMountedRef.current = false\r\n }\r\n }, [])\r\n\r\n return getIsMounted\r\n}\r\n","import { Button, ButtonGroup, ButtonSizeType, Icon } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport debounce from 'lodash.debounce'\r\nimport React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport Chart from '../../models/chart'\r\nimport Utils from '../../utils'\r\nimport { getLeftOffset } from '../renderUtils'\r\nimport { LoadLatestDataButton } from './load-latest-data-button'\r\n\r\nexport const ZOOM_CONTROLS_ACTIVE_CLASS = 'is-active'\r\nexport const ZOOM_CONTROLS_IS_IN_AREA_CLASS = 'is-in-area'\r\n\r\nconst buttonCommonProps: { size: ButtonSizeType; className: string; contentClass: string } = {\r\n size: 'none',\r\n className: 'w-7 h-6',\r\n contentClass: 'flex justify-center',\r\n}\r\n\r\nconst isMobile = Utils.isMobile()\r\n\r\ninterface ZoomControlsProps {\r\n zoomControlsRef: React.RefObject\r\n isVisible: boolean\r\n chartModel: Chart\r\n onZoomIn: () => void\r\n onZoomOut: () => void\r\n onZoomReset: () => void\r\n}\r\n\r\nconst getDefaultLeftOffset = (chartModel: Chart) =>\r\n getLeftOffset({\r\n quote: chartModel.quote(),\r\n chartModel,\r\n config: {},\r\n })\r\n\r\nexport function ZoomControls({\r\n zoomControlsRef,\r\n chartModel,\r\n isVisible,\r\n onZoomIn,\r\n onZoomOut,\r\n onZoomReset,\r\n}: ZoomControlsProps) {\r\n const chartLayoutModel = useModelState(chartModel.chart_layout(), { watchProperties: ['idea'] })\r\n const [isGoToRecentVisible, setIsGoToRecentVisible] = React.useState(false)\r\n const { defaultZoomFactor } = chartLayoutModel\r\n const [isZoomResetVisible, setIsZoomResetVisible] = React.useState(chartModel.zoomFactor !== defaultZoomFactor)\r\n const handleGoToMostRecent = React.useCallback(() => {\r\n chartModel.updateAttributes({ leftOffset: getDefaultLeftOffset(chartModel), dateRange: null })\r\n }, [chartModel])\r\n\r\n React.useEffect(() => {\r\n const handleChartModelChangeDebounced = debounce(\r\n () => {\r\n setIsZoomResetVisible(chartModel.zoomFactor !== defaultZoomFactor)\r\n setIsGoToRecentVisible(chartModel.leftOffset !== getDefaultLeftOffset(chartModel))\r\n },\r\n 100,\r\n { maxWait: 333 }\r\n )\r\n chartModel.bind('change', handleChartModelChangeDebounced)\r\n return () => {\r\n handleChartModelChangeDebounced.cancel()\r\n chartModel.unbind('change', handleChartModelChangeDebounced)\r\n }\r\n }, [defaultZoomFactor, chartModel])\r\n\r\n return (\r\n \r\n {!isMobile && (\r\n
\r\n {isZoomResetVisible && (\r\n
\r\n \r\n \r\n \r\n \r\n \r\n
\r\n )}\r\n \r\n \r\n \r\n \r\n\r\n \r\n \r\n
\r\n )}\r\n\r\n
\r\n {!!chartLayoutModel.idea?.id && }\r\n\r\n {isGoToRecentVisible && (\r\n \r\n \r\n \r\n \r\n \r\n )}\r\n
\r\n \r\n )\r\n}\r\n","import Spine from '@finviz/spine'\r\nimport { Button, Notification, NotificationContextType, Paragraph, withNotificationContext } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport Hammer from 'hammerjs'\r\nimport debounce from 'lodash.debounce'\r\nimport React from 'react'\r\n\r\nimport { CustomSpineEvents, DrawingSpineOptionsEvent, EmptyObject, ObjectHash, PaneArea } from '../../../types/shared'\r\nimport CanvasElement from '../../canvas/element'\r\nimport ChartEvent from '../../chart-events/chart-event'\r\nimport { IndicatorType, ScaleType, SetVisibilityTo, SpecificChartFunctionality } from '../../constants/common'\r\nimport IndicatorElement from '../../indicators/indicator'\r\nimport { withElementStyleDialogState } from '../../modals/element_style'\r\nimport ChartModel from '../../models/chart'\r\nimport ChartEventElement from '../../models/chart-event-element'\r\nimport ElementModel from '../../models/element'\r\nimport MouseModel from '../../models/mouse'\r\nimport PaneModel from '../../models/pane'\r\nimport Quote from '../../models/quote'\r\nimport { handleRemoveIndicatorPane } from '../../models/utils'\r\nimport Utils, { isRedesignedPage } from '../../utils'\r\nimport { getContextWithCache } from '../../utils/canvas'\r\nimport { getBarWidthWithMargin, unmountCanvas } from '../../utils/chart'\r\nimport { setElementCursor } from '../../utils/cursor'\r\nimport { getValueInRange, isPrimaryClick } from '../../utils/helpers'\r\nimport { getInitialStoreDrawings } from '../autosave/utils'\r\nimport { CHART_LAYOUT_CHILD_CHANGE_EVENT } from '../chart_layout/constants'\r\nimport ContextMenu from '../context_menu'\r\nimport { getMinMaxLeftOffset, getSettings, recountScale, renderPane } from '../renderUtils'\r\nimport { DrawingTool } from '../toolbar/interfaces'\r\nimport { getChartAlt } from '../utils'\r\nimport { ChartEventPopoverWithState } from './chart-event-popover-with-state'\r\nimport { withPaneModel } from './with-pane-model'\r\nimport { ZOOM_CONTROLS_ACTIVE_CLASS, ZOOM_CONTROLS_IS_IN_AREA_CLASS, ZoomControls } from './zoom_controls'\r\n\r\n// Indicates how many time lower/higher can new scale be compared to original one\r\nconst ALLOWED_MIN_MAX_ZOOM = 10000\r\n\r\ninterface PaneProps {\r\n model: PaneModel\r\n chartModel: ChartModel\r\n activeTool: DrawingTool\r\n activeChartInteraction: string | null\r\n chartIndex: number\r\n paneIndex: number\r\n touchEventsDisabled: boolean\r\n onPaneClick: (model: PaneModel) => void\r\n onZoomerReset: () => void\r\n onZoomerMouseDown: React.MouseEventHandler\r\n onZoomerTouchStart: React.TouchEventHandler\r\n onAddToZoomFactor: (data: { diff: number; shouldCalculateRightAlign: boolean }) => void\r\n onResizerMouseDown: (e: React.MouseEvent, model: PaneModel) => void\r\n onPaneDestroy: (paneId: string) => void\r\n setActiveChartInteraction: (value: string | null) => void\r\n openElementStyleDialog?: (element: CanvasElement | IndicatorElement) => void\r\n notificationContext: NotificationContextType\r\n}\r\n\r\ninterface PaneState {\r\n hasSeenCrossNotification: boolean\r\n}\r\n\r\nfunction toggleE2eRenderInProgress({ id, isInProgress }: { id: number; isInProgress: boolean }) {\r\n if (process.env.IS_E2E_TESTING) {\r\n window.rendersInProgress = window.rendersInProgress ?? []\r\n\r\n if (isInProgress) {\r\n window.isRenderInProgress = true\r\n window.rendersInProgress.push(id)\r\n } else {\r\n window.rendersInProgress = window.rendersInProgress.filter((progressId) => id !== progressId)\r\n\r\n if (window.rendersInProgress.length === 0) {\r\n window.isRenderInProgress = Date.now()\r\n }\r\n }\r\n }\r\n}\r\n\r\nclass Pane extends React.Component {\r\n rafId?: number | null = null\r\n crossRafId?: number | null = null\r\n quoteModel: Quote\r\n paneRef = React.createRef()\r\n scalerRef = React.createRef()\r\n zoomerRef = React.createRef()\r\n zoomControlsRef = React.createRef()\r\n canvasWrapperRef = React.createRef()\r\n canvasRef = React.createRef()\r\n crossCanvasRef = React.createRef()\r\n chartLayoutModel = this.props.chartModel.chart_layout()\r\n paneHammer!: HammerManager\r\n scalerHammer!: HammerManager\r\n zoomerHammer!: HammerManager\r\n canvasWrapperHammer!: HammerManager\r\n mouseDown = false\r\n lastClientX?: number\r\n lastClientY?: number\r\n currentViewRange: { min: number; max: number } | null = null\r\n lastX!: number\r\n lastY!: number\r\n lastActiveTool: DrawingTool\r\n scalerLastY: number | null = null\r\n isElementHovered = false\r\n hoveredElement: CanvasElement | null = null\r\n isMobile: boolean\r\n isDisableTouchCrossAvailable = true\r\n\r\n canvas: HTMLCanvasElement | null = null\r\n canvasCtx: CanvasRenderingContext2D | null = null\r\n crossCanvas: HTMLCanvasElement | null = null\r\n crossCanvasCtx: CanvasRenderingContext2D | null = null\r\n isIndicatorPane = false\r\n\r\n state: PaneState = {\r\n hasSeenCrossNotification: !!window.localStorage?.getItem('hasSeenCrossNotification'),\r\n }\r\n\r\n // expects chartModel, model, onResizerMouseDown, onPaneDestroy\r\n constructor(props: PaneProps) {\r\n super(props)\r\n\r\n this.quoteModel = this.props.chartModel.quote()\r\n props.model.updateAttribute('instance', this)\r\n props.model.bind('update', this.onModelUpdate)\r\n props.model\r\n .elements()\r\n .bind('create', this.onElementCreate)\r\n .bind('destroy', this.onElementDestroy)\r\n .bind('replace', this.onElementReplace)\r\n .bind('select', this.onElementSelect)\r\n .bind('makeClone', this.onElementClone)\r\n .bind('change', this.immediateRecountScaleOnChartIndicatorChange)\r\n .bind('change', debounce(this.recountScale, 50))\r\n props.model.bind(CustomSpineEvents.ManualChange, this.recountScale)\r\n\r\n props.model.chartEvents().bind('create', this.onElementCreate).bind('change', debounce(this.recountScale, 50))\r\n\r\n this.props.chartModel.bind('update', this.onChartUpdate)\r\n this.props.chartModel.bind(`change ${CustomSpineEvents.IndicatorsChange}`, this.recountScale)\r\n this.quoteModel.bind('change', this.recountScale)\r\n this.isMobile = !!Utils.isMobile()\r\n this.lastActiveTool = props.activeTool\r\n if (!MouseModel.pane()) {\r\n MouseModel.updateAttribute('pane', props.model)\r\n }\r\n this.isIndicatorPane = props.model.getIsIndicatorPane()\r\n this.recountScale()\r\n }\r\n\r\n componentDidMount() {\r\n const { model } = this.props\r\n this.chartLayoutModel.bind('theme', this.renderAll)\r\n this.chartLayoutModel.bind('theme', this.renderCross)\r\n\r\n const initialStoreDrawings = getInitialStoreDrawings() ?? []\r\n const elements = [...model.getAllElements(), ...model.getAllChartEvents(false)]\r\n elements.forEach((element) => {\r\n this.onElementCreate(element)\r\n if (element.isDrawing()) {\r\n const hasDrawingInInitialCache = initialStoreDrawings.some(({ elementId }) => element.elementId === elementId)\r\n if (hasDrawingInInitialCache) {\r\n element.instance?.updateScales()\r\n }\r\n element.instance.cachePointPositionTimestamp()\r\n } else if (element.isChartEvent()) {\r\n element.instance?.updateScales()\r\n }\r\n })\r\n\r\n model?.updateChartEventsZIndexes()\r\n\r\n this.canvas = this.canvasRef.current\r\n this.canvasCtx = getContextWithCache(this.canvasRef.current)\r\n this.crossCanvas = this.crossCanvasRef.current\r\n this.crossCanvasCtx = getContextWithCache(this.crossCanvasRef.current)\r\n\r\n this.paneHammer = new Hammer.Manager(this.paneRef.current!, { touchAction: 'none' })\r\n this.paneHammer.add(new Hammer.Press({ threshold: 5, time: 500 })) // chrome simulator \"long touch\" -> \"oncontextmenu\" is 680ms +- 2ms\r\n this.paneHammer.on('press', this.onPress)\r\n this.canvasWrapperHammer = new Hammer(this.canvasWrapperRef.current!, { touchAction: 'none' })\r\n this.canvasWrapperHammer.on('tap', this.onClick)\r\n this.canvasWrapperRef.current?.addEventListener('touchmove', this.onTouchMove, { passive: false })\r\n\r\n if (this.chartLayoutModel.scrollable || !this.isMobile) {\r\n if (this.scalerRef.current) {\r\n this.scalerHammer = new Hammer(this.scalerRef.current, { touchAction: 'none' })\r\n this.scalerHammer.on('doubletap', this.onScalerReset)\r\n }\r\n if (this.zoomerRef.current) {\r\n this.zoomerHammer = new Hammer(this.zoomerRef.current, { touchAction: 'none' })\r\n this.zoomerHammer.on('doubletap', this.props.onZoomerReset)\r\n }\r\n this.canvasWrapperHammer.on('doubletap', this.onDoubleClick)\r\n }\r\n\r\n this.onChartUpdate({ width: this.props.chartModel.width })\r\n this.onModelUpdate({ height: model.height })\r\n this.forceUpdate()\r\n this.chartLayoutModel.trigger(CHART_LAYOUT_CHILD_CHANGE_EVENT)\r\n }\r\n\r\n componentWillUnmount() {\r\n this.canvasWrapperRef.current?.removeEventListener('touchmove', this.onTouchMove)\r\n unmountCanvas(this.canvas)\r\n unmountCanvas(this.crossCanvas)\r\n this.props.chartModel.unbind('update', this.onChartUpdate)\r\n this.props.chartModel.unbind('change', this.recountScale)\r\n this.quoteModel.unbind('change', this.recountScale)\r\n }\r\n\r\n render() {\r\n const { activeTool, touchEventsDisabled, onPaneClick, paneIndex, chartIndex, model, chartModel } = this.props\r\n if (touchEventsDisabled) {\r\n this.paneHammer?.set({ touchAction: 'auto' })\r\n this.scalerHammer?.set({ touchAction: 'auto' })\r\n this.zoomerHammer?.set({ touchAction: 'auto' })\r\n this.canvasWrapperHammer?.set({ touchAction: 'auto' })\r\n } else {\r\n const touchAction = this.getIsHammerAllowScrollActive() ? 'auto' : 'none'\r\n this.scalerHammer?.set({ touchAction: 'none' })\r\n this.zoomerHammer?.set({ touchAction: 'none' })\r\n this.paneHammer?.set({ touchAction })\r\n this.canvasWrapperHammer?.set({ touchAction })\r\n }\r\n\r\n const isChartPane = model.getIsChartPane()\r\n\r\n return (\r\n onPaneClick(model)}\r\n onTouchStart={() => onPaneClick(model)}\r\n onContextMenu={this.onContextMenu}\r\n data-testid={`chart-${chartIndex}-pane-${paneIndex}`}\r\n >\r\n {isChartPane && }\r\n {paneIndex !== 0 && (\r\n this.props.onResizerMouseDown(e, model)}\r\n data-testid={`chart-${chartIndex}-pane-${paneIndex}-resizer`}\r\n />\r\n )}\r\n {this.chartLayoutModel.initialScrollable && (\r\n \r\n )}\r\n\r\n {this.chartLayoutModel.initialScrollable && isChartPane && (\r\n <>\r\n \r\n {\r\n this.props.onAddToZoomFactor({ diff: 0.1, shouldCalculateRightAlign: true })\r\n }}\r\n onZoomOut={() => {\r\n this.props.onAddToZoomFactor({ diff: -0.1, shouldCalculateRightAlign: true })\r\n }}\r\n onZoomReset={this.props.onZoomerReset}\r\n />\r\n \r\n )}\r\n \r\n {getChartAlt(this.quoteModel)}\r\n {this.chartLayoutModel.cross && }\r\n \r\n \r\n )\r\n }\r\n\r\n getIsHammerAllowScrollActive = () =>\r\n this.chartLayoutModel.specificChartFunctionality !== SpecificChartFunctionality.chartPage &&\r\n !this.chartLayoutModel.isTouchCrossActive &&\r\n !this.chartLayoutModel.scrollable\r\n\r\n onElementCreate = (el: ElementModel | ChartEventElement) => {\r\n el.instance.bind('change', this.renderAll)\r\n this.renderAll()\r\n }\r\n\r\n onElementReplace = (el: ElementModel, oldElementInstance: CanvasElement) => {\r\n oldElementInstance.unbind('change', this.renderAll)\r\n el.instance.bind('change', this.renderAll)\r\n if (oldElementInstance === this.props.model.selection && !this.chartLayoutModel.isDrawingModeContinuousActive) {\r\n this.setSelection(el.instance)\r\n } else {\r\n this.setSelection(null)\r\n }\r\n this.renderAll()\r\n }\r\n\r\n onElementDestroy = (el: ElementModel) => {\r\n const { type } = el.instance\r\n el.instance.unbind('change', this.renderAll)\r\n if (el.instance === this.props.model.selection) {\r\n this.setSelection(null)\r\n }\r\n if (type.startsWith('charts/') || type.startsWith('indicators/')) {\r\n this.props.onPaneDestroy(el['pane_id'])\r\n }\r\n this.renderAll()\r\n }\r\n\r\n onElementSelect = (el: ElementModel) => {\r\n this.setSelectedElement(el.instance)\r\n }\r\n\r\n onElementClone = (_: unknown, clonedElementInstance: CanvasElement) => {\r\n this.setSelectedElement(clonedElementInstance)\r\n }\r\n\r\n onModelUpdate = ({ height }: { height: number }) => {\r\n this.setCanvasSize({\r\n width: this.props.chartModel.width,\r\n height,\r\n })\r\n }\r\n\r\n onChartUpdate = ({ width }: { width: number }) => {\r\n const { model, chartModel } = this.props\r\n this.setCanvasSize({\r\n width,\r\n height: model.height,\r\n })\r\n const quote = chartModel.quote()\r\n if (!this.quoteModel.eql(quote)) {\r\n this.quoteModel.unbind('change', this.recountScale)\r\n if (quote) {\r\n this.quoteModel = quote\r\n this.quoteModel.bind('change', this.recountScale)\r\n }\r\n }\r\n }\r\n\r\n onZoomerMouseMove: React.MouseEventHandler = (e) => {\r\n if (!this.chartLayoutModel.scrollable || (this.isMobile && !this.chartLayoutModel.isTouchCrossActive)) return\r\n const area = this.getArea(e)\r\n MouseModel.updateAttributes({\r\n position: { x: area.x, y: null },\r\n pane: this.props.model,\r\n })\r\n }\r\n\r\n onMouseMoveOnScrolling = (event: TouchEvent | MouseEvent) => {\r\n if (this.props.activeChartInteraction) {\r\n return\r\n }\r\n\r\n let { clientX, clientY } = event as MouseEvent\r\n const { model } = this.props\r\n\r\n const isTouch = typeof TouchEvent !== 'undefined' && event instanceof TouchEvent\r\n if (isTouch && event.targetTouches?.length > 0) {\r\n clientX = event.targetTouches[0].clientX\r\n clientY = event.targetTouches[0].clientY\r\n }\r\n if (!model.selection && !this.chartLayoutModel.activeChartEvent) {\r\n if (this.lastClientX != null) {\r\n const dif = this.lastClientX - clientX\r\n this.addToLeftOffset(-dif)\r\n }\r\n if (model.scaleRange && this.lastClientY != null) {\r\n let { min, max } = model.scaleRange\r\n let difY\r\n switch (this.props.chartModel.scale) {\r\n case ScaleType.Logarithmic: {\r\n difY = this.lastClientY - clientY\r\n min = model.scale.y.invert(model.scale.y(min) + difY)\r\n max = model.scale.y.invert(model.scale.y(max) + difY)\r\n break\r\n }\r\n default: {\r\n difY = (this.lastClientY - clientY) * (model.scale.y.invert(0) - model.scale.y.invert(1))\r\n min -= difY\r\n max -= difY\r\n break\r\n }\r\n }\r\n\r\n model.updateAttribute('scaleRange', { min, max })\r\n this.recountScale()\r\n this.currentViewRange = this.props.model.getChartOrIndicatorElement()?.instance?.getMinMax?.() ?? null\r\n }\r\n }\r\n this.lastClientX = clientX\r\n this.lastClientY = clientY\r\n }\r\n\r\n onScalerTouchStart: React.TouchEventHandler = (e) => {\r\n if (!this.chartLayoutModel.scrollable || this.props.touchEventsDisabled) return\r\n if (this.chartLayoutModel.scrollable && e.targetTouches.length === 1) {\r\n this.onScalerMouseDown(e.targetTouches[0])\r\n }\r\n }\r\n\r\n onScalerTouchMove = (e: TouchEvent) => {\r\n if (this.chartLayoutModel.scrollable && e.targetTouches.length === 1) {\r\n this.onScalerMouseMove(e.targetTouches[0])\r\n }\r\n }\r\n\r\n onScalerTouchEnd = () => {\r\n if (this.chartLayoutModel.scrollable) {\r\n this.onScalerMouseUp()\r\n }\r\n }\r\n\r\n onScalerMouseEnter = () => {\r\n MouseModel.updateAttributes({\r\n position: null,\r\n pane: null,\r\n })\r\n }\r\n\r\n onScalerMouseDown = (event: React.MouseEvent | React.Touch) => {\r\n const { activeChartInteraction, setActiveChartInteraction, model } = this.props\r\n if ((event instanceof MouseEvent && event.button) || activeChartInteraction || !this.chartLayoutModel.scrollable) {\r\n return\r\n }\r\n setActiveChartInteraction('scaler')\r\n\r\n this.scalerLastY = event.clientY\r\n // here we need current domain scale or former \"nice\" value\r\n const [currentDomainMax, currentDomainMin] = model.scale.y.domain()\r\n this.currentViewRange = { min: currentDomainMin, max: currentDomainMax }\r\n document.addEventListener<'mousemove'>('mousemove', this.onScalerMouseMove)\r\n document.addEventListener('mouseup', this.onScalerMouseUp)\r\n document.addEventListener('touchmove', this.onScalerTouchMove)\r\n document.addEventListener('touchend', this.onScalerTouchEnd)\r\n }\r\n\r\n onScalerMouseMove = (event: MouseEvent | Touch) => {\r\n const { model, chartModel } = this.props\r\n if (model.scaleRange === null && this.currentViewRange === null) {\r\n return\r\n }\r\n let { min, max } = model.scaleRange || this.currentViewRange!\r\n let difY\r\n switch (this.props.chartModel.scale) {\r\n case ScaleType.Logarithmic: {\r\n difY = this.scalerLastY! - event.clientY\r\n min = model.scale.y.invert(model.scale.y(min) - difY)\r\n max = model.scale.y.invert(model.scale.y(max) + difY)\r\n break\r\n }\r\n default: {\r\n difY = -(this.scalerLastY! - event.clientY) * (model.scale.y.invert(0) - model.scale.y.invert(1))\r\n min -= difY\r\n max += difY\r\n break\r\n }\r\n }\r\n this.scalerLastY = event.clientY\r\n\r\n const originalMinMax = model.getChartOrIndicatorElement()?.instance?.getMinMax?.()\r\n if (originalMinMax) {\r\n const currentDiff = Math.abs(max - min)\r\n const originalDiff = Math.abs(originalMinMax.max - originalMinMax.min)\r\n\r\n if (currentDiff > originalDiff * ALLOWED_MIN_MAX_ZOOM || currentDiff < originalDiff / ALLOWED_MIN_MAX_ZOOM) {\r\n return\r\n }\r\n }\r\n\r\n model.updateAttribute('scaleRange', { min, max })\r\n chartModel.updateAttribute('dateRange', null)\r\n this.recountScale()\r\n }\r\n\r\n onScalerMouseUp = () => {\r\n this.scalerLastY = null\r\n\r\n document.removeEventListener('mousemove', this.onScalerMouseMove)\r\n document.removeEventListener('mouseup', this.onScalerMouseUp)\r\n document.removeEventListener('touchmove', this.onScalerTouchMove)\r\n document.removeEventListener('touchend', this.onScalerTouchEnd)\r\n this.props.setActiveChartInteraction(null)\r\n }\r\n\r\n onScalerReset = () => {\r\n const { model, chartModel } = this.props\r\n if (!this.chartLayoutModel.scrollable) return\r\n chartModel.updateAttribute('dateRange', null)\r\n model.updateAttribute('scaleRange', null)\r\n this.recountScale()\r\n }\r\n\r\n addToLeftOffset = (n: number) => {\r\n const quote = this.props.chartModel.quote()\r\n const barWidth = getBarWidthWithMargin({\r\n chartLayout: this.chartLayoutModel,\r\n zoomFactor: this.props.chartModel.zoomFactor,\r\n })\r\n const leftOffset = getMinMaxLeftOffset({\r\n newLeftOffset: this.props.chartModel.leftOffset + n,\r\n chartModel: this.props.chartModel,\r\n barWidth,\r\n barIndex: quote.barIndex[quote.open.length - 1],\r\n })\r\n\r\n if (leftOffset > barWidth) {\r\n quote.fetchOlderData()\r\n }\r\n this.props.chartModel.updateAttributes({\r\n leftOffset,\r\n dateRange: null,\r\n })\r\n }\r\n\r\n onDoubleClick = (event: HammerInput) => {\r\n event.preventDefault()\r\n const area = this.getArea(event)\r\n const element = this.props.model.selection || this.getElement(area)\r\n if (element && element.type !== IndicatorType.Cot && !element.isCreator) {\r\n setTimeout(() => {\r\n this.props.openElementStyleDialog!(element)\r\n }, 0)\r\n element.trigger('dblclick', event)\r\n }\r\n }\r\n\r\n onPress = (e: ObjectHash) => {\r\n if (e.pointerType !== 'touch') return\r\n\r\n e.clientX = e.center.x\r\n e.clientY = e.center.y\r\n\r\n const el = this.props.model.selection || this.getElement(this.getArea(e))\r\n if (!this.chartLayoutModel.isTouchCrossActive) {\r\n if (!el) {\r\n this.onCanvasPress(e as React.MouseEvent)\r\n } else {\r\n this.onContextMenu(e as React.MouseEvent, el)\r\n }\r\n }\r\n }\r\n\r\n onContextMenu = (e: React.MouseEvent, element?: IndicatorElement | CanvasElement) => {\r\n e.preventDefault()\r\n const area = this.getArea(e)\r\n const elementInArea = this.getElement(area)\r\n const el = element ?? elementInArea\r\n if (!el || el.thumbsAreInArea(area)) {\r\n return\r\n }\r\n const elementModel = ElementModel.findByAttribute('instance', el)\r\n if (!elementModel) return\r\n this.setSelectedElement(el)\r\n const hasProperties =\r\n ['indicator', 'canvas'].some((type) => el.type.startsWith(type)) && el.type !== IndicatorType.Cot\r\n const isElementDrawing = elementModel.isDrawing()\r\n\r\n return ContextMenu.show(\r\n e,\r\n [\r\n hasProperties && {\r\n id: 'edit',\r\n label: 'Edit style',\r\n onClick: () => this.props.openElementStyleDialog!(el),\r\n },\r\n\r\n !(elementModel.isChart() || elementModel?.isIndicator()) && {\r\n id: 'clone',\r\n label: 'Clone',\r\n onClick: () => elementModel.makeClone(),\r\n },\r\n\r\n ...(isElementDrawing\r\n ? [\r\n { type: 'divider', label: 'Visibility' },\r\n\r\n {\r\n id: 'visibility-current-and-above',\r\n label: 'Current interval and above',\r\n onClick: () => elementModel.instance.setVisibilityTo(SetVisibilityTo.currentAndAbove),\r\n },\r\n\r\n {\r\n id: 'visibility-current-and-below',\r\n label: 'Current interval and below',\r\n onClick: () => elementModel.instance.setVisibilityTo(SetVisibilityTo.currentAndBelow),\r\n },\r\n\r\n {\r\n id: 'visibility-current-only',\r\n label: 'Current interval only',\r\n onClick: () => elementModel.instance.setVisibilityTo(SetVisibilityTo.currentOnly),\r\n },\r\n\r\n {\r\n id: 'visibility-all-intervals',\r\n label: 'All intervals',\r\n onClick: () => elementModel.instance.setVisibilityTo(SetVisibilityTo.all),\r\n },\r\n ]\r\n : []),\r\n\r\n (isElementDrawing || hasProperties) && { type: 'divider' },\r\n\r\n {\r\n id: 'bring-to-front',\r\n label: 'Bring to Front',\r\n onClick: () => elementModel.bringToFront(),\r\n },\r\n {\r\n id: 'send-to-back',\r\n label: 'Send to Back',\r\n onClick: () => elementModel.sendToBack(),\r\n },\r\n {\r\n id: 'bring-forward',\r\n label: 'Bring Forward',\r\n onClick: () => elementModel.bringForward(),\r\n },\r\n {\r\n id: 'send-backward',\r\n label: 'Send Backward',\r\n onClick: () => elementModel.sendBackward(),\r\n },\r\n\r\n { type: 'divider' },\r\n\r\n {\r\n id: 'remove',\r\n label: 'Remove',\r\n onClick: () => {\r\n if (elementModel.isIndicator()) {\r\n handleRemoveIndicatorPane({ paneIndex: this.props.paneIndex, chartLayoutModel: this.chartLayoutModel })\r\n } else {\r\n elementModel.destroyCascade({ eventType: DrawingSpineOptionsEvent.Remove })\r\n this.props.model.normalizeZIndexes()\r\n }\r\n },\r\n },\r\n ]\r\n .filter(Boolean)\r\n .map((item) => ({ ...item, gtag: { element_type: el.type } }))\r\n )\r\n }\r\n\r\n immediateRecountScaleOnChartIndicatorChange = (element?: ElementModel) => {\r\n if (element?.isChart() || element?.isIndicator()) {\r\n this.recountScale()\r\n }\r\n }\r\n\r\n recountScale = (_?: unknown, updateType?: Spine.Event) => {\r\n const { model } = this.props\r\n const chartModel = model.chart()\r\n if (updateType === 'destroy' || !chartModel || !chartModel.quote()) {\r\n return\r\n }\r\n\r\n recountScale({ chartModel, paneModel: model })\r\n\r\n if (this.canvasCtx) {\r\n this.renderAll()\r\n }\r\n }\r\n\r\n onBlur = () => {\r\n if (this.props.model.selection?.getIsCreator?.()) {\r\n this.setSelection(null)\r\n } else {\r\n this.setSelectedElement(null)\r\n }\r\n if (this.hoveredElement) {\r\n this.hoveredElement.setIsHovered(false)\r\n this.hoveredElement = null\r\n }\r\n this.props.model.getAllElements().forEach((element) => {\r\n if (element.instance.getIsCreator?.() && !element.instance.getIsCreatorDialogOpen?.()) {\r\n element.destroyCascade()\r\n }\r\n })\r\n }\r\n\r\n renderAll = (type?: string) => {\r\n if (process.env.IS_E2E_TESTING) window.isRenderInProgress = true\r\n\r\n if (type === 'cross' && this.chartLayoutModel.cross) {\r\n if (this.crossRafId === null) {\r\n const crossRafId = window.requestAnimationFrame(() => {\r\n this.renderCross()\r\n if (process.env.IS_E2E_TESTING) {\r\n toggleE2eRenderInProgress({ id: crossRafId, isInProgress: false })\r\n }\r\n })\r\n if (process.env.IS_E2E_TESTING) {\r\n toggleE2eRenderInProgress({ id: crossRafId, isInProgress: true })\r\n }\r\n this.crossRafId = crossRafId\r\n }\r\n } else if (this.rafId == null && this.canvasCtx) {\r\n const rafId = window.requestAnimationFrame(() => {\r\n this._renderAll()\r\n if (process.env.IS_E2E_TESTING) {\r\n toggleE2eRenderInProgress({ id: rafId, isInProgress: false })\r\n }\r\n })\r\n if (process.env.IS_E2E_TESTING) {\r\n toggleE2eRenderInProgress({ id: rafId, isInProgress: true })\r\n }\r\n this.rafId = rafId\r\n }\r\n }\r\n\r\n _renderAll = () => {\r\n const { model } = this.props\r\n // _renderAll may be called after Chart was deleted because of requestAnimationFrame\r\n if (model.chart() === null || this.canvasRef.current === null || !this.canvasCtx) {\r\n return\r\n }\r\n if (this.getIsUpdatedDesign()) {\r\n if (this.crossRafId === null) {\r\n this.crossRafId = window.requestAnimationFrame(this.renderCross)\r\n }\r\n }\r\n this.rafId = undefined\r\n\r\n renderPane({\r\n chartLayoutModel: this.chartLayoutModel,\r\n chartModel: this.props.chartModel,\r\n paneModel: model,\r\n canvasCtx: this.canvasCtx,\r\n })\r\n }\r\n\r\n getIsUpdatedDesign() {\r\n const { specificChartFunctionality } = this.chartLayoutModel\r\n const isCharts = specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const isRedesignedFuturesForexCrypto = isRedesignedPage({ specificChartFunctionality })\r\n\r\n return isCharts || isRedesignedFuturesForexCrypto\r\n }\r\n\r\n renderCross = () => {\r\n const { model } = this.props\r\n const isMouseInPane = MouseModel.getShouldRenderCrossInPane(model)\r\n this.crossRafId = null\r\n if (!this.crossCanvasCtx) {\r\n return\r\n }\r\n this.crossCanvasCtx.clearRect(0, 0, this.props.chartModel.width, model.height)\r\n const isCrossDisabled =\r\n PaneModel.select((p) => !!p.selection && !p.selection.type.startsWith('indicators/')).length !== 0 ||\r\n this.props.chartModel.getIsDisabled() ||\r\n !isMouseInPane\r\n\r\n for (const { instance: elementInstance } of model.getAllElements()) {\r\n if (\r\n (!isCrossDisabled && elementInstance.renderCross != null) ||\r\n (isCrossDisabled && elementInstance.renderCrossText != null)\r\n ) {\r\n this.crossCanvasCtx.save()\r\n if (isCrossDisabled) {\r\n elementInstance.renderCrossText!(this.crossCanvasCtx, Number.NaN)\r\n } else {\r\n elementInstance.renderCross!(this.crossCanvasCtx)\r\n }\r\n this.crossCanvasCtx.restore()\r\n }\r\n }\r\n }\r\n\r\n getArea = (e: ObjectHash, additionalData?: T): PaneArea => {\r\n const { model } = this.props\r\n const clientX = e.clientX || additionalData?.clientX\r\n const clientY = e.clientY || additionalData?.clientY\r\n const Settings = getSettings(model)\r\n const areaRectangle = this.canvas!.getBoundingClientRect()\r\n const areaRectangleCursorX = clientX - areaRectangle.left\r\n const areaRectangleCursorY = clientY - areaRectangle.top\r\n const x = areaRectangleCursorX - model.chart().leftOffset - Settings.left.width\r\n const y = areaRectangleCursorY - Settings.top.height\r\n const scale = model.scale\r\n const chartLeftX = areaRectangle.left + Settings.left.width\r\n const chartRightX = areaRectangle.right - Settings.right.width\r\n return {\r\n ...(additionalData as T),\r\n // TODO: rewrite if canvas uses padding/border\r\n x: scale.x.invert(x),\r\n y: scale.y.invert(y),\r\n scaled: {\r\n x,\r\n y,\r\n },\r\n width: 1,\r\n height: 1,\r\n cursorX: areaRectangleCursorX,\r\n cursorY: areaRectangleCursorY,\r\n isCursorInChartWidthBoundaries: clientX > chartLeftX && clientX < chartRightX,\r\n }\r\n }\r\n\r\n setCanvasSize = ({ width, height }: { width: number; height: number }) => {\r\n const ratio = Utils.getScaleRatio()\r\n const canvasElement = this.canvasRef.current\r\n\r\n /**\r\n * It seems that value passed into element attr (e.g. height) is ceiled down,\r\n * so if you provide canvas element with height 100.5 we'll get integer 100 from canvasElement.height\r\n * If the difference in values between \"new height\" and canvasElement.height is less than 1, I treat it as the same value\r\n */\r\n if (\r\n this.canvasCtx &&\r\n canvasElement &&\r\n (Math.abs(height * ratio - canvasElement.height) >= 1 || Math.abs(width * ratio - canvasElement.width) >= 1)\r\n ) {\r\n Utils.setSizeOnCanvasElement({ canvasElement, width, height })\r\n this.canvasCtx.scale(ratio, ratio)\r\n if (this.chartLayoutModel.cross && this.crossCanvasCtx) {\r\n Utils.setSizeOnCanvasElement({\r\n canvasElement: this.crossCanvasRef.current,\r\n width,\r\n height,\r\n })\r\n this.crossCanvasCtx.scale(ratio, ratio)\r\n }\r\n setTimeout(() => {\r\n this.recountScale()\r\n })\r\n }\r\n }\r\n\r\n onClick = (event: HammerInput) => {\r\n const area = this.getArea(event, {\r\n clientX: event.center.x,\r\n clientY: event.center.y,\r\n })\r\n const element = this.props.model.selection || this.getElement(area)\r\n element?.trigger('click', area)\r\n\r\n if (!this.isDisableTouchCrossAvailable) {\r\n this.isDisableTouchCrossAvailable = true\r\n return\r\n }\r\n\r\n if (this.chartLayoutModel.isTouchCrossActive) {\r\n MouseModel.updateAttributes({\r\n position: null,\r\n pane: null,\r\n })\r\n this.chartLayoutModel.updateAttributes({\r\n scrollable: this.chartLayoutModel.initialScrollable,\r\n isTouchCrossActive: false,\r\n })\r\n } else if (\r\n this.isMobile &&\r\n !this.state.hasSeenCrossNotification &&\r\n this.lastActiveTool === DrawingTool.Mouse &&\r\n this.chartLayoutModel.specificChartFunctionality !== SpecificChartFunctionality.smallIndex\r\n ) {\r\n const isChartsPage = this.chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n\r\n this.setState({ hasSeenCrossNotification: true })\r\n this.props.notificationContext.show(\r\n {\r\n this.props.notificationContext.hide()\r\n window.localStorage.setItem('hasSeenCrossNotification', 'true')\r\n }}\r\n theme=\"dark\"\r\n >\r\n Got it\r\n \r\n }\r\n >\r\n Long press the chart to show the crosshair.\r\n ,\r\n { inline: !isChartsPage }\r\n )\r\n }\r\n\r\n this.lastActiveTool = this.props.activeTool\r\n }\r\n\r\n onPaneMouseLeave = () => {\r\n // timout in onPaneMouseMove may cause racecondition where active class is added right after it's been removed\r\n setTimeout(() => {\r\n this.zoomControlsRef.current?.classList.remove(ZOOM_CONTROLS_ACTIVE_CLASS, ZOOM_CONTROLS_IS_IN_AREA_CLASS)\r\n })\r\n if (this.chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage) {\r\n this.renderCross()\r\n }\r\n }\r\n\r\n onPaneMouseMove = (e: React.MouseEvent | React.Touch, isMouseDownIgnored = false) => {\r\n const { model, chartModel } = this.props\r\n const zoomControls = this.zoomControlsRef.current\r\n const paneHeight = model.height\r\n if (zoomControls) {\r\n const area = this.getArea<{ mouseDown: boolean; clientX: number; clientY: number }>(e, {\r\n mouseDown: !isMouseDownIgnored && this.mouseDown,\r\n clientX: e.clientX,\r\n clientY: e.clientY,\r\n })\r\n\r\n // timeout is needed here as adding a classname on parent element of a button where we are listening on a click is not working properly if done synchrnousely\r\n setTimeout(() => {\r\n // 103 is the destance between pane bottom and zoom-controls top\r\n // zoomer bottom (8 px) + zoomer height (20px) - 13px + zoom controls height (75px) = 90px\r\n const isInArea = model.height - 90 <= area.cursorY && paneHeight > 210\r\n\r\n if (\r\n isInArea &&\r\n !zoomControls.classList.contains(ZOOM_CONTROLS_IS_IN_AREA_CLASS) &&\r\n !chartModel.getIsDisabled()\r\n ) {\r\n zoomControls.classList.add(ZOOM_CONTROLS_IS_IN_AREA_CLASS)\r\n } else if (!isInArea && zoomControls.classList.contains(ZOOM_CONTROLS_IS_IN_AREA_CLASS)) {\r\n zoomControls.classList.remove(ZOOM_CONTROLS_IS_IN_AREA_CLASS)\r\n }\r\n\r\n if (!area.mouseDown && !model.selection && isInArea && !chartModel.getIsDisabled()) {\r\n if (!zoomControls.classList.contains(ZOOM_CONTROLS_ACTIVE_CLASS)) {\r\n zoomControls.classList.add(ZOOM_CONTROLS_ACTIVE_CLASS)\r\n }\r\n } else if (zoomControls.classList.contains(ZOOM_CONTROLS_ACTIVE_CLASS)) {\r\n zoomControls.classList.remove(ZOOM_CONTROLS_ACTIVE_CLASS)\r\n }\r\n })\r\n }\r\n }\r\n\r\n onMouseLeave = () => {\r\n this.mouseDown = false\r\n }\r\n\r\n onTouchStart = (e: React.TouchEvent) => {\r\n if (!this.props.touchEventsDisabled && e.targetTouches.length === 1) {\r\n const touchEvent = e.targetTouches[0]\r\n if (this.chartLayoutModel.scrollable) {\r\n this.onCanvasInteractionStart(touchEvent)\r\n } else if (this.chartLayoutModel.isTouchCrossActive) {\r\n this.lastClientX = touchEvent.clientX\r\n this.lastClientY = touchEvent.clientY\r\n if (!MouseModel.pane()?.eql(this.props.model)) {\r\n const area = this.getArea(touchEvent, {\r\n mouseDown: this.mouseDown,\r\n clientX: touchEvent.clientX,\r\n clientY: touchEvent.clientY,\r\n })\r\n this.setMousePosition(this.getMousePositionInBoundaries(area))\r\n this.isDisableTouchCrossAvailable = false\r\n }\r\n } else {\r\n const area = this.getArea(touchEvent, { isTouch: true }) // passing isTouch is pretty confusing, it's used in Tools.jsx -> onMouseDown method\r\n const element = this.getElement(area)\r\n if (element?.getIsChartEvent?.()) {\r\n const chartEventElement = element as ChartEvent\r\n chartEventElement.toggleIsOpen()\r\n }\r\n }\r\n this.onPaneMouseMove(touchEvent, true)\r\n }\r\n }\r\n\r\n onTouchMove = (e: TouchEvent) => {\r\n if (!this.props.touchEventsDisabled) {\r\n if (!this.getIsHammerAllowScrollActive()) {\r\n e.preventDefault()\r\n }\r\n if (!this.props.touchEventsDisabled && e.targetTouches.length === 1) {\r\n this.onCanvasInteractionMove(e.targetTouches[0])\r\n }\r\n }\r\n }\r\n\r\n onTouchEnd = (e: React.TouchEvent) => {\r\n if (!this.props.touchEventsDisabled && this.chartLayoutModel.scrollable) {\r\n this.onCanvasInteractionEnd(e)\r\n }\r\n }\r\n\r\n onCanvasPress = (e: React.MouseEvent) => {\r\n if (this.chartLayoutModel.scrollable) {\r\n this.chartLayoutModel.updateAttribute('scrollable', false)\r\n document.removeEventListener('touchmove', this.onMouseMoveOnScrolling)\r\n }\r\n if (!this.chartLayoutModel.isTouchCrossActive) {\r\n this.chartLayoutModel.updateAttribute('isTouchCrossActive', true)\r\n this.onCanvasInteractionMove(e)\r\n }\r\n }\r\n\r\n onCanvasInteractionStart = (e: React.Touch | React.MouseEvent) => {\r\n const { activeTool, activeChartInteraction, chartModel, model } = this.props\r\n const isTouch = typeof Touch !== 'undefined' && e instanceof Touch\r\n this.lastActiveTool = activeTool\r\n\r\n if (isPrimaryClick(e) && !activeChartInteraction && !chartModel.getIsDisabled()) {\r\n const area = this.getArea(e, { isTouch }) // passing isTouch is pretty confusing, it's used in Tools.jsx -> onMouseDown method\r\n const element = this.getElement(area)\r\n\r\n // if user click outside of drawable area but still inside canvas creator would hang unfinised,\r\n // it that case we want to cancel element creation, same as we do on click outside of canvas / onBlur\r\n if (model.selection?.isCreator && !area.isCursorInChartWidthBoundaries && element !== model.selection) {\r\n model.getAllElements().forEach((element) => {\r\n if (element.instance.getIsCreator?.() && !element.instance.getIsCreatorDialogOpen?.()) {\r\n element.destroyCascade()\r\n }\r\n })\r\n }\r\n if (this.chartLayoutModel.scrollable) {\r\n setElementCursor({ elementId: this.chartLayoutModel.getHTMLElementId(), cursor: 'grabbing' })\r\n if (model.scaleRange) {\r\n this.currentViewRange = model.getChartOrIndicatorElement()?.instance?.getMinMax?.() ?? null\r\n }\r\n document.addEventListener(isTouch ? 'touchmove' : 'mousemove', this.onMouseMoveOnScrolling)\r\n document.addEventListener(isTouch ? 'touchend' : 'mouseup', this.onCanvasInteractionEnd)\r\n }\r\n if (element?.getIsChartEvent?.()) {\r\n this.setSelectedElement(null)\r\n const chartEventElement = element as ChartEvent\r\n chartEventElement.toggleIsOpen()\r\n } else if (\r\n activeTool === DrawingTool.Mouse ||\r\n model.getAllElements().some(({ instance }) => instance.isCreator)\r\n ) {\r\n element?.trigger('mousedown', area)\r\n this.setSelectedElement(element)\r\n }\r\n model.trigger('mousedown', model, area, element)\r\n this.mouseDown = true\r\n this.lastX = area.x\r\n this.lastY = area.y\r\n }\r\n\r\n this.lastClientX = e.clientX\r\n this.lastClientY = e.clientY\r\n }\r\n\r\n onCanvasInteractionMove = (e: React.MouseEvent | React.Touch) => {\r\n const area = this.getArea(e, {\r\n mouseDown: this.mouseDown,\r\n clientX: e.clientX,\r\n clientY: e.clientY,\r\n })\r\n if (!area.isCursorInChartWidthBoundaries) {\r\n MouseModel.updateAttributes({\r\n position: null,\r\n pane: null,\r\n })\r\n return\r\n }\r\n\r\n const { model } = this.props\r\n const hoveredElement = this.getElement(area)\r\n const element = model.selection || hoveredElement\r\n\r\n if (!(this.isMobile && !this.chartLayoutModel.isTouchCrossActive)) {\r\n this.isDisableTouchCrossAvailable = true\r\n this.setMousePosition(\r\n this.lastClientX && this.lastClientY && this.chartLayoutModel.isTouchCrossActive && MouseModel.position\r\n ? this.getMousePositionInBoundaries({\r\n x: MouseModel.position.x + (model.scale.x.invert(area.clientX) - model.scale.x.invert(this.lastClientX)),\r\n y: MouseModel.position.y + (model.scale.y.invert(area.clientY) - model.scale.y.invert(this.lastClientY)),\r\n })\r\n : { x: area.x, y: area.y }\r\n )\r\n }\r\n\r\n if (!this.chartLayoutModel.scrollable) {\r\n this.lastClientX = area.clientX\r\n this.lastClientY = area.clientY\r\n }\r\n\r\n element?.trigger('mousemove', area)\r\n if (\r\n this.mouseDown &&\r\n model.selection instanceof CanvasElement &&\r\n !model.selection.activeThumb &&\r\n !this.chartLayoutModel.activeChartEvent\r\n ) {\r\n if (!model.selection.getIsCreator?.()) {\r\n model.selection.moveBy(area.x - this.lastX, area.y - this.lastY)\r\n }\r\n this.lastX = area.x\r\n this.lastY = area.y\r\n this.renderAll()\r\n }\r\n const isElementHovered =\r\n this.props.activeTool === DrawingTool.Mouse &&\r\n ((element && element === hoveredElement) || hoveredElement instanceof CanvasElement)\r\n\r\n if (hoveredElement !== this.hoveredElement && this.hoveredElement instanceof CanvasElement) {\r\n this.hoveredElement.setIsHovered(false)\r\n this.hoveredElement = null\r\n }\r\n\r\n if (isElementHovered && hoveredElement instanceof CanvasElement) {\r\n if (!hoveredElement.isHovered && !hoveredElement.isSelected) {\r\n hoveredElement.setIsHovered(true)\r\n this.hoveredElement = hoveredElement\r\n }\r\n }\r\n\r\n if (isElementHovered !== this.isElementHovered && this.canvas && hoveredElement?.type !== IndicatorType.Cot) {\r\n this.canvas.className = isElementHovered ? 'hover' : ''\r\n if (this.chartLayoutModel.cross && this.crossCanvas) {\r\n this.crossCanvas.className = `second${isElementHovered ? ' hover' : ''}`\r\n }\r\n this.isElementHovered = isElementHovered\r\n }\r\n }\r\n\r\n onCanvasInteractionEnd = (event: TouchEvent | MouseEvent | React.TouchEvent) => {\r\n if (MouseModel.position) {\r\n setElementCursor({ elementId: this.chartLayoutModel.getHTMLElementId(), cursor: 'crosshair' })\r\n } else {\r\n setElementCursor({ elementId: this.chartLayoutModel.getHTMLElementId(), cursor: 'default' })\r\n }\r\n const isTouch = typeof TouchEvent !== 'undefined' && event instanceof TouchEvent\r\n this.mouseDown = false\r\n const area = this.getArea(event)\r\n const element = this.props.model.selection || this.getElement(area)\r\n element?.trigger('mouseup', area)\r\n document.removeEventListener(isTouch ? 'touchmove' : 'mousemove', this.onMouseMoveOnScrolling)\r\n document.removeEventListener(isTouch ? 'touchend' : 'mouseup', this.onCanvasInteractionEnd)\r\n }\r\n\r\n getMousePositionInBoundaries = ({ x, y }: { x: number; y: number }) => {\r\n const { model } = this.props\r\n const Settings = getSettings(model)\r\n const canvasAreaRectangle = this.canvas!.getBoundingClientRect()\r\n const chartLeft = model.scale.x.invert(-model.chart().leftOffset + 1)\r\n const chartRight = model.scale.x.invert(\r\n canvasAreaRectangle.width - Settings.right.width - Settings.left.width - model.chart().leftOffset - 1\r\n )\r\n const chartTop = model.scale.y.invert(0)\r\n const chartBottom = model.scale.y.invert(canvasAreaRectangle.height - Settings.bottom.height - Settings.top.height)\r\n\r\n return {\r\n x: getValueInRange({\r\n value: x,\r\n min: chartLeft,\r\n max: chartRight,\r\n }),\r\n y: getValueInRange({\r\n value: y,\r\n min: chartBottom,\r\n max: chartTop,\r\n }),\r\n }\r\n }\r\n\r\n setMousePosition = ({ x, y }: { x: number; y: number }) => {\r\n const isSameMouseModel = !!MouseModel.pane()?.eql(this.props.model)\r\n MouseModel.updateAttributes({\r\n position: { x, y },\r\n ...(isSameMouseModel ? {} : { pane: this.props.model }),\r\n })\r\n }\r\n\r\n setSelection = (selection: IndicatorElement | CanvasElement | null) => {\r\n if (selection instanceof CanvasElement) {\r\n selection?.setIsSelected(true)\r\n }\r\n\r\n this.props.model.updateAttribute('selection', selection)\r\n }\r\n\r\n setSelectedElement = (element: IndicatorElement | CanvasElement | null) => {\r\n const { selection } = this.props.model\r\n const isSelectionCanvas = selection instanceof CanvasElement\r\n if (element !== selection || (isSelectionCanvas && element && !selection?.isSelected)) {\r\n if (isSelectionCanvas) {\r\n selection?.setIsSelected(false)\r\n }\r\n if (isSelectionCanvas && selection?.isCreator) {\r\n this.setSelection(null)\r\n } else {\r\n this.setSelection(element)\r\n }\r\n }\r\n }\r\n\r\n getElement = (area: PaneArea) => {\r\n const chartEvents = this.props.model.getAllChartEvents(false)\r\n\r\n for (let i = chartEvents.length - 1; i >= 0; i--) {\r\n const el = chartEvents[i].instance\r\n if (el.getIsInChartView(this.props.chartModel) && el.isInArea(area)) {\r\n return el\r\n }\r\n }\r\n\r\n const elements = this.props.model.getAllElements()\r\n\r\n for (let i = elements.length - 1; i >= 0; i--) {\r\n const el = elements[i].instance\r\n if (el.getIsInChartView(this.props.chartModel) && el.isInArea(area)) {\r\n return el\r\n }\r\n }\r\n return null\r\n }\r\n\r\n getCanvasDOMNode = () =>\r\n // This is used in app/modals/publish/publish.jsx\r\n this.canvasRef.current\r\n}\r\n\r\nexport default withNotificationContext(withElementStyleDialogState(withPaneModel(Pane)))\r\n","import React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport PaneModel from '../../models/pane'\r\n\r\nexport function withPaneModel

(Component: React.ComponentType

) {\r\n return function WrappedComponent(props: P) {\r\n const model = useModelState(props.model, { watchProperties: ['selection'] })\r\n\r\n return \r\n }\r\n}\r\n","import { Spinner } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport React from 'react'\r\n\r\nexport function ChartSpinnerOverlay({ shouldDisplay, className }: { shouldDisplay: boolean; className: string }) {\r\n const [isVisible, setIsVisible] = React.useState(shouldDisplay)\r\n React.useEffect(() => {\r\n let timeout: number\r\n if (!shouldDisplay) {\r\n timeout = window.setTimeout(() => {\r\n setIsVisible(false)\r\n }, 400)\r\n }\r\n return () => {\r\n clearTimeout(timeout)\r\n }\r\n }, [shouldDisplay])\r\n\r\n return (\r\n <>\r\n {isVisible && (\r\n \r\n \r\n \r\n )}\r\n \r\n )\r\n}\r\n","import React from 'react'\r\n\r\nimport { RootChartConfigObjectChart } from '../../../types/shared'\r\nimport ChartModel from '../../models/chart'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { DrawingTool } from '../toolbar/interfaces'\r\n\r\nexport const CHART_CLASS_NAMES = 'chart flex-1 relative'\r\nexport const DEFAULT_WRAPPER_COMPONENT = 'div'\r\n\r\nexport interface ChartProps {\r\n chartIndex: number\r\n gridArea?: string\r\n WrapperComp?: React.RefForwardingComponent\r\n config: RootChartConfigObjectChart\r\n chartModel: ChartModel\r\n layoutModel: ChartLayout\r\n setActiveChartInteraction: (interaction: string | null) => void\r\n activeChartInteraction: string | null\r\n activeTool: DrawingTool\r\n touchEventsDisabled: boolean\r\n hasOutline?: boolean\r\n shouldResize?: boolean\r\n renderChartToolbar?: () => React.ReactNode\r\n}\r\n","import classnames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { Instrument } from '../../../types/shared'\r\nimport { ChartEditorEnum, SpecificChartFunctionality } from '../../constants/common'\r\nimport math from '../../helpers/math'\r\nimport ChartModel from '../../models/chart'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport MouseModel from '../../models/mouse'\r\nimport PaneModel from '../../models/pane'\r\nimport Quote from '../../models/quote'\r\nimport { QuoteFetchType } from '../../models/quote/constants'\r\nimport utils, { isRedesignEnabled } from '../../utils'\r\nimport { getBarWidthWithMargin, getZoomFactorForBarsToDisplay } from '../../utils/chart'\r\nimport { ChartControls } from '../chart-controls'\r\nimport Pane from '../pane'\r\nimport {\r\n getBarIndex,\r\n getIsSmallIndexChart,\r\n getLeftOffset,\r\n getMinMaxLeftOffset,\r\n updateZoomAndLeftOffsetByDateRange,\r\n} from '../renderUtils'\r\nimport { ChartProps } from './constants'\r\nimport { withChartInit } from './with-chart-init'\r\nimport { withWatchedPanesOnChartModel } from './with-watched-panes-on-chart-model'\r\n\r\nfunction preventDefaultFunc(event: Event) {\r\n event.preventDefault()\r\n}\r\n\r\nfunction getZoomFactor({\r\n chartLayout,\r\n currentZoomFactor,\r\n diff,\r\n minBarWidthInPx = 1,\r\n maxBarWidthInPx = 66,\r\n}: {\r\n chartLayout: ChartLayout\r\n currentZoomFactor: number\r\n diff: number\r\n minBarWidthInPx?: number\r\n maxBarWidthInPx?: number\r\n}) {\r\n const minZoomFactor = getZoomFactorForBarsToDisplay({\r\n chartLayout,\r\n chartVisibleWidth: minBarWidthInPx,\r\n numOfVisibleBars: 1,\r\n })\r\n const maxZoomFactor = getZoomFactorForBarsToDisplay({\r\n chartLayout,\r\n chartVisibleWidth: maxBarWidthInPx,\r\n numOfVisibleBars: 1,\r\n })\r\n const isNegativeDirection = diff < 0\r\n const newZoomFactor = currentZoomFactor + diff\r\n const newZoomFactorInRange = Math.min(Math.max(minZoomFactor, newZoomFactor), maxZoomFactor)\r\n\r\n if (newZoomFactor > newZoomFactorInRange && currentZoomFactor > newZoomFactorInRange) {\r\n return isNegativeDirection ? newZoomFactor : currentZoomFactor\r\n }\r\n\r\n if (newZoomFactor < newZoomFactorInRange && currentZoomFactor < newZoomFactorInRange) {\r\n return !isNegativeDirection ? newZoomFactor : currentZoomFactor\r\n }\r\n\r\n return newZoomFactorInRange\r\n}\r\n\r\ninterface ChartState {\r\n panesWrapperElement: HTMLDivElement | null\r\n}\r\n\r\nclass Chart extends React.Component {\r\n lastWidth: number\r\n mouseWheelTimeout?: number\r\n setStateWithPanesTimeout?: number\r\n lastHeight = 0\r\n lastY: number | null = null\r\n lastX: number | null = null\r\n resizerPaneIndex = -1\r\n minimalPaneHeight = 0\r\n zoomerRightAlign: {\r\n barIndex?: number\r\n index: number\r\n offsetDiff: number\r\n } | null = null\r\n\r\n // expects model, config, layoutModel\r\n constructor(props: ChartProps) {\r\n super(props)\r\n\r\n this.lastWidth = props.chartModel.width\r\n this.props.layoutModel.bind('change', this.onLayoutModelChange)\r\n this.state = { panesWrapperElement: null }\r\n }\r\n\r\n componentDidMount() {\r\n const { chartModel } = this.props\r\n this.lastWidth = this.props.layoutModel.width\r\n\r\n chartModel.trigger('change', chartModel)\r\n chartModel.bind('createPane', this.onPaneCreate)\r\n\r\n this.calculateMinimalPaneHeight()\r\n this.handleQuoteChange(chartModel.quote()!)\r\n this.onModelChange()\r\n\r\n chartModel.bind('update', this.onModelChange)\r\n chartModel.bind('destroy', () => {\r\n Quote.unbind('olderData', this.onOlderDataLoaded)\r\n Quote.unbind(`${QuoteFetchType.Refetch} ${QuoteFetchType.NewerData}`, this.onDataLoaded)\r\n })\r\n\r\n Quote.bind('olderData', this.onOlderDataLoaded)\r\n Quote.bind(`${QuoteFetchType.Refetch} ${QuoteFetchType.NewerData}`, this.onDataLoaded)\r\n }\r\n\r\n componentDidUpdate(prevProps: Readonly, prevState: Readonly) {\r\n if (\r\n prevState.panesWrapperElement !== this.state.panesWrapperElement ||\r\n prevProps.layoutModel.isWheelZoomEnabled !== this.props.layoutModel.isWheelZoomEnabled\r\n ) {\r\n prevState.panesWrapperElement?.removeEventListener('wheel', preventDefaultFunc)\r\n\r\n if (this.props.layoutModel.isWheelZoomEnabled) {\r\n // can't use onWheel as it has passive: true\r\n this.state.panesWrapperElement?.addEventListener('wheel', preventDefaultFunc, { passive: false })\r\n }\r\n }\r\n }\r\n\r\n componentWillUnmount() {\r\n const { chartModel, layoutModel } = this.props\r\n if (this.setStateWithPanesTimeout) {\r\n clearTimeout(this.setStateWithPanesTimeout)\r\n }\r\n layoutModel.unbind('change', this.onLayoutModelChange)\r\n chartModel.unbind('update', this.onModelChange)\r\n\r\n this.state.panesWrapperElement?.removeEventListener('wheel', preventDefaultFunc)\r\n }\r\n\r\n handleSetPanesWrapperRef = (panesWrapperElement: HTMLDivElement | null) => {\r\n this.setState({ panesWrapperElement })\r\n }\r\n\r\n render() {\r\n const { activeTool, chartIndex, layoutModel, chartModel, renderChartToolbar } = this.props\r\n const panes =\r\n layoutModel.specificChartFunctionality === SpecificChartFunctionality.futuresPage\r\n ? chartModel.getAllValidPanes()\r\n : chartModel.getAllPanes()\r\n const showSettings = layoutModel.editors.includes(ChartEditorEnum.settings)\r\n\r\n return (\r\n <>\r\n this.onClick(undefined)}\r\n data-testid={`chart-${chartIndex}-settings`}\r\n onMouseEnter={this.resetMouseModel}\r\n >\r\n {showSettings && }\r\n \r\n {layoutModel.editable && showSettings && renderChartToolbar && (\r\n \r\n {renderChartToolbar()}\r\n \r\n )}\r\n \r\n {panes.map((pane, index) => (\r\n \r\n ))}\r\n \r\n \r\n )\r\n }\r\n\r\n onMouseWheel = (e: React.WheelEvent) => {\r\n const { chartModel, layoutModel } = this.props\r\n const isLoading = chartModel.panes().count() < 1\r\n if (!layoutModel.isWheelZoomEnabled || isLoading) {\r\n return\r\n }\r\n if (!this.zoomerRightAlign) {\r\n this.calcZoomerRightAlign()\r\n }\r\n clearTimeout(this.mouseWheelTimeout)\r\n this.mouseWheelTimeout = window.setTimeout(() => {\r\n this.zoomerRightAlign = null\r\n }, 250)\r\n this.onZoomerMouseMove(e, undefined, true)\r\n }\r\n\r\n onClick = (activePane: PaneModel | undefined) => {\r\n if (\r\n !this.props.layoutModel.activeChart.eql(this.props.chartModel) ||\r\n !(this.props.layoutModel.activePane?.eql(activePane) || this.props.layoutModel.activePane === activePane)\r\n ) {\r\n this.props.layoutModel.updateAttributes({ activeChart: this.props.chartModel, activePane })\r\n }\r\n }\r\n\r\n onPaneCreate = () => {\r\n const { chartModel } = this.props\r\n this.onModelChange()\r\n this.calculateMinimalPaneHeight()\r\n chartModel.trigger('change', chartModel)\r\n }\r\n\r\n onPaneDestroy = (paneId: string) => {\r\n const { chartModel } = this.props\r\n const pane = chartModel.panes().find(paneId)\r\n\r\n if (pane) {\r\n pane.destroyCascade()\r\n this.onModelChange()\r\n chartModel.trigger('change', chartModel)\r\n }\r\n }\r\n\r\n onModelChange = (chartModelParam?: ChartModel) => {\r\n const { chartModel, config } = this.props\r\n const panes = chartModel.getAllPanes()\r\n const quote = chartModel.quote()\r\n\r\n if (panes.length === 0 || !quote || chartModel.leftOffset === undefined) {\r\n return\r\n }\r\n\r\n const { width, height } = chartModel\r\n let panesHeight = panes.reduce((sum, pane) => sum + (pane.height ?? 0), 0)\r\n if (panesHeight !== height) {\r\n panesHeight = panes.reduce((sum, pane) => {\r\n const newPaneHeight = Math.round((pane.height / panesHeight) * height)\r\n if (!Number.isNaN(newPaneHeight)) {\r\n pane.updateAttribute('height', newPaneHeight)\r\n }\r\n return sum + newPaneHeight\r\n }, 0)\r\n const chartPane = chartModel.getChartPane()\r\n if (chartPane && panesHeight !== height) {\r\n const newChartPaneHeight = chartPane.height + height - panesHeight\r\n if (!Number.isNaN(newChartPaneHeight)) {\r\n chartPane.updateAttribute('height', newChartPaneHeight)\r\n }\r\n }\r\n }\r\n\r\n const newLeftOffset = getLeftOffset({\r\n quote,\r\n chartModel,\r\n config: config,\r\n })\r\n const newIsScrolled = chartModel.leftOffset !== newLeftOffset\r\n const isScrolled = chartModel.isScrolled\r\n if (!isScrolled && this.lastWidth !== width) {\r\n this.lastWidth = width\r\n chartModel.updateAttribute('leftOffset', newLeftOffset)\r\n } else if (isScrolled !== newIsScrolled) {\r\n chartModel.updateAttributes({ isScrolled: newIsScrolled })\r\n }\r\n\r\n if (this.lastHeight !== height) {\r\n this.lastHeight = height\r\n this.calculateMinimalPaneHeight()\r\n }\r\n\r\n if (chartModelParam) {\r\n this.handleQuoteChange(chartModelParam.quote())\r\n }\r\n }\r\n\r\n onLayoutModelChange = ({ activeChart, activePane }: { activeChart: ChartModel; activePane: PaneModel }) => {\r\n const { chartModel } = this.props\r\n if (!activeChart) {\r\n return\r\n }\r\n for (const pane of chartModel.getAllPanes()) {\r\n if (activePane?.id !== pane.id && pane.selection?.isSelected === true) {\r\n pane.selection.setIsSelected(false)\r\n pane.updateAttribute('selection', undefined)\r\n }\r\n }\r\n }\r\n\r\n onResizerMouseDown = (e: React.MouseEvent | MouseEvent, model: PaneModel) => {\r\n if (e.button !== 0) {\r\n return\r\n }\r\n this.lastY = e.clientY\r\n this.resizerPaneIndex = this.props.chartModel\r\n .panes()\r\n .all()\r\n .findIndex((pane) => pane.eql(model))\r\n document.addEventListener('mousemove', this.onResizerMouseMove)\r\n document.addEventListener('mouseup', this.onResizerMouseUp)\r\n }\r\n\r\n onResizerMouseMove = (e: MouseEvent) => {\r\n if (this.resizerPaneIndex > 0 && this.lastY !== null && this.resizePanesAccordingly(this.lastY! - e.clientY)) {\r\n this.lastY = e.clientY\r\n }\r\n }\r\n\r\n onResizerMouseUp = (e: MouseEvent) => {\r\n const { chartModel } = this.props\r\n if (this.resizerPaneIndex > 0 && this.lastY !== null) {\r\n this.resizePanesAccordingly(this.lastY - e.clientY)\r\n this.lastY = null\r\n\r\n chartModel.trigger('change', chartModel)\r\n }\r\n\r\n document.removeEventListener('mousemove', this.onResizerMouseMove)\r\n document.removeEventListener('mouseup', this.onResizerMouseUp)\r\n }\r\n\r\n calculateMinimalPaneHeight() {\r\n const { chartModel } = this.props\r\n const { minHeight, total } = chartModel\r\n .panes()\r\n .all()\r\n .reduce(\r\n ({ minHeight, total }, pane) => {\r\n if (minHeight > pane.height) {\r\n minHeight = pane.height\r\n }\r\n total += pane.getIsChartPane() ? 3 : 1\r\n return { minHeight, total }\r\n },\r\n { minHeight: chartModel.height, total: 0 }\r\n )\r\n const optiMinHeight = Math.floor(chartModel.height / total)\r\n this.minimalPaneHeight = Math.min(minHeight, optiMinHeight)\r\n }\r\n\r\n resizePanesAccordingly(difY: number) {\r\n const { chartModel } = this.props\r\n const panes = chartModel.panes().all()\r\n let basePane = this.resizerPaneIndex\r\n if (!difY) {\r\n return true\r\n } else if (difY > 0) {\r\n let i = basePane\r\n let pane = panes[i]\r\n if (pane.height + difY >= this.minimalPaneHeight) {\r\n pane.updateAttribute('height', pane.height + difY)\r\n } else {\r\n pane.updateAttribute('height', this.minimalPaneHeight)\r\n }\r\n for (--i; i >= 0; i--) {\r\n pane = panes[i]\r\n if (pane.height - difY >= this.minimalPaneHeight) {\r\n pane.updateAttribute('height', pane.height - difY)\r\n break\r\n } else {\r\n pane.updateAttribute('height', this.minimalPaneHeight)\r\n }\r\n }\r\n } else if (difY < 0) {\r\n basePane = Math.max(0, basePane - 1)\r\n let i = basePane\r\n let pane = panes[i]\r\n if (pane.height - difY >= this.minimalPaneHeight) {\r\n pane.updateAttribute('height', pane.height - difY)\r\n } else {\r\n pane.updateAttribute('height', this.minimalPaneHeight)\r\n }\r\n for (++i; i < panes.length; i++) {\r\n pane = panes[i]\r\n if (pane.height + difY >= this.minimalPaneHeight) {\r\n pane.updateAttribute('height', pane.height + difY)\r\n break\r\n } else {\r\n pane.updateAttribute('height', this.minimalPaneHeight)\r\n }\r\n }\r\n }\r\n\r\n const panesHeight = panes.reduce((sum, pane) => sum + pane.height, 0)\r\n if (panesHeight !== chartModel.height) {\r\n difY = chartModel.height - panesHeight\r\n\r\n const pane = panes[basePane]\r\n pane.updateAttribute('height', pane.height + difY)\r\n\r\n // if we exceeded total height we need to stop updating lastY - return false\r\n return false\r\n }\r\n\r\n return true\r\n }\r\n\r\n onZoomerTouchStart = (e: React.TouchEvent | TouchEvent) => {\r\n if (!this.props.layoutModel.scrollable || e.touches.length !== 1 || this.props.touchEventsDisabled) {\r\n return\r\n }\r\n this.onZoomerMouseDown(e.targetTouches[0])\r\n }\r\n\r\n onZoomerTouchMove = (e: TouchEvent) => {\r\n if (!this.props.layoutModel.scrollable || e.touches.length !== 1) {\r\n return\r\n }\r\n this.onZoomerMouseMove(e.targetTouches[0])\r\n }\r\n\r\n onZoomerTouchEnd = () => {\r\n if (!this.props.layoutModel.scrollable) {\r\n return\r\n }\r\n this.onZoomerMouseUp()\r\n }\r\n\r\n getRawDistance = (e: Pick) => {\r\n const p1 = { x: e.touches[0].clientX, y: e.touches[0].clientY }\r\n const p2 = { x: e.touches[1].clientX, y: e.touches[1].clientY }\r\n return math.distance(p1, p2)\r\n }\r\n\r\n onPinchStart = (e: React.TouchEvent) => {\r\n const { chartModel } = this.props\r\n const { activeChartInteraction, setActiveChartInteraction, touchEventsDisabled } = this.props\r\n const isLoading = chartModel.panes().count() < 1\r\n\r\n if (\r\n this.props.layoutModel.scrollable &&\r\n e.touches.length === 2 &&\r\n !activeChartInteraction &&\r\n !isLoading &&\r\n !touchEventsDisabled\r\n ) {\r\n setActiveChartInteraction('pinch')\r\n this.onZoomerMouseDown({ clientX: this.getRawDistance(e as unknown as TouchEvent) })\r\n\r\n document.addEventListener('touchmove', this.onPinchMove)\r\n document.addEventListener('touchend', this.onPinchEnd)\r\n }\r\n }\r\n\r\n onPinchMove = (e: TouchEvent) => {\r\n if (e.touches.length === 2) {\r\n this.onZoomerMouseMove({ clientX: this.getRawDistance(e) })\r\n }\r\n }\r\n\r\n onPinchEnd = (e: TouchEvent) => {\r\n if (e.touches.length === 1) {\r\n this.onZoomerMouseUp()\r\n document.removeEventListener('touchmove', this.onPinchMove)\r\n document.removeEventListener('touchend', this.onPinchEnd)\r\n }\r\n }\r\n\r\n calcZoomerRightAlign = () => {\r\n const { chartModel } = this.props\r\n const { ChartSettings } = chartModel.getChartLayoutSettings()\r\n const quote = chartModel.quote()\r\n const fx = chartModel.panes().first().scale.x\r\n const barWidth = getBarWidthWithMargin({ zoomFactor: chartModel.zoomFactor, chartLayout: this.props.layoutModel })\r\n const currentLeftOffset = getLeftOffset({ quote, chartModel, config: this.props.config, barWidth })\r\n this.zoomerRightAlign = null\r\n\r\n if (quote.isIntraday && quote.instrument === Instrument.Stock) {\r\n const barIndex = quote.getBarIndex(quote.close.length - 1)\r\n let offsetDiff =\r\n chartModel.leftOffset -\r\n getLeftOffset({\r\n quote,\r\n chartModel: chartModel,\r\n config: this.props.config,\r\n barWidth,\r\n barIndex,\r\n shouldAlignDaysToLeftApplied: false,\r\n })\r\n const offsetBars = ~~(offsetDiff / barWidth)\r\n offsetDiff -= offsetBars * barWidth\r\n this.zoomerRightAlign = {\r\n barIndex,\r\n index: barIndex - offsetBars,\r\n offsetDiff,\r\n }\r\n } else if (chartModel.leftOffset <= currentLeftOffset) {\r\n this.zoomerRightAlign = {\r\n index: quote.getBarIndex(quote.open.length - 1),\r\n offsetDiff: chartModel.leftOffset - currentLeftOffset,\r\n }\r\n } else {\r\n const offset = chartModel.leftOffset\r\n for (let i = 0; i < quote.open.length; i += 1) {\r\n const x = fx(i)\r\n if (x + offset < 0) {\r\n continue\r\n }\r\n if (x + offset > chartModel.width - ChartSettings.left.width - ChartSettings.right.width) {\r\n const barIndex = quote.getBarIndex(i - 1)\r\n let offsetDiff =\r\n offset -\r\n getLeftOffset({\r\n quote,\r\n chartModel,\r\n config: this.props.config,\r\n barWidth,\r\n barIndex,\r\n })\r\n const offsetBars = ~~(offsetDiff / barWidth)\r\n offsetDiff -= offsetBars * barWidth\r\n this.zoomerRightAlign = {\r\n barIndex,\r\n index: barIndex - offsetBars,\r\n offsetDiff,\r\n }\r\n break\r\n }\r\n }\r\n }\r\n }\r\n\r\n onZoomerMouseDown = (e: Partial) => {\r\n if ((e.button !== 0 && 'button' in e) || !this.props.layoutModel.scrollable) {\r\n return\r\n }\r\n switch (this.props.activeChartInteraction) {\r\n case 'pinch':\r\n break\r\n case null:\r\n this.props.setActiveChartInteraction('zoomer')\r\n break\r\n default:\r\n return\r\n }\r\n\r\n this.lastX = e.clientX ?? null\r\n this.calcZoomerRightAlign()\r\n\r\n document.addEventListener('mousemove', this.onZoomerMouseMove)\r\n document.addEventListener('mouseup', this.onZoomerMouseUp)\r\n document.addEventListener('touchmove', this.onZoomerTouchMove)\r\n document.addEventListener('touchend', this.onZoomerTouchEnd)\r\n }\r\n\r\n normalizeWheelDeltaY = (e: WheelEvent) => {\r\n // because wheel deltaY on mouse and touchpad is quite different we need to normalize it\r\n const abs = Math.abs(e.deltaY)\r\n if (abs === 0) return 0\r\n return Math.log(abs) * Math.sign(e.deltaY) * 10\r\n }\r\n\r\n onZoomerMouseMove = (\r\n e: React.WheelEvent | MouseEvent | Touch | { clientX: number },\r\n _?: unknown,\r\n isMouseWheel = false\r\n ) => {\r\n const { chartModel, layoutModel } = this.props\r\n let difX\r\n if (!layoutModel.scrollable) return\r\n if (!isMouseWheel && this.lastX !== null) {\r\n difX = (this.lastX - e.clientX) / chartModel.width\r\n this.lastX = e.clientX\r\n } else {\r\n // standard difX calculation result is around 0.00x, wheel deltaY is whole px\r\n // because of that we divide px with 1000\r\n difX = this.normalizeWheelDeltaY(e as WheelEvent) / 1000\r\n }\r\n\r\n this.addToZoomFactor({ diff: -difX })\r\n }\r\n\r\n addToZoomFactor = ({\r\n diff,\r\n shouldCalculateRightAlign = false,\r\n }: {\r\n diff: number\r\n shouldCalculateRightAlign?: boolean\r\n }) => {\r\n const { chartModel, layoutModel } = this.props\r\n if (shouldCalculateRightAlign) {\r\n this.calcZoomerRightAlign()\r\n }\r\n // 6 is default bar width with margin on charts page, so to get the similar feeling when zooming we're multiplying the zoom factor by the coefficient\r\n const diffCoefficient = chartModel.zoomFactor * (6 / getBarWidthWithMargin({ chartLayout: this.props.layoutModel }))\r\n const zoomFactor = getZoomFactor({\r\n chartLayout: layoutModel,\r\n currentZoomFactor: chartModel.zoomFactor,\r\n diff: diff * diffCoefficient,\r\n })\r\n const barWidth = getBarWidthWithMargin({\r\n zoomFactor,\r\n chartLayout: this.props.layoutModel,\r\n })\r\n\r\n let leftOffset\r\n if (this.props.config.stretch) {\r\n leftOffset = 0\r\n } else if (getIsSmallIndexChart(this.props.layoutModel.specificChartFunctionality)) {\r\n leftOffset = barWidth\r\n } else if (this.zoomerRightAlign) {\r\n leftOffset = getMinMaxLeftOffset({\r\n newLeftOffset:\r\n getLeftOffset({\r\n quote: chartModel.quote(),\r\n chartModel: chartModel,\r\n config: this.props.config,\r\n barWidth,\r\n barIndex: this.zoomerRightAlign.index,\r\n shouldAlignDaysToLeftApplied: false,\r\n }) + this.zoomerRightAlign.offsetDiff,\r\n chartModel: chartModel,\r\n barWidth,\r\n barIndex: getBarIndex(chartModel.quote()),\r\n })\r\n } else {\r\n return\r\n }\r\n chartModel.updateAttributes({\r\n zoomFactor,\r\n leftOffset,\r\n dateRange: null,\r\n })\r\n if (shouldCalculateRightAlign) {\r\n this.zoomerRightAlign = null\r\n }\r\n }\r\n\r\n onZoomerMouseUp = () => {\r\n this.zoomerRightAlign = null\r\n document.removeEventListener('mousemove', this.onZoomerMouseMove)\r\n document.removeEventListener('mouseup', this.onZoomerMouseUp)\r\n document.removeEventListener('touchmove', this.onZoomerTouchMove)\r\n document.removeEventListener('touchend', this.onZoomerTouchEnd)\r\n this.props.setActiveChartInteraction(null)\r\n }\r\n\r\n onZoomerReset = () => {\r\n const { chartModel, layoutModel } = this.props\r\n const zoomFactor = chartModel.chart_layout().defaultZoomFactor\r\n const barWidth = getBarWidthWithMargin({ zoomFactor, chartLayout: layoutModel })\r\n const leftOffset = getLeftOffset({\r\n quote: chartModel.quote(),\r\n chartModel,\r\n config: this.props.config,\r\n barWidth,\r\n })\r\n\r\n chartModel.updateAttributes({\r\n zoomFactor,\r\n leftOffset,\r\n dateRange: null,\r\n })\r\n }\r\n\r\n onOlderDataLoaded = () => {\r\n throw new Error('onOlderDataLoaded not implemented')\r\n // TODO implement similarly to onDataLoaded\r\n }\r\n\r\n resetMouseModel = () => {\r\n const isLoading = this.props.chartModel.panes().count() < 1\r\n if (!isLoading) {\r\n MouseModel.updateAttributes({\r\n position: null,\r\n pane: null,\r\n })\r\n }\r\n }\r\n\r\n handleQuoteChange = (quote: Quote) => {\r\n const { chartModel } = this.props\r\n\r\n // Update only date range chart\r\n if (chartModel.dateRange) {\r\n if (!quote.eql(chartModel.quote()) || chartModel.timeframe !== quote.timeframe || quote.date.length === 0) {\r\n return\r\n }\r\n updateZoomAndLeftOffsetByDateRange({ chartModel, quote })\r\n }\r\n }\r\n\r\n onDataLoaded = (newQuote: Quote, fetchType: QuoteFetchType) => {\r\n const { chartModel } = this.props\r\n const quote = chartModel.quote()\r\n if (!quote?.eql(newQuote)) {\r\n return\r\n }\r\n\r\n const shouldForceLeftOffsetUpdate = fetchType === QuoteFetchType.Refetch\r\n let newLeftOffset = chartModel.leftOffset // TODO find proper fix. If this line is removed (if we don't trigger leftOffset update), the chart stops being updated for the user until they move chart around.\r\n if (\r\n (this.props.layoutModel.scrollable === false && !this.props.layoutModel.isTouchCrossActive) ||\r\n !chartModel.isScrolled ||\r\n shouldForceLeftOffsetUpdate\r\n ) {\r\n newLeftOffset = getLeftOffset({\r\n quote,\r\n chartModel: chartModel,\r\n config: this.props.config,\r\n })\r\n }\r\n\r\n chartModel.setChartEvents(quote.chartEvents, !quote.events)\r\n\r\n if (newLeftOffset !== chartModel.leftOffset) {\r\n chartModel.getAllElements().forEach((element) => {\r\n if (element.isDrawing() && !element.isMouseDown()) {\r\n element.instance.updateScales()\r\n }\r\n })\r\n }\r\n\r\n chartModel.updateAttribute('leftOffset', newLeftOffset)\r\n\r\n this.handleQuoteChange(quote)\r\n }\r\n}\r\n\r\nexport default withChartInit(withWatchedPanesOnChartModel(Chart))\r\n","import classNames from 'classnames'\r\nimport merge from 'lodash.merge'\r\nimport React from 'react'\r\n\r\nimport { ObjectHash } from '../../../types/shared'\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport Quote from '../../models/quote'\r\nimport { getChartsDimensions, isRedesignEnabled } from '../../utils'\r\nimport { prefetchPerfIndicatorAllQuotes } from '../../utils/chart'\r\nimport { getLeftOffset } from '../renderUtils'\r\nimport { ChartSpinnerOverlay } from './chart-spinner-overlay'\r\nimport { CHART_CLASS_NAMES, ChartProps, DEFAULT_WRAPPER_COMPONENT } from './constants'\r\n\r\nexport function withChartInit(Component: React.ComponentType) {\r\n return function WrappedComponent(props: ChartProps) {\r\n const { WrapperComp = DEFAULT_WRAPPER_COMPONENT, gridArea } = props\r\n const isModelDestroyedRef = React.useRef(false)\r\n const model = useModelState(props.chartModel, { watchProperties: ['panes', 'quote'] })\r\n const layoutModel = useModelState(props.layoutModel, { watchProperties: ['activeChart'] })\r\n const quote = model.quote()\r\n\r\n const initChartRef = React.useRef(async () => {\r\n const { chartModel, config } = props\r\n const { premarket, hasChartEvents, aftermarket, ticker, instrument, timeframe, panes: panesConfig } = config\r\n\r\n const options = {\r\n premarket,\r\n aftermarket,\r\n events: hasChartEvents,\r\n patterns: panesConfig.some(\r\n (pane) =>\r\n pane.elements?.some(\r\n (element) => element.overlays?.some((overlay: ObjectHash) => overlay.type === 'overlays/patterns')\r\n )\r\n ),\r\n }\r\n\r\n const quote = await Quote.get({\r\n ticker,\r\n instrument,\r\n timeframe,\r\n options,\r\n })\r\n const panesWithPerfIndicator = panesConfig.filter(({ elements }) =>\r\n elements.some(({ type }) => type === 'indicators/perf')\r\n )\r\n\r\n if (panesWithPerfIndicator) {\r\n await Promise.allSettled(\r\n panesWithPerfIndicator.map((paneWithPerfIndicator) =>\r\n prefetchPerfIndicatorAllQuotes({ paneWithPerfIndicator, timeframe, options })\r\n )\r\n )\r\n }\r\n\r\n if (isModelDestroyedRef.current) {\r\n return\r\n }\r\n\r\n config.panes.forEach((pane) => {\r\n const paneProperties = merge({}, pane)\r\n paneProperties.chart = chartModel\r\n chartModel.createPaneCascade(paneProperties)\r\n })\r\n\r\n chartModel.updateAttributes({\r\n quote,\r\n premarket: options.premarket,\r\n aftermarket: options.aftermarket,\r\n })\r\n\r\n chartModel.setChartEvents(quote.chartEvents, true)\r\n\r\n if (props.shouldResize) {\r\n const chartsDimensions = getChartsDimensions(props.layoutModel.getHTMLElementId())\r\n props.layoutModel.updateAttributes(chartsDimensions)\r\n }\r\n\r\n if (chartModel.leftOffset == null) {\r\n const leftOffset = getLeftOffset({ quote, chartModel: chartModel, config: props.config })\r\n chartModel.updateAttribute('leftOffset', leftOffset)\r\n }\r\n })\r\n\r\n React.useEffect(() => {\r\n const handleModelBeforeDestroy = () => {\r\n isModelDestroyedRef.current = true\r\n }\r\n\r\n model.bind('beforeDestroy', handleModelBeforeDestroy)\r\n initChartRef.current()\r\n return () => {\r\n model.unbind('beforeDestroy', handleModelBeforeDestroy)\r\n }\r\n // We want to run it only on mount\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n const isQuotePage = props.layoutModel.specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n const isChartPage = props.layoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const isFuturesForexCryptoPage = [\r\n SpecificChartFunctionality.futuresPage,\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n ].includes(props.layoutModel.specificChartFunctionality)\r\n const isModelReady =\r\n quote && ((quote.fetchedAt === undefined && quote.close.length > 0) || quote.fetchedAt > 0 || quote)\r\n const loadingStyle =\r\n !isModelReady && isQuotePage\r\n ? // 2px is border\r\n { width: model.width ? model.width + 2 : '100%', height: model.height + 2 }\r\n : undefined\r\n\r\n return (\r\n \r\n {isChartPage && (\r\n \r\n )}\r\n {isModelReady && }\r\n \r\n )\r\n }\r\n}\r\n","import React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartModel from '../../models/chart'\r\n\r\nexport function withWatchedPanesOnChartModel

(Component: React.ComponentType

) {\r\n return function WrappedComponent(props: P) {\r\n const model = useModelState(props.chartModel, { watchProperties: ['panes'] })\r\n\r\n return \r\n }\r\n}\r\n","import { DefaultErrorBoundary } from '@finviz/website'\r\nimport * as React from 'react'\r\nimport { FallbackProps } from 'react-error-boundary'\r\n\r\nexport function ModuleLoadFailed(props: Partial) {\r\n return (\r\n \r\n )\r\n}\r\n","export const portfolioWatchlistAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"portfolio-watchlist\" */ './portfolio-watchlist'),\r\n cacheKey: 'portfolio-watchlist',\r\n}\r\n","import { IconNameType } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { portfolioWatchlistAsyncModule } from './portfolio-watchlist/async-modules'\r\nimport { withModuleAsyncLoad } from './with-module-async-load'\r\n\r\nexport enum SidebarModule {\r\n portfolio = 'portfolio',\r\n}\r\n\r\nexport type SidebarModuleType = {\r\n key: SidebarModule\r\n icon: IconNameType\r\n description: string\r\n content: React.ComponentType\r\n width?: {\r\n min?: number | string\r\n max?: number | string\r\n default?: { desktop?: number; mobile?: number }\r\n }\r\n}\r\n\r\nexport const sidebarModules: Record = Object.freeze({\r\n [SidebarModule.portfolio]: {\r\n key: SidebarModule.portfolio,\r\n icon: 'briefcase',\r\n description: 'Portfolio watchlist',\r\n content: withModuleAsyncLoad(portfolioWatchlistAsyncModule, true),\r\n width: { min: 200, default: { mobile: 275 } },\r\n },\r\n})\r\n","import { Delayed, Spinner } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { useAsyncModule } from '../../../utils/async-modules-utils'\r\nimport { ModuleLoadFailed } from './module-load-failed'\r\n\r\nexport function withModuleAsyncLoad<\r\n T extends { default: React.ComponentType<{ setIsComponentReady: React.Dispatch> }> },\r\n>(asyncModule: { importFn: () => Promise; cacheKey: string }, withInitialLoading = false) {\r\n return function InnerFunction() {\r\n const [isComponentReady, setIsComponentReady] = React.useState(false)\r\n const [sidebarModule, { isError }] = useAsyncModule({\r\n ...asyncModule,\r\n isSuspenseMode: true,\r\n })\r\n\r\n const SidebarModule = sidebarModule?.default\r\n\r\n if (isError) {\r\n return \r\n }\r\n\r\n return (\r\n <>\r\n {!isComponentReady && withInitialLoading && (\r\n \r\n

\r\n \r\n
\r\n \r\n )}\r\n {!!SidebarModule && }\r\n \r\n )\r\n }\r\n}\r\n","import { Resizable } from 're-resizable'\r\nimport React from 'react'\r\n\r\nimport Utils from '../../utils'\r\nimport { DEFAULT_WIDTHS, SidebarDirection } from './constants'\r\nimport { useSidebarContext } from './hooks/sidebar-context'\r\n\r\ntype SidebarContentProps = {\r\n children: React.ReactNode\r\n}\r\n\r\nexport default function SidebarContent({ children }: SidebarContentProps) {\r\n const { direction, onResize, close, width } = useSidebarContext()\r\n const minWidth = width?.min ?? DEFAULT_WIDTHS.min\r\n const maxWidth = width?.max ?? DEFAULT_WIDTHS.max\r\n const defaultMobile = width?.default?.mobile ?? minWidth\r\n const defaultDesktop = width?.default?.desktop ?? maxWidth\r\n\r\n return (\r\n <>\r\n {direction === SidebarDirection.vertical && (\r\n \r\n {children}\r\n \r\n )}\r\n {direction === SidebarDirection.horizontal && (\r\n <>\r\n
\r\n
\r\n {children}\r\n
\r\n \r\n )}\r\n \r\n )\r\n}\r\n","import { Button, Icon, Paragraph, Tooltip, TooltipTrigger, useTooltipState } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { SidebarDirection } from './constants'\r\nimport { useSidebarContext } from './hooks/sidebar-context'\r\nimport { sidebarModules } from './modules/modules'\r\n\r\nexport const MOBILE_TOOLBAR_DIV_ID = 'toolbar-mobile'\r\n\r\ntype SidebarTabsProps = {\r\n className?: string\r\n}\r\n\r\nexport default function SidebarTabs({ className }: SidebarTabsProps) {\r\n const { isOpen, direction, activeModule, selectModule } = useSidebarContext()\r\n const tooltipState = useTooltipState({ placement: 'left', unstable_timeout: 300 })\r\n\r\n return (\r\n \r\n {/* reserved space for drawing button on mobile devices */}\r\n {direction === SidebarDirection.horizontal && (\r\n \r\n )}\r\n\r\n {Object.entries(sidebarModules).map(([key, value]) => {\r\n const isActive = activeModule?.key === key\r\n return (\r\n \r\n \r\n {\r\n selectModule(isActive ? undefined : value.key)\r\n }}\r\n className={classnames({ 'ml-2': direction === SidebarDirection.horizontal })}\r\n data-testid={`sidebar-${key}-btn`}\r\n >\r\n \r\n \r\n \r\n \r\n {value.description}\r\n \r\n \r\n )\r\n })}\r\n
\r\n )\r\n}\r\n","import { Delayed, Spinner, localStorage } from '@finviz/website'\r\nimport * as React from 'react'\r\nimport { ErrorBoundary } from 'react-error-boundary'\r\nimport { useNavigate, useSearchParams } from 'react-router-dom'\r\n\r\nimport { getIsMobilePortrait } from '../../utils'\r\nimport { SidebarDirection } from './constants'\r\nimport { SidebarContext, SidebarContextType } from './hooks/sidebar-context'\r\nimport { ModuleLoadFailed } from './modules/module-load-failed'\r\nimport { SidebarModule, SidebarModuleType, sidebarModules } from './modules/modules'\r\nimport SidebarContent from './sidebar-content'\r\nimport SidebarTabs from './sidebar-tabs'\r\n\r\nexport const SIDEBAR_QUERY_PARAM = 'sidebar'\r\n\r\n// This is a temp function, to remove unused property from localstorage\r\nfunction removeSidebarFromLocalstorage() {\r\n const SIDEBAR_LOCAL_STORAGE_KEY = 'sidebarModule'\r\n localStorage.removeValue(SIDEBAR_LOCAL_STORAGE_KEY)\r\n}\r\nremoveSidebarFromLocalstorage()\r\n\r\ntype SidebarProps = {\r\n onShouldResize: () => void\r\n direction: SidebarDirection\r\n tabsClassName?: string\r\n}\r\n\r\n// Todo - this is not correct approach but this component can unmount/mount on mobile orientation change so we can't keep it inside the component\r\nlet isInit = false\r\n\r\nexport function Sidebar({ onShouldResize, direction, tabsClassName }: SidebarProps) {\r\n const navigate = useNavigate()\r\n const [urlSearchParams] = useSearchParams()\r\n const sidebarModuleKey = (urlSearchParams.get(SIDEBAR_QUERY_PARAM) as keyof typeof sidebarModules | null) || null\r\n const [activeModule, setActiveModule] = React.useState(null)\r\n\r\n const isOpen = !!activeModule\r\n const handleSelectModule = React.useCallback(\r\n (key?: SidebarModule) => {\r\n const newUrlSearchParams = new URLSearchParams(urlSearchParams)\r\n if (key) {\r\n newUrlSearchParams.set(SIDEBAR_QUERY_PARAM, key)\r\n } else {\r\n newUrlSearchParams.delete(SIDEBAR_QUERY_PARAM)\r\n }\r\n navigate({ search: newUrlSearchParams.toString() }, { replace: true })\r\n },\r\n [urlSearchParams, navigate]\r\n )\r\n\r\n const handleCloseSidebar = React.useCallback(() => {\r\n handleSelectModule(undefined)\r\n }, [handleSelectModule])\r\n\r\n // Resize charts every time the sidebar is opened/closed or active module is changed\r\n React.useEffect(() => {\r\n onShouldResize()\r\n }, [activeModule, onShouldResize])\r\n\r\n // Set active module based on sidebarModuleKey\r\n React.useEffect(() => {\r\n let sidebarModule = sidebarModuleKey && sidebarModules[sidebarModuleKey]\r\n\r\n if (!isInit && getIsMobilePortrait()) {\r\n sidebarModule = null\r\n handleCloseSidebar()\r\n }\r\n\r\n setActiveModule(sidebarModule)\r\n isInit = true\r\n }, [sidebarModuleKey, handleCloseSidebar])\r\n\r\n const contextValue: SidebarContextType = React.useMemo(\r\n () => ({\r\n direction,\r\n isOpen,\r\n isCloseVisible: direction === SidebarDirection.horizontal,\r\n width: activeModule?.width,\r\n activeModule,\r\n onResize: onShouldResize,\r\n close: handleCloseSidebar,\r\n selectModule: handleSelectModule,\r\n }),\r\n [direction, isOpen, onShouldResize, activeModule, handleCloseSidebar, handleSelectModule]\r\n )\r\n\r\n return (\r\n \r\n {activeModule && (\r\n \r\n \r\n \r\n
\r\n \r\n
\r\n \r\n }\r\n >\r\n \r\n \r\n
\r\n
\r\n )}\r\n \r\n
\r\n )\r\n}\r\n","export const drawingCreatorsAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"drawing-creators\" */ './module-entry'),\r\n cacheKey: 'drawing-creators',\r\n}\r\n","import { DrawingActions, IToolbarDrawingAction, IToolbarDrawingActionItem } from './interfaces'\r\n\r\nexport const drawingActions: Record = {\r\n [DrawingActions.AddNote]: {\r\n id: DrawingActions.AddNote,\r\n title: 'Add note',\r\n icon: 'note',\r\n },\r\n [DrawingActions.DeleteDrawings]: {\r\n id: DrawingActions.DeleteDrawings,\r\n title: 'Remove all drawings',\r\n icon: 'drawingActionDelete',\r\n },\r\n [DrawingActions.DeleteAutoSavedDrawings]: {\r\n id: DrawingActions.DeleteAutoSavedDrawings,\r\n title: 'Remove all autosaved drawings',\r\n icon: 'drawingActionDelete',\r\n },\r\n}\r\n\r\nexport const getToolbarDrawingActions = ({\r\n isAutoSaveActive,\r\n isAddNoteAvailable = false,\r\n isIdea,\r\n}: {\r\n isAutoSaveActive: boolean\r\n isAddNoteAvailable?: boolean\r\n isIdea?: boolean\r\n}): Array => [\r\n ...(isAddNoteAvailable\r\n ? [\r\n {\r\n defaultItem: drawingActions[DrawingActions.AddNote],\r\n isDisabled: isIdea,\r\n disabledTooltip: 'Add note is not available in ideas',\r\n },\r\n ]\r\n : []),\r\n {\r\n defaultItem:\r\n drawingActions[isAutoSaveActive ? DrawingActions.DeleteAutoSavedDrawings : DrawingActions.DeleteDrawings],\r\n },\r\n]\r\n","import { DrawingSetting, IToolbarDrawingSetting, IToolbarDrawingsSettingItem } from './interfaces'\r\n\r\nconst drawingSettings: Record = {\r\n [DrawingSetting.PreserveDrawings]: {\r\n id: DrawingSetting.PreserveDrawings,\r\n icon: 'drawingSettingPreserveDrawings',\r\n iconActive: 'drawingSettingPreserveDrawingsActive',\r\n title: 'Preserve drawings: Off',\r\n titleActive: 'Preserve drawings: On',\r\n },\r\n [DrawingSetting.DrawingModeContinuous]: {\r\n id: DrawingSetting.DrawingModeContinuous,\r\n icon: 'drawingSettingDrawingMode',\r\n iconActive: 'drawingSettingDrawingModeActive',\r\n title: 'Drawing mode: Single',\r\n titleActive: 'Drawing mode: Continuous',\r\n },\r\n [DrawingSetting.HideDrawings]: {\r\n id: DrawingSetting.HideDrawings,\r\n icon: 'drawingSettingHide',\r\n iconActive: 'drawingSettingShow',\r\n title: 'Hide drawings',\r\n titleActive: 'Show drawings',\r\n },\r\n [DrawingSetting.LockDrawings]: {\r\n id: DrawingSetting.LockDrawings,\r\n icon: 'drawingSettingLock',\r\n iconActive: 'drawingSettingUnlock',\r\n title: 'Lock drawings',\r\n titleActive: 'Unlock drawings',\r\n },\r\n}\r\n\r\nconst preserveDrawingsAutosaveOverride: IToolbarDrawingSetting = {\r\n id: DrawingSetting.PreserveDrawings, // DrawingSetting.PreserveDrawings so it works with current settings sync to DB\r\n icon: 'drawingSettingAutosaveOff',\r\n iconActive: 'drawingSettingAutosaveOn',\r\n iconAction: 'drawingSettingAutosaveSaving',\r\n title: 'Drawings autosave: Off',\r\n titleActive: 'Drawings Autosave: On',\r\n titleAction: 'Drawings Autosave: Saving',\r\n}\r\n\r\nexport const getToolbarDrawingSettings = ({\r\n isPreserveDrawingsAndAutosaveAvailable,\r\n isIdea,\r\n isAutoSaveInProgress,\r\n}: {\r\n isPreserveDrawingsAndAutosaveAvailable?: boolean\r\n isIdea?: boolean\r\n isAutoSaveInProgress?: boolean\r\n}): Array => {\r\n const toolbarSettings = [\r\n {\r\n defaultItem: drawingSettings[DrawingSetting.DrawingModeContinuous],\r\n },\r\n ...(isPreserveDrawingsAndAutosaveAvailable\r\n ? [\r\n {\r\n defaultItem: preserveDrawingsAutosaveOverride,\r\n isDisabled: isIdea,\r\n isInAction: isAutoSaveInProgress,\r\n disabledTooltip: 'Autosave is not available in ideas',\r\n },\r\n ]\r\n : []),\r\n {\r\n defaultItem: drawingSettings[DrawingSetting.HideDrawings],\r\n },\r\n {\r\n defaultItem: drawingSettings[DrawingSetting.LockDrawings],\r\n },\r\n ]\r\n\r\n return toolbarSettings\r\n}\r\n","import { DrawingTool, IToolbarDrawingTool, IToolbarDrawingToolItem } from './interfaces'\r\n\r\nexport const drawingTools: Record = {\r\n [DrawingTool.Mouse]: {\r\n id: DrawingTool.Mouse,\r\n title: 'Mouse',\r\n icon: 'toolMouse',\r\n },\r\n [DrawingTool.Measure]: {\r\n id: DrawingTool.Measure,\r\n title: 'Measure',\r\n icon: 'toolMeasure',\r\n },\r\n [DrawingTool.ScaledLine]: {\r\n id: DrawingTool.ScaledLine,\r\n title: 'Line',\r\n icon: 'toolLine',\r\n },\r\n [DrawingTool.Arrow]: {\r\n id: DrawingTool.Arrow,\r\n title: 'Arrow',\r\n icon: 'toolArrow',\r\n },\r\n [DrawingTool.VerticalLine]: {\r\n id: DrawingTool.VerticalLine,\r\n title: 'Vertical line',\r\n icon: 'toolMidLineV',\r\n },\r\n [DrawingTool.HorizontalLine]: {\r\n id: DrawingTool.HorizontalLine,\r\n title: 'Horizontal line',\r\n icon: 'toolMidLineH',\r\n },\r\n [DrawingTool.Rectangle]: {\r\n id: DrawingTool.Rectangle,\r\n title: 'Rectangle',\r\n icon: 'toolRect',\r\n },\r\n [DrawingTool.RotatedRectangle]: {\r\n id: DrawingTool.RotatedRectangle,\r\n title: 'Rotated rectangle',\r\n icon: 'toolRectRotated',\r\n },\r\n [DrawingTool.Triangle]: {\r\n id: DrawingTool.Triangle,\r\n title: 'Triangle',\r\n icon: 'toolTriangle',\r\n },\r\n [DrawingTool.Ellipse]: {\r\n id: DrawingTool.Ellipse,\r\n title: 'Ellipse',\r\n icon: 'toolEllipse',\r\n },\r\n [DrawingTool.Curve]: {\r\n id: DrawingTool.Curve,\r\n title: 'Curve',\r\n icon: 'toolCurve',\r\n },\r\n [DrawingTool.Pitchfork]: {\r\n id: DrawingTool.Pitchfork,\r\n title: 'Pitchfork',\r\n icon: 'toolPitchfork',\r\n },\r\n [DrawingTool.Polygon]: {\r\n id: DrawingTool.Polygon,\r\n title: 'Polygon',\r\n icon: 'toolPolygon',\r\n },\r\n [DrawingTool.Xabcd]: {\r\n id: DrawingTool.Xabcd,\r\n title: 'XABCD',\r\n icon: 'toolXABCD',\r\n },\r\n [DrawingTool.ScaledText]: {\r\n id: DrawingTool.ScaledText,\r\n title: 'Text',\r\n icon: 'toolText',\r\n },\r\n [DrawingTool.Brush]: {\r\n id: DrawingTool.Brush,\r\n title: 'Brush',\r\n icon: 'toolBrush',\r\n },\r\n [DrawingTool.ElliottWaves]: {\r\n id: DrawingTool.ElliottWaves,\r\n title: 'Elliott waves',\r\n icon: 'toolElliottWave',\r\n },\r\n [DrawingTool.FibonacciRetracements]: {\r\n id: DrawingTool.FibonacciRetracements,\r\n title: 'Fibonacci retracements',\r\n icon: 'toolFibonacci',\r\n },\r\n [DrawingTool.Position]: {\r\n id: DrawingTool.Position,\r\n title: 'Position',\r\n icon: 'toolPosition',\r\n },\r\n [DrawingTool.Callout]: {\r\n id: DrawingTool.Callout,\r\n title: 'Callout',\r\n icon: 'toolCallout',\r\n },\r\n}\r\n\r\nexport const toolbarDrawingTools: Array = [\r\n {\r\n defaultItem: drawingTools[DrawingTool.Mouse],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Measure],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.ScaledLine],\r\n toolGroup: [\r\n drawingTools[DrawingTool.ScaledLine],\r\n drawingTools[DrawingTool.VerticalLine],\r\n drawingTools[DrawingTool.HorizontalLine],\r\n drawingTools[DrawingTool.Curve],\r\n ],\r\n toolGroupTitle: 'Line tools',\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Arrow],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Rectangle],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.RotatedRectangle],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Triangle],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Ellipse],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Polygon],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Xabcd],\r\n toolGroup: [drawingTools[DrawingTool.Xabcd], drawingTools[DrawingTool.Pitchfork]],\r\n toolGroupTitle: 'XABCD tools',\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.ScaledText],\r\n toolGroup: [drawingTools[DrawingTool.ScaledText], drawingTools[DrawingTool.Callout]],\r\n toolGroupTitle: 'Text tools',\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Brush],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.ElliottWaves],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.FibonacciRetracements],\r\n },\r\n {\r\n defaultItem: drawingTools[DrawingTool.Position],\r\n },\r\n]\r\n","import { Toolbar as ToolbarComponent, ToolbarDivider, ToolbarGroupProps, ToolbarItem } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { PaneArea } from '../../../types/shared'\r\nimport { SpecificChartFunctionality } from '../../constants/common'\r\nimport { drawingCreatorsAsyncModule } from '../../creators/async-modules'\r\nimport { ElementStyleDialogContext } from '../../modals/element_style'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport { AutoSaveState } from '../../models/constants'\r\nimport PaneModel from '../../models/pane'\r\nimport { useAsyncModule } from '../../utils/async-modules-utils'\r\nimport { getIsPreserveDrawingsAndAutosaveAvailable } from '../../utils/chart'\r\nimport { getToolbarDrawingActions } from './drawingActions'\r\nimport { getToolbarDrawingSettings } from './drawingSettings'\r\nimport { drawingTools, toolbarDrawingTools } from './drawingTools'\r\nimport { DrawingSetting, DrawingTool, IToolBarProps } from './interfaces'\r\n\r\nexport const DISABLED_ITEM_TOOLTIP_LABEL = \"Disabled due 'lock/hide' drawings active\"\r\n\r\nexport default function Toolbar({\r\n isSidebar,\r\n isHorizontal,\r\n isMobileOverlay,\r\n activeTool,\r\n chartLayoutModel,\r\n onActiveToolChange,\r\n onDrawingActionClick,\r\n onDrawingSettingClick,\r\n onDrawingEnd,\r\n drawingSettings,\r\n isAlternativeTheme,\r\n areToolsDisabled,\r\n}: IToolBarProps) {\r\n const [drawingCreatorsModule, { isLoading: isDrawingCreatorsModuleLoading }] = useAsyncModule({\r\n ...drawingCreatorsAsyncModule,\r\n shouldLoadModule: true,\r\n })\r\n const { autoSaveState } = useModelState(\r\n React.useMemo(() => chartLayoutModel.drawingsInternalStore(), [chartLayoutModel]),\r\n { watchProperties: ['autoSaveState'] }\r\n )\r\n const [isDrawing, setIsDrawing] = React.useState(false)\r\n const openElementStyleDialog = React.useContext(ElementStyleDialogContext)\r\n\r\n const availableDrawingSettings = getToolbarDrawingSettings({\r\n isPreserveDrawingsAndAutosaveAvailable: getIsPreserveDrawingsAndAutosaveAvailable(chartLayoutModel),\r\n isAutoSaveInProgress: autoSaveState === AutoSaveState.Saving,\r\n isIdea: !!chartLayoutModel.idea?.id,\r\n })\r\n\r\n const availableDrawingActions = getToolbarDrawingActions({\r\n isAutoSaveActive: autoSaveState !== AutoSaveState.Off,\r\n isAddNoteAvailable: chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage,\r\n isIdea: !!chartLayoutModel.idea?.id,\r\n })\r\n\r\n React.useEffect(() => {\r\n if (!drawingCreatorsModule) {\r\n return\r\n }\r\n\r\n const onMouseDown = (model: PaneModel, area: PaneArea & { isTouch: boolean }) => {\r\n const isDrawingModeContinuous = drawingSettings[DrawingSetting.DrawingModeContinuous]\r\n const hasData = model.chart().quote().close.length > 0\r\n const hasHiddenDrawings = drawingSettings[DrawingSetting.HideDrawings]\r\n const tool = drawingTools[activeTool].id\r\n\r\n if (tool === DrawingTool.Mouse || isDrawing || hasHiddenDrawings || !hasData) {\r\n return\r\n }\r\n\r\n setIsDrawing(true)\r\n const { drawingToolsTouchCreatorsByType, drawingToolsCreatorsByType } = drawingCreatorsModule\r\n const ToolClass = area.isTouch ? drawingToolsTouchCreatorsByType[tool] : drawingToolsCreatorsByType[tool]\r\n const element = model.elements().create({\r\n instance: new ToolClass(area, {}, model, openElementStyleDialog, () => {\r\n if (!isDrawingModeContinuous) {\r\n onActiveToolChange(DrawingTool.Mouse)\r\n }\r\n setIsDrawing(false)\r\n onDrawingEnd?.()\r\n }),\r\n })\r\n element.one('destroy', ({ instance }) => {\r\n if (instance.getIsCreator()) {\r\n setIsDrawing(false)\r\n onDrawingEnd?.()\r\n }\r\n })\r\n\r\n element.trigger('select', element)\r\n }\r\n PaneModel.bind('mousedown', onMouseDown)\r\n return () => {\r\n PaneModel.unbind('mousedown', onMouseDown)\r\n }\r\n }, [\r\n activeTool,\r\n onActiveToolChange,\r\n openElementStyleDialog,\r\n onDrawingEnd,\r\n drawingCreatorsModule,\r\n drawingSettings,\r\n isDrawing,\r\n ])\r\n\r\n return (\r\n \r\n {toolbarDrawingTools.map((item) => {\r\n const isActive = activeTool === item.defaultItem.id || item.toolGroup?.some((tool) => tool.id === activeTool)\r\n const isToolLoading = isDrawingCreatorsModuleLoading && isActive\r\n\r\n return (\r\n \r\n )\r\n })}\r\n \r\n {availableDrawingSettings.map((item) => (\r\n \r\n ))}\r\n {availableDrawingActions.map((item) => (\r\n \r\n ))}\r\n \r\n )\r\n}\r\n","import Toolbar from './toolbar'\r\n\r\nexport default Toolbar\r\n","import { Textarea } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { ObjectHash } from '../../../../types/shared'\r\nimport { useModelState } from '../../../model-hooks/use-model-state'\r\nimport Chart from '../../../models/chart'\r\nimport ChartLayout from '../../../models/chart_layout'\r\nimport { useDrawingAutoSaveControls } from '../../autosave/use-drawing-auto-save-controls'\r\nimport { getElementNoteText, getTickersAndContainerTypesInLayoutModel } from '../../autosave/utils'\r\n\r\ninterface ChartAutoSaveNoteProps {\r\n ticker: string\r\n note: string\r\n onNoteChange: (note: string, ticker: string) => void\r\n}\r\n\r\nfunction ChartAutoSaveNote({ ticker, note, onNoteChange }: ChartAutoSaveNoteProps) {\r\n return (\r\n ) => {\r\n onNoteChange(e.target.value, ticker)\r\n }}\r\n />\r\n )\r\n}\r\n\r\ninterface Props {\r\n chartLayoutModel: ChartLayout\r\n}\r\n\r\nexport function ChartAutoSaveNotes({ chartLayoutModel }: Props) {\r\n const { handleAutoSaveNoteChange } = useDrawingAutoSaveControls(chartLayoutModel)\r\n const [tickers, setTickers] = React.useState([])\r\n const unwatchedInternalStore = React.useMemo(() => chartLayoutModel.drawingsInternalStore(), [chartLayoutModel])\r\n const drawingsInternalStore = useModelState(unwatchedInternalStore, { watchProperties: ['elements'] })\r\n\r\n React.useEffect(() => {\r\n // There was no better way how to listen on ticker changes which is necessary for displaying correct text areas\r\n const handleChartChange = () => {\r\n const { tickers } = getTickersAndContainerTypesInLayoutModel(chartLayoutModel)\r\n setTickers(tickers)\r\n }\r\n\r\n Chart.bind('change', handleChartChange)\r\n handleChartChange()\r\n return () => {\r\n Chart.unbind('change', handleChartChange)\r\n }\r\n }, [chartLayoutModel])\r\n\r\n const tickerNoteMap = React.useMemo(() => {\r\n const map: ObjectHash = {}\r\n drawingsInternalStore.elements.forEach((element) => {\r\n if (element.containerType === 'note' && tickers.includes(element.ticker)) {\r\n map[element.ticker] = getElementNoteText(element)\r\n }\r\n })\r\n\r\n return map\r\n }, [drawingsInternalStore.elements, tickers])\r\n\r\n return (\r\n
\r\n {tickers.map((ticker) => (\r\n \r\n ))}\r\n
\r\n )\r\n}\r\n","import { Dialog, DialogBody, DialogHeader } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport ChartLayout from '../../../models/chart_layout'\r\nimport { ChartAutoSaveNotes } from './auto-save-notes'\r\n\r\ninterface INoteDialog {\r\n dialogState: any\r\n chartLayoutModel: ChartLayout\r\n}\r\n\r\nexport function AutoSaveNotesDialog({ dialogState, chartLayoutModel }: INoteDialog) {\r\n return (\r\n \r\n dialogState.hide()}>Notes\r\n \r\n {(dialogState.visible || dialogState.animating) && }\r\n \r\n \r\n )\r\n}\r\n","import { Button, ConfirmationDialog as ConfirmationDialogComponent } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nconst getDialogContent = ({\r\n isAutosaveDialogContent,\r\n tickers,\r\n}: {\r\n isAutosaveDialogContent: boolean\r\n tickers: string[]\r\n}) => {\r\n if (isAutosaveDialogContent) {\r\n return {\r\n title: 'Remove all autosaved drawings?',\r\n message: (\r\n <>\r\n Do you really want to remove all autosaved drawings? This action is irreversible and will remove all\r\n non-idea drawings for {tickers.join(', ')}.\r\n \r\n ),\r\n }\r\n }\r\n return {\r\n title: 'Remove all drawings?',\r\n message: `Do you really want to remove all drawings? This action only affects the current page and visible tickers. This action doesn't remove autosaved drawings or ideas.`,\r\n }\r\n}\r\n\r\nexport interface IConfirmationDialog {\r\n state: any\r\n onCancel: () => void\r\n onAction: () => void\r\n isAutosaveDialogContent: boolean\r\n tickers: string[]\r\n}\r\n\r\nexport function ConfirmationDialog({\r\n onCancel,\r\n onAction,\r\n state,\r\n isAutosaveDialogContent = false,\r\n tickers,\r\n}: IConfirmationDialog) {\r\n const dialogContent = getDialogContent({ isAutosaveDialogContent, tickers })\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n }\r\n >\r\n {dialogContent.message}\r\n \r\n )\r\n}\r\n","import { Button, Icon } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { drawingTools } from '../drawingTools'\r\nimport { DrawingTool } from '../interfaces'\r\n\r\ntype ToolButtonProps = {\r\n onClick: () => void\r\n activeTool: DrawingTool\r\n}\r\n\r\nexport default function ToolButton({ activeTool, onClick }: ToolButtonProps) {\r\n return (\r\n \r\n )\r\n}\r\n","import { Button } from '@finviz/website'\r\nimport classNames from 'classnames'\r\nimport React from 'react'\r\nimport ReactDOM from 'react-dom'\r\nimport { useSearchParams } from 'react-router-dom'\r\n\r\nimport { SIDEBAR_QUERY_PARAM } from '../../sidebar/sidebar'\r\nimport { MOBILE_TOOLBAR_DIV_ID } from '../../sidebar/sidebar-tabs'\r\nimport { DrawingActions, DrawingTool, IToolBarProps } from '../interfaces'\r\nimport Toolbar from '../toolbar'\r\nimport ToolButton from './tool-button'\r\n\r\ntype ToolbarMobileProps = Omit\r\n\r\nexport default function ToolbarMobile({\r\n activeTool,\r\n onActiveToolChange,\r\n onDrawingActionClick,\r\n ...rest\r\n}: ToolbarMobileProps) {\r\n const [isToolbarVisible, setIsToolbarVisible] = React.useState(false)\r\n const [urlSearchParams, setUrlSearchParams] = useSearchParams()\r\n const [toolbarMobileElement, setToolbarMobileElement] = React.useState(null)\r\n\r\n // get toolbar mobile element on first render\r\n React.useEffect(() => {\r\n setToolbarMobileElement(document.getElementById(MOBILE_TOOLBAR_DIV_ID))\r\n }, [])\r\n\r\n const handleActiveToolChange = React.useCallback(\r\n (drawingTool: DrawingTool, trigger?: 'button' | 'select' | 'group') => {\r\n onActiveToolChange(drawingTool, trigger)\r\n\r\n if (trigger !== 'group') return setIsToolbarVisible(false)\r\n },\r\n [onActiveToolChange]\r\n )\r\n\r\n // Hide toolbar on click outside\r\n const wrapperRef = React.useRef(null)\r\n React.useEffect(() => {\r\n if (!isToolbarVisible) return\r\n\r\n function handleClickOutside(event: TouchEvent | MouseEvent) {\r\n // Get the currently open select\r\n const openSelect = document.querySelector('.finviz-popover[data-enter]')\r\n if (wrapperRef.current?.contains(event.target as Node) || openSelect?.contains(event.target as Node)) return\r\n setIsToolbarVisible(false)\r\n }\r\n\r\n document.addEventListener('mousedown', handleClickOutside)\r\n document.addEventListener('touchstart', handleClickOutside)\r\n\r\n return () => {\r\n document.removeEventListener('mousedown', handleClickOutside)\r\n document.removeEventListener('touchstart', handleClickOutside)\r\n }\r\n }, [isToolbarVisible])\r\n\r\n const handleDrawingActionClick = (actionId: DrawingActions) => {\r\n onDrawingActionClick?.(actionId)\r\n setIsToolbarVisible(false)\r\n }\r\n\r\n if (!toolbarMobileElement) return null\r\n\r\n return ReactDOM.createPortal(\r\n <>\r\n \r\n \r\n \r\n {urlSearchParams.has(SIDEBAR_QUERY_PARAM) || activeTool === DrawingTool.Mouse ? (\r\n {\r\n setIsToolbarVisible(true)\r\n setUrlSearchParams((params) => {\r\n params.delete(SIDEBAR_QUERY_PARAM)\r\n return params\r\n })\r\n }}\r\n >\r\n Draw\r\n \r\n ) : (\r\n {\r\n setIsToolbarVisible(true)\r\n }}\r\n />\r\n )}\r\n ,\r\n toolbarMobileElement\r\n )\r\n}\r\n","import React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { AutoSaveState } from '../../models/constants'\r\n\r\ninterface LoadLatestDataButtonProps {\r\n chartLayoutModel: ChartLayout\r\n}\r\n\r\nexport function AutoSaveStateIndicator({ chartLayoutModel }: LoadLatestDataButtonProps) {\r\n const drawingsInternalStoreUnwatched = React.useMemo(\r\n () => chartLayoutModel.drawingsInternalStore(),\r\n [chartLayoutModel]\r\n )\r\n const { autoSaveState } = useModelState(drawingsInternalStoreUnwatched, { watchProperties: ['autoSaveState'] })!\r\n const [isVisible, setIsVisible] = React.useState(false)\r\n\r\n React.useEffect(() => {\r\n if (autoSaveState === AutoSaveState.Off) {\r\n return\r\n }\r\n\r\n let setVisibilityTimeout: NodeJS.Timeout | null = null\r\n const newIsVisible = autoSaveState !== AutoSaveState.Saved\r\n\r\n setVisibilityTimeout = setTimeout(\r\n () => {\r\n setIsVisible(newIsVisible)\r\n },\r\n newIsVisible ? 0 : 3000\r\n )\r\n\r\n const checkIfNeededPreventLeaving = (event: BeforeUnloadEvent) => {\r\n if (autoSaveState === AutoSaveState.Saved) {\r\n return undefined\r\n }\r\n\r\n const message = `Your latest changes haven't been saved yet. If you leave now, your changes might be lost.`\r\n event.returnValue = message\r\n return message\r\n }\r\n\r\n window.addEventListener('beforeunload', checkIfNeededPreventLeaving)\r\n\r\n return () => {\r\n window.removeEventListener('beforeunload', checkIfNeededPreventLeaving)\r\n if (setVisibilityTimeout) {\r\n clearTimeout(setVisibilityTimeout)\r\n }\r\n }\r\n }, [autoSaveState])\r\n\r\n if (!isVisible) {\r\n return null\r\n }\r\n\r\n // @todo - add proper indicator component here\r\n return null\r\n}\r\n","import { Textarea } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { isRedesignEnabled } from '../../utils'\r\nimport { useDrawingAutoSaveControls } from '../autosave/use-drawing-auto-save-controls'\r\n\r\ninterface Props {\r\n chartLayoutModel: ChartLayout\r\n ideaNoteRef?: React.RefObject\r\n}\r\n\r\nconst hasRedesign = isRedesignEnabled()\r\n\r\nexport function ChartLayoutAutoSaveNote({ chartLayoutModel: chartLayoutModelUnwatched, ideaNoteRef }: Props) {\r\n const chartLayoutModel = useModelState(chartLayoutModelUnwatched, {\r\n watchProperties: ['idea'],\r\n })!\r\n const { handleIdeaNoteChange } = useDrawingAutoSaveControls(chartLayoutModel)\r\n\r\n if (!chartLayoutModel.editable) {\r\n return null\r\n }\r\n\r\n return (\r\n
\r\n {!hasRedesign &&
Note:
}\r\n
\r\n ) => {\r\n handleIdeaNoteChange(e.target.value)\r\n }}\r\n />\r\n
\r\n
\r\n )\r\n}\r\n","import { getExtendedDialogState, useDialogState } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { publishModalAsyncModule } from '../../modals/publish/async-modules'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { useAsyncModule } from '../../utils/async-modules-utils'\r\n\r\ninterface PublishOldButtonClickListenerProps {\r\n isListening: boolean\r\n layoutModel: ChartLayout\r\n}\r\n\r\nexport function getPublishChartHtmlElements() {\r\n const publishChartElements = document.getElementsByClassName('js-publish-chart')\r\n const publishChartHtmlElements = Array.from(publishChartElements) as HTMLElement[]\r\n\r\n return publishChartHtmlElements\r\n}\r\n\r\nfunction getChartImgUrl(index: number) {\r\n const imgElement = document.getElementById(`chart${index}`) as HTMLImageElement | null\r\n return imgElement?.src ?? null\r\n}\r\n\r\nexport function PublishOldButtonClickListener({ isListening, layoutModel }: PublishOldButtonClickListenerProps) {\r\n const dialog = useDialogState()\r\n const { isFullyClosed } = getExtendedDialogState(dialog)\r\n const [dialogConfig, setDialogConfig] = React.useState({\r\n isCanvas: true,\r\n chartImgUrl: null as null | string,\r\n timeframe: '',\r\n ticker: '',\r\n })\r\n const [publishModalModule] = useAsyncModule({\r\n ...publishModalAsyncModule,\r\n shouldLoadModule: !isFullyClosed,\r\n })\r\n const PublishDialog = publishModalModule?.default\r\n\r\n React.useEffect(() => {\r\n const publishChartHtmlElements = getPublishChartHtmlElements()\r\n const clickHandler = (event: MouseEvent) => {\r\n const { index, ticker, timeframe } = (event.currentTarget as HTMLElement).dataset\r\n if (index && ticker && timeframe) {\r\n const indexInt = Number.parseInt(index)\r\n setDialogConfig({\r\n ticker,\r\n timeframe,\r\n isCanvas: indexInt === 0,\r\n chartImgUrl: indexInt > 0 ? getChartImgUrl(indexInt) : null,\r\n })\r\n dialog.show()\r\n }\r\n }\r\n\r\n if (isListening) {\r\n publishChartHtmlElements.forEach((el) => {\r\n el.addEventListener('click', clickHandler)\r\n })\r\n }\r\n\r\n return () => {\r\n publishChartHtmlElements.forEach((el) => {\r\n el.removeEventListener('click', clickHandler)\r\n })\r\n }\r\n }, [dialog, isListening])\r\n\r\n return PublishDialog ? : null\r\n}\r\n","import { Button, Dialog, DialogBody, DialogFooter, DialogHeader, Paragraph } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nexport enum IdeaDrawingsConfirmationOptions {\r\n Merge,\r\n Override,\r\n Nothing,\r\n Cancel,\r\n}\r\n\r\ninterface IIdeaLeaveDialog {\r\n state: any\r\n actionCallback: (action: IdeaDrawingsConfirmationOptions) => void\r\n}\r\n\r\nexport function IdeaLeaveDialog({ actionCallback, state }: IIdeaLeaveDialog) {\r\n return (\r\n actionCallback(IdeaDrawingsConfirmationOptions.Cancel)}\r\n finalFocusRef={{ current: document.body }}\r\n >\r\n actionCallback(IdeaDrawingsConfirmationOptions.Cancel)}>\r\n You’re About to Leave your Idea\r\n \r\n \r\n
\r\n What would you like to do with the drawings from your current Idea?\r\n \r\n Replace Drawings\r\n
\r\n Your Autosaved Drawings for this ticker will be deleted, and the Idea Drawings will be copied to the live\r\n chart.\r\n
\r\n \r\n Combine Drawings\r\n
\r\n The Idea Drawings will be copied to the live chart without changing the positions or settings of any\r\n Autosaved Drawings. This may cause duplicates if some drawings were also autosaved.\r\n
\r\n \r\n Do Nothing\r\n
\r\n Close the idea without changing any Autosaved Drawings.\r\n
\r\n
\r\n
\r\n \r\n actionCallback(IdeaDrawingsConfirmationOptions.Override)}\r\n >\r\n Replace\r\n \r\n actionCallback(IdeaDrawingsConfirmationOptions.Merge)}\r\n >\r\n Combine\r\n \r\n actionCallback(IdeaDrawingsConfirmationOptions.Nothing)}\r\n >\r\n Do Nothing\r\n \r\n \r\n \r\n )\r\n}\r\n","import { useDialogState, useTrackPageView } from '@finviz/website'\r\nimport * as dateFns from 'date-fns'\r\nimport React from 'react'\r\nimport { useLocation, useNavigate } from 'react-router-dom'\r\n\r\nimport {\r\n ChartElementType,\r\n ChartsOrQuotePageQueryParams,\r\n ChartsPageQueryParams,\r\n QuotePageQueryChartTypes,\r\n QuotePageQueryParams,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n} from '../../constants/common'\r\nimport Chart from '../../models/chart'\r\nimport ChartLayoutModel from '../../models/chart_layout'\r\nimport { getRawTickerForInstrument } from '../../models/utils'\r\nimport utils from '../../utils'\r\nimport { getInstrument, handleTypeChange } from '../../utils/chart'\r\nimport { getUuid } from '../../utils/helpers'\r\nimport { initHlc } from '../../utils/hlc'\r\nimport { decodeQueryString, encodeQueryString } from '../../utils/query_string'\r\nimport { IdeaLeaveDialog } from '../autosave/idea-leave-dialog'\r\nimport { IdeaDrawingsConfirmationOptions } from '../autosave/idea-leave-dialog'\r\nimport { useDrawingAutoSaveApi } from '../autosave/use-drawing-autosave-api'\r\nimport { getTickersAndContainerTypesInLayoutModel, handleCallMethodOnAllDrawings } from '../autosave/utils'\r\nimport { getChartElementTypeFromResponseType } from '../utils'\r\n\r\nconst getChartElementTypeFromQueryType = (queryType: QuotePageQueryChartTypes | null) => {\r\n switch (queryType) {\r\n case QuotePageQueryChartTypes.l:\r\n return ChartElementType.LineChart\r\n case QuotePageQueryChartTypes.hc:\r\n return ChartElementType.HollowCandleStick\r\n case QuotePageQueryChartTypes.ha:\r\n return ChartElementType.HeikinAshi\r\n case QuotePageQueryChartTypes.o:\r\n return ChartElementType.OhlcChart\r\n case QuotePageQueryChartTypes.p:\r\n return ChartElementType.PerfChart\r\n case QuotePageQueryChartTypes.c:\r\n case QuotePageQueryChartTypes.cs:\r\n return ChartElementType.CandleStick\r\n default:\r\n return (\r\n getChartElementTypeFromResponseType(window.FinvizSettings?.TA?.style ?? null) ?? ChartElementType.CandleStick\r\n )\r\n }\r\n}\r\n\r\nconst useChartRouteChange = (chartLayoutModel: ChartLayoutModel | null) => {\r\n useTrackPageView({ trackInitial: false })\r\n const location = useLocation()\r\n const navigate = useNavigate()\r\n const { deleteAllDrawings } = useDrawingAutoSaveApi()\r\n const dialog = useDialogState()\r\n\r\n const isQuotePage = chartLayoutModel?.specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n const isChartPage = chartLayoutModel?.specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const isFuturesForexCryptoPage = [\r\n SpecificChartFunctionality.futuresPage,\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n ].includes(chartLayoutModel?.specificChartFunctionality as SpecificChartFunctionality)\r\n\r\n React.useEffect(() => {\r\n if (isChartPage) {\r\n utils.setCookie(\r\n 'chartsUrl',\r\n `?${encodeQueryString({ ...decodeQueryString(location.search), i: undefined, settings: undefined })}`,\r\n dateFns.add(new Date(), { months: 1 })\r\n )\r\n }\r\n }, [isChartPage, location.search])\r\n\r\n React.useEffect(() => {\r\n const decodedQueryString = decodeQueryString(location.search)\r\n // We can navigate to idea chart without a refresh e.g. using browser back button\r\n // It breaks charts because we don't have idea data & idea quote anymore\r\n // So if we end up on a page with idea in the url and we don't have any idea data in chartLayout model we'll refresh the page\r\n if (chartLayoutModel && decodedQueryString.i && !chartLayoutModel.idea?.id) {\r\n window.location.reload()\r\n }\r\n // No need to have chartLayoutModel as dependecny here , I'm only interested in idea on the model\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [location.search, chartLayoutModel?.idea?.id])\r\n\r\n const updateChartConfig = React.useCallback(() => {\r\n if (!chartLayoutModel) return\r\n\r\n const decodedSearch = decodeQueryString(location.search)\r\n\r\n const urlType = (decodedSearch as QuotePageQueryParams).ty ?? null\r\n handleTypeChange({\r\n type: getChartElementTypeFromQueryType(urlType),\r\n chartLayoutModel,\r\n })\r\n\r\n if (isChartPage && chartLayoutModel.layout !== (decodedSearch as ChartsPageQueryParams).l) {\r\n chartLayoutModel.updateAttributes({ layout: (decodedSearch as ChartsPageQueryParams).l })\r\n }\r\n\r\n chartLayoutModel.getAllCharts().forEach((chartModel, chartIndex) => {\r\n const urlTicker = decodedSearch.t.split(',')[chartIndex] ?? null\r\n const urlTimeframe = decodedSearch.p?.split(',')[chartIndex] ?? null\r\n const urlDateRange = decodedSearch.r?.split(',')[chartIndex] ?? null\r\n const upperCaseTicker = urlTicker?.toUpperCase()\r\n\r\n /**\r\n * Only Charts page charts can change instruments. Other pages need forced\r\n * instrument because we might not be able to guess it from urlTicker\r\n */\r\n let instrument = getInstrument(upperCaseTicker)\r\n if (chartLayoutModel.specificChartFunctionality !== SpecificChartFunctionality.chartPage) {\r\n instrument = chartModel.instrument\r\n }\r\n\r\n const newChartConfig = {\r\n instrument,\r\n ticker: getRawTickerForInstrument(instrument, upperCaseTicker),\r\n timeframe: urlTimeframe,\r\n dateRange: urlDateRange,\r\n }\r\n\r\n if (Object.entries(newChartConfig).some(([key, value]) => chartModel[key as keyof Chart] !== value)) {\r\n chartModel.updateAttributesAndSync(newChartConfig)\r\n }\r\n })\r\n }, [chartLayoutModel, location.search, isChartPage])\r\n\r\n React.useEffect(() => {\r\n const decodedSearch = decodeQueryString(location.search)\r\n\r\n if (\r\n !chartLayoutModel ||\r\n !decodedSearch.p ||\r\n !decodedSearch.t ||\r\n !(isQuotePage || isChartPage || isFuturesForexCryptoPage)\r\n ) {\r\n if (!decodedSearch.p && isQuotePage) {\r\n navigate(\r\n {\r\n search: `?${encodeQueryString({\r\n ...decodedSearch,\r\n p: window.FinvizSettings.defaultPeriod ?? TIMEFRAME.d,\r\n r: window.FinvizSettings.defaultDateRange,\r\n })}`,\r\n },\r\n {\r\n replace: true,\r\n }\r\n )\r\n }\r\n return\r\n }\r\n if (chartLayoutModel.idea?.id && dialog.visible) {\r\n dialog.hide()\r\n }\r\n\r\n if (!decodedSearch.i && chartLayoutModel.idea?.id) {\r\n const urlTicker = decodedSearch.t.split(',')\r\n const isSameTicker = chartLayoutModel\r\n .getAllCharts()\r\n .every((chart, i) => chart.getQuoteRawTicker() === urlTicker[i])\r\n\r\n if (isSameTicker && window.FinvizSettings.hasUserPremium && chartLayoutModel.isPreserveDrawingsActive) {\r\n dialog.show()\r\n return\r\n }\r\n if (!chartLayoutModel.isPreserveDrawingsActive || !isSameTicker) {\r\n handleCallMethodOnAllDrawings({ chartLayoutModel, elementMethod: 'destroyCascade' })\r\n }\r\n chartLayoutModel.exitIdea()\r\n }\r\n updateChartConfig()\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [\r\n location.search,\r\n dialog.show,\r\n navigate,\r\n chartLayoutModel,\r\n isQuotePage,\r\n isChartPage,\r\n isFuturesForexCryptoPage,\r\n updateChartConfig,\r\n ])\r\n\r\n const handleIdeaLeave = React.useCallback(\r\n async (action: IdeaDrawingsConfirmationOptions) => {\r\n if (!chartLayoutModel) return\r\n if (action === IdeaDrawingsConfirmationOptions.Cancel) {\r\n navigate(-1)\r\n return\r\n }\r\n switch (action) {\r\n case IdeaDrawingsConfirmationOptions.Merge: {\r\n handleCallMethodOnAllDrawings({\r\n chartLayoutModel,\r\n elementMethod: 'refreshElementId',\r\n })\r\n break\r\n }\r\n case IdeaDrawingsConfirmationOptions.Override: {\r\n const { tickers } = getTickersAndContainerTypesInLayoutModel(chartLayoutModel)\r\n await deleteAllDrawings({ tickers, lastLocalChange: initHlc(getUuid(), Date.now()) })\r\n break\r\n }\r\n case IdeaDrawingsConfirmationOptions.Nothing: {\r\n handleCallMethodOnAllDrawings({\r\n chartLayoutModel,\r\n elementMethod: 'destroyCascade',\r\n })\r\n break\r\n }\r\n default:\r\n break\r\n }\r\n chartLayoutModel.exitIdea()\r\n updateChartConfig()\r\n dialog.hide()\r\n },\r\n [dialog, chartLayoutModel, updateChartConfig, deleteAllDrawings, navigate]\r\n )\r\n\r\n return {\r\n dialog,\r\n handleIdeaLeave,\r\n }\r\n}\r\n\r\nfunction getChartLayoutWithChartRouteChange

(\r\n Component: React.ComponentType

\r\n) {\r\n return function WrappedComponent(props: P) {\r\n const { dialog, handleIdeaLeave } = useChartRouteChange(props.chartLayoutModel)\r\n return (\r\n <>\r\n \r\n \r\n \r\n )\r\n }\r\n}\r\n\r\nexport function withChartRouteChange

(\r\n Component: React.ComponentType

\r\n) {\r\n // Chart layout is used in ReactRouter context and also outside of RR context\r\n // if we use RR hooks outside the context it will crash so this function will return different component for quote & chart pages than for other usecases\r\n const ChartLayoutComponent = getChartLayoutWithChartRouteChange(Component)\r\n return function WrappedComponent(props: P) {\r\n const { ty } = decodeQueryString()\r\n const isChartPage = props.chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const isQuotePage = props.chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n const isFuturesForexCryptoPage = [\r\n SpecificChartFunctionality.futuresPage,\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n ].includes(props.chartLayoutModel.specificChartFunctionality)\r\n if (isChartPage || (isQuotePage && ty !== 'p') || isFuturesForexCryptoPage) {\r\n return \r\n }\r\n\r\n return \r\n }\r\n}\r\n","import merge from 'lodash.merge'\r\nimport React from 'react'\r\n\r\nimport { RootChartConfigObject, Theme } from '../../../types/shared'\r\nimport {\r\n ChartEditorEnum,\r\n MOBILE_BARS_TO_VIEW,\r\n MOBILE_VIEW_BREAKPOINT_WIDTH,\r\n SpecificChartFunctionality,\r\n} from '../../constants/common'\r\nimport ChartLayoutModel from '../../models/chart_layout'\r\nimport DrawingsInternalStore from '../../models/drawings-internal-store'\r\nimport { getSettings } from '../../models/settings'\r\nimport utils, { isRedesignedPage } from '../../utils'\r\nimport { getIsPreserveDrawingsAndAutosaveAvailable, getZoomFactorForBarsToDisplay } from '../../utils/chart'\r\nimport { getContainerTypeFromPaneConfig, getInitialStoreDrawings } from '../autosave/utils'\r\nimport { DrawingSetting } from '../toolbar/interfaces'\r\nimport { CHART_LAYOUT_CHILD_CHANGE_EVENT } from './constants'\r\n\r\ninterface Props {\r\n config: RootChartConfigObject\r\n onRegisterChartLayoutModel?: (chartLayoutModel: ChartLayoutModel) => void\r\n parentElement?: HTMLElement\r\n}\r\n\r\nfunction getDefaultZoomFactor(chartLayout: ChartLayoutModel) {\r\n const innerWidth = window.innerWidth\r\n if (\r\n innerWidth >= MOBILE_VIEW_BREAKPOINT_WIDTH ||\r\n chartLayout.specificChartFunctionality !== SpecificChartFunctionality.chartPage\r\n ) {\r\n return 1\r\n }\r\n\r\n return getZoomFactorForBarsToDisplay({\r\n chartLayout,\r\n numOfVisibleBars: MOBILE_BARS_TO_VIEW,\r\n chartVisibleWidth: innerWidth,\r\n })\r\n}\r\n\r\nfunction OnInitListener({\r\n chartLayoutModel,\r\n config,\r\n onRegisterChartLayoutModel,\r\n parentElement,\r\n}: Props & { chartLayoutModel: ChartLayoutModel; parentElement?: HTMLElement }) {\r\n const [isInit, setIsInit] = React.useState(false)\r\n\r\n /*\r\n * This entire effect is used to check for updates in entire chart layout obj tree.\r\n * Once config object matches object generated from chart layout, the layout model is completely initialised.\r\n *\r\n * We couldn't just add a callback to `componentDidMount` (or equivalent) because its children are rendered asynchronously.\r\n *\r\n * */\r\n React.useEffect(() => {\r\n if (onRegisterChartLayoutModel && chartLayoutModel && !isInit) {\r\n const checkIfInitIsComplete = () => {\r\n const { charts } = chartLayoutModel.toConfig()\r\n const isReady =\r\n charts.length === config.charts.length &&\r\n charts.every(\r\n (chart, chartIndex) =>\r\n chart.panes.length === config.charts[chartIndex].panes.length &&\r\n chart.panes.every(\r\n (pane, paneIndex) =>\r\n pane.elements.length === config.charts[chartIndex].panes[paneIndex].elements.length &&\r\n pane.elements.every(\r\n (element, elementIndex) =>\r\n element.overlays?.length ===\r\n config.charts[chartIndex].panes[paneIndex].elements[elementIndex].overlays?.length\r\n )\r\n )\r\n )\r\n\r\n if (isReady) {\r\n setIsInit(true)\r\n chartLayoutModel.updateAttributes({ isInit: true })\r\n onRegisterChartLayoutModel(chartLayoutModel)\r\n if (parentElement) {\r\n parentElement.style.opacity = 'unset'\r\n parentElement.style.minHeight = 'unset'\r\n parentElement.style.minWidth = 'unset'\r\n }\r\n }\r\n }\r\n\r\n chartLayoutModel.bind(CHART_LAYOUT_CHILD_CHANGE_EVENT, checkIfInitIsComplete)\r\n\r\n checkIfInitIsComplete()\r\n\r\n return () => {\r\n chartLayoutModel.unbind(CHART_LAYOUT_CHILD_CHANGE_EVENT, checkIfInitIsComplete)\r\n }\r\n }\r\n }, [chartLayoutModel, config, isInit, onRegisterChartLayoutModel, parentElement])\r\n\r\n return null\r\n}\r\n\r\nexport const withCompleteLayoutModelInit = (Component: any) => (props: Props) => {\r\n const config = React.useMemo(() => {\r\n const newConfig = merge({}, props.config, {\r\n editable: props.config.editable ?? true,\r\n canChangeTicker: props.config.canChangeTicker ?? true,\r\n scrollable: props.config.scrollable ?? true,\r\n cross: props.config.cross ?? true,\r\n theme:\r\n props.config.theme && [Theme.light, Theme.dark].includes(props.config.theme) ? props.config.theme : Theme.light,\r\n editors: props.config.editors ?? [ChartEditorEnum.publish, ChartEditorEnum.tools, ChartEditorEnum.ideas],\r\n ideas: props.config.ideas ?? true,\r\n specificChartFunctionality: props.config.specificChartFunctionality ?? SpecificChartFunctionality.default,\r\n initialStoreDrawings: [],\r\n })\r\n\r\n if (!newConfig.ideas) {\r\n newConfig.editors = newConfig.editors.filter((x) => x !== 'ideas')\r\n }\r\n\r\n // We need to add these because ideas might not have them and chart controls wouldn’t render properly\r\n if (isRedesignedPage(newConfig, [SpecificChartFunctionality.quotePage])) {\r\n newConfig.editors = newConfig.editors.concat([ChartEditorEnum.settings, ChartEditorEnum.timeframe])\r\n }\r\n\r\n const initialStoreDrawings = getInitialStoreDrawings()?.filter(({ changeType }) => changeType !== 'destroy') ?? []\r\n const isQuotePage = newConfig.specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n const isQuotePageWithDrawingsOff = isQuotePage && utils.getCookie('charts-draw') !== 'on'\r\n\r\n if (initialStoreDrawings.length === 0 || isQuotePageWithDrawingsOff) {\r\n return newConfig\r\n }\r\n\r\n const noteDrawing = initialStoreDrawings.find(\r\n ({ containerType, ticker }) =>\r\n containerType === 'note' && props.config.charts.some((chart) => chart.ticker === ticker)\r\n )\r\n\r\n const note = noteDrawing && JSON.parse(noteDrawing.elementAttrs)?.text\r\n const ideaObject = isQuotePage && note ? { note } : undefined\r\n\r\n return {\r\n ...newConfig,\r\n initialStoreDrawings,\r\n idea: newConfig.idea ?? ideaObject,\r\n charts: newConfig.charts.map((chart) => {\r\n const { ticker, panes } = chart\r\n return {\r\n ...chart,\r\n panes: panes.map((pane) => {\r\n const containerType = getContainerTypeFromPaneConfig(pane)\r\n const newElements = initialStoreDrawings\r\n .filter(\r\n (drawing) =>\r\n drawing.containerType === containerType &&\r\n drawing.ticker === ticker &&\r\n !pane.elements.some((paneElement) => paneElement.elementId === drawing.elementId)\r\n )\r\n .map(({ elementId, zIndex, elementAttrs }) => ({\r\n elementId,\r\n zIndex,\r\n ...JSON.parse(elementAttrs),\r\n }))\r\n return {\r\n ...pane,\r\n elements: [...pane.elements, ...newElements],\r\n }\r\n }),\r\n }\r\n }),\r\n }\r\n // We need to disable the eslint check because the hook is supposed to run only once on mount\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n const chartLayoutModel = React.useMemo(() => {\r\n const settings = getSettings({ ...config, theme: config.theme! })\r\n const chartLayout = ChartLayoutModel.create({\r\n layout: config.layout,\r\n width: config.width,\r\n height: config.height,\r\n editable: config.editable,\r\n canChangeTicker: config.canChangeTicker,\r\n scrollable: config.scrollable,\r\n initialScrollable: config.scrollable,\r\n cross: config.cross,\r\n editors: config.editors,\r\n theme: config.theme,\r\n idea: config.idea,\r\n settings,\r\n isWheelZoomEnabled: config.specificChartFunctionality === SpecificChartFunctionality.chartPage,\r\n specificChartFunctionality: config.specificChartFunctionality,\r\n isHideDrawingsActive: false,\r\n isPreserveDrawingsActive: !!(\r\n getIsPreserveDrawingsAndAutosaveAvailable(config) &&\r\n window.FinvizSettings.toolsState?.[DrawingSetting.PreserveDrawings]\r\n ),\r\n isLockDrawingsActive: false,\r\n uuid: config.uuid,\r\n drawingsInternalStore: DrawingsInternalStore.create({\r\n elements: config.initialStoreDrawings,\r\n }),\r\n })\r\n\r\n chartLayout.updateAttributes({ defaultZoomFactor: getDefaultZoomFactor(chartLayout) })\r\n\r\n return chartLayout\r\n\r\n // We need to disable the eslint check because the hook is supposed to run only once on mount\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n return chartLayoutModel ? (\r\n <>\r\n \r\n \r\n \r\n ) : null\r\n}\r\n","import debounce from 'lodash.debounce'\r\nimport React from 'react'\r\n\r\nimport Chart from '../../models/chart'\r\nimport Quote from '../../models/quote'\r\n\r\nconst MAX_QUOTE_CACHE_TIME_IN_MS = 300000 // 5 min\r\n\r\nexport const withQuoteCacheManagement = (Component: any) => (props: any) => {\r\n React.useEffect(() => {\r\n const cleanupQuoteCache = () => {\r\n const allQuotes = Quote.all()\r\n const allCharts = Chart.all()\r\n const allChartQuotes = allCharts.flatMap((chart) => chart.getAllQuotes())\r\n\r\n allQuotes.forEach((quote) => {\r\n if (\r\n !allChartQuotes.some((usedQuote) => usedQuote.eql(quote)) &&\r\n !quote.isFetching &&\r\n quote.fetchedAt > -1 &&\r\n quote.fetchedAt < Date.now() - MAX_QUOTE_CACHE_TIME_IN_MS\r\n ) {\r\n quote.destroy()\r\n }\r\n })\r\n }\r\n\r\n const checkQuoteCacheDebounce = debounce(cleanupQuoteCache, 500)\r\n\r\n Quote.bind('change', checkQuoteCacheDebounce)\r\n return () => {\r\n checkQuoteCacheDebounce.cancel()\r\n Quote.unbind('change', checkQuoteCacheDebounce)\r\n }\r\n }, [])\r\n\r\n return \r\n}\r\n","import debounce from 'lodash.debounce'\r\nimport React from 'react'\r\n\r\nimport { ObjectHash } from '../../../types/shared'\r\nimport { EXTRA_MARKET_BUFFER_MINUTES, QUOTE_FETCH_EVENT } from '../../constants/common'\r\nimport Chart from '../../models/chart'\r\nimport ChartLayoutModel from '../../models/chart_layout'\r\nimport Pane from '../../models/pane'\r\nimport { QuoteFetchType } from '../../models/quote/constants'\r\n\r\ninterface Props {\r\n chartLayoutModel: ChartLayoutModel\r\n}\r\n\r\ntype PollingIntervalToChartsType = ObjectHash\r\n\r\n/*\r\n * This HOC loops through all charts and checks if they are supposed to be refetch in some interval\r\n * It creates groups of charts to be refreshed grouped by the refresh interval\r\n * */\r\nexport const withQuotePolling = (Component: any) => (props: Props) => {\r\n const [pollingIntervalToCharts, setPollingIntervalToCharts] = React.useState({})\r\n const checkForChartsWithPolling = React.useCallback(() => {\r\n // check for charts which have some refresh interval and group chart ids by the interval value e.g. { interval_in_ms: [id1, id2] }\r\n const newPollingIntervalToCharts: PollingIntervalToChartsType = {} // example { 60000: ['c-0', 'c-1'], 9000: ['c-4'] }\r\n props.chartLayoutModel.getAllCharts().forEach((chart) => {\r\n const chartRefreshInterval = chart.getRefreshInterval()\r\n\r\n if (chartRefreshInterval) {\r\n newPollingIntervalToCharts[chartRefreshInterval] = newPollingIntervalToCharts[chartRefreshInterval] ?? []\r\n newPollingIntervalToCharts[chartRefreshInterval].push(chart.id)\r\n }\r\n })\r\n\r\n if (JSON.stringify(newPollingIntervalToCharts) !== JSON.stringify(pollingIntervalToCharts)) {\r\n setPollingIntervalToCharts(newPollingIntervalToCharts)\r\n }\r\n }, [props.chartLayoutModel, pollingIntervalToCharts])\r\n const intervalIdsRef = React.useRef([])\r\n\r\n React.useEffect(() => {\r\n const checkForChartsWithPollingDebounced = debounce(checkForChartsWithPolling)\r\n const chartsCheckerIntervalId = window.setInterval(\r\n checkForChartsWithPollingDebounced,\r\n EXTRA_MARKET_BUFFER_MINUTES * 1000\r\n )\r\n\r\n // listen on any changes in all charts & panes and call debounced check for charts/indicators with quotes that needs to be refetched periodically\r\n Chart.bind('change', checkForChartsWithPollingDebounced)\r\n Pane.bind('change', checkForChartsWithPollingDebounced)\r\n\r\n return () => {\r\n checkForChartsWithPollingDebounced.cancel()\r\n Chart.unbind('change', checkForChartsWithPollingDebounced)\r\n Pane.unbind('change', checkForChartsWithPollingDebounced)\r\n window.clearInterval(chartsCheckerIntervalId)\r\n }\r\n }, [checkForChartsWithPolling])\r\n\r\n React.useEffect(() => {\r\n const timeoutDurations = Object.keys(pollingIntervalToCharts).map(Number)\r\n const allCharts = props.chartLayoutModel.getAllCharts()\r\n const timeoutDurationsMin = Math.min(...timeoutDurations)\r\n\r\n timeoutDurations.forEach((duration) => {\r\n const timeoutId = window.setInterval(() => {\r\n const chartIds = pollingIntervalToCharts[duration]\r\n // get all UNIQUE quotes used in charts and refetch them\r\n allCharts\r\n .filter((chart) => chartIds.includes(chart.id))\r\n .flatMap((chart) => chart.getAllQuotes())\r\n .filter(\r\n (quote, index, quotesToUpdate) =>\r\n !quote.isFetching && index === quotesToUpdate.findIndex((quoteToUpdate) => quote.eql(quoteToUpdate))\r\n )\r\n .forEach((quote) => {\r\n quote.fetchData({ fetchType: QuoteFetchType.NewerData })\r\n })\r\n if (duration === timeoutDurationsMin) {\r\n document.dispatchEvent(new Event(QUOTE_FETCH_EVENT))\r\n }\r\n }, duration)\r\n intervalIdsRef.current.push(timeoutId)\r\n })\r\n\r\n return () => {\r\n if (intervalIdsRef.current.length > 0) {\r\n intervalIdsRef.current.forEach((timeoutId) => {\r\n window.clearInterval(timeoutId)\r\n })\r\n intervalIdsRef.current = []\r\n }\r\n }\r\n }, [props.chartLayoutModel, pollingIntervalToCharts])\r\n\r\n return \r\n}\r\n","import Spine from '@finviz/spine'\r\nimport { ChartGrid, ChartGridCell } from '@finviz/website'\r\nimport classnames from 'classnames'\r\nimport flowRight from 'lodash.flowright'\r\nimport merge from 'lodash.merge'\r\nimport throttle from 'lodash.throttle'\r\nimport React from 'react'\r\nimport * as ReactDOM from 'react-dom'\r\n\r\nimport {\r\n ChartConfigObject,\r\n DrawingSpineOptionsEvent,\r\n IIdea,\r\n RootChartConfigObject,\r\n RootChartConfigObjectChart,\r\n} from '../../../types/shared'\r\nimport { ChartEditorEnum, LAYOUTS, LayoutType, SpecificChartFunctionality } from '../../constants/common'\r\nimport ChartModel from '../../models/chart'\r\nimport ChartLayoutModel from '../../models/chart_layout'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { AutoSaveState } from '../../models/constants'\r\nimport ElementModel from '../../models/element'\r\nimport utils, {\r\n getChartsDimensions,\r\n getFullscreenStatus,\r\n getIsMobilePortrait,\r\n isRedesignEnabled,\r\n isRedesignedPage,\r\n} from '../../utils'\r\nimport { getIsPreserveDrawingsAndAutosaveAvailable, getIsSidebarEnabled } from '../../utils/chart'\r\nimport fetchApi from '../../utils/fetch_api'\r\nimport { getTickersAndContainerTypesInLayoutModel } from '../autosave/utils'\r\nimport { withDrawingsAutoSave } from '../autosave/with-auto-save'\r\nimport Chart from '../chart'\r\nimport { SidebarDirection } from '../sidebar/constants'\r\nimport { Sidebar } from '../sidebar/sidebar'\r\nimport Toolbar from '../toolbar'\r\nimport { AutoSaveNotesDialog } from '../toolbar/auto-save-notes'\r\nimport { ConfirmationDialog } from '../toolbar/confirmation_dialog'\r\nimport { DrawingActions, DrawingSetting, DrawingTool } from '../toolbar/interfaces'\r\nimport ToolbarMobile from '../toolbar/mobile/toolbar-mobile'\r\nimport { withDialogState } from '../with_dialog_state_hook'\r\nimport { AutoSaveStateIndicator } from './auto-save-state-indicator'\r\nimport { ChartLayoutAutoSaveNote } from './chart-layout-auto-save-note'\r\nimport { PublishOldButtonClickListener, getPublishChartHtmlElements } from './publish_old_button_click_listener'\r\nimport { withChartPageTitle } from './with-chart-page-title'\r\nimport { withChartRouteChange } from './with-chart-route-change'\r\nimport { withCompleteLayoutModelInit } from './with-complete-layout-model-init'\r\nimport { withIdeaModelState } from './with-idea-model-state'\r\nimport { withQuoteCacheManagement } from './with-quote-cache-management'\r\nimport { withQuotePolling } from './with-quote-polling'\r\n\r\ninterface ChartLayoutComponentProps {\r\n config: RootChartConfigObject\r\n confirmationDialogState: any\r\n noteDialogState: any\r\n shouldResize?: boolean\r\n chartLayoutModel: ChartLayoutModel\r\n idea?: IIdea\r\n deleteAllAutoSavedElements: () => void\r\n isAutoSaveActive: boolean\r\n}\r\n\r\ninterface ChartLayoutComponentState {\r\n editable: boolean\r\n editors: ChartEditorEnum[]\r\n layout: LayoutType\r\n activeChartInteraction: string | null\r\n touchEventsDisabled: boolean\r\n isToolbarHorizontal: boolean\r\n activeTool: DrawingTool\r\n drawingSettings: Record\r\n}\r\n\r\nclass ChartLayoutComponentBase extends React.Component {\r\n // expects config, bindPublic\r\n model: ChartLayoutModel\r\n isMobile = Boolean(utils.isMobile(true))\r\n charts: Array<{ model: ChartModel; config: RootChartConfigObjectChart }>\r\n orientationChangeTimeout: number | undefined\r\n preserveDrawingAbortController = new AbortController()\r\n\r\n constructor(props: ChartLayoutComponentProps) {\r\n super(props)\r\n\r\n this.model = props.chartLayoutModel\r\n const config = props.config\r\n\r\n this.charts = []\r\n for (const chartConfig of config.charts) {\r\n const modelProperties: Partial = merge({}, chartConfig)\r\n\r\n modelProperties.chart_layout = this.model\r\n delete modelProperties.panes\r\n if (modelProperties.zoomFactor == null) {\r\n modelProperties.zoomFactor = this.model.defaultZoomFactor\r\n }\r\n if (modelProperties.refreshData == null) {\r\n modelProperties.refreshData = true\r\n }\r\n if (!modelProperties.dateRange) {\r\n modelProperties.dateRange = null\r\n }\r\n modelProperties.isHideDrawingsActive = this.model.isHideDrawingsActive\r\n modelProperties.isScrolled = false\r\n const model = this.model.charts().create(modelProperties)\r\n this.charts.push({ model, config: chartConfig })\r\n }\r\n this.model.updateAttribute('activeChart', this.model.charts().first())\r\n\r\n this.state = {\r\n editable: this.model.editable,\r\n editors: this.model.editors,\r\n layout: this.model.layout,\r\n activeChartInteraction: null,\r\n activeTool: DrawingTool.Mouse,\r\n touchEventsDisabled: false,\r\n isToolbarHorizontal: true,\r\n drawingSettings: {\r\n [DrawingSetting.DrawingModeContinuous]: false,\r\n [DrawingSetting.PreserveDrawings]: this.handleInitialPreserveDrawingsState(),\r\n [DrawingSetting.HideDrawings]: false,\r\n [DrawingSetting.LockDrawings]: false,\r\n },\r\n }\r\n }\r\n\r\n componentDidMount() {\r\n if (this.state.editable) {\r\n const DELETE = 46\r\n window.addEventListener('keyup', (e) => {\r\n const selected = this.model.getPaneWithSelection()\r\n if (e.keyCode === DELETE && selected) {\r\n const element = ElementModel.findByAttribute('instance', selected.selection)\r\n if (element) {\r\n const elementPane = element.pane()\r\n element.destroyCascade({ eventType: DrawingSpineOptionsEvent.Remove })\r\n elementPane.normalizeZIndexes()\r\n }\r\n }\r\n })\r\n }\r\n\r\n if (this.isMobile) {\r\n this.model.settings.ThumbSettings.size = this.model.settings.ThumbSettings.touchSize\r\n }\r\n\r\n this.onModelChange()\r\n\r\n this.model.bind('change', this.onModelChange)\r\n this.model.charts().bind('destroy', this.onChartDestroy)\r\n\r\n this.setToolbarPosition()\r\n window.addEventListener('resize', this.onWindowResize)\r\n window.addEventListener('orientationchange', this.handleOrientationChange)\r\n\r\n if (this.isMobile) {\r\n this.checkTouchEventsDisabled()\r\n window.addEventListener('touchend', this.checkTouchEventsDisabled)\r\n }\r\n }\r\n\r\n componentDidUpdate(prevProps: Readonly): void {\r\n if (prevProps.idea && !this.props.idea) {\r\n if (this.model.specificChartFunctionality === SpecificChartFunctionality.chartPage) {\r\n this.onWindowResize()\r\n }\r\n document.querySelector('#idea-title-container')?.remove()\r\n }\r\n\r\n this.setToolbarPosition()\r\n }\r\n\r\n componentWillUnmount() {\r\n this.preserveDrawingAbortController.abort()\r\n this.model.unbind('change', this.onModelChange)\r\n\r\n window.removeEventListener('resize', this.onWindowResize)\r\n window.removeEventListener('orientationchange', this.handleOrientationChange)\r\n\r\n if (this.isMobile) {\r\n window.removeEventListener('touchend', this.checkTouchEventsDisabled)\r\n }\r\n\r\n clearTimeout(this.orientationChangeTimeout)\r\n this.throttledResize.cancel()\r\n this.model.destroyCascade()\r\n }\r\n\r\n handleInitialPreserveDrawingsState = () => {\r\n let preserveDrawings = false\r\n if (getIsPreserveDrawingsAndAutosaveAvailable(this.model)) {\r\n if (window.FinvizSettings.toolsState?.[DrawingSetting.PreserveDrawings] !== undefined) {\r\n preserveDrawings = window.FinvizSettings.toolsState[DrawingSetting.PreserveDrawings]\r\n } else {\r\n this.handlePreserveDrawingsSettings()\r\n }\r\n }\r\n this.model.updateAttribute('isPreserveDrawingsActive', preserveDrawings)\r\n return preserveDrawings\r\n }\r\n\r\n handlePreserveDrawingsSettings = async (value?: boolean) => {\r\n const setPreserveDrawings = (val: boolean) => {\r\n this.model.updateAttribute('isPreserveDrawingsActive', val)\r\n this.setState((prevState) => ({\r\n drawingSettings: {\r\n ...prevState.drawingSettings,\r\n [DrawingSetting.PreserveDrawings]: val,\r\n },\r\n }))\r\n }\r\n\r\n try {\r\n this.preserveDrawingAbortController.abort()\r\n this.preserveDrawingAbortController = new AbortController()\r\n const response = await fetchApi({\r\n location: '/api/tools_state.ashx',\r\n method: value !== undefined ? 'POST' : 'GET',\r\n body:\r\n value !== undefined\r\n ? new URLSearchParams({ tools_state: JSON.stringify({ [DrawingSetting.PreserveDrawings]: value }) })\r\n : undefined,\r\n throwOnStatusCodes: [404],\r\n abortController: this.preserveDrawingAbortController,\r\n })\r\n\r\n if (value === undefined && response?.[DrawingSetting.PreserveDrawings] !== undefined) {\r\n setPreserveDrawings(response[DrawingSetting.PreserveDrawings])\r\n }\r\n } catch {\r\n if (value !== undefined) {\r\n setPreserveDrawings(!value)\r\n }\r\n }\r\n }\r\n\r\n handleOrientationChange = () => {\r\n this.orientationChangeTimeout = window.setTimeout(() => {\r\n this.setToolbarPosition()\r\n if (this.props.shouldResize) {\r\n this.handleResize()\r\n }\r\n })\r\n }\r\n\r\n onWindowResize = () => {\r\n this.setToolbarPosition()\r\n\r\n if (this.props.shouldResize) {\r\n this.throttledResize()\r\n }\r\n }\r\n\r\n handleResize = () => {\r\n const modelAttrs: Partial = getChartsDimensions(this.model.getHTMLElementId())\r\n this.model.updateAttributes(modelAttrs)\r\n }\r\n\r\n throttledResize = throttle(this.handleResize, 200)\r\n\r\n setToolbarPosition() {\r\n // quote page toolbar\r\n // 210px represents: (20px (toolbar left margin) + 80px (toolbar width) + 5px (toolbar rigth margin)) * 2 (both sides of chart)\r\n const newIsToolbarHorizontal = this.model.width + 210 > window.innerWidth || window.innerWidth < 1000\r\n if (newIsToolbarHorizontal !== this.state.isToolbarHorizontal) {\r\n this.setState({\r\n isToolbarHorizontal: newIsToolbarHorizontal,\r\n })\r\n }\r\n }\r\n\r\n checkTouchEventsDisabled = () => {\r\n if (!/\\bcharts\\b/.test(window.location.pathname) || getFullscreenStatus() || this.getVisualViewportScale() === 1) {\r\n this.state?.touchEventsDisabled && this.setState({ touchEventsDisabled: false })\r\n } else {\r\n !this.state?.touchEventsDisabled && this.setState({ touchEventsDisabled: true })\r\n }\r\n }\r\n\r\n getVisualViewportScale = () => {\r\n if (process.env.IS_E2E_TESTING) {\r\n return 1\r\n }\r\n if (window.visualViewport && this.isMobile) {\r\n return window.visualViewport.scale\r\n } else {\r\n return 1\r\n }\r\n }\r\n\r\n handleActiveToolChange = (activeTool: DrawingTool) => {\r\n if (!this.model.isLockDrawingsActive) {\r\n this.setState({ activeTool })\r\n }\r\n }\r\n\r\n handleDrawingAction = (actionId: DrawingActions) => {\r\n switch (actionId) {\r\n case DrawingActions.AddNote:\r\n this.props.noteDialogState.toggle()\r\n break\r\n case DrawingActions.DeleteDrawings:\r\n case DrawingActions.DeleteAutoSavedDrawings:\r\n this.props.confirmationDialogState.show()\r\n break\r\n default:\r\n return\r\n }\r\n }\r\n\r\n handleConfirmationDialogCloseBtn = () => {\r\n this.props.confirmationDialogState.hide()\r\n }\r\n\r\n handleConfirmationDialogDeleteBtn = () => {\r\n if (this.model.drawingsInternalStore().autoSaveState !== AutoSaveState.Off) {\r\n this.props.deleteAllAutoSavedElements()\r\n }\r\n this.model.getAllElements().forEach((element) => {\r\n if (element.isDrawing()) {\r\n element.destroyCascade({ eventType: DrawingSpineOptionsEvent.Remove })\r\n const drawingToRemove = this.model\r\n .drawingsInternalStore()\r\n .elements.find(({ elementId }) => elementId === element.id)\r\n if (drawingToRemove) {\r\n drawingToRemove.changeType = 'destroy'\r\n }\r\n }\r\n })\r\n this.handleConfirmationDialogCloseBtn()\r\n }\r\n\r\n handleDrawingsSetting = (settingId: DrawingSetting) => {\r\n const newObj = { ...this.state.drawingSettings, [settingId]: !this.state.drawingSettings[settingId] }\r\n\r\n switch (settingId) {\r\n case DrawingSetting.HideDrawings:\r\n this.handleActiveToolChange(DrawingTool.Mouse)\r\n this.toggleHideDrawings(newObj[DrawingSetting.HideDrawings])\r\n this.handleLockDrawings(newObj)\r\n break\r\n case DrawingSetting.PreserveDrawings:\r\n this.handlePreserveDrawingsSettings(newObj[DrawingSetting.PreserveDrawings])\r\n this.model.updateAttribute('isPreserveDrawingsActive', newObj[DrawingSetting.PreserveDrawings])\r\n break\r\n case DrawingSetting.LockDrawings:\r\n this.handleActiveToolChange(DrawingTool.Mouse)\r\n this.handleLockDrawings(newObj)\r\n break\r\n case DrawingSetting.DrawingModeContinuous:\r\n this.model.updateAttribute('isDrawingModeContinuousActive', newObj[DrawingSetting.DrawingModeContinuous])\r\n newObj[DrawingSetting.DrawingModeContinuous] === false && this.handleActiveToolChange(DrawingTool.Mouse)\r\n break\r\n default:\r\n break\r\n }\r\n\r\n this.setState({ drawingSettings: newObj })\r\n window.gtag?.('event', 'drawings_settings_toggle', {\r\n event_category: newObj[settingId] ? 'enable' : 'disable',\r\n event_label: settingId,\r\n })\r\n }\r\n\r\n handleLockDrawings = (drawingSettings: Record) => {\r\n this.model.updateAttribute(\r\n 'isLockDrawingsActive',\r\n !(!drawingSettings[DrawingSetting.HideDrawings] && !drawingSettings[DrawingSetting.LockDrawings])\r\n )\r\n }\r\n\r\n toggleHideDrawings(value: boolean) {\r\n this.model.updateAttribute('isHideDrawingsActive', value)\r\n this.model.getAllCharts().forEach((chart) => chart.updateAttribute('isHideDrawingsActive', value))\r\n }\r\n\r\n renderToolbar(args: any) {\r\n const { activeTool, drawingSettings } = this.state\r\n return args.isOverlayToolbar ? (\r\n \r\n ) : (\r\n \r\n )\r\n }\r\n\r\n render() {\r\n const { newCharts, useGrid } = this.props.config\r\n const { activeTool, editable, editors, isToolbarHorizontal } = this.state\r\n const publish = editors.includes(ChartEditorEnum.publish) && getPublishChartHtmlElements().length > 0\r\n const chartLayout = LAYOUTS[this.model.layout]\r\n const isMobilePortrait = getIsMobilePortrait(this.isMobile)\r\n const { tickers } = getTickersAndContainerTypesInLayoutModel(this.model)\r\n\r\n if (newCharts) {\r\n const isSidebarEnabled = getIsSidebarEnabled(SpecificChartFunctionality.chartPage)\r\n return (\r\n <>\r\n

\r\n {!isMobilePortrait &&\r\n // Due safari iOS flex-column bug not resizing height properly we need to render toolbar\r\n // outside of flex for portrait and inside for landscape\r\n // https://github.com/finvizhq/charts/pull/784\r\n this.renderToolbar({\r\n isSidebar: true,\r\n isHorizontal: false,\r\n })}\r\n \r\n \r\n \r\n {this.charts.map(({ model, config }, index) => (\r\n }\r\n gridArea={chartLayout.gridAreas?.[index]}\r\n setActiveChartInteraction={this.setActiveChartInteraction}\r\n activeTool={activeTool}\r\n activeChartInteraction={this.state.activeChartInteraction}\r\n touchEventsDisabled={this.state.touchEventsDisabled}\r\n shouldResize={this.props.shouldResize}\r\n />\r\n ))}\r\n \r\n \r\n
\r\n {isMobilePortrait && isSidebarEnabled && (\r\n \r\n )}\r\n {isMobilePortrait &&\r\n this.renderToolbar({\r\n isSidebar: false,\r\n isHorizontal: true,\r\n isOverlayToolbar: isSidebarEnabled,\r\n })}\r\n {this.props.idea?.note && (\r\n
\r\n
\r\n {this.props.idea.note}\r\n
\r\n
\r\n )}\r\n \r\n )\r\n }\r\n\r\n const hasRedesign = isRedesignEnabled()\r\n const hasChartTools = editable && editors.includes(ChartEditorEnum.tools)\r\n const renderTools = isRedesignedPage(this.model) ? hasChartTools && !isToolbarHorizontal : hasChartTools\r\n\r\n const ideaTitleContainer = document.querySelector('#idea-title-container')\r\n const ideaTitle = this.props.idea?.date &&\r\n this.model.specificChartFunctionality === SpecificChartFunctionality.quotePage && (\r\n

{`Your idea from ${this.props.idea.date}`}

\r\n )\r\n\r\n return (\r\n <>\r\n {ideaTitleContainer ? ReactDOM.createPortal(ideaTitle, ideaTitleContainer) : ideaTitle}\r\n \r\n {renderTools && (\r\n \r\n {this.renderToolbar({\r\n isHorizontal: isToolbarHorizontal,\r\n isAlternativeTheme: true,\r\n })}\r\n \r\n )}\r\n \r\n \r\n {this.charts.map(({ model, config }, index) => (\r\n \r\n this.renderToolbar({\r\n isHorizontal: true,\r\n isAlternativeTheme: true,\r\n })\r\n : undefined\r\n }\r\n />\r\n ))}\r\n \r\n
\r\n
\r\n
\r\n {this.model.specificChartFunctionality === SpecificChartFunctionality.quotePage && (\r\n \r\n )}\r\n \r\n \r\n )\r\n }\r\n\r\n setActiveChartInteraction = (value: string | null) => {\r\n this.setState({ activeChartInteraction: value })\r\n }\r\n\r\n updateLayout() {\r\n const layout = LAYOUTS[this.model.layout]\r\n const charts = this.model.charts().all()\r\n if (charts.length === 0) {\r\n return\r\n }\r\n\r\n if (charts.length > layout.count) {\r\n this.removeCharts(layout.count)\r\n } else if (charts.length < layout.count) {\r\n this.addCharts(layout.count - charts.length)\r\n }\r\n\r\n this.model\r\n .charts()\r\n .all()\r\n .forEach((chart, index) => {\r\n const [rowStart, columnStart, rowEnd, columnEnd] =\r\n layout.gridAreas?.[index]\r\n .replace(/ /g, '')\r\n .split('/')\r\n .map((num) => Number.parseInt(num)) || []\r\n const numOfRowsCovered = [rowEnd, rowStart].every((value) => value !== undefined) ? rowEnd - rowStart : 1\r\n const numOfColumnsCovered = [columnStart, columnEnd].every((value) => value !== undefined)\r\n ? columnEnd - columnStart\r\n : 1\r\n const percentageOfRowsCovered = numOfRowsCovered / layout.rows\r\n const percentageOfColumnsCovered = numOfColumnsCovered / layout.columns\r\n const newWidth = ~~(this.model.width * percentageOfColumnsCovered)\r\n const isChartPage = this.model.specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const chartLayoutHeight = isChartPage\r\n ? this.model.height\r\n : this.model.charts().first().height || this.model.height\r\n let newHeight = ~~(chartLayoutHeight * percentageOfRowsCovered)\r\n\r\n if (this.model.editors.includes(ChartEditorEnum.settings) && isChartPage) {\r\n newHeight -= this.model.settings.ChartSettings.general.settingsHeight\r\n }\r\n if ((chart.width !== newWidth || chart.height !== newHeight) && newWidth > 0 && newHeight > 0) {\r\n chart.updateAttributes({ width: newWidth, height: newHeight })\r\n }\r\n })\r\n }\r\n\r\n addCharts(count: number) {\r\n const quote = this.model.charts().last().quote()\r\n if (!quote) return\r\n const config = {\r\n ...this.model.charts().last().toObject(),\r\n leftOffset: null,\r\n chart_layout: this.model,\r\n aftermarket: quote.aftermarket,\r\n premarket: quote.premarket,\r\n }\r\n for (let i = 0; i < count; i++) {\r\n const model = this.model.charts().create(config)\r\n this.charts.push({ model, config })\r\n }\r\n }\r\n\r\n removeCharts(wantedCount: number) {\r\n while (this.model.charts().count() > wantedCount) {\r\n const chart = this.model.charts().last()\r\n chart.destroyCascade()\r\n this.charts.pop()\r\n }\r\n }\r\n\r\n onChartDestroy = (chartModel: ChartModel) => {\r\n this.updateLayout()\r\n if (this.model.activeChart?.eql(chartModel)) {\r\n this.model.updateAttribute('activeChart', this.model.charts().last())\r\n }\r\n }\r\n\r\n onModelChange = (layoutModel?: ChartLayout, event?: Spine.Event) => {\r\n if (event === 'refresh') {\r\n return\r\n }\r\n this.updateLayout()\r\n\r\n if (layoutModel && event === 'update') {\r\n this.setState({\r\n editable: layoutModel.editable,\r\n editors: layoutModel.editors,\r\n layout: layoutModel.layout,\r\n })\r\n }\r\n }\r\n}\r\n\r\nexport const ChartLayoutComponent = flowRight(\r\n withQuoteCacheManagement,\r\n withDialogState,\r\n withCompleteLayoutModelInit,\r\n withChartPageTitle,\r\n withChartRouteChange,\r\n withIdeaModelState,\r\n withQuotePolling,\r\n withDrawingsAutoSave\r\n)(ChartLayoutComponentBase)\r\n","import { useDialogState } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nexport const withDialogState = (Component: any) => (props: any) => {\r\n const confirmationDialogState = useDialogState()\r\n const noteDialogState = useDialogState({ modal: false })\r\n\r\n return \r\n}\r\n","import * as React from 'react'\r\n\r\nimport { SpecificChartFunctionality, TIMEFRAME } from '../../constants/common'\r\nimport math from '../../helpers/math'\r\nimport ChartLayoutModel from '../../models/chart_layout'\r\nimport Quote from '../../models/quote'\r\n\r\nfunction useChartPageTitle() {\r\n const defaultDocumentTitleRef = React.useRef(document.title)\r\n\r\n const { current: updateChartsTitle } = React.useRef((chartLayoutModel: ChartLayoutModel) => {\r\n const charts = chartLayoutModel\r\n .getAllCharts()\r\n .reduce(\r\n (acc, current) => {\r\n if (acc.some(({ ticker }) => ticker === current.ticker)) {\r\n return acc\r\n }\r\n return [...acc, { ticker: current.ticker, timeframe: current.timeframe, instrument: current.instrument }]\r\n },\r\n [] as Array<{ ticker: string; timeframe: TIMEFRAME; instrument: string }>\r\n )\r\n .map((chart) => {\r\n const { ticker, timeframe, instrument } = chart\r\n const quotes = Quote.select(\r\n (quote: Quote) =>\r\n quote.ticker === ticker.replace('@', '') &&\r\n quote.timeframe === timeframe &&\r\n quote.instrument === instrument &&\r\n chartLayoutModel.isIdeaId(quote.ideaID)\r\n )\r\n if (quotes.length > 0) {\r\n const { lastClose, instrument, afterClose, prevClose, name } = quotes[0]\r\n let percentageChange: number\r\n if (!lastClose) {\r\n return null\r\n }\r\n if (prevClose !== null) {\r\n percentageChange = (lastClose / prevClose - 1) * 100\r\n }\r\n if (afterClose !== null && afterClose !== lastClose) {\r\n percentageChange = (afterClose / lastClose - 1) * 100\r\n }\r\n return `${name || ticker} ${math.round({\r\n value: lastClose,\r\n lastClose,\r\n instrument,\r\n overridePlaces: undefined,\r\n })} ${percentageChange! > 0 ? '+' : '-'}${math.round({\r\n value: Math.abs(percentageChange!),\r\n overridePlaces: 2,\r\n })}%`\r\n }\r\n return null\r\n })\r\n .filter((chart) => chart !== null)\r\n\r\n if (charts && charts.length > 0) {\r\n const title = charts.join(' | ')\r\n if (document.title !== title) {\r\n document.title = title\r\n }\r\n } else if (document.title !== defaultDocumentTitleRef.current) {\r\n document.title = defaultDocumentTitleRef.current\r\n }\r\n })\r\n\r\n return { updateChartsTitle }\r\n}\r\n\r\nexport function withChartPageTitle

(\r\n Component: React.ComponentType

\r\n) {\r\n return function WrappedComponent(props: P) {\r\n const { updateChartsTitle } = useChartPageTitle()\r\n\r\n const handleChartsUpdate = React.useCallback(() => {\r\n updateChartsTitle(props.chartLayoutModel)\r\n }, [props.chartLayoutModel, updateChartsTitle])\r\n\r\n React.useEffect(() => {\r\n if (props.chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage) {\r\n props.chartLayoutModel.charts().bind('change', handleChartsUpdate)\r\n\r\n handleChartsUpdate()\r\n\r\n return () => {\r\n props.chartLayoutModel.charts().unbind('change', handleChartsUpdate)\r\n }\r\n }\r\n }, [props.chartLayoutModel, handleChartsUpdate])\r\n\r\n return \r\n }\r\n}\r\n","import React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartLayoutModel from '../../models/chart_layout'\r\n\r\nexport function withIdeaModelState

(\r\n Component: React.ComponentType

\r\n) {\r\n return function WrappedComponent(props: P) {\r\n const chartLayoutModel = useModelState(props.chartLayoutModel, { watchProperties: ['idea'] })\r\n return \r\n }\r\n}\r\n","import { NotificationWrapper, withSuspense } from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { RootChartConfigObject } from '../../../types/shared'\r\nimport { ElementStyleDialogWrapper } from '../../modals/element_style'\r\nimport { useChartLayoutGlobalModelAsync } from '../../utils/useChartLayoutGlobalModelAsync'\r\nimport { ChartLayoutComponent } from './chart_layout_component'\r\n\r\ninterface ChartLayoutProps {\r\n config: RootChartConfigObject\r\n shouldResize?: boolean\r\n parentElement?: HTMLElement\r\n isWithNotifications?: boolean\r\n}\r\n\r\nexport function ChartLayout({ config, shouldResize, isWithNotifications = true }: ChartLayoutProps) {\r\n const Wrapper = isWithNotifications ? NotificationWrapper : React.Fragment\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n )\r\n}\r\n\r\nexport function ChartLayoutWithGlobalStateRaw({\r\n config,\r\n shouldResize,\r\n parentElement,\r\n}: Omit) {\r\n const { setChartLayoutModel, getChartLayoutModelConfig, lastGlobalRerender } = useChartLayoutGlobalModelAsync()\r\n\r\n return (\r\n \r\n {config && (\r\n \r\n )}\r\n \r\n )\r\n}\r\n\r\nexport const ChartLayoutWithGlobalState = withSuspense(ChartLayoutWithGlobalStateRaw)\r\n","import { Button } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport Utils, { getExitFullscreen, getFullscreenStatus, getRequestFullscreen } from '../../utils'\r\n\r\nconst isIPad = Utils.isIPad()\r\nconst IPAD_FULLSCREEN_CLASS = 'is-ipad-fullscreen'\r\n\r\nexport function FullscreenButton() {\r\n const [isFullscreen, setIsFullscreen] = React.useState(getFullscreenStatus())\r\n const requestFullscreen = getRequestFullscreen(document.documentElement)\r\n const exitFullscreen = getExitFullscreen()\r\n\r\n const onClick = React.useRef(() => {\r\n if (getFullscreenStatus()) {\r\n exitFullscreen.call(document)\r\n } else {\r\n requestFullscreen.call(document.documentElement)\r\n }\r\n })\r\n\r\n React.useEffect(() => {\r\n const checkFullscreen = () => {\r\n if (isIPad) {\r\n if (getFullscreenStatus()) {\r\n document.body.classList.add(IPAD_FULLSCREEN_CLASS)\r\n } else {\r\n document.body.classList.remove(IPAD_FULLSCREEN_CLASS)\r\n }\r\n }\r\n setIsFullscreen(getFullscreenStatus())\r\n }\r\n\r\n document.addEventListener('webkitfullscreenchange', checkFullscreen)\r\n document.addEventListener('fullscreenchange', checkFullscreen)\r\n return () => {\r\n document.removeEventListener('webkitfullscreenchange', checkFullscreen)\r\n document.removeEventListener('fullscreenchange', checkFullscreen)\r\n }\r\n }, [])\r\n\r\n if (!requestFullscreen) return null\r\n\r\n return (\r\n \r\n {isFullscreen ? 'Exit Full screen' : 'Full screen'}\r\n \r\n )\r\n}\r\n","import {\r\n Button,\r\n Dropdown,\r\n DropdownItem,\r\n DropdownSeparator,\r\n Icon,\r\n IconNameType,\r\n Paragraph,\r\n useDropdownState,\r\n} from '@finviz/website'\r\nimport * as React from 'react'\r\nimport { useLocation, useNavigate } from 'react-router-dom'\r\n\r\nimport { LAYOUTS } from '../../constants/common'\r\nimport { sortObjects } from '../../helpers/sorter'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport { ChartSyncableParts } from '../../models/chart/contstants'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { decodeQueryString } from '../../utils/query_string'\r\nimport { useChartsPathLocation } from '../chart-controls/use-charts-path-location'\r\n\r\nconst SORTED_LAYOUT_KEYS = sortObjects(\r\n Object.entries(LAYOUTS).map(([key, value]) => ({ ...value, key })),\r\n [{ sortBy: 'columns' }, { sortBy: 'count' }]\r\n).map(({ key }) => key)\r\n\r\nexport function ChartLayoutDropdown({ model }: { model: ChartLayout }) {\r\n const location = useLocation()\r\n const navigate = useNavigate()\r\n const parsedQuery = decodeQueryString(location.search)\r\n const chartLayoutModel = useModelState(model, { watchProperties: ['layout', 'syncChartParts'] })\r\n const { getChartsToPath } = useChartsPathLocation({ chartLayoutModel })\r\n const state = useDropdownState({ placement: 'bottom', orientation: 'horizontal' })\r\n\r\n return (\r\n \r\n Layout\r\n \r\n }\r\n >\r\n

\r\n
\r\n {SORTED_LAYOUT_KEYS.map((layout) => (\r\n {\r\n navigate(getChartsToPath({ layout }))\r\n }}\r\n >\r\n \r\n \r\n ))}\r\n
\r\n \r\n
\r\n
\r\n Sync:\r\n
\r\n {ChartSyncableParts.map(({ value, label }) => {\r\n const isChartPartInSync = chartLayoutModel.getIsChartPartInSync(value)\r\n return (\r\n {\r\n chartLayoutModel.setSyncChartParts(value, !isChartPartInSync)\r\n if (!isChartPartInSync) window.gtag?.('event', 'sync', { event_label: value })\r\n }}\r\n >\r\n {label}\r\n \r\n )\r\n })}\r\n
\r\n
\r\n \r\n )\r\n}\r\n","import { ObjectHash } from '../../types/shared'\r\nimport { SORT_DIRECTION } from '../constants/common'\r\n\r\nexport function sortObjects(\r\n arr: ObjectHash[],\r\n options: Array<{ sortBy: string; sortDirection?: keyof typeof SORT_DIRECTION }> = []\r\n) {\r\n return arr.sort((a, b) =>\r\n options.reduce((acc, option) => {\r\n const { sortBy, sortDirection = SORT_DIRECTION.ASC } = option\r\n const directionMultiplier = sortDirection === SORT_DIRECTION.ASC ? 1 : -1\r\n return acc === 0 ? (a[sortBy] - b[sortBy]) * directionMultiplier : acc\r\n }, 0)\r\n )\r\n}\r\n","import { Button, setCookieRequest } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { updateSettings } from '../../models/settings'\r\n\r\nexport function ThemeToggleButton({ model }: { model: ChartLayout }) {\r\n const chartLayoutModel = useModelState(model, { watchProperties: ['theme'] })\r\n const isDarkMode = model.theme === 'dark'\r\n\r\n const onClick = () => {\r\n const theme = isDarkMode ? 'light' : 'dark'\r\n chartLayoutModel.updateAttributes({ theme, settings: updateSettings(chartLayoutModel, theme) })\r\n chartLayoutModel.trigger('theme', chartLayoutModel)\r\n setCookieRequest('chartsTheme', theme).catch(() => {})\r\n\r\n if (isDarkMode) {\r\n document.documentElement.classList.remove('dark')\r\n } else {\r\n document.documentElement.classList.add('dark')\r\n }\r\n }\r\n\r\n if (!chartLayoutModel) {\r\n return null\r\n }\r\n\r\n return (\r\n \r\n )\r\n}\r\n","import { Button, Time, TimeBreakpoint } from '@finviz/website'\r\nimport * as React from 'react'\r\n\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { FullscreenButton } from './fullscreen_button'\r\nimport { IdeasDropdown } from './ideas_dropdown'\r\nimport { ChartLayoutDropdown } from './layout_dropdown'\r\nimport { Publish } from './publish'\r\nimport { ThemeToggleButton } from './theme_toggle_button'\r\nimport { TourButton } from './tour_button'\r\n\r\nconst BREAKPOINTS: TimeBreakpoint[] = [\r\n { minWidth: -Infinity, marketBadgeText: false, timeFormat: 'timeOnly' },\r\n { minWidth: 550, marketBadgeText: false, timeFormat: 'short' },\r\n { minWidth: 700, marketBadgeText: false, timeFormat: 'long' },\r\n { minWidth: 768, marketBadgeText: true, timeFormat: 'long' },\r\n]\r\n\r\ninterface ChartLayoutHeaderProps {\r\n model: ChartLayout\r\n onSettingsOpen: () => void\r\n hasPublish: boolean\r\n}\r\n\r\nexport function ChartLayoutHeaderComponent({ model, onSettingsOpen = () => {}, hasPublish }: ChartLayoutHeaderProps) {\r\n const chartLayout = useModelState(model, { watchProperties: ['idea'] })!\r\n\r\n return (\r\n <>\r\n
\r\n \r\n Ideas\r\n \r\n
\r\n
\r\n \r\n Chart tour\r\n \r\n \r\n \r\n {hasPublish && (\r\n \r\n Share\r\n \r\n )}\r\n \r\n \r\n \r\n
\r\n \r\n )\r\n}\r\n\r\nexport const ChartLayoutHeader = React.memo(\r\n ChartLayoutHeaderComponent,\r\n (prevProps, nextProps) =>\r\n prevProps.model === nextProps.model &&\r\n prevProps.onSettingsOpen === nextProps.onSettingsOpen &&\r\n prevProps.hasPublish === nextProps.hasPublish\r\n)\r\n","import {\r\n ButtonSizeType,\r\n CustomDateRange,\r\n TimeframeBar,\r\n useCustomDateRangeDialog,\r\n useFavoriteTimeframes,\r\n withSuspense,\r\n} from '@finviz/website'\r\nimport React from 'react'\r\n\r\nimport { Instrument } from '../../../types/shared'\r\nimport { TIMEFRAME } from '../../constants/common'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport { isRedesignEnabled } from '../../utils'\r\nimport { useChartLayoutGlobalModelAsync } from '../../utils/useChartLayoutGlobalModelAsync'\r\nimport { useChartControls } from './use-chart-controls'\r\nimport { IDateRange, useChartModelCustomDateRangeValues } from './use-chart-model-custom-date-range-values'\r\n\r\nfunction StockDetailTimeframeBarRaw({\r\n size = 'regular',\r\n className = '!m-0 space-x-2',\r\n isDateRangeAvailable,\r\n isPremium,\r\n isLoadingOverride,\r\n isScrollIntoViewEnabled = false,\r\n onTimeframeSelect = () => {},\r\n onDateRangeSelect = () => {},\r\n}: {\r\n size?: ButtonSizeType\r\n className?: string\r\n isDateRangeAvailable: boolean\r\n isPremium: boolean\r\n isLoadingOverride?: boolean\r\n isScrollIntoViewEnabled?: boolean\r\n onTimeframeSelect?: (timeframe: any) => void\r\n onDateRangeSelect?: (timeframe: any) => void\r\n}) {\r\n const { chartLayoutModel } = useChartLayoutGlobalModelAsync()\r\n const chartModelUnwatched = React.useMemo(() => chartLayoutModel?.getAllCharts()[0] ?? null, [chartLayoutModel])\r\n const { favoriteTimeframes, toggleFavoriteTimeframe } = useFavoriteTimeframes(isPremium)\r\n const chartModel = useModelState(chartModelUnwatched, {\r\n watchProperties: ['timeframe', 'dateRange'],\r\n })\r\n const { instrument = Instrument.Stock } = chartModel?.quote() || {}\r\n const { isLoading } = useChartControls({\r\n chartModel,\r\n isInteractive: isDateRangeAvailable,\r\n })\r\n\r\n const {\r\n anchorDate,\r\n generateChartLayoutRouterPath,\r\n timeframeGroupsWithHref,\r\n dateRangeGroupsWithHref,\r\n isFetching,\r\n handleCustomDateRangeValidation,\r\n } = useChartModelCustomDateRangeValues({ chartModel, isPremium })\r\n const { onDialogSubmit, customDateRangeDialogState, handleDateRangeSelect, getDateRangeTimeframe } =\r\n useCustomDateRangeDialog({\r\n instrument,\r\n anchorDate,\r\n pathGenerator: generateChartLayoutRouterPath,\r\n })\r\n\r\n const dateRangeGroups = dateRangeGroupsWithHref({ isPremium, customRange: chartModel?.dateRange, instrument })\r\n const timeFrameGroups = timeframeGroupsWithHref(isPremium)\r\n\r\n async function handleCustomRangeSubmit(values: { dateRange: string | null }) {\r\n const dateRangeTimeframe = getDateRangeTimeframe(values.dateRange) as IDateRange | null\r\n if (!dateRangeTimeframe) return\r\n\r\n const isValid = await handleCustomDateRangeValidation(dateRangeTimeframe)\r\n if (isValid) onDialogSubmit(dateRangeTimeframe)\r\n }\r\n\r\n return (\r\n <>\r\n {\r\n handleDateRangeSelect(value)\r\n onDateRangeSelect?.(value)\r\n }}\r\n onTimeframeSelect={onTimeframeSelect}\r\n onFavoriteTimeframeToggle={({ value }: { value: string }) => {\r\n toggleFavoriteTimeframe(value as TIMEFRAME)\r\n }}\r\n isDateRangeAvailable={isDateRangeAvailable}\r\n containerElement={document.body}\r\n className={className}\r\n isFavoritesEnabled={isPremium}\r\n isScrollIntoViewEnabled={isScrollIntoViewEnabled}\r\n />\r\n\r\n {chartModel && (\r\n \r\n )}\r\n \r\n )\r\n}\r\n\r\nexport const StockDetailTimeframeBar = withSuspense(StockDetailTimeframeBarRaw)\r\n","import { ChartConfigChartPane, Position, RootChartConfigObject } from '../../types/shared'\r\nimport { ChartElementType, IndicatorType, OverlayType, PANE_HEIGHT_DEFAULT, ScaleType } from '../constants/common'\r\n\r\nfunction hasPaneWithCOTCode(panes: ChartConfigChartPane[], code: string) {\r\n return panes.some(({ elements }) =>\r\n elements.some((element) => element.type === IndicatorType.Cot && element.code === code)\r\n )\r\n}\r\nfunction pushIndicators(\r\n panes: ChartConfigChartPane[],\r\n indicator: { name: string; parameters: string },\r\n options?: { COTs?: string[] }\r\n) {\r\n if (indicator.name === 'cot') {\r\n const cotKeys = options?.COTs ?? []\r\n if (cotKeys.length === 0) {\r\n cotKeys.push('')\r\n }\r\n cotKeys.forEach(function (code: string) {\r\n if (!hasPaneWithCOTCode(panes, code)) {\r\n panes.push({\r\n height: PANE_HEIGHT_DEFAULT.indicator,\r\n elements: [\r\n {\r\n type: IndicatorType.Cot,\r\n code,\r\n },\r\n ],\r\n })\r\n }\r\n })\r\n } else {\r\n panes.push({\r\n height: PANE_HEIGHT_DEFAULT.indicator,\r\n elements: [\r\n {\r\n type: ('indicators/' + indicator.name) as IndicatorType,\r\n period: indicator.parameters,\r\n },\r\n ],\r\n })\r\n }\r\n}\r\n\r\nfunction getChartTypeByTaConfigStyle(style: string) {\r\n const chartTypeMap = {\r\n candlestick: ChartElementType.CandleStick,\r\n heikinashi: ChartElementType.HeikinAshi,\r\n hollowcandlestick: ChartElementType.HollowCandleStick,\r\n line: ChartElementType.LineChart,\r\n ohlc: ChartElementType.OhlcChart,\r\n }\r\n return chartTypeMap[style as keyof typeof chartTypeMap]\r\n}\r\n\r\nfunction getChartScaleByTaConfigScale(scale: string | undefined) {\r\n const chartScaleMap = {\r\n linear: ScaleType.Linear,\r\n percentage: ScaleType.Percentage,\r\n logarithmic: ScaleType.Logarithmic,\r\n }\r\n return chartScaleMap[scale as keyof typeof chartScaleMap] ?? ScaleType.Linear\r\n}\r\n\r\n/*\r\n * Merges chartConfig (in \"chart\" format) with taConfig (in format that TA is preserved in DB)\r\n */\r\nexport const mergeChartAndTAConfig = function convertTA(\r\n chartConfig: RootChartConfigObject,\r\n taConfig: TaConfigObject,\r\n options?: { COTs: string[] }\r\n) {\r\n const panes = chartConfig.charts[0].panes\r\n const chart = chartConfig.charts[0]\r\n\r\n chart.scale = getChartScaleByTaConfigScale(taConfig.scale)\r\n\r\n taConfig.indicators\r\n .filter((indicator) => indicator.position === Position.Above)\r\n .forEach((indicator) => {\r\n pushIndicators(panes, indicator, options)\r\n })\r\n\r\n const overlays = taConfig.overlays.map(function (overlay) {\r\n return {\r\n type: ('overlays/' + overlay.name) as OverlayType,\r\n period: overlay.parameters ?? '',\r\n color: overlay.color ?? '',\r\n }\r\n })\r\n panes.push({\r\n height: PANE_HEIGHT_DEFAULT.chart,\r\n elements: [\r\n {\r\n type: getChartTypeByTaConfigStyle(taConfig.style),\r\n overlays: overlays,\r\n },\r\n ],\r\n })\r\n\r\n taConfig.indicators\r\n .filter((indicator) => indicator.position === Position.Below)\r\n .forEach((indicator) => {\r\n pushIndicators(panes, indicator, options)\r\n })\r\n\r\n chartConfig.height = chart.height = PANE_HEIGHT_DEFAULT.chart + (panes.length - 1) * PANE_HEIGHT_DEFAULT.indicator\r\n}\r\n\r\nexport const getPanes = function getPanes(taConfig: TaConfigObject) {\r\n const options = {}\r\n const panes: ChartConfigChartPane[] = []\r\n\r\n taConfig.indicators\r\n .filter((indicator) => indicator.position === Position.Above)\r\n .forEach((indicator) => {\r\n pushIndicators(panes, indicator, options)\r\n })\r\n\r\n const overlays = taConfig.overlays.map(function (overlay) {\r\n return {\r\n type: ('overlays/' + overlay.name) as OverlayType,\r\n period: overlay.parameters ?? '',\r\n color: overlay.color ?? '',\r\n }\r\n })\r\n panes.push({\r\n height: PANE_HEIGHT_DEFAULT.chart,\r\n elements: [\r\n {\r\n type: getChartTypeByTaConfigStyle(taConfig.style),\r\n overlays: overlays,\r\n },\r\n ],\r\n })\r\n\r\n taConfig.indicators\r\n .filter((indicator) => indicator.position === Position.Below)\r\n .forEach((indicator) => {\r\n pushIndicators(panes, indicator, options)\r\n })\r\n\r\n return panes\r\n}\r\n","export * from 'finviz-charts/app/lib-export'\r\n\r\nexport enum SettingsTab {\r\n Chart = 'chart',\r\n Colors = 'colors',\r\n}\r\n\r\nexport enum SidebarDirection {\r\n vertical,\r\n horizontal,\r\n}\r\n","export const createAlertAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"create-alert\" */ './module-entry'),\r\n cacheKey: 'create-alert',\r\n}\r\n","export const saveToPortfolioAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"save-to-portfolio\" */ './module-entry'),\r\n cacheKey: 'save-to-portfolio',\r\n}\r\n","import { waitForPreviousPromise } from '../../main/services/wait-for-previous-promise'\r\n\r\nfunction getCurrentDateInMs() {\r\n return new Date().valueOf()\r\n}\r\n\r\nfunction getIsDocumentVisible() {\r\n return document.visibilityState === 'visible' || document.hidden === false\r\n}\r\n\r\n/**\r\n * Invoke a callback when page visibility changes. Turns the callback into a promise\r\n * and waits for the previous promise to finish before invoking it again\r\n */\r\nexport function notifyOnVisibilityChange(callback: (visible: boolean) => void | Promise) {\r\n const promisifiedCallback = waitForPreviousPromise(() => callback(getIsDocumentVisible()))\r\n\r\n document.addEventListener('visibilitychange', promisifiedCallback)\r\n\r\n return {\r\n callback: promisifiedCallback,\r\n unsubscribe: () => {\r\n document.removeEventListener('visibilitychange', promisifiedCallback)\r\n },\r\n }\r\n}\r\n\r\n/**\r\n * Calls callback based on interval and document visibility. Returns unsubscribe function.\r\n * How it works:\r\n * - document is hidden: interval cleared\r\n * - document visible: interval set-up with remaining time from last interval. Call immediately if interval elapsed\r\n */\r\nexport function intervalCallbackOnWindowVisible(\r\n interval: number | (() => number),\r\n callback: () => void | Promise\r\n) {\r\n const getInterval = typeof interval === 'function' ? interval : () => interval\r\n let refreshPromise: Promise | void | null = null\r\n let nextRefresh = getCurrentDateInMs() + getInterval()\r\n let refreshTimeout: NodeJS.Timeout | null = null\r\n\r\n async function refresh() {\r\n nextRefresh = getCurrentDateInMs() + getInterval()\r\n // Call callback asynchronously\r\n refreshPromise = callback()\r\n await refreshPromise\r\n refreshPromise = null\r\n\r\n // Queue next refresh\r\n if (getIsDocumentVisible()) {\r\n refreshTimeout = setTimeout(refresh, Math.max(0, nextRefresh - getCurrentDateInMs()))\r\n }\r\n }\r\n\r\n /**\r\n * Handle the visibility change event, compute callback remaining time or call immediately\r\n */\r\n function handleVisibilityChange() {\r\n if (refreshTimeout) clearTimeout(refreshTimeout)\r\n\r\n if (getIsDocumentVisible() && refreshPromise === null) {\r\n const currentDateMs = getCurrentDateInMs()\r\n // Refresh if the document is stale, otherwise set a timeout to refresh later\r\n if (nextRefresh <= currentDateMs) {\r\n refresh()\r\n } else {\r\n refreshTimeout = setTimeout(refresh, nextRefresh - currentDateMs)\r\n }\r\n }\r\n }\r\n\r\n if (getIsDocumentVisible()) {\r\n refreshTimeout = setTimeout(refresh, getInterval())\r\n }\r\n\r\n document.addEventListener('visibilitychange', handleVisibilityChange)\r\n\r\n return () => {\r\n if (refreshTimeout) clearTimeout(refreshTimeout)\r\n document.removeEventListener('visibilitychange', handleVisibilityChange)\r\n }\r\n}\r\n","export enum AdsProvider {\r\n None,\r\n InvestingChannel,\r\n Freestar,\r\n}\r\n\r\nexport function getAdsProvider() {\r\n if (FinvizSettings.hasUserPremium) return AdsProvider.None\r\n\r\n if (FinvizSettings.adsProvider === 2) {\r\n return AdsProvider.Freestar\r\n }\r\n\r\n return AdsProvider.InvestingChannel\r\n}\r\n\r\n/**\r\n * Tracks virtual page views to google analytics and freestar\r\n */\r\nexport function trackPageView(props: { pathname?: string; query?: string; freestarPageView?: boolean }) {\r\n const { pathname = window.location.pathname, query = window.location.search, freestarPageView = true } = props\r\n\r\n window.gtag?.('set', 'page_path', `${pathname}${query.length ? '?' : ''}${query.replace(/^\\?/, '')}`)\r\n window.gtag?.('event', 'page_view')\r\n\r\n if (freestarPageView && getAdsProvider() === AdsProvider.Freestar) {\r\n window.freestar?.queue.push(() => freestar.trackPageview())\r\n }\r\n}\r\n","export const portfolioWatchlistTableAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"portfolio-watchlist-table\" */ './PortfolioWatchlistTable'),\r\n cacheKey: 'portfolio-watchlist-table',\r\n}\r\n","import logo from './app/shared/assets/logo.png'\r\nimport logo_light from './app/shared/assets/logo_light.png'\r\n\r\nexport * from './main/components'\r\n\r\nexport { getSanitizedTicker } from './app/shared/ticker-sanitizer'\r\nexport * from './app/queryString'\r\nexport * from './main/modules/portfolio/types'\r\n\r\nexport { getFormattedDateString } from './app/header/utils'\r\nexport { decodeQueryString, encodeQueryString } from './app/queryString'\r\nexport { createAlertAsyncModule } from './app/quote/create-alert/async-modules'\r\nexport { saveToPortfolioAsyncModule } from './app/quote/save-to-portfolio/async-modules'\r\nexport { formatDateToStringUS } from './app/shared/utils'\r\nexport { portfolioWatchlistTableAsyncModule } from './main/components/portfolio/async-modules'\r\nexport { useTrackPageView } from './main/hooks/use-track-pageview'\r\nexport { useAsyncModule, withSuspense } from './main/services/async-modules-utils'\r\nexport { importWithRetry } from './main/services/import-with-retry'\r\nexport * as localStorage from './main/services/local-storage'\r\nexport { waitForPreviousPromise } from './main/services/wait-for-previous-promise'\r\nexport { setCookieRequest } from './main/services/api'\r\n\r\nexport const assets = { logo, logo_light }\r\n","import classnames from 'classnames'\r\nimport { ForwardedRef, HTMLProps, PropsWithChildren, ReactNode, forwardRef } from 'react'\r\n\r\nimport { Icon } from './icon'\r\n\r\nexport enum ColorVariant {\r\n violet = 'violet',\r\n emerald = 'emerald',\r\n orange = 'orange',\r\n teal = 'teal',\r\n pink = 'pink',\r\n lime = 'lime',\r\n purple = 'purple',\r\n green = 'green',\r\n yellow = 'yellow',\r\n blue = 'blue',\r\n red = 'red',\r\n gray = 'gray',\r\n default = 'default',\r\n}\r\n\r\nexport enum CheckboxSize {\r\n none = '', // Do not set fixed size\r\n small = 'min-h-6 text-2xs', // 24px\r\n regular = 'min-h-7 text-sm', // 28px\r\n}\r\nexport type CheckboxSizeType = keyof typeof CheckboxSize\r\n\r\ninterface CheckboxProps extends Omit, 'label' | 'size'> {\r\n /**\r\n * Text that gets displayed on the right side of the checkbox\r\n */\r\n label?: ReactNode\r\n\r\n checked: boolean\r\n\r\n /**\r\n * Size of the checkbox\r\n *\r\n * @default \"regular\"\r\n */\r\n size?: CheckboxSizeType\r\n\r\n /**\r\n * Color of the checkbox\r\n *\r\n * @default \"default\"\r\n */\r\n color?: ColorVariant\r\n}\r\n\r\nfunction CheckboxComponent(\r\n {\r\n className,\r\n label,\r\n size = 'regular',\r\n color = ColorVariant.default,\r\n children,\r\n ...props\r\n }: PropsWithChildren,\r\n ref: ForwardedRef\r\n) {\r\n const checked = props.checked ?? props.defaultChecked\r\n\r\n return (\r\n \r\n
\r\n \r\n {checked && (\r\n \r\n )}\r\n
\r\n {label ?? children}\r\n \r\n )\r\n}\r\n\r\nexport const Checkbox = forwardRef(CheckboxComponent)\r\n","import classnames from 'classnames'\r\nimport { HTMLProps, PropsWithChildren, memo, useCallback, useLayoutEffect, useRef, useState } from 'react'\r\n\r\nexport interface Interaction {\r\n left: number\r\n top: number\r\n}\r\n\r\n/**\r\n * Clamp value between two bounds\r\n */\r\nfunction clamp(num: number, min = 0, max = 1) {\r\n return num > max ? max : num < min ? min : num\r\n}\r\n\r\n/**\r\n * Check if an event was triggered by touch\r\n */\r\nfunction isTouch(event: MouseEvent | TouchEvent): event is TouchEvent {\r\n return 'touches' in event\r\n}\r\n\r\n/**\r\n * Returns a relative position of the pointer inside the node's bounding box\r\n */\r\nfunction getRelativePosition(node: HTMLDivElement, event: MouseEvent | TouchEvent): Interaction {\r\n const rect = node.getBoundingClientRect()\r\n\r\n // Get user's pointer position from `touches` array if it's a `TouchEvent`\r\n const pointer = isTouch(event) ? event.touches[0] : (event as MouseEvent)\r\n\r\n return {\r\n left: clamp((pointer.pageX - (rect.left + window.pageXOffset)) / rect.width),\r\n top: clamp((pointer.pageY - (rect.top + window.pageYOffset)) / rect.height),\r\n }\r\n}\r\n\r\n/**\r\n * Browsers introduced an intervention, making touch events passive by default.\r\n * This workaround removes `preventDefault` call from the touch handlers.\r\n * @see https://github.com/facebook/react/issues/19651\r\n */\r\nfunction preventDefaultMove(event: MouseEvent | TouchEvent) {\r\n !isTouch(event) && event.preventDefault()\r\n}\r\n\r\ninterface Props {\r\n onMove: (interaction: Interaction) => void\r\n onKey: (offset: Interaction) => void\r\n}\r\n\r\nfunction DraggablePickerComponent({\r\n onMove,\r\n onKey,\r\n className,\r\n ...props\r\n}: PropsWithChildren & HTMLProps) {\r\n const container = useRef(null)\r\n const hasTouched = useRef(false)\r\n const [isDragging, setDragging] = useState(false)\r\n\r\n /**\r\n * Prevent mobile browsers from handling mouse events (conflicting with touch ones).\r\n * If we detected a touch interaction before, we prefer reacting to touch events only.\r\n */\r\n const isValid = useRef((event: MouseEvent | TouchEvent): boolean => {\r\n if (hasTouched.current && !isTouch(event)) return false\r\n if (!hasTouched.current) hasTouched.current = isTouch(event)\r\n return true\r\n })\r\n\r\n const handleMove = useCallback(\r\n (event: MouseEvent | TouchEvent) => {\r\n preventDefaultMove(event)\r\n\r\n // If user moves the pointer outside of the window or iframe bounds and release it there,\r\n // `mouseup`/`touchend` won't be fired. In order to stop the picker from following the cursor\r\n // after the user has moved the mouse/finger back to the document, we check `event.buttons`\r\n // and `event.touches`. It allows us to detect that the user is just moving his pointer\r\n // without pressing it down\r\n const isDown = isTouch(event) ? event.touches.length > 0 : event.buttons > 0\r\n\r\n if (isDown && container.current) {\r\n onMove(getRelativePosition(container.current, event))\r\n } else {\r\n setDragging(false)\r\n }\r\n },\r\n [onMove]\r\n )\r\n\r\n const handleMoveStart = useCallback(\r\n ({ nativeEvent }: React.MouseEvent | React.TouchEvent) => {\r\n preventDefaultMove(nativeEvent)\r\n\r\n if (!isValid.current(nativeEvent)) return\r\n\r\n // The node/ref must actually exist when user start an interaction.\r\n // We won't suppress the ESLint warning though, as it should probably be something to be aware of.\r\n onMove(getRelativePosition(container.current!, nativeEvent))\r\n setDragging(true)\r\n },\r\n [onMove]\r\n )\r\n\r\n const handleKeyDown = useCallback(\r\n (event: React.KeyboardEvent) => {\r\n const keyCode = event.which || event.keyCode\r\n\r\n // Ignore all keys except arrow ones\r\n if (keyCode < 37 || keyCode > 40) return\r\n // Do not scroll page by arrow keys when document is focused on the element\r\n event.preventDefault()\r\n // Send relative offset to the parent component.\r\n // We use codes (37←, 38↑, 39→, 40↓) instead of keys ('ArrowRight', 'ArrowDown', etc)\r\n // to reduce the size of the library\r\n onKey({\r\n left: keyCode === 39 ? 0.05 : keyCode === 37 ? -0.05 : 0,\r\n top: keyCode === 40 ? 0.05 : keyCode === 38 ? -0.05 : 0,\r\n })\r\n },\r\n [onKey]\r\n )\r\n\r\n const handleMoveEnd = useCallback(() => setDragging(false), [])\r\n\r\n const toggleDocumentEvents = useCallback(\r\n (state) => {\r\n // add or remove additional pointer event listeners\r\n const toggleEvent = state ? window.addEventListener : window.removeEventListener\r\n toggleEvent(hasTouched.current ? 'touchmove' : 'mousemove', handleMove)\r\n toggleEvent(hasTouched.current ? 'touchend' : 'mouseup', handleMoveEnd)\r\n },\r\n [handleMove, handleMoveEnd]\r\n )\r\n\r\n useLayoutEffect(() => {\r\n toggleDocumentEvents(isDragging)\r\n return () => {\r\n isDragging && toggleDocumentEvents(false)\r\n }\r\n }, [isDragging, toggleDocumentEvents])\r\n\r\n return (\r\n \r\n )\r\n}\r\n\r\nexport const DraggablePicker = memo(DraggablePickerComponent)\r\n","interface PointerProps {\r\n className?: string\r\n top?: number\r\n left: number\r\n color: string\r\n}\r\n\r\nexport function Pointer({ color, left, top = 0.5 }: PointerProps) {\r\n return (\r\n \r\n
\r\n
\r\n )\r\n}\r\n","/**\r\n * Keep this file in sync with `app/utils/colors.ts` in charts repo\r\n * */\r\n\r\nexport interface RGBA {\r\n r: number\r\n g: number\r\n b: number\r\n a: number\r\n}\r\n\r\nexport interface HSVA {\r\n h: number\r\n s: number\r\n v: number\r\n a: number\r\n}\r\n\r\nexport interface HSLA {\r\n h: number\r\n s: number\r\n l: number\r\n a: number\r\n}\r\n\r\n/**\r\n * Convert Hex string to RGBA object.\r\n * @see https://css-tricks.com/converting-color-spaces-in-javascript/\r\n *\r\n * Input: color in hex3, hex4, hex6 or hex8 format (#fff)\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hexStringToRGBA(hexString: string): RGBA {\r\n const hexColor = removeHashSymbol(hexString)\r\n let r: string | number = 0\r\n let g: string | number = 0\r\n let b: string | number = 0\r\n let a: string | number = 255\r\n\r\n // 3 digits\r\n if (hexColor.length === 3 || hexColor.length === 4) {\r\n r = '0x' + hexColor[0] + hexColor[0]\r\n g = '0x' + hexColor[1] + hexColor[1]\r\n b = '0x' + hexColor[2] + hexColor[2]\r\n // Get channel if defined\r\n a = hexColor.length === 4 ? '0x' + hexColor[3] + hexColor[3] : a\r\n\r\n // 6 digits\r\n } else if (hexColor.length === 6 || hexColor.length === 8) {\r\n r = '0x' + hexColor[0] + hexColor[1]\r\n g = '0x' + hexColor[2] + hexColor[3]\r\n b = '0x' + hexColor[4] + hexColor[5]\r\n // Get channel if defined\r\n a = hexColor.length === 8 ? '0x' + hexColor[6] + hexColor[7] : a\r\n }\r\n\r\n return { r: Number(r), g: Number(g), b: Number(b), a: Math.min(Math.round((Number(a) / 255) * 100) / 100, 1) }\r\n}\r\n\r\n/**\r\n * Convert HEX string to HSVA color representation.\r\n *\r\n * Input: color in hex3, hex4, hex6 or hex8 format (#fff)\r\n *\r\n * Output: { h: [0,360], s: [0,1], v: [0,1], a: [0,1]}\r\n */\r\nexport function hexStringToHSVA(hexString: string) {\r\n return rgbaToHSVA(hexStringToRGBA(hexString))\r\n}\r\n\r\n/**\r\n * Convert HEX string to HSLA color representation.\r\n *\r\n * Input: color in hex3, hex4, hex6 or hex8 format (#fff)\r\n *\r\n * Output: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n */\r\nexport function hexStringToHSLA(hexString: string) {\r\n return rgbaToHSLA(hexStringToRGBA(hexString))\r\n}\r\n\r\n/**\r\n * Convert alpha value to hex value\r\n *\r\n * Input: [0,1]\r\n *\r\n * Output: alpha in HEX format\r\n */\r\nexport function alphaToHex(alpha: number) {\r\n return Math.max(Math.min(Math.round(alpha * 255), 255), 0)\r\n .toString(16)\r\n .padStart(2, '0')\r\n}\r\n\r\n/**\r\n * Convert RGBA color to HEX string.\r\n *\r\n * Input: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n *\r\n * Output: color in hex6 or hex8 depending on whether or not alpha is enabled\r\n */\r\nexport function rgbaToHexString(color: RGBA, alpha = false) {\r\n const r = color.r.toString(16)\r\n const g = color.g.toString(16)\r\n const b = color.b.toString(16)\r\n const hexString = '#' + r.padStart(2, '0') + g.padStart(2, '0') + b.padStart(2, '0')\r\n\r\n if (!alpha || color.a === 1) {\r\n return hexString\r\n }\r\n\r\n return `${hexString}${alphaToHex(color.a)}`\r\n}\r\n\r\n/**\r\n * Convert HSVA object to HEX string\r\n *\r\n * @see https://css-tricks.com/converting-color-spaces-in-javascript/\r\n *\r\n * Input: { h: [0,360], s: [0,1], v: [0,1], a: [0,1]}\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hsvaToHEXString(color: HSVA, alpha = false) {\r\n const rgbaColor = hsvaToRGBA(color)\r\n\r\n return rgbaToHexString(rgbaColor, alpha)\r\n}\r\n\r\n/**\r\n * Convert HSLA object to HEX string\r\n *\r\n * @see https://css-tricks.com/converting-color-spaces-in-javascript/\r\n *\r\n * Input: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hslaToHexString(color: HSLA, alpha = false) {\r\n const rgbaColor = hslaToRGBA(color)\r\n\r\n return rgbaToHexString(rgbaColor, alpha)\r\n}\r\n\r\n/**\r\n * Convert RGBA color to HSVA\r\n * @see https://stackoverflow.com/a/54070620/6662683\r\n *\r\n * Input: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n *\r\n * Output: { h: [0,360], s: [0,1], v: [0,1], a: [0,1]}\r\n */\r\nexport function rgbaToHSVA(color: RGBA): HSVA {\r\n const r = color.r / 255\r\n const g = color.g / 255\r\n const b = color.b / 255\r\n\r\n const v = Math.max(r, g, b)\r\n const c = v - Math.min(r, g, b)\r\n const h = c && (v === r ? (g - b) / c : v === g ? 2 + (b - r) / c : 4 + (r - g) / c)\r\n\r\n return {\r\n h: 60 * (h < 0 ? h + 6 : h),\r\n s: v ? c / v : 0,\r\n v: v,\r\n a: color.a,\r\n }\r\n}\r\n\r\n/**\r\n * Convert RGBA to HSLA\r\n * @see https://stackoverflow.com/a/54071699/6662683\r\n *\r\n * Input: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n *\r\n * Output: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n */\r\nexport function rgbaToHSLA(color: RGBA): HSLA {\r\n const r = color.r / 255\r\n const g = color.g / 255\r\n const b = color.b / 255\r\n\r\n const v = Math.max(r, g, b)\r\n const c = v - Math.min(r, g, b)\r\n const f = 1 - Math.abs(v + v - c - 1)\r\n const h = c && (v === r ? (g - b) / c : v === g ? 2 + (b - r) / c : 4 + (r - g) / c)\r\n\r\n return {\r\n h: 60 * (h < 0 ? h + 6 : h),\r\n s: f ? c / f : 0,\r\n l: (v + v - c) / 2,\r\n a: color.a,\r\n }\r\n}\r\n\r\n/**\r\n * Convert HSVA color to RGBA\r\n * @see https://stackoverflow.com/a/54024653/6662683\r\n *\r\n * Input: { h: [0,360], s: [0,1], v: [0,1], a: [0,1]}\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hsvaToRGBA(color: HSVA): RGBA {\r\n const f = (n: number, k = (n + color.h / 60) % 6) => color.v - color.v * color.s * Math.max(Math.min(k, 4 - k, 1), 0)\r\n\r\n return {\r\n r: Math.round(f(5) * 255),\r\n g: Math.round(f(3) * 255),\r\n b: Math.round(f(1) * 255),\r\n a: Math.round(color.a * 100) / 100,\r\n }\r\n}\r\n\r\n/**\r\n * Convert HSLA color to RGBA\r\n * @see https://stackoverflow.com/a/54014428/6662683\r\n *\r\n * Input: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hslaToRGBA(color: HSLA): RGBA {\r\n const a = color.s * Math.min(color.l, 1 - color.l)\r\n const f = (n: number, k = (n + color.h / 30) % 12) => color.l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1)\r\n\r\n return {\r\n r: Math.round(f(0) * 255),\r\n g: Math.round(f(8) * 255),\r\n b: Math.round(f(4) * 255),\r\n a: color.a,\r\n }\r\n}\r\n\r\n/**\r\n * Convert RGBA color to rgba() string\r\n *\r\n * Input: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n *\r\n * Output: rgba(r, g, b, a)\r\n */\r\nexport function rgbaToRGBAString(color: RGBA) {\r\n return `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})`\r\n}\r\n\r\n/**\r\n * Convert rgba() string to RGBA color\r\n *\r\n * Input: rgba(r, g, b, a)\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function rgbaStringToObject(color: string) {\r\n const colorParts = /^rgba?\\(([0-9]{1,3})[ ,]+([0-9]{1,3})[ ,]+([0-9]{1,3})[ ,]*([01].?[0-9]*)?\\)$/.exec(color)\r\n const [red, green, blue, alpha = '1'] = colorParts?.slice(1) || [0, 0, 0, 1].map(String)\r\n return {\r\n r: Number.parseInt(red),\r\n g: Number.parseInt(green),\r\n b: Number.parseInt(blue),\r\n a: Number.parseFloat(alpha),\r\n }\r\n}\r\n\r\n/**\r\n * Convert HSLA color to hsla() string\r\n *\r\n * Input: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n *\r\n * Output: hsla(h, s, l, a)\r\n */\r\nexport function hslaToHSLAString(color: HSLA) {\r\n return `hsla(${Math.round(color.h)}, ${Math.round(color.s * 10000) / 100}%, ${Math.round(color.l * 10000) / 100}%, ${\r\n color.a\r\n })`\r\n}\r\n\r\nexport function removeHashSymbol(strColor: string) {\r\n return strColor.replace(/#/g, '')\r\n}\r\n\r\n/**\r\n * Check if the param is a valid color by setting it as style\r\n */\r\nexport function isValidColor(strColor: string) {\r\n const isRgb = strColor.startsWith('rgba')\r\n const s = new Option().style\r\n\r\n s.color = isRgb ? strColor : `#${removeHashSymbol(strColor)}`\r\n\r\n return s.color !== ''\r\n}\r\n\r\n/**\r\n * Normalize color to be a hex value\r\n */\r\nexport function convertColorToHEX(strColor: string) {\r\n const isRgb = getIsRgb(strColor)\r\n\r\n if (isRgb) {\r\n return rgbaToHexString(rgbaStringToObject(strColor), true)\r\n }\r\n\r\n return strColor\r\n}\r\n\r\n/**\r\n * Returns true if color is rgb or rgba\r\n */\r\nexport function getIsRgb(strColor: string, isAlphaAllowed = true) {\r\n const rgbKeys = ['rgb']\r\n if (isAlphaAllowed) {\r\n rgbKeys.push('rgba')\r\n }\r\n return rgbKeys.some((startsWith) => strColor.startsWith(startsWith))\r\n}\r\n\r\n/**\r\n * Convert any color format to HSVA (internal color picker representation)\r\n */\r\nexport function getHSVAFromColor(strColor: string) {\r\n if (getIsRgb(strColor)) {\r\n return rgbaToHSVA(rgbaStringToObject(strColor))\r\n }\r\n\r\n return hexStringToHSVA(strColor)\r\n}\r\n\r\n/**\r\n * Stringify HSVA color representation into a output format\r\n */\r\nexport function stringifyHSVAColor(color: HSVA, output: 'rgba' | 'hex', canSelectAlpha?: boolean) {\r\n switch (output) {\r\n case 'rgba':\r\n return rgbaToRGBAString(hsvaToRGBA(color))\r\n default:\r\n return hsvaToHEXString(color, canSelectAlpha)\r\n }\r\n}\r\n\r\n/**\r\n * Get luma value from RGBA color using the Rec. 709 coefficients\r\n * @see https://en.wikipedia.org/wiki/Luma_%28video%29\r\n *\r\n * If luma is >= 165 the foreground color should be dark\r\n */\r\nexport function getLumaFromRGBA(color: RGBA) {\r\n return 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b\r\n}\r\n\r\n/**\r\n * Checks if luma is >= 165 or alpha < 0.3\r\n */\r\nexport function getIsColorTooLightOrTransparent(color: RGBA) {\r\n return getLumaFromRGBA(color) >= 165 || color.a < 0.5\r\n}\r\n\r\n/**\r\n * Set specific alpha for a hex color\r\n */\r\nexport function getHEXWithSpecificAplha(color: string, alpha = 1) {\r\n const rgbaColor = hexStringToRGBA(color)\r\n return rgbaToHexString({ ...rgbaColor, a: alpha }, true)\r\n}\r\n\r\n/**\r\n * Get rgba from valid color string\r\n */\r\nexport function getRGBAValueFromValidColorString(value: string) {\r\n if (getIsRgb(value)) return rgbaToRGBAString(rgbaStringToObject(value))\r\n return rgbaToRGBAString(hexStringToRGBA(value))\r\n}\r\n","import { useCallback, useMemo } from 'react'\r\n\r\nimport { DraggablePicker, Interaction } from './draggable'\r\nimport { Pointer } from './pointer'\r\nimport { HSVA, hsvaToHEXString } from './util'\r\n\r\ninterface LightnessProps {\r\n color: HSVA\r\n onChange: (color: HSVA) => void\r\n}\r\n\r\nexport function Alpha({ color, onChange }: LightnessProps) {\r\n const changeLightness = useCallback((pos: Interaction) => onChange({ ...color, a: 1 - pos.left }), [onChange, color])\r\n\r\n const gradientPreview = useMemo(() => {\r\n const gradientFrom = hsvaToHEXString({ ...color, a: 1 })\r\n const gradientTo = hsvaToHEXString({ ...color, a: 0 }, true)\r\n\r\n return `linear-gradient(90deg, ${gradientFrom}, ${gradientTo})`\r\n // Don’t recalculate when alpha changes\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [color.h, color.s, color.v])\r\n\r\n return (\r\n \r\n
\r\n
\r\n
\r\n \r\n \r\n )\r\n}\r\n","import { Icon } from '../icon'\r\nimport { HSVA, hexStringToHSVA } from './util'\r\n\r\nconst DEFAULT_COLORS = [\r\n { title: 'Rose', value: '#f43f5e' },\r\n { title: 'Pink', value: '#db2777' },\r\n { title: 'Fuchsia', value: '#c026d3' },\r\n { title: 'Purple', value: '#9333ea' },\r\n { title: 'Violet', value: '#7c3aed' },\r\n { title: 'Indigo', value: '#4f46e5' },\r\n { title: 'Blue', value: '#2563eb' },\r\n { title: 'Light Blue', value: '#0284c7' },\r\n { title: 'Cyan', value: '#0891b2' },\r\n { title: 'Teal', value: '#0d9488' },\r\n { title: 'Emerald', value: '#059669' },\r\n { title: 'Green', value: '#16a34a' },\r\n { title: 'Lime', value: '#65a30d' },\r\n { title: 'Yellow', value: '#eab308' },\r\n { title: 'Amber', value: '#d97706' },\r\n { title: 'Red', value: '#dc2626' },\r\n]\r\n\r\ninterface ColorItem {\r\n /**\r\n * Name of the color\r\n */\r\n title: string\r\n\r\n /**\r\n * Hex value\r\n */\r\n value: string\r\n}\r\n\r\ninterface ColorPaletteProps {\r\n /**\r\n * Current selected color in HEX format (supports HEX8 for alpha)\r\n */\r\n color: string\r\n\r\n /**\r\n * List of colors to display in the palette\r\n *\r\n * @default DEFAULT_COLORS\r\n */\r\n colors?: ColorItem[]\r\n\r\n /**\r\n * Callback when user picks a color\r\n */\r\n onChange: (color: string, originalColor: HSVA) => void\r\n}\r\n\r\nexport function ColorPalette({ color, colors = DEFAULT_COLORS, onChange }: ColorPaletteProps) {\r\n const lowerCaseColor = color.toLowerCase()\r\n\r\n return (\r\n
\r\n {colors.map((colorObj) => {\r\n const isSelected = lowerCaseColor.startsWith(colorObj.value)\r\n return (\r\n onChange(colorObj.value, hexStringToHSVA(colorObj.value))}\r\n >\r\n {isSelected && }\r\n
\r\n )\r\n })}\r\n
\r\n )\r\n}\r\n","import { useCallback, useMemo } from 'react'\r\n\r\nimport { DraggablePicker, Interaction } from './draggable'\r\nimport { Pointer } from './pointer'\r\nimport { HSVA, hsvaToHEXString } from './util'\r\n\r\ninterface HueSaturationProps {\r\n color: HSVA\r\n onChange: (color: HSVA) => void\r\n}\r\n\r\nfunction getPositionFromHSLA(color: HSVA) {\r\n return {\r\n left: color.h / 360,\r\n top: 1 - color.s,\r\n }\r\n}\r\n\r\nexport function HueSaturation({ color, onChange }: HueSaturationProps) {\r\n const position = useMemo(() => getPositionFromHSLA(color), [color])\r\n\r\n const colorPreview = useMemo(() => hsvaToHEXString({ h: color.h, s: color.s, v: 1, a: 1 }), [color.h, color.s])\r\n\r\n const changeSaturation = useCallback(\r\n (pos: Interaction) =>\r\n onChange({\r\n h: Math.round(pos.left * 360),\r\n s: 1 - pos.top,\r\n v: 1,\r\n a: color.a,\r\n }),\r\n [color.a, onChange]\r\n )\r\n\r\n return (\r\n \r\n
\r\n
\r\n
\r\n \r\n \r\n )\r\n}\r\n","import { useCallback, useMemo } from 'react'\r\n\r\nimport { DraggablePicker, Interaction } from './draggable'\r\nimport { Pointer } from './pointer'\r\nimport { HSVA, hsvaToHEXString } from './util'\r\n\r\ninterface LightnessProps {\r\n color: HSVA\r\n onChange: (color: HSVA) => void\r\n}\r\n\r\nexport function Lightness({ color, onChange }: LightnessProps) {\r\n const changeLightness = useCallback((pos: Interaction) => onChange({ ...color, v: 1 - pos.left }), [onChange, color])\r\n\r\n const colorPreview = useMemo(\r\n () => hsvaToHEXString({ h: color.h, s: color.s, v: color.v, a: 1 }),\r\n [color.h, color.s, color.v]\r\n )\r\n\r\n const gradientPreview = useMemo(() => {\r\n const gradientFrom = hsvaToHEXString({ h: color.h, s: color.s, v: 1, a: 1 })\r\n const gradientTo = hsvaToHEXString({ h: color.h, s: color.s, v: 0, a: 1 })\r\n\r\n return `linear-gradient(90deg, ${gradientFrom}, ${gradientTo})`\r\n }, [color.h, color.s])\r\n\r\n return (\r\n \r\n
\r\n \r\n \r\n )\r\n}\r\n","import classnames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { Icon, IconNameType, isValidIconName } from '../icon'\r\nimport { getIsColorTooLightOrTransparent, hexStringToRGBA } from './util'\r\n\r\ninterface ColorPreviewProps {\r\n /**\r\n * Name of an icon or JSX.Element\r\n */\r\n icon?: JSX.Element | IconNameType\r\n\r\n /**\r\n * One or more colors to show in the preview\r\n */\r\n color: string | string[]\r\n\r\n /**\r\n * Wrapper classname\r\n */\r\n className?: string\r\n}\r\n\r\nexport function ColorPreview({ icon, color, className }: ColorPreviewProps) {\r\n const colors = Array.isArray(color) ? color : [color]\r\n const isTooLight = getIsColorTooLightOrTransparent(hexStringToRGBA(colors[0]))\r\n return (\r\n \r\n {icon && (\r\n
\r\n {isValidIconName(icon) ? (\r\n \r\n ) : (\r\n icon\r\n )}\r\n
\r\n )}\r\n {colors.map((color, index) => (\r\n //   has to be there because of a bug on safari which ignores h-full when empty element\r\n
\r\n  \r\n
\r\n ))}\r\n
\r\n )\r\n}\r\n","import classnames from 'classnames'\r\nimport React, { ForwardedRef, useCallback, useEffect, useState } from 'react'\r\n\r\nimport { Input, InputComponentProps } from '../input'\r\nimport { ColorPreview } from './color-preview'\r\nimport { ColorPickerProps } from './picker'\r\nimport * as colorUtil from './util'\r\n\r\ninterface PickerInputProps extends Omit {\r\n color: ColorPickerProps['color']\r\n onChange: ColorPickerProps['onChange']\r\n\r\n /*\r\n * Is color preview square visible\r\n *\r\n * @default true\r\n * */\r\n hasColorPreview?: boolean\r\n}\r\nexport const PickerInput = React.forwardRef(\r\n (\r\n { color, inputClass, hasColorPreview = true, onChange, ...props }: PickerInputProps,\r\n ref: ForwardedRef\r\n ) => {\r\n const [colorInput, setColorInput] = useState(colorUtil.removeHashSymbol(color))\r\n const isRgba = colorUtil.getIsRgb(colorInput)\r\n\r\n useEffect(() => {\r\n setColorInput(colorUtil.removeHashSymbol(color))\r\n }, [color])\r\n\r\n const handleColorInputChange = useCallback(\r\n (event) => {\r\n const value = colorUtil.removeHashSymbol(event.currentTarget.value)\r\n const isRgba = value.startsWith('rgba')\r\n const colorValue = isRgba ? value : `#${value}`\r\n\r\n setColorInput(value)\r\n if ((value.length >= 6 || (isRgba && value.length >= 16)) && colorUtil.isValidColor(colorValue)) {\r\n onChange(colorValue, colorUtil.hexStringToHSVA(colorValue))\r\n }\r\n },\r\n [onChange]\r\n )\r\n return (\r\n \r\n {hasColorPreview && (\r\n
\r\n \r\n
\r\n )}\r\n {!isRgba && #}\r\n
\r\n }\r\n onChange={handleColorInputChange}\r\n />\r\n )\r\n }\r\n)\r\n","import classnames from 'classnames'\r\nimport React, { ReactNode, useCallback, useEffect, useRef, useState } from 'react'\r\n\r\nimport { isMobile } from '../../../app/shared/isMobile'\r\nimport { Button } from '../button'\r\nimport { Popover, PopoverTrigger, usePopoverState } from '../popover'\r\nimport { Alpha } from './alpha'\r\nimport { ColorPalette } from './color-palette'\r\nimport { HueSaturation } from './hue-saturation'\r\nimport { Lightness } from './lightness'\r\nimport { PickerInput } from './picker-input'\r\nimport * as colorUtil from './util'\r\n\r\nexport interface ColorPickerProps {\r\n /**\r\n * The selected color in HEX format (supports HEX8 for alpha)\r\n */\r\n color: string\r\n\r\n /**\r\n * Whether or not the user is able to select custom color\r\n *\r\n * @default true\r\n */\r\n canSelectCustom?: boolean\r\n\r\n /**\r\n * Whether or not the user is able to change alpha channel. Only applicable\r\n * when `canSelectCustom` is true\r\n *\r\n * @default true\r\n */\r\n canSelectAlpha?: boolean\r\n\r\n /**\r\n * Sets the output format for the color picker\r\n *\r\n * @default 'hex'\r\n */\r\n outputFormat?: 'hex' | 'rgba'\r\n\r\n /**\r\n * Callback when user changes color. Use the second parameter to do color space\r\n * conversions otherwise the color could differ due to rounding\r\n */\r\n onChange: (color: string, originalColor: colorUtil.HSVA) => void\r\n\r\n /**\r\n * Callback when user clicks on a palette item. Used to close popover\r\n */\r\n onPaletteItemClick?: () => void\r\n}\r\n\r\nexport function ColorPicker({\r\n color,\r\n canSelectCustom = true,\r\n canSelectAlpha = true,\r\n outputFormat = 'hex',\r\n onChange,\r\n onPaletteItemClick,\r\n}: ColorPickerProps) {\r\n const cachedColor = useRef(color)\r\n const [hsvaColor, setColor] = useState(colorUtil.getHSVAFromColor(color))\r\n\r\n /**\r\n * Update state if the color from outside changed\r\n */\r\n useEffect(() => {\r\n const currentColor = colorUtil.removeHashSymbol(cachedColor.current)\r\n const newColor = colorUtil.removeHashSymbol(color)\r\n\r\n if (currentColor === newColor || !colorUtil.isValidColor(newColor)) return\r\n\r\n cachedColor.current = color\r\n setColor(colorUtil.getHSVAFromColor(color))\r\n }, [color])\r\n\r\n /**\r\n * Handle color change\r\n * 1. update cache so we can correctly check when outside color updates\r\n * 2. Update internal color representation\r\n * 3. call onChange with string color\r\n */\r\n const onChangeCallback = useCallback(\r\n (color: colorUtil.HSVA) => {\r\n const stringColor = colorUtil.stringifyHSVAColor(color, outputFormat, canSelectAlpha)\r\n cachedColor.current = stringColor\r\n onChange(stringColor, color)\r\n setColor(color)\r\n },\r\n [onChange, canSelectAlpha, outputFormat]\r\n )\r\n\r\n const onSetCustomCodeClick = useCallback(() => {\r\n const value = prompt('Enter a color code')?.trim()\r\n\r\n if (!value) return\r\n\r\n const isValid = colorUtil.isValidColor(value)\r\n\r\n if (!isValid) {\r\n return alert('The code is not a valid color')\r\n }\r\n\r\n onChangeCallback(colorUtil.getHSVAFromColor(value))\r\n }, [onChangeCallback])\r\n\r\n return (\r\n
\r\n {canSelectCustom && (\r\n <>\r\n {isMobile() && (\r\n \r\n )}\r\n \r\n \r\n\r\n {canSelectAlpha && }\r\n \r\n )}\r\n\r\n \r\n {\r\n onPaletteItemClick?.()\r\n onChangeCallback({ ...orignalColor, a: hsvaColor.a })\r\n }}\r\n />\r\n
\r\n \r\n )\r\n}\r\n\r\ninterface InputColorPickerProps extends ColorPickerProps {\r\n /**\r\n * Label for the input\r\n */\r\n label?: ReactNode\r\n inputDataTestId?: string\r\n}\r\n\r\nexport function InputColorPicker({ label, inputDataTestId, onChange, ...props }: InputColorPickerProps) {\r\n const popoverState = usePopoverState()\r\n const canSelectCustom = props.canSelectCustom !== false\r\n const isMobileDevice = isMobile()\r\n\r\n return (\r\n <>\r\n \r\n \r\n \r\n {\r\n if (canSelectCustom) return\r\n popoverState.hide()\r\n }}\r\n />\r\n \r\n \r\n \r\n )\r\n}\r\n","import classnames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { isMobile } from '../../../app/shared/isMobile'\r\nimport { Button, ButtonComponentProps, ButtonRounding, ButtonSizeType } from '../button'\r\nimport { ButtonGroup } from '../button-group'\r\nimport { IconNameType } from '../icon'\r\nimport { Popover, PopoverProps, PopoverTrigger, usePopoverState } from '../popover'\r\nimport { ColorPreview } from './color-preview'\r\nimport { ColorPicker, ColorPickerProps } from './picker'\r\nimport { PickerInput } from './picker-input'\r\nimport * as colorUtil from './util'\r\n\r\ninterface MultiColorPickerProps extends ColorPickerProps {\r\n /**\r\n * Label for color text input\r\n *\r\n * @default undefined\r\n */\r\n colorInputLabel?: string\r\n}\r\n\r\nexport function MultiColorPicker({\r\n colorInputLabel,\r\n onChange,\r\n canSelectCustom = true,\r\n ...props\r\n}: MultiColorPickerProps) {\r\n const isMobileDevice = isMobile()\r\n\r\n return (\r\n <>\r\n {canSelectCustom && !isMobileDevice && (\r\n
\r\n \r\n
\r\n )}\r\n \r\n {}} />\r\n \r\n \r\n )\r\n}\r\n\r\ninterface ColorTabButtonProps extends ButtonComponentProps {\r\n /*\r\n * Preview color\r\n * */\r\n color: string\r\n}\r\n\r\nexport function ColorTabButton({ color, children, ...props }: ColorTabButtonProps) {\r\n return (\r\n }\r\n {...props}\r\n >\r\n {children}\r\n \r\n )\r\n}\r\n\r\ntype ButtonColorProperties = { color: string; label: string }\r\n\r\ninterface ButtonColorPickerProps\r\n extends Omit {\r\n /**\r\n * Temporary prop to enable/disable multi picker funcionality,\r\n * in the future we'll only use secondaryColor prop to decide if the picker is multi picker or not\r\n *\r\n * @default undefined\r\n */\r\n isMultiPicker?: boolean\r\n\r\n /**\r\n * Button classname\r\n */\r\n className?: string\r\n\r\n /**\r\n * Array of objects with color and value\r\n */\r\n colors: ColorType[]\r\n\r\n /**\r\n * Color onchange callback\r\n */\r\n onChange: (colors: ColorType[], originalColor: colorUtil.HSVA) => void\r\n\r\n /**\r\n * Button size\r\n *\r\n * @default undefined\r\n */\r\n size?: ButtonSizeType\r\n /**\r\n * Label for color text input\r\n *\r\n * @default undefined\r\n */\r\n colorInputLabel?: string\r\n\r\n /**\r\n * Name of an icon or JSX.Element\r\n */\r\n icon?: JSX.Element | IconNameType\r\n\r\n /**\r\n * Hides color picker when clicked outside of popover,\r\n * works with changing focus from the trigger component to another one\r\n *\r\n * @default true\r\n */\r\n hideOnClickOutside: PopoverProps['hideOnClickOutside']\r\n\r\n /**\r\n * Popover overlay click callback, if nothing's provided it calls hide when clicked outside of popover on its overlay\r\n * If false is provided, overlay click calls hide func on popover state object\r\n *\r\n * @default undefined\r\n */\r\n onOverlayClick?: (() => void) | false\r\n\r\n /**\r\n * Identifier for e2e testing\r\n *\r\n * @default undefined\r\n */\r\n buttonPickerDataTestId?: string\r\n}\r\n\r\nexport function ButtonColorPicker({\r\n size,\r\n icon,\r\n colors,\r\n className,\r\n onChange,\r\n buttonPickerDataTestId,\r\n hideOnClickOutside = true,\r\n onOverlayClick,\r\n ...props\r\n}: ButtonColorPickerProps) {\r\n const popoverState = usePopoverState()\r\n const isMultiPicker = !!props.isMultiPicker && colors.length > 1\r\n const [activeColorIndex, setActiveColorIndex] = React.useState(0)\r\n const handleColorChange = React.useCallback(\r\n (color: string, originalColor: colorUtil.HSVA) => {\r\n onChange(\r\n colors.map((colorObject, index) => (index === activeColorIndex ? { ...colorObject, color } : colorObject)),\r\n originalColor\r\n )\r\n },\r\n [activeColorIndex, colors, onChange]\r\n )\r\n return (\r\n <>\r\n \r\n color)}\r\n className={classnames('h-full w-full', ButtonRounding.small)}\r\n />\r\n \r\n \r\n {isMultiPicker && (\r\n
\r\n \r\n {colors.map(({ color, label }, index) => (\r\n setActiveColorIndex(index)}\r\n >\r\n {label}\r\n \r\n ))}\r\n \r\n
\r\n )}\r\n \r\n \r\n \r\n )\r\n}\r\n","import copy from 'copy-to-clipboard'\r\nimport React from 'react'\r\n\r\nimport { Button } from '../button'\r\nimport { InputProps, Textarea } from '../input'\r\n\r\ninterface Props extends Pick {\r\n className?: string\r\n text: string\r\n bottomLeftContent?: React.ReactNode\r\n}\r\n\r\nexport const CopyToClipboard: React.FC = ({ className, label, text, bottomLeftContent }) => {\r\n const [isCopied, setIsCopied] = React.useState(false)\r\n\r\n const handleCopyToClipboard = React.useCallback(() => {\r\n setIsCopied(true)\r\n copy(text)\r\n }, [text])\r\n\r\n React.useEffect(() => {\r\n let timeout: NodeJS.Timeout\r\n const resetTimer = () => {\r\n if (!timeout) return\r\n clearTimeout(timeout)\r\n }\r\n if (isCopied) {\r\n resetTimer()\r\n timeout = setTimeout(() => {\r\n setIsCopied(false)\r\n }, 2000)\r\n }\r\n\r\n return () => {\r\n resetTimer()\r\n }\r\n }, [isCopied])\r\n\r\n return (\r\n
\r\n e.currentTarget.select()}\r\n inputClass=\"h-12\"\r\n data-testid=\"copy-to-clipboard-textarea\"\r\n value={text}\r\n />\r\n
\r\n {bottomLeftContent &&
{bottomLeftContent}
}\r\n \r\n {isCopied ? 'Copied' : 'Copy'}\r\n \r\n
\r\n
\r\n )\r\n}\r\n","import * as React from 'react'\r\nimport { CalendarProps } from 'react-calendar'\r\n\r\nimport { Box } from '../box'\r\nimport { ZIndexContext, getExtendedDialogState } from '../dialog'\r\nimport { Popover, PopoverTrigger, usePopoverState } from '../popover'\r\nimport { Spinner } from '../spinner'\r\n\r\nconst DatePickerComponent = React.lazy(() => import('./picker'))\r\n\r\ntype RangePickerCallback = (value: [Date, Date], ev: React.ChangeEvent) => void\r\ntype PickerCallback = (value: Date, ev: React.ChangeEvent) => void\r\n\r\ninterface DatePickerProps extends Omit {\r\n /**\r\n * Trigger element for the picker\r\n */\r\n children: JSX.Element\r\n\r\n onChange: PickerCallback | RangePickerCallback\r\n\r\n zIndex?: string\r\n}\r\n\r\nexport function StatelessDatePicker({\r\n state,\r\n children,\r\n zIndex,\r\n ...props\r\n}: DatePickerProps & { state: ReturnType; zIndex?: string }) {\r\n const { isFullyClosed } = getExtendedDialogState(state)\r\n return (\r\n <>\r\n \r\n {(triggerProps: React.HTMLProps) =>\r\n React.Children.map(children, (child) => {\r\n if (React.isValidElement(child))\r\n return React.cloneElement(child, { ...triggerProps, ...(child.props as any) })\r\n })\r\n }\r\n \r\n {!isFullyClosed && (\r\n \r\n \r\n \r\n \r\n \r\n }\r\n >\r\n ) => {\r\n state.hide()\r\n props.onChange?.(value, ev)\r\n }}\r\n />\r\n \r\n \r\n \r\n )}\r\n \r\n )\r\n}\r\n\r\nexport function DatePicker(props: DatePickerProps) {\r\n const popover = usePopoverState()\r\n\r\n return \r\n}\r\n","import * as React from 'react'\r\nimport { usePopper } from 'react-popper'\r\n\r\nimport { usePopoverMaxHeight } from '../../hooks/use-popover-maxHeight'\r\nimport { Button } from '../button'\r\nimport { getExtendedDialogState } from '../dialog'\r\nimport { Dropdown, DropdownItem, DropdownSeparator, useDropdownState } from '../dropdown'\r\nimport { ObjectHash } from '../types'\r\n\r\nconst DEFAULT_OFFSETS: [number, number] = [5, 5]\r\n\r\nfunction getVirtualRef(top: number, left: number) {\r\n return {\r\n getBoundingClientRect(): DOMRect {\r\n const rect = {\r\n top: top - window.scrollY,\r\n x: top - window.scrollY,\r\n left: left - window.scrollX,\r\n y: left - window.scrollX,\r\n bottom: top,\r\n right: left,\r\n width: 0,\r\n height: 0,\r\n }\r\n\r\n return {\r\n ...rect,\r\n toJSON: () => rect,\r\n }\r\n },\r\n }\r\n}\r\n\r\nexport interface IContextMenuOption {\r\n type?: never\r\n id: string\r\n label: React.ReactNode\r\n onClick?: () => void\r\n options?: ContextMenuItem[]\r\n gtag?: ObjectHash\r\n}\r\n\r\ninterface IContextMenuDivider {\r\n type: 'divider'\r\n label?: React.ReactNode\r\n}\r\n\r\nexport type ContextMenuItem = IContextMenuOption | IContextMenuDivider\r\n\r\ninterface ContextMenuProps {\r\n /**\r\n * Top coordinate of the click\r\n */\r\n top: number\r\n\r\n /**\r\n * Left coordinate of the click\r\n */\r\n left: number\r\n\r\n /**\r\n * Can limit the max height of the menu\r\n *\r\n * @default undefined\r\n */\r\n menuMaxHeight?: number\r\n\r\n /**\r\n * Items visible in the menu\r\n */\r\n items: ContextMenuItem[]\r\n\r\n /**\r\n * Callback to hide the menu\r\n */\r\n hide: () => void\r\n}\r\n\r\nexport function ContextMenu({ top, left, menuMaxHeight, hide, items }: ContextMenuProps) {\r\n const [popperElement, setPopperElement] = React.useState(null)\r\n const virtualRef = React.useMemo(() => getVirtualRef(top, left), [left, top])\r\n const dropdownState = useDropdownState({ placement: 'bottom-start' })\r\n const { isFullyClosed } = getExtendedDialogState(dropdownState)\r\n const hasBeenOpen = React.useRef(false)\r\n\r\n const { styles, attributes } = usePopper(virtualRef, popperElement, {\r\n placement: 'auto-end',\r\n modifiers: [\r\n {\r\n name: 'offset',\r\n options: {\r\n offset: DEFAULT_OFFSETS,\r\n },\r\n },\r\n ],\r\n })\r\n\r\n /**\r\n * This effect handles closing the context menu (parent element) itself\r\n */\r\n React.useEffect(() => {\r\n if (isFullyClosed && hasBeenOpen.current) hide()\r\n }, [isFullyClosed, hide])\r\n\r\n /**\r\n * This effect handles opening/closing the inner dropdown\r\n */\r\n React.useEffect(() => {\r\n dropdownState.show()\r\n hasBeenOpen.current = true // This acts as a way to differentiate the first render\r\n\r\n return () => dropdownState.hide()\r\n // This needs to run only on mount/unmount for obvious reasons\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n return (\r\n \r\n }\r\n menuMaxHeight={menuMaxHeight}\r\n state={dropdownState}\r\n items={items}\r\n isStatic\r\n />\r\n \r\n )\r\n}\r\n\r\ninterface ContextMenuInnerProps {\r\n label: JSX.Element\r\n items: ContextMenuItem[]\r\n state: ReturnType\r\n isStatic?: boolean\r\n menuMaxHeight?: number\r\n}\r\n\r\nfunction ContextMenuInner(\r\n { label, items, state, isStatic, menuMaxHeight = Number.MAX_SAFE_INTEGER }: ContextMenuInnerProps,\r\n ref: React.ForwardedRef\r\n) {\r\n const innerState = useDropdownState({ placement: 'right-start' })\r\n const maxHeightStyle = usePopoverMaxHeight({\r\n maxHeightLimit: menuMaxHeight,\r\n hasViewportHeightLimit: true,\r\n offsets: DEFAULT_OFFSETS,\r\n state,\r\n })\r\n\r\n return (\r\n \r\n {items.map((item, index) => {\r\n if (item.type === 'divider') {\r\n return {item.label}\r\n }\r\n\r\n if (item?.options !== undefined) {\r\n return (\r\n \r\n {item.label}\r\n \r\n }\r\n items={item.options}\r\n />\r\n )\r\n }\r\n\r\n return (\r\n {\r\n item.onClick?.()\r\n window.gtag?.('event', 'context-menu', Object.assign({ menu_option: item.id }, item.gtag))\r\n }}\r\n data-testid={`dropdown-menu-${item.id}`}\r\n className=\"shrink-0\"\r\n >\r\n {item.label}\r\n \r\n )\r\n })}\r\n \r\n )\r\n}\r\n\r\nconst ContextMenuDropdown = React.forwardRef(ContextMenuInner)\r\n","import classnames from 'classnames'\r\nimport React from 'react'\r\n\r\ninterface GridLayoutProps extends React.HTMLProps {\r\n /**\r\n * Number of columns\r\n */\r\n columns?: number\r\n\r\n /**\r\n * Number of rows\r\n */\r\n rows?: number\r\n\r\n /**\r\n * Whether or not a border is rendered between and around items. eg. charts\r\n * on HP won’t have a border\r\n *\r\n * @default false\r\n */\r\n border?: boolean\r\n}\r\n\r\nexport const ChartGridCell = React.forwardRef(\r\n ({ children, gridArea, className, ...props }, ref) => (\r\n \r\n {children}\r\n \r\n )\r\n)\r\n\r\ninterface ChartGridCellProps extends React.HTMLProps {\r\n /**\r\n * Css grid-area value\r\n */\r\n gridArea?: string\r\n}\r\n\r\nexport function GridLayout({ columns = 1, rows = 1, border = false, children, className, ...props }: GridLayoutProps) {\r\n return (\r\n \r\n {children}\r\n \r\n )\r\n}\r\n\r\ninterface ChartGridProps extends GridLayoutProps {\r\n isResizable?: boolean\r\n}\r\n\r\nexport const ChartGrid: React.FC = (props) => \r\n","import * as React from 'react'\r\n\r\nimport { PropsWithAs, RequireByKey } from '../types'\r\n\r\nconst defaultValueAccessor: ValueAccessor = (data) => data\r\n\r\nconst DEFAULT_VALUE_KEY = 'value'\r\nconst DEFAULT_CHANGE_KEY = 'onChange'\r\n\r\ntype ValueAccessor<\r\n TagType extends React.ElementType,\r\n ValueKey extends keyof React.ComponentProps = typeof DEFAULT_VALUE_KEY,\r\n ChangeKey extends keyof React.ComponentProps = typeof DEFAULT_CHANGE_KEY,\r\n> = (...args: Parameters[ChangeKey]>) => React.ComponentProps[ValueKey]\r\n\r\nexport type InnerStateProps<\r\n TagType extends React.ElementType,\r\n ValueKey extends keyof React.ComponentProps,\r\n ChangeKey extends keyof React.ComponentProps,\r\n> = RequireByKey, 'as'> & {\r\n valueKey?: ValueKey\r\n changeKey?: ChangeKey\r\n valueAccessor?: ValueAccessor\r\n}\r\n\r\nexport function InnerState<\r\n TagType extends React.ElementType,\r\n ValueKey extends keyof React.ComponentProps = typeof DEFAULT_VALUE_KEY,\r\n ChangeKey extends keyof React.ComponentProps = typeof DEFAULT_CHANGE_KEY,\r\n>({\r\n as: asComponent,\r\n valueKey = 'value' as ValueKey,\r\n changeKey = 'onChange' as ChangeKey,\r\n valueAccessor = defaultValueAccessor,\r\n ...props\r\n}: InnerStateProps) {\r\n const { [valueKey]: value, [changeKey]: onChange } = props\r\n const [state, setState] = React.useState[ValueKey]>(value)\r\n\r\n const handleChange = React.useCallback>(\r\n (...args) => {\r\n setState(valueAccessor(...args))\r\n onChange(...args)\r\n },\r\n [onChange, valueAccessor]\r\n )\r\n\r\n return React.createElement(asComponent, {\r\n ...props,\r\n [valueKey]: state,\r\n [changeKey]: handleChange,\r\n })\r\n}\r\n","import classnames from 'classnames'\r\nimport { HTMLProps, ReactNode, useEffect, useMemo, useRef, useState } from 'react'\r\n\r\nimport { Label } from './typography'\r\n\r\nexport enum RangeSize {\r\n small = 'sm:h-6', // 24px height\r\n regular = 'sm:h-7', // 28px height\r\n medium = 'sm:h-8', // 32px height\r\n large = 'sm:h-9', // 36px height\r\n}\r\n\r\ntype InputProps = HTMLProps\r\n\r\ninterface RangeSliderProps extends Omit {\r\n /**\r\n * Label which is rendered above the select\r\n */\r\n label?: ReactNode\r\n\r\n /**\r\n * Range size. All inputs have forced height on mobile to avoid zoom\r\n *\r\n * @default regular\r\n */\r\n size?: keyof typeof RangeSize\r\n\r\n /**\r\n * Element which will be rendered on the left side of the slider\r\n */\r\n leftContent?: ReactNode\r\n\r\n /**\r\n * Element which will be rendered on the right side of the slider\r\n */\r\n rightContent?: ReactNode\r\n\r\n /**\r\n * Class name for the wrapper element\r\n */\r\n className?: string\r\n\r\n /**\r\n * Class name for the input element\r\n */\r\n inputClassName?: string\r\n\r\n /**\r\n * Min value for the input\r\n *\r\n * @default 0\r\n */\r\n min?: number\r\n\r\n /**\r\n * Max value for the input\r\n *\r\n * @default 100\r\n */\r\n max?: number\r\n\r\n /**\r\n * Step value for the input\r\n *\r\n * @default 1\r\n */\r\n step?: number\r\n\r\n /**\r\n * Current value\r\n */\r\n value: number\r\n\r\n /**\r\n * Callback when value changes\r\n */\r\n onChange: InputProps['onChange']\r\n}\r\n\r\nexport function RangeSlider({\r\n label,\r\n size = 'regular',\r\n leftContent,\r\n rightContent,\r\n min = 0,\r\n max = 100,\r\n step = 1,\r\n className,\r\n inputClassName,\r\n ...props\r\n}: RangeSliderProps) {\r\n const [hasTrack, setHasTrack] = useState(false)\r\n const trackRef = useRef(null)\r\n const thumbRef = useRef(null)\r\n\r\n useEffect(() => {\r\n setHasTrack(Boolean(trackRef.current && thumbRef.current))\r\n }, [])\r\n\r\n const thumbLeft = useMemo(() => {\r\n const track = trackRef.current\r\n const thumb = thumbRef.current\r\n const valuePercent = (props.value - min) / (max - min)\r\n\r\n if (!hasTrack || !track || !thumb) return\r\n\r\n const trackBox = track.getBoundingClientRect()\r\n const thumbBox = thumb.getBoundingClientRect()\r\n\r\n return ((valuePercent * (trackBox.width - thumbBox.width)) / trackBox.width) * 100\r\n }, [min, max, props.value, hasTrack])\r\n\r\n return (\r\n \r\n )\r\n}\r\n","import { ButtonRoundingType, ButtonThemeType } from '../button'\r\nimport { IconNameType } from '../icon'\r\n\r\nexport enum ToolbarTheme {\r\n chipTransparent, // (default)\r\n alternative,\r\n}\r\n\r\nexport enum ToolbarDirection {\r\n vertical,\r\n horizontal,\r\n}\r\n\r\nexport type ToolbarDirectionType = keyof typeof ToolbarDirection\r\n\r\nexport interface IButtonThemeSettings {\r\n className?: string\r\n theme: ButtonThemeType\r\n rounding: ButtonRoundingType\r\n}\r\n\r\nexport interface IToolbarItem {\r\n id: string\r\n icon: IconNameType\r\n iconActive?: IconNameType\r\n iconAction?: IconNameType\r\n title: string\r\n titleActive?: string\r\n titleAction?: string\r\n}\r\n\r\nexport type ToolbarThemeType = keyof typeof ToolbarTheme\r\n","import * as React from 'react'\r\n\r\nimport { ToolbarDirection, ToolbarTheme } from './interfaces'\r\n\r\nexport interface IToolbarContext {\r\n direction: ToolbarDirection\r\n theme: ToolbarTheme\r\n isWrapped: boolean\r\n isStretched: boolean\r\n isMobile: boolean\r\n}\r\n\r\nexport const ToolbarContext = React.createContext({\r\n direction: ToolbarDirection.vertical,\r\n theme: ToolbarTheme.chipTransparent,\r\n isWrapped: false,\r\n isStretched: false,\r\n isMobile: false,\r\n})\r\n\r\nexport function useToolbarContext() {\r\n return React.useContext(ToolbarContext)\r\n}\r\n","import classnames from 'classnames'\r\nimport throttle from 'lodash.throttle'\r\nimport React from 'react'\r\n\r\nimport { isSafariDesktop } from '../../../app/shared/isMobile'\r\nimport { IToolbarContext, ToolbarContext } from './hooks'\r\nimport { ToolbarDirection, ToolbarDirectionType, ToolbarTheme, ToolbarThemeType } from './interfaces'\r\n\r\nconst getToolbarSettings = ({\r\n direction,\r\n isWrapped,\r\n isMobile,\r\n theme,\r\n}: IToolbarContext): React.HTMLProps => {\r\n switch (isWrapped) {\r\n case true:\r\n return {\r\n className: classnames('shrink-0 items-center bg-white dark:bg-gray-800', {\r\n 'flex flex-wrap justify-between': direction === ToolbarDirection.vertical,\r\n 'grid border border-gray-100 dark:border-gray-600 p-1.5 gap-1 border-box rounded-md grid-cols-2':\r\n FinvizSettings.hasRedesignEnabled,\r\n }),\r\n }\r\n\r\n default:\r\n return {\r\n className: classnames('flex shrink-0 items-center p-1.5 bg-white dark:bg-gray-800', {\r\n 'space-x-1.5 px-1.5': direction === ToolbarDirection.horizontal && FinvizSettings.hasRedesignEnabled,\r\n 'flex-col overflow-hidden overflow-y-auto [--inset-l:0.5rem] landscape-primary:pl-inset-left':\r\n direction === ToolbarDirection.vertical,\r\n 'space-y-2': direction === ToolbarDirection.vertical && !isMobile,\r\n 'pb-inset-bottom [--inset-b:0.5rem]': theme !== ToolbarTheme.alternative && !isMobile,\r\n 'w-screen space-x-2 overflow-hidden overflow-x-auto':\r\n direction === ToolbarDirection.horizontal && theme !== ToolbarTheme.alternative,\r\n 'overflow-x-hidden': theme === ToolbarTheme.alternative,\r\n 'relative z-10 rounded-md border border-gray-100 dark:border-gray-600': isMobile,\r\n }),\r\n }\r\n }\r\n}\r\n\r\nexport interface ToolbarProps {\r\n /**\r\n * Toolbar direction\r\n *\r\n * @default vertical\r\n */\r\n direction?: ToolbarDirectionType\r\n\r\n /**\r\n * Toolbar buttons theme\r\n *\r\n * @default light\r\n */\r\n theme?: ToolbarThemeType\r\n\r\n /**\r\n * Charts mobile design\r\n *\r\n * @default false\r\n */\r\n isMobile?: boolean\r\n\r\n className?: string\r\n}\r\n\r\nexport function Toolbar({\r\n direction = 'vertical',\r\n theme = 'chipTransparent',\r\n isMobile = false,\r\n children,\r\n className,\r\n}: React.PropsWithChildren) {\r\n const toolbarRef = React.useRef(null)\r\n const contextProviderValue = React.useMemo(\r\n () => ({\r\n direction: ToolbarDirection[direction],\r\n theme: ToolbarTheme[theme],\r\n isWrapped:\r\n ToolbarDirection[direction] === ToolbarDirection.vertical && ToolbarTheme[theme] === ToolbarTheme.alternative,\r\n isStretched:\r\n ToolbarDirection[direction] === ToolbarDirection.horizontal && ToolbarTheme[theme] === ToolbarTheme.alternative,\r\n isMobile,\r\n }),\r\n [direction, theme, isMobile]\r\n )\r\n const toolbarSettings = getToolbarSettings(contextProviderValue)\r\n\r\n React.useLayoutEffect(() => {\r\n // Workaround for Safari scrollbar bug https://github.com/finvizhq/charts/issues/1038\r\n // Safari injects scrollbar after layout render and doesn't trigger reflow\r\n if (ToolbarTheme[theme] !== ToolbarTheme.alternative && isSafariDesktop()) {\r\n const forceReflow = throttle(() => {\r\n if (toolbarRef.current !== null) {\r\n const originalWidth = toolbarRef.current.style.width\r\n toolbarRef.current.style.width = '0'\r\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\r\n toolbarRef.current.offsetWidth\r\n toolbarRef.current.style.width = originalWidth\r\n }\r\n }, 200)\r\n\r\n forceReflow()\r\n window.addEventListener('resize', forceReflow)\r\n\r\n return () => {\r\n window.removeEventListener('resize', forceReflow)\r\n }\r\n }\r\n }, [theme])\r\n\r\n // reason for key is that popover is sealing initial state, description in\r\n // https://github.com/finvizhq/Finviz-Website/pull/402\r\n return (\r\n \r\n {children}\r\n \r\n )\r\n}\r\n","import classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { Button, ButtonHTMLProps, ButtonProps } from '../button'\r\nimport { Delayed } from '../delayed'\r\nimport { Icon } from '../icon'\r\nimport { Spinner } from '../spinner'\r\nimport { PropsWithAs } from '../types'\r\nimport { useToolbarContext } from './hooks'\r\nimport { IToolbarItem, ToolbarTheme } from './interfaces'\r\n\r\nfunction getButtonThemeSettings({\r\n theme,\r\n isActive,\r\n isStretched,\r\n isInAction,\r\n}: {\r\n theme: ToolbarTheme\r\n isStretched: boolean\r\n isActive?: boolean\r\n isInAction?: boolean\r\n}): Omit & ButtonProps {\r\n const includeRedesign = FinvizSettings.hasRedesignEnabled\r\n switch (theme) {\r\n case ToolbarTheme.alternative:\r\n return {\r\n className: classnames(\r\n {\r\n grow: isStretched,\r\n 'h-10 w-10': !isStretched && !includeRedesign,\r\n 'animate-pulse': isInAction,\r\n },\r\n\r\n !includeRedesign && {\r\n 'active:bg-white disabled:bg-white disabled:text-gray-300 disabled:hover:text-gray-300': true,\r\n 'border border-white text-gray-500 hover:border-gray-100 hover:text-gray-900': !isActive,\r\n 'border border-gray-900 text-gray-900': isActive,\r\n }\r\n ),\r\n theme: includeRedesign ? 'chipTransparent' : 'transparent',\r\n rounding: includeRedesign ? undefined : 'none',\r\n size: isStretched || includeRedesign ? undefined : 'none',\r\n }\r\n default:\r\n return {\r\n className: classnames(\r\n 'border dark:disabled:bg-gray-800 dark:disabled:text-gray-600 disabled:text-gray-300 disabled:bg-white dark:disabled:hover:bg-gray-800 dark:disabled:hover:text-gray-600 disabled:hover:text-gray-300 disabled:hover:bg-white',\r\n {\r\n 'animate-pulse': isInAction,\r\n 'border-transparent text-gray-500 hover:bg-gray-200/30 hover:text-gray-900 dark:text-gray-400 dark:hover:bg-gray-500/30 dark:hover:text-gray-200':\r\n !isActive,\r\n 'border-blue-400 bg-blue-50 text-gray-900 dark:bg-gray-700 dark:text-white': isActive,\r\n }\r\n ),\r\n theme: 'transparent',\r\n rounding: 'small',\r\n }\r\n }\r\n}\r\n\r\nexport interface ToolbarButtonProps extends Omit {\r\n item: IToolbarItem\r\n disabledTooltip?: string\r\n isInAction?: boolean\r\n isLoading?: boolean\r\n}\r\n\r\nexport function ToolbarButton({\r\n item,\r\n disabledTooltip,\r\n isInAction: isInActionProp,\r\n isLoading,\r\n ...props\r\n}: PropsWithAs & ToolbarButtonProps) {\r\n const { theme, isStretched } = useToolbarContext()\r\n const isInAction = isInActionProp && item.iconAction !== undefined\r\n const buttonSettings = getButtonThemeSettings({\r\n theme,\r\n isStretched,\r\n isActive: props.active,\r\n isInAction: isInAction,\r\n })\r\n\r\n const getMainIcon = () => (\r\n \r\n )\r\n\r\n return (\r\n & ToolbarButtonProps)}\r\n appearance={props.appearance ?? 'square'}\r\n title={props.disabled && disabledTooltip ? disabledTooltip : (props.active && item.titleActive) || item.title}\r\n size={\r\n buttonSettings.size ??\r\n (theme === ToolbarTheme.chipTransparent || FinvizSettings.hasRedesignEnabled ? 'medium' : 'large')\r\n }\r\n >\r\n {isLoading ? (\r\n \r\n \r\n \r\n ) : (\r\n <>\r\n {props.children ??\r\n (isInAction ? (\r\n \r\n \r\n \r\n ) : (\r\n getMainIcon()\r\n ))}\r\n \r\n )}\r\n \r\n )\r\n}\r\n","import classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { isMobile } from '../../../app/shared/isMobile'\r\nimport { Icon } from '../icon'\r\nimport { List, ListItem, useListState } from '../list'\r\nimport { useList } from '../list/hooks'\r\nimport { Popover, PopoverTrigger, useHoverPopover } from '../popover'\r\nimport { NativeSelect } from '../select/NativeSelect'\r\nimport { useToolbarContext } from './hooks'\r\nimport { IToolbarItem, ToolbarTheme } from './interfaces'\r\nimport { ToolbarButton } from './toolbar-button'\r\n\r\nexport interface ToolbarGroupProps {\r\n /**\r\n * Main button item\r\n */\r\n defaultItem: IToolbarItem\r\n\r\n /**\r\n * Shows spinner instead of icon\r\n */\r\n isLoading?: boolean\r\n\r\n /**\r\n * Current selected item id\r\n */\r\n isActive: boolean\r\n\r\n /**\r\n * Should indicate some action in progress\r\n */\r\n isInAction?: boolean\r\n\r\n /**\r\n * Array of items\r\n */\r\n groupItems: IToolbarItem[]\r\n\r\n /**\r\n * Expand group button label\r\n */\r\n groupTitle?: string\r\n\r\n /**\r\n * On item select callback\r\n */\r\n onChange: (id: string, trigger: 'button' | 'select' | 'group') => void\r\n\r\n /**\r\n * Use native select for mobile devices\r\n *\r\n * @default true\r\n */\r\n useNativeSelect?: boolean\r\n\r\n /**\r\n * Is item disabled\r\n */\r\n disabled?: boolean\r\n\r\n /**\r\n * Tooltip message if item is disabled\r\n */\r\n disabledTooltip?: string\r\n}\r\n\r\nexport function ToolbarGroup({\r\n defaultItem,\r\n isActive,\r\n isLoading,\r\n groupItems,\r\n groupTitle,\r\n onChange,\r\n useNativeSelect = isMobile(),\r\n disabled,\r\n disabledTooltip,\r\n}: ToolbarGroupProps) {\r\n const listState = useListState({ currentId: null })\r\n const { theme, isStretched } = useToolbarContext()\r\n const [selectedItem, setSelectedItem] = React.useState(defaultItem)\r\n const groupId = groupTitle?.replace(/\\s/g, '-').toLocaleLowerCase()\r\n const isAlternativeTheme = theme === ToolbarTheme.alternative\r\n const popoverState = useHoverPopover({\r\n placement: isAlternativeTheme && isStretched ? 'bottom' : 'right-start',\r\n })\r\n const select = useList(\r\n popoverState,\r\n selectedItem.id,\r\n groupItems?.map((i) => ({ value: i.id, label: i.title })) ?? [],\r\n (option) => {\r\n setSelectedItem(groupItems![groupItems!.findIndex((item) => item.id === option.value)])\r\n onChange(option.value, 'select')\r\n }\r\n )\r\n\r\n return (\r\n \r\n ) => {\r\n ev.preventDefault()\r\n ev.stopPropagation()\r\n onChange(selectedItem.id, 'group')\r\n }}\r\n >\r\n \r\n \r\n \r\n\r\n {useNativeSelect ? (\r\n ({ value: item.id, label: item.title }))}\r\n onChange={(option) => {\r\n setSelectedItem(groupItems![groupItems!.findIndex((item) => item.id === option.value)])\r\n onChange(option.value, 'select')\r\n }}\r\n onClick={() => onChange(selectedItem.id, 'select')}\r\n />\r\n ) : (\r\n \r\n \r\n {groupItems.map((item) => (\r\n }\r\n data-testid={`toolbar-group-${groupId}-${item.id}`}\r\n >\r\n {item.title}\r\n \r\n ))}\r\n \r\n \r\n )}\r\n \r\n )\r\n}\r\n","import { PartialBy } from '../../types'\r\nimport { ToolbarButton } from './toolbar-button'\r\nimport { ToolbarGroup, ToolbarGroupProps } from './toolbar-group'\r\n\r\nexport function ToolbarItem({\r\n defaultItem,\r\n isLoading,\r\n isActive,\r\n isInAction,\r\n groupItems,\r\n groupTitle,\r\n onChange,\r\n useNativeSelect,\r\n disabled,\r\n disabledTooltip,\r\n}: PartialBy) {\r\n const isItemActive = isActive && !disabled\r\n\r\n if (!!groupItems?.length) {\r\n return (\r\n \r\n )\r\n }\r\n\r\n return (\r\n {\r\n onChange(defaultItem.id, 'button')\r\n }}\r\n />\r\n )\r\n}\r\n","import classnames from 'classnames'\r\nimport React from 'react'\r\n\r\nimport { useToolbarContext } from './hooks'\r\nimport { ToolbarDirection, ToolbarTheme } from './interfaces'\r\n\r\ntype ToolbarDividerProps = {\r\n className?: string\r\n}\r\n\r\nexport function ToolbarDivider({ className }: ToolbarDividerProps) {\r\n const { direction, theme } = useToolbarContext()\r\n\r\n return (\r\n \r\n )\r\n}\r\n","import { Box } from '../box'\r\nimport { Heading, Paragraph } from '../typography'\r\nimport { TourStep } from './types'\r\n\r\nexport function StepContent({ step }: { step: TourStep }) {\r\n return (\r\n \r\n {step.title && (\r\n \r\n {step.title}\r\n \r\n )}\r\n {step.body && {step.body}}\r\n \r\n )\r\n}\r\n","import classnames from 'classnames'\r\nimport * as React from 'react'\r\nimport * as ReactDOM from 'react-dom/server'\r\nimport Shepherd from 'shepherd.js'\r\n\r\nimport {\r\n BUTTON_BASE_CLASS,\r\n BUTTON_FOCUS_STYLES,\r\n ButtonPadding,\r\n ButtonRounding,\r\n ButtonSize,\r\n ButtonTheme,\r\n getButtonTheme,\r\n} from '../button'\r\nimport { StepContent } from './step-content'\r\nimport { TourDefinition, TourStep } from './types'\r\n\r\ntype ExcludesFalse = (x: T | false) => x is T\r\n\r\n/**\r\n * Async load Shepherd module when we need it\r\n */\r\nlet shepherdLibrary: typeof Shepherd\r\nexport async function loadShepherdLibrary(setLoading: (state: boolean) => void) {\r\n if (shepherdLibrary) return shepherdLibrary\r\n\r\n try {\r\n setLoading(true)\r\n const shepherdPromise = await import('shepherd.js')\r\n shepherdLibrary = shepherdPromise.default\r\n setLoading(false)\r\n\r\n return shepherdLibrary\r\n } catch {}\r\n}\r\n\r\n/**\r\n * Get buttons based on index in the step array\r\n */\r\nconst buttonClasses = classnames(BUTTON_BASE_CLASS, BUTTON_FOCUS_STYLES, ButtonSize.regular, ButtonRounding.regular)\r\nfunction getStepButtons(tour: Shepherd.Tour, step: TourStep, index: number, arr: TourStep[]) {\r\n return [\r\n {\r\n action: tour.complete,\r\n classes: classnames(buttonClasses, 'mr-auto', getButtonTheme(ButtonTheme.light).button, ButtonPadding.regular),\r\n text: 'Exit',\r\n },\r\n index > 0 && {\r\n action: tour.back,\r\n classes: classnames(buttonClasses, getButtonTheme(ButtonTheme.light).button, ButtonPadding.regular),\r\n text: step.backButton ?? 'Back',\r\n },\r\n {\r\n classes: classnames(buttonClasses, getButtonTheme(ButtonTheme.blue).button, ButtonPadding.regular),\r\n action: tour.next,\r\n text: step.nextButton ?? (index === arr.length - 1 ? 'Finish' : 'Next'),\r\n },\r\n ].filter(Boolean as unknown as ExcludesFalse)\r\n}\r\n\r\n/**\r\n * Convert tour steps to Shepherd steps\r\n */\r\nexport function processSteps(tour: Shepherd.Tour, steps: TourStep[]): Shepherd.Step.StepOptions[] {\r\n return steps.map((step, index) => ({\r\n attachTo: { element: step.target, on: step.placement ?? 'auto' },\r\n classes: 'z-dialog',\r\n // Add offset\r\n popperOptions: {\r\n modifiers: [\r\n {\r\n name: 'offset',\r\n options: {\r\n offset: step.offset ?? [0, 10],\r\n },\r\n },\r\n ],\r\n },\r\n // Render the body\r\n text: ReactDOM.renderToString(React.createElement(StepContent, { step })),\r\n // Add buttons\r\n buttons: getStepButtons(tour, step, index, steps),\r\n modalOverlayOpeningRadius: step.overlayRadius ?? 8,\r\n modalOverlayOpeningPadding: step.overlayPadding ?? 0,\r\n }))\r\n}\r\n\r\nexport function getTourKey() {\r\n return `tour${window.location.pathname.replace(/[/.]/g, '-')}`\r\n}\r\n\r\nexport function getStepsForUser(tours: TourDefinition[]) {\r\n const lastFinishedTour = localStorage?.getItem(getTourKey())\r\n const lastTourIndex = tours.findIndex((tour) => tour.id === lastFinishedTour)\r\n const allToursViewed = lastTourIndex === tours.length - 1 || tours.slice(lastTourIndex + 1).every((item) => item.skip)\r\n const toursToView = allToursViewed ? tours : tours.slice(lastTourIndex + 1)\r\n const userTour = toursToView.reduce(\r\n (acc, current) =>\r\n current.skip\r\n ? acc\r\n : {\r\n ...acc,\r\n id: current.id,\r\n steps: [...acc.steps, ...current.steps],\r\n },\r\n { id: 'tour', steps: [], initialTour: toursToView[0].id }\r\n )\r\n\r\n return { hasNewTours: !allToursViewed, tour: userTour }\r\n}\r\n\r\nexport function completeTour(key: string) {\r\n localStorage?.setItem(getTourKey(), key)\r\n}\r\n","import * as React from 'react'\r\nimport Shepherd from 'shepherd.js'\r\n\r\nimport { TourDefinition } from './types'\r\nimport * as tourUtils from './utils'\r\n\r\nexport const DEFAULT_OPTIONS = {\r\n exitOnEsc: true,\r\n useModalOverlay: true,\r\n}\r\n\r\n/**\r\n * Hook which controls shepherd.js. The library is lazy-loaded when the tour starts\r\n *\r\n * Returns:\r\n * - `isLoading`: state of the library loading\r\n * - `currentTour`: tour object, only defined after library has loaded\r\n * - `startTour`: load the library and start tour. Returns `currentTour`\r\n * - `getStepsForUser`: returns a list of tour steps based on tours the user finished\r\n * - `completeTour`: persists the last finished tour to local storage\r\n */\r\nexport function useTour(options?: Shepherd.Tour.TourOptions) {\r\n const [isLoading, setIsLoading] = React.useState(false)\r\n const [currentTour, setTour] = React.useState(null)\r\n\r\n /**\r\n * We’re loading shepherd asynchronously and want to have loading state so we use\r\n * AbortController to check if the component is still mounted.\r\n */\r\n const controller = React.useRef('AbortController' in window ? new AbortController() : undefined)\r\n const loadingSetter = React.useRef((state: boolean) => {\r\n if (controller.current?.signal.aborted) return\r\n\r\n setIsLoading(state)\r\n })\r\n // Cleanup effect to abort the controller\r\n React.useEffect(() => () => controller.current?.abort(), [])\r\n\r\n const startTour = React.useCallback(\r\n async (definition: TourDefinition, setComplete = true) => {\r\n const shepherdLibrary = await tourUtils.loadShepherdLibrary(loadingSetter.current)\r\n\r\n if (shepherdLibrary && !controller.current?.signal.aborted) {\r\n const tour = currentTour ?? new shepherdLibrary.Tour({ ...DEFAULT_OPTIONS, ...options })\r\n\r\n if (!currentTour) setTour(tour)\r\n\r\n // Reset the tour steps in case they were updated\r\n Array.from(tour.steps).forEach((step) => tour.removeStep(step.id))\r\n\r\n const processedSteps = tourUtils.processSteps(tour, definition.steps)\r\n tour.addSteps(processedSteps)\r\n\r\n if (setComplete) {\r\n tourUtils.completeTour(definition.id)\r\n }\r\n\r\n tour.start()\r\n window.gtag?.('event', 'tour-start', { event_label: definition.initialTour ?? definition.id })\r\n\r\n return tour\r\n }\r\n },\r\n [currentTour, options]\r\n )\r\n\r\n return {\r\n isLoading,\r\n currentTour,\r\n startTour,\r\n getStepsForUser: tourUtils.getStepsForUser,\r\n completeTour: tourUtils.completeTour,\r\n }\r\n}\r\n","import React from 'react'\r\nimport { TabInitialState, TabStateReturn, useTabState } from 'reakit/Tab'\r\n\r\ntype TabsProps = {\r\n settings?: TabInitialState\r\n}\r\n\r\nconst TabsContext = React.createContext(null)\r\nexport const useTabsContext = () => React.useContext(TabsContext)\r\n\r\nexport function Tabs({ settings, children }: React.PropsWithChildren) {\r\n const state = useTabState(settings)\r\n const value = React.useMemo(() => state, [state])\r\n\r\n return (\r\n \r\n
{children}
\r\n
\r\n )\r\n}\r\n","import classNames from 'classnames'\r\nimport React from 'react'\r\nimport * as Reakit from 'reakit/Tab'\r\n\r\nimport { BUTTON_DEFAULT_ELEMENT, Button, ButtonComponentProps } from '../button'\r\nimport { Icon, IconNameType, isValidIconName } from '../icon'\r\nimport { useTabsContext } from './tabs'\r\n\r\n// Must have the same keys as ButtonSize\r\nexport enum TabSpacing {\r\n xxsmall = 'space-x-0.5', // 2px spacing\r\n xsmall = 'space-x-1', // 4px spacing\r\n none = 'space-x-1.5', // 6px spacing\r\n small = 'space-x-1.5', // 6px spacing\r\n regular = 'space-x-1.5', // 6px spacing\r\n medium = 'space-x-2', // 8px spacing\r\n large = 'space-x-2', // 8px spacing\r\n}\r\n\r\nfunction getRightContent(content: JSX.Element | IconNameType | undefined, isActive: boolean) {\r\n if (isValidIconName(content)) return \r\n else if (React.isValidElement(content))\r\n return React.cloneElement(content as React.ReactElement<{ active: boolean }>, {\r\n active: isActive,\r\n })\r\n else return content\r\n}\r\n\r\nexport function Tab({\r\n rounding = 'none',\r\n theme = 'tab',\r\n size = 'medium',\r\n children,\r\n ...props\r\n}: React.PropsWithChildren>) {\r\n const state = useTabsContext()\r\n const spacing = TabSpacing[size]\r\n\r\n return (\r\n \r\n {(itemProps: ButtonComponentProps) => {\r\n const active = Boolean(itemProps['aria-selected'])\r\n const rightContent = getRightContent(itemProps.rightContent, active)\r\n\r\n return (\r\n \r\n {children}\r\n {rightContent}\r\n \r\n )\r\n }}\r\n \r\n )\r\n}\r\n","import classNames from 'classnames'\r\nimport React from 'react'\r\nimport * as Reakit from 'reakit/Tab'\r\n\r\nimport { useTabsContext } from './tabs'\r\n\r\ntype TabListProps = {\r\n 'aria-label': string\r\n className?: string\r\n}\r\n\r\nexport function TabList({ 'aria-label': ariaLabel, className, children }: React.PropsWithChildren) {\r\n const state = useTabsContext()\r\n\r\n return (\r\n \r\n {children}\r\n \r\n )\r\n}\r\n","import React from 'react'\r\nimport * as Reakit from 'reakit/Tab'\r\n\r\nimport { useTabsContext } from './tabs'\r\n\r\nexport function TabPanel({ children, ...props }: Omit, 'as'>) {\r\n const state = useTabsContext()\r\n\r\n return (\r\n \r\n {children}\r\n \r\n )\r\n}\r\n","import classNames from 'classnames'\r\nimport React from 'react'\r\n\r\nenum BadgeSize {\r\n small = 'h-4 min-w-4', // 16px height\r\n medium = 'h-5 min-w-5', // 20px height\r\n}\r\ntype BadgeSizeType = keyof typeof BadgeSize\r\n\r\nenum BadgePadding {\r\n small = 'px-[5px] py-0', // 16px height\r\n medium = 'px-1.5 py-0.5', // 20px height\r\n}\r\ntype BadgePaddingType = keyof typeof BadgePadding\r\n\r\ntype BadgeProps = {\r\n size?: BadgeSizeType\r\n padding?: BadgePaddingType\r\n active?: boolean\r\n}\r\n\r\nexport function Badge({ size = 'medium', padding = size, active, children }: React.PropsWithChildren) {\r\n const badgePadding = BadgePadding[padding]\r\n const badgeSize = BadgeSize[size]\r\n\r\n return (\r\n \r\n {children}\r\n \r\n )\r\n}\r\n","import classnames from 'classnames'\r\nimport * as React from 'react'\r\nimport * as Reakit from 'reakit/Popover'\r\nimport { Portal } from 'reakit/Portal'\r\n\r\nimport { usePopoverMaxHeight } from '../../hooks/use-popover-maxHeight'\r\nimport { useWindowSize } from '../../hooks/use-window-size'\r\nimport { Box, BoxProps, BoxTheme } from '../box'\r\nimport { getExtendedDialogState, useZIndex } from '../dialog'\r\nimport { TooltipArrow } from '../tooltip/tooltip-arrow'\r\nimport { PopoverStateReturn } from './hooks'\r\n\r\nexport interface PopoverProps extends BoxProps, Pick {\r\n /**\r\n * The returned object from `usePopoverState`\r\n */\r\n state: PopoverStateReturn\r\n\r\n /**\r\n * Focus the popover when it opens\r\n *\r\n * @default true\r\n */\r\n focusOnShow?: Reakit.PopoverProps['unstable_autoFocusOnShow']\r\n\r\n /**\r\n * Focus the anchor element when it closes\r\n *\r\n * @default true\r\n */\r\n focusOnHide?: Reakit.PopoverProps['unstable_autoFocusOnHide']\r\n\r\n /**\r\n * Focus the anchor element when it closes\r\n *\r\n * @default undefined\r\n */\r\n finalFocusRef?: Reakit.PopoverProps['unstable_finalFocusRef']\r\n\r\n /**\r\n * Hides when clicked outside of popover, works with changing focus from the trigger component to another one\r\n *\r\n * @default true\r\n */\r\n hideOnClickOutside?: Reakit.PopoverProps['hideOnClickOutside']\r\n\r\n /**\r\n * Overlay click callback or if false is provided, overlay click calls hide func on popover state object\r\n *\r\n * @default undefined\r\n */\r\n onOverlayClick?: (() => void) | false\r\n\r\n /**\r\n * Popover wrapper css style object\r\n *\r\n * @default undefined\r\n */\r\n popoverWrapperStyle?: React.CSSProperties\r\n\r\n /**\r\n * Show popover arrow\r\n *\r\n * @default false\r\n */\r\n hasArrow?: boolean\r\n\r\n /**\r\n * Enable or disable backdrop click events\r\n *\r\n * @default true\r\n */\r\n hasBackdrop?: boolean\r\n\r\n /**\r\n * Set the popover to height to be limited by the viewport instead of having full height\r\n *\r\n * @default false\r\n */\r\n hasViewportHeightLimit?: boolean\r\n\r\n /**\r\n * Set the popover max-width to be limited by the trigger button\r\n */\r\n hasButtonWidthLimit?: boolean\r\n\r\n /**\r\n * Can be used together with `hasViewportHeightLimit` to limit the height of the popover\r\n *\r\n * @default undefined\r\n */\r\n popoverMaxHeight?: number\r\n}\r\n\r\nexport function Popover({\r\n state,\r\n children,\r\n focusOnShow = true,\r\n focusOnHide = true,\r\n finalFocusRef,\r\n 'aria-label': ariaLabel,\r\n hide,\r\n hideOnClickOutside = true,\r\n hasArrow = false,\r\n hasBackdrop = true,\r\n onOverlayClick,\r\n popoverWrapperStyle,\r\n popoverMaxHeight = Number.MAX_SAFE_INTEGER,\r\n theme = 'light',\r\n hasViewportHeightLimit = false,\r\n hasButtonWidthLimit = false,\r\n ...props\r\n}: PopoverProps) {\r\n const zIndex = useZIndex()\r\n const { isFullyClosed } = getExtendedDialogState(state)\r\n const { innerHeight } = useWindowSize({ isWatching: !isFullyClosed })\r\n\r\n const buttonElement = state.unstable_referenceRef.current\r\n const maxHeightStyle = usePopoverMaxHeight({\r\n maxHeightLimit: popoverMaxHeight,\r\n hasViewportHeightLimit,\r\n offsets: state.offsets,\r\n state,\r\n })\r\n\r\n React.useEffect(() => {\r\n if (!buttonElement || !state.visible || !(hasViewportHeightLimit || hasButtonWidthLimit)) return\r\n\r\n const buttonRect = buttonElement.getBoundingClientRect()\r\n const popoverId = buttonElement.getAttribute('aria-controls')\r\n const popoverWrapper = popoverId ? document.getElementById(popoverId) : null\r\n\r\n // Limit popover max-width to be width of the trigger button\r\n if (hasButtonWidthLimit) {\r\n popoverWrapper?.style.setProperty('max-width', `${buttonRect.width}px`)\r\n }\r\n }, [\r\n state.visible,\r\n state.offsets,\r\n buttonElement,\r\n hasViewportHeightLimit,\r\n hasButtonWidthLimit,\r\n innerHeight,\r\n state.placement,\r\n popoverMaxHeight,\r\n ])\r\n\r\n if (isFullyClosed) return null\r\n\r\n return (\r\n \r\n \r\n {({ onTransitionEnd, onAnimationEnd, ...innerProps }) => (\r\n <>\r\n {\r\n // prevents from page scroll when clicked outside of popover\r\n event.preventDefault()\r\n }}\r\n />\r\n \r\n \r\n {hasArrow && (\r\n \r\n \r\n \r\n )}\r\n {children}\r\n \r\n \r\n \r\n )}\r\n \r\n \r\n )\r\n}\r\n","import * as React from 'react'\r\nimport * as Reakit from 'reakit/Popover'\r\n\r\nimport { COMPONENT_ANIMATION_DURATION } from '../constants'\r\n\r\nexport type PopoverStateReturn = ReturnType\r\n\r\nconst DEFAULT_OFFSET: [number, number] = [0, 5]\r\nconst HOVER_TIMEOUT = 150\r\n\r\nconst preventDefault = (ev: React.MouseEvent) => {\r\n ev.preventDefault()\r\n}\r\n\r\n/**\r\n * Hook which provides state to dialogs\r\n */\r\nexport function usePopoverState(settings?: Reakit.PopoverInitialState) {\r\n const offsets = (settings?.unstable_offset ?? DEFAULT_OFFSET) as [number, number]\r\n const popover = Reakit.usePopoverState({\r\n ...settings,\r\n placement: settings?.placement ?? 'bottom-start',\r\n unstable_offset: offsets,\r\n animated: COMPONENT_ANIMATION_DURATION,\r\n modal: false,\r\n })\r\n\r\n return { ...popover, offsets }\r\n}\r\n\r\nexport function useHoverPopover(settings?: Reakit.PopoverInitialState) {\r\n const popover = usePopoverState(settings)\r\n const showTimeout = React.useRef(null)\r\n const hideTimeout = React.useRef(null)\r\n\r\n const clearTimeouts = React.useRef(() => {\r\n if (showTimeout.current !== null) {\r\n window.clearTimeout(showTimeout.current)\r\n }\r\n if (hideTimeout.current !== null) {\r\n window.clearTimeout(hideTimeout.current)\r\n }\r\n })\r\n\r\n const showPopover = React.useRef(() => {\r\n clearTimeouts.current()\r\n showTimeout.current = window.setTimeout(() => {\r\n popover.show()\r\n }, HOVER_TIMEOUT)\r\n })\r\n\r\n const hidePopover = React.useRef(() => {\r\n clearTimeouts.current()\r\n hideTimeout.current = window.setTimeout(() => {\r\n popover.hide()\r\n }, HOVER_TIMEOUT)\r\n })\r\n\r\n // Unmount cleanup\r\n React.useEffect(() => () => clearTimeouts.current(), [])\r\n\r\n return {\r\n ...popover,\r\n show: showPopover.current,\r\n hide: hidePopover.current,\r\n onMouseOver: showPopover.current,\r\n onMouseOut: hidePopover.current,\r\n onMouseDown: preventDefault,\r\n }\r\n}\r\n","import classnames from 'classnames'\r\nimport * as React from 'react'\r\nimport * as Reakit from 'reakit/Popover'\r\n\r\nimport { useZIndex } from '../dialog'\r\n\r\ninterface PopoverButtonProps extends Reakit.PopoverDisclosureHTMLProps {\r\n state: Reakit.PopoverStateReturn\r\n as?: React.ElementType\r\n}\r\n/**\r\n * The trigger button component which handles ref & focus return, etc.\r\n */\r\nexport const PopoverTrigger = React.forwardRef(\r\n ({ state, ...props }: PopoverButtonProps, ref: React.ForwardedRef) => {\r\n const zIndex = useZIndex()\r\n\r\n return (\r\n \r\n {props.children}\r\n \r\n )\r\n }\r\n)\r\n","import * as React from 'react'\r\nimport { useNavigate } from 'react-router-dom'\r\n\r\nimport { SelectItem, SelectItemGroup } from './types'\r\nimport { flattenItems, isSelectItemGroup } from './utils'\r\n\r\ninterface NativeSelectProps extends Omit, 'onChange'> {\r\n items: ItemType[]\r\n onChange?: (item: ItemType) => void\r\n}\r\n\r\nexport function NativeSelect | SelectItem>({\r\n items,\r\n onChange,\r\n placeholder = 'Select value',\r\n ...props\r\n}: NativeSelectProps) {\r\n const showPlaceholder = props.value === -1\r\n const handleNativeSelectChange = React.useCallback(\r\n (e: React.ChangeEvent) => {\r\n const itemIndex = e.target.selectedIndex + (showPlaceholder ? -1 : 0)\r\n const selectedItem = flattenItems(items)[itemIndex] as SelectItem\r\n\r\n if (!selectedItem) return\r\n\r\n onChange?.(selectedItem as any)\r\n\r\n if (!selectedItem.href || !selectedItem.reloadDocument) {\r\n return\r\n }\r\n\r\n if (typeof selectedItem.href === 'string') {\r\n window.location.href = selectedItem.href\r\n return\r\n }\r\n\r\n const newUrl = new URL(selectedItem.href.pathname!, window.location.href)\r\n newUrl.search = selectedItem.href.search ?? ''\r\n newUrl.hash = selectedItem.href.hash ?? ''\r\n\r\n window.location.href = newUrl.toString()\r\n },\r\n [items, onChange, showPlaceholder]\r\n )\r\n\r\n return (\r\n \r\n {showPlaceholder && }\r\n {items.map((item, itemIndex) => {\r\n if (isSelectItemGroup(item)) {\r\n return (\r\n \r\n {item.items.map((option, optionIndex) => (\r\n \r\n ))}\r\n \r\n )\r\n }\r\n\r\n return (\r\n \r\n )\r\n })}\r\n \r\n )\r\n}\r\n\r\nexport function NativeSelectInRouterContext | SelectItem>(\r\n props: NativeSelectProps\r\n) {\r\n const navigate = useNavigate()\r\n\r\n const onChangeWithNavigate = React.useCallback(\r\n (item: SelectItem) => {\r\n props.onChange?.(item as any)\r\n\r\n if (item.href) navigate(item.href)\r\n },\r\n // We don’t need the whole props here, just onChange and items\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [navigate, props.onChange, props.items]\r\n )\r\n\r\n return \r\n}\r\n","import * as Ariakit from '@ariakit/react'\r\nimport classNames from 'classnames'\r\nimport * as React from 'react'\r\n\r\ninterface ItemsGroupProps extends Omit, 'ref' | 'label'> {\r\n /**\r\n * Group label\r\n */\r\n label?: string\r\n}\r\n\r\nexport const ItemsGroup = React.forwardRef(function ItemsGroup(\r\n { label, children, ...props }: React.PropsWithChildren,\r\n ref: React.ForwardedRef\r\n) {\r\n return (\r\n \r\n {label && {label}}\r\n {children}\r\n \r\n )\r\n})\r\n","import * as Ariakit from '@ariakit/react'\r\nimport classNames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { BUTTON_DEFAULT_ELEMENT, Button, ButtonComponentProps, ButtonPadding, ButtonThemeType } from '../button'\r\n\r\ninterface InternalOptionProps {\r\n /**\r\n * Description for the option\r\n */\r\n subtitle?: React.ReactNode\r\n\r\n /**\r\n * Set the button theme when it is selected\r\n */\r\n activeTheme?: ButtonThemeType\r\n\r\n /**\r\n * Set the base button theme when not selected\r\n */\r\n theme?: ButtonThemeType | ((isHovered: boolean) => ButtonThemeType)\r\n}\r\n\r\nfunction getDefaultTheme(isHovered: boolean) {\r\n return isHovered ? 'menuItem' : 'menuItemTransparent'\r\n}\r\n\r\nconst InternalOption = React.forwardRef(function InternalOption<\r\n TagType extends React.ElementType = typeof BUTTON_DEFAULT_ELEMENT,\r\n>(\r\n {\r\n subtitle,\r\n children,\r\n 'aria-selected': ariaSelected,\r\n 'data-active-item': dataActiveItem,\r\n rounding = 'small',\r\n activeTheme = 'blue',\r\n theme = getDefaultTheme,\r\n ...props\r\n }: Omit, 'theme'> & InternalOptionProps,\r\n ref: React.ForwardedRef\r\n) {\r\n const isSelected = ariaSelected === true\r\n const isHovered = dataActiveItem === true\r\n const defaultTheme = typeof theme === 'function' ? theme(isHovered) : theme\r\n\r\n return (\r\n )}\r\n ref={ref}\r\n align=\"left\"\r\n className={classNames(props.className, ButtonPadding.regular, 'select-none', {\r\n 'text-2xs': !!subtitle && !props.theme,\r\n })}\r\n contentClass={classNames(props.contentClass, 'font-normal')}\r\n rounding={rounding}\r\n active={props.active ?? (isHovered && !isSelected)}\r\n theme={isSelected ? activeTheme : defaultTheme}\r\n size={props.size ?? (subtitle ? 'none' : props.size)}\r\n aria-selected={ariaSelected}\r\n data-active-item={dataActiveItem}\r\n >\r\n {children}\r\n {subtitle && (\r\n \r\n {subtitle}\r\n \r\n )}\r\n \r\n )\r\n})\r\n\r\ninterface SelectOptionProps extends InternalOptionProps {\r\n value: ValueType\r\n}\r\n\r\nexport const SelectOption = React.forwardRef(function SelectOption<\r\n ValueType,\r\n TagType extends React.ElementType = typeof BUTTON_DEFAULT_ELEMENT,\r\n>(\r\n { as, ...props }: Omit, 'value' | 'theme'> & SelectOptionProps,\r\n ref: React.ForwardedRef\r\n) {\r\n const context = Ariakit.useSelectContext()!\r\n const isComboBox = !!context.combobox\r\n\r\n return (\r\n } /> : }\r\n />\r\n )\r\n})\r\n","import { SelectRenderer, SelectRendererItemProps } from '@ariakit/react-core/select/select-renderer'\r\nimport classNames from 'classnames'\r\nimport * as React from 'react'\r\nimport { useInRouterContext } from 'react-router-dom'\r\n\r\nimport { ButtonRoundingType } from '../button'\r\nimport { ItemsGroup } from './ItemsGroup'\r\nimport { SelectOption } from './SelectOption'\r\nimport { SelectItem, SelectItemGroup } from './types'\r\nimport { filterSelectOptions, getSelectItemProps, isSelectItem } from './utils'\r\n\r\nfunction getCollectionItem(item: SelectItem, index: number) {\r\n return {\r\n id: `item-${item.value}/${index}`,\r\n label: item.label,\r\n value: item,\r\n }\r\n}\r\n\r\ninterface SelectItemsVirtualizedProps {\r\n items: ItemType[]\r\n itemRenderer: (item: SelectItem, providedProps?: any) => React.ReactNode\r\n}\r\n\r\nfunction SelectItemsVirtualized | SelectItemGroup>(\r\n props: SelectItemsVirtualizedProps\r\n) {\r\n const listItems = React.useMemo(\r\n () =>\r\n props.items?.map((item, index) =>\r\n isSelectItem(item) ? getCollectionItem(item, index) : { ...item, items: item.items.map(getCollectionItem) }\r\n ) as ItemType[],\r\n [props.items]\r\n )\r\n const hasGroups = isSelectItem(listItems[0]) === false\r\n\r\n return (\r\n \r\n {({ value: groupOritem, index, label, ...restProps }: any) => {\r\n if (isSelectItem(groupOritem)) {\r\n return props.itemRenderer(groupOritem, { key: index, ...restProps })\r\n }\r\n\r\n return (\r\n (\r\n \r\n {rendererProps.children}\r\n \r\n )}\r\n >\r\n {({ value, index, ...restItem }: SelectRendererItemProps<{ value: SelectItem }>) =>\r\n props.itemRenderer(value, { key: index, ...restItem })\r\n }\r\n \r\n )\r\n }}\r\n \r\n )\r\n}\r\n\r\ninterface SelectItemsProps {\r\n searchValue: string\r\n items?: ItemType[]\r\n rounding?: ButtonRoundingType\r\n parentTestId?: string\r\n}\r\n\r\nexport function SelectItems | SelectItemGroup>({\r\n items,\r\n rounding,\r\n searchValue,\r\n parentTestId,\r\n virtualized,\r\n}: SelectItemsProps & { virtualized?: boolean }) {\r\n const isInRouterContext = useInRouterContext()\r\n const filteredItems = React.useMemo(() => filterSelectOptions(items, searchValue), [items, searchValue])\r\n\r\n const getItem = React.useCallback(\r\n (innerItem: SelectItem, providedProps?: any) => (\r\n \r\n {innerItem.label}\r\n \r\n ),\r\n [isInRouterContext, parentTestId, rounding, virtualized]\r\n )\r\n\r\n if (!filteredItems.length) {\r\n return
Nothing to select
\r\n }\r\n\r\n if (virtualized) {\r\n return \r\n }\r\n\r\n return (\r\n <>\r\n {filteredItems.map((item, index) => {\r\n if (isSelectItem(item)) {\r\n return getItem(item, { key: index })\r\n }\r\n\r\n return (\r\n \r\n {item.items.map((item, itemIndex) => getItem(item, { key: itemIndex }))}\r\n \r\n )\r\n })}\r\n \r\n )\r\n}\r\n","import * as Ariakit from '@ariakit/react'\r\nimport classNames from 'classnames'\r\nimport * as React from 'react'\r\nimport { Portal } from 'reakit'\r\n\r\nimport { Input } from '../input'\r\n\r\nenum ListRounding {\r\n none = '',\r\n regular = 'rounded-lg',\r\n}\r\n\r\nenum ListTheme {\r\n none = '',\r\n default = 'border border-primary bg-primary',\r\n}\r\n\r\nfunction focusWithoutScroll(element: HTMLElement | null) {\r\n element?.focus({ preventScroll: true })\r\n\r\n return !element\r\n}\r\n\r\nfunction onBackdropClick(ev: React.MouseEvent) {\r\n ev.preventDefault()\r\n}\r\n\r\nexport interface SelectListProps {\r\n /**\r\n * Internal prop which enables input at the top of the popover list\r\n */\r\n isComboBox?: boolean\r\n\r\n /**\r\n * Set rounding for the popover list\r\n *\r\n * @default regular\r\n */\r\n rounding?: keyof typeof ListRounding\r\n\r\n /**\r\n * Popover theme\r\n */\r\n theme?: keyof typeof ListTheme\r\n\r\n /**\r\n * The amount of space between button and its popover\r\n *\r\n * @default 4\r\n */\r\n gutter?: number\r\n\r\n /**\r\n * Change how the items are laid out\r\n *\r\n * @default vertical\r\n */\r\n orientation?: 'vertical' | 'horizontal'\r\n\r\n /**\r\n * Custom popover class\r\n */\r\n className?: string\r\n\r\n /**\r\n * Internal prop used to display no results when automatic `item` filtering doesn’t return any items\r\n */\r\n hasItemChildren?: boolean\r\n\r\n /**\r\n * Do not render the items when the popover is not visible\r\n *\r\n * @default false\r\n */\r\n unmountOnHide?: boolean\r\n}\r\n\r\nexport function SelectList({\r\n isComboBox,\r\n rounding = 'regular',\r\n theme = 'default',\r\n gutter = 4,\r\n orientation = 'vertical',\r\n className,\r\n unmountOnHide = false,\r\n hasItemChildren,\r\n children,\r\n}: React.PropsWithChildren) {\r\n const ListElement = React.useMemo(\r\n () => (isComboBox ? Ariakit.ComboboxList : (wrapperProps: any) =>
),\r\n [isComboBox]\r\n )\r\n const context = Ariakit.useSelectContext()!\r\n const placement = context.useState('currentPlacement')\r\n const hasChildren = hasItemChildren || React.Children.count(children) > 0\r\n\r\n return (\r\n // Temporary fix for modal reakit dialogs\r\n \r\n }\r\n className={classNames(\r\n className,\r\n ListRounding[rounding],\r\n ListTheme[theme],\r\n 'custom-scrollbar absolute z-dialog flex flex-col overflow-hidden shadow-modal outline-none dark:shadow-modal-dark',\r\n // These are set by popper, we just need to make sure we don’t encroach on the safe insets\r\n 'min-w-[--popover-anchor-width] max-w-[--popover-available-width]',\r\n // Animations\r\n 'opacity-0 transition duration-[250ms] data-[enter]:translate-y-0 data-[enter]:opacity-100',\r\n {\r\n // When in combobox mode, the padding is smaller so we can render a gradient under the combobox input.\r\n // Change the custom scrollbar offset so the top of the first item fits the top of our scrollbar\r\n '[--scrollbar-offset-top:theme(spacing.1)]': isComboBox,\r\n '[--scrollbar-radius:0]': ListRounding[rounding] === ListRounding.none,\r\n // Direction based styles\r\n 'max-h-[calc(var(--popover-available-height)-env(safe-area-inset-bottom))] -translate-y-1':\r\n placement.startsWith('bottom'),\r\n 'max-h-[calc(var(--popover-available-height)-env(safe-area-inset-top))] translate-y-1':\r\n placement.startsWith('top'),\r\n }\r\n )}\r\n >\r\n {isComboBox && (\r\n
\r\n
\r\n \r\n }\r\n />\r\n
\r\n
\r\n
\r\n )}\r\n \r\n {hasChildren ? children :
Nothing to select
}\r\n \r\n \r\n \r\n )\r\n}\r\n","import * as Ariakit from '@ariakit/react'\r\nimport * as React from 'react'\r\nimport { Portal } from 'reakit'\r\n\r\nimport { notifyOnVisibilityChange } from '../../../app/shared/documentVisibility'\r\nimport { TooltipArrow } from '../tooltip/tooltip-arrow'\r\nimport { TooltipBox } from '../tooltip/tooltip-box'\r\n\r\nfunction TooltipInner(props: any) {\r\n const tooltipContext = Ariakit.useTooltipContext()\r\n const currentPlacement = tooltipContext?.useState('currentPlacement') ?? 'auto'\r\n\r\n /**\r\n * Ignore focus re-trigger (do not show tooltip) when page visibility/focus state changes\r\n * - some browsers re-trigger focus on `activeElement` when document becomes visible\r\n */\r\n React.useEffect(() => {\r\n const subscription = notifyOnVisibilityChange((visible) => {\r\n if (!visible) tooltipContext?.hide()\r\n })\r\n return () => {\r\n subscription.unsubscribe()\r\n }\r\n // Changing this to `tooltip` dependency will run this effect on every render\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n return (\r\n // Temporary fix for modal reakit dialogs\r\n \r\n \r\n \r\n \r\n \r\n
\r\n }\r\n />\r\n {props.children}\r\n \r\n \r\n
\r\n )\r\n}\r\n\r\nexport function SelectTooltipWrapper({ content, children }: { content?: React.ReactNode; children: JSX.Element }) {\r\n const context = Ariakit.useSelectContext()\r\n const isPopoverOpen = context?.useState('open')\r\n const hasShownTooltip = React.useRef(false)\r\n\r\n React.useEffect(() => {\r\n if (isPopoverOpen) hasShownTooltip.current = true\r\n }, [isPopoverOpen])\r\n\r\n if (!content) return null\r\n\r\n return (\r\n \r\n {\r\n // Do not open again unless user focuses the button again (or presses another ESC)\r\n if (hasShownTooltip.current) ev.preventDefault()\r\n hasShownTooltip.current = false\r\n }}\r\n />\r\n {content}\r\n \r\n )\r\n}\r\n","import * as Ariakit from '@ariakit/react'\r\nimport { Placement } from '@popperjs/core'\r\nimport * as React from 'react'\r\n\r\nimport { SelectButtonProps } from './SelectButton'\r\nimport { SelectItems } from './SelectItems'\r\nimport { SelectList, SelectListProps } from './SelectList'\r\nimport { SelectTooltipWrapper } from './SelectTooltipWrapper'\r\nimport { SelectItem, SelectItemGroup } from './types'\r\n\r\nexport interface DesktopSelectProps\r\n extends Omit<\r\n SelectButtonProps,\r\n // Fix clash with `button` element html props\r\n 'value' | 'defaultValue' | 'onChange' | 'label' | 'name' | 'valueOverride'\r\n >,\r\n Pick {\r\n /**\r\n * Name of the select which coudl be used to distinguish onChange events.\r\n * Passed as 2nd argument to `onChange`\r\n */\r\n name?: Name\r\n\r\n /**\r\n * Set value for the select\r\n */\r\n value?: ValueType\r\n\r\n /**\r\n * Set default value for an uncontrolled select\r\n */\r\n defaultValue?: ValueType\r\n\r\n /**\r\n * Label to display above the select\r\n */\r\n label?: React.ReactNode\r\n\r\n /**\r\n * Callback when item changes. Called for both controlled and uncontrolled selects\r\n */\r\n onChange?: (\r\n item: ItemType extends SelectItemGroup\r\n ? ValueType extends SelectItem\r\n ? ValueType\r\n : SelectItem\r\n : ItemType,\r\n name: Name\r\n ) => void\r\n\r\n /**\r\n * Options to select from. When defined, the options are constructed automatically\r\n * so you don’t have to pass children to the select.\r\n *\r\n * When `nativeSelect` is set to \"mobile\", children take precedence on desktop\r\n */\r\n items?: ItemType[]\r\n\r\n /**\r\n * Enable virtualization of select items to improve performance of long lists\r\n *\r\n * @default items.length > 50\r\n */\r\n virtualized?: boolean\r\n\r\n /**\r\n * Custom button renderer for the select\r\n */\r\n trigger?: JSX.Element\r\n\r\n /**\r\n * Text for the button (usually the selected value). Falls back to placeholder if not set\r\n */\r\n triggerContent?: React.ReactNode\r\n\r\n /**\r\n * Show tooltip on the select\r\n */\r\n tooltip?: React.ReactNode\r\n\r\n /**\r\n * Popover placement\r\n *\r\n * @default \"bottom-start\"\r\n */\r\n placement?: Placement\r\n\r\n /**\r\n * Change the direction of the items placement in popover\r\n *\r\n * @default vertical\r\n */\r\n orientation?: 'vertical' | 'horizontal'\r\n\r\n /**\r\n * Set whether or not the Select is interactive to save resources. If not interactive,\r\n * the select only renders a placeholder button\r\n *\r\n * @default true\r\n */\r\n isInteractive?: boolean\r\n\r\n /**\r\n * Callback when the select opens or closes\r\n */\r\n onInteractionChange?: (open: boolean) => void\r\n\r\n /**\r\n * ### Only applicable for desktop selects without `children`, when passing `items`.\r\n * ### If you want to pass `children`, use the `onSearch` prop instead.\r\n *\r\n * Specifies whether or not to show a search input inside of the popover. Number\r\n * specifies the >= number of items after which search will be visible.\r\n * Search is made for both value and label props\r\n *\r\n * @default 10\r\n */\r\n comboBox?: boolean | number\r\n\r\n /**\r\n * ### Only applicable for desktop selects with `children`.\r\n * ### Use `comboBox` if you have `items` prop\r\n * When defined, the select is considered being a combobox and will display\r\n * input for filtering items. The filtering is up to the user.\r\n */\r\n onSearch?: (value: string) => void\r\n\r\n /**\r\n * When combined with `items` the children will automatically have testid assigned.\r\n * Otherwise just passed to the trigger button\r\n */\r\n 'data-testid'?: string\r\n\r\n listProps?: SelectListProps\r\n}\r\n\r\nexport function DesktopSelect<\r\n ValueType,\r\n ItemType extends SelectItem | SelectItemGroup,\r\n Name = never,\r\n>({\r\n name,\r\n label,\r\n value,\r\n defaultValue,\r\n onChange,\r\n items,\r\n virtualized = (items?.length ?? 0) > 50,\r\n trigger,\r\n tooltip,\r\n onInteractionChange,\r\n comboBox,\r\n onSearch,\r\n children,\r\n gutter,\r\n placement = 'bottom-start',\r\n orientation,\r\n listProps,\r\n ...props\r\n}: React.PropsWithChildren>) {\r\n // Used when `items` are passed to construct a desktop select with comboBox\r\n const [internalSearch, setInternalSearch] = React.useState('')\r\n\r\n // Setup combobox if enabled\r\n const isComboBox =\r\n !!onSearch || comboBox === true || (typeof comboBox === 'number' && !!items && items.length > comboBox)\r\n const SelectWrapper = isComboBox ? Ariakit.ComboboxProvider : React.Fragment\r\n const wrapperProps = React.useMemo(\r\n () =>\r\n isComboBox ? { resetValueOnHide: true, includesBaseElement: false, setValue: onSearch ?? setInternalSearch } : {},\r\n [isComboBox, onSearch]\r\n )\r\n\r\n // Handle tooltip prop\r\n const ButtonWrapper = tooltip ? SelectTooltipWrapper : React.Fragment\r\n const buttonWrapperProps = React.useMemo(() => (tooltip ? { content: tooltip } : {}), [tooltip])\r\n\r\n if (isComboBox && !!children && !onSearch) {\r\n console.warn(\r\n 'ComboBoxes with children options require `onSearch` prop, otherwise searching will not work. \\n Either provide `onSearch` or disable this behavior by passing `comboBox={false}`'\r\n )\r\n }\r\n\r\n return (\r\n \r\n {/* @ts-expect-error - The types are wrong here, the select allows any values, not just strings or ints */}\r\n \r\n // Loop to the first item after pressing arrow down on last item\r\n focusLoop\r\n virtualFocus\r\n value={value}\r\n defaultValue={defaultValue ?? ''}\r\n // Item will always be of ItemType\r\n setValue={(item) => setTimeout(() => onChange?.(item as any, name!), 50)}\r\n setOpen={onInteractionChange}\r\n placement={placement}\r\n orientation={orientation}\r\n >\r\n {label && {label}}\r\n\r\n \r\n \r\n \r\n\r\n \r\n {/* Either construct options from children or provided items prop */}\r\n {children ?? (\r\n \r\n )}\r\n \r\n \r\n \r\n )\r\n}\r\n","import * as Ariakit from '@ariakit/react'\r\nimport classNames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { Button, ButtonHTMLProps, ButtonProps, ButtonSize } from '../button'\r\nimport { Delayed } from '../delayed'\r\nimport { Icon, IconNameType, isValidIconName } from '../icon'\r\nimport { Spinner } from '../spinner'\r\nimport { SelectItem } from './types'\r\nimport { isSelectItem } from './utils'\r\n\r\ntype ValueType = SelectItem | string\r\n\r\nconst DEFAULT_RIGHT_ICON = 'caretDown'\r\n\r\nexport interface SelectButtonProps extends Omit, Omit {\r\n /**\r\n * Show a spinner in place of the button caret. The spinner is wrapped in Delayed\r\n * and uses the default timeout\r\n */\r\n isLoading?: boolean\r\n\r\n /**\r\n * Placeholder when no value is selected\r\n */\r\n placeholder?: string\r\n\r\n /**\r\n * Override for the select value from context. Used to provide value for native\r\n * select trigger\r\n */\r\n valueOverride?: ValueType\r\n\r\n rightContent?: boolean | IconNameType | JSX.Element\r\n}\r\n\r\nexport const SelectButton = React.forwardRef>(\r\n function SelectButton(\r\n {\r\n isLoading,\r\n placeholder = 'Select value',\r\n children,\r\n valueOverride,\r\n theme = 'outline',\r\n rightContent = DEFAULT_RIGHT_ICON,\r\n ...props\r\n },\r\n ref\r\n ) {\r\n const context = Ariakit.useSelectContext()\r\n const contextValue = context?.useState('value') as ValueType\r\n const isOpen = context?.useState('open')\r\n const selectedValue = valueOverride ?? contextValue\r\n\r\n let buttonText = placeholder\r\n if (isSelectItem(selectedValue)) buttonText = selectedValue.label ?? selectedValue.value\r\n else if (typeof selectedValue === 'string' && selectedValue.length) buttonText = selectedValue\r\n else if (selectedValue) buttonText = String(selectedValue)\r\n\r\n const rightIcon =\r\n isValidIconName(rightContent) || rightContent === true ? (\r\n \r\n ) : React.isValidElement(rightContent) ? (\r\n rightContent\r\n ) : undefined\r\n\r\n return (\r\n \r\n \r\n \r\n ) : (\r\n rightIcon\r\n )\r\n }\r\n >\r\n {children ?? buttonText}\r\n \r\n )\r\n }\r\n)\r\n","import * as React from 'react'\r\nimport { useInRouterContext } from 'react-router-dom'\r\n\r\nimport { isMobile } from '../../../app/shared/isMobile'\r\nimport { DesktopSelect, DesktopSelectProps } from './DesktopSelect'\r\nimport { NativeSelect, NativeSelectInRouterContext } from './NativeSelect'\r\nimport { SelectButton } from './SelectButton'\r\nimport { SelectItem } from './types'\r\nimport { findSelectedIndex, findSelectedValue } from './utils'\r\n\r\nconst isMobileDevice = isMobile()\r\n\r\nexport interface SelectProps extends DesktopSelectProps {\r\n /**\r\n * Whether or not to show a native select when clicking the button.\r\n * When rendering native select, you must provide `items`, `value` and `onChange`\r\n *\r\n * @default false\r\n */\r\n nativeSelect?: boolean | 'mobile'\r\n}\r\n\r\nexport function Select({\r\n name,\r\n label,\r\n value: providedValue,\r\n defaultValue: providedDefaultValue,\r\n onChange,\r\n items,\r\n trigger,\r\n gutter,\r\n orientation,\r\n triggerContent,\r\n isInteractive = true,\r\n onInteractionChange,\r\n nativeSelect = false,\r\n comboBox = 10,\r\n onSearch,\r\n 'data-testid': dataTestid,\r\n listProps,\r\n virtualized,\r\n ...props\r\n}: React.PropsWithChildren>) {\r\n // Used by native select to handle navigation for link items\r\n const isInRouterContext = useInRouterContext()\r\n // Let users either provide the selected item or its value. Items can also be grouped so we need to find the correct value\r\n const value = findSelectedValue(items, providedValue) ?? providedValue\r\n const defaultValue = findSelectedValue(items, providedDefaultValue) ?? providedDefaultValue\r\n\r\n // Extracted trigger to a variable because it is used in every branch\r\n const selectTrigger = trigger ?? (\r\n ) : undefined}\r\n data-testid={dataTestid}\r\n >\r\n {triggerContent}\r\n \r\n )\r\n\r\n // Save some resources by rendering the trigger only\r\n if (!isInteractive) {\r\n return selectTrigger\r\n }\r\n\r\n const renderNativeSelect = nativeSelect === true || (nativeSelect === 'mobile' && isMobileDevice)\r\n if (renderNativeSelect) {\r\n const NativeSelectComponent = isInRouterContext ? NativeSelectInRouterContext : NativeSelect\r\n const selectedIndex = findSelectedIndex(items, providedValue ?? providedDefaultValue)\r\n\r\n return (\r\n
\r\n {selectTrigger}\r\n
\r\n )\r\n }\r\n\r\n return (\r\n \r\n )\r\n}\r\n","import { Link } from 'react-router-dom'\r\n\r\nimport { SelectItem, SelectItemGroup } from './types'\r\n\r\nexport function getSelectItemProps(item: SelectItem, inRouterContext?: boolean) {\r\n if (item.href) {\r\n if (inRouterContext) return { as: Link, to: item.href, reloadDocument: item.reloadDocument }\r\n else return { as: 'a', href: item.href }\r\n }\r\n\r\n return {}\r\n}\r\n\r\nexport function isSelectItem(item: unknown): item is SelectItem {\r\n return !!(item?.hasOwnProperty('label') && item?.hasOwnProperty('value')) && !item?.hasOwnProperty('items')\r\n}\r\n\r\nexport function isSelectItemGroup(item: unknown): item is SelectItemGroup {\r\n return !!item?.hasOwnProperty('items')\r\n}\r\n\r\nfunction matchesSearchTerm(item: SelectItem, searchTerm: string) {\r\n const lowerSearch = searchTerm.toLowerCase()\r\n\r\n return (\r\n (typeof item.value === 'string' && item.value.toLowerCase().includes(lowerSearch)) ||\r\n item.label.toLowerCase().includes(lowerSearch)\r\n )\r\n}\r\n\r\nfunction isSameItem(obj1: unknown, obj2?: unknown) {\r\n if (isSelectItem(obj1) && isSelectItem(obj2)) return obj1.value === obj2.value\r\n else if (isSelectItem(obj1)) return obj1.value === obj2\r\n return obj1 === obj2\r\n}\r\n\r\n/**\r\n * Used in combobox to find matching items\r\n */\r\nexport function filterSelectOptions | SelectItemGroup>(\r\n items: ItemType[] | undefined,\r\n searchTerm: string\r\n) {\r\n const finalResults: ItemType[] = []\r\n\r\n items?.forEach((item) => {\r\n if (isSelectItemGroup(item)) {\r\n const filtered = item.items.filter((option) => matchesSearchTerm(option, searchTerm))\r\n if (filtered.length) finalResults.push({ ...item, items: filtered })\r\n } else if (matchesSearchTerm(item, searchTerm)) {\r\n finalResults.push(item)\r\n }\r\n })\r\n\r\n return finalResults\r\n}\r\n\r\n/**\r\n * Used in select to allow users to pass any kind of valid value\r\n */\r\nexport function findSelectedValue(\r\n items: ItemType[] = [],\r\n value?: ValueType | SelectItem\r\n) {\r\n for (const item of items) {\r\n if (isSelectItemGroup(item)) {\r\n const foundItem = item.items.find((option) => isSameItem(option, value)) as SelectItem\r\n if (foundItem) return foundItem\r\n } else if (isSameItem(item, value)) {\r\n return item as SelectItem\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Used for native selects to match against user provided value\r\n */\r\nexport function findSelectedIndex(\r\n items: ItemType[] = [],\r\n value?: ValueType | SelectItem\r\n) {\r\n for (let index = 0; index < items.length; index++) {\r\n const item = items[index]\r\n\r\n if (isSelectItemGroup(item)) {\r\n const itemIndex = item.items.findIndex((option) => isSameItem(option, value))\r\n if (itemIndex > -1) return `${index}${itemIndex}`\r\n } else if (isSameItem(item, value)) {\r\n return index\r\n }\r\n }\r\n\r\n return -1\r\n}\r\n\r\nexport function flattenItems(items: ItemType[]) {\r\n return items.flatMap((itemOrGroup) =>\r\n isSelectItemGroup(itemOrGroup) ? (itemOrGroup.items as ItemType[]) : itemOrGroup\r\n )\r\n}\r\n","import * as React from 'react'\r\nimport { Link, To } from 'react-router-dom'\r\n\r\nimport { TIMEFRAME } from '../../constants'\r\nimport { ButtonRoundingType, ButtonSizeType } from '../button'\r\nimport { DropdownSeparator } from '../dropdown'\r\nimport { Icon } from '../icon'\r\nimport { Select, SelectOption } from '../select'\r\nimport { SelectItem } from '../select/types'\r\n\r\nexport interface DateRangeBaseOption extends SelectItem {\r\n timeframe?: TIMEFRAME\r\n href?: To\r\n withReload?: boolean\r\n}\r\n\r\ninterface Props {\r\n chartIndex: number\r\n dateRangeGroups: Array<{ label?: string; dateRanges: DateRange[] }>\r\n selectedDateRange: string | null\r\n onDateRangeSelect: (value: DateRange) => void\r\n rounding?: ButtonRoundingType\r\n size?: ButtonSizeType\r\n}\r\n\r\nconst DATERANGE_TOOLTIP = 'Range'\r\n\r\nexport function DateRangeSelect({\r\n size,\r\n chartIndex,\r\n dateRangeGroups,\r\n selectedDateRange,\r\n onDateRangeSelect,\r\n rounding,\r\n}: Props) {\r\n const flatDateRanges = React.useMemo(() => dateRangeGroups.flatMap(({ dateRanges }) => dateRanges), [dateRangeGroups])\r\n\r\n return (\r\n {\r\n onDateRangeSelect(flatDateRanges.find((item) => item.value === value)!)\r\n }}\r\n rounding={rounding}\r\n appearance=\"square\"\r\n theme=\"chip\"\r\n size={size}\r\n triggerContent={}\r\n rightContent={false}\r\n active={selectedDateRange ? true : undefined}\r\n data-testid={`chart-${chartIndex}-date-range-select`}\r\n >\r\n {dateRangeGroups.flatMap(({ label, dateRanges }, index) => [\r\n {label},\r\n ...dateRanges.map(({ href, value, label, withReload }) => {\r\n let linkProps = {}\r\n if (href) {\r\n linkProps = {\r\n as: Link,\r\n to: href,\r\n reloadDocument: withReload ?? !FinvizSettings.hasUserPremium,\r\n }\r\n }\r\n return (\r\n \r\n {label}\r\n \r\n )\r\n }),\r\n ])}\r\n \r\n )\r\n}\r\n","import classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { Delayed } from '../delayed'\r\nimport { Spinner } from '../spinner'\r\n\r\ninterface Props {\r\n label: React.ReactNode\r\n isLoading: boolean\r\n}\r\n\r\nexport function LabelWithDelayedSpinner({ label, isLoading }: Props) {\r\n return (\r\n <>\r\n {label}\r\n {isLoading && (\r\n
\r\n {label}}>\r\n \r\n \r\n
\r\n )}\r\n \r\n )\r\n}\r\n","import classNames from 'classnames'\r\nimport * as React from 'react'\r\nimport { Link, To } from 'react-router-dom'\r\n\r\nimport { Button, ButtonProps, ButtonRoundingType, ButtonSizeType } from '../button'\r\nimport { DropdownSeparator } from '../dropdown'\r\nimport { Icon } from '../icon'\r\nimport { SelectItem } from '../select'\r\nimport { Select, SelectOption } from '../select'\r\nimport { LabelWithDelayedSpinner } from './label-with-delayed-spinner'\r\n\r\nexport type TimeframeBaseOption = SelectItem & {\r\n labelShort?: string\r\n labelPageTitle?: string\r\n href?: To\r\n withReload?: boolean\r\n}\r\n\r\ninterface Props {\r\n chartIndex: number\r\n isCompactView: boolean\r\n isCompactOnly: boolean\r\n timeFrameGroups: Array<{ label: string; timeframes: TimeFrame[] }>\r\n selectedTimeframe: string\r\n onTimeframeSelect: (value: TimeFrame) => void\r\n favoriteTimeframes: string[]\r\n onFavoriteTimeframeToggle: (value: TimeFrame) => void\r\n rounding?: ButtonRoundingType\r\n size?: ButtonSizeType\r\n isLoading?: boolean\r\n isFavoritesEnabled: boolean\r\n theme?: ButtonProps['theme']\r\n}\r\n\r\nconst TIMEFRAME_TOOLTIP = 'Interval'\r\n\r\nexport function TimeframeSelect({\r\n size,\r\n chartIndex,\r\n timeFrameGroups,\r\n selectedTimeframe,\r\n favoriteTimeframes,\r\n isLoading = false,\r\n isCompactView,\r\n isCompactOnly,\r\n onTimeframeSelect,\r\n onFavoriteTimeframeToggle,\r\n rounding,\r\n isFavoritesEnabled,\r\n theme = 'chip',\r\n}: Props) {\r\n const flatTimeframes = React.useMemo(() => timeFrameGroups.flatMap(({ timeframes }) => timeframes), [timeFrameGroups])\r\n\r\n const getSelectedTimeframeLabel = React.useCallback(() => {\r\n if (isCompactView) {\r\n const selectedTimeframeItem = flatTimeframes.find(({ value }) => value === selectedTimeframe)\r\n return selectedTimeframeItem?.labelShort ?? selectedTimeframeItem?.label\r\n }\r\n return ''\r\n }, [flatTimeframes, isCompactView, selectedTimeframe])\r\n\r\n return (\r\n item.value === selectedTimeframe)}\r\n leftContent={\r\n
\r\n } isLoading={isLoading && isCompactView} />\r\n
\r\n }\r\n onChange={(item) => onTimeframeSelect(item as TimeFrame)}\r\n data-testid={`chart-${chartIndex}-timeframe-select`}\r\n >\r\n {timeFrameGroups.flatMap(({ timeframes }, groupIndex) => [\r\n ,\r\n ...timeframes.map((item) => {\r\n const isIconButtonActive = favoriteTimeframes.includes(item.value)\r\n let linkProps = {}\r\n if (item.href) {\r\n linkProps = {\r\n as: Link,\r\n to: item.href,\r\n reloadDocument: !!item.withReload,\r\n }\r\n }\r\n return (\r\n ) => {\r\n ev.stopPropagation()\r\n ev.preventDefault()\r\n onFavoriteTimeframeToggle(item)\r\n }}\r\n className={classNames('group -mr-2', {\r\n 'text-gray-300': !isIconButtonActive,\r\n 'text-yellow-200': isIconButtonActive,\r\n })}\r\n >\r\n \r\n \r\n \r\n ) : undefined\r\n }\r\n >\r\n {item.label}\r\n \r\n )\r\n }),\r\n ])}\r\n \r\n )\r\n}\r\n","import classnames from 'classnames'\r\nimport * as React from 'react'\r\nimport { Link } from 'react-router-dom'\r\n\r\nimport { useElementMeasure } from '../../hooks/use-element-measure'\r\nimport { Button, ButtonPadding, ButtonProps, ButtonRoundingType, ButtonSize, ButtonSizeType } from '../button'\r\nimport { DateRangeBaseOption, DateRangeSelect } from './daterange-select'\r\nimport { LabelWithDelayedSpinner } from './label-with-delayed-spinner'\r\nimport { TimeframeBaseOption, TimeframeSelect } from './timeframe-select'\r\n\r\ninterface Props {\r\n isPremium?: boolean\r\n chartIndex?: number\r\n compactViewMaxBreakpointPx?: number\r\n timeFrameGroups: Array<{ label: string; timeframes: TimeFrame[] }>\r\n dateRangeGroups: Array<{ label?: string; dateRanges: DateRange[] }>\r\n selectedTimeframe: string\r\n selectedDateRange: string | null\r\n onTimeframeSelect: (value: TimeFrame) => void\r\n onDateRangeSelect: (value: DateRange) => void\r\n favoriteTimeframes: string[]\r\n onFavoriteTimeframeToggle: (value: TimeFrame) => void\r\n size?: ButtonSizeType\r\n loadingTimeframe?: string\r\n rounding?: ButtonRoundingType\r\n isDateRangeAvailable?: boolean\r\n containerElement?: HTMLElement\r\n className?: string\r\n isFavoritesEnabled?: boolean\r\n isScrollIntoViewEnabled?: boolean\r\n isTimeframeSelectEnabled?: boolean\r\n isCompactOnly?: boolean\r\n theme?: ButtonProps['theme']\r\n}\r\n\r\nfunction getTimeframeChipElementId({ timeframe, chartIndex }: { timeframe: string; chartIndex: number }) {\r\n return `${chartIndex}-${timeframe}`\r\n}\r\n\r\nfunction getButtonPadding(size: ButtonSize): keyof typeof ButtonPadding {\r\n switch (size) {\r\n case ButtonSize.xxsmall:\r\n case ButtonSize.xsmall:\r\n case ButtonSize.small:\r\n case ButtonSize.regular:\r\n return 'small'\r\n case ButtonSize.medium:\r\n return 'regular'\r\n case ButtonSize.large:\r\n return 'medium'\r\n case ButtonSize.none:\r\n return 'none'\r\n }\r\n}\r\n\r\nexport function TimeframeBar({\r\n isPremium = FinvizSettings.hasUserPremium,\r\n chartIndex = 0,\r\n compactViewMaxBreakpointPx = 400,\r\n timeFrameGroups,\r\n dateRangeGroups,\r\n selectedTimeframe,\r\n selectedDateRange,\r\n favoriteTimeframes,\r\n loadingTimeframe,\r\n onTimeframeSelect,\r\n onDateRangeSelect,\r\n onFavoriteTimeframeToggle,\r\n size,\r\n rounding,\r\n isDateRangeAvailable = true,\r\n containerElement,\r\n className,\r\n isFavoritesEnabled = true,\r\n isScrollIntoViewEnabled = true,\r\n isTimeframeSelectEnabled,\r\n isCompactOnly = false,\r\n theme,\r\n}: Props) {\r\n const [scrollWrapperElement, setScrollWrapperElement] = React.useState(null)\r\n const [timeframeButtonsScrollLocation, setTimeframeButtonsScrollLocation] = React.useState({\r\n isOnLeftEdge: true,\r\n isOnRightEdge: true,\r\n })\r\n const { setElementRef, elementWidth } = useElementMeasure(containerElement)\r\n const flatTimeframes = React.useMemo(() => timeFrameGroups.flatMap(({ timeframes }) => timeframes), [timeFrameGroups])\r\n\r\n const timeframesInExpandedPanel = React.useMemo(\r\n () =>\r\n isFavoritesEnabled\r\n ? flatTimeframes.filter(({ value }) => value === selectedTimeframe || favoriteTimeframes.includes(value))\r\n : flatTimeframes,\r\n [flatTimeframes, selectedTimeframe, favoriteTimeframes, isFavoritesEnabled]\r\n )\r\n\r\n const isCompactView =\r\n isCompactOnly || elementWidth < compactViewMaxBreakpointPx || timeframesInExpandedPanel.length <= 1\r\n const checkTimeframeWrapperScrollPosition = React.useCallback(() => {\r\n if (scrollWrapperElement) {\r\n const isOnLeftEdge = scrollWrapperElement.scrollLeft === 0\r\n const isOnRightEdge =\r\n Math.ceil(scrollWrapperElement.offsetWidth + scrollWrapperElement.scrollLeft) >=\r\n scrollWrapperElement.scrollWidth\r\n\r\n if (\r\n timeframeButtonsScrollLocation.isOnLeftEdge !== isOnLeftEdge ||\r\n timeframeButtonsScrollLocation.isOnRightEdge !== isOnRightEdge\r\n ) {\r\n setTimeframeButtonsScrollLocation({ isOnLeftEdge, isOnRightEdge })\r\n }\r\n }\r\n }, [timeframeButtonsScrollLocation, scrollWrapperElement])\r\n\r\n React.useEffect(() => {\r\n checkTimeframeWrapperScrollPosition()\r\n }, [checkTimeframeWrapperScrollPosition, scrollWrapperElement, elementWidth])\r\n\r\n React.useEffect(() => {\r\n if (!isCompactView && isScrollIntoViewEnabled) {\r\n const timeframeElement = document.getElementById(\r\n getTimeframeChipElementId({ chartIndex, timeframe: selectedTimeframe })\r\n )\r\n\r\n if (timeframeElement && scrollWrapperElement) {\r\n const leftOffset =\r\n timeframeElement.offsetLeft + timeframeElement.clientWidth / 2 - scrollWrapperElement.clientWidth / 2\r\n\r\n scrollWrapperElement.scrollTo(Math.max(0, Math.min(leftOffset, scrollWrapperElement.scrollWidth)), 0)\r\n }\r\n }\r\n }, [isCompactView, chartIndex, selectedTimeframe, elementWidth, isScrollIntoViewEnabled, scrollWrapperElement])\r\n\r\n return (\r\n \r\n {(isTimeframeSelectEnabled ?? isFavoritesEnabled) && (\r\n
\r\n \r\n
\r\n )}\r\n {!isCompactView && (\r\n
\r\n \r\n {\r\n /*\r\n * Vertical scrolling doesn't scroll horizontally by default (it's possible when holding shift)\r\n * When using touchpad we may get values in both delatX and deltaY, so if someone's scrolling horizontally we don't want to do anything\r\n * but if they are scrolling vertically (deltaY > deltaX) we want to scroll horizontally the value they would nativally scroll in vertical direction\r\n * */\r\n const absDx = Math.abs(event.deltaX)\r\n const absDy = Math.abs(event.deltaY)\r\n if (absDy > absDx) {\r\n event.currentTarget.scrollLeft += event.deltaY\r\n }\r\n }}\r\n >\r\n {timeframesInExpandedPanel.map((timeframe) => {\r\n let linkProps = {}\r\n if (timeframe.href) {\r\n linkProps = {\r\n as: Link,\r\n to: timeframe.href,\r\n reloadDocument: timeframe.withReload ?? !isPremium,\r\n onClick: () => onTimeframeSelect(timeframe),\r\n }\r\n } else {\r\n linkProps = {\r\n onClick: (ev: React.MouseEvent) => {\r\n ev.preventDefault()\r\n onTimeframeSelect(timeframe)\r\n },\r\n }\r\n }\r\n return (\r\n \r\n \r\n \r\n )\r\n })}\r\n
\r\n \r\n
\r\n )}\r\n {isDateRangeAvailable && (\r\n
\r\n \r\n
\r\n )}\r\n \r\n )\r\n}\r\n","import { type To } from 'react-router-dom'\r\n\r\nimport { decodeQueryString, encodeQueryString } from '../../../app/queryString'\r\nimport { SpecificChartFunctionality, TIMEFRAME } from '../../constants'\r\nimport { DateRangeType, Instrument } from '../../types'\r\nimport { CUSTOM_DATE_RANGE, CustomDateRangePrefixEnum, DATE_RANGE_PREFIX_DELMITER } from './custom-date-range-utils'\r\n\r\ninterface ITimeFrame {\r\n value: TIMEFRAME | 'intraday'\r\n label: string\r\n labelShort: string\r\n labelPageTitle?: string\r\n}\r\n\r\nexport interface ITimeframeGroup {\r\n label: string\r\n timeframes: ITimeFrame[]\r\n}\r\n\r\ninterface IDateRange {\r\n value: string\r\n label: string\r\n timeframe?: TIMEFRAME\r\n}\r\n\r\nexport interface IRangeGroup {\r\n label?: string\r\n dateRanges: IDateRange[]\r\n}\r\n\r\nexport const generateTimeframeGroups = (isPremium = true): ITimeframeGroup[] => {\r\n const premiumTimeframes: ITimeframeGroup[] = [\r\n {\r\n label: '',\r\n timeframes: [\r\n { value: TIMEFRAME.i1, label: '1 Minute', labelShort: '1M' },\r\n { value: TIMEFRAME.i2, label: '2 Minutes', labelShort: '2M' },\r\n { value: TIMEFRAME.i3, label: '3 Minutes', labelShort: '3M' },\r\n { value: TIMEFRAME.i5, label: '5 Minutes', labelShort: '5M' },\r\n { value: TIMEFRAME.i10, label: '10 Minutes', labelShort: '10M' },\r\n { value: TIMEFRAME.i15, label: '15 Minutes', labelShort: '15M' },\r\n { value: TIMEFRAME.i30, label: '30 Minutes', labelShort: '30M' },\r\n ],\r\n },\r\n {\r\n label: '',\r\n timeframes: [\r\n { value: TIMEFRAME.h, label: '1 Hour', labelShort: '1H', labelPageTitle: 'Hourly' },\r\n { value: TIMEFRAME.h2, label: '2 Hours', labelShort: '2H' },\r\n { value: TIMEFRAME.h4, label: '4 Hours', labelShort: '4H' },\r\n ],\r\n },\r\n {\r\n label: '',\r\n timeframes: [\r\n { value: TIMEFRAME.d, label: '1 Day', labelShort: 'D', labelPageTitle: 'Daily' },\r\n { value: TIMEFRAME.w, label: '1 Week', labelShort: 'W', labelPageTitle: 'Weekly' },\r\n { value: TIMEFRAME.m, label: '1 Month', labelShort: 'M', labelPageTitle: 'Monthly' },\r\n ],\r\n },\r\n ]\r\n\r\n const freeTimeframes = [\r\n {\r\n // intradayTimeframe is only for non premium users used as redirect to elite subscription\r\n label: '',\r\n timeframes: [{ value: 'intraday' as const, label: 'Intraday', labelShort: 'Intraday' }],\r\n },\r\n {\r\n label: '',\r\n timeframes: [\r\n { value: TIMEFRAME.d, label: '1 Day', labelShort: 'Daily' },\r\n { value: TIMEFRAME.w, label: '1 Week', labelShort: 'Weekly' },\r\n { value: TIMEFRAME.m, label: '1 Month', labelShort: 'Monthly' },\r\n ],\r\n },\r\n ]\r\n\r\n return isPremium ? premiumTimeframes : freeTimeframes\r\n}\r\n\r\nexport function getTimeframeGroups(isPremium: boolean) {\r\n return generateTimeframeGroups(isPremium)\r\n}\r\n\r\nexport const generateDateRangeGroups = ({\r\n isPremium,\r\n instrument,\r\n}: {\r\n isPremium: boolean\r\n instrument: Instrument\r\n}): IRangeGroup[] => {\r\n const isStock = instrument === Instrument.Stock\r\n const rangeGroups: Array<{ label?: string; dateRanges: IDateRange[] }> = [\r\n {\r\n label: 'Days',\r\n dateRanges: [\r\n { value: DateRangeType.d1, label: '1 Day', timeframe: isStock ? TIMEFRAME.i1 : TIMEFRAME.i5 },\r\n { value: DateRangeType.d5, label: '5 Days', timeframe: isStock ? TIMEFRAME.i5 : TIMEFRAME.i30 },\r\n ],\r\n },\r\n {\r\n label: 'Months',\r\n dateRanges: [\r\n { value: DateRangeType.m1, label: '1 Month', timeframe: TIMEFRAME.d },\r\n { value: DateRangeType.m3, label: '3 Months', timeframe: TIMEFRAME.d },\r\n { value: DateRangeType.m6, label: '6 Months', timeframe: TIMEFRAME.d },\r\n ],\r\n },\r\n {\r\n label: 'Years',\r\n dateRanges: [\r\n { value: DateRangeType.ytd, label: 'Year to Date', timeframe: TIMEFRAME.d },\r\n { value: DateRangeType.y1, label: '1 Year', timeframe: TIMEFRAME.d },\r\n { value: DateRangeType.y2, label: '2 Years', timeframe: TIMEFRAME.w },\r\n { value: DateRangeType.y5, label: '5 Years', timeframe: isPremium ? TIMEFRAME.w : TIMEFRAME.m },\r\n { value: DateRangeType.max, label: 'Max', timeframe: TIMEFRAME.m },\r\n ],\r\n },\r\n ]\r\n\r\n return rangeGroups\r\n}\r\n\r\nexport function getDateRangeGroups({\r\n isPremium,\r\n customRange,\r\n isCustomAvailable = true,\r\n instrument,\r\n}: {\r\n isPremium: boolean\r\n customRange?: string\r\n isCustomAvailable?: boolean\r\n instrument: Instrument\r\n}) {\r\n const rangeGroups = generateDateRangeGroups({ isPremium, instrument })\r\n\r\n if (isPremium && isCustomAvailable !== false) {\r\n const [dateRangePrefix] = customRange?.split(DATE_RANGE_PREFIX_DELMITER) ?? []\r\n rangeGroups.push({\r\n dateRanges: [\r\n {\r\n value:\r\n customRange && Object.values(CustomDateRangePrefixEnum).includes(dateRangePrefix)\r\n ? customRange\r\n : CUSTOM_DATE_RANGE,\r\n label: 'Custom',\r\n },\r\n ],\r\n })\r\n }\r\n\r\n return rangeGroups\r\n}\r\n\r\nexport function getDateRangeGroupsWithHref({\r\n isPremium,\r\n customRange,\r\n generatePath,\r\n withReload,\r\n isCustomAvailable,\r\n instrument,\r\n}: {\r\n isPremium: boolean\r\n isCustomAvailable?: boolean\r\n customRange?: string\r\n withReload?: boolean\r\n instrument: Instrument\r\n generatePath: (dateRange: IDateRange) => To\r\n}) {\r\n return getDateRangeGroups({\r\n isPremium,\r\n isCustomAvailable,\r\n customRange,\r\n instrument,\r\n }).map((dateRangeGroup: IRangeGroup) => ({\r\n label: dateRangeGroup.label,\r\n dateRanges: dateRangeGroup.dateRanges.map((dateRange) => ({\r\n ...dateRange,\r\n href:\r\n !isPremium || Object.values(DateRangeType).includes(dateRange.value as DateRangeType)\r\n ? generatePath(dateRange)\r\n : undefined,\r\n withReload: withReload ?? !isPremium,\r\n })),\r\n }))\r\n}\r\n\r\nconst FREE_PERIODS_STOCK = ['d', 'w', 'm']\r\n\r\nexport function generatePathForTimeframeDateRange({\r\n isPremium,\r\n pathname,\r\n timeframe,\r\n dateRange,\r\n utmCampaign,\r\n freeTimeframes = FREE_PERIODS_STOCK,\r\n dateRangeQueryKey = 'r',\r\n}: {\r\n isPremium: boolean\r\n pathname: string\r\n timeframe: TIMEFRAME | 'intraday'\r\n dateRange?: string | null\r\n utmCampaign?: string\r\n freeTimeframes?: string[]\r\n dateRangeQueryKey?: string\r\n}) {\r\n if (isPremium || freeTimeframes.includes(timeframe)) {\r\n return {\r\n pathname,\r\n search: `?${encodeQueryString({\r\n ...decodeQueryString(),\r\n i: undefined,\r\n p: timeframe,\r\n [dateRangeQueryKey]: dateRange ?? undefined,\r\n })}`,\r\n }\r\n }\r\n\r\n return {\r\n pathname: '/elite.ashx',\r\n search: `?${encodeQueryString({\r\n utm_source: 'finviz',\r\n utm_medium: 'banner',\r\n utm_campaign: utmCampaign || window.location.pathname,\r\n })}`,\r\n }\r\n}\r\n\r\nexport const timeframeUtm: Partial> = {\r\n [SpecificChartFunctionality.quotePage]: 'quote-timeframe',\r\n [SpecificChartFunctionality.futuresPage]: 'futures-timeframe',\r\n [SpecificChartFunctionality.forexPage]: 'forex-timeframe',\r\n [SpecificChartFunctionality.cryptoPage]: 'crypto-timeframe',\r\n}\r\n\r\nexport const daterangeUtm: Partial> = {\r\n [SpecificChartFunctionality.futuresPage]: 'futures-timeframe-daterange',\r\n [SpecificChartFunctionality.forexPage]: 'forex-timeframe-daterange',\r\n [SpecificChartFunctionality.cryptoPage]: 'crypto-timeframe-daterange',\r\n}\r\n","import * as dateFns from 'date-fns'\r\n\r\nimport { formatDateToStringUS } from '../../../app/shared/utils'\r\nimport { TIMEFRAME } from '../../constants'\r\nimport { Instrument } from '../../types'\r\nimport { generateDateRangeGroups } from './utils'\r\n\r\n// **************START**************\r\n// Functions from here until END have to be in sync with\r\n// charts: app/utils/chart-date-range-utils.ts\r\n// *********************************\r\n\r\nexport enum CustomDateRangePrefixEnum {\r\n Range = 'range',\r\n Prev = 'prev',\r\n}\r\n\r\nexport const CUSTOM_DATE_RANGE = 'custom'\r\nexport const DATE_RANGE_PREFIX_DELMITER = '_'\r\nconst CUSTOM_DATE_RANGE_DELIMITER = 'x'\r\nconst CUSTOM_PREV_RANGE_DELIMITER = '-'\r\n\r\nexport function getParsedDateRange(dateRange?: string) {\r\n return dateRange?.split(DATE_RANGE_PREFIX_DELMITER) ?? []\r\n}\r\n\r\nexport function parseCustomDateRangeUrlParam({ dateRange, anchorDate }: { dateRange: string; anchorDate: Date }) {\r\n const [dateRangePrefix, dateRangeValue] = getParsedDateRange(dateRange)\r\n\r\n if (dateRangePrefix === CustomDateRangePrefixEnum.Range) {\r\n const [dateFromString, dateToString] = dateRangeValue.replace(/-/g, '/').split(CUSTOM_DATE_RANGE_DELIMITER)\r\n const dateFrom = dateFromString ? new Date(dateFromString) : null\r\n const dateTo = dateToString ? new Date(dateToString) : null\r\n return {\r\n start: dateFrom && !Number.isNaN(dateFrom.getTime()) ? dateFrom : null,\r\n end: dateTo && !Number.isNaN(dateTo.getTime()) ? dateFns.endOfDay(dateTo) : null,\r\n }\r\n }\r\n\r\n if (dateRangePrefix === CustomDateRangePrefixEnum.Prev) {\r\n const [years, months, days] = dateRangeValue.split(CUSTOM_PREV_RANGE_DELIMITER).map(Number)\r\n\r\n if ([years, months, days].some(Number.isNaN)) {\r\n return { start: null, end: null }\r\n }\r\n\r\n return {\r\n start: dateFns.startOfDay(dateFns.sub(anchorDate, { years, months, days: days - 1 })),\r\n end: anchorDate,\r\n }\r\n }\r\n\r\n return { start: null, end: anchorDate }\r\n}\r\n\r\n// **************END**************\r\n// Functions below don't need to be\r\n// in sync with Website repository\r\n// *******************************\r\n\r\nconst DAYS_IN_YEAR = 365\r\n\r\nexport function getCustomStartEndDateRangeUrlParam({ start, end }: { start: Date | null; end: Date | null }) {\r\n const startString = start ? formatDateToStringUS(start) : ''\r\n const endString = end ? formatDateToStringUS(end) : ''\r\n\r\n const stringParts = [\r\n CustomDateRangePrefixEnum.Range,\r\n DATE_RANGE_PREFIX_DELMITER,\r\n startString,\r\n CUSTOM_DATE_RANGE_DELIMITER,\r\n endString,\r\n ]\r\n\r\n return stringParts.join('').replace(/\\//g, '-')\r\n}\r\n\r\nexport function getPrevPeriodDateRangeUrlParam({\r\n years,\r\n months,\r\n days,\r\n}: {\r\n years: number\r\n months: number\r\n days: number\r\n}) {\r\n const stringParts = [\r\n CustomDateRangePrefixEnum.Prev,\r\n DATE_RANGE_PREFIX_DELMITER,\r\n years,\r\n CUSTOM_PREV_RANGE_DELIMITER,\r\n months,\r\n CUSTOM_PREV_RANGE_DELIMITER,\r\n days,\r\n ]\r\n\r\n return stringParts.join('')\r\n}\r\n\r\nexport function getTimeframeForDateRangeType({\r\n dateRange,\r\n isPremium = true,\r\n instrument,\r\n}: {\r\n dateRange: string\r\n isPremium?: boolean\r\n instrument: Instrument\r\n}) {\r\n const dateRanges = generateDateRangeGroups({ isPremium, instrument }).flatMap(({ dateRanges }) => dateRanges)\r\n return dateRanges.find(({ value }) => value === dateRange)?.timeframe ?? null\r\n}\r\n\r\nexport function getTimeframeFromDateRange({\r\n dateRange,\r\n anchorDate,\r\n instrument,\r\n isPremium,\r\n}: {\r\n dateRange: string\r\n anchorDate: Date\r\n instrument: Instrument\r\n isPremium: boolean\r\n}) {\r\n const dateRangeTimeframe = getTimeframeForDateRangeType({ dateRange, instrument })\r\n if (dateRangeTimeframe) {\r\n return dateRangeTimeframe\r\n }\r\n const { start, end } = parseCustomDateRangeUrlParam({ dateRange, anchorDate })\r\n const startNyTime = start ?? new Date(0)\r\n const startToReferenceDateNumOfDays = dateFns.differenceInCalendarDays(anchorDate, startNyTime) + 1\r\n const rangeNumOfDays = dateFns.differenceInCalendarDays(end ?? anchorDate, startNyTime) + 1\r\n /**\r\n * DB_BARS_LIMIT - code below is dependent on amount of data we store for specific timeframes\r\n * Search DB_BARS_LIMIT in the project to find other places with such code.\r\n */\r\n if (rangeNumOfDays > 6 * DAYS_IN_YEAR) {\r\n return TIMEFRAME.m\r\n }\r\n\r\n if (rangeNumOfDays > 4 * DAYS_IN_YEAR) {\r\n return isPremium ? TIMEFRAME.w : TIMEFRAME.m\r\n }\r\n\r\n if (rangeNumOfDays > 1.5 * DAYS_IN_YEAR) {\r\n return TIMEFRAME.w\r\n }\r\n\r\n // Keep these values in sync with values in FetchQuoteIntraday in quote.cs\r\n if (instrument === Instrument.Stock) {\r\n if (rangeNumOfDays <= 1 && startToReferenceDateNumOfDays <= 11) {\r\n return TIMEFRAME.i1\r\n }\r\n\r\n if (rangeNumOfDays <= 5 && startToReferenceDateNumOfDays <= 16) {\r\n return TIMEFRAME.i5\r\n }\r\n\r\n if (rangeNumOfDays <= 7 && startToReferenceDateNumOfDays <= 200) {\r\n return TIMEFRAME.i30\r\n }\r\n } else {\r\n if (startToReferenceDateNumOfDays <= 2) {\r\n return TIMEFRAME.i5\r\n }\r\n if (startToReferenceDateNumOfDays <= 7) {\r\n return TIMEFRAME.i30\r\n }\r\n }\r\n\r\n return TIMEFRAME.d\r\n}\r\n","import * as dateFns from 'date-fns'\r\nimport * as React from 'react'\r\n\r\nimport { formatDateToStringUS } from '../../../app/shared/utils'\r\nimport { Button } from '../button'\r\nimport { ButtonGroup } from '../button-group'\r\nimport { DatePicker } from '../date-picker'\r\nimport { Delayed } from '../delayed'\r\nimport { Dialog, DialogBody, DialogFooter, DialogHeader } from '../dialog'\r\nimport { Input } from '../input'\r\nimport { Spinner } from '../spinner'\r\nimport {\r\n CustomDateRangePrefixEnum,\r\n getCustomStartEndDateRangeUrlParam,\r\n getParsedDateRange,\r\n getPrevPeriodDateRangeUrlParam,\r\n parseCustomDateRangeUrlParam,\r\n} from './custom-date-range-utils'\r\n\r\nconst DATA_YEAR_START = 1980\r\nconst DATE_PICKER_MIN_DATE = new Date(`01/01/${DATA_YEAR_START}`)\r\nconst YEARS_MAX_VALUE = new Date().getFullYear() - DATA_YEAR_START\r\n\r\nconst TAB_BUTTON_COMMON_PROPS = { type: 'button', className: 'flex-1', contentClass: 'text-center' } as const\r\n\r\nexport enum CustomRangeType {\r\n StartEnd,\r\n Manual,\r\n}\r\n\r\ninterface StartEndRange {\r\n kind: CustomRangeType.StartEnd\r\n start: Date | null\r\n end: Date | null\r\n}\r\n\r\ninterface ManualRange {\r\n kind: CustomRangeType.Manual\r\n days?: number\r\n months?: number\r\n years?: number\r\n}\r\n\r\nexport type CustomDateRangeType = StartEndRange | ManualRange\r\n\r\ninterface DialogContentProps {\r\n /**\r\n * Dialog state\r\n */\r\n dialogState: any\r\n dateRange?: string\r\n anchorDate: Date\r\n onDialogSubmit: (args: { dateRange: string | null }) => void\r\n isFetching?: boolean\r\n}\r\n\r\nconst DEFAULT_MANUAL_RANGE: ManualRange = {\r\n kind: CustomRangeType.Manual,\r\n days: 0,\r\n months: 0,\r\n years: 0,\r\n}\r\n\r\nconst DEFAULT_START_END_RANGE: StartEndRange = {\r\n kind: CustomRangeType.StartEnd,\r\n start: null,\r\n end: null,\r\n}\r\n\r\nfunction isValidManualRangeState({ years = 0, months = 0, days = 0 }: ManualRange) {\r\n return years + months + days > 0\r\n}\r\n\r\nfunction isValidStartEndRangeState({ start, end }: StartEndRange) {\r\n return !!(start || end)\r\n}\r\n\r\nfunction getDefaultSelectedTab(dateRange?: string) {\r\n if (dateRange) {\r\n const [dateRangePrefix] = getParsedDateRange(dateRange)\r\n if (dateRangePrefix === CustomDateRangePrefixEnum.Range) {\r\n return CustomRangeType.StartEnd\r\n }\r\n if (dateRangePrefix === CustomDateRangePrefixEnum.Prev) {\r\n return CustomRangeType.Manual\r\n }\r\n }\r\n return CustomRangeType.StartEnd\r\n}\r\n\r\nfunction getDefaultSelectedDate({\r\n dateRange,\r\n anchorDate,\r\n}: {\r\n dateRange?: string\r\n anchorDate: Date\r\n}): CustomDateRangeType {\r\n if (dateRange) {\r\n const [dateRangePrefix] = getParsedDateRange(dateRange)\r\n const { start, end } = parseCustomDateRangeUrlParam({ dateRange, anchorDate })\r\n if (dateRangePrefix === CustomDateRangePrefixEnum.Range) {\r\n return { kind: CustomRangeType.StartEnd, start, end }\r\n }\r\n if (dateRangePrefix === CustomDateRangePrefixEnum.Prev && start && end) {\r\n const { years, months, days } = dateFns.intervalToDuration({\r\n start: dateFns.sub(start, { days: 1 }),\r\n end,\r\n })\r\n return { kind: CustomRangeType.Manual, years, months, days }\r\n }\r\n }\r\n\r\n return DEFAULT_START_END_RANGE\r\n}\r\n\r\nexport function CustomDateRange({\r\n dialogState,\r\n dateRange,\r\n anchorDate,\r\n onDialogSubmit,\r\n isFetching,\r\n}: DialogContentProps) {\r\n const [selectedTab, setSelectedTab] = React.useState(getDefaultSelectedTab(dateRange))\r\n\r\n const [state, setState] = React.useState(getDefaultSelectedDate({ dateRange, anchorDate }))\r\n\r\n const { current: onChange } = React.useRef((kind: CustomRangeType, newValue: Partial) => {\r\n setState((prevState) => {\r\n if (kind === CustomRangeType.Manual) {\r\n const defaults = prevState?.kind === CustomRangeType.Manual ? prevState : DEFAULT_MANUAL_RANGE\r\n return { ...defaults, ...newValue } as ManualRange\r\n }\r\n if (kind === CustomRangeType.StartEnd) {\r\n const defaults = prevState?.kind === CustomRangeType.StartEnd ? prevState : DEFAULT_START_END_RANGE\r\n\r\n const newState = { ...defaults, ...newValue }\r\n if (newState.start && newState.end && newState.start.getTime() > newState.end.getTime()) {\r\n const newEnd = new Date(newState.start.getTime())\r\n newState.start = newState.end\r\n newState.end = newEnd\r\n }\r\n return newState\r\n }\r\n return prevState\r\n })\r\n })\r\n\r\n const handleSubmit = (ev: React.FormEvent) => {\r\n ev.preventDefault()\r\n\r\n let dateRange = null\r\n\r\n if (state?.kind === CustomRangeType.StartEnd && isValidStartEndRangeState(state)) {\r\n dateRange = getCustomStartEndDateRangeUrlParam({ start: state.start, end: state.end })\r\n } else if (state?.kind === CustomRangeType.Manual && isValidManualRangeState(state)) {\r\n dateRange = getPrevPeriodDateRangeUrlParam({\r\n days: state.days ?? 0,\r\n months: state.months ?? 0,\r\n years: state.years ?? 0,\r\n })\r\n }\r\n\r\n onDialogSubmit({ dateRange })\r\n }\r\n\r\n const isAbsolute = state?.kind === CustomRangeType.StartEnd\r\n const fromDate = isAbsolute ? state.start : DEFAULT_START_END_RANGE.start\r\n const toDate = isAbsolute ? state.end : DEFAULT_START_END_RANGE.end\r\n\r\n const manualRange = {\r\n ...DEFAULT_MANUAL_RANGE,\r\n ...(state?.kind === CustomRangeType.Manual ? state : {}),\r\n }\r\n\r\n return (\r\n \r\n \r\n Custom Date Range\r\n \r\n
\r\n \r\n \r\n setSelectedTab(CustomRangeType.StartEnd)}\r\n >\r\n Start / End\r\n \r\n setSelectedTab(CustomRangeType.Manual)}\r\n >\r\n Range\r\n \r\n \r\n\r\n {selectedTab === CustomRangeType.StartEnd ? (\r\n
\r\n onChange(CustomRangeType.StartEnd, { start })}\r\n >\r\n \r\n \r\n onChange(CustomRangeType.StartEnd, { end })}\r\n >\r\n \r\n \r\n
\r\n ) : (\r\n
\r\n ) =>\r\n onChange(CustomRangeType.Manual, { years: Number.parseInt(ev.currentTarget.value) })\r\n }\r\n />\r\n ) =>\r\n onChange(CustomRangeType.Manual, { months: Number.parseInt(ev.currentTarget.value) })\r\n }\r\n />\r\n ) =>\r\n onChange(CustomRangeType.Manual, { days: Number.parseInt(ev.currentTarget.value) })\r\n }\r\n />\r\n
\r\n )}\r\n
\r\n \r\n
\r\n \r\n setState(state.kind === CustomRangeType.Manual ? DEFAULT_MANUAL_RANGE : DEFAULT_START_END_RANGE)\r\n }\r\n >\r\n Reset\r\n \r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n )\r\n}\r\n","import React from 'react'\r\nimport { To, useNavigate } from 'react-router-dom'\r\n\r\nimport { TIMEFRAME } from '../../constants'\r\nimport { Instrument } from '../../types'\r\nimport { useDialogState } from '../dialog'\r\nimport { getTimeframeFromDateRange } from './custom-date-range-utils'\r\n\r\ninterface IPathForTimeframeDateRangeProps {\r\n timeframe: TIMEFRAME | 'intraday'\r\n dateRange?: string | null\r\n ticker?: string\r\n}\r\n\r\ninterface IUseCustomDateRangeDialogSubmitProps {\r\n anchorDate?: Date\r\n instrument?: Instrument\r\n shouldReloadOnNavigate?: boolean\r\n pathGenerator?: ({ ticker, timeframe, dateRange }: IPathForTimeframeDateRangeProps) => {\r\n pathname: string\r\n search: string\r\n }\r\n}\r\n\r\nexport function useCustomDateRangeDialog({\r\n anchorDate,\r\n instrument,\r\n pathGenerator,\r\n shouldReloadOnNavigate = false,\r\n}: IUseCustomDateRangeDialogSubmitProps) {\r\n const navigate = useNavigate()\r\n const customDateRangeDialogState = useDialogState()\r\n\r\n const isPremium = FinvizSettings.hasUserPremium\r\n\r\n const handleDateRangeSelect = React.useCallback(\r\n (\r\n { value, timeframe, href }: { value: string; timeframe?: TIMEFRAME; href?: To },\r\n callback?: ({ value, timeframe, href }: { value: string; timeframe: TIMEFRAME; href?: To }) => void\r\n ) => {\r\n if (!timeframe) {\r\n if (isPremium) {\r\n customDateRangeDialogState.show()\r\n }\r\n return\r\n }\r\n\r\n if (!href && pathGenerator) {\r\n const path = pathGenerator({ timeframe, dateRange: value })\r\n if (shouldReloadOnNavigate) {\r\n window.location.href = `${path.pathname}?${path.search}`\r\n } else {\r\n navigate(path)\r\n }\r\n }\r\n\r\n callback?.({ value, timeframe, href })\r\n },\r\n [navigate, customDateRangeDialogState, isPremium, pathGenerator, shouldReloadOnNavigate]\r\n )\r\n\r\n const getDateRangeTimeframe = React.useCallback(\r\n (dateRange: string | null) => {\r\n if (!anchorDate || !instrument || !dateRange) return null\r\n\r\n return {\r\n value: dateRange,\r\n timeframe: getTimeframeFromDateRange({\r\n dateRange: dateRange!,\r\n anchorDate,\r\n isPremium,\r\n instrument,\r\n }),\r\n }\r\n },\r\n [anchorDate, instrument, isPremium]\r\n )\r\n\r\n const onDialogSubmit = React.useCallback(\r\n ({ value: dateRange, timeframe: newTimeframe }: { value: string; timeframe: TIMEFRAME }) => {\r\n handleDateRangeSelect({\r\n value: dateRange,\r\n timeframe: newTimeframe,\r\n })\r\n customDateRangeDialogState.hide()\r\n },\r\n // We only want `customDateRangeDialogState.hide`, not the whole dialog\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [customDateRangeDialogState.hide, handleDateRangeSelect]\r\n )\r\n\r\n return { onDialogSubmit, customDateRangeDialogState, handleDateRangeSelect, getDateRangeTimeframe }\r\n}\r\n","import * as React from 'react'\r\n\r\nimport { TIMEFRAME } from '../../constants'\r\nimport { useSyncLocalStorage } from '../../hooks/use-sync-local-storage'\r\n\r\ntype FavoriteTimeframesMap = { [K in TIMEFRAME | 'intraday']?: boolean }\r\n\r\nexport const TIMEFRAME_FAVORITE_DEFAULTS = {\r\n [TIMEFRAME.i1]: true,\r\n [TIMEFRAME.i2]: false,\r\n [TIMEFRAME.i3]: true,\r\n [TIMEFRAME.i5]: true,\r\n [TIMEFRAME.i10]: false,\r\n [TIMEFRAME.i15]: true,\r\n [TIMEFRAME.i30]: true,\r\n [TIMEFRAME.h]: true,\r\n [TIMEFRAME.h2]: false,\r\n [TIMEFRAME.h4]: false,\r\n [TIMEFRAME.d]: true,\r\n [TIMEFRAME.w]: true,\r\n [TIMEFRAME.m]: true,\r\n}\r\n\r\nexport const TIMEFRAME_FAVORITE_DEFAULTS_FREE = {\r\n ...TIMEFRAME_FAVORITE_DEFAULTS,\r\n intraday: true,\r\n}\r\n\r\nconst LOCAL_STORAGE_KEY = 'favoriteTimeframesMap'\r\n\r\nexport function useFavoriteTimeframes(isPremium = true) {\r\n const { state, setState } = useSyncLocalStorage(\r\n LOCAL_STORAGE_KEY,\r\n isPremium ? TIMEFRAME_FAVORITE_DEFAULTS : TIMEFRAME_FAVORITE_DEFAULTS_FREE\r\n )\r\n\r\n const toggleFavoriteTimeframe = React.useCallback(\r\n (timeframe: TIMEFRAME | 'intraday') => {\r\n setState((prevState) => ({\r\n ...prevState,\r\n [timeframe]: !prevState[timeframe],\r\n }))\r\n },\r\n [setState]\r\n )\r\n\r\n const favoriteTimeframes = React.useMemo(\r\n () => Object.keys(state).filter((key) => state[key as keyof FavoriteTimeframesMap]),\r\n [state]\r\n )\r\n\r\n return {\r\n favoriteTimeframes: isPremium ? favoriteTimeframes : Object.keys(TIMEFRAME_FAVORITE_DEFAULTS_FREE),\r\n toggleFavoriteTimeframe,\r\n }\r\n}\r\n","import * as React from 'react'\r\n\r\nimport * as storage from '../services/local-storage'\r\n\r\n/**\r\n * Hook to synchronize localStorage.setItem across all components on the page on all open tabs\r\n */\r\nexport function useSyncLocalStorage(storageKey: string, defaultValue: ValueType) {\r\n const [state, setState] = React.useState(storage.getValue(storageKey, defaultValue))\r\n\r\n React.useEffect(() => {\r\n const subscription = storage.subscribeToChanges(storageKey, defaultValue, setState)\r\n\r\n return () => {\r\n subscription.unsubscribe()\r\n }\r\n }, [storageKey, defaultValue])\r\n\r\n const setValue = React.useCallback(\r\n (valueGetter: React.SetStateAction) => storage.setValue(storageKey, valueGetter, defaultValue),\r\n [defaultValue, storageKey]\r\n )\r\n\r\n return {\r\n state,\r\n setState: setValue,\r\n }\r\n}\r\n","import * as React from 'react'\r\nimport * as Reakit from 'reakit/Tooltip'\r\n\r\nimport { getExtendedDialogState } from './dialog'\r\nimport { Input, InputHTMLProps, InputProps } from './input'\r\nimport { Tooltip, TooltipColor, TooltipTrigger, useTooltipState } from './tooltip'\r\n\r\ntype TooltipInputProps = InputProps & InputHTMLProps & { isInteractive?: boolean }\r\n\r\nexport interface TooltipInputWrapperProps extends Pick {\r\n children: React.ReactElement\r\n /**\r\n * Tooltip text content\r\n */\r\n tooltipContent?: React.ReactNode\r\n tooltipColor?: keyof typeof TooltipColor\r\n tooltipSettings?: Reakit.TooltipInitialState\r\n}\r\n\r\nfunction TooltipInputWrapper({\r\n children,\r\n tooltipContent,\r\n tooltipColor,\r\n tooltipSettings,\r\n name,\r\n}: TooltipInputWrapperProps) {\r\n const tooltip = useTooltipState({ placement: 'bottom', ...tooltipSettings })\r\n const { isFullyClosed } = getExtendedDialogState(tooltip)\r\n\r\n return (\r\n <>\r\n \r\n {children}\r\n \r\n {tooltipContent && !isFullyClosed && (\r\n \r\n {tooltipContent}\r\n \r\n )}\r\n \r\n )\r\n}\r\n\r\nfunction TooltipInputComponent(\r\n {\r\n tooltipContent,\r\n tooltipColor,\r\n tooltipSettings,\r\n isInteractive = true,\r\n ...props\r\n }: TooltipInputProps & Omit,\r\n ref: React.ForwardedRef\r\n) {\r\n const input = \r\n\r\n if (!isInteractive) {\r\n return input\r\n }\r\n\r\n return (\r\n \r\n {input}\r\n \r\n )\r\n}\r\n\r\nexport const TooltipInput = React.forwardRef(TooltipInputComponent)\r\n","import React from 'react'\r\n\r\nimport { DropdownStateReturn } from '../components/dropdown'\r\nimport { PopoverStateReturn } from '../components/popover'\r\nimport { useWindowSize } from './use-window-size'\r\n\r\ntype Props = {\r\n maxHeightLimit: number\r\n hasViewportHeightLimit: boolean\r\n offsets: [number, number]\r\n state: PopoverStateReturn | DropdownStateReturn\r\n}\r\n\r\nconst MAX_HEIGHT_PROPERTY = '--popover-max-height'\r\nconst POPOVER_HEIGHT_LIMIT_STYLE = {\r\n maxHeight: `calc(var(${MAX_HEIGHT_PROPERTY}) - env(safe-area-inset-bottom))`,\r\n}\r\n\r\n/**\r\n * Limit popover height to be always in viewport is `hasViewportHeightLimit` is true\r\n */\r\nexport function usePopoverMaxHeight({ maxHeightLimit, hasViewportHeightLimit, offsets, state }: Props) {\r\n const { innerHeight } = useWindowSize({ isWatching: state.visible || state.animating })\r\n const buttonElement = state.unstable_referenceRef.current\r\n\r\n React.useEffect(() => {\r\n if (!buttonElement || !state.visible || !hasViewportHeightLimit) return\r\n\r\n // calculate height\r\n const buttonRect = buttonElement.getBoundingClientRect()\r\n const [, offsetY] = offsets\r\n let elementMaxHeight = 'auto'\r\n if (state.placement.startsWith('bottom')) {\r\n let height = innerHeight - buttonRect.bottom - offsetY * 2\r\n // when used on pages where is scrollable content, buttonRect.bottom is sometimes negative\r\n // in that case we need to subtract window.scrollY\r\n if (buttonRect.bottom < 0) height -= window.scrollY\r\n elementMaxHeight = `${Math.min(height, maxHeightLimit)}px`\r\n } else {\r\n const height = buttonRect.top - offsetY * 2\r\n elementMaxHeight = `${Math.min(height, maxHeightLimit)}px`\r\n }\r\n\r\n // set height\r\n const popoverId = buttonElement.getAttribute('aria-controls')\r\n const popoverWrapper = popoverId ? document.getElementById(popoverId) : null\r\n popoverWrapper?.style.setProperty(MAX_HEIGHT_PROPERTY, elementMaxHeight)\r\n }, [buttonElement, innerHeight, maxHeightLimit, hasViewportHeightLimit, offsets, state.placement, state.visible])\r\n\r\n return hasViewportHeightLimit ? POPOVER_HEIGHT_LIMIT_STYLE : undefined\r\n}\r\n","import * as React from 'react'\r\nimport { useLocation } from 'react-router-dom'\r\n\r\nimport * as tracking from '../../app/shared/tracking'\r\n\r\nexport function useTrackPageView(props?: { trackInitial?: boolean; trackAutomatically?: boolean }) {\r\n const { trackInitial = false, trackAutomatically = true } = props ?? {}\r\n const initialRender = React.useRef(trackInitial)\r\n const location = useLocation()\r\n\r\n const handleTrackView = React.useCallback(() => {\r\n tracking.trackPageView({ pathname: location.pathname, query: location.search })\r\n }, [location.pathname, location.search])\r\n\r\n React.useEffect(() => {\r\n if (!trackAutomatically) return\r\n if (initialRender.current) handleTrackView()\r\n initialRender.current = true\r\n }, [trackAutomatically, handleTrackView, trackInitial])\r\n\r\n return handleTrackView\r\n}\r\n","import throttle from 'lodash.throttle'\r\nimport * as React from 'react'\r\n\r\ninterface Props {\r\n throttleWaitInMs?: number\r\n isWatching?: boolean\r\n}\r\n\r\nexport function useWindowSize({ throttleWaitInMs = 300, isWatching = true }: Props = {}) {\r\n const [size, setSize] = React.useState({\r\n innerWidth: window.innerWidth,\r\n innerHeight: window.innerHeight,\r\n })\r\n\r\n React.useEffect(() => {\r\n if (!isWatching) return\r\n\r\n const handleResize = throttle(() => {\r\n setSize({\r\n innerWidth: window.innerWidth,\r\n innerHeight: window.innerHeight,\r\n })\r\n }, throttleWaitInMs)\r\n\r\n window.addEventListener('resize', handleResize)\r\n\r\n return () => {\r\n handleResize.cancel()\r\n window.removeEventListener('resize', handleResize)\r\n }\r\n }, [throttleWaitInMs, isWatching])\r\n\r\n return size\r\n}\r\n","import { TableAlign } from '../../components/Table'\r\nimport { SortByShape } from '../../hooks/use-sort-data'\r\nimport { NullableNumbers } from '../../types'\r\n\r\nexport enum PortfolioQuery {\r\n View = 'v',\r\n TableView = 'tv',\r\n PortfolioId = 'pid',\r\n Order = 'o',\r\n Tickers = 't',\r\n Map = 'map',\r\n Size = 'mapSize',\r\n Subtype = 'subtype',\r\n Group = 'group',\r\n}\r\n\r\nexport enum PortfolioMapSizeKey {\r\n MarketValue = 'market',\r\n Gain = 'gain',\r\n}\r\n\r\nexport enum PortfolioView {\r\n View = '1',\r\n Edit = '2',\r\n}\r\n\r\nexport enum PortfolioTableView {\r\n Ticker = '1',\r\n Trade = '2',\r\n}\r\n\r\nexport const PortfolioTableViewLabels = {\r\n [PortfolioTableView.Ticker]: 'Tickers',\r\n [PortfolioTableView.Trade]: 'Trades',\r\n}\r\n\r\nexport enum PortfolioSymbolType {\r\n Stock = 'stock',\r\n Cash = 'cash',\r\n}\r\n\r\nexport enum PortfolioTransaction {\r\n Watch = 0,\r\n\r\n // Stock transactions\r\n Buy = 1,\r\n Short = 2,\r\n\r\n // Cash transactions\r\n CashDeposit = 200,\r\n CashWithdraw = 201,\r\n CashIncome = 202,\r\n CashFee = 203,\r\n}\r\n\r\nexport enum NumberOfShares {\r\n None = 0,\r\n /**\r\n * The usage of this is technically incorrect. The value for `PositiveNumber` is 1.\r\n * But we don’t care in this context, because we only want to differentiate betwen zero/non-zero values,\r\n * which helps us get correct types.\r\n *\r\n * # Don’t compare `entry.shares === NumberOfShares.PositiveNumber`\r\n */\r\n PositiveNumber = 1,\r\n}\r\n\r\nexport interface PortfolioEntryBase {\r\n id: number\r\n ticker: string\r\n date: string\r\n transaction: PortfolioTransaction\r\n shares: number\r\n price: number\r\n type: PortfolioSymbolType\r\n}\r\n\r\n/**\r\n * Base type which lists all common properties\r\n */\r\nexport interface PortfolioEntryComputed {\r\n valuePaid: number\r\n valueMarket: number\r\n valueMarketPrev: number\r\n gainMarket: number\r\n gainMarketPct: number\r\n gainMarketUsd: number\r\n gainTodayUsd: number\r\n lastChangePct: number\r\n}\r\n\r\n/**\r\n * Transaction with > 0 shares\r\n */\r\nexport interface PortfolioTransactionStake extends PortfolioEntryBase, PortfolioEntryComputed {\r\n shares: NumberOfShares.PositiveNumber\r\n}\r\n\r\n/**\r\n * Transaction with 0 shares\r\n */\r\nexport interface PortfolioTransactionWatch\r\n extends Omit,\r\n NullableNumbers {\r\n shares: NumberOfShares.None\r\n transaction: PortfolioTransaction\r\n}\r\n\r\nexport type PortfolioEntryTransaction = PortfolioTransactionStake | PortfolioTransactionWatch\r\n\r\nexport type PortfolioActionType = PortfolioEntryTransaction & { isNotification?: boolean; message?: string }\r\n\r\n/**\r\n * Top level portfolio entry\r\n */\r\nexport interface PortfolioGroup extends PortfolioEntryComputed {\r\n ticker: string\r\n shares: number\r\n industry: string\r\n country: string\r\n company: string\r\n marketCap: number\r\n prevClose: number\r\n lastClose: number\r\n lastVolume: number\r\n perfWeek: number\r\n costAvg: number\r\n transactions: PortfolioEntryTransaction[]\r\n order: number\r\n id: number\r\n date: string\r\n type: PortfolioSymbolType\r\n isDelisted?: true\r\n}\r\n\r\nexport type PortfolioTrade = Omit & PortfolioEntryTransaction\r\n\r\nexport type PortfolioMapEntry = Omit & PortfolioTransactionStake\r\n\r\n/**\r\n * Summary row for the whole portfolio\r\n */\r\nexport interface PortfolioSummary {\r\n tickers: number\r\n transactions: number\r\n shares: number\r\n lastChangePct: number\r\n valuePaid: number\r\n valueMarket: number\r\n valueMarketStocks: number\r\n valueMarketStocksPrev: number\r\n gainMarketUsd: number\r\n gainMarketPct: number\r\n gainTodayUsd: number\r\n}\r\n\r\nexport interface PortfolioDefinition {\r\n id: number\r\n name: string\r\n order: number\r\n}\r\n\r\nexport interface PortfolioInitData {\r\n limit: number\r\n limitTransactions: number\r\n selectedPortfolio: number\r\n portfolios: PortfolioDefinition[]\r\n portfolio: PortfolioGroup[]\r\n news: string[]\r\n version?: number\r\n}\r\n\r\nexport interface PortfolioFormEntry\r\n extends Pick,\r\n Partial> {\r\n uuid: string\r\n}\r\n\r\nexport interface PortfolioFormGroup extends Pick {\r\n id: string\r\n transactions: PortfolioFormEntry[]\r\n}\r\n\r\nexport enum ColumnId {\r\n Spacer = 'spacer',\r\n Ticker = 'ticker',\r\n Company = 'company',\r\n LastClose = 'lastClose',\r\n CostAvg = 'costAvg',\r\n LastChange = 'lastChange',\r\n LastChangePct = 'lastChangePct',\r\n LastVolume = 'lastVolume',\r\n Transaction = 'transaction',\r\n Date = 'date',\r\n Shares = 'shares',\r\n Price = 'price',\r\n ValuePaid = 'valuePaid',\r\n Amount = 'amount',\r\n ValueMarket = 'valueMarket',\r\n GainMarketUsd = 'gainMarketUsd',\r\n GainMarketPct = 'gainMarketPct',\r\n GainMarketCombined = 'gainMarketCombined',\r\n GainTodayUsd = 'gainTodayUsd',\r\n GainTodayCombined = 'gainTodayCombined',\r\n Order = 'order',\r\n}\r\n\r\nexport enum RowKind {\r\n Group, // A group of transactions\r\n Transaction, // A transaction made inside ticker\r\n Summary, // Portfolio summary\r\n Watchlist, // Charts portfolio watchlist table\r\n Trade,\r\n}\r\n\r\ninterface GroupProps {\r\n kind: RowKind.Group\r\n row: PortfolioGroup\r\n}\r\ninterface TradeProps {\r\n kind: RowKind.Trade\r\n row: PortfolioTrade\r\n}\r\n\r\ninterface TransactionProps {\r\n kind: RowKind.Transaction\r\n row: PortfolioEntryTransaction\r\n}\r\n\r\ninterface SummaryProps {\r\n kind: RowKind.Summary\r\n row: PortfolioSummary\r\n}\r\n\r\ninterface WatchlistProps {\r\n index: number\r\n kind: RowKind.Watchlist\r\n row: PortfolioGroup\r\n}\r\n\r\nexport interface TableColumnDefinition<\r\n PropsType = GroupProps | TradeProps | TransactionProps | SummaryProps | WatchlistProps,\r\n> extends SortByShape {\r\n urlSort: string\r\n name: string\r\n align?: TableAlign\r\n\r\n /**\r\n * Get the value of the column and render it\r\n */\r\n renderColumn: (props: PropsType) => React.ReactNode\r\n}\r\n\r\nexport enum ActionKind {\r\n AddTickers,\r\n RemoveTicker,\r\n AddTransaction,\r\n EditTransaction,\r\n RemoveTransaction,\r\n ReorderTickers,\r\n PortfoliosReorder,\r\n}\r\n\r\nexport interface Action {\r\n kind: ActionKind\r\n payload: PayloadType\r\n}\r\n\r\nexport type AddTickersError = {\r\n tickers?: string\r\n}\r\n\r\nexport interface CreatePortfolioErrors extends AddTickersError {\r\n portfolioName?: string\r\n}\r\n\r\nexport interface CreatePortfolioData {\r\n tickers: string\r\n portfolioName: string\r\n}\r\n\r\nexport type FormErrors = Partial>\r\n\r\nexport interface PortfolioBulkEditErrors {\r\n portfolioName: boolean\r\n rows: Record\r\n}\r\n","import * as React from 'react'\r\n\r\nimport { Notification, useNotification } from '../components/notification'\r\nimport { Paragraph } from '../components/typography'\r\nimport { useIsMounted } from '../hooks/use-is-mounted'\r\nimport { importWithRetry } from './import-with-retry'\r\n\r\nconst cache: any = {}\r\nconst errorsCache: any = {}\r\n\r\nenum ErrorSeverity {\r\n medium,\r\n high,\r\n}\r\n\r\nfunction defaultCaptureException(exception: Error, captureContext?: { extra: Record }) {\r\n if (process.env.NODE_ENV === 'development') {\r\n console.error(exception)\r\n } else {\r\n window.Sentry.captureException(exception, captureContext)\r\n }\r\n}\r\n\r\n/**\r\n * Hook used to asynchronously load a module\r\n *\r\n * Usage: [wiki](https://github.com/finvizhq/Finviz-Website/wiki/Loading-modules-asynchronously#useasyncmodule)\r\n */\r\nexport function useAsyncModule({\r\n importFn,\r\n onError,\r\n errorSeverity,\r\n cacheKey,\r\n captureException = defaultCaptureException,\r\n shouldLoadModule = false,\r\n isSuspenseMode = false as SuspenseMode,\r\n}: {\r\n importFn: () => Promise\r\n onError?: () => void\r\n cacheKey: string\r\n errorSeverity?: keyof typeof ErrorSeverity\r\n shouldLoadModule?: boolean\r\n captureException?: typeof defaultCaptureException\r\n isSuspenseMode?: SuspenseMode\r\n}) {\r\n const notificationContext = useNotification()\r\n const [isLoading, setIsLoading] = React.useState(false)\r\n const [isError, setIsError] = React.useState(false)\r\n const getIsMounted = useIsMounted()\r\n\r\n const handleError = () => {\r\n onError?.()\r\n setIsError(true)\r\n\r\n if (errorSeverity === undefined) {\r\n return\r\n }\r\n\r\n if (ErrorSeverity[errorSeverity] === ErrorSeverity.high) {\r\n window.handleScriptNotLoaded()\r\n window.renderScriptNotLoaded()\r\n }\r\n\r\n if (ErrorSeverity[errorSeverity] === ErrorSeverity.medium) {\r\n notificationContext.show(\r\n \r\n \r\n One or more of the required application components couldn’t be loaded.
Please try to repeat the\r\n action or{' '}\r\n window.location.reload()}>\r\n refresh the page\r\n {' '}\r\n if the problem persists.\r\n
\r\n
\r\n )\r\n }\r\n }\r\n\r\n const loadModule = async () => {\r\n if (cache[cacheKey]) {\r\n return cache[cacheKey]\r\n }\r\n\r\n setIsLoading(true)\r\n\r\n try {\r\n cache[cacheKey] = await importWithRetry(importFn)\r\n } catch (error) {\r\n captureException(error as Error)\r\n handleError()\r\n } finally {\r\n if (getIsMounted()) {\r\n setIsLoading(false)\r\n }\r\n }\r\n\r\n return cache[cacheKey]\r\n }\r\n\r\n React.useEffect(() => {\r\n if (shouldLoadModule) {\r\n loadModule()\r\n }\r\n // We want to run it only on shouldLoadModule change\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [shouldLoadModule])\r\n\r\n const cachedModule = cache[cacheKey]\r\n if (isSuspenseMode) {\r\n if (errorsCache[cacheKey]) throw errorsCache[cacheKey]\r\n if (!cachedModule) {\r\n throw importFn()\r\n .then((mod) => (cache[cacheKey] = mod))\r\n .catch((err) => {\r\n handleError()\r\n errorsCache[cacheKey] = err\r\n })\r\n }\r\n }\r\n\r\n return [cachedModule ?? null, { isLoading, loadModule, isError }] as [\r\n SuspenseMode extends true ? T : T | null,\r\n { isLoading: boolean; loadModule: () => Promise; isError: boolean },\r\n ]\r\n}\r\n\r\n/**\r\n * HOC which wraps component in React.Suspense\r\n *\r\n * Usage: [wiki](https://github.com/finvizhq/Finviz-Website/wiki/Loading-modules-asynchronously#withsuspense)\r\n */\r\nexport function withSuspense

>(\r\n Component: React.ComponentType

,\r\n fallback: React.ReactNode = null\r\n) {\r\n return function WrappedComponent(props: P) {\r\n return (\r\n \r\n \r\n \r\n )\r\n }\r\n}\r\n","const NUM_OF_RETRIES = 3\r\n\r\nexport function importWithRetry(importFn: () => Promise, retries = 0) {\r\n const result = importFn().catch(async (err) => {\r\n if (retries > NUM_OF_RETRIES) {\r\n throw err\r\n }\r\n\r\n await new Promise((r) => setTimeout(r, 1000 * retries))\r\n\r\n return importWithRetry(importFn, retries + 1)\r\n }) as Promise\r\n\r\n return result\r\n}\r\n","import { EventEmitter } from 'events'\r\nimport * as React from 'react'\r\n\r\nlet emitter: EventEmitter | undefined\r\n\r\n/**\r\n * Get the emitter which is used to sync components across the page, subscibe to\r\n * changes and attach event which handles changes across windows\r\n */\r\nexport function subscribeToChanges(\r\n key: string,\r\n defaultValue: ValueType,\r\n changeCallback?: (value: React.SetStateAction) => void\r\n) {\r\n if (!emitter) emitter = new EventEmitter()\r\n\r\n const onChange = (value: React.SetStateAction) => {\r\n const newValue = value ?? getValue(key, defaultValue)\r\n setValue(key, newValue, defaultValue, false)\r\n changeCallback?.(newValue)\r\n }\r\n\r\n const onStorageChange = (ev: StorageEvent) => {\r\n if (ev.key === key) {\r\n try {\r\n const value = ev.newValue ? JSON.parse(ev.newValue) : null\r\n onChange(value ?? defaultValue)\r\n } catch {\r\n onChange(defaultValue)\r\n }\r\n }\r\n }\r\n\r\n emitter.addListener(key, onChange)\r\n window.addEventListener('storage', onStorageChange)\r\n\r\n return {\r\n emitter,\r\n unsubscribe: () => {\r\n emitter?.removeListener(key, onChange)\r\n window.removeEventListener('storage', onStorageChange)\r\n },\r\n }\r\n}\r\n\r\n/**\r\n * Get value from local storage or fall back to `defaultValue`\r\n */\r\nexport function getValue(key: string, defaultValue: ValueType): ValueType {\r\n try {\r\n const value = localStorage.getItem(key)\r\n const parsedValue = value ? JSON.parse(value) : null\r\n return parsedValue ?? defaultValue\r\n } catch {\r\n return defaultValue\r\n }\r\n}\r\n\r\n/**\r\n * Set value to local storage. Optionally emits the change to all other components\r\n * which are subscribed with the same `key`\r\n */\r\nexport function setValue(\r\n key: string,\r\n valueGetter: React.SetStateAction,\r\n defaultValue: ValueType,\r\n emit = true\r\n) {\r\n try {\r\n const state = getValue(key, defaultValue)\r\n const valueToStore = valueGetter instanceof Function ? valueGetter(state) : valueGetter\r\n\r\n localStorage.setItem(key, JSON.stringify(valueToStore))\r\n if (emit) emitter?.emit(key, valueToStore)\r\n } catch {}\r\n}\r\n\r\n/**\r\n * Removes value from local storage. Optionally emits the change to all other components\r\n * which are subscribed with the same `key`\r\n */\r\nexport function removeValue(key: string, emit = true) {\r\n try {\r\n localStorage.removeItem(key)\r\n if (emit) emitter?.emit(key, undefined)\r\n } catch {}\r\n}\r\n\r\n/**\r\n * Helper function to migrate old value type to new one (eg. boolean to object)\r\n */\r\nexport function migrateValue(\r\n key: string,\r\n /**\r\n * The migrate function might get called multiple times on the page, so `oldValue` in the callback\r\n * can actually be the already migrated value. Make sure to add a condition to only migrate once.\r\n */\r\n transformValue: NewValue | ((oldValue: PrevValue | NewValue) => NewValue),\r\n defaultValue: NewValue\r\n) {\r\n try {\r\n const oldValue = getValue(key, undefined)\r\n if (typeof oldValue === 'undefined') return\r\n const migratedValue = transformValue instanceof Function ? transformValue(oldValue) : transformValue\r\n setValue(key, migratedValue, defaultValue, false) // don’t emit to other components\r\n } catch {}\r\n}\r\n","/**\r\n * Ignore any subsequent callback calls until the previous callback has finished\r\n */\r\n\r\nexport function waitForPreviousPromise(callback: () => void | Promise) {\r\n let callbackPromise: Promise | void | null = null\r\n\r\n return async function () {\r\n if (callbackPromise !== null) return\r\n\r\n callbackPromise = callback()\r\n await callbackPromise\r\n callbackPromise = null\r\n }\r\n}\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport { getRoundedObject, getXYOffsetFromLine } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\nexport interface IArrowAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n border: DrawingBorder\r\n}\r\n\r\nclass Arrow extends Element {\r\n static type = CanvasElementType.arrow\r\n\r\n declare scaled: Pick\r\n name = 'Arrow'\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.renderContent = this.renderContent.bind(this)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'l',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'r',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n border: {\r\n width: 3,\r\n color: this.getChartLayoutSettings().ElementSettings.Colors.line,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, y1, y2 } = this.scaled\r\n const roundedXY = getRoundedObject({ x1, x2, y1, y2 })\r\n const translateXY = getXYOffsetFromLine({ lineWidth: this.attrs.border.width, ...roundedXY })\r\n\r\n context.translate(translateXY.x, translateXY.y)\r\n context.beginPath()\r\n context.set('lineCap', 'round')\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n\r\n const angle = Math.PI / 8\r\n const d = 20\r\n\r\n context.beginPath()\r\n context.moveTo(roundedXY.x1, roundedXY.y1)\r\n context.lineTo(roundedXY.x2, roundedXY.y2)\r\n context.stroke()\r\n\r\n const lineAngle = Math.atan2(roundedXY.y2 - roundedXY.y1, roundedXY.x2 - roundedXY.x1)\r\n const h = Math.abs(d / Math.cos(angle))\r\n\r\n const angle1 = lineAngle + angle\r\n const topx = roundedXY.x1 + Math.cos(angle1) * h\r\n const topy = roundedXY.y1 + Math.sin(angle1) * h\r\n const angle2 = lineAngle - angle\r\n const botx = roundedXY.x1 + Math.cos(angle2) * h\r\n const boty = roundedXY.y1 + Math.sin(angle2) * h\r\n\r\n context.beginPath()\r\n context.moveTo(topx, topy)\r\n context.lineTo(roundedXY.x1, roundedXY.y1)\r\n context.lineTo(botx, boty)\r\n context.stroke()\r\n context.translate(translateXY.x * -1, translateXY.y * -1)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.x2 += x\r\n this.attrs.y1 += y\r\n this.attrs.y2 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n if (type === 'l') {\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n } else {\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n if (math.distanceToSegment(area.scaled, this.scaled) <= 10) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nArrow.prototype.modalConfig = {\r\n inputs: [{ type: 'line', name: 'border' }],\r\n}\r\n\r\nexport default Arrow\r\n","import { DrawingBorder, PaneArea, RequireByKey, ResizeByThumbFuncProps } from '../../../types/shared'\r\nimport { CanvasElementType } from '../../constants/common'\r\nimport math from '../../helpers/math'\r\nimport PaneModel from '../../models/pane'\r\nimport { getContextWithCache } from '../../utils/canvas'\r\nimport Element, { EdgeValues } from '../element'\r\nimport Thumb from '../thumb'\r\n\r\nexport type BrushPoints = Array<[x: number, y: number]>\r\n\r\nexport interface IBrushAttrs {\r\n points: BrushPoints\r\n fill: string\r\n border: DrawingBorder\r\n isPolyLineClosed: boolean\r\n positionPointsTimestamps: BrushPoints\r\n}\r\n\r\nclass Brush extends Element {\r\n static type = CanvasElementType.brushV1\r\n\r\n untranslatedContext: CanvasRenderingContext2D | null = null\r\n\r\n name = 'Brush'\r\n\r\n brushPath: Path2D | null = null\r\n\r\n cachedFill = {\r\n previousFill: '',\r\n shouldRenderFill: false,\r\n }\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.untranslatedContext = getContextWithCache(document.createElement('canvas'))\r\n this.setFillCache()\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultTransparentFill,\r\n border: {\r\n width: 3,\r\n color: ElementSettings.Colors.border,\r\n },\r\n isPolyLineClosed: false,\r\n } as Partial\r\n }\r\n\r\n setFillCache() {\r\n this.cachedFill.previousFill = this.attrs.fill\r\n if (this.attrs.fill.length === 9) {\r\n this.cachedFill.shouldRenderFill = this.attrs.fill.slice(7) !== '00'\r\n } else {\r\n this.cachedFill.shouldRenderFill = true\r\n }\r\n }\r\n\r\n getShouldRenderFill() {\r\n if (this.attrs.fill !== this.cachedFill.previousFill) {\r\n this.setFillCache()\r\n }\r\n return this.cachedFill.shouldRenderFill\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n if (this.attrs.border != null) {\r\n context.set('strokeStyle', this.attrs.border.color)\r\n }\r\n context.set('lineCap', 'round')\r\n context.set('lineJoin', 'round')\r\n\r\n const brushPath = new Path2D()\r\n const { points } = this.attrs\r\n context.beginPath()\r\n brushPath.moveTo(this.fx(points[0][0]), this.fy(points[0][1]))\r\n let i\r\n if (points.length > 3) {\r\n for (i = 0; i < points.length - 2; i++) {\r\n const xc = (this.fx(points[i][0]) + this.fx(points[i + 1][0])) / 2\r\n const yc = (this.fy(points[i][1]) + this.fy(points[i + 1][1])) / 2\r\n brushPath.quadraticCurveTo(this.fx(points[i][0]), this.fy(points[i][1]), xc, yc)\r\n }\r\n brushPath.quadraticCurveTo(\r\n this.fx(points[i][0]),\r\n this.fy(points[i][1]),\r\n this.fx(points[i + 1][0]),\r\n this.fy(points[i + 1][1])\r\n )\r\n } else {\r\n for (const point of points) {\r\n brushPath.lineTo(this.fx(point[0]), this.fy(point[1]))\r\n }\r\n }\r\n\r\n if (this.attrs.isPolyLineClosed) {\r\n brushPath.closePath()\r\n }\r\n this.brushPath = brushPath\r\n if (this.attrs.fill && this.getShouldRenderFill()) {\r\n context.set('fillStyle', this.attrs.fill)\r\n context.fill(brushPath)\r\n }\r\n if (this.attrs?.border?.width) {\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.stroke(brushPath)\r\n }\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getThumbs() {\r\n const [firstX, firstY] = this.attrs.points[0]\r\n const [lastX, lastY] = this.attrs.points[this.attrs.points.length - 1]\r\n\r\n return [\r\n new Thumb(\r\n 'first',\r\n () => firstX,\r\n () => firstY,\r\n this.moveByThumb,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'last',\r\n () => lastX,\r\n () => lastY,\r\n this.moveByThumb,\r\n this.model\r\n ),\r\n ]\r\n }\r\n\r\n moveByThumb = ({ difX, difY }: RequireByKey) => {\r\n this.moveBy(difX, difY)\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n if (this.getIsCreator()) return\r\n for (const point of this.attrs.points) {\r\n point[0] += x\r\n point[1] += y\r\n }\r\n }\r\n\r\n onMouseUp() {\r\n const [currentDomainMax, currentDomainMin] = this.model.scale.y.domain()\r\n for (const point of this.attrs.points) {\r\n point[0] = this.roundToFixed(point[0], 2)\r\n point[1] = this.roundY(point[1], currentDomainMax - currentDomainMin)\r\n }\r\n super.onMouseUp()\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const { points } = this.attrs\r\n if (\r\n (this.getShouldRenderFill() || this.attrs.isPolyLineClosed) &&\r\n this.brushPath &&\r\n this.untranslatedContext?.isPointInPath(this.brushPath, area.scaled.x, area.scaled.y)\r\n ) {\r\n return true\r\n } else if (points.length > 1) {\r\n for (let i = 0; i < points.length - 1; i++) {\r\n if (\r\n math.distanceToSegment(area.scaled, {\r\n x1: this.fx(points[i][0]),\r\n y1: this.fy(points[i][1]),\r\n x2: this.fx(points[i + 1][0]),\r\n y2: this.fy(points[i + 1][1]),\r\n }) <= 10\r\n ) {\r\n return true\r\n }\r\n }\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n cachePointPositionTimestamp = () => {\r\n const quote = this.model?.chart()?.quote()\r\n if (quote) {\r\n const positionPointsTimestamps = this.attrs.points.map(([x, y]) => [quote.getTimestampFomPositionX(x), y])\r\n this.set({ positionPointsTimestamps } as Partial)\r\n }\r\n }\r\n\r\n updateScales() {\r\n const quote = this.model.chart().quote()\r\n const { positionPointsTimestamps } = this.attrs\r\n if (!quote || !positionPointsTimestamps) {\r\n // positionPointsTimestamps check is temporary to prevent app from crashing\r\n // caused by corrupted drawings - https://github.com/finvizhq/charts/pull/1386/files\r\n return\r\n }\r\n const points = positionPointsTimestamps.map(([x, y]) => [quote.getPositionXFromTimestamp(x), y])\r\n this.set({ points } as Partial)\r\n }\r\n\r\n roundToFixed = (value: number, places: number) => Number.parseFloat(math.round({ value, overridePlaces: places }))\r\n\r\n roundY = (y: number, domainDiff: number) => {\r\n if (domainDiff < 1) {\r\n const numberOfLeadingZeros = Math.abs(Math.floor(Math.log10(Math.abs(domainDiff)) + 1))\r\n if (numberOfLeadingZeros > 0) {\r\n return this.roundToFixed(y, numberOfLeadingZeros + 4)\r\n } else {\r\n return this.roundToFixed(y, numberOfLeadingZeros + 3)\r\n }\r\n } else if (domainDiff < 10) {\r\n return this.roundToFixed(y, 3)\r\n }\r\n return this.roundToFixed(y, 2)\r\n }\r\n\r\n getAutosaveOmittedProperties() {\r\n return ['points']\r\n }\r\n\r\n getEdgeXYValues() {\r\n if (this.edgeXYValues === null) {\r\n const edgeXYValues = {} as EdgeValues\r\n this.attrs.points.forEach(([x, y]) => {\r\n edgeXYValues.minX = Math.min(x, edgeXYValues.minX ?? x)\r\n edgeXYValues.minY = Math.min(y, edgeXYValues.minY ?? y)\r\n edgeXYValues.maxX = Math.max(x, edgeXYValues.maxX ?? x)\r\n edgeXYValues.maxY = Math.max(y, edgeXYValues.maxY ?? y)\r\n })\r\n\r\n this.edgeXYValues = edgeXYValues\r\n }\r\n\r\n return this.edgeXYValues\r\n }\r\n}\r\n\r\nBrush.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1, max: 20, default: {} },\r\n { type: 'checkbox', name: 'isPolyLineClosed', label: 'Close line' },\r\n ],\r\n}\r\n\r\nexport default Brush\r\n","import math from '../../helpers/math'\r\n\r\ninterface ICoordinates {\r\n x: number\r\n y: number\r\n}\r\nexport interface IRectangleSidesCoordinates {\r\n topLeft: ICoordinates\r\n topRight: ICoordinates\r\n rightTop: ICoordinates\r\n rightBottom: ICoordinates\r\n bottomRight: ICoordinates\r\n bottomLeft: ICoordinates\r\n leftBottom: ICoordinates\r\n leftTop: ICoordinates\r\n}\r\n\r\nexport interface ITailCoordinates {\r\n tailRoot: ICoordinates\r\n tailTip: ICoordinates\r\n}\r\n\r\nexport enum TailDirection {\r\n noTail,\r\n topLeftCorner,\r\n topRightCorner,\r\n bottomLeftCorner,\r\n bottomRightCorner,\r\n topSide,\r\n rightSide,\r\n bottomSide,\r\n leftSide,\r\n}\r\n\r\nexport const getRectangleSidesCoordinates = ({\r\n padding,\r\n radius,\r\n x2,\r\n y2,\r\n textWidth,\r\n measuredHeight,\r\n}: {\r\n padding: number\r\n radius: number\r\n x2: number\r\n y2: number\r\n textWidth: number\r\n measuredHeight: number\r\n}): IRectangleSidesCoordinates => ({\r\n topLeft: {\r\n x: x2 - padding + radius,\r\n y: y2 - padding,\r\n },\r\n topRight: {\r\n x: x2 + textWidth + padding - radius,\r\n y: y2 - padding,\r\n },\r\n rightTop: {\r\n x: x2 + textWidth + padding,\r\n y: y2 - padding + radius,\r\n },\r\n rightBottom: {\r\n x: x2 + textWidth + padding,\r\n y: y2 + padding + measuredHeight - radius,\r\n },\r\n bottomRight: {\r\n x: x2 + textWidth + padding - radius,\r\n y: y2 + padding + measuredHeight,\r\n },\r\n bottomLeft: {\r\n x: x2 - padding + radius,\r\n y: y2 + padding + measuredHeight,\r\n },\r\n leftBottom: {\r\n x: x2 - padding,\r\n y: y2 + padding + measuredHeight - radius,\r\n },\r\n leftTop: {\r\n x: x2 - padding,\r\n y: y2 - padding + radius,\r\n },\r\n})\r\n\r\nexport const getTailCoordinates = ({\r\n rectangleSides,\r\n x1,\r\n y1,\r\n}: {\r\n rectangleSides: IRectangleSidesCoordinates\r\n x1: number\r\n y1: number\r\n}): ITailCoordinates => ({\r\n tailRoot: {\r\n x: rectangleSides.topLeft.x + (rectangleSides.topRight.x - rectangleSides.topLeft.x) / 2,\r\n y: rectangleSides.leftTop.y + (rectangleSides.leftBottom.y - rectangleSides.leftTop.y) / 2,\r\n },\r\n tailTip: {\r\n x: x1,\r\n y: y1,\r\n },\r\n})\r\n\r\nconst getTailHalfWidth = (halfWidth: number, p1: ICoordinates, p2: ICoordinates): number => {\r\n const dist = math.distance(p1, p2)\r\n if (dist < halfWidth * 2) {\r\n return dist / 2\r\n } else {\r\n return halfWidth\r\n }\r\n}\r\n\r\nexport const getTailToSideIntersection = ({\r\n tail,\r\n rectangleSides,\r\n}: {\r\n tail: ITailCoordinates\r\n rectangleSides: IRectangleSidesCoordinates\r\n}): TailDirection => {\r\n const { topLeft, topRight, rightTop, rightBottom, bottomRight, bottomLeft, leftBottom, leftTop } = rectangleSides\r\n const { tailTip, tailRoot } = tail\r\n if (math.twoSegmentLinesIntersection(tailTip, tailRoot, topLeft, leftTop)) {\r\n return TailDirection.topLeftCorner\r\n } else if (math.twoSegmentLinesIntersection(tailTip, tailRoot, topRight, rightTop)) {\r\n return TailDirection.topRightCorner\r\n } else if (math.twoSegmentLinesIntersection(tailTip, tailRoot, bottomLeft, leftBottom)) {\r\n return TailDirection.bottomLeftCorner\r\n } else if (math.twoSegmentLinesIntersection(tailTip, tailRoot, bottomRight, rightBottom)) {\r\n return TailDirection.bottomRightCorner\r\n } else if (math.twoSegmentLinesIntersection(tailTip, tailRoot, topLeft, topRight)) {\r\n return TailDirection.topSide\r\n } else if (math.twoSegmentLinesIntersection(tailTip, tailRoot, rightTop, rightBottom)) {\r\n return TailDirection.rightSide\r\n } else if (math.twoSegmentLinesIntersection(tailTip, tailRoot, bottomLeft, bottomRight)) {\r\n return TailDirection.bottomSide\r\n } else if (math.twoSegmentLinesIntersection(tailTip, tailRoot, leftTop, leftBottom)) {\r\n return TailDirection.leftSide\r\n } else {\r\n return TailDirection.noTail\r\n }\r\n}\r\n\r\ninterface IRenderCallout {\r\n context: any\r\n radius: number\r\n requiredTailHalfWidth: number\r\n tail: ITailCoordinates\r\n rectangleSides: IRectangleSidesCoordinates\r\n tailDirection: TailDirection\r\n}\r\n\r\nexport const renderCallout = ({\r\n context,\r\n radius,\r\n requiredTailHalfWidth,\r\n tail,\r\n rectangleSides,\r\n tailDirection,\r\n}: IRenderCallout): void => {\r\n const { topLeft, topRight, rightTop, rightBottom, bottomRight, bottomLeft, leftBottom, leftTop } = rectangleSides\r\n const { tailTip, tailRoot } = tail\r\n\r\n // draw rounded rectangle from top left corner clockwise\r\n // !!! ORDER OF RENDER MATTERS !!!\r\n\r\n // renderTopLeftCorner\r\n if (tailDirection === TailDirection.topLeftCorner) {\r\n context.moveTo(leftTop.x, leftTop.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(topLeft.x, topLeft.y)\r\n } else {\r\n context.moveTo(leftTop.x, leftTop.y)\r\n context.arcTo(leftTop.x, topLeft.y, topLeft.x, topLeft.y, radius)\r\n }\r\n\r\n // renderTopLine\r\n if (tailDirection === TailDirection.topSide) {\r\n const tailLineToTopLineIntersection = math.twoSegmentLinesIntersection(tailTip, tailRoot, topLeft, topRight)\r\n if (!tailLineToTopLineIntersection) {\r\n context.lineTo(topRight.x, topRight.y)\r\n return\r\n }\r\n const tailHalfWidth = getTailHalfWidth(requiredTailHalfWidth, topLeft, topRight)\r\n if (tailLineToTopLineIntersection.x - tailHalfWidth < topLeft.x) {\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(topLeft.x + tailHalfWidth * 2, tailLineToTopLineIntersection.y)\r\n } else if (tailLineToTopLineIntersection.x + tailHalfWidth > topRight.x) {\r\n context.lineTo(topRight.x - tailHalfWidth * 2, tailLineToTopLineIntersection.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(topRight.x, tailLineToTopLineIntersection.y)\r\n } else {\r\n context.lineTo(tailLineToTopLineIntersection.x - tailHalfWidth, tailLineToTopLineIntersection.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(tailLineToTopLineIntersection.x + tailHalfWidth, tailLineToTopLineIntersection.y)\r\n context.lineTo(topRight.x, topRight.y)\r\n }\r\n } else {\r\n context.lineTo(topRight.x, topRight.y)\r\n }\r\n\r\n // renderTopRightCorner\r\n if (tailDirection === TailDirection.topRightCorner) {\r\n context.lineTo(topRight.x, topRight.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(rightTop.x, rightTop.y)\r\n } else {\r\n context.arcTo(rightTop.x, topRight.y, rightTop.x, rightTop.y, radius)\r\n }\r\n\r\n // renderRightLine\r\n if (tailDirection === TailDirection.rightSide) {\r\n const tailLineToRightLineIntersection = math.twoSegmentLinesIntersection(tailTip, tailRoot, rightTop, rightBottom)\r\n if (!tailLineToRightLineIntersection) {\r\n context.lineTo(rightBottom.x, rightBottom.y)\r\n return\r\n }\r\n const tailHalfWidth = getTailHalfWidth(requiredTailHalfWidth, rightTop, rightBottom)\r\n if (tailLineToRightLineIntersection.y - tailHalfWidth < rightTop.y) {\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(rightTop.x, rightTop.y + tailHalfWidth * 2)\r\n } else if (tailLineToRightLineIntersection.y + tailHalfWidth > rightBottom.y) {\r\n context.lineTo(rightBottom.x, rightBottom.y - tailHalfWidth * 2)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(rightBottom.x, rightBottom.y)\r\n } else {\r\n context.lineTo(tailLineToRightLineIntersection.x, tailLineToRightLineIntersection.y - tailHalfWidth)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(tailLineToRightLineIntersection.x, tailLineToRightLineIntersection.y + tailHalfWidth)\r\n context.lineTo(rightBottom.x, rightBottom.y)\r\n }\r\n } else {\r\n context.lineTo(rightBottom.x, rightBottom.y)\r\n }\r\n\r\n // renderBottomRightCorner\r\n if (tailDirection === TailDirection.bottomRightCorner) {\r\n context.lineTo(rightBottom.x, rightBottom.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(bottomRight.x, bottomRight.y)\r\n } else {\r\n context.arcTo(rightBottom.x, bottomRight.y, bottomRight.x, bottomRight.y, radius)\r\n }\r\n\r\n // renderBottomLine\r\n if (tailDirection === TailDirection.bottomSide) {\r\n const tailLineToBottomLineIntersection = math.twoSegmentLinesIntersection(\r\n tailTip,\r\n tailRoot,\r\n bottomLeft,\r\n bottomRight\r\n )\r\n if (!tailLineToBottomLineIntersection) {\r\n context.lineTo(bottomLeft.x, bottomLeft.y)\r\n return\r\n }\r\n const tailHalfWidth = getTailHalfWidth(requiredTailHalfWidth, bottomLeft, bottomRight)\r\n if (tailLineToBottomLineIntersection.x + tailHalfWidth > bottomRight.x) {\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(bottomRight.x - tailHalfWidth * 2, tailLineToBottomLineIntersection.y)\r\n } else if (tailLineToBottomLineIntersection.x - tailHalfWidth < bottomLeft.x) {\r\n context.lineTo(bottomLeft.x + tailHalfWidth * 2, tailLineToBottomLineIntersection.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(bottomLeft.x, tailLineToBottomLineIntersection.y)\r\n } else {\r\n context.lineTo(tailLineToBottomLineIntersection.x + tailHalfWidth, tailLineToBottomLineIntersection.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(tailLineToBottomLineIntersection.x - tailHalfWidth, tailLineToBottomLineIntersection.y)\r\n context.lineTo(bottomLeft.x, bottomLeft.y)\r\n }\r\n } else {\r\n context.lineTo(bottomLeft.x, bottomLeft.y)\r\n }\r\n\r\n // renderBottomLeftCorner\r\n if (tailDirection === TailDirection.bottomLeftCorner) {\r\n context.lineTo(bottomLeft.x, bottomLeft.y)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(leftBottom.x, leftBottom.y)\r\n } else {\r\n context.arcTo(leftBottom.x, bottomLeft.y, leftBottom.x, leftBottom.y, radius)\r\n }\r\n\r\n // renderLeftLine\r\n if (tailDirection === TailDirection.leftSide) {\r\n const tailLineToLeftLineIntersection = math.twoSegmentLinesIntersection(tailTip, tailRoot, leftTop, leftBottom)\r\n if (!tailLineToLeftLineIntersection) {\r\n context.lineTo(leftTop.x, leftTop.y)\r\n return\r\n }\r\n const tailHalfWidth = getTailHalfWidth(requiredTailHalfWidth, leftTop, leftBottom)\r\n if (tailLineToLeftLineIntersection.y + tailHalfWidth > leftBottom.y) {\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(leftBottom.x, leftBottom.y - tailHalfWidth * 2)\r\n } else if (tailLineToLeftLineIntersection.y - tailHalfWidth < leftTop.y) {\r\n context.lineTo(leftTop.x, leftTop.y + tailHalfWidth * 2)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(leftTop.x, leftTop.y)\r\n } else {\r\n context.lineTo(tailLineToLeftLineIntersection.x, tailLineToLeftLineIntersection.y + tailHalfWidth)\r\n context.lineTo(tailTip.x, tailTip.y)\r\n context.lineTo(tailLineToLeftLineIntersection.x, tailLineToLeftLineIntersection.y - tailHalfWidth)\r\n context.lineTo(leftTop.x, leftTop.y)\r\n }\r\n } else {\r\n context.lineTo(leftTop.x, leftTop.y)\r\n }\r\n}\r\n","import merge from 'lodash.merge'\r\n\r\nimport { PaneArea, RequireByKey, ResizeByThumbWithTypeAndDifs, TextAttrs } from '../../../types/shared'\r\nimport { PADDING } from '../../constants/common'\r\nimport { CanvasElementType } from '../../constants/common'\r\nimport math from '../../helpers/math'\r\nimport Chart from '../../models/chart'\r\nimport PaneModel from '../../models/pane'\r\nimport Text from '../text'\r\nimport Thumb from '../thumb'\r\nimport {\r\n getRectangleSidesCoordinates,\r\n getTailCoordinates,\r\n getTailToSideIntersection,\r\n renderCallout,\r\n} from './callout_utils'\r\n\r\nexport interface ICalloutAttrs {\r\n x1: number\r\n y1: number\r\n x2: number\r\n y2: number\r\n}\r\n\r\ninterface FontFamilyHeightCoefficient {\r\n Arial: {\r\n firstLine: number\r\n otherLines: number\r\n }\r\n Verdana: {\r\n firstLine: number\r\n otherLines: number\r\n }\r\n}\r\n\r\ntype CalloutTextAttrs = ICalloutAttrs & RequireByKey\r\n\r\nclass Callout extends Text {\r\n static type = CanvasElementType.calloutV1\r\n\r\n name = 'Callout'\r\n\r\n declare fontFamilyHeightCoeficient: FontFamilyHeightCoefficient\r\n declare isActualBoundingBoxAvailable: boolean\r\n declare lastAttrs: Attrs\r\n declare scaled: Pick\r\n declare measuredHeight: number\r\n declare font: string\r\n declare context?: CanvasRenderingContext2D\r\n declare lines: {\r\n text: string\r\n metrics: TextMetrics\r\n }[]\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'tail',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n getModalConfigBase() {\r\n return {\r\n inputs: [\r\n { type: 'multiline_string', name: 'text', required: true },\r\n { type: 'font', name: 'font' },\r\n {\r\n type: 'background',\r\n name: 'fillStyle',\r\n label: 'Color',\r\n default: this.getChartLayoutSettings().ElementSettings.Colors.textWithoutBackground,\r\n },\r\n {\r\n type: 'background',\r\n name: 'background',\r\n label: 'Background',\r\n default: 'rgba(0,0,0,0)',\r\n },\r\n {\r\n type: 'border',\r\n name: 'border',\r\n min: 0,\r\n },\r\n ],\r\n }\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n text: '',\r\n font: {\r\n size: 15,\r\n family: 'Arial',\r\n style: 'normal',\r\n weight: 'normal',\r\n },\r\n fillStyle: ElementSettings.Colors.textWithoutBackground,\r\n lineHeight: 15,\r\n // left | right | center | start | end\r\n textAlign: 'left',\r\n // top | middle | alphabetic | bottom\r\n textBaseline: 'alphabetic',\r\n padding: {\r\n top: 0,\r\n right: 0,\r\n bottom: 0,\r\n left: 0,\r\n },\r\n background: ElementSettings.defaultFill,\r\n border: { color: ElementSettings.Colors.line, width: 1 },\r\n } as Partial\r\n }\r\n\r\n setupContext(context: CanvasRenderingContext2D) {\r\n this.context = context\r\n context.set('font', this.font)\r\n context.set('fillStyle', this.attrs.fillStyle)\r\n context.set('textAlign', this.attrs.textAlign)\r\n context.set('textBaseline', this.attrs.textBaseline)\r\n this.setupTextMetricsCache()\r\n }\r\n\r\n setupTextMetricsCache() {\r\n const ctx = this.context\r\n\r\n if (\r\n (this.attrs.text !== this.lastAttrs?.text ||\r\n JSON.stringify(this.attrs.font) !== JSON.stringify(this.lastAttrs?.font)) &&\r\n ctx\r\n ) {\r\n this.lastAttrs = merge({}, this.attrs)\r\n this.lines = this.getLines().map((line) => ({\r\n text: line,\r\n metrics: ctx.measureText(line),\r\n }))\r\n this.measuredHeight = this.lines.reduce((acc, current, currentIndex) => {\r\n const lineHeight =\r\n current.metrics.actualBoundingBoxAscent +\r\n current.metrics.actualBoundingBoxDescent +\r\n (currentIndex !== this.lines.length - 1 ? PADDING.S : 0)\r\n return acc + lineHeight\r\n }, 0)\r\n }\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n this.render(context)\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n renderText() {\r\n if (!this.context) return\r\n let y = this.scaled.y2 + this.attrs.padding.top\r\n let previousDescent = 0\r\n for (let i = 0; i < this.lines.length; i++) {\r\n y += i === 0 ? 0 : this.lines[i].metrics.actualBoundingBoxAscent + previousDescent + PADDING.S\r\n this.context.fillText(this.lines[i].text, this.scaled.x2 + this.attrs.padding.left, y)\r\n previousDescent = this.lines[i].metrics.actualBoundingBoxDescent\r\n }\r\n }\r\n\r\n getCalloutProperties() {\r\n const textWidth = this.attrs.text === '' ? this.attrs.font.size * 2 : this.width\r\n const requiredTailHalfWidth = this.attrs.font.size * 0.5\r\n const padding = this.attrs.border.width / 2 + this.attrs.font.size * 0.5\r\n const radius = textWidth < requiredTailHalfWidth ? textWidth / 2 : requiredTailHalfWidth\r\n\r\n const measuredHeight = this.measuredHeight < requiredTailHalfWidth ? radius * 2 : this.measuredHeight\r\n const y2 = this.scaled.y2 - (this.lines?.[0]?.metrics.actualBoundingBoxAscent || measuredHeight)\r\n\r\n // Points diagram\r\n //.......X-----------------X.......\r\n //.................................\r\n //...X.........................X...\r\n //...|.........................|...\r\n //...|.........................|...\r\n //...X.........................X...\r\n //.................................\r\n //.......X-----------------X.......\r\n\r\n const rectangleSides = getRectangleSidesCoordinates({\r\n padding,\r\n radius,\r\n x2: this.scaled.x2,\r\n y2,\r\n textWidth,\r\n measuredHeight,\r\n })\r\n const tail = getTailCoordinates({ rectangleSides, x1: this.scaled.x1, y1: this.scaled.y1 })\r\n const tailDirection = getTailToSideIntersection({ tail, rectangleSides })\r\n\r\n return {\r\n radius,\r\n requiredTailHalfWidth,\r\n rectangleSides,\r\n tail,\r\n tailDirection,\r\n }\r\n }\r\n\r\n renderBackground() {\r\n if (!this.attrs.background || !this.context) {\r\n return\r\n }\r\n\r\n const { radius, requiredTailHalfWidth, tail, tailDirection, rectangleSides } = this.getCalloutProperties()\r\n\r\n this.context.beginPath()\r\n this.context.set('fillStyle', this.attrs.background)\r\n this.context.lineJoin = 'round'\r\n renderCallout({\r\n context: this.context,\r\n radius,\r\n requiredTailHalfWidth,\r\n tail,\r\n rectangleSides,\r\n tailDirection,\r\n })\r\n this.context.closePath()\r\n this.context.fill()\r\n this.context.set('fillStyle', this.attrs.fillStyle)\r\n this.renderBorder()\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n // is in rectangle\r\n const { tail, rectangleSides, requiredTailHalfWidth } = this.getCalloutProperties()\r\n if (\r\n this.lines &&\r\n rectangleSides &&\r\n rectangleSides.leftTop.x < area.scaled.x &&\r\n rectangleSides.topLeft.y < area.scaled.y &&\r\n rectangleSides.rightBottom.x > area.scaled.x &&\r\n rectangleSides.bottomRight.y > area.scaled.y\r\n ) {\r\n return true\r\n }\r\n // is in tail\r\n if (tail) {\r\n const tailP1 = math.perpendicularPointToLine({\r\n distance: requiredTailHalfWidth,\r\n line: { x1: tail.tailTip.x, y1: tail.tailTip.y, x2: tail.tailRoot.x, y2: tail.tailRoot.y },\r\n })\r\n const pointOffsetX = tailP1.x - tail.tailRoot.x\r\n const pointOffsetY = tailP1.y - tail.tailRoot.y\r\n const tailP2 = { x: tail.tailRoot.x + -1 * pointOffsetX, y: tail.tailRoot.y + -1 * pointOffsetY }\r\n const polygon = [tail.tailTip, tailP1, tailP2]\r\n if (math.pointInPolygon(area.scaled, polygon)) {\r\n return true\r\n }\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x2 += x\r\n this.attrs.y2 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n if (type === 'tail') {\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n }\r\n }\r\n\r\n getIsInChartView(chart: Chart) {\r\n if (this.getIsCreator() || !this.lines) {\r\n return true\r\n }\r\n\r\n const { tail, rectangleSides } = this.getCalloutProperties()\r\n\r\n return [...Object.values(rectangleSides), tail.tailRoot, tail.tailTip].some(\r\n ({ x, y }) => x <= -chart.leftOffset + chart.width && x >= -chart.leftOffset && y >= 0 && y <= this.model.height\r\n )\r\n }\r\n}\r\n\r\nexport default Callout\r\n","import { Bezier } from 'bezier-js'\r\n\r\nimport { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\nexport interface ICurveAttrs {\r\n x1: number\r\n x2: number\r\n x3: number\r\n cp1x: number\r\n cp2x: number\r\n y1: number\r\n y2: number\r\n y3: number\r\n cp1y: number\r\n cp2y: number\r\n border: DrawingBorder\r\n}\r\n\r\nclass Curve extends Element {\r\n static type = CanvasElementType.curve\r\n\r\n name = 'Curve'\r\n declare scaled: Pick\r\n declare curve: Bezier\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.render = this.render.bind(this)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'a',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'b',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'c',\r\n () => this.attrs.x3 || this.attrs.x2,\r\n () => this.attrs.y3 || this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n border: {\r\n width: 1,\r\n color: this.getChartLayoutSettings().ElementSettings.Colors.line,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2', 'x3'], y: ['y1', 'y2', 'y3'] })\r\n\r\n drawQuadraticCurve(context: CanvasRenderingContext2D, curve: Bezier) {\r\n const { points } = curve\r\n context.beginPath()\r\n context.moveTo(points[0].x, points[0].y)\r\n context.quadraticCurveTo(points[1].x, points[1].y, points[2].x, points[2].y)\r\n context.stroke()\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, x3, y1, y2, y3 } = this.scaled\r\n context.translate(0.5, 0.5)\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n if (!x3 || !y3) {\r\n context.beginPath()\r\n context.moveTo(x1, y1)\r\n context.lineTo(x2, y2)\r\n context.lineTo(x3, y3)\r\n context.stroke()\r\n } else {\r\n this.curve = Bezier.quadraticFromPoints({ x: x1, y: y1 }, { x: x2, y: y2 }, { x: x3, y: y3 }, 0.5)\r\n this.drawQuadraticCurve(context, this.curve)\r\n }\r\n\r\n context.translate(-0.5, -0.5)\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.x2 += x\r\n this.attrs.x3 += x\r\n this.attrs.cp1x += x\r\n this.attrs.cp2x += x\r\n\r\n this.attrs.y1 += y\r\n this.attrs.y2 += y\r\n this.attrs.y3 += y\r\n this.attrs.cp1y += y\r\n this.attrs.cp2y += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'a':\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n break\r\n case 'b':\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n break\r\n case 'c':\r\n this.attrs.x3 += difX\r\n this.attrs.y3 += difY\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n if (this.curve && this.curve.project(area.scaled).d! <= 10) {\r\n return true\r\n }\r\n return this.thumbsAreInArea(area)\r\n }\r\n\r\n getIsInChartView(chart: Chart) {\r\n if (this.getIsCreator()) {\r\n return true\r\n }\r\n\r\n const { x1, x2, x3, y1, y2, y3 } = this.scaled\r\n if (!x3 || !y3) {\r\n return true\r\n }\r\n const isInView =\r\n Bezier.quadraticFromPoints({ x: x1, y: y1 }, { x: x2, y: y2 }, { x: x3, y: y3 }, 0.5).points.some(\r\n ({ x, y }) => x <= -chart.leftOffset + chart.width && x >= -chart.leftOffset && y >= 0 && y <= this.model.height\r\n ) ?? true\r\n\r\n return isInView\r\n }\r\n}\r\n\r\nCurve.prototype.modalConfig = {\r\n inputs: [{ type: 'line', name: 'border' }],\r\n}\r\n\r\nexport default Curve\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\nexport interface IEllipseAttrs {\r\n x1: number\r\n x2: number\r\n x3: number\r\n cp1x: number\r\n cp2x: number\r\n y1: number\r\n y2: number\r\n y3: number\r\n cp1y: number\r\n cp2y: number\r\n width: number\r\n fill: string\r\n border: DrawingBorder\r\n}\r\n\r\ninterface ICoordinates {\r\n topCenterX: number\r\n topCenterY: number\r\n topRightX: number\r\n topRightY: number\r\n topLeftX: number\r\n topLeftY: number\r\n centerLeftX: number\r\n centerLeftY: number\r\n centerRightX: number\r\n centerRightY: number\r\n bottomCenterX: number\r\n bottomCenterY: number\r\n bottomLeftX: number\r\n bottomLeftY: number\r\n bottomRightX: number\r\n bottomRightY: number\r\n}\r\n\r\n// OLD Ellipse \"v0\" kept for backward-compatibiluty for old saved ideas\r\n// current Ellipse tool located in ellipse folder\r\nclass Ellipse extends Element {\r\n static type = CanvasElementType.ellipse\r\n\r\n name = 'Ellipse'\r\n\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'x1',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'x2',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'lw',\r\n () => this.model.scale.x.invert(this.getCoordinates().centerLeftX),\r\n () => this.model.scale.y.invert(this.getCoordinates().centerLeftY),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'rw',\r\n () => this.model.scale.x.invert(this.getCoordinates().centerRightX),\r\n () => this.model.scale.y.invert(this.getCoordinates().centerRightY),\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n const boundingPointKeys = this.getBoundingPointKeys()\r\n this.scale({ x: [...boundingPointKeys.x, 'width'], y: boundingPointKeys.y })\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultFill,\r\n border: {\r\n width: 1,\r\n color: ElementSettings.Colors.line,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const c = this.getCoordinates()\r\n\r\n context.set('fillStyle', this.attrs.fill)\r\n\r\n context.beginPath()\r\n context.moveTo(c.bottomCenterX, c.bottomCenterY)\r\n context.bezierCurveTo(c.bottomRightX, c.bottomRightY, c.topRightX, c.topRightY, c.topCenterX, c.topCenterY)\r\n context.bezierCurveTo(c.topLeftX, c.topLeftY, c.bottomLeftX, c.bottomLeftY, c.bottomCenterX, c.bottomCenterY)\r\n context.closePath()\r\n context.fill()\r\n\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n if ((this.attrs.border != null ? this.attrs.border.width : undefined) !== 0) {\r\n context.stroke()\r\n }\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.y1 += y\r\n this.attrs.x2 += x\r\n this.attrs.y2 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'x1':\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n break\r\n case 'x2':\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n break\r\n case 'lw':\r\n this.attrs.width += difX\r\n break\r\n case 'rw':\r\n this.attrs.width -= difX\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n getCoordinates(): ICoordinates {\r\n // TODO cache?\r\n // http://stackoverflow.com/questions/14169234/the-relation-of-the-bezier-curve-and-ellipse\r\n const rotationAngle =\r\n Math.PI + Math.atan(-1 / ((this.scaled.y2 - this.scaled.y1) / (this.scaled.x2 - this.scaled.x1)))\r\n\r\n const sign = this.scaled.y1 > this.scaled.y2 ? 1 : -1\r\n const radiusX = this.scaled.width / 2\r\n let radiusY = (sign * Math.abs(this.scaled.y1 - this.scaled.y2)) / Math.cos(rotationAngle) / 2\r\n if (this.scaled.y1 === this.scaled.y2) {\r\n radiusY = Math.abs(this.scaled.x1 - this.scaled.x2) / 2\r\n }\r\n\r\n const width_two_thirds = (radiusX * 4) / 3\r\n\r\n const dx1 = Math.sin(rotationAngle) * radiusY\r\n const dy1 = Math.cos(rotationAngle) * radiusY\r\n const dx2 = Math.cos(rotationAngle) * width_two_thirds\r\n const dy2 = Math.sin(rotationAngle) * width_two_thirds\r\n\r\n const x = this.scaled.x1 + dx1\r\n const y = this.scaled.y1 - dy1\r\n\r\n const topCenterX = x - dx1\r\n const topCenterY = y + dy1\r\n const topRightX = topCenterX + dx2\r\n const topRightY = topCenterY + dy2\r\n const topLeftX = topCenterX - dx2\r\n const topLeftY = topCenterY - dy2\r\n\r\n const bottomCenterX = x + dx1\r\n const bottomCenterY = y - dy1\r\n const bottomRightX = bottomCenterX + dx2\r\n const bottomRightY = bottomCenterY + dy2\r\n const bottomLeftX = bottomCenterX - dx2\r\n const bottomLeftY = bottomCenterY - dy2\r\n\r\n const centerRightX = x + dx2\r\n const centerRightY = y + dy2\r\n const centerLeftX = x - dx2\r\n const centerLeftY = y - dy2\r\n\r\n return {\r\n topCenterX,\r\n topCenterY,\r\n topRightX,\r\n topRightY,\r\n topLeftX,\r\n topLeftY,\r\n centerLeftX,\r\n centerLeftY,\r\n centerRightX,\r\n centerRightY,\r\n bottomCenterX,\r\n bottomCenterY,\r\n bottomLeftX,\r\n bottomLeftY,\r\n bottomRightX,\r\n bottomRightY,\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const c = this.getCoordinates()\r\n const left = Math.min(this.scaled.x1, this.scaled.x2, c.centerRightX)\r\n const right = Math.max(this.scaled.x1, this.scaled.x2, c.centerLeftX)\r\n const top = Math.min(this.scaled.y1, this.scaled.y2, c.centerRightY)\r\n const bottom = Math.max(this.scaled.y1, this.scaled.y2, c.centerLeftY)\r\n if (left < area.scaled.x && area.scaled.x < right && top < area.scaled.y && area.scaled.y < bottom) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n getIsInChartView() {\r\n return true\r\n }\r\n}\r\n\r\nEllipse.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1, default: {} },\r\n ],\r\n}\r\n\r\nexport default Ellipse\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\ntype RotatedRectangleCoordiantes = [[number, number], [number, number], [number, number], [number, number]]\r\n\r\nexport interface IRotatedRectangleAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n height: number\r\n fill: string\r\n border: DrawingBorder\r\n}\r\n\r\n// OLD RotatedRectangle \"v0\" kept for backward-compatibiluty for old saved ideas\r\n// current RotatedRectangle tool located in rotated_rectangle folder\r\nclass RotatedRectangle extends Element {\r\n static type = CanvasElementType.rotatedRectangle\r\n\r\n name = 'Rotated rectangle'\r\n\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n const x = this.model.scale.x.invert\r\n const y = this.model.scale.y.invert\r\n this._thumbs = [\r\n new Thumb(\r\n 'ml',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'mr',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'tl',\r\n () => x(this.getRectCoordinates()[0][0]),\r\n () => y(this.getRectCoordinates()[0][1]),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'tr',\r\n () => x(this.getRectCoordinates()[1][0]),\r\n () => y(this.getRectCoordinates()[1][1]),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'bl',\r\n () => x(this.getRectCoordinates()[2][0]),\r\n () => y(this.getRectCoordinates()[2][1]),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'br',\r\n () => x(this.getRectCoordinates()[3][0]),\r\n () => y(this.getRectCoordinates()[3][1]),\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n const boundingPointKeys = this.getBoundingPointKeys()\r\n this.scale({ x: [...boundingPointKeys.x, 'height'], y: boundingPointKeys.y })\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultFill,\r\n border: {\r\n width: 1,\r\n color: ElementSettings.Colors.border,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n context.set('fillStyle', this.attrs.fill)\r\n\r\n context.beginPath()\r\n const coords = this.getRectCoordinates()\r\n for (const point of coords) {\r\n context.lineTo(point[0], point[1])\r\n }\r\n context.lineTo(coords[0][0], coords[0][1])\r\n context.fill()\r\n\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n if ((this.attrs.border != null ? this.attrs.border.width : undefined) !== 0) {\r\n context.stroke()\r\n }\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getRectCoordinates(): RotatedRectangleCoordiantes {\r\n const mx1 = this.scaled.x1\r\n const mx2 = this.scaled.x2\r\n const my1 = this.scaled.y1\r\n const my2 = this.scaled.y2\r\n const { height } = this.scaled\r\n\r\n const k = (my2 - my1) / (mx2 - mx1)\r\n const nk = -1 / k\r\n\r\n const sign = my1 > my2 ? 1 : -1\r\n const dx = (sign * Math.sqrt((height * height) / (1 + nk * nk))) / 2\r\n const dy = nk * dx\r\n\r\n let x1 = mx1 - dx\r\n let y1 = my1 - dy\r\n let x2 = mx2 - dx\r\n let y2 = my2 - dy\r\n\r\n let x3 = mx2 + dx\r\n let y3 = my2 + dy\r\n let x4 = mx1 + dx\r\n let y4 = my1 + dy\r\n\r\n if (my1 === my2) {\r\n x1 = mx1\r\n y1 = my1 - height / 2\r\n x2 = mx2\r\n y2 = my2 - height / 2\r\n\r\n x3 = mx2\r\n y3 = my2 + height / 2\r\n x4 = mx1\r\n y4 = my1 + height / 2\r\n }\r\n\r\n return [\r\n [x1, y1],\r\n [x2, y2],\r\n [x3, y3],\r\n [x4, y4],\r\n ]\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.y1 += y\r\n this.attrs.x2 += x\r\n this.attrs.y2 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'ml':\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n break\r\n case 'mr':\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n break\r\n case 'tl':\r\n case 'tr':\r\n this.attrs.height += difY\r\n break\r\n case 'bl':\r\n case 'br':\r\n this.attrs.height -= difY\r\n break\r\n default:\r\n return\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const coords = this.getRectCoordinates()\r\n const polygon = coords.map((c) => ({ x: c[0], y: c[1] }))\r\n if (math.pointInPolygon(area.scaled, polygon)) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n getIsInChartView() {\r\n return true\r\n }\r\n}\r\n\r\nRotatedRectangle.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1, default: {} },\r\n ],\r\n}\r\n\r\nexport default RotatedRectangle\r\n","// TODO FontAwesome font or similar needs to be loaded before using Symbol\r\nimport { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\nexport interface ISymbolAttrs {\r\n x1: number\r\n scaleX: number\r\n y1: number\r\n scaleY: number\r\n angle: number\r\n fill: string\r\n symbol: string\r\n border: DrawingBorder\r\n}\r\n\r\nclass SymbolElement extends Element {\r\n static type = CanvasElementType.symbol\r\n\r\n name = 'Symbol'\r\n\r\n declare textWidth: number\r\n declare textHeight: number\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n\r\n this.resize = this.resize.bind(this)\r\n\r\n const sx = (sign: number) =>\r\n this.getRotatedCoordinates(this.scaled.x1 + sign * (this.textWidth / 2) * this.attrs.scaleX, this.scaled.y1)\r\n const sy = (sign: number) =>\r\n this.getRotatedCoordinates(this.scaled.x1, this.scaled.y1 + sign * (this.textHeight / 2) * this.attrs.scaleY)\r\n this._thumbs = [\r\n new Thumb(\r\n 'xr',\r\n () => this.model.scale.x.invert(sx(+1).x),\r\n () => this.model.scale.y.invert(sx(+1).y),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'xl',\r\n () => this.model.scale.x.invert(sx(-1).x),\r\n () => this.model.scale.y.invert(sx(-1).y),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'yt',\r\n () => this.model.scale.x.invert(sy(+1).x),\r\n () => this.model.scale.y.invert(sy(+1).y),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'yb',\r\n () => this.model.scale.x.invert(sy(-1).x),\r\n () => this.model.scale.y.invert(sy(-1).y),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'c',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n this.attrs.angle = this.attrs.angle || 0\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1'], y: ['y1'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n context.set('font', '36px FontAwesome')\r\n context.set('fillStyle', this.attrs.fill)\r\n context.set('textAlign', 'left')\r\n context.set('textBaseline', 'top')\r\n\r\n this.textWidth = context.measureText(this.attrs.symbol).width\r\n this.textHeight = 36\r\n const xScale = this.attrs.scaleX\r\n const yScale = this.attrs.scaleY\r\n\r\n const xOffset = this.textWidth / -2\r\n const yOffset = this.textHeight / -2\r\n\r\n context.save()\r\n context.translate(this.scaled.x1, this.scaled.y1)\r\n context.rotate(this.attrs.angle)\r\n context.scale(xScale, yScale)\r\n context.fillText(this.attrs.symbol, xOffset, yOffset)\r\n context.restore()\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getRotatedCoordinates(x: number, y: number) {\r\n const cx = this.scaled.x1\r\n const cy = this.scaled.y1\r\n const dx = x - cx\r\n const dy = y - cy\r\n const rx = dx * Math.cos(this.attrs.angle) - dy * Math.sin(this.attrs.angle)\r\n const ry = dy * Math.cos(this.attrs.angle) + dx * Math.sin(this.attrs.angle)\r\n return { x: cx + rx, y: cy + ry }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n return (this.attrs.y1 += y)\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'xl':\r\n this.attrs.scaleX -= difX\r\n break\r\n case 'xr':\r\n this.attrs.scaleX += difX\r\n break\r\n case 'yt':\r\n this.attrs.scaleY -= difY\r\n break\r\n case 'yb':\r\n this.attrs.scaleY += difY\r\n break\r\n case 'c':\r\n this.attrs.angle += difX / 5\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const halfWidth = (this.textWidth / 2) * this.attrs.scaleX\r\n const halfHeight = (this.textHeight / 2) * this.attrs.scaleY\r\n const left = Math.min(this.scaled.x1 - halfWidth, this.scaled.x1 + halfWidth)\r\n const right = Math.max(this.scaled.x1 - halfWidth, this.scaled.x1 + halfWidth)\r\n const top = Math.min(this.scaled.y1 - halfHeight, this.scaled.y1 + halfHeight)\r\n const bottom = Math.max(this.scaled.y1 - halfHeight, this.scaled.y1 + halfHeight)\r\n if (left < area.scaled.x && area.scaled.x < right && top < area.scaled.y && area.scaled.y < bottom) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nSymbolElement.prototype.defaults = { fill: 'rgba(0,0,0,1)' }\r\n\r\nSymbolElement.prototype.modalConfig = {\r\n inputs: [{ type: 'background', name: 'fill', label: 'Fill' }],\r\n}\r\n\r\nexport default SymbolElement\r\n","import { CanvasElementType } from '../constants/common'\r\nimport arrow from './arrow'\r\nimport brush_v1 from './brush/brush_v1'\r\nimport callout_v1 from './callout/callout_v1'\r\nimport curve from './curve'\r\nimport element from './element'\r\nimport elliottWaves from './elliott_waves/elliott_waves'\r\nimport ellipse from './ellipse'\r\nimport ellipse_v1 from './ellipse/ellipse_v1'\r\nimport fibonacci from './fibonacci_retracements'\r\nimport horizontalLine from './horizontal_line'\r\nimport line from './line'\r\nimport measure from './measure'\r\nimport pitchfork_v1 from './pitchfork/pitchfork_v1'\r\nimport polygon from './polygon'\r\nimport position from './position'\r\nimport rectangle from './rectangle'\r\nimport rotatedRectangle from './rotated_rectangle'\r\nimport rotatedRectangle_v1 from './rotated_rectangle/rotated_rectangle_v1'\r\nimport scaledLine from './scaled_line'\r\nimport scaledText from './scaled_text'\r\nimport symbolElement from './symbol'\r\nimport text from './text'\r\nimport triangle from './triangle'\r\nimport verticalLine from './vertical_line'\r\nimport xabcd from './xabcd'\r\n\r\nexport const drawingToolsByType = Object.freeze({\r\n [CanvasElementType.element]: element,\r\n [CanvasElementType.arrow]: arrow,\r\n [CanvasElementType.brushV1]: brush_v1,\r\n [CanvasElementType.calloutV1]: callout_v1,\r\n [CanvasElementType.curve]: curve,\r\n [CanvasElementType.elliottWaves]: elliottWaves,\r\n [CanvasElementType.ellipse]: ellipse,\r\n [CanvasElementType.ellipseV1]: ellipse_v1,\r\n [CanvasElementType.fibonacciRetracements]: fibonacci,\r\n [CanvasElementType.horizontalLine]: horizontalLine,\r\n [CanvasElementType.line]: line,\r\n [CanvasElementType.measure]: measure,\r\n [CanvasElementType.pitchforkV1]: pitchfork_v1,\r\n [CanvasElementType.polygon]: polygon,\r\n [CanvasElementType.position]: position,\r\n [CanvasElementType.rectangle]: rectangle,\r\n [CanvasElementType.rotatedRectangle]: rotatedRectangle,\r\n [CanvasElementType.rotatedRectangleV1]: rotatedRectangle_v1,\r\n [CanvasElementType.scaledLine]: scaledLine,\r\n [CanvasElementType.scaledText]: scaledText,\r\n [CanvasElementType.symbol]: symbolElement,\r\n [CanvasElementType.text]: text,\r\n [CanvasElementType.triangle]: triangle,\r\n [CanvasElementType.verticalLine]: verticalLine,\r\n [CanvasElementType.xabcd]: xabcd,\r\n})\r\n","import Spine from '@finviz/spine'\r\nimport merge from 'lodash.merge'\r\nimport mergewith from 'lodash.mergewith'\r\nimport omit from 'lodash.omit'\r\n\r\nimport {\r\n ChartConfigChartPaneElement,\r\n ObjectHash,\r\n PaneArea,\r\n RequireByKey,\r\n TodoObjectHashAnyType,\r\n} from '../../types/shared'\r\nimport Thumb from '../canvas/thumb'\r\nimport {\r\n CanvasElementType,\r\n ChartElementType,\r\n ChartEventType,\r\n IVisibility,\r\n IndicatorType,\r\n MacroTimeframe,\r\n MicroMacroTimeframe,\r\n OverlayType,\r\n SetVisibilityTo,\r\n TIMEFRAME,\r\n} from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport PaneModel, { ScaleAxis } from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport { getChartLayoutSettings } from '../models/settings'\r\nimport { isInRange } from '../utils/helpers'\r\n\r\nexport type TodoModalConfig = TodoObjectHashAnyType\r\ntype TodoPositionTimestamps = TodoObjectHashAnyType\r\n\r\nexport interface DefaultAttrs extends ObjectHash {\r\n positionTimestamps?: TodoPositionTimestamps\r\n visibility?: IVisibility\r\n}\r\n\r\nexport type EdgeValues = { minX?: number; maxX?: number; minY?: number; maxY?: number }\r\n\r\nclass Element extends Spine.Module {\r\n static type: CanvasElementType | OverlayType | ChartElementType | IndicatorType | ChartEventType =\r\n CanvasElementType.element\r\n\r\n static fromObject(obj: T['attrs'], model: T['model']) {\r\n return new this(obj, model) as T\r\n }\r\n\r\n static getNumOfBarsBuffer(\r\n _?: RequireByKey | RequireByKey\r\n ) {\r\n return 0\r\n }\r\n\r\n isCreator = false\r\n isCreatorDialogOpen = false\r\n attrs: Attrs = {} as Attrs\r\n\r\n model: any\r\n _thumbs: Thumb[]\r\n\r\n getDefaults?(): Partial\r\n renderCross?(ctx: RenderingContext2DType): void\r\n renderCrossText?(\r\n ctx: RenderingContext2DType,\r\n crossIndex: number,\r\n getDataByCrossIndex?: (key: keyof Quote, shouldReturnRoundedString?: boolean) => string | undefined\r\n ): void\r\n\r\n renderContent?(ctx: RenderingContext2DType): void\r\n renderGrid?(ctx: RenderingContext2DType): void\r\n renderLabels?(ctx: RenderingContext2DType): void\r\n declare defaults?: Partial\r\n getModalConfigBase?(): TodoModalConfig\r\n declare modalConfig?: TodoModalConfig\r\n getMinMax?(): { min: number; max: number }\r\n setupAxis?(fx: ScaleAxis): void | { min: number; max: number }\r\n\r\n activeThumb: Thumb | null = null\r\n isMouseDown = false\r\n isSelected = false\r\n isHovered = false\r\n isEditInProgress = false\r\n edgeXYValues: EdgeValues | null = null\r\n declare scaled?: ObjectHash | Partial\r\n\r\n declare toolsCallback: () => void\r\n\r\n constructor(values: Partial, model: Model) {\r\n super(values, model)\r\n this.model = model\r\n if (this.getDefaults) {\r\n this.set(this.getDefaults() || {})\r\n } else {\r\n this.set(this.defaults || {})\r\n }\r\n this.set(values)\r\n this._thumbs = []\r\n\r\n this.onMouseDown = this.onMouseDown.bind(this)\r\n this.onMouseMove = this.onMouseMove.bind(this)\r\n this.onMouseUp = this.onMouseUp.bind(this)\r\n this.bind('mousedown', this.onMouseDown)\r\n this.bind('mousemove', this.onMouseMove)\r\n this.bind('mouseup', this.onMouseUp)\r\n this.bind('change', () => {\r\n // elements is optional because this.model is not Pane in all usecases, e.g. base_chart extends this element and sets Chart as model\r\n const element = this.getIsChartEvent()\r\n ? this.model.chartEvents?.()?.findByAttribute('instance', this)\r\n : this.model.elements?.()?.findByAttribute('instance', this)\r\n\r\n element?.trigger('change', element)\r\n })\r\n }\r\n\r\n get type() {\r\n return (this.constructor as typeof Element).type\r\n }\r\n\r\n getThumbs() {\r\n return this._thumbs\r\n }\r\n\r\n moveBy(_: number, __: number) {}\r\n\r\n setIsSelected(isSelected: boolean) {\r\n this.isSelected = isSelected\r\n this.trigger('change')\r\n }\r\n\r\n setIsHovered(isHovered: boolean) {\r\n this.isHovered = isHovered\r\n this.trigger('change')\r\n }\r\n\r\n getShouldRenderThumbs() {\r\n return this.isSelected || this.isHovered\r\n }\r\n\r\n getIsPaneSelection(): boolean {\r\n const paneModel = this.model.elements().findByAttribute('instance', this)?.pane() as PaneModel | undefined\r\n return paneModel?.selection === this\r\n }\r\n\r\n set(obj: Partial) {\r\n const attrsSubset = Object.keys(obj).reduce(\r\n (acc, key) => ({ ...acc, [key]: this.attrs[key] }),\r\n {} as Partial\r\n )\r\n if (JSON.stringify(obj) !== JSON.stringify(attrsSubset)) {\r\n const customizer = (objValue: Partial, srcValue: Partial, key: keyof Attrs) => {\r\n if (this.getIsDrawing() && key === 'visibility') {\r\n return srcValue ?? {}\r\n }\r\n }\r\n mergewith(this.attrs, obj, customizer)\r\n if (this.getIsPaneSelection() && !this.getIsCreator()) {\r\n this.cachePointPositionTimestamp()\r\n }\r\n this.trigger('change', this)\r\n }\r\n this.edgeXYValues = null\r\n return this\r\n }\r\n\r\n get(key: T) {\r\n return this.attrs[key]\r\n }\r\n\r\n getBoundingPointKeys = (): { x: string[]; y: string[] } | void => {}\r\n\r\n fx = (x: number) => this.model.scale.x(x)\r\n\r\n fy = (y: number) => this.model.scale.y(y)\r\n\r\n scale({ x, y }: { x: string[]; y: string[] }) {\r\n this.scaled = {}\r\n x.forEach((el) => {\r\n Object.defineProperty(this.scaled, el, {\r\n get: () => this.fx(this.attrs[el]),\r\n })\r\n })\r\n\r\n y.forEach((el) => {\r\n Object.defineProperty(this.scaled, el, {\r\n get: () => this.fy(this.attrs[el]),\r\n })\r\n })\r\n }\r\n\r\n render(_: RenderingContext2DType) {}\r\n\r\n renderThumbs(context: CanvasRenderingContext2D) {\r\n const isHoveredThumbStyle = this.isHovered && !this.isSelected\r\n if (isHoveredThumbStyle) {\r\n context.globalAlpha = 0.5\r\n }\r\n this.getThumbs().map((thumb) => thumb.render(context))\r\n context.globalAlpha = 1\r\n }\r\n\r\n onMouseDown(area: PaneArea) {\r\n this.isMouseDown = true\r\n this.isEditInProgress = true\r\n for (const thumb of this.getThumbs()) {\r\n if (thumb.isInArea(area)) {\r\n this.activeThumb = thumb\r\n this.activeThumb.startEditing(area)\r\n return\r\n }\r\n }\r\n }\r\n\r\n onMouseMove(area: PaneArea) {\r\n if (!area.mouseDown) {\r\n return\r\n }\r\n if (this.activeThumb != null) {\r\n this.activeThumb.moveTo(area)\r\n this.trigger('change')\r\n }\r\n }\r\n\r\n onMouseUp(_?: PaneArea) {\r\n this.isMouseDown = false\r\n this.isEditInProgress = false\r\n this.activeThumb = null\r\n if (!this.getIsCreator() && !this.getIsChartEvent()) {\r\n this.cachePointPositionTimestamp()\r\n }\r\n this.trigger('change', this)\r\n }\r\n\r\n cachePointPositionTimestamp = () => {\r\n const quote = this.model?.chart().quote()\r\n if (quote) {\r\n const { x: xPointKeys } = this.getBoundingPointKeys()!\r\n const positionTimestamps = xPointKeys.reduce((acc, key) => {\r\n const positionX = this.attrs[key]\r\n const timeStamp = positionX && quote.getTimestampFomPositionX(positionX)\r\n return {\r\n ...acc,\r\n [key]: timeStamp,\r\n }\r\n }, {}) as TodoPositionTimestamps\r\n this.set({ positionTimestamps } as Partial)\r\n }\r\n }\r\n\r\n updateScales() {\r\n const quote = this.model.chart().quote()\r\n const { positionTimestamps } = this.attrs\r\n if (!quote || !positionTimestamps) {\r\n // positionTimestamps check is temporary to prevent app from crashing\r\n // caused by corrupted drawings - https://github.com/finvizhq/charts/pull/1386/files\r\n return\r\n }\r\n const pointPoitionsFromTimestamp = Object.entries(positionTimestamps).reduce(\r\n (acc, [key, timestamp]) => ({\r\n ...acc,\r\n [key]: timestamp && quote.getPositionXFromTimestamp(timestamp),\r\n }),\r\n {}\r\n )\r\n this.set(pointPoitionsFromTimestamp)\r\n }\r\n\r\n thumbsAreInArea(area: PaneArea) {\r\n for (const thumb of this.getThumbs()) {\r\n if (thumb.isInArea(area)) {\r\n return true\r\n }\r\n }\r\n return false\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n return this.thumbsAreInArea(area)\r\n }\r\n\r\n isDrawingElementLockedOrInvisible() {\r\n return this.model.chart().chart_layout().isLockDrawingsActive || !this.getIsVisible()\r\n }\r\n\r\n getModalConfig() {\r\n let config\r\n if (this.getModalConfigBase) {\r\n config = merge({}, this.getModalConfigBase())\r\n } else {\r\n config = merge({}, this.modalConfig)\r\n }\r\n if (this.getIsDrawing()) {\r\n config.inputs.push({ type: 'visibility', name: 'visibility', label: 'Visibility' })\r\n }\r\n if (config.title == null) {\r\n config.title = this.name\r\n }\r\n for (const input of config.inputs) {\r\n if (input.default != null) {\r\n input.value = input.default\r\n }\r\n if (this.attrs[input.name] != null) {\r\n input.value = this.attrs[input.name]\r\n }\r\n }\r\n return config\r\n }\r\n\r\n toObject() {\r\n return merge({}, this.attrs, { type: this.type })\r\n }\r\n\r\n toConfig(): T['attrs'] & { type: T['type'] } {\r\n return this.toObject()\r\n }\r\n\r\n getAutosaveOmittedProperties() {\r\n return this.attrs.positionTimestamps ? Object.keys(this.attrs.positionTimestamps) : []\r\n }\r\n\r\n toAutosaveConfig() {\r\n // We don't want to save attrs which are stored in \"position timestamps\" because they are relative to timeframe for example\r\n // so in order to keep drawings in sync across different timeframes we can't rely on its position but we have to rely on \"position timestamps\" and then call updateScales to calculate correct positions for given timeframe\r\n return omit(this.toConfig(), this.getAutosaveOmittedProperties()) as Partial\r\n }\r\n\r\n replaceMyself(element: Element) {\r\n setTimeout(() => {\r\n element.cachePointPositionTimestamp()\r\n const el = this.model.elements().findByAttribute('instance', this)\r\n if (!el) {\r\n // Temporary code below\r\n // additional info gaining for https://finvizcom.sentry.io/issues/3990343438/events/e87ce8b4108341cf81f15ec78707c65e/?project=33153&query=is%3Aunresolved+Cannot+read+properties+of+undefined&referrer=previous-event&statsPeriod=14d&stream_index=0\r\n window.Sentry?.captureMessage('element.ts replaceMyself', {\r\n extra: {\r\n oldElement: {\r\n type: this?.type,\r\n isCreator: this?.isCreator,\r\n isMouseDown: this?.isMouseDown,\r\n isSelected: this?.isSelected,\r\n isHovered: this?.isHovered,\r\n isEditInProgress: this?.isEditInProgress,\r\n },\r\n newElement: {\r\n type: element?.type,\r\n isCreator: element?.isCreator,\r\n isMouseDown: element?.isMouseDown,\r\n isSelected: element?.isSelected,\r\n isHovered: element?.isHovered,\r\n isEditInProgress: element?.isEditInProgress,\r\n },\r\n },\r\n })\r\n } else {\r\n el.replace(element)\r\n }\r\n })\r\n }\r\n\r\n toString() {\r\n return this.name\r\n }\r\n\r\n getIsCreator() {\r\n return this.isCreator\r\n }\r\n\r\n getIsCreatorDialogOpen() {\r\n return this.isCreatorDialogOpen\r\n }\r\n\r\n release() {\r\n this.cachePointPositionTimestamp()\r\n this.unbind()\r\n }\r\n\r\n getChartLayoutSettings() {\r\n return getChartLayoutSettings(this.model.chart().chart_layout())\r\n }\r\n\r\n getIsDrawing() {\r\n return !!this.type.startsWith('canvas/')\r\n }\r\n\r\n getIsChartEvent() {\r\n return !!this?.type.startsWith('chartEvent/')\r\n }\r\n\r\n getIsVisible() {\r\n const { micro, macro } = MicroMacroTimeframe[this.model.chart().quote().timeframe as TIMEFRAME]\r\n const visibility = this.attrs.visibility?.[macro]\r\n\r\n // this.attrs.visibility.minutes === undefined: drawing visible on any minutes timeframe\r\n if (visibility === undefined) return true\r\n // this.attrs.visibility.minutes === {}: drawing invisible on any minutes timeframe\r\n if (Object.keys(visibility).length === 0) return false\r\n // this.attrs.visibility.minutes === {from: 5, to: 15}: drawing visible on minutes TF between 5 & 15 interval\r\n return isInRange({ value: micro, min: visibility.from, max: visibility.to })\r\n }\r\n\r\n setVisibilityTo(setTo: SetVisibilityTo) {\r\n const { macro, micro } = MicroMacroTimeframe[this.model.chart().quote().timeframe as TIMEFRAME]\r\n const currentIndex = Object.keys(MacroTimeframe).indexOf(macro)\r\n\r\n let timeframesToSet: string[] = []\r\n let attrsToSet: { from?: number; to?: number } = {}\r\n\r\n switch (setTo) {\r\n case SetVisibilityTo.currentAndAbove: {\r\n timeframesToSet = Object.keys(MacroTimeframe).filter((key, index) => index < currentIndex)\r\n attrsToSet = { from: micro }\r\n break\r\n }\r\n case SetVisibilityTo.currentAndBelow: {\r\n timeframesToSet = Object.keys(MacroTimeframe).filter((key, index) => index > currentIndex)\r\n attrsToSet = { to: micro }\r\n break\r\n }\r\n case SetVisibilityTo.currentOnly: {\r\n timeframesToSet = Object.keys(MacroTimeframe).filter((key, index) => index !== currentIndex)\r\n attrsToSet = { from: micro, to: micro }\r\n break\r\n }\r\n case SetVisibilityTo.all:\r\n default: {\r\n this.set({ visibility: {} } as Partial)\r\n return\r\n }\r\n }\r\n\r\n this.set({\r\n visibility: Object.assign({}, ...timeframesToSet.map((item) => ({ [item]: {} })), { [macro]: attrsToSet }),\r\n } as Partial)\r\n }\r\n\r\n getEdgeXYValues() {\r\n const { x: xPoints, y: yPoints } = this.getBoundingPointKeys() ?? {}\r\n if (this.edgeXYValues === null) {\r\n const edgeXYValues = {} as EdgeValues\r\n xPoints?.forEach((key) => {\r\n const positionX = this.attrs[key]\r\n if (positionX !== undefined) {\r\n edgeXYValues.minX = Math.min(positionX, edgeXYValues.minX ?? positionX)\r\n edgeXYValues.maxX = Math.max(positionX, edgeXYValues.maxX ?? positionX)\r\n }\r\n })\r\n yPoints?.forEach((key) => {\r\n const positionY = this.attrs[key]\r\n if (positionY !== undefined) {\r\n edgeXYValues.minY = Math.min(positionY, edgeXYValues.minY ?? positionY)\r\n edgeXYValues.maxY = Math.max(positionY, edgeXYValues.maxY ?? positionY)\r\n }\r\n })\r\n\r\n this.edgeXYValues = edgeXYValues\r\n }\r\n\r\n return this.edgeXYValues\r\n }\r\n\r\n getIsInChartView(chart: Chart, options?: { omitX?: boolean; omitY?: boolean }) {\r\n const { minX, maxX, minY, maxY } = this.getEdgeXYValues()\r\n\r\n if (this.getIsCreator()) {\r\n return true\r\n }\r\n\r\n if (!options?.omitX) {\r\n const isMaxXInvalid = maxX === undefined || isNaN(maxX)\r\n const isMinXInvalid = minX === undefined || isNaN(minX)\r\n if (\r\n !isMaxXInvalid &&\r\n !isMinXInvalid &&\r\n !(this.fx(maxX) >= -chart.leftOffset && this.fx(minX) <= -chart.leftOffset + chart.width)\r\n ) {\r\n return false\r\n }\r\n }\r\n\r\n if (!options?.omitY) {\r\n if (minY === undefined || maxY === undefined) {\r\n return true\r\n }\r\n\r\n const topBound = this.model.scale.y.invert(0)\r\n const bottomBound = this.model.scale.y.invert(this.model.height)\r\n return topBound >= minY && bottomBound <= maxY\r\n }\r\n\r\n // If all checks fall through, render element\r\n return true\r\n }\r\n}\r\n\r\nexport default Element\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../../types/shared'\r\nimport { CanvasElementType, TextAlign, TextBaseline } from '../../constants/common'\r\nimport { getOffsetFromLineWidth } from '../../controllers/renderUtils'\r\nimport math from '../../helpers/math'\r\nimport PaneModel from '../../models/pane'\r\nimport Element from '../element'\r\nimport Text from '../text'\r\nimport Thumb from '../thumb'\r\n\r\nexport interface IElliottWavesAttrs {\r\n waves: Array<{ x: number; y: number }>\r\n positionWavesTimestamps?: Array<{ x: number; y: number }>\r\n border: DrawingBorder\r\n}\r\n\r\nclass ElliottWaves extends Element {\r\n static type = CanvasElementType.elliottWaves\r\n\r\n name = 'Elliott Wave'\r\n waves = ['', 'I', 'II', 'III', 'IV', 'V']\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n border: {\r\n width: 2,\r\n color: this.getChartLayoutSettings().ElementSettings.Colors.line,\r\n },\r\n } as Partial\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const offset = getOffsetFromLineWidth(this.attrs.border.width)\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n\r\n context.translate(offset, offset)\r\n context.beginPath()\r\n context.moveTo(Math.round(this.fx(this.attrs.waves[0].x)), Math.round(this.fy(this.attrs.waves[0].y)))\r\n for (const p of this.attrs.waves.slice(1)) {\r\n context.lineTo(Math.round(this.fx(p.x)), Math.round(this.fy(p.y)))\r\n }\r\n context.stroke()\r\n context.translate(offset * -1, offset * -1)\r\n\r\n const text = new Text(\r\n {\r\n font: { size: 8, style: 'bold' },\r\n textBaseline: TextBaseline.middle,\r\n textAlign: TextAlign.center,\r\n fillStyle: this.getChartLayoutSettings().ElementSettings.Colors.textWithoutBackground,\r\n },\r\n this.model\r\n )\r\n for (let i = 0; i < this.attrs.waves.length; i++) {\r\n let y\r\n const p = this.attrs.waves[i]\r\n if (i > 0 && this.attrs.waves[i - 1].y > p.y) {\r\n y = this.fy(p.y) + 8\r\n } else {\r\n y = this.fy(p.y) - 8\r\n }\r\n text.set({ text: this.waves[i], x: this.fx(p.x), y })\r\n text.render(context)\r\n }\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getThumbs() {\r\n return this.attrs.waves.map(\r\n (wave, index) =>\r\n new Thumb(\r\n `${index}`,\r\n () => wave.x,\r\n () => wave.y,\r\n this.resize,\r\n this.model\r\n )\r\n )\r\n }\r\n\r\n cachePointPositionTimestamp = () => {\r\n const quote = this.model?.chart().quote()\r\n if (quote) {\r\n const positionWavesTimestamps = this.attrs.waves.map((wave) => ({\r\n ...wave,\r\n x: quote.getTimestampFomPositionX(wave.x),\r\n }))\r\n\r\n this.set({ positionWavesTimestamps } as Partial)\r\n }\r\n }\r\n\r\n updateScales() {\r\n const quote = this.model.chart().quote()\r\n const { positionWavesTimestamps } = this.attrs\r\n if (!quote || !positionWavesTimestamps) {\r\n // positionWavesTimestamps check is temporary to prevent app from crashing\r\n // caused by corrupted drawings - https://github.com/finvizhq/charts/pull/1386/files\r\n return\r\n }\r\n const waves = positionWavesTimestamps.map((wave) => ({\r\n ...wave,\r\n x: quote.getPositionXFromTimestamp(wave.x),\r\n }))\r\n this.set({ waves } as Partial)\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n for (const point of this.attrs.waves) {\r\n point.x += x\r\n point.y += y\r\n }\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n this.attrs.waves[+type].x += difX\r\n this.attrs.waves[+type].y += difY\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const waves = this.attrs.waves\r\n for (let i = 0; i < waves.length - 1; i++) {\r\n if (\r\n math.distanceToSegment(area.scaled, {\r\n x1: this.fx(waves[i].x),\r\n y1: this.fy(waves[i].y),\r\n x2: this.fx(waves[i + 1].x),\r\n y2: this.fy(waves[i + 1].y),\r\n }) <= 10\r\n ) {\r\n return true\r\n }\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n getAutosaveOmittedProperties() {\r\n return ['waves']\r\n }\r\n}\r\n\r\nElliottWaves.prototype.modalConfig = {\r\n inputs: [{ type: 'line', name: 'border' }],\r\n}\r\n\r\nexport default ElliottWaves\r\n","import { DrawingBorder, PaneArea, Point, ResizeByThumbWithTypeAndDifs } from '../../../types/shared'\r\nimport { CanvasElementType } from '../../constants/common'\r\nimport math from '../../helpers/math'\r\nimport PaneModel from '../../models/pane'\r\nimport { getContextWithCache } from '../../utils/canvas'\r\nimport Element from '../element'\r\nimport Thumb from '../thumb'\r\n\r\nexport interface IEllipseAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n cursorTargetX: number\r\n cursorTargetY: number\r\n\r\n fill: string\r\n border: DrawingBorder\r\n}\r\n\r\ninterface Coordinates {\r\n P1: Point\r\n P2: Point\r\n P3: Point\r\n P4: Point\r\n CP1: Point\r\n CP2: Point\r\n CP3: Point\r\n CP4: Point\r\n}\r\n\r\nclass EllipseV1 extends Element {\r\n static type = CanvasElementType.ellipseV1\r\n\r\n name = 'Ellipse'\r\n\r\n untranslatedContext: CanvasRenderingContext2D | null = null\r\n declare ellipsePath: Path2D\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this.untranslatedContext = getContextWithCache(document.createElement('canvas'))\r\n this._thumbs = [\r\n new Thumb(\r\n 'left',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'right',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'top',\r\n () => this.getEllipsePoints(true).P2.x || this.attrs.x1,\r\n () => this.getEllipsePoints(true).P2.y || this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'bottom',\r\n () => this.getEllipsePoints(true).P4.x || this.attrs.x2,\r\n () => this.getEllipsePoints(true).P4.y || this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultFill,\r\n border: {\r\n width: 1,\r\n color: ElementSettings.Colors.border,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2', 'cursorTargetX'], y: ['y1', 'y2', 'cursorTargetY'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const coordinates = this.getEllipsePoints() as Coordinates\r\n const ellipse = new Path2D()\r\n context.set('fillStyle', this.attrs.fill)\r\n context.beginPath()\r\n if (coordinates.P2.x === coordinates.P3.x || coordinates.P2.y === coordinates.P3.y) {\r\n ellipse.lineTo(coordinates.P1.x, coordinates.P1.y)\r\n ellipse.lineTo(coordinates.P2.x, coordinates.P2.y)\r\n } else {\r\n ellipse.moveTo(coordinates.P4.x, coordinates.P4.y)\r\n ellipse.bezierCurveTo(\r\n coordinates.CP4.x,\r\n coordinates.CP4.y,\r\n coordinates.CP1.x,\r\n coordinates.CP1.y,\r\n coordinates.P2.x,\r\n coordinates.P2.y\r\n )\r\n ellipse.bezierCurveTo(\r\n coordinates.CP2.x,\r\n coordinates.CP2.y,\r\n coordinates.CP3.x,\r\n coordinates.CP3.y,\r\n coordinates.P4.x,\r\n coordinates.P4.y\r\n )\r\n ellipse.closePath()\r\n this.ellipsePath = ellipse\r\n context.fill(ellipse)\r\n }\r\n\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n context.stroke(ellipse)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getEllipsePoints(inverted = false) {\r\n const { x1, x2, y1, y2, cursorTargetX, cursorTargetY } = this.scaled\r\n\r\n const P1 = { x: x2, y: y2 }\r\n const P3 = { x: x1, y: y1 }\r\n\r\n let perpendicularPoint\r\n if (!isNaN(cursorTargetX) && !isNaN(cursorTargetY)) {\r\n const cursor = { x: cursorTargetX, y: cursorTargetY }\r\n const line = { x1, y1, x2, y2 }\r\n const distance = math.distanceToLine(cursor, line)\r\n perpendicularPoint = math.perpendicularPointToLine({\r\n distance,\r\n line,\r\n })\r\n } else {\r\n return {\r\n P1: P3,\r\n P2: P1,\r\n P3: P1,\r\n P4: P3,\r\n }\r\n }\r\n\r\n const lineCenterX = (P1.x + P3.x) / 2\r\n const lineCenterY = (P1.y + P3.y) / 2\r\n const pointOffsetX = perpendicularPoint.x - P1.x\r\n const pointOffsetY = perpendicularPoint.y - P1.y\r\n\r\n const P2 = { x: lineCenterX + pointOffsetX, y: lineCenterY + pointOffsetY }\r\n const P4 = { x: lineCenterX + -1 * pointOffsetX, y: lineCenterY + -1 * pointOffsetY }\r\n const invertX = this.model.scale.x.invert\r\n const invertY = this.model.scale.y.invert\r\n if (inverted) {\r\n return {\r\n P2: { x: invertX(P2.x), y: invertY(P2.y) },\r\n P4: { x: invertX(P4.x), y: invertY(P4.y) },\r\n }\r\n }\r\n\r\n const perpendicularPointEllipseOffsetX = (perpendicularPoint.x - P2.x) / 0.75 - (perpendicularPoint.x - P2.x)\r\n const perpendicularPointEllipseOffsetY = (perpendicularPoint.y - P2.y) / 0.75 - (perpendicularPoint.y - P2.y)\r\n\r\n const P1WithOffsetX = P1.x + perpendicularPointEllipseOffsetX\r\n const P1WithOffsetY = P1.y + perpendicularPointEllipseOffsetY\r\n\r\n const P3WithOffsetX = P3.x - perpendicularPointEllipseOffsetX\r\n const P3WithOffsetY = P3.y - perpendicularPointEllipseOffsetY\r\n\r\n const CP1 = {\r\n x: perpendicularPoint.x + perpendicularPointEllipseOffsetX,\r\n y: perpendicularPoint.y + perpendicularPointEllipseOffsetY,\r\n }\r\n const controlPointOffsetX = CP1.x - P1WithOffsetX\r\n const controlPointOffsetY = CP1.y - P1WithOffsetY\r\n\r\n const CP2 = { x: P3WithOffsetX + controlPointOffsetX, y: P3WithOffsetY + controlPointOffsetY }\r\n const CP3 = { x: P3WithOffsetX + -1 * controlPointOffsetX, y: P3WithOffsetY + -1 * controlPointOffsetY }\r\n const CP4 = { x: P1WithOffsetX + -1 * controlPointOffsetX, y: P1WithOffsetY + -1 * controlPointOffsetY }\r\n\r\n return {\r\n P1,\r\n P2,\r\n P3,\r\n P4,\r\n CP1,\r\n CP2,\r\n CP3,\r\n CP4,\r\n }\r\n }\r\n\r\n getRotatedPointCoordinates = ({\r\n rotationAxisPoint,\r\n pointToRotate,\r\n oldLinePoint,\r\n newLinePoint,\r\n }: {\r\n rotationAxisPoint: { x: number; y: number }\r\n pointToRotate: { x: number; y: number }\r\n oldLinePoint: { x: number; y: number }\r\n newLinePoint: { x: number; y: number }\r\n }) => {\r\n const angle = math.sharedPointLinesAngle({\r\n sharedPoint: rotationAxisPoint,\r\n oldLinePoint,\r\n newLinePoint,\r\n })\r\n const rotatedPoinCoordinates = math.rotatedPointCoordinates({\r\n rotationAxisPoint,\r\n angle,\r\n pointToRotate,\r\n })\r\n return {\r\n x: this.model.scale.x.invert(rotatedPoinCoordinates.x),\r\n y: this.model.scale.y.invert(rotatedPoinCoordinates.y),\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.y1 += y\r\n this.attrs.x2 += x\r\n this.attrs.y2 += y\r\n this.attrs.cursorTargetX += x\r\n this.attrs.cursorTargetY += y\r\n }\r\n\r\n resize({ type, difX, difY, area }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'left':\r\n const newLeftPoint = {\r\n x: this.attrs.x1 + difX,\r\n y: this.attrs.y1 + difY,\r\n }\r\n const leftRotatedCursorPoint = this.getRotatedPointCoordinates({\r\n rotationAxisPoint: { x: this.scaled.x2, y: this.scaled.y2 },\r\n pointToRotate: {\r\n x: this.scaled.cursorTargetX,\r\n y: this.scaled.cursorTargetY,\r\n },\r\n oldLinePoint: { x: this.scaled.x1, y: this.scaled.y1 },\r\n newLinePoint: { x: this.model.scale.x(newLeftPoint.x), y: this.model.scale.y(newLeftPoint.y) },\r\n })\r\n this.attrs = {\r\n ...this.attrs,\r\n x1: newLeftPoint.x,\r\n y1: newLeftPoint.y,\r\n cursorTargetX: leftRotatedCursorPoint.x,\r\n cursorTargetY: leftRotatedCursorPoint.y,\r\n }\r\n break\r\n case 'right':\r\n const newRightPoint = {\r\n x: this.attrs.x2 + difX,\r\n y: this.attrs.y2 + difY,\r\n }\r\n const rightRotatedCursorPoint = this.getRotatedPointCoordinates({\r\n rotationAxisPoint: { x: this.scaled.x1, y: this.scaled.y1 },\r\n pointToRotate: {\r\n x: this.scaled.cursorTargetX,\r\n y: this.scaled.cursorTargetY,\r\n },\r\n oldLinePoint: { x: this.scaled.x2, y: this.scaled.y2 },\r\n newLinePoint: { x: this.model.scale.x(newRightPoint.x), y: this.model.scale.y(newRightPoint.y) },\r\n })\r\n this.attrs = {\r\n ...this.attrs,\r\n x2: newRightPoint.x,\r\n y2: newRightPoint.y,\r\n cursorTargetX: rightRotatedCursorPoint.x,\r\n cursorTargetY: rightRotatedCursorPoint.y,\r\n }\r\n break\r\n case 'top':\r\n case 'bottom':\r\n this.attrs = {\r\n ...this.attrs,\r\n cursorTargetX: area.x,\r\n cursorTargetY: area.y,\r\n }\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n if (this.ellipsePath && this.untranslatedContext?.isPointInPath(this.ellipsePath, area.scaled.x, area.scaled.y)) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n getIsInChartView() {\r\n return true\r\n }\r\n}\r\n\r\nEllipseV1.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1, default: {} },\r\n ],\r\n}\r\n\r\nexport default EllipseV1\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType, TextAlign, TextBaseline } from '../constants/common'\r\nimport { getRoundedObject, getXYOffsetFromLine } from '../controllers/renderUtils'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Text, { ITextAttrs } from './text'\r\nimport Thumb from './thumb'\r\n\r\ntype Coefficients = string\r\n\r\nexport interface IFibonacciRetracementsAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n coefficients: Coefficients\r\n border: DrawingBorder\r\n}\r\n\r\nclass FibonacciRetracements<\r\n Attrs extends IFibonacciRetracementsAttrs = IFibonacciRetracementsAttrs,\r\n> extends Element {\r\n static type = CanvasElementType.fibonacciRetracements\r\n\r\n name = 'Fibonacci Retracements'\r\n declare coefficients: { default: string; parsed: number[]; max: number }\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'oneCoefficient_1',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'oneCoefficient_2',\r\n () => this.attrs.x2,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'zeroCoefficient_1',\r\n () => this.attrs.x1,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'zeroCoefficient_2',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.parseCoefficients(this.attrs.coefficients)\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n border: {\r\n width: 1,\r\n color: this.getChartLayoutSettings().ElementSettings.Colors.line,\r\n },\r\n coefficients: [0, 0.236, 0.382, 0.5, 0.618, 1].toString(),\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n parseCoefficients(coefficients: Coefficients) {\r\n if (!this.coefficients || coefficients !== this.coefficients.default) {\r\n const parsed = coefficients.split(',').map((x) => parseFloat(x.trim()))\r\n this.coefficients = { default: coefficients, parsed, max: Math.max(...parsed) }\r\n }\r\n }\r\n\r\n getMaxCoefficientUnscaledY() {\r\n return this.model.scale.y.invert(this.scaled.y2 - this.coefficients.max * (this.scaled.y2 - this.scaled.y1))\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, y1, y2 } = this.scaled\r\n const roundedXY = getRoundedObject({ x1, x2, y1, y2 })\r\n const translateXY = getXYOffsetFromLine({ lineWidth: this.attrs.border.width, ...roundedXY, y2: roundedXY.y1 })\r\n\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n this.parseCoefficients(this.attrs.coefficients)\r\n\r\n const height = this.attrs.y2 - this.attrs.y1\r\n const heightScaled = roundedXY.y2 - roundedXY.y1\r\n\r\n context.translate(translateXY.x, translateXY.y)\r\n context.beginPath()\r\n for (const p of this.coefficients.parsed) {\r\n context.moveTo(roundedXY.x1, Math.round(y2 - p * heightScaled))\r\n context.lineTo(roundedXY.x2, Math.round(y2 - p * heightScaled))\r\n }\r\n context.stroke()\r\n context.translate(translateXY.x * -1, translateXY.y * -1)\r\n\r\n const text = new Text(\r\n {\r\n x: roundedXY.x1,\r\n font: { size: 8, style: 'bold' },\r\n textBaseline: TextBaseline.bottom,\r\n fillStyle: this.attrs.border.color,\r\n textAlign: TextAlign.left,\r\n },\r\n this.model\r\n )\r\n if (roundedXY.x1 > roundedXY.x2) {\r\n text.set({ textAlign: TextAlign.right })\r\n }\r\n\r\n for (const p of this.coefficients.parsed) {\r\n const y = this.attrs.y2 - p * height\r\n text.set({\r\n text: (p * 100).toFixed(1) + '%: ' + y.toFixed(2),\r\n y: Math.round(this.fy(y) - this.attrs.border.width / 2),\r\n } as Partial)\r\n text.render(context)\r\n }\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getThumbs() {\r\n if (this.coefficients.max > 1 && this._thumbs.length < 6) {\r\n this._thumbs = [\r\n ...this._thumbs,\r\n new Thumb(\r\n 'maxCoefficient_1',\r\n () => this.attrs.x1,\r\n () => this.getMaxCoefficientUnscaledY(),\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'maxCoefficient_2',\r\n () => this.attrs.x2,\r\n () => this.getMaxCoefficientUnscaledY(),\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n }\r\n if (this.coefficients.max <= 1 && this._thumbs.length > 4) {\r\n this._thumbs.splice(4)\r\n }\r\n\r\n return this._thumbs\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.x2 += x\r\n this.attrs.y1 += y\r\n this.attrs.y2 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'oneCoefficient_1':\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n break\r\n case 'oneCoefficient_2':\r\n this.attrs.x2 += difX\r\n this.attrs.y1 += difY\r\n break\r\n case 'zeroCoefficient_1':\r\n this.attrs.x1 += difX\r\n this.attrs.y2 += difY\r\n break\r\n case 'zeroCoefficient_2':\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n break\r\n case 'maxCoefficient_1':\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY / this.coefficients.max\r\n break\r\n case 'maxCoefficient_2':\r\n this.attrs.x2 += difX\r\n this.attrs.y1 += difY / this.coefficients.max\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const maxCoefficientY = this.coefficients.max > 1 && this.getMaxCoefficientUnscaledY()\r\n const left = Math.min(this.attrs.x1, this.attrs.x2)\r\n const right = Math.max(this.attrs.x1, this.attrs.x2)\r\n const top = maxCoefficientY\r\n ? Math.min(this.attrs.y1, this.attrs.y2, maxCoefficientY)\r\n : Math.min(this.attrs.y1, this.attrs.y2)\r\n const bottom = maxCoefficientY\r\n ? Math.max(this.attrs.y1, this.attrs.y2, maxCoefficientY)\r\n : Math.max(this.attrs.y1, this.attrs.y2)\r\n if (left < area.x && area.x < right && top < area.y && area.y < bottom) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nFibonacciRetracements.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'line', name: 'border' },\r\n { type: 'string', name: 'coefficients', label: 'Coefficients' },\r\n ],\r\n}\r\n\r\nexport default FibonacciRetracements\r\n","import { Maybe, RequireByKey, ResizeByThumbFuncProps } from '../../types/shared'\r\nimport { CanvasElementType, TextBaseline } from '../constants/common'\r\nimport math from '../helpers/math'\r\nimport Chart from '../models/chart'\r\nimport PaneModel from '../models/pane'\r\nimport ScaledLine, { IScaledLineAttrs } from './scaled_line'\r\nimport Text from './text'\r\n\r\nconst DEFAULT_DECIMAL_PLACES = 2\r\n\r\nclass HorizontalLine extends ScaledLine {\r\n static type = CanvasElementType.horizontalLine\r\n\r\n name = 'Horizontal line'\r\n decimalPlaces = DEFAULT_DECIMAL_PLACES\r\n declare scaled: Pick\r\n declare model: PaneModel\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n\r\n this.updateDecimalPlaces()\r\n\r\n if (this.attrs.y1) {\r\n this.attrs.y1 = Number(math.round({ value: this.attrs.y1, overridePlaces: this.decimalPlaces }))\r\n }\r\n if (this.modalConfig) {\r\n const step = `0.${'0'.repeat(this.decimalPlaces - 1)}1`\r\n this.modalConfig.inputs[1] = {\r\n ...this.modalConfig.inputs[1],\r\n step,\r\n min: Number(step),\r\n }\r\n }\r\n this.renderContent = this.renderContent.bind(this)\r\n this._thumbs = []\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n updateDecimalPlaces() {\r\n const quote = this.model.chart().quote()\r\n this.decimalPlaces = quote\r\n ? math.getInstrumentDecimalPlaces({\r\n instrument: quote.instrument,\r\n value: quote.lastClose,\r\n })\r\n : DEFAULT_DECIMAL_PLACES\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n this.attrs.y2 = this.attrs.y1\r\n // mixing scaled and unscaled values, do not copy paste as solution\r\n this.attrs.x1 = ChartSettings.left.width * -1\r\n this.attrs.x2 =\r\n this.model\r\n .chart()\r\n .quote()\r\n .getBarIndex(this.model.chart().quote().close.length - 1) + this.model.chart().width\r\n super.renderContent(context)\r\n }\r\n\r\n renderLabels(context: CanvasRenderingContext2D) {\r\n if (this.attrs.y1) {\r\n this.updateDecimalPlaces()\r\n const { ChartSettings, IndicatorSettings } = this.getChartLayoutSettings()\r\n const isIndicatorPane = this.model\r\n .elements()\r\n .all()\r\n .some((element) => element.isIndicator())\r\n const settings = isIndicatorPane ? IndicatorSettings : ChartSettings\r\n context.translate(this.model.chart().width - settings.right.width, settings.top.height)\r\n new Text(\r\n {\r\n x: 6,\r\n y: this.scaled.y1,\r\n font: { size: 8, style: 'bold' },\r\n lineHeight: 8,\r\n padding: {\r\n top: 2,\r\n right: 2,\r\n bottom: 2,\r\n left: 2,\r\n },\r\n fillStyle: '#fff',\r\n background: '#000',\r\n textBaseline: TextBaseline.middle,\r\n text: this.attrs.y1.toFixed(this.decimalPlaces).toString(),\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n }\r\n\r\n moveBy(x: Maybe, y: number) {\r\n this.attrs.y1 += y\r\n }\r\n\r\n resize({ difY }: RequireByKey) {\r\n this.moveBy(0, difY)\r\n }\r\n\r\n getIsInChartView(chart: Chart) {\r\n return super.getIsInChartView(chart, { omitX: true })\r\n }\r\n}\r\n\r\nHorizontalLine.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'line', name: 'border' },\r\n { type: 'number', name: 'y1', label: 'Price', allowDecimal: true },\r\n ],\r\n}\r\n\r\nexport default HorizontalLine\r\n","import { PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport { getRoundedObject, getXYOffsetFromLine } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\ninterface ILineAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n dashLength: number\r\n lineWidth: number\r\n strokeStyle: string\r\n}\r\n\r\nclass Line extends Element {\r\n static type = CanvasElementType.line\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.render = this.render.bind(this)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'l',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'r',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n lineWidth: 1,\r\n strokeStyle: this.getChartLayoutSettings().ElementSettings.Colors.line,\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n render(context: CanvasRenderingContext2D) {\r\n const { x1, y1, x2, y2, lineWidth } = this.attrs\r\n const roundedXY = getRoundedObject({ x1, y1, x2, y2 })\r\n const translateXY = getXYOffsetFromLine({ lineWidth, ...roundedXY })\r\n\r\n context.translate(translateXY.x, translateXY.y)\r\n context.beginPath()\r\n context.set('lineWidth', this.attrs.lineWidth)\r\n context.set('strokeStyle', this.attrs.strokeStyle)\r\n\r\n context.moveTo(roundedXY.x1, roundedXY.y1)\r\n if (this.attrs.dashLength) {\r\n context.setLineDash([this.attrs.dashLength])\r\n }\r\n context.lineTo(roundedXY.x2, roundedXY.y2)\r\n context.stroke()\r\n if (this.attrs.dashLength) {\r\n context.setLineDash([])\r\n }\r\n context.translate(translateXY.x * -1, translateXY.y * -1)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.x2 += x\r\n this.attrs.y1 += y\r\n this.attrs.y2 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n if (type === 'l') {\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n } else {\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n if (math.distanceToSegment(area, this.attrs) <= 10) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nexport default Line\r\n","import { PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType, TextBaseline } from '../constants/common'\r\nimport { getRoundedObject } from '../controllers/renderUtils'\r\nimport PaneModel from '../models/pane'\r\nimport { numberToStringWithUnitsSuffix } from '../utils'\r\nimport { getRoundedString } from '../utils/helpers'\r\nimport Element from './element'\r\nimport Text, { ITextAttrs } from './text'\r\nimport Thumb from './thumb'\r\n\r\ninterface Coordinates {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n}\r\n\r\nexport interface IMeasureAttrs extends Coordinates {\r\n fill: string\r\n}\r\n\r\nclass Measure extends Element {\r\n static type = CanvasElementType.measure\r\n\r\n name = 'Measure'\r\n declare scaled: Pick\r\n\r\n x1Dif: number\r\n x2Dif: number\r\n startingX1: number\r\n startingX2: number\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'tl',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'br',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n this.x1Dif = this.x2Dif = 0\r\n\r\n this.startingX1 = this.attrs.x1\r\n this.startingX2 = this.attrs.x2\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n getVolumeSumString = () => {\r\n const { volume, barIndex }: { volume: number[]; barIndex: number[] } = this.model.chart().quote()\r\n const roundedX1 = Math.round(this.attrs.x1)\r\n const roundedX2 = Math.round(this.attrs.x2)\r\n // min/max values are offset by 1 so there's no value on such index\r\n // and at the same time it won't iterate over unlimited number of nonexisting indexes\r\n const minIndexLimit = barIndex[0] - 1\r\n const maxIndexLimit = barIndex[barIndex.length - 1] + 1\r\n const volMinIndex = Math.min(Math.max(Math.min(roundedX1, roundedX2), minIndexLimit), maxIndexLimit)\r\n const volMaxIndex = Math.min(Math.max(Math.max(roundedX1, roundedX2), minIndexLimit), maxIndexLimit)\r\n\r\n let volumeSum = 0\r\n for (let i = volMinIndex; i <= volMaxIndex; i++) {\r\n const volumeIndex = barIndex.indexOf(i)\r\n if (volumeIndex >= 0) {\r\n volumeSum += volume[volumeIndex]\r\n }\r\n }\r\n\r\n return `Vol ${numberToStringWithUnitsSuffix(volumeSum)}`\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n context.set('fillStyle', this.attrs.fill)\r\n const { x1, x2, y1, y2 } = this.scaled\r\n const roundedXY = getRoundedObject({ x1, x2, y1, y2 })\r\n\r\n const width = roundedXY.x2 - roundedXY.x1\r\n const height = roundedXY.y2 - roundedXY.y1\r\n context.fillRect(x1, roundedXY.y1, width, height)\r\n\r\n const priceDif = this.attrs.y2 - this.attrs.y1\r\n const percentage = (100 / this.attrs.y1) * priceDif\r\n const heightStr = `${priceDif.toFixed(2)} (${percentage.toFixed(2)}%)`\r\n\r\n const text = new Text(\r\n {\r\n text: `${getRoundedString({ number: Math.abs(this.attrs.x2 - this.attrs.x1), numOfDecimalPlaces: 2 })} bars`,\r\n fillStyle: '#333',\r\n font: { size: 10, family: 'Arial', weight: 'bold' },\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.model\r\n )\r\n const baseX = x1 + width / 2\r\n const baseY = roundedXY.y1 + height / 2\r\n let textWidth = text.measure(context)\r\n text.set({\r\n x: baseX - textWidth / 2,\r\n y: baseY - text.getHeight(),\r\n } as Partial)\r\n text.render(context)\r\n\r\n text.set({ text: heightStr })\r\n textWidth = text.measure(context)\r\n text.set({\r\n x: baseX - textWidth / 2,\r\n y: baseY,\r\n } as Partial)\r\n text.render(context)\r\n\r\n text.set({ text: this.getVolumeSumString() })\r\n textWidth = text.measure(context)\r\n text.set({\r\n x: baseX - textWidth / 2,\r\n y: baseY + text.getHeight(),\r\n } as Partial)\r\n text.render(context)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n addToCoordinates(difs: Partial) {\r\n this.attrs.y1 += difs.y1 || 0\r\n this.attrs.y2 += difs.y2 || 0\r\n\r\n this.x1Dif += difs.x1 || 0\r\n this.x2Dif += difs.x2 || 0\r\n\r\n // The reason for adding +1 is to \"ceil\" the number when moving to the left (decreasing bar index)\r\n const newX1 = ~~(this.startingX1 + this.x1Dif) + (this.x1Dif < 0 ? 1 : 0)\r\n if (~~this.attrs.x1 - newX1 !== 0) {\r\n this.attrs.x1 = newX1\r\n }\r\n const newX2 = ~~(this.startingX2 + this.x2Dif) + (this.x2Dif < 0 ? 1 : 0)\r\n if (~~this.attrs.x2 - newX2 !== 0) {\r\n this.attrs.x2 = newX2\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n return this.addToCoordinates({\r\n x1: x,\r\n y1: y,\r\n x2: x,\r\n y2: y,\r\n })\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n if (type === 'tl') {\r\n this.addToCoordinates({ x1: difX, y1: difY })\r\n } else {\r\n this.addToCoordinates({ x2: difX, y2: difY })\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const x1 = Math.round(this.attrs.x1)\r\n const x2 = Math.round(this.attrs.x2)\r\n\r\n const left = Math.min(x1, x2)\r\n const right = Math.max(x1, x2)\r\n const top = Math.min(this.attrs.y1, this.attrs.y2)\r\n const bottom = Math.max(this.attrs.y1, this.attrs.y2)\r\n if (left < area.x && area.x < right && top < area.y && area.y < bottom) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n onMouseDown(paneArea: PaneArea) {\r\n super.onMouseDown(paneArea)\r\n this.startingX1 = this.attrs.x1\r\n this.startingX2 = this.attrs.x2\r\n }\r\n\r\n onMouseUp(paneArea?: PaneArea) {\r\n super.onMouseUp(paneArea)\r\n this.x1Dif = this.x2Dif = 0\r\n }\r\n}\r\n\r\nMeasure.prototype.defaults = { fill: 'rgba(180,220,255,0.8)' }\r\n\r\nMeasure.prototype.modalConfig = {\r\n inputs: [{ type: 'background', name: 'fill' }],\r\n}\r\n\r\nexport default Measure\r\n","import { Point } from '../../../types/shared'\r\nimport { getRoundedObject } from '../../controllers/renderUtils'\r\nimport math from '../../helpers/math'\r\nimport PaneModel from '../../models/pane'\r\nimport { isInRange } from '../../utils/helpers'\r\nimport { ITrendAttrs } from './pitchfork_v1'\r\n\r\ninterface IGetEdgeIntersectionPointArguments {\r\n sides: { x: number; y: number }[][]\r\n rayOrigin: Point\r\n rayDirection: Point\r\n}\r\n\r\nexport const getEdgeIntersectionPoint = ({ sides, rayOrigin, rayDirection }: IGetEdgeIntersectionPointArguments) => {\r\n if (rayOrigin.x === rayDirection.x && rayOrigin.y === rayDirection.y) return rayDirection\r\n\r\n let intersection = rayDirection\r\n let intersectionDistance = 0\r\n for (let index = 0; index < sides.length; index++) {\r\n const rayToLineIntersection = math.getRayToLineSegmentIntersection(\r\n rayOrigin,\r\n rayDirection,\r\n sides[index][0],\r\n sides[index][1]\r\n )\r\n if (rayToLineIntersection) {\r\n const distance = math.distance(rayToLineIntersection, rayOrigin)\r\n if (distance > intersectionDistance && isInRange({ value: distance })) {\r\n intersectionDistance = distance\r\n intersection = { x: rayToLineIntersection.x, y: rayToLineIntersection.y }\r\n }\r\n }\r\n }\r\n\r\n return intersection\r\n}\r\n\r\nexport const getChartVisibleAreaBoundaries = (paneModel: PaneModel) => {\r\n const { left, right, top, bottom } = paneModel.getChartLayoutSettings().ChartSettings\r\n const { leftOffset, width } = paneModel.chart()\r\n\r\n const chartVisibleAreaLeftX = Math.abs(leftOffset)\r\n const chartVisibleAreaRightX = chartVisibleAreaLeftX + width - left.width - right.width\r\n const chartVisibleAreaTopY = 0\r\n const chartVisibleAreaBottomY = paneModel.height - top.height - bottom.height\r\n\r\n const chartVisibleAreaTopLeftPoint = {\r\n x: chartVisibleAreaLeftX,\r\n y: chartVisibleAreaTopY,\r\n }\r\n const chartVisibleAreaTopRightPoint = {\r\n x: chartVisibleAreaRightX,\r\n y: chartVisibleAreaTopY,\r\n }\r\n const chartVisibleAreaBottomLeftPoint = {\r\n x: chartVisibleAreaLeftX,\r\n y: chartVisibleAreaBottomY,\r\n }\r\n const chartVisibleAreaBottomRightPoint = {\r\n x: chartVisibleAreaRightX,\r\n y: chartVisibleAreaBottomY,\r\n }\r\n const topSide = [chartVisibleAreaTopLeftPoint, chartVisibleAreaTopRightPoint]\r\n const rightSide = [chartVisibleAreaTopRightPoint, chartVisibleAreaBottomRightPoint]\r\n const bottomSide = [chartVisibleAreaBottomLeftPoint, chartVisibleAreaBottomRightPoint]\r\n const leftSide = [chartVisibleAreaTopLeftPoint, chartVisibleAreaBottomLeftPoint]\r\n\r\n const sides = [topSide, rightSide, bottomSide, leftSide]\r\n\r\n return sides\r\n}\r\n\r\ninterface IGetPitchforkCoordinates {\r\n paneModel: PaneModel\r\n rayOrigin: Point\r\n rayDirectionControlPoint1: Point\r\n rayDirectionControlPoint2?: Point\r\n trend1: ITrendAttrs\r\n trend2: ITrendAttrs\r\n}\r\n\r\ninterface ILineSegment {\r\n P1: Point\r\n P2: Point\r\n}\r\n\r\ninterface ICoordinates {\r\n medianRay: ILineSegment\r\n trend1Ray1: ILineSegment | undefined\r\n trend1Ray2: ILineSegment | undefined\r\n trend2Ray1: ILineSegment | undefined\r\n trend2Ray2: ILineSegment | undefined\r\n}\r\n\r\nexport const getPitchforkCoordinates = ({\r\n paneModel,\r\n rayOrigin,\r\n rayDirectionControlPoint1,\r\n rayDirectionControlPoint2,\r\n trend1,\r\n trend2,\r\n}: IGetPitchforkCoordinates) => {\r\n const sides = getChartVisibleAreaBoundaries(paneModel)\r\n\r\n const coordinates: ICoordinates = {\r\n medianRay: { P1: rayOrigin, P2: rayDirectionControlPoint1 },\r\n trend1Ray1: undefined,\r\n trend2Ray1: undefined,\r\n trend1Ray2: undefined,\r\n trend2Ray2: undefined,\r\n }\r\n\r\n // If rayDirectionControlPoint2 doesn't exist return only medianRay with rayDirectionControlPoint1 as rayDirection\r\n if (!rayDirectionControlPoint2) {\r\n coordinates.medianRay = {\r\n P1: getRoundedObject(rayOrigin),\r\n P2: getRoundedObject(\r\n getEdgeIntersectionPoint({\r\n sides,\r\n rayOrigin,\r\n rayDirection: rayDirectionControlPoint1,\r\n })\r\n ),\r\n }\r\n return coordinates\r\n }\r\n\r\n const medianRayDirectionPoint = math.getMiddlePointOnLineSegment(rayDirectionControlPoint1, rayDirectionControlPoint2)\r\n const rayOriginToRayDirectionVector = {\r\n x: medianRayDirectionPoint.x - rayOrigin.x,\r\n y: medianRayDirectionPoint.y - rayOrigin.y,\r\n }\r\n\r\n const rayDirectionControlPoint1ToPoint2Vector = {\r\n x: rayDirectionControlPoint1.x - rayDirectionControlPoint2.x,\r\n y: rayDirectionControlPoint1.y - rayDirectionControlPoint2.y,\r\n }\r\n\r\n const normalizedRayDirectionControlPoint1ToPoint2Vector = math.normalizeVector(\r\n rayDirectionControlPoint1ToPoint2Vector\r\n )\r\n\r\n const medianRayDirectionPointToRayDirectionControlPoint1Distance = math.distance(\r\n medianRayDirectionPoint,\r\n rayDirectionControlPoint1\r\n )\r\n\r\n coordinates.medianRay = {\r\n P1: getRoundedObject(rayOrigin),\r\n P2: getRoundedObject(\r\n getEdgeIntersectionPoint({\r\n sides,\r\n rayOrigin,\r\n rayDirection: medianRayDirectionPoint,\r\n })\r\n ),\r\n }\r\n if (trend1.active) {\r\n const trend1Ray = getTrendRayCoordinates({\r\n trend: trend1.trend,\r\n medianToControlPointDistance: medianRayDirectionPointToRayDirectionControlPoint1Distance,\r\n normalizedControlToControlPointVector: normalizedRayDirectionControlPoint1ToPoint2Vector,\r\n rayOriginToRayDirectionVector,\r\n medianRayDirectionPoint,\r\n sides,\r\n })\r\n\r\n coordinates.trend1Ray1 = trend1Ray.trendRay1\r\n coordinates.trend1Ray2 = trend1Ray.trendRay2\r\n }\r\n if (trend2.active) {\r\n const trend2Ray = getTrendRayCoordinates({\r\n trend: trend2.trend,\r\n medianToControlPointDistance: medianRayDirectionPointToRayDirectionControlPoint1Distance,\r\n normalizedControlToControlPointVector: normalizedRayDirectionControlPoint1ToPoint2Vector,\r\n rayOriginToRayDirectionVector,\r\n medianRayDirectionPoint,\r\n sides,\r\n })\r\n\r\n coordinates.trend2Ray1 = trend2Ray.trendRay1\r\n coordinates.trend2Ray2 = trend2Ray.trendRay2\r\n }\r\n\r\n return coordinates\r\n}\r\n\r\ninterface IGetTrendRayCoordinates {\r\n trend: number\r\n medianToControlPointDistance: number\r\n normalizedControlToControlPointVector: Point\r\n rayOriginToRayDirectionVector: Point\r\n medianRayDirectionPoint: Point\r\n sides: Point[][]\r\n}\r\n\r\nconst getTrendRayCoordinates = ({\r\n trend,\r\n medianToControlPointDistance,\r\n normalizedControlToControlPointVector,\r\n rayOriginToRayDirectionVector,\r\n medianRayDirectionPoint,\r\n sides,\r\n}: IGetTrendRayCoordinates) => {\r\n const medianToTrendLineDistance = medianToControlPointDistance * trend\r\n\r\n const trendRayPoint1Origin = math.addPoints(\r\n medianRayDirectionPoint,\r\n math.multiplyVectorByScalar(normalizedControlToControlPointVector, medianToTrendLineDistance)\r\n )\r\n const trendPoint2RayOriginPoint2 = math.subtractPoints(\r\n medianRayDirectionPoint,\r\n math.multiplyVectorByScalar(normalizedControlToControlPointVector, medianToTrendLineDistance)\r\n )\r\n\r\n const trendRayPoint1DirectionPoint = {\r\n x: trendRayPoint1Origin.x + rayOriginToRayDirectionVector.x,\r\n y: trendRayPoint1Origin.y + rayOriginToRayDirectionVector.y,\r\n }\r\n const trendPoint2RayDirectionPoint = {\r\n x: trendPoint2RayOriginPoint2.x + rayOriginToRayDirectionVector.x,\r\n y: trendPoint2RayOriginPoint2.y + rayOriginToRayDirectionVector.y,\r\n }\r\n\r\n return {\r\n trendRay1: {\r\n P1: getRoundedObject(trendRayPoint1Origin),\r\n P2: getRoundedObject(\r\n getEdgeIntersectionPoint({\r\n sides,\r\n rayOrigin: trendRayPoint1Origin,\r\n rayDirection: trendRayPoint1DirectionPoint,\r\n })\r\n ),\r\n },\r\n trendRay2: {\r\n P1: getRoundedObject(trendPoint2RayOriginPoint2),\r\n P2: getRoundedObject(\r\n getEdgeIntersectionPoint({\r\n sides,\r\n rayOrigin: trendPoint2RayOriginPoint2,\r\n rayDirection: trendPoint2RayDirectionPoint,\r\n })\r\n ),\r\n },\r\n }\r\n}\r\n","import { PaneArea, ResizeByThumbWithTypeAndDifs } from '../../../types/shared'\r\nimport { CanvasElementType } from '../../constants/common'\r\nimport { getOffsetFromLineWidth } from '../../controllers/renderUtils'\r\nimport math from '../../helpers/math'\r\nimport Chart from '../../models/chart'\r\nimport PaneModel from '../../models/pane'\r\nimport { getHEXWithSpecificAplha } from '../../utils/colors'\r\nimport Element from '../element'\r\nimport Thumb from '../thumb'\r\nimport { getPitchforkCoordinates } from './pitchfork_utils'\r\n\r\nexport interface ITrendAttrs {\r\n active: boolean\r\n trend: number\r\n color: string\r\n}\r\n\r\nexport interface IPitchforkAttrs {\r\n x1: number\r\n y1: number\r\n x2: number\r\n y2: number\r\n x3: number\r\n y3: number\r\n median: { color: string; width: number }\r\n trend1: ITrendAttrs\r\n trend2: ITrendAttrs\r\n}\r\n\r\nclass Pitchfork extends Element {\r\n static type = CanvasElementType.pitchforkV1\r\n\r\n declare scaled: Pick\r\n name = 'Pitchfork'\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n\r\n this.resize = this.resize.bind(this)\r\n\r\n this._thumbs = [\r\n new Thumb(\r\n 'medianRayOrigin',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'rayDirectionControlPoint1',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'rayDirectionControlPoint2',\r\n () => this.attrs.x3,\r\n () => this.attrs.y3,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n median: { color: '#e72f2f', width: 1 },\r\n trend1: {\r\n color: '#004ad31c',\r\n active: true,\r\n trend: 1,\r\n },\r\n trend2: {\r\n color: '#00ca4e1f',\r\n active: true,\r\n trend: 0.5,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2', 'x3'], y: ['y1', 'y2', 'y3'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, x3, y1, y2, y3 } = this.scaled\r\n\r\n const offset = getOffsetFromLineWidth(this.attrs.median.width)\r\n context.translate(offset, offset)\r\n\r\n const { medianRay, trend1Ray1, trend1Ray2, trend2Ray1, trend2Ray2 } = getPitchforkCoordinates({\r\n paneModel: this.model,\r\n rayOrigin: { x: x1, y: y1 },\r\n rayDirectionControlPoint1: { x: x2, y: y2 },\r\n rayDirectionControlPoint2: Number.isNaN(x3) || Number.isNaN(y3) ? undefined : { x: x3, y: y3 },\r\n trend1: this.attrs.trend1,\r\n trend2: this.attrs.trend2,\r\n })\r\n\r\n context.set('lineWidth', this.attrs.median.width)\r\n\r\n const trendLines = [\r\n { trend: this.attrs.trend1, line1: trend1Ray1, line2: trend1Ray2 },\r\n { trend: this.attrs.trend2, line1: trend2Ray1, line2: trend2Ray2 },\r\n ].sort((a, b) => {\r\n if (Math.abs(a.trend.trend) > Math.abs(b.trend.trend)) {\r\n return -1\r\n }\r\n if (Math.abs(a.trend.trend) < Math.abs(b.trend.trend)) {\r\n return 1\r\n }\r\n return 0\r\n })\r\n\r\n // Draw trend lines and fill\r\n trendLines.forEach((trendLine, trendLineIndex) => {\r\n if (trendLine.line1 && trendLine.line2) {\r\n const { line1, line2 } = trendLine\r\n const solidTrendColor = getHEXWithSpecificAplha(trendLine.trend.color)\r\n const nextTrendLine = trendLines[trendLineIndex + 1]\r\n\r\n context.beginPath()\r\n context.moveTo(line1.P1.x, line1.P1.y)\r\n context.lineTo(line1.P2.x, line1.P2.y)\r\n if (trendLineIndex !== trendLines.length - 1 && nextTrendLine.line1 && nextTrendLine.line2) {\r\n context.lineTo(nextTrendLine.line1.P2.x, nextTrendLine.line1.P2.y)\r\n context.lineTo(nextTrendLine.line1.P1.x, nextTrendLine.line1.P1.y)\r\n context.moveTo(nextTrendLine.line2.P1.x, nextTrendLine.line2.P1.y)\r\n context.lineTo(nextTrendLine.line2.P2.x, nextTrendLine.line2.P2.y)\r\n }\r\n context.lineTo(line2.P2.x, line2.P2.y)\r\n context.lineTo(line2.P1.x, line2.P1.y)\r\n context.closePath()\r\n context.set('fillStyle', trendLine.trend.color)\r\n context.fill()\r\n\r\n context.beginPath()\r\n context.moveTo(line1.P1.x, line1.P1.y)\r\n context.lineTo(line1.P2.x, line1.P2.y)\r\n context.moveTo(line2.P1.x, line2.P1.y)\r\n context.lineTo(line2.P2.x, line2.P2.y)\r\n context.set('strokeStyle', solidTrendColor)\r\n context.stroke()\r\n }\r\n })\r\n\r\n // Draw median ray line\r\n context.beginPath()\r\n context.moveTo(medianRay.P1.x, medianRay.P1.y)\r\n context.lineTo(medianRay.P2.x, medianRay.P2.y)\r\n\r\n // Draw line between outer trend lines origin points or if smaller than 1 between direction control points\r\n const outerTrendLines =\r\n trendLines.filter(\r\n (item) => item.line1 && item.line2 && item.trend.active && Math.abs(item.trend.trend) >= 1\r\n )[0] ?? {}\r\n\r\n if (outerTrendLines.line1 && outerTrendLines.line2) {\r\n context.moveTo(outerTrendLines.line1.P1.x, outerTrendLines.line1.P1.y)\r\n context.lineTo(outerTrendLines.line2.P1.x, outerTrendLines.line2.P1.y)\r\n } else if (!Number.isNaN(x3) && !Number.isNaN(y3)) {\r\n context.moveTo(x2, y2)\r\n context.lineTo(x3, y3)\r\n }\r\n\r\n context.set('strokeStyle', this.attrs.median.color)\r\n context.stroke()\r\n\r\n context.translate(offset * -1, offset * -1)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.y1 += y\r\n this.attrs.x2 += x\r\n this.attrs.y2 += y\r\n this.attrs.x3 += x\r\n this.attrs.y3 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'medianRayOrigin':\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n break\r\n case 'rayDirectionControlPoint1':\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n break\r\n case 'rayDirectionControlPoint2':\r\n this.attrs.x3 += difX\r\n this.attrs.y3 += difY\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const { x1, x2, x3, y1, y2, y3 } = this.scaled\r\n const { medianRay, trend1Ray1, trend1Ray2, trend2Ray1, trend2Ray2 } = getPitchforkCoordinates({\r\n paneModel: this.model,\r\n rayOrigin: { x: x1, y: y1 },\r\n rayDirectionControlPoint1: { x: x2, y: y2 },\r\n rayDirectionControlPoint2: Number.isNaN(x3) || Number.isNaN(y3) ? undefined : { x: x3, y: y3 },\r\n trend1: this.attrs.trend1,\r\n trend2: this.attrs.trend2,\r\n })\r\n const outerTrendLines =\r\n Math.abs(this.attrs.trend1.trend) > Math.abs(this.attrs.trend2.trend)\r\n ? { line1: trend1Ray1, line2: trend1Ray2 }\r\n : { line1: trend2Ray1, line2: trend2Ray2 }\r\n\r\n if (\r\n math.distanceToSegment(area.scaled, {\r\n x1: medianRay.P1.x,\r\n y1: medianRay.P1.y,\r\n x2: medianRay.P2.x,\r\n y2: medianRay.P2.y,\r\n }) <= 10\r\n ) {\r\n // cursor is near median ray\r\n return true\r\n } else if (\r\n !Number.isNaN(x3) &&\r\n !Number.isNaN(y3) &&\r\n math.distanceToSegment(area.scaled, {\r\n x1: x2,\r\n y1: y2,\r\n x2: x3,\r\n y2: y3,\r\n }) <= 10\r\n ) {\r\n // cursor is near line connecting direction control points\r\n return true\r\n } else if (\r\n outerTrendLines.line1 &&\r\n outerTrendLines.line2 &&\r\n math.pointInPolygon(area.scaled, [\r\n outerTrendLines.line1.P1,\r\n outerTrendLines.line1.P2,\r\n outerTrendLines.line2.P2,\r\n outerTrendLines.line2.P1,\r\n ])\r\n ) {\r\n // cursor is on polygon created by outer trend lines\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n getIsInChartView(_: Chart) {\r\n return true\r\n }\r\n}\r\n\r\nPitchfork.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'line', name: 'median' },\r\n { type: 'trend', name: 'trend1' },\r\n { type: 'trend', name: 'trend2' },\r\n ],\r\n}\r\n\r\nexport default Pitchfork\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport { getOffsetFromLineWidth } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Element, { EdgeValues } from './element'\r\nimport Thumb from './thumb'\r\n\r\ntype Points = Array<{ x: number; y: number }>\r\n\r\nexport interface IPolygonAttrs {\r\n points: Points\r\n fill: string\r\n border: DrawingBorder\r\n positionPointsTimestamps?: Points\r\n}\r\n\r\nclass Polygon extends Element {\r\n static type = CanvasElementType.polygon\r\n\r\n name = 'Polygon'\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this.attrs.fill = this.attrs.fill || 'rgba(50, 60, 70, 0.8)'\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultFill,\r\n border: {\r\n width: 1,\r\n color: ElementSettings.Colors.border,\r\n },\r\n } as Partial\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n context.set('fillStyle', this.attrs.fill)\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n\r\n const offset = getOffsetFromLineWidth(this.attrs.border.width)\r\n context.translate(offset, offset)\r\n\r\n const { points } = this.attrs\r\n context.beginPath()\r\n context.moveTo(this.fx(points[0].x), this.fy(points[0].y))\r\n for (const p of points.slice(1)) {\r\n context.lineTo(this.fx(p.x), this.fy(p.y))\r\n }\r\n\r\n if (this.isPolygon()) {\r\n context.closePath()\r\n context.fill()\r\n }\r\n context.translate(offset * -1, offset * -1)\r\n if ((this.attrs.border != null ? this.attrs.border.width : undefined) !== 0) {\r\n context.stroke()\r\n }\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getThumbs() {\r\n return this.attrs.points.map(\r\n (point, index) =>\r\n new Thumb(\r\n `${index}`,\r\n () => point.x,\r\n () => point.y,\r\n this.resize,\r\n this.model\r\n )\r\n )\r\n }\r\n\r\n cachePointPositionTimestamp = () => {\r\n const quote = this.model?.chart()?.quote()\r\n if (quote) {\r\n const positionPointsTimestamps = this.attrs.points.map((point) => ({\r\n ...point,\r\n x: quote.getTimestampFomPositionX(point.x),\r\n }))\r\n\r\n this.set({ positionPointsTimestamps } as Partial)\r\n }\r\n }\r\n\r\n updateScales() {\r\n const quote = this.model.chart().quote()\r\n const { positionPointsTimestamps } = this.attrs\r\n if (!quote || !positionPointsTimestamps) {\r\n // positionWavesTimestamps check is temporary to prevent app from crashing\r\n // caused by corrupted drawings - https://github.com/finvizhq/charts/pull/1386/files\r\n return\r\n }\r\n const points = positionPointsTimestamps.map((point) => ({\r\n ...point,\r\n x: quote.getPositionXFromTimestamp(point.x),\r\n }))\r\n this.set({ points } as Partial)\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n for (const point of this.attrs.points) {\r\n point.x += x\r\n point.y += y\r\n }\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n const last = this.attrs.points.length - 1\r\n if (this.isPolygon() && (+type === 0 || +type === last)) {\r\n this.attrs.points[0].x += difX\r\n this.attrs.points[0].y += difY\r\n this.attrs.points[last].x += difX\r\n this.attrs.points[last].y += difY\r\n } else {\r\n this.attrs.points[+type].x += difX\r\n this.attrs.points[+type].y += difY\r\n }\r\n }\r\n\r\n isPolygon() {\r\n return (\r\n this.attrs.points[0].x === this.attrs.points.last()?.x && this.attrs.points[0].y === this.attrs.points.last()?.y\r\n )\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const scaledPoints = this.attrs.points.map((p) => ({\r\n x: this.fx(p.x),\r\n y: this.fy(p.y),\r\n }))\r\n if (this.isPolygon()) {\r\n if (math.pointInPolygon(area.scaled, scaledPoints)) {\r\n return true\r\n }\r\n } else {\r\n for (let i = 0; i < scaledPoints.length - 1; i++) {\r\n if (\r\n math.distanceToSegment(area.scaled, {\r\n x1: scaledPoints[i].x,\r\n y1: scaledPoints[i].y,\r\n x2: scaledPoints[i + 1].x,\r\n y2: scaledPoints[i + 1].y,\r\n }) <= 10\r\n ) {\r\n return true\r\n }\r\n }\r\n }\r\n\r\n return super.isInArea(area)\r\n }\r\n\r\n getAutosaveOmittedProperties() {\r\n return ['points']\r\n }\r\n\r\n getEdgeXYValues() {\r\n if (this.edgeXYValues === null) {\r\n const edgeXYValues = {} as EdgeValues\r\n this.attrs.points.forEach(({ x, y }) => {\r\n const xPoint = x\r\n const yPoint = y\r\n edgeXYValues.minX = Math.min(xPoint, edgeXYValues.minX ?? xPoint)\r\n edgeXYValues.minY = Math.min(yPoint, edgeXYValues.minY ?? yPoint)\r\n edgeXYValues.maxX = Math.max(xPoint, edgeXYValues.maxX ?? xPoint)\r\n edgeXYValues.maxY = Math.max(yPoint, edgeXYValues.maxY ?? yPoint)\r\n })\r\n\r\n this.edgeXYValues = edgeXYValues\r\n }\r\n\r\n return this.edgeXYValues\r\n }\r\n}\r\n\r\nPolygon.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1, default: {} },\r\n ],\r\n}\r\n\r\nexport default Polygon\r\n","import { PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType, TextBaseline } from '../constants/common'\r\nimport { getRoundedObject } from '../controllers/renderUtils'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Text, { ITextAttrs } from './text'\r\nimport Thumb from './thumb'\r\n\r\ninterface Coordinates {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n}\r\n\r\nexport interface IPositionAttrs extends Coordinates {\r\n targetColor: string\r\n stopColor: string\r\n targetY: number\r\n centerY: number\r\n stopY: number\r\n}\r\n\r\nclass Position extends Element {\r\n static type = CanvasElementType.position\r\n\r\n name = 'Position'\r\n\r\n declare scaled: Pick\r\n\r\n x1Dif: number\r\n x2Dif: number\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 't1',\r\n () => this.attrs.x1,\r\n () => this.attrs.targetY,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 't2',\r\n () => this.attrs.x2,\r\n () => this.attrs.targetY,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 's1',\r\n () => this.attrs.x1,\r\n () => this.attrs.stopY,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 's2',\r\n () => this.attrs.x2,\r\n () => this.attrs.stopY,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'c1',\r\n () => this.attrs.x1,\r\n () => this.attrs.centerY,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'c2',\r\n () => this.attrs.x2,\r\n () => this.attrs.centerY,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n this.x1Dif = this.x2Dif = 0\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['targetY', 'centerY', 'stopY'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, targetY, centerY, stopY } = this.scaled\r\n const roundedXY = getRoundedObject({ x1, x2, targetY, centerY, stopY })\r\n let sign, stopBaseline, targetBaseline\r\n const width = roundedXY.x2 - roundedXY.x1\r\n\r\n context.set('fillStyle', this.attrs.targetColor)\r\n context.fillRect(roundedXY.x1, roundedXY.targetY, width, roundedXY.centerY - roundedXY.targetY)\r\n\r\n context.set('fillStyle', this.attrs.stopColor)\r\n context.fillRect(roundedXY.x1, roundedXY.centerY, width, roundedXY.stopY - roundedXY.centerY)\r\n\r\n const targetDif = Math.abs(this.attrs.targetY - this.attrs.centerY)\r\n const targetPerc = (100 / this.attrs.centerY) * targetDif\r\n const targetStr = `Target: ${targetDif.toFixed(2)} (${targetPerc.toFixed(2)}%)`\r\n\r\n const stopDif = Math.abs(this.attrs.stopY - this.attrs.centerY)\r\n const stopPerc = (100 / this.attrs.centerY) * stopDif\r\n const stopStr = `Stop: ${stopDif.toFixed(2)} (${stopPerc.toFixed(2)}%)`\r\n\r\n if (this.attrs.targetY > this.attrs.centerY) {\r\n sign = 1\r\n targetBaseline = TextBaseline.bottom\r\n stopBaseline = TextBaseline.top\r\n } else {\r\n sign = -1\r\n targetBaseline = TextBaseline.top\r\n stopBaseline = TextBaseline.bottom\r\n }\r\n\r\n const text = new Text(\r\n {\r\n text: targetStr,\r\n fillStyle: this.getChartLayoutSettings().ElementSettings.Colors.textWithoutBackground,\r\n font: { size: 10, family: 'Arial', weight: 'bold' },\r\n y: roundedXY.targetY - sign * 4,\r\n textBaseline: targetBaseline,\r\n },\r\n this.model\r\n )\r\n let textWidth = text.measure(context)\r\n text.set({ x: roundedXY.x1 + width / 2 - textWidth / 2 } as Partial)\r\n text.render(context)\r\n\r\n text.set({\r\n text: stopStr,\r\n y: roundedXY.stopY + sign * 4,\r\n textBaseline: stopBaseline,\r\n })\r\n textWidth = text.measure(context)\r\n text.set({ x: roundedXY.x1 + width / 2 - textWidth / 2 } as Partial)\r\n text.render(context)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n addToCoordinates(difs: Partial) {\r\n let middle, middle1, result\r\n if (difs.targetY) {\r\n result = this.attrs.targetY + difs.targetY\r\n if (\r\n (this.attrs.targetY > this.attrs.centerY && result < this.attrs.centerY) ||\r\n (this.attrs.targetY < this.attrs.centerY && result > this.attrs.centerY)\r\n ) {\r\n this.attrs.stopY = this.attrs.centerY - (this.attrs.stopY - this.attrs.centerY) // swap target&stop\r\n }\r\n this.attrs.targetY = result\r\n }\r\n\r\n if (difs.stopY) {\r\n result = this.attrs.stopY + difs.stopY\r\n if (\r\n (this.attrs.stopY > this.attrs.centerY && result < this.attrs.centerY) ||\r\n (this.attrs.stopY < this.attrs.centerY && result > this.attrs.centerY)\r\n ) {\r\n this.attrs.targetY = this.attrs.centerY - (this.attrs.targetY - this.attrs.centerY) // swap target&stop\r\n }\r\n this.attrs.stopY = result\r\n }\r\n\r\n if (\r\n difs.centerY &&\r\n ((this.attrs.stopY < (middle = this.attrs.centerY + difs.centerY) && middle < this.attrs.targetY) ||\r\n (this.attrs.stopY > (middle1 = this.attrs.centerY + difs.centerY) && middle1 > this.attrs.targetY))\r\n ) {\r\n this.attrs.centerY += difs.centerY\r\n }\r\n\r\n this.x1Dif += difs.x1 || 0\r\n this.x2Dif += difs.x2 || 0\r\n const roundDif = ~~this.x1Dif || ~~this.x2Dif\r\n if (roundDif !== 0) {\r\n if (difs.x1 != null) {\r\n this.attrs.x1 += roundDif\r\n }\r\n if (difs.x2 != null) {\r\n this.attrs.x2 += roundDif\r\n }\r\n this.x1Dif = this.x2Dif = 0\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n return this.addToCoordinates({\r\n x1: x,\r\n x2: x,\r\n targetY: y,\r\n centerY: y,\r\n stopY: y,\r\n })\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n const [coordType, coordIndex] = (type as string).split('')\r\n const yPoints: Record = { t: 'targetY', c: 'centerY', s: 'stopY' }\r\n const obj: Partial = {\r\n [`x${coordIndex}`]: difX,\r\n [yPoints[coordType]]: difY,\r\n }\r\n return this.addToCoordinates(obj)\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const x1 = Math.round(this.attrs.x1)\r\n const x2 = Math.round(this.attrs.x2)\r\n const left = Math.min(x1, x2)\r\n const right = Math.max(x1, x2)\r\n const top = Math.min(this.attrs.targetY, this.attrs.stopY)\r\n const bottom = Math.max(this.attrs.targetY, this.attrs.stopY)\r\n if (left < area.x && area.x < right && top < area.y && area.y < bottom) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nPosition.prototype.defaults = {\r\n targetColor: 'rgba(0,200,0,0.3)',\r\n stopColor: 'rgba(200,0,0,0.3)',\r\n}\r\n\r\nPosition.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'targetColor' },\r\n { type: 'background', name: 'stopColor' },\r\n ],\r\n}\r\n\r\nexport default Position\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport { getOffsetFromLineWidth, getRoundedObject } from '../controllers/renderUtils'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\nexport interface IRectangleAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n fill: string\r\n border: DrawingBorder\r\n}\r\n\r\nclass Rectangle extends Element {\r\n static type = CanvasElementType.rectangle\r\n\r\n name = 'Rectangle'\r\n\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'br',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'tl',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultFill,\r\n border: {\r\n width: 1,\r\n color: ElementSettings.Colors.border,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, y1, y2 } = this.scaled\r\n const roundedXY = getRoundedObject({ x1, x2, y1, y2 })\r\n const width = roundedXY.x2 - roundedXY.x1\r\n const height = roundedXY.y2 - roundedXY.y1\r\n\r\n context.set('fillStyle', this.attrs.fill)\r\n\r\n context.fillRect(roundedXY.x1, roundedXY.y1, width, height)\r\n\r\n if ((this.attrs.border != null ? this.attrs.border.width : undefined) !== 0) {\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n const offset = getOffsetFromLineWidth(this.attrs.border.width)\r\n context.strokeRect(roundedXY.x1 + offset, roundedXY.y1 + offset, width, height)\r\n }\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.x2 += x\r\n this.attrs.y1 += y\r\n this.attrs.y2 += y\r\n\r\n // @todo - Live sync of elements while they are being moved around\r\n // In order to have live sync across charts we need to trigger change so listeners can update other charts with new values\r\n // this.set(this.attrs)\r\n // this.trigger('change', this)\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n if (type === 'tl') {\r\n this.attrs.x1 += difX\r\n return (this.attrs.y1 += difY)\r\n } else {\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const left = Math.min(this.attrs.x1, this.attrs.x2)\r\n const right = Math.max(this.attrs.x1, this.attrs.x2)\r\n const top = Math.min(this.attrs.y1, this.attrs.y2)\r\n const bottom = Math.max(this.attrs.y1, this.attrs.y2)\r\n if (left < area.x && area.x < right && top < area.y && area.y < bottom) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nRectangle.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1, default: {} },\r\n ],\r\n}\r\n\r\nexport default Rectangle\r\n","import { DrawingBorder, PaneArea, Point, ResizeByThumbWithTypeAndDifs } from '../../../types/shared'\r\nimport { CanvasElementType } from '../../constants/common'\r\nimport { getOffsetFromLineWidth, getRoundedObject } from '../../controllers/renderUtils'\r\nimport math from '../../helpers/math'\r\nimport PaneModel from '../../models/pane'\r\nimport Element from '../element'\r\nimport Thumb from '../thumb'\r\n\r\nexport interface IRotatedRectangleV1Attrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n cursorTargetX: number\r\n cursorTargetY: number\r\n fill: string\r\n border: DrawingBorder\r\n}\r\n\r\nclass RotatedRectangleV1 extends Element {\r\n static type = CanvasElementType.rotatedRectangleV1\r\n\r\n name = 'New Rotated Rectangle'\r\n\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.resize = this.resize.bind(this)\r\n this._thumbs = [\r\n new Thumb(\r\n 'middleLeft',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'middleRight',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'topRight',\r\n () => this.getRectCoordinates(true).P1.x || this.attrs.x2,\r\n () => this.getRectCoordinates(true).P1.y || this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'topLeft',\r\n () => this.getRectCoordinates(true).P2.x || this.attrs.x2,\r\n () => this.getRectCoordinates(true).P2.y || this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'bottomLeft',\r\n () => this.getRectCoordinates(true).P3.x || this.attrs.x1,\r\n () => this.getRectCoordinates(true).P3.y || this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'bottomRight',\r\n () => this.getRectCoordinates(true).P4.x || this.attrs.x1,\r\n () => this.getRectCoordinates(true).P4.y || this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultFill,\r\n border: {\r\n width: 1,\r\n color: ElementSettings.Colors.border,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2', 'cursorTargetX'], y: ['y1', 'y2', 'cursorTargetY'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { P1, P2, P3, P4 } = this.getRectCoordinates()\r\n const roundedXY = {\r\n P1: getRoundedObject(P1),\r\n P2: getRoundedObject(P2),\r\n P3: getRoundedObject(P3),\r\n P4: getRoundedObject(P4),\r\n }\r\n const offset = getOffsetFromLineWidth(this.attrs.border.width)\r\n context.set('fillStyle', this.attrs.fill)\r\n\r\n context.translate(offset, offset)\r\n context.beginPath()\r\n if (roundedXY.P1.x === roundedXY.P4.x && roundedXY.P1.y === roundedXY.P4.y) {\r\n context.lineTo(roundedXY.P1.x, roundedXY.P1.y)\r\n context.lineTo(roundedXY.P2.x, roundedXY.P2.y)\r\n } else {\r\n context.lineTo(roundedXY.P1.x, roundedXY.P1.y)\r\n context.lineTo(roundedXY.P2.x, roundedXY.P2.y)\r\n context.lineTo(roundedXY.P3.x, roundedXY.P3.y)\r\n context.lineTo(roundedXY.P4.x, roundedXY.P4.y)\r\n context.closePath()\r\n context.fill()\r\n }\r\n context.translate(offset * -1, offset * -1)\r\n\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n context.stroke()\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n getRectCoordinates(inverted = false) {\r\n const { x1, x2, y1, y2, cursorTargetX, cursorTargetY } = this.scaled\r\n let perpendicularPoint\r\n if (!isNaN(cursorTargetX) && !isNaN(cursorTargetY)) {\r\n const cursor = { x: cursorTargetX, y: cursorTargetY }\r\n const line = { x1, y1, x2, y2 }\r\n const distance = math.distanceToLine(cursor, line)\r\n perpendicularPoint = math.perpendicularPointToLine({\r\n distance,\r\n line,\r\n })\r\n } else {\r\n return {\r\n P1: { x: x2, y: y2 },\r\n P2: { x: x1, y: y1 },\r\n P3: { x: x1, y: y1 },\r\n P4: { x: x2, y: y2 },\r\n }\r\n }\r\n\r\n const pointOffsetX = perpendicularPoint.x - x2\r\n const pointOffsetY = perpendicularPoint.y - y2\r\n\r\n const P1 = { x: x2 + pointOffsetX, y: y2 + pointOffsetY }\r\n const P2 = { x: x1 + pointOffsetX, y: y1 + pointOffsetY }\r\n const P3 = { x: x1 + -1 * pointOffsetX, y: y1 + -1 * pointOffsetY }\r\n const P4 = { x: x2 + -1 * pointOffsetX, y: y2 + -1 * pointOffsetY }\r\n\r\n const invertX = this.model.scale.x.invert\r\n const invertY = this.model.scale.y.invert\r\n if (inverted) {\r\n return {\r\n P1: { x: invertX(P1.x), y: invertY(P1.y) },\r\n P2: { x: invertX(P2.x), y: invertY(P2.y) },\r\n P3: { x: invertX(P3.x), y: invertY(P3.y) },\r\n P4: { x: invertX(P4.x), y: invertY(P4.y) },\r\n }\r\n }\r\n return { P1, P2, P3, P4 }\r\n }\r\n\r\n getRotatedPointCoordinates = ({\r\n rotationAxisPoint,\r\n pointToRotate,\r\n oldLinePoint,\r\n newLinePoint,\r\n }: {\r\n rotationAxisPoint: Point\r\n pointToRotate: Point\r\n oldLinePoint: Point\r\n newLinePoint: Point\r\n }) => {\r\n const angle = math.sharedPointLinesAngle({\r\n sharedPoint: rotationAxisPoint,\r\n oldLinePoint,\r\n newLinePoint,\r\n })\r\n const rotatedPoinCoordinates = math.rotatedPointCoordinates({\r\n rotationAxisPoint,\r\n angle,\r\n pointToRotate,\r\n })\r\n return {\r\n x: this.model.scale.x.invert(rotatedPoinCoordinates.x),\r\n y: this.model.scale.y.invert(rotatedPoinCoordinates.y),\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.y1 += y\r\n this.attrs.x2 += x\r\n this.attrs.y2 += y\r\n this.attrs.cursorTargetX += x\r\n this.attrs.cursorTargetY += y\r\n }\r\n\r\n resize({ type, difX, difY, area }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'middleLeft':\r\n const newMiddleLeftPoint = {\r\n x: this.attrs.x1 + difX,\r\n y: this.attrs.y1 + difY,\r\n }\r\n const middleLeftRotatedCursorPoint = this.getRotatedPointCoordinates({\r\n rotationAxisPoint: { x: this.scaled.x2, y: this.scaled.y2 },\r\n pointToRotate: {\r\n x: this.scaled.cursorTargetX,\r\n y: this.scaled.cursorTargetY,\r\n },\r\n oldLinePoint: { x: this.scaled.x1, y: this.scaled.y1 },\r\n newLinePoint: { x: this.model.scale.x(newMiddleLeftPoint.x), y: this.model.scale.y(newMiddleLeftPoint.y) },\r\n })\r\n this.attrs = {\r\n ...this.attrs,\r\n x1: newMiddleLeftPoint.x,\r\n y1: newMiddleLeftPoint.y,\r\n cursorTargetX: middleLeftRotatedCursorPoint.x,\r\n cursorTargetY: middleLeftRotatedCursorPoint.y,\r\n }\r\n break\r\n case 'middleRight':\r\n const newMiddleRightPoint = {\r\n x: this.attrs.x2 + difX,\r\n y: this.attrs.y2 + difY,\r\n }\r\n const middleRightRotatedCursorPoint = this.getRotatedPointCoordinates({\r\n rotationAxisPoint: { x: this.scaled.x1, y: this.scaled.y1 },\r\n pointToRotate: {\r\n x: this.scaled.cursorTargetX,\r\n y: this.scaled.cursorTargetY,\r\n },\r\n oldLinePoint: { x: this.scaled.x2, y: this.scaled.y2 },\r\n newLinePoint: { x: this.model.scale.x(newMiddleRightPoint.x), y: this.model.scale.y(newMiddleRightPoint.y) },\r\n })\r\n this.attrs = {\r\n ...this.attrs,\r\n x2: newMiddleRightPoint.x,\r\n y2: newMiddleRightPoint.y,\r\n cursorTargetX: middleRightRotatedCursorPoint.x,\r\n cursorTargetY: middleRightRotatedCursorPoint.y,\r\n }\r\n break\r\n case 'topRight':\r\n case 'topLeft':\r\n case 'bottomLeft':\r\n case 'bottomRight':\r\n this.attrs = {\r\n ...this.attrs,\r\n cursorTargetX: area.x,\r\n cursorTargetY: area.y,\r\n }\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const coordinates = this.getRectCoordinates()\r\n const polygon = Object.keys(coordinates).map((point) => ({\r\n x: coordinates[point as 'P1' | 'P2' | 'P3' | 'P4'].x,\r\n y: coordinates[point as 'P1' | 'P2' | 'P3' | 'P4'].y,\r\n }))\r\n if (math.pointInPolygon(area.scaled, polygon)) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n\r\n getIsInChartView() {\r\n return true\r\n }\r\n}\r\n\r\nRotatedRectangleV1.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1, default: {} },\r\n ],\r\n}\r\n\r\nexport default RotatedRectangleV1\r\n","import { DrawingBorder, PaneArea } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport { getRoundedObject, getXYOffsetFromLine } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Line from './line'\r\n\r\nexport interface IScaledLineAttrs {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n dashLength: number\r\n lineWidth: number\r\n strokeStyle: string\r\n border: DrawingBorder\r\n}\r\n\r\nclass ScaledLine extends Line {\r\n static type = CanvasElementType.scaledLine\r\n\r\n name = 'Line'\r\n\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.renderContent = this.renderContent.bind(this)\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n border: {\r\n width: 1,\r\n color: this.getChartLayoutSettings().ElementSettings.Colors.border,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, y1, y2 } = this.scaled\r\n const roundedXY = getRoundedObject({ x1, x2, y1, y2 })\r\n const translateXY = getXYOffsetFromLine({ lineWidth: this.attrs.border.width, ...roundedXY })\r\n\r\n context.translate(translateXY.x, translateXY.y)\r\n context.beginPath()\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n\r\n context.moveTo(roundedXY.x1, roundedXY.y1)\r\n if (this.attrs.dashLength) {\r\n context.setLineDash([this.attrs.dashLength])\r\n }\r\n context.lineTo(roundedXY.x2, roundedXY.y2)\r\n context.stroke()\r\n context.translate(translateXY.x * -1, translateXY.y * -1)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n if (math.distanceToSegment(area.scaled, this.scaled) <= 10) {\r\n return true\r\n }\r\n return this.thumbsAreInArea(area)\r\n }\r\n}\r\n\r\nScaledLine.prototype.modalConfig = {\r\n inputs: [{ type: 'line', name: 'border' }],\r\n}\r\n\r\nexport default ScaledLine\r\n","import merge from 'lodash.merge'\r\n\r\nimport { PaneArea } from '../../types/shared'\r\nimport { PADDING } from '../constants/common'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport PaneModel from '../models/pane'\r\nimport Text, { ITextAttrs } from './text'\r\n\r\ninterface FontFamilyHeightCoefficient {\r\n Arial: {\r\n firstLine: number\r\n otherLines: number\r\n }\r\n Verdana: {\r\n firstLine: number\r\n otherLines: number\r\n }\r\n}\r\n\r\nclass ScaledText extends Text {\r\n static type = CanvasElementType.scaledText\r\n\r\n name = 'Text'\r\n declare fontFamilyHeightCoeficient: FontFamilyHeightCoefficient\r\n declare lastAttrs: Attrs\r\n declare scaled: Partial\r\n declare measuredHeight: number\r\n\r\n declare font: string\r\n declare context?: CanvasRenderingContext2D\r\n declare lines: {\r\n text: string\r\n metrics: TextMetrics\r\n }[]\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.scale({ x: ['x'], y: ['y'] })\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x'], y: ['y'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n this.render(context)\r\n }\r\n\r\n setupTextMetricsCache() {\r\n const ctx = this.context\r\n\r\n if (\r\n (this.attrs.text !== this.lastAttrs?.text ||\r\n JSON.stringify(this.attrs.font) !== JSON.stringify(this.lastAttrs?.font)) &&\r\n ctx\r\n ) {\r\n this.lastAttrs = merge({}, this.attrs)\r\n this.lines = this.getLines().map((line) => ({\r\n text: line,\r\n metrics: ctx.measureText(line),\r\n }))\r\n this.measuredHeight = this.lines.reduce((acc, current, currentIndex) => {\r\n const lineHeight =\r\n current.metrics.actualBoundingBoxAscent +\r\n current.metrics.actualBoundingBoxDescent +\r\n (currentIndex !== this.lines.length - 1 ? PADDING.XXXS : 0)\r\n return acc + lineHeight\r\n }, 0)\r\n }\r\n }\r\n\r\n // private\r\n setupContext(context: CanvasRenderingContext2D) {\r\n this.context = context\r\n context.set('font', this.font)\r\n context.set('fillStyle', this.attrs.fillStyle!)\r\n context.set('textAlign', this.attrs.textAlign!)\r\n context.set('textBaseline', this.attrs.textBaseline)\r\n this.setupTextMetricsCache()\r\n }\r\n\r\n // private\r\n renderText() {\r\n if (!this.context) return\r\n let y = this.scaled.y! + this.attrs.padding.top\r\n let previousDescent = 0\r\n for (let i = 0; i < this.lines.length; i++) {\r\n y += i === 0 ? 0 : this.lines[i].metrics.actualBoundingBoxAscent + previousDescent + PADDING.XXXS\r\n this.context.fillText(this.lines[i].text, this.scaled.x! + this.attrs.padding.left, y)\r\n previousDescent = this.lines[i].metrics.actualBoundingBoxDescent\r\n }\r\n }\r\n\r\n // private\r\n renderBackground() {\r\n if (!this.attrs.background || !this.context) {\r\n return\r\n }\r\n const padding = this.attrs.border!.width / 2 + PADDING.XXS\r\n\r\n this.context.beginPath()\r\n this.context.rect(\r\n this.scaled.x! - padding,\r\n this.scaled.y! - this.lines[0].metrics.actualBoundingBoxAscent - padding,\r\n this.width + padding * 2,\r\n this.measuredHeight + padding * 2\r\n )\r\n this.context.set('fillStyle', this.attrs.background)\r\n this.context.fill()\r\n this.context.set('fillStyle', this.attrs.fillStyle!)\r\n this.renderBorder()\r\n this.context.closePath()\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n // TODO\r\n // if @attrs.textBaseline == 'middle'\r\n // rect.y = @attrs.y - rect.height/2\r\n if (\r\n this.lines &&\r\n this.scaled.x! < area.scaled.x &&\r\n area.scaled.x < this.scaled.x! + this.width &&\r\n this.scaled.y! - this.lines[0].metrics.actualBoundingBoxAscent < area.scaled.y &&\r\n area.scaled.y < this.scaled.y! - this.lines[0].metrics.actualBoundingBoxAscent + this.measuredHeight\r\n ) {\r\n return true\r\n }\r\n return this.thumbsAreInArea(area)\r\n }\r\n\r\n getIsInChartView(chart: Chart) {\r\n if (this.getIsCreator()) {\r\n return true\r\n }\r\n\r\n if (!this.lines) {\r\n return true\r\n }\r\n\r\n const padding = this.attrs.border!.width / 2 + PADDING.XXS\r\n const textBoxX = this.scaled.x! - padding\r\n const textBoxY = this.scaled.y! - this.lines[0].metrics.actualBoundingBoxAscent - padding\r\n const textBoxWidth = this.width + padding * 2\r\n const textBoxHeight = this.measuredHeight + padding * 2\r\n\r\n if (\r\n textBoxX <= -chart.leftOffset + chart.width &&\r\n textBoxX + textBoxWidth >= -chart.leftOffset &&\r\n textBoxY <= this.model.height &&\r\n textBoxY + textBoxHeight >= 0\r\n ) {\r\n return true\r\n }\r\n\r\n return false\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x! += x\r\n this.attrs.y! += y\r\n }\r\n}\r\n\r\nexport default ScaledText\r\n","import { PaneArea, RequireByKey, TextAttrs } from '../../types/shared'\r\nimport { CanvasElementType, TextAlign, TextBaseline } from '../constants/common'\r\nimport Element, { TodoModalConfig } from './element'\r\n\r\nexport interface Area {\r\n x: number\r\n y: number\r\n}\r\n\r\nexport type ITextAttrs = RequireByKey & Partial\r\n\r\nconst DEFAULTS: Partial = {\r\n text: '',\r\n font: {\r\n size: 20,\r\n family: 'Arial',\r\n style: 'normal',\r\n weight: 'normal',\r\n },\r\n lineHeight: 20,\r\n // left | right | center | start | end\r\n textAlign: TextAlign.left,\r\n // top | hanging | middle | alphabetic | ideographic | bottom\r\n textBaseline: TextBaseline.alphabetic,\r\n padding: {\r\n top: 0,\r\n right: 0,\r\n bottom: 0,\r\n left: 0,\r\n },\r\n}\r\n\r\nclass Text extends Element {\r\n static type = CanvasElementType.text\r\n\r\n static getMergedPropsWithDefaults>(\r\n propKey: T,\r\n props: Partial = {}\r\n ) {\r\n return {\r\n ...DEFAULTS[propKey],\r\n ...Object.entries(props).reduce((acc, [key, value]) => (value ? { ...acc, [key]: value } : acc), {}),\r\n }\r\n }\r\n\r\n name = 'Anchored text'\r\n declare context?: CanvasRenderingContext2D\r\n declare width: number\r\n declare height: number\r\n declare font: string\r\n\r\n static initClass() {\r\n Object.defineProperty(this.prototype, 'width', {\r\n get() {\r\n // TODO: revisit this getter, when you call `this.width` you don't expect/want context change\r\n if (this.context) {\r\n this.setupContext(this.context)\r\n }\r\n return this.measure() + this.attrs.padding.left + this.attrs.padding.right\r\n },\r\n })\r\n\r\n Object.defineProperty(this.prototype, 'height', {\r\n get() {\r\n const count = this.getLines().length\r\n return this.attrs.lineHeight * count + this.attrs.padding.top + this.attrs.padding.bottom\r\n },\r\n })\r\n\r\n Object.defineProperty(this.prototype, 'font', {\r\n get() {\r\n const f = this.attrs.font\r\n return `${f.style} ${f.weight} ${f.size}pt ${f.family}`\r\n },\r\n })\r\n }\r\n\r\n getModalConfigBase() {\r\n return {\r\n inputs: [\r\n { type: 'multiline_string', name: 'text', required: true },\r\n { type: 'font', name: 'font' },\r\n {\r\n type: 'background',\r\n name: 'fillStyle',\r\n label: 'Color',\r\n default: this.getChartLayoutSettings().ElementSettings.Colors.textWithoutBackground,\r\n },\r\n {\r\n type: 'background',\r\n name: 'background',\r\n label: 'Background',\r\n default: 'rgba(0,0,0,0)',\r\n },\r\n {\r\n type: 'border',\r\n name: 'border',\r\n min: 0,\r\n default: { color: 'rgba(0,0,0)', width: 0 },\r\n },\r\n ],\r\n } as unknown as TodoModalConfig\r\n }\r\n\r\n getDefaults() {\r\n return {\r\n ...DEFAULTS,\r\n fillStyle: this.getChartLayoutSettings().ElementSettings.Colors.textWithoutBackground,\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x'], y: ['y'] })\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n if (obj.font?.size && !obj.lineHeight) {\r\n this.attrs.lineHeight = Math.max(obj.font.size, this.attrs.lineHeight)\r\n }\r\n return this\r\n }\r\n\r\n render(context: CanvasRenderingContext2D) {\r\n this.setupContext(context)\r\n if (this.attrs.angle && this.context) {\r\n // TODO background & multiline text\r\n this.context.save()\r\n this.context.translate(this.attrs.x!, this.attrs.y!)\r\n this.context.rotate((this.attrs.angle * Math.PI) / 180)\r\n this.context.fillText(this.attrs.text, 0, 0)\r\n this.context.restore()\r\n } else {\r\n this.renderBackground()\r\n this.renderText()\r\n }\r\n }\r\n\r\n measure(context?: CanvasRenderingContext2D) {\r\n if (context) {\r\n this.setupContext(context)\r\n }\r\n const lines = this.getLines()\r\n let max = 0\r\n for (const line of lines) {\r\n max = Math.max(this.context?.measureText(line).width ?? Number.MIN_SAFE_INTEGER, max)\r\n }\r\n return ~~max\r\n }\r\n\r\n isInArea(testArea: PaneArea) {\r\n const area = this.convertArea(testArea)\r\n // TODO iny align\r\n if (\r\n this.attrs.x! < area.x &&\r\n area.x < this.attrs.x! + this.width &&\r\n this.attrs.y! - this.attrs.font.size < area.y &&\r\n area.y < this.attrs.y! - this.attrs.font.size + this.height\r\n ) {\r\n return true\r\n }\r\n return super.isInArea(testArea)\r\n }\r\n\r\n setupContext(context: CanvasRenderingContext2D) {\r\n this.context = context\r\n context.set('font', this.font)\r\n context.set('fillStyle', this.attrs.fillStyle)\r\n context.set('textAlign', this.attrs.textAlign)\r\n context.set('textBaseline', this.attrs.textBaseline)\r\n }\r\n\r\n getLines() {\r\n return this.attrs.text.toString().split('\\n')\r\n }\r\n\r\n renderText() {\r\n if (!this.context) return\r\n let { y } = this.attrs // + @attrs.padding.top\r\n for (const line of this.getLines()) {\r\n this.context.fillText(line, this.attrs.x! + this.attrs.padding.left, y!)\r\n y! += this.attrs.lineHeight\r\n }\r\n }\r\n\r\n renderBackground() {\r\n if (!this.attrs.background || !this.context) {\r\n return\r\n }\r\n\r\n const { width } = this\r\n const { height } = this\r\n const rawHight = height - this.attrs.padding.top - this.attrs.padding.bottom\r\n const { x } = this.attrs\r\n let y = this.attrs.y! - height\r\n\r\n if (this.attrs.textBaseline === 'middle') {\r\n y = this.attrs.y! - rawHight / 2 - this.attrs.padding.top - 1\r\n } else if (this.attrs.textBaseline === 'alphabetic') {\r\n y = this.attrs.y! - this.attrs.lineHeight\r\n }\r\n\r\n this.context.beginPath()\r\n this.context.set('fillStyle', this.attrs.background)\r\n this.context.rect(x!, y, width, height)\r\n this.context.fill()\r\n this.context.set('fillStyle', this.attrs.fillStyle)\r\n this.renderBorder()\r\n this.context.closePath()\r\n }\r\n\r\n renderBorder() {\r\n const { lineWidth = 0, strokeStyle, border } = this.attrs\r\n const borderWidth = border?.width ?? 0\r\n\r\n if ((lineWidth || this.attrs.strokeStyle || borderWidth > 0) && this.context) {\r\n this.context.set('strokeStyle', strokeStyle ?? border?.color ?? '')\r\n this.context.set('lineWidth', Math.max(lineWidth, borderWidth))\r\n this.context.stroke()\r\n }\r\n }\r\n\r\n private convertArea(area: PaneArea) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n return {\r\n x: this.model.scale.x(area.x) + this.model.chart().leftOffset + ChartSettings.left.width,\r\n y: this.model.scale.y(area.y) + ChartSettings.top.height,\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x! += this.model.scale.x(x) + 1\r\n this.attrs.y! += this.model.scale.y(y) - this.model.scale.y(0)\r\n }\r\n\r\n getHeight() {\r\n return this.height\r\n }\r\n}\r\n\r\nText.initClass()\r\n\r\nexport default Text\r\n","import { PaneArea, ResizeByThumbFuncProps, ThumbType } from '../../types/shared'\r\nimport { getOffsetFromLineWidth } from '../controllers/renderUtils'\r\nimport PaneModel from '../models/pane'\r\n\r\ntype Area = PaneArea\r\ntype ResizeFunc = (props: ResizeByThumbFuncProps) => void\r\ntype ScaleFunc = () => number\r\n\r\nclass Thumb {\r\n type: ThumbType\r\n lastX = 0\r\n lastY = 0\r\n fx: ScaleFunc\r\n fy: ScaleFunc\r\n resize: ResizeFunc\r\n model: PaneModel\r\n\r\n constructor(type: ThumbType, fx: ScaleFunc, fy: ScaleFunc, resize: ResizeFunc, model: PaneModel) {\r\n this.type = type\r\n this.fx = fx\r\n this.fy = fy\r\n this.resize = resize\r\n this.model = model\r\n }\r\n\r\n render(context: CanvasRenderingContext2D) {\r\n const { ThumbSettings } = this.model.getChartLayoutSettings()\r\n context.set('fillStyle', ThumbSettings.color)\r\n context.set('strokeStyle', ThumbSettings.borderColor)\r\n context.set('lineWidth', ThumbSettings.borderWidth)\r\n const x = ~~this.x()\r\n const y = ~~this.y()\r\n const thumbWidth = this.getThumbWidth()\r\n const offset = getOffsetFromLineWidth(ThumbSettings.borderWidth)\r\n context.beginPath()\r\n context.rect(x + offset, y + offset, thumbWidth, thumbWidth)\r\n context.fill()\r\n context.stroke()\r\n }\r\n\r\n startEditing(area: Area) {\r\n this.lastX = area.x\r\n return (this.lastY = area.y)\r\n }\r\n\r\n moveTo(area: Area) {\r\n const difX = area.x - this.lastX\r\n const difY = area.y - this.lastY\r\n this.resize({ type: this.type, difX, difY, area })\r\n this.lastX = area.x\r\n this.lastY = area.y\r\n }\r\n\r\n isInArea(area: Area) {\r\n const width = this.model.scale.x.invert(this.getThumbWidth())\r\n const height = this.model.scale.y.invert(0) - this.model.scale.y.invert(this.getThumbWidth())\r\n // +- width/2 because we have coordinates of a center\r\n if (\r\n this.fx() + width / 2 >= area.x &&\r\n this.fx() - width / 2 <= area.x &&\r\n this.fy() + height / 2 > area.y &&\r\n this.fy() - height / 2 < area.y\r\n ) {\r\n return true\r\n }\r\n return false\r\n }\r\n\r\n getThumbWidth() {\r\n const { ThumbSettings } = this.model.getChartLayoutSettings()\r\n return ThumbSettings.size + ThumbSettings.borderWidth * 2\r\n }\r\n\r\n x() {\r\n const { ThumbSettings } = this.model.getChartLayoutSettings()\r\n return this.model.scale.x(this.fx()) - ThumbSettings.size / 2\r\n }\r\n\r\n y() {\r\n const { ThumbSettings } = this.model.getChartLayoutSettings()\r\n return this.model.scale.y(this.fy()) - ThumbSettings.size / 2\r\n }\r\n}\r\n\r\nexport default Thumb\r\n","import { PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport { getOffsetFromLineWidth, getRoundedObject } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Thumb from './thumb'\r\n\r\nexport interface ITriangleAttrs {\r\n x1: number\r\n x2: number\r\n x3: number\r\n y1: number\r\n y2: number\r\n y3: number\r\n fill: string\r\n border: string\r\n}\r\n\r\nclass Triangle extends Element {\r\n static type = CanvasElementType.triangle\r\n\r\n declare scaled: Pick\r\n name = 'Triangle'\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n\r\n this.resize = this.resize.bind(this)\r\n\r\n this._thumbs = [\r\n new Thumb(\r\n 'a',\r\n () => this.attrs.x1,\r\n () => this.attrs.y1,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'b',\r\n () => this.attrs.x2,\r\n () => this.attrs.y2,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'c',\r\n () => this.attrs.x3,\r\n () => this.attrs.y3,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return { fill: ElementSettings.defaultFill, border: ElementSettings.Colors.border } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2', 'x3'], y: ['y1', 'y2', 'y3'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { x1, x2, x3, y1, y2, y3 } = this.scaled\r\n const roundedXY = getRoundedObject({ x1, x2, x3, y1, y2, y3 })\r\n\r\n context.set('fillStyle', this.attrs.fill)\r\n\r\n const offset = this.getShouldRenderThumbs() ? getOffsetFromLineWidth(1) : 0\r\n\r\n context.translate(offset, offset)\r\n context.beginPath()\r\n context.moveTo(roundedXY.x1, roundedXY.y1)\r\n context.lineTo(roundedXY.x2, roundedXY.y2)\r\n context.lineTo(roundedXY.x3, roundedXY.y3)\r\n context.lineTo(roundedXY.x1, roundedXY.y1)\r\n context.fill()\r\n context.translate(offset * -1, offset * -1)\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n context.set('strokeStyle', this.attrs.border)\r\n context.stroke()\r\n this.renderThumbs(context)\r\n }\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n this.attrs.x1 += x\r\n this.attrs.y1 += y\r\n this.attrs.x2 += x\r\n this.attrs.y2 += y\r\n this.attrs.x3 += x\r\n this.attrs.y3 += y\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n switch (type) {\r\n case 'a':\r\n this.attrs.x1 += difX\r\n this.attrs.y1 += difY\r\n break\r\n case 'b':\r\n this.attrs.x2 += difX\r\n this.attrs.y2 += difY\r\n break\r\n case 'c':\r\n this.attrs.x3 += difX\r\n this.attrs.y3 += difY\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n const polygon = [1, 2, 3].map((i) => ({\r\n x: this.scaled[`x${i}` as 'x1' | 'x2' | 'x3'],\r\n y: this.scaled[`y${i}` as 'y1' | 'y2' | 'y3'],\r\n }))\r\n if (math.pointInPolygon(area.scaled, polygon)) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nTriangle.prototype.modalConfig = {\r\n inputs: [{ type: 'background', name: 'fill' }],\r\n}\r\n\r\nexport default Triangle\r\n","import { RequireByKey, ResizeByThumbFuncProps } from '../../types/shared'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport PaneModel from '../models/pane'\r\nimport ScaledLine, { IScaledLineAttrs } from './scaled_line'\r\n\r\nclass VerticalLine extends ScaledLine {\r\n static type = CanvasElementType.verticalLine\r\n\r\n name = 'Vertical line'\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n\r\n this.renderContent = this.renderContent.bind(this)\r\n\r\n this.attrs.x2 = this.attrs.x1\r\n this._thumbs = [this._thumbs[0]]\r\n }\r\n\r\n getBoundingPointKeys = () => ({ x: ['x1', 'x2'], y: ['y1', 'y2'] })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const domain = this.model.scale.y.domain()\r\n this.attrs.y1 = domain[0]\r\n this.attrs.y2 = domain[1]\r\n this._thumbs[0].fy = () => (this.attrs.y1 + this.attrs.y2) / 2\r\n super.renderContent(context)\r\n }\r\n\r\n moveBy(x: number) {\r\n return (this.attrs.x1 = this.attrs.x2 += x)\r\n }\r\n\r\n resize({ difX }: RequireByKey) {\r\n return this.moveBy(difX)\r\n }\r\n\r\n getIsInChartView(chart: Chart) {\r\n return super.getIsInChartView(chart, { omitY: true })\r\n }\r\n}\r\n\r\nexport default VerticalLine\r\n","import { DrawingBorder, PaneArea, ResizeByThumbWithTypeAndDifs } from '../../types/shared'\r\nimport { CanvasElementType, TextAlign, TextBaseline } from '../constants/common'\r\nimport { getOffsetFromLineWidth, getRoundedObject } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport PaneModel from '../models/pane'\r\nimport Element from './element'\r\nimport Text, { ITextAttrs } from './text'\r\nimport Thumb from './thumb'\r\n\r\nexport interface IXABCDPositionAttrs {\r\n xx: number\r\n xy: number\r\n ax: number\r\n ay: number\r\n bx: number\r\n by: number\r\n cx: number\r\n cy: number\r\n dx: number\r\n dy: number\r\n}\r\n\r\ntype xPoints = 'xx' | 'ax' | 'bx' | 'cx' | 'dx'\r\ntype yPoints = 'xy' | 'ay' | 'by' | 'cy' | 'dy'\r\n\r\nexport interface IXABCDAttrs extends IXABCDPositionAttrs {\r\n fill: string\r\n border: DrawingBorder\r\n lineWidth: number\r\n}\r\n\r\nclass XABCD extends Element {\r\n static type = CanvasElementType.xabcd\r\n\r\n name = 'XABCD pattern'\r\n\r\n declare scaled: Pick\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n\r\n this.resize = this.resize.bind(this)\r\n\r\n this._thumbs = [\r\n new Thumb(\r\n 'x',\r\n () => this.attrs.xx,\r\n () => this.attrs.xy,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'a',\r\n () => this.attrs.ax,\r\n () => this.attrs.ay,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'b',\r\n () => this.attrs.bx,\r\n () => this.attrs.by,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'c',\r\n () => this.attrs.cx,\r\n () => this.attrs.cy,\r\n this.resize,\r\n this.model\r\n ),\r\n new Thumb(\r\n 'd',\r\n () => this.attrs.dx,\r\n () => this.attrs.dy,\r\n this.resize,\r\n this.model\r\n ),\r\n ]\r\n if (this.attrs.lineWidth == null) {\r\n this.attrs.lineWidth = 1\r\n }\r\n this.scale(this.getBoundingPointKeys())\r\n }\r\n\r\n getDefaults() {\r\n const { ElementSettings } = this.getChartLayoutSettings()\r\n return {\r\n fill: ElementSettings.defaultFill,\r\n border: {\r\n width: 1,\r\n color: ElementSettings.Colors.border,\r\n },\r\n } as Partial\r\n }\r\n\r\n getBoundingPointKeys = () => ({\r\n x: ['xx', 'ax', 'bx', 'cx', 'dx'],\r\n y: ['xy', 'ay', 'by', 'cy', 'dy'],\r\n })\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n const { xx, xy, ax, ay, bx, by, cx, cy, dx, dy } = this.scaled\r\n const roundedXY = getRoundedObject({ xx, xy, ax, ay, bx, by, cx, cy, dx, dy })\r\n\r\n context.set('fillStyle', this.attrs.fill)\r\n context.set('lineWidth', this.attrs.border.width)\r\n context.set('strokeStyle', this.attrs.border.color)\r\n\r\n const offset = getOffsetFromLineWidth(this.attrs.border.width)\r\n context.translate(offset, offset)\r\n\r\n context.beginPath()\r\n context.moveTo(roundedXY.xx, roundedXY.xy)\r\n context.lineTo(roundedXY.ax, roundedXY.ay)\r\n context.lineTo(roundedXY.bx, roundedXY.by)\r\n context.lineTo(roundedXY.xx, roundedXY.xy)\r\n context.fill()\r\n if ((this.attrs.border != null ? this.attrs.border.width : undefined) !== 0) {\r\n context.stroke()\r\n }\r\n\r\n context.beginPath()\r\n context.moveTo(roundedXY.bx, roundedXY.by)\r\n context.lineTo(roundedXY.cx, roundedXY.cy)\r\n context.lineTo(roundedXY.dx, roundedXY.dy)\r\n context.lineTo(roundedXY.bx, roundedXY.by)\r\n context.fill()\r\n if ((this.attrs.border != null ? this.attrs.border.width : undefined) !== 0) {\r\n context.stroke()\r\n }\r\n\r\n context.beginPath()\r\n context.moveTo(roundedXY.ax, roundedXY.ay)\r\n context.lineTo(roundedXY.cx, roundedXY.cy)\r\n context.moveTo(roundedXY.xx, roundedXY.xy)\r\n context.lineTo(roundedXY.dx, roundedXY.dy)\r\n context.stroke()\r\n\r\n const text = new Text(\r\n {\r\n font: { size: 8, style: 'bold' },\r\n lineHeight: 8,\r\n padding: {\r\n top: 2,\r\n right: 2,\r\n bottom: 2,\r\n left: 2,\r\n },\r\n textBaseline: TextBaseline.middle,\r\n textAlign: TextAlign.start,\r\n fillStyle: '#ffffff',\r\n background: this.attrs.fill || '#000000',\r\n },\r\n this.model\r\n )\r\n\r\n for (const t of Array.from('xabcd')) {\r\n text\r\n .set({\r\n text: t.toUpperCase(),\r\n x: roundedXY[(t + 'x') as xPoints] - 6,\r\n y: roundedXY[(t + 'y') as yPoints] + 12,\r\n } as Partial)\r\n .render(context)\r\n }\r\n\r\n const retLabel = (y1: string, y2: string, y3: string) => {\r\n const len = Math.abs(this.attrs[(y1 + 'y') as yPoints] - this.attrs[(y2 + 'y') as yPoints])\r\n const ret = Math.abs(this.attrs[(y3 + 'y') as yPoints] - this.attrs[(y2 + 'y') as yPoints]) / len\r\n const x = (roundedXY[(y1 + 'x') as xPoints] + roundedXY[(y3 + 'x') as xPoints]) / 2\r\n const y = (roundedXY[(y1 + 'y') as yPoints] + roundedXY[(y3 + 'y') as yPoints]) / 2\r\n return text\r\n .set({\r\n text: ret.toFixed(3),\r\n x,\r\n y,\r\n })\r\n .render(context)\r\n }\r\n\r\n retLabel('x', 'a', 'b')\r\n retLabel('a', 'b', 'c')\r\n retLabel('b', 'c', 'd')\r\n retLabel('x', 'a', 'd')\r\n\r\n if (this.getShouldRenderThumbs()) {\r\n this.renderThumbs(context)\r\n }\r\n context.translate(offset * -1, offset * -1)\r\n }\r\n\r\n moveBy(x: number, y: number) {\r\n for (const t of Array.from('xabcd')) {\r\n this.attrs[(t + 'x') as xPoints] += x\r\n this.attrs[(t + 'y') as yPoints] += y\r\n }\r\n }\r\n\r\n resize({ type, difX, difY }: ResizeByThumbWithTypeAndDifs) {\r\n this.attrs[(type + 'x') as xPoints] += difX\r\n return (this.attrs[(type + 'y') as yPoints] += difY)\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n if (super.isDrawingElementLockedOrInvisible()) return false\r\n let t\r\n const xab = (() => {\r\n const result = []\r\n for (t of Array.from('xab')) {\r\n result.push({ x: this.scaled[(t + 'x') as xPoints], y: this.scaled[(t + 'y') as yPoints] })\r\n }\r\n return result\r\n })()\r\n const bcd = (() => {\r\n const result1 = []\r\n for (t of Array.from('bcd')) {\r\n result1.push({ x: this.scaled[(t + 'x') as xPoints], y: this.scaled[(t + 'y') as yPoints] })\r\n }\r\n return result1\r\n })()\r\n if (math.pointInPolygon(area.scaled, xab) || math.pointInPolygon(area.scaled, bcd)) {\r\n return true\r\n }\r\n return super.isInArea(area)\r\n }\r\n}\r\n\r\nXABCD.prototype.modalConfig = {\r\n inputs: [\r\n { type: 'background', name: 'fill' },\r\n { type: 'border', name: 'border', min: 1 },\r\n ],\r\n}\r\n\r\nexport default XABCD\r\n","import Utils from '../utils'\r\nimport { getContextWithCache } from '../utils/canvas'\r\nimport { captureException, getIsSSr } from '../utils/helpers'\r\n\r\nclass Cache {\r\n constructor() {\r\n this.canvas = getIsSSr() ? null : document.createElement('canvas')\r\n }\r\n\r\n set(callback, width, height) {\r\n this.callback = callback\r\n this.width = width\r\n this.height = height\r\n this.rendered = false\r\n }\r\n\r\n render(context, x, y) {\r\n if (x == null) {\r\n x = 0\r\n }\r\n if (y == null) {\r\n y = 0\r\n }\r\n if (!this.rendered) {\r\n this.refresh()\r\n }\r\n if (this.width < 1 || this.height < 1) {\r\n return\r\n }\r\n\r\n try {\r\n if (this.ratio >= 1 && this.canvas) {\r\n context.drawImage(\r\n this.canvas,\r\n 0,\r\n 0,\r\n ~~(this.width * this.ratio),\r\n ~~(this.height * this.ratio),\r\n x,\r\n y,\r\n this.width,\r\n this.height\r\n )\r\n } else {\r\n context.save()\r\n context.translate(x, y)\r\n this.callback(context)\r\n context.restore()\r\n }\r\n } catch (e) {\r\n captureException(\r\n e,\r\n this.canvas\r\n ? {\r\n extra: {\r\n width: this.width,\r\n height: this.height,\r\n ratio: this.ratio,\r\n cWidth: this.canvas.width,\r\n cHeight: this.canvas.height,\r\n sWidth: window.screen.width,\r\n sHeight: window.screen.height,\r\n },\r\n }\r\n : {}\r\n )\r\n }\r\n }\r\n\r\n refresh() {\r\n if (getIsSSr()) {\r\n return\r\n }\r\n this.canvas.width = this.width\r\n this.canvas.height = this.height\r\n this.context = getContextWithCache(this.canvas)\r\n this.ratio = Utils.getScaleRatio()\r\n Utils.setSizeOnCanvasElement({ canvasElement: this.canvas, width: this.width, height: this.height })\r\n this.context.scale(this.ratio, this.ratio)\r\n\r\n this.callback(this.context)\r\n this.rendered = true\r\n }\r\n}\r\n\r\nexport default Cache\r\n","import { ObjectHash, Theme } from '../../../types/shared'\r\nimport { TextAlign, TextBaseline } from '../../constants/common'\r\nimport { IChartThemeColors, IElementThemeColors, IIndicatorThemeColors } from '../constants'\r\n\r\nexport enum OHLCType {\r\n singleLine = 'singleLine',\r\n dateOnly = 'dateOnly',\r\n timeOnly = 'timeOnly',\r\n}\r\n\r\nexport interface IMargin {\r\n top?: number\r\n right?: number\r\n bottom?: number\r\n left?: number\r\n}\r\n\r\ninterface IPadding {\r\n top?: number\r\n right?: number\r\n bottom?: number\r\n left?: number\r\n}\r\n\r\ninterface IGenericText {\r\n margin: IMargin\r\n font: IFont\r\n}\r\n\r\ninterface IFont {\r\n size?: number\r\n style?: string\r\n weight?: string\r\n family?: string\r\n lineHeight?: number\r\n padding?: IPadding\r\n baseline?: TextBaseline\r\n textAlign?: TextAlign\r\n}\r\n\r\ninterface ISettingsGeneralBase {\r\n Colors: IChartThemeColors\r\n}\r\n\r\nexport interface ISettingsCenterBase {\r\n barWidth: number\r\n barMargin: number\r\n border: number\r\n volumeHeight?: number\r\n}\r\n\r\ninterface ISettingsTopBase {\r\n height: number\r\n}\r\n\r\ninterface ISettingsBottomBase {\r\n height: number\r\n}\r\n\r\ninterface ISettingsLeftBase {\r\n width: number\r\n}\r\n\r\ninterface ISettingsRightBase {\r\n width: number\r\n}\r\n\r\nexport interface ISettings {\r\n ChartSettings: IChartSettings\r\n IndicatorSettings: IIndicatorSettings\r\n MarketSentimentSettings: IMarketSentimentChartSettings\r\n ColorsSettings: Array\r\n ThumbSettings: IThumbSettings\r\n ElementSettings: IElementSettings\r\n isOurSiteRequest?: boolean\r\n}\r\n\r\nexport interface IChartSettings {\r\n general: IChartGeneral\r\n center: ISettingsCenterBase\r\n top: IChartTop\r\n bottom: IChartBottom\r\n left: IChartLeft\r\n right: IChartRight\r\n}\r\n\r\ninterface IChartGeneral {\r\n settingsHeight: number\r\n tickerTimeframeChangeHeight: number\r\n Colors: IChartThemeColors & ObjectHash\r\n}\r\n\r\ninterface IChartTop extends ISettingsTopBase {\r\n baseline: TextBaseline\r\n ticker: IGenericText\r\n ohlc: IOHLC\r\n change: IGenericText\r\n}\r\n\r\ninterface IOHLC extends IGenericText {\r\n type?: OHLCType\r\n}\r\n\r\ninterface IChartBottom extends ISettingsBottomBase {\r\n baseline: TextBaseline\r\n axis: IGenericText\r\n}\r\n\r\ninterface IChartLeft extends ISettingsLeftBase {\r\n overlayLabel: IOverlayLabel\r\n timeframe: IGenericText\r\n volumeAxis: IGenericText\r\n}\r\n\r\ninterface IOverlayLabel extends IGenericText {\r\n labelSpacing: number\r\n}\r\n\r\ninterface IChartRight extends ISettingsRightBase {\r\n axis: IGenericText\r\n}\r\n\r\nexport interface IIndicatorSettings {\r\n general: IIndicatorGeneral\r\n center: ISettingsCenterBase\r\n top: ISettingsTopBase\r\n bottom: ISettingsBottomBase\r\n left: IIndicatorLeft\r\n right: IIndicatorRight\r\n}\r\n\r\ninterface IIndicatorRight extends ISettingsRightBase {\r\n axis: IGenericText\r\n}\r\n\r\ninterface IIndicatorLeft extends ISettingsLeftBase {\r\n indicatorLabel: IIndicatorLabel\r\n}\r\n\r\ninterface IIndicatorLabel extends IGenericText {\r\n labelSpacing: number\r\n}\r\n\r\ninterface IIndicatorGeneral {\r\n Colors: IIndicatorThemeColors\r\n height: number\r\n}\r\n\r\ninterface IMarketSentimentChartSettings {\r\n general: ISettingsGeneralBase\r\n center: ISettingsCenterBase\r\n top: ISettingsTopBase\r\n bottom: ISettingsBottomBase\r\n left: ISettingsLeftBase\r\n right: ISettingsRightBase\r\n}\r\n\r\ninterface IThumbSettings {\r\n size: number\r\n touchSize: number\r\n color: string\r\n borderWidth: number\r\n borderColor: string\r\n}\r\n\r\ninterface IElementSettings {\r\n Colors: IElementThemeColors\r\n defaultFill: string\r\n defaultTransparentFill: string\r\n}\r\n","export enum ChartMinWidthBreakpoints {\r\n xs = 0,\r\n s = 480,\r\n m = 768,\r\n l = 1024,\r\n}\r\n\r\nexport function getChartBreakpoints(chartWidthInPx: number) {\r\n return {\r\n isXs: chartWidthInPx >= ChartMinWidthBreakpoints.xs,\r\n isS: chartWidthInPx >= ChartMinWidthBreakpoints.s,\r\n isM: chartWidthInPx >= ChartMinWidthBreakpoints.m,\r\n isL: chartWidthInPx >= ChartMinWidthBreakpoints.l,\r\n }\r\n}\r\n","import * as d3 from 'd3'\r\nimport merge from 'lodash.merge'\r\n\r\nimport {\r\n ChartConfigChartPaneElement,\r\n CustomSpineEvents,\r\n Instrument,\r\n Maybe,\r\n RequireByKey,\r\n Theme,\r\n} from '../../types/shared'\r\nimport Cache from '../canvas/cache'\r\nimport Element from '../canvas/element'\r\nimport Line from '../canvas/line'\r\nimport Text from '../canvas/text'\r\nimport tailwindColors from '../constants/colors'\r\nimport {\r\n CHART_MARGIN,\r\n ChartElementType,\r\n FONT_SIZE,\r\n IndicatorType,\r\n IntradayTimeframeInterval,\r\n LINE_HEIGHT,\r\n MONTHS,\r\n OFFSET,\r\n PADDING,\r\n ScaleType,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n TIMEFRAMES_WITH_PRE_MARKET,\r\n TextAlign,\r\n TextBaseline,\r\n getTimeframeLabel,\r\n} from '../constants/common'\r\nimport {\r\n getIsSmallIndexChart,\r\n getPercentageFromValue,\r\n getTranslate,\r\n getValueFromPercentage,\r\n} from '../controllers/renderUtils'\r\nimport Chart from '../models/chart'\r\nimport { getColorOverwrites } from '../models/chart_settings'\r\nimport { ISettings, OHLCType } from '../models/chart_settings/interfaces'\r\nimport { darkerWickColors, thinBarColorsOverride } from '../models/constants'\r\nimport mouseModel from '../models/mouse'\r\nimport PaneModel, { ScaleAxis } from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport { getChartLayoutSettings } from '../models/settings'\r\nimport Overlay from '../overlays/overlay'\r\nimport { overlaysByType } from '../overlays/overlays'\r\nimport utils, { dateFromDateString, isRedesignedPage, numberToStringWithUnitsSuffix } from '../utils'\r\nimport {\r\n ITickerChange,\r\n getBarWidthWithMargin,\r\n getBarWidthWithMarginByParts,\r\n getChangeColor,\r\n getShouldUseDarkerWickColors,\r\n getTickerChange,\r\n getTickerChangeFromCloseValues,\r\n getVirtualTimeframeTradedDates,\r\n renderCross,\r\n round,\r\n unmountCanvas,\r\n} from '../utils/chart'\r\nimport { convertColorToHEX, getHEXWithSpecificAplha, getHSVAFromColor, stringifyHSVAColor } from '../utils/colors'\r\nimport { setElementCursor } from '../utils/cursor'\r\nimport { drawInVisibleArea, getFirstBarToRenderIndex, getLastBarToRenderIndex } from '../utils/draw_in_visible_area'\r\nimport { getChartBreakpoints } from './utils'\r\n\r\nexport interface BaseChartAttrs {\r\n overlays: Required['overlays']\r\n}\r\n\r\ntype OhlcLineElements = Array<{ text: string; color: string } | 'space'>\r\n\r\ninterface LastOHLCAttrs {\r\n text: string\r\n x: number\r\n y: number\r\n width: number\r\n textBaseline: TextBaseline\r\n textAlign: TextAlign\r\n}\r\n\r\ninterface IRenderOHLCParameters {\r\n context: CanvasRenderingContext2D\r\n date: Maybe\r\n open?: Maybe\r\n high?: Maybe\r\n low?: Maybe\r\n close?: Maybe\r\n volume?: Maybe\r\n afterHour?: string\r\n isSmallIndexChart?: boolean\r\n isNewestOHLC?: boolean\r\n directRender?: boolean\r\n time?: string\r\n changePercentage?: Maybe\r\n}\r\n\r\ninterface XAxisLabel {\r\n x: number\r\n text: string\r\n textWidth: number\r\n hasPriority?: boolean\r\n allowedOverflow?: number\r\n}\r\n\r\ninterface IRenderXAxisProps {\r\n textRenderer: Text\r\n startBarIndex: number\r\n endBarIndex: number\r\n}\r\n\r\nconst getDateString = ({ date, timeframe }: { date: Date; timeframe: TIMEFRAME }) => {\r\n let dateString = ''\r\n const month = date.getMonth() // 20141126\r\n const year = date.getFullYear()\r\n const day = date.getDate()\r\n switch (timeframe) {\r\n case TIMEFRAME.i1:\r\n case TIMEFRAME.i2:\r\n case TIMEFRAME.i3:\r\n case TIMEFRAME.i5:\r\n case TIMEFRAME.i10:\r\n case TIMEFRAME.i15:\r\n case TIMEFRAME.i30:\r\n case TIMEFRAME.h:\r\n case TIMEFRAME.h2:\r\n case TIMEFRAME.h4:\r\n const t =\r\n (((date.getHours() + 11) % 12) + 1).toString().padLeft('00') +\r\n ':' +\r\n date.getMinutes().toString().padLeft('00') +\r\n (date.getHours() < 12 ? 'AM' : 'PM')\r\n dateString = `${MONTHS[month]} ${day} ${t}`\r\n break\r\n case TIMEFRAME.d:\r\n case TIMEFRAME.w:\r\n dateString = `${MONTHS[month]} ${day}`\r\n break\r\n case TIMEFRAME.m:\r\n dateString = `${MONTHS[month]} ${year}`\r\n break\r\n default:\r\n break\r\n }\r\n\r\n return dateString\r\n}\r\n\r\nconst getIsOverlapping = ({\r\n x,\r\n textWidth,\r\n renderedLabelRanges,\r\n}: {\r\n x: number\r\n textWidth: number\r\n renderedLabelRanges: Array<{ from: number; to: number }>\r\n}) =>\r\n renderedLabelRanges.some(({ from, to }) => {\r\n const minX = x - textWidth / 2\r\n const maxX = x + textWidth / 2\r\n return (from < maxX && maxX < to) || (from < minX && minX < to)\r\n })\r\n\r\nfunction getClosestDifferentMinMaxValueIndices(\r\n currentMinIndex: number,\r\n currentMaxIndex: number,\r\n high: number[],\r\n low: number[]\r\n): { minIndex: number; maxIndex: number } {\r\n const hasPreviousIndex = currentMinIndex > 0\r\n const hasNextIndex = currentMaxIndex < high.length - 1\r\n let minIndex = currentMinIndex\r\n let maxIndex = currentMaxIndex\r\n if (hasPreviousIndex) {\r\n minIndex -= 1\r\n }\r\n if (hasNextIndex) {\r\n maxIndex += 1\r\n }\r\n\r\n if (low[minIndex] === high[maxIndex] && (hasPreviousIndex || hasNextIndex)) {\r\n return getClosestDifferentMinMaxValueIndices(minIndex, maxIndex, high, low)\r\n }\r\n\r\n return low[minIndex] < high[maxIndex] ? { minIndex, maxIndex } : { minIndex: maxIndex, maxIndex: minIndex }\r\n}\r\n\r\nconst SMALL_INDEX_CHART_LABEL_BUFFER = 15\r\n\r\nconst gray300 = tailwindColors.gray[300]\r\n\r\nclass BaseChart extends Element {\r\n static initClass() {\r\n Object.defineProperty(this.prototype, 'width', {\r\n get() {\r\n const { ChartSettings } = this.getChartLayoutSettings() as ISettings\r\n return this.model.width - ChartSettings.left.width - ChartSettings.right.width\r\n },\r\n })\r\n\r\n Object.defineProperty(this.prototype, 'height', {\r\n get() {\r\n const { ChartSettings } = this.getChartLayoutSettings() as ISettings\r\n return this.paneModel.height - ChartSettings.top.height - ChartSettings.bottom.height\r\n },\r\n })\r\n }\r\n\r\n static getNumOfBarsBuffer({ overlays }: RequireByKey) {\r\n return Math.max(0, ...overlays.map((overlay) => overlaysByType[overlay.type].getNumOfBarsBuffer(overlay)))\r\n }\r\n\r\n static label = 'Chart'\r\n static iconName = ''\r\n\r\n paneModel: PaneModel\r\n model: Chart\r\n data: Quote\r\n specificChartFunctionality: SpecificChartFunctionality\r\n tickerWidth = 0\r\n changeWidth = 0\r\n lastOhlc: Array> = []\r\n overlays: Overlay[] = []\r\n isLargeChart?: boolean\r\n shouldRenderVolume = true\r\n afterChange: {\r\n x: number\r\n y: number\r\n width: number\r\n } | null = null\r\n\r\n declare setupAxisTimeFrame: string\r\n declare volumeFY: d3.ScaleLinear\r\n declare tickerText: Text\r\n declare baseCache: Cache\r\n declare leftOffset: number\r\n declare context: CanvasRenderingContext2D\r\n declare width: number\r\n declare height: number\r\n declare isMobile: boolean\r\n\r\n constructor(values: Partial, paneModel: PaneModel) {\r\n super(values, paneModel)\r\n\r\n this.paneModel = paneModel\r\n this.model = this.paneModel.chart()\r\n this.data = this.model.quote()\r\n const chartLayoutModel = this.model.chart_layout()\r\n this.specificChartFunctionality = chartLayoutModel.specificChartFunctionality\r\n this.isLargeChart = chartLayoutModel.isLargeChart\r\n this.isMobile = utils.isMobile(true)\r\n\r\n this.overlays = []\r\n if (values.overlays) {\r\n for (const overlayDefinition of values.overlays) {\r\n // overlayDefinition.color coming from DB is always string however overlays\r\n // internaly didn't use format as in db (type, color, period) but rather\r\n // more overlay specific parameters eg. (BB: topColor, bottomColor, etc.)\r\n // thus overlayDefinition.color might be undefined\r\n // approach could be reworked in https://github.com/finvizhq/charts/issues/770\r\n // but for now (!overlayDefinition.color) check solve issue as well\r\n const overlay = overlaysByType[overlayDefinition.type].fromObject(\r\n {\r\n ...overlayDefinition,\r\n color:\r\n !overlayDefinition.color || overlayDefinition.color.includes('|')\r\n ? ''\r\n : convertColorToHEX(overlayDefinition.color),\r\n },\r\n this.paneModel\r\n )\r\n this.addOverlay(overlay)\r\n }\r\n delete values.overlays\r\n }\r\n\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n this.renderText = this.renderText.bind(this)\r\n this.renderCrossText = this.renderCrossText.bind(this)\r\n this.setupCache = this.setupCache.bind(this)\r\n this.renderOverlaysLabels = this.renderOverlaysLabels.bind(this)\r\n\r\n // this.paneModel.bind('update', this.setupAxis.bind(this))\r\n this.paneModel.bind('update', this.setupCache)\r\n this.paneModel.bind('change', this.trigger.bind(this, 'change'))\r\n this.model = this.paneModel.chart()\r\n // this.model.bind('change', this.setupAxis.bind(this))\r\n this.model.bind('change', this.setupCache)\r\n this.model.bind('change', this.trigger.bind(this, 'change'))\r\n this.model.bind(CustomSpineEvents.IndicatorsChange, this.handleIndicatorsChange.bind(this))\r\n const mouseModelChangeHandler = this.trigger.bind(this, 'change', 'cross')\r\n this.model.bind('destroy', () => {\r\n this.model.unbind('change', this.setupCache)\r\n this.model.unbind(CustomSpineEvents.IndicatorsChange, this.handleIndicatorsChange.bind(this))\r\n mouseModel.unbind('change', mouseModelChangeHandler)\r\n unmountCanvas(this.baseCache.canvas)\r\n })\r\n mouseModel.bind('change', mouseModelChangeHandler)\r\n\r\n this.model.chart_layout().bind('theme', this.setupCache)\r\n this.model.chart_layout().bind('update', this.updateShouldRenderVolume.bind(this))\r\n\r\n this.setupCache()\r\n }\r\n\r\n renderChart() {\r\n throw Error('Implement renderChart')\r\n }\r\n\r\n render(context: CanvasRenderingContext2D) {\r\n this.data = this.model.quote()\r\n this.leftOffset = this.model.leftOffset\r\n this.context = context\r\n\r\n if (this.data.close.length === 0) {\r\n this.renderChartNotAvailable()\r\n if (!this.getIsRedesignedChart()) this.renderTicker(context)\r\n return\r\n }\r\n\r\n this.context.save()\r\n this.clip()\r\n this.renderVolume()\r\n this.renderChart()\r\n this.renderOverlays()\r\n this.renderPrevClose()\r\n this.renderFadeExtendedHours()\r\n this.context.restore()\r\n if (!this.getIsRedesignedChart()) this.renderTicker(context)\r\n }\r\n\r\n renderGrid(context: CanvasRenderingContext2D) {\r\n this.data = this.model.quote()\r\n this.leftOffset = this.model.leftOffset\r\n this.context = context\r\n // text, xAxis, volumeAxis\r\n this.renderXAxis()\r\n this.baseCache.render(context)\r\n }\r\n\r\n renderTicker(context: CanvasRenderingContext2D) {\r\n if (this.tickerText) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n context.translate(ChartSettings.left.width, 0)\r\n this.tickerText.render(context)\r\n\r\n if (getIsSmallIndexChart(this.specificChartFunctionality) && this.data.ticker === 'RUSSELL 2000') {\r\n const { Colors } = ChartSettings.general\r\n new Text(\r\n {\r\n text: 'ETF',\r\n x: ChartSettings.top.ticker.margin.left,\r\n y: ChartSettings.top.ticker.margin.top! + FONT_SIZE.XXS + OFFSET.XXS,\r\n font: { size: FONT_SIZE.XXS },\r\n fillStyle: Colors.text,\r\n textBaseline: ChartSettings.top.baseline,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n\r\n context.translate(-ChartSettings.left.width, 0)\r\n }\r\n }\r\n\r\n renderTimeframe(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const quote = this.model.quote()\r\n const y = (this.height - this.volumeFY.range()[1] - 4) / 2\r\n\r\n return new Text(\r\n {\r\n text: quote.instrument === Instrument.Group ? 'YEAR PERFORMANCE %' : getTimeframeLabel(quote.timeframe),\r\n x: ChartSettings.left.timeframe.margin.left,\r\n y: ChartSettings.top.height + y + (ChartSettings.left.timeframe.margin.top ?? 0),\r\n angle: -90,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.left.timeframe.font),\r\n fillStyle: Colors.textSecondary,\r\n textAlign: TextAlign.center,\r\n textBaseline: TextBaseline.alphabetic,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n\r\n renderText(context: CanvasRenderingContext2D) {\r\n const { ChartSettings, isOurSiteRequest } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n context.save()\r\n context.translate(ChartSettings.left.width, 0)\r\n\r\n if (!getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n this.tickerText = new Text(\r\n {\r\n text: this.data.name || this.data.ticker,\r\n x: ChartSettings.top.ticker.margin.left,\r\n y: ChartSettings.top.ticker.margin.top,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.top.ticker.font),\r\n textBaseline: ChartSettings.top.baseline,\r\n fillStyle: Colors.text,\r\n },\r\n this.paneModel\r\n )\r\n } else {\r\n this.tickerText = new Text(\r\n {\r\n text: this.data.name || this.data.ticker,\r\n x: ChartSettings.top.ticker.margin.left,\r\n y: ChartSettings.top.ticker.margin.top,\r\n font: { size: FONT_SIZE.L, style: 'bold' },\r\n fillStyle: Colors.text,\r\n },\r\n this.paneModel\r\n )\r\n }\r\n this.tickerWidth = this.tickerText.measure(context)\r\n\r\n // render watermark on backend chart\r\n if (this.specificChartFunctionality === SpecificChartFunctionality.offScreen) {\r\n let yOffset = 0\r\n if (!isOurSiteRequest) {\r\n yOffset = this.isLargeChart ? -2 : -3\r\n }\r\n new Text(\r\n {\r\n text: '© finviz.com',\r\n x: this.width + ChartSettings.right.width - 2,\r\n y: 1 + yOffset,\r\n font: { size: isOurSiteRequest ? FONT_SIZE.XS : FONT_SIZE.M },\r\n textAlign: TextAlign.right,\r\n textBaseline: TextBaseline.top,\r\n fillStyle: isOurSiteRequest ? 'rgb(136, 193, 233)' : tailwindColors.finviz.blue,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n\r\n if (!this.getIsRedesignedChart()) {\r\n this.renderChange({ context })\r\n if (!this.lastOhlc[0]) {\r\n this.getOHLC({ context, directRender: false })\r\n }\r\n this.getOHLC({ context })\r\n }\r\n\r\n context.restore()\r\n if (!this.getIsRedesignedChart() && !getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n this.renderTimeframe(context)\r\n }\r\n }\r\n\r\n getOHLC({\r\n context,\r\n directRender = true,\r\n data,\r\n date,\r\n dateString = null,\r\n changePercentage = null,\r\n }: {\r\n context: CanvasRenderingContext2D\r\n directRender?: boolean\r\n data?: {\r\n open?: string\r\n high?: string\r\n low?: string\r\n close?: string\r\n volume?: string\r\n }\r\n date?: Date\r\n dateString?: string | null\r\n changePercentage?: ITickerChange | null\r\n }) {\r\n if (!this.data.lastDate) return\r\n\r\n // modulo \"parsing\" is 100% faster than with str.slice()\r\n const lastDate = `${MONTHS[(~~(this.data.lastDate / 100) % 100) - 1]} ${this.data.lastDate % 100}` // YYYYMMDD / 20211118 => Nov 18\r\n if (getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n this.renderOHLC({\r\n context,\r\n date: lastDate,\r\n isSmallIndexChart: true,\r\n isNewestOHLC: true,\r\n directRender,\r\n })\r\n } else if (data && date) {\r\n this.renderOHLC({\r\n context,\r\n date: getDateString({ date, timeframe: this.data.timeframe }),\r\n open: data.open,\r\n high: data.high,\r\n low: data.low,\r\n close: data.close,\r\n volume: numberToStringWithUnitsSuffix(Number(data.volume)),\r\n directRender,\r\n changePercentage,\r\n })\r\n } else if (dateString !== null) {\r\n this.renderOHLC({\r\n context,\r\n date: dateString,\r\n open: null,\r\n high: null,\r\n low: null,\r\n close: null,\r\n volume: null,\r\n directRender,\r\n })\r\n } else {\r\n this.renderOHLC({\r\n context,\r\n date: lastDate,\r\n afterHour:\r\n Number.isFinite(this.data.afterClose) && this.data.afterClose !== this.data.lastClose\r\n ? this.roundOhlc(this.data.afterClose)\r\n : undefined,\r\n volume: numberToStringWithUnitsSuffix(this.data.lastVolume),\r\n isNewestOHLC: true,\r\n time: utils.dateFromUnixTimestamp(this.data.date.last()!).toLocaleTimeString('en-US', {\r\n hour: '2-digit',\r\n minute: '2-digit',\r\n }),\r\n directRender,\r\n ...this.getRoundedLastData(),\r\n })\r\n }\r\n }\r\n\r\n getRoundedLastData() {\r\n return {\r\n open: this.roundOhlc(this.data.lastOpen),\r\n high: this.roundOhlc(this.data.lastHigh),\r\n low: this.roundOhlc(this.data.lastLow),\r\n close: this.roundOhlc(this.data.lastClose),\r\n }\r\n }\r\n\r\n renderOverlaysLabels(context: CanvasRenderingContext2D) {\r\n if (!this.getIsRedesignedChart()) {\r\n this.renderOverlaysLabelsQuotePage(context)\r\n } else if (this.data.close.length !== 0) {\r\n this.renderOverlaysLabelsChartsPage(context)\r\n }\r\n }\r\n\r\n renderOverlaysLabelsQuotePage(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const text = new Text(\r\n {\r\n x: ChartSettings.left.overlayLabel.margin.left,\r\n y: ChartSettings.top.height + ChartSettings.left.overlayLabel.margin.top!,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.left.overlayLabel.font),\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.paneModel\r\n )\r\n for (const overlay of this.overlays) {\r\n if (!overlay.isRenderedOverlaysLabel()) {\r\n continue\r\n }\r\n text\r\n .set({\r\n text: overlay.toString(),\r\n y: text.get('y')! + ChartSettings.left.overlayLabel.labelSpacing,\r\n fillStyle: overlay.getLabelColor(),\r\n })\r\n .render(context)\r\n }\r\n }\r\n\r\n getYAxisLeftMargin() {\r\n if (this.data.instrument === Instrument.Crypto && this.data.lastClose <= 0.001) {\r\n return 3\r\n }\r\n return 8\r\n }\r\n\r\n getYAxisLastCloseLabel({ lastClose, firstVisibleClose }: { lastClose: number; firstVisibleClose?: number | null }) {\r\n if (typeof firstVisibleClose === 'number' && this.model.scale === ScaleType.Percentage) {\r\n return `${this.round(getPercentageFromValue({ number: lastClose, base: firstVisibleClose }), 2)}%`\r\n }\r\n return this.round(lastClose)\r\n }\r\n\r\n renderYAxis(\r\n context: CanvasRenderingContext2D,\r\n { lastClose }: RequireByKey, 'lastClose'> = this.data,\r\n renderLabels = true\r\n ) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n let y, lineTicks, textTicks, lastCloseLabel\r\n const translate = getTranslate({ context, xOffset: ChartSettings.left.width, yOffset: ChartSettings.top.height })\r\n translate.do()\r\n const tickCount = Math.floor(this.paneModel.height / 35)\r\n const minMax = this.getMinMax()\r\n const { firstVisibleClose } = minMax\r\n const height = this.height\r\n let stepPrice = 0\r\n let placesAxis\r\n\r\n switch (this.model.scale) {\r\n case ScaleType.Percentage: {\r\n if (!firstVisibleClose) return\r\n\r\n const scaleRange = this.paneModel.scaleRange\r\n const { min, max } = scaleRange || minMax\r\n\r\n this.model.updateAttribute('firstBarClose', firstVisibleClose)\r\n\r\n const minPerc = getPercentageFromValue({ number: min, base: firstVisibleClose })\r\n const maxPerc = getPercentageFromValue({ number: max, base: firstVisibleClose })\r\n\r\n const percScale = d3.scaleLinear().range([0, this.height]).domain([maxPerc, minPerc]).nice(10)\r\n textTicks = percScale.ticks(Math.min(tickCount, 9))\r\n lineTicks = textTicks.map((tick) => getValueFromPercentage({ number: tick, base: firstVisibleClose }))\r\n lastCloseLabel = this.getYAxisLastCloseLabel({ lastClose, firstVisibleClose })\r\n break\r\n }\r\n case ScaleType.Logarithmic: {\r\n if (!firstVisibleClose) return\r\n\r\n const scaleRange = this.paneModel.scaleRange\r\n const { min, max } = scaleRange || minMax\r\n lineTicks = [Math.floor(min)]\r\n const pixelGap = 30\r\n\r\n const negativeScale = []\r\n if (min < 0) {\r\n let previousNegativeTick = Math.min(0, max)\r\n while (this.paneModel.scale.y(previousNegativeTick) + pixelGap < this.paneModel.scale.y(min)) {\r\n const tick = this.paneModel.scale.y.invert(this.paneModel.scale.y(previousNegativeTick) + pixelGap)\r\n if (previousNegativeTick === tick) {\r\n break\r\n }\r\n const range = d3.nice(-previousNegativeTick, -tick, 2)\r\n previousNegativeTick = -range[range.length - 1]\r\n negativeScale.unshift(previousNegativeTick)\r\n }\r\n }\r\n\r\n const positiveScale = []\r\n if (max > 0) {\r\n positiveScale.push(Math.max(this.paneModel.scale.y.invert(this.paneModel.scale.y(min) + pixelGap), 0))\r\n }\r\n while (this.paneModel.scale.y(positiveScale[positiveScale.length - 1]) - pixelGap > 0) {\r\n const previousTick = positiveScale[positiveScale.length - 1]\r\n const positiveScaleY = this.paneModel.scale.y(positiveScale[positiveScale.length - 1])\r\n const tick = this.paneModel.scale.y.invert(positiveScaleY - pixelGap)\r\n if (previousTick === tick) {\r\n break\r\n }\r\n\r\n const range = d3.nice(previousTick, tick, 2)\r\n positiveScale.push(range[range.length - 1])\r\n }\r\n lineTicks = [...negativeScale, ...positiveScale]\r\n textTicks = lineTicks\r\n lastCloseLabel = this.getYAxisLastCloseLabel({ lastClose })\r\n break\r\n }\r\n default:\r\n // default to linear scale type\r\n lineTicks = this.paneModel.scale.y.ticks(Math.min(tickCount, 9))\r\n textTicks = lineTicks\r\n lastCloseLabel = this.getYAxisLastCloseLabel({ lastClose })\r\n }\r\n\r\n if (textTicks.length >= 2) {\r\n stepPrice = Math.abs(textTicks[1] - textTicks[0])\r\n }\r\n if (\r\n stepPrice > 10 ||\r\n (getIsSmallIndexChart(this.specificChartFunctionality) && Math.round(textTicks[0]).toString().length > 3) // if small index chart max tick is less than 999 (3 digits) allow for decimals in axis labels\r\n ) {\r\n placesAxis = 0\r\n }\r\n\r\n const getYLineText = (val: number, places?: number) => {\r\n switch (this.model.scale) {\r\n case ScaleType.Percentage:\r\n return `${val}%`\r\n default:\r\n return this.round(val, places)\r\n }\r\n }\r\n\r\n const yTickText = new Text(\r\n {\r\n x: this.width + this.getYAxisLeftMargin() + ChartSettings.right.axis.margin.left!,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.right.axis.font),\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.paneModel\r\n )\r\n\r\n let yTickLine = this.getYLine()\r\n const resetYTicksStyles = () => {\r\n yTickText.set({\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.right.axis.font),\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n })\r\n yTickLine = this.getYLine()\r\n }\r\n for (let i = 0; i < lineTicks.length; i++) {\r\n y = Math.round(this.fy(lineTicks[i]))\r\n if (y < 0 || y > height) continue\r\n if (y === height) y -= 1 // due pixel perfect rendering of lines, line on bottom edge is moved outside of \"chart area\" because of 0.5px translate, to compensate for this we subtract 1px\r\n yTickLine.set({ y1: y, y2: y })\r\n yTickText.set({\r\n text: getYLineText(textTicks[i], placesAxis),\r\n y,\r\n })\r\n if (this.model.scale === ScaleType.Percentage && textTicks[i] === 0) {\r\n yTickLine.set({ strokeStyle: Colors.text })\r\n yTickText.set({\r\n font: { weight: 'bold', size: yTickText.attrs.font.size },\r\n fillStyle: Colors.percentageZeroLineText,\r\n })\r\n yTickLine.render(context)\r\n yTickText.render(context)\r\n resetYTicksStyles()\r\n } else {\r\n yTickLine.render(context)\r\n yTickText.render(context)\r\n }\r\n }\r\n translate.undo()\r\n\r\n if (renderLabels) {\r\n this.renderYAxisLabel({ context, yCoordinate: Math.round(this.fy(lastClose)), label: lastCloseLabel })\r\n // if (typeof this.data.afterClose === 'number') {\r\n // this.renderYAxisLabel({\r\n // context,\r\n // yCoordinate: this.getYAxisSecondaryLabelYCoordinate({\r\n // mainLabelValue: lastClose,\r\n // secondaryLabelValue: this.data.afterClose,\r\n // }),\r\n // label: this.getYAxisLastCloseLabel({ lastClose: this.data.afterClose, firstVisibleClose }),\r\n // background: this.getSecondaryLabelBackgroundColor(),\r\n // })\r\n // }\r\n }\r\n }\r\n\r\n getSecondaryLabelBackgroundColor() {\r\n return stringifyHSVAColor(\r\n {\r\n ...getHSVAFromColor(this.getChartLayoutSettings().ChartSettings.general.Colors.currentBackground),\r\n s: 0.3,\r\n },\r\n 'hex'\r\n )\r\n }\r\n\r\n getYAxisSecondaryLabelYCoordinate({\r\n mainLabelValue,\r\n secondaryLabelValue,\r\n }: {\r\n mainLabelValue: number\r\n secondaryLabelValue: number\r\n }) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { lineHeight } = ChartSettings.right.axis.font\r\n const padding = Text.getMergedPropsWithDefaults('padding', ChartSettings.right.axis.font.padding)\r\n\r\n const direction = Math.sign(mainLabelValue - secondaryLabelValue) || 1\r\n const offset = (lineHeight ?? LINE_HEIGHT.S) + (padding.top ?? PADDING.XXS) + (padding.bottom ?? PADDING.XXS)\r\n const mainLabelValuePosition = Math.round(this.fy(mainLabelValue))\r\n const secondaryLabelValuePosition = Math.round(this.fy(secondaryLabelValue))\r\n const offsetedY = mainLabelValuePosition + offset * direction\r\n\r\n return Math.abs(secondaryLabelValuePosition - mainLabelValuePosition) > offset\r\n ? secondaryLabelValuePosition\r\n : offsetedY\r\n }\r\n\r\n renderYAxisLabel({\r\n context,\r\n yCoordinate,\r\n label,\r\n background,\r\n }: {\r\n context: CanvasRenderingContext2D\r\n yCoordinate: number\r\n label: string\r\n background?: string\r\n }) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const translate = getTranslate({ context, xOffset: ChartSettings.left.width, yOffset: ChartSettings.top.height })\r\n const { Colors } = ChartSettings.general\r\n const { size, lineHeight } = ChartSettings.right.axis.font\r\n const padding = Text.getMergedPropsWithDefaults('padding', ChartSettings.right.axis.font.padding)\r\n\r\n translate.do()\r\n new Text(\r\n {\r\n text: label,\r\n x: this.width + this.getYAxisLeftMargin() - padding.left + ChartSettings.right.axis.margin.left!,\r\n y: yCoordinate,\r\n font: Text.getMergedPropsWithDefaults('font', { size, style: 'bold' }),\r\n lineHeight,\r\n padding,\r\n textBaseline: TextBaseline.middle,\r\n fillStyle:\r\n this.specificChartFunctionality === SpecificChartFunctionality.offScreen ? 'black' : Colors.currentText,\r\n background: background || Colors.currentBackground,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n translate.undo()\r\n }\r\n\r\n renderXAxis() {\r\n const { leftOffset, width } = this\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n\r\n this.context.save()\r\n if (\r\n this.data.getDrawDays() !== 1 &&\r\n !getIsSmallIndexChart(this.specificChartFunctionality) &&\r\n this.data.instrument !== Instrument.MarketSentiment\r\n ) {\r\n this.clip(true)\r\n }\r\n this.context.translate(ChartSettings.left.width, ChartSettings.top.height)\r\n const textRenderer = new Text(\r\n {\r\n y: this.height + ChartSettings.bottom.axis.margin.top!,\r\n font: Text.getMergedPropsWithDefaults('font', { size: ChartSettings.bottom.axis.font.size }),\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.top,\r\n textAlign: TextAlign.center,\r\n },\r\n this.paneModel\r\n )\r\n\r\n // Ticks are placed at the start of each timeframe period (hour/day/month/year).\r\n // The \"-1\" in the code ensures we start searching from one bar outside the visible area,\r\n // avoiding a tick on the first visible index unless it marks the start of a new timeframe period.\r\n // For example, if the start of December is on December 3rd and the first visible bar is on December 14th,\r\n // we won't display a tick.\r\n const startBarIndex = Math.max(\r\n getFirstBarToRenderIndex({\r\n quote: this.data,\r\n scale: this.paneModel.scale,\r\n leftOffset,\r\n }).index - 1,\r\n 0\r\n )\r\n\r\n const endBarIndex = getLastBarToRenderIndex({\r\n quote: this.data,\r\n scale: this.paneModel.scale,\r\n leftOffset,\r\n chartWidth: width,\r\n }).index\r\n\r\n switch (this.data.timeframe) {\r\n case TIMEFRAME.i1:\r\n case TIMEFRAME.i2:\r\n case TIMEFRAME.i3:\r\n case TIMEFRAME.i5:\r\n if (this.data.instrument === Instrument.Stock) {\r\n if (\r\n this.type === ChartElementType.LineChart &&\r\n this.specificChartFunctionality === SpecificChartFunctionality.offScreen &&\r\n this.data.timeframe === 'i5'\r\n ) {\r\n this.render15MinXAxis({ textRenderer, startBarIndex, endBarIndex })\r\n } else {\r\n this.renderIntradayXAxis(textRenderer)\r\n }\r\n } else {\r\n this.renderIntradayXAxisFutures({ textRenderer, startBarIndex, endBarIndex })\r\n }\r\n break\r\n case TIMEFRAME.i10:\r\n if (getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n this.renderIntradayXAxis(textRenderer)\r\n } else {\r\n this.render15MinXAxis({ textRenderer, startBarIndex, endBarIndex })\r\n }\r\n break\r\n case TIMEFRAME.i15:\r\n case TIMEFRAME.i30:\r\n case TIMEFRAME.h:\r\n case TIMEFRAME.h2:\r\n case TIMEFRAME.h4:\r\n this.render15MinXAxis({ textRenderer, startBarIndex, endBarIndex })\r\n break\r\n case TIMEFRAME.d:\r\n this.renderDailyXAxis({ textRenderer, startBarIndex, endBarIndex })\r\n break\r\n case TIMEFRAME.w:\r\n this.renderWeeklyXAxis({ textRenderer, startBarIndex, endBarIndex })\r\n break\r\n case TIMEFRAME.m:\r\n this.renderMonthlyXAxis({ textRenderer, startBarIndex, endBarIndex })\r\n break\r\n default:\r\n break\r\n }\r\n this.context.restore()\r\n }\r\n\r\n isXPointVisible(x: number, buffer = 0) {\r\n return x >= 0 - buffer && x <= this.width + buffer\r\n }\r\n\r\n renderXAxisLabels({\r\n labels,\r\n textRenderer,\r\n allowedOverflow = 0,\r\n }: {\r\n labels: Omit[]\r\n textRenderer: Text\r\n allowedOverflow?: number\r\n }) {\r\n const sortedLabels: XAxisLabel[] = []\r\n const renderedLabelRanges: Array<{ from: number; to: number }> = []\r\n labels.reverse().forEach((label) => {\r\n textRenderer.set({ text: label.text })\r\n const textWidth = Math.floor(textRenderer.measure(this.context))\r\n const newLabel = { ...label, textWidth }\r\n if (label.hasPriority) {\r\n sortedLabels.unshift(newLabel)\r\n } else {\r\n sortedLabels.push(newLabel)\r\n }\r\n })\r\n\r\n sortedLabels.forEach(({ x, text, textWidth }) => {\r\n if (!this.isXPointVisible(x, allowedOverflow)) {\r\n return\r\n }\r\n const halfOfTextWidth = textWidth / 2\r\n const overflowLeft = x - halfOfTextWidth + allowedOverflow\r\n const overflowRight = this.width - (x + halfOfTextWidth) + allowedOverflow\r\n let labelX = x\r\n if (overflowLeft < 0) {\r\n labelX = Math.round(x - overflowLeft)\r\n } else if (overflowRight < 0) {\r\n labelX = Math.round(x + overflowRight)\r\n }\r\n if (getIsOverlapping({ x: labelX, textWidth, renderedLabelRanges })) {\r\n return\r\n }\r\n renderedLabelRanges.push({\r\n from: labelX - halfOfTextWidth - OFFSET.M,\r\n to: labelX + halfOfTextWidth + OFFSET.M,\r\n })\r\n textRenderer.set({ text, x: labelX })\r\n textRenderer.render(this.context)\r\n })\r\n }\r\n\r\n renderIntradayXAxis(textRenderer: Text) {\r\n const interval = IntradayTimeframeInterval[this.data.timeframe as keyof typeof IntradayTimeframeInterval]\r\n const marketStartHour = ~~(this.data.marketStartMinutes / 60)\r\n let marketEndHour = 15 + Math.ceil(this.data.aftermarketLengthMinutes / 60)\r\n const labels = []\r\n if (getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n marketEndHour = 16\r\n }\r\n\r\n const xLine = this.getXLine()\r\n const barWidth = getBarWidthWithMargin({\r\n zoomFactor: this.model.zoomFactor,\r\n chartLayout: this.model.chart_layout(),\r\n })\r\n\r\n const dayToOffset = this.data.getDayToOffset()\r\n const isSmallIndexChart = getIsSmallIndexChart(this.specificChartFunctionality)\r\n const allowedOverflow = isSmallIndexChart ? SMALL_INDEX_CHART_LABEL_BUFFER : 0\r\n for (const day in dayToOffset) {\r\n const dayIndex = dayToOffset[day]\r\n const date = dateFromDateString(day)\r\n\r\n for (let i = marketStartHour; i <= marketEndHour; i++) {\r\n let x =\r\n ((i * 60 - this.data.marketStartMinutes) / interval) * barWidth +\r\n dayIndex * (this.data.drawMinutesPerDay / interval) * barWidth +\r\n this.leftOffset\r\n if (!this.isXPointVisible(x, allowedOverflow)) {\r\n continue\r\n }\r\n let roundedX = Math.round(x)\r\n\r\n if (i === marketStartHour) {\r\n if (isSmallIndexChart) {\r\n roundedX = Math.round(x - 3 + (30 / interval) * barWidth)\r\n // ~9:30AM\r\n xLine\r\n .set({\r\n x1: roundedX,\r\n x2: roundedX,\r\n })\r\n .render(this.context)\r\n continue\r\n }\r\n if (this.data.premarketLengthMinutes === 0) {\r\n // If there is no premarket, day starts at 9:30 AM\r\n x += (30 / interval) * barWidth\r\n }\r\n roundedX = Math.round(x)\r\n xLine.set({ x1: roundedX, x2: roundedX }).render(this.context)\r\n labels.push({\r\n hasPriority: true,\r\n text: MONTHS[date.getMonth()] + ' ' + date.getDate().toString().padLeft('00'),\r\n x: roundedX,\r\n })\r\n } else {\r\n xLine.set({ x1: roundedX, x2: roundedX }).render(this.context)\r\n labels.push({\r\n text: ((i + 11) % 12) + 1 + (i < 12 ? 'AM' : 'PM'),\r\n x: roundedX,\r\n })\r\n }\r\n }\r\n }\r\n this.renderXAxisLabels({ labels, textRenderer, allowedOverflow })\r\n }\r\n\r\n renderIntradayXAxisFutures({ textRenderer, startBarIndex, endBarIndex }: IRenderXAxisProps) {\r\n let lastDay = ''\r\n let lastHours = NaN\r\n\r\n const labels = []\r\n const xLine = this.getXLine()\r\n for (let i = startBarIndex; i <= endBarIndex; i++) {\r\n const date = utils.dateFromUnixTimestamp(this.data.date[i])\r\n const day = date.getDate() + '-' + date.getMonth()\r\n const hours = date.getHours()\r\n const x = Math.round(this.fx(i) + this.leftOffset)\r\n\r\n if (day !== lastDay) {\r\n lastDay = day\r\n lastHours = hours\r\n if (!this.isXPointVisible(x)) {\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n labels.push({\r\n x,\r\n text: MONTHS[date.getMonth()] + ' ' + date.getDate().toString().padLeft('00'),\r\n })\r\n } else if (hours % 2 === 0 && hours !== lastHours) {\r\n lastHours = hours\r\n if (!this.isXPointVisible(x)) {\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n labels.push({ x, text: ((hours + 11) % 12) + 1 + (hours < 12 ? 'AM' : 'PM') })\r\n }\r\n }\r\n this.renderXAxisLabels({ labels, textRenderer })\r\n }\r\n\r\n render15MinXAxis({ textRenderer, startBarIndex, endBarIndex }: IRenderXAxisProps) {\r\n let lastDay = ''\r\n let x = 0\r\n\r\n const labels = []\r\n const xLine = this.getXLine()\r\n for (let i = startBarIndex; i <= endBarIndex; i++) {\r\n const date = utils.dateFromUnixTimestamp(this.data.date[i])\r\n const day = date.getDate() + '-' + date.getMonth()\r\n if (day !== lastDay) {\r\n lastDay = day\r\n if (this.data.instrument === Instrument.Stock) {\r\n const barAtMinute = date.getMinutes() + date.getHours() * 60\r\n const indexOffset = (barAtMinute - this.data.marketStartMinutes) / this.data.interval\r\n x = Math.round(this.paneModel.scale.x(this.data.barIndex[i] - indexOffset) + this.leftOffset)\r\n } else {\r\n x = Math.round(this.fx(i) + this.leftOffset)\r\n }\r\n if (!this.isXPointVisible(x)) {\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n labels.push({\r\n text: MONTHS[date.getMonth()] + ' ' + date.getDate().toString().padLeft('00'),\r\n x,\r\n })\r\n }\r\n }\r\n\r\n // Offscreen only - if lastDate !== lastBarDate add tick\r\n if (this.specificChartFunctionality === SpecificChartFunctionality.offScreen) {\r\n const lastDate = `${MONTHS[(~~(this.data.lastDate / 100) % 100) - 1]} ${(this.data.lastDate % 100)\r\n .toString()\r\n .padLeft('00')}` // YYYYMMDD / 20211118 => Nov 18\r\n\r\n if (labels.length > 0 && labels[labels.length - 1].text !== lastDate) {\r\n const barsInDay = this.data.getBarsInDay()!\r\n const barWidth = getBarWidthWithMargin({\r\n zoomFactor: this.model.zoomFactor,\r\n chartLayout: this.model.chart_layout(),\r\n })\r\n const dayWidth = barsInDay * barWidth\r\n x += dayWidth\r\n labels.push({\r\n text: lastDate,\r\n x,\r\n })\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n }\r\n }\r\n\r\n this.renderXAxisLabels({ labels, textRenderer })\r\n }\r\n\r\n renderDailyXAxis({ textRenderer, startBarIndex, endBarIndex }: IRenderXAxisProps) {\r\n let lastMonth = ''\r\n\r\n const labels = []\r\n const xLine = this.getXLine()\r\n for (let i = startBarIndex; i <= endBarIndex; i++) {\r\n const date = utils.dateFromUnixTimestamp(this.data.date[i])\r\n const month = date.getMonth() + '-' + date.getFullYear()\r\n if (month !== lastMonth) {\r\n lastMonth = month\r\n const x = Math.round(this.fx(i) + this.leftOffset)\r\n if (!this.isXPointVisible(x)) {\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n labels.push({\r\n hasPriority: date.getMonth() === 0,\r\n text: date.getMonth() === 0 ? date.getFullYear().toString() : MONTHS[date.getMonth()],\r\n x,\r\n })\r\n }\r\n }\r\n this.renderXAxisLabels({ labels, textRenderer })\r\n }\r\n\r\n renderWeeklyXAxis({ textRenderer, startBarIndex, endBarIndex }: IRenderXAxisProps) {\r\n let lastMonth = ''\r\n\r\n const labels = []\r\n const xLine = this.getXLine()\r\n const { Colors } = this.getChartLayoutSettings().ChartSettings.general\r\n for (let i = startBarIndex; i <= endBarIndex; i++) {\r\n const date = utils.dateFromUnixTimestamp(this.data.date[i])\r\n const month = date.getMonth() + '-' + date.getFullYear()\r\n if (month !== lastMonth) {\r\n lastMonth = month\r\n const x = Math.round(this.fx(i) + this.leftOffset)\r\n if (!this.isXPointVisible(x)) {\r\n continue\r\n }\r\n if (date.getMonth() % 3 === 0) {\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n } else {\r\n new Line(\r\n {\r\n x1: x,\r\n x2: x,\r\n y1: 0,\r\n y2: this.height,\r\n strokeStyle: Colors.gridSecondary,\r\n dashLength: 3,\r\n },\r\n this.paneModel\r\n ).render(this.context)\r\n }\r\n const isYearLabel = date.getMonth() === 0\r\n labels.push({\r\n text: isYearLabel ? date.getFullYear().toString().substring(2) : MONTHS[date.getMonth()][0],\r\n hasPriority: isYearLabel,\r\n x,\r\n })\r\n }\r\n }\r\n this.renderXAxisLabels({ labels, textRenderer })\r\n }\r\n\r\n renderMonthlyXAxis({ textRenderer, startBarIndex, endBarIndex }: IRenderXAxisProps) {\r\n let lastYear = null\r\n\r\n const labels = []\r\n const xLine = this.getXLine()\r\n for (let i = startBarIndex; i <= endBarIndex; i++) {\r\n const date = utils.dateFromUnixTimestamp(this.data.date[i])\r\n const year = date.getFullYear()\r\n const isJanuary = date.getMonth() === 0\r\n if (year !== lastYear && (labels.length !== 0 || isJanuary)) {\r\n lastYear = year\r\n const x = Math.round(this.fx(i) + this.leftOffset)\r\n if (!this.isXPointVisible(x)) {\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n labels.push({\r\n text: date.getFullYear().toString(),\r\n x,\r\n })\r\n }\r\n }\r\n this.renderXAxisLabels({ labels, textRenderer })\r\n }\r\n\r\n handleIndicatorsChange() {\r\n this.updateShouldRenderVolume()\r\n this.setupCache()\r\n this.trigger('change')\r\n }\r\n\r\n updateShouldRenderVolume() {\r\n this.shouldRenderVolume = !this.model.chart_layout().getIsIndicatorPresent(IndicatorType.Vol)\r\n }\r\n\r\n getVolumeTicks(count: number, maxHeight: number, fontHeight: number): number[] {\r\n const maxCount = 5\r\n const minCount = 1\r\n if (count > maxCount) {\r\n count = maxCount\r\n }\r\n const ticks = this.volumeFY.ticks(count).filter((tick) => tick !== 0)\r\n if (count <= minCount) {\r\n return [ticks[ticks.length - 1]]\r\n }\r\n // ticks are rendered on middle line so we have +- 1/2 of font size above and below range[min,max]\r\n // so we already have +-1 fontsize space, but in some cases that wouldn't be enough so we need to scale\r\n // dynamically, we add 3px of space per tick gap\r\n if (ticks.length * fontHeight + (ticks.length - 1) * 3 > maxHeight) {\r\n return this.getVolumeTicks(count - 1, maxHeight, fontHeight)\r\n }\r\n return ticks\r\n }\r\n\r\n renderVolumeAxis(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n if (getIsSmallIndexChart(this.specificChartFunctionality)) {\r\n context.save()\r\n const relativeVolume = Math.max(0, Math.min(2, this.data.relativeVolume))\r\n\r\n const x = 20\r\n const fy = (y: number) => ChartSettings.top.height + this.height - this.height * (0.5 * y)\r\n const height = this.height * (0.5 * relativeVolume)\r\n\r\n const label = new Text(\r\n {\r\n x: 15,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n textAlign: TextAlign.right,\r\n },\r\n this.paneModel\r\n )\r\n for (let i = 0.5; i <= 2; i += 0.5) {\r\n const y = Math.round(fy(i))\r\n label\r\n .set({\r\n text: i.toFixed(1),\r\n y: y,\r\n })\r\n .render(context)\r\n\r\n context.set('strokeStyle', 'rgb(130, 130, 130)')\r\n context.beginPath()\r\n context.setLineDash([2, 3])\r\n context.translate(0, 0.5)\r\n context.moveTo(x, y)\r\n context.lineTo(x + 7, y)\r\n context.translate(0, -0.5)\r\n context.stroke()\r\n }\r\n\r\n context.set('fillStyle', 'rgba(0, 135, 255, 0.58)')\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', Colors.grid)\r\n context.setLineDash([])\r\n\r\n context.fillRect(x, Math.round(ChartSettings.top.height + this.height - height), 7, Math.round(height))\r\n context.translate(0.5, 0.5)\r\n context.strokeRect(x, ChartSettings.top.height, 7, this.height)\r\n context.translate(-0.5, -0.5)\r\n\r\n new Text(\r\n {\r\n text: 'RELATIVE\\nVOLUME',\r\n x: 33,\r\n y: ChartSettings.top.height + this.height + 6,\r\n font: { size: FONT_SIZE.XXS },\r\n lineHeight: LINE_HEIGHT.XS,\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.top,\r\n textAlign: TextAlign.right,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n context.restore()\r\n return\r\n }\r\n const rangeMax = this.volumeFY.range()[1]\r\n const volumeAxisFontSize = ChartSettings.left.volumeAxis.font.size!\r\n const tickCount = Math.floor(rangeMax / volumeAxisFontSize)\r\n const ticks = this.getVolumeTicks(tickCount, rangeMax, volumeAxisFontSize)\r\n const format = this.volumeFY.tickFormat(4, 's')\r\n const text = new Text(\r\n {\r\n x: ChartSettings.left.volumeAxis.margin.left,\r\n font: Text.getMergedPropsWithDefaults('font', { size: ChartSettings.left.volumeAxis.font.size }),\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n textAlign: TextAlign.right,\r\n },\r\n this.paneModel\r\n )\r\n ticks.forEach((tick) =>\r\n text\r\n .set({\r\n text: format(tick).replace(/G/, 'B'), // https://github.com/d3/d3-format/blob/master/README.md#locale_formatPrefix\r\n y: ChartSettings.top.height + this.height - this.volumeFY(tick),\r\n })\r\n .render(context)\r\n )\r\n }\r\n\r\n renderVolume() {\r\n if (!this.shouldRenderVolume) return\r\n\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n // Return if the domain bounds are equal, this would put any value in the middle\r\n const [domainFrom, domainTo] = this.volumeFY.domain()\r\n if (this.setupAxisTimeFrame !== this.data.timeframe || domainFrom === domainTo) {\r\n return\r\n }\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height + this.height - 59,\r\n })\r\n translate.do()\r\n const halfBarWidth = this.getHalfBarWidth()\r\n const barWidthWithoutMargin = this.getBarWithoutMarginWidth()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.paneModel.scale,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i, x) => {\r\n // Skip render if the value is <= 0\r\n if (this.data.volume[i] <= 0) {\r\n return\r\n }\r\n\r\n this.context.fillStyle = this.data.close[i] < this.data.open[i] ? Colors.volumeTrendDown : Colors.volumeTrendUp\r\n const y = Math.round(this.volumeFY(this.data.volume[i]))\r\n this.context.fillRect(x - halfBarWidth, 60, barWidthWithoutMargin, -y)\r\n },\r\n })\r\n translate.undo()\r\n }\r\n\r\n renderOverlays() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n for (const overlay of this.overlays) {\r\n overlay.renderContent(this.context)\r\n }\r\n translate.undo()\r\n }\r\n\r\n renderCross(context: CanvasRenderingContext2D) {\r\n const isRendered = renderCross({\r\n context,\r\n mouseModel,\r\n paneModel: this.paneModel,\r\n contentWidth: this.width,\r\n contentHeight: this.height,\r\n quote: this.data,\r\n getRoundDecimalPlaces: (price) => this.getPlacesLastClose(price),\r\n onRenderCrossText: !this.getIsRedesignedChart() ? this.renderCrossText : undefined,\r\n })\r\n if (this.getIsRedesignedChart()) {\r\n this.renderCrossText(context, mouseModel.getCrossIndexForPane(this.paneModel))\r\n }\r\n\r\n if (isRendered !== undefined) {\r\n setElementCursor({\r\n elementId: this.model.chart_layout().getHTMLElementId(),\r\n cursor: isRendered ? 'crosshair' : 'default',\r\n conditionalCursor: 'grabbing',\r\n })\r\n }\r\n }\r\n\r\n getDataByCrossIndex(crossIndex: number, key: keyof Quote, shouldReturnRoundedString = true) {\r\n const n = this.data.getDataByBarIndex(key, crossIndex)\r\n if (n !== null) {\r\n return shouldReturnRoundedString ? this.roundOhlc(n) : `${n}`\r\n }\r\n }\r\n\r\n getCrossIndexChange(crossIndex: number) {\r\n const crossDataIndex = this.data.getDataIndexByBarIndex(crossIndex)\r\n const crossClose = this.data.close[crossDataIndex] ?? null\r\n const previousClose = this.data.close[crossDataIndex - 1] ?? null\r\n if (crossClose !== null && previousClose !== null) {\r\n return getTickerChangeFromCloseValues({ data: this.data, anchorClose: crossClose, prevClose: previousClose })\r\n }\r\n\r\n return null\r\n }\r\n\r\n renderCrossText(context: CanvasRenderingContext2D, crossIndex: number) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n context.save()\r\n context.translate(ChartSettings.left.width, 0)\r\n\r\n if (this.getIsRedesignedChart()) {\r\n this.renderOverlaysLabels(context)\r\n if (Number.isNaN(crossIndex)) {\r\n this.getOHLC({ context })\r\n context.restore()\r\n return\r\n }\r\n }\r\n\r\n const dateByBarIndex = this.data.getDataByBarIndex('date', crossIndex)\r\n const date = dateByBarIndex ? utils.dateFromUnixTimestamp(dateByBarIndex) : null\r\n\r\n if (date === null) {\r\n const virtualTradedDates =\r\n this.data.date.length > 0\r\n ? getVirtualTimeframeTradedDates({\r\n dateStart: this.data.date[0],\r\n dateEnd: this.data.date[this.data.date.length - 1],\r\n quote: this.data,\r\n })\r\n : []\r\n this.getOHLC({\r\n context,\r\n dateString: virtualTradedDates[crossIndex]\r\n ? getDateString({\r\n date: utils.dateFromUnixTimestamp(virtualTradedDates[crossIndex]),\r\n timeframe: this.data.timeframe,\r\n })\r\n : null,\r\n })\r\n context.restore()\r\n return\r\n }\r\n\r\n this.getOHLC({\r\n context,\r\n date,\r\n data: {\r\n open: this.getDataByCrossIndex(crossIndex, 'open'),\r\n high: this.getDataByCrossIndex(crossIndex, 'high'),\r\n low: this.getDataByCrossIndex(crossIndex, 'low'),\r\n close: this.getDataByCrossIndex(crossIndex, 'close'),\r\n volume: this.getDataByCrossIndex(crossIndex, 'volume', false),\r\n },\r\n changePercentage: this.getCrossIndexChange(crossIndex),\r\n })\r\n\r\n context.restore()\r\n }\r\n\r\n renderChange({ context }: { context: CanvasRenderingContext2D }) {\r\n const CHANGE_SPACER = 10\r\n const { ChartSettings, isOurSiteRequest } = this.getChartLayoutSettings()\r\n const { ticker, change, ohlc } = ChartSettings.top\r\n const { tickerChange, tickerAfterChange } = getTickerChange({ data: this.data })\r\n\r\n if (!tickerChange) {\r\n return\r\n }\r\n\r\n const isOffscreen = this.specificChartFunctionality === SpecificChartFunctionality.offScreen\r\n const isGroupInstrument = this.data.instrument === Instrument.Group\r\n const finvizWatermarkOffset = !isOffscreen || isOurSiteRequest || this.isLargeChart ? 0 : 15\r\n const changeText = new Text(\r\n {\r\n text: isOffscreen && isGroupInstrument ? tickerChange.percentString : tickerChange.string,\r\n x: !getIsSmallIndexChart(this.specificChartFunctionality)\r\n ? this.width - ChartSettings.top.change.margin.right! - finvizWatermarkOffset\r\n : this.width,\r\n y: ChartSettings.top.change.margin.top,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.top.change.font),\r\n textAlign: TextAlign.right,\r\n textBaseline: ChartSettings.top.baseline,\r\n fillStyle: getChangeColor({ change: tickerChange.points, ChartSettings }),\r\n },\r\n this.paneModel\r\n )\r\n this.changeWidth = changeText.measure(context)\r\n changeText.render(context)\r\n\r\n if (isOffscreen && (!this.isLargeChart || isGroupInstrument)) {\r\n return\r\n }\r\n if (tickerAfterChange) {\r\n const afterChangeText = new Text(\r\n {\r\n text: tickerAfterChange?.string,\r\n font: Text.getMergedPropsWithDefaults('font', ChartSettings.top.change.font),\r\n textAlign: TextAlign.right,\r\n textBaseline: ChartSettings.top.baseline,\r\n fillStyle: getChangeColor({ change: tickerAfterChange.points, ChartSettings }),\r\n },\r\n this.paneModel\r\n )\r\n const afterChangeTextWidth = afterChangeText.measure(context)\r\n const oneLineAHChangeWidth = this.changeWidth + CHANGE_SPACER + afterChangeTextWidth\r\n\r\n if (\r\n ChartSettings.left.width + this.tickerWidth + ticker.margin.left! + OFFSET.S <\r\n ChartSettings.left.width + this.width - oneLineAHChangeWidth - change.margin.right!\r\n ) {\r\n afterChangeText\r\n .set({\r\n x: this.width - ChartSettings.top.change.margin.right! - this.changeWidth - CHANGE_SPACER,\r\n y: ChartSettings.top.change.margin.top,\r\n })\r\n .render(context)\r\n this.afterChange = null\r\n this.changeWidth = oneLineAHChangeWidth\r\n } else if (\r\n this.lastOhlc[0] &&\r\n ChartSettings.left.width +\r\n this.tickerWidth +\r\n ticker.margin.left! +\r\n this.lastOhlc[0].width! +\r\n ohlc.margin.left! +\r\n ohlc.margin.right! <\r\n ChartSettings.left.width + this.width - afterChangeTextWidth - change.margin.right!\r\n ) {\r\n afterChangeText\r\n .set({\r\n x: this.width - ChartSettings.top.change.margin.right!,\r\n y: ChartSettings.top.change.margin.top! - ChartSettings.top.change.font.size! - OFFSET.S,\r\n })\r\n .render(context)\r\n this.changeWidth = Math.max(this.changeWidth, afterChangeTextWidth)\r\n this.afterChange = {\r\n x: this.width - ChartSettings.top.change.margin.right!,\r\n y: ChartSettings.top.change.margin.top! - ChartSettings.top.change.font.size! - OFFSET.S,\r\n width: afterChangeTextWidth,\r\n }\r\n }\r\n }\r\n }\r\n\r\n renderOHLC(parameters: IRenderOHLCParameters) {\r\n if (!this.getIsRedesignedChart()) {\r\n this.renderOHLCQuotePage(parameters)\r\n } else {\r\n this.renderOHLCChartsPage(parameters)\r\n }\r\n }\r\n\r\n renderOHLCChartsPage({ context, date, open, high, low, close, volume, changePercentage }: IRenderOHLCParameters) {\r\n const chartBreakpoints = getChartBreakpoints(this.width)\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n\r\n const OhlcText = new Text(\r\n {\r\n font: { size: FONT_SIZE.S },\r\n lineHeight: 18,\r\n fillStyle: Colors.text,\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.middle,\r\n background: getHEXWithSpecificAplha(Colors.canvasFill, 0.8),\r\n },\r\n this.paneModel\r\n )\r\n\r\n const dateElements = date ? [{ text: date, color: gray300 }] : []\r\n const trendColor = (open ?? 0) > (close ?? 0) ? tailwindColors.red[400] : tailwindColors.green[400]\r\n const oElements = open\r\n ? [\r\n { text: 'O', color: gray300 },\r\n { text: open, color: trendColor },\r\n ]\r\n : []\r\n const hElements = high\r\n ? [\r\n { text: 'H', color: gray300 },\r\n { text: high, color: trendColor },\r\n ]\r\n : []\r\n const lElements = low\r\n ? [\r\n { text: 'L', color: gray300 },\r\n { text: low, color: trendColor },\r\n ]\r\n : []\r\n const cElements = close\r\n ? [\r\n { text: 'C', color: gray300 },\r\n { text: close, color: trendColor },\r\n ]\r\n : []\r\n const volElements = volume\r\n ? [\r\n { text: 'Vol', color: gray300 },\r\n { text: volume, color: trendColor },\r\n ]\r\n : []\r\n const changeElements = changePercentage != null ? [{ text: changePercentage.string, color: trendColor }] : []\r\n\r\n const lines: OhlcLineElements[] = []\r\n\r\n const getFlatLineArrayWithSpaces = (lineElements: OhlcLineElements[]) =>\r\n lineElements.flatMap((elements, index) =>\r\n index > 0 ? ([...(elements.length > 0 ? ['space'] : []), ...elements] as OhlcLineElements) : elements\r\n )\r\n if (chartBreakpoints.isM) {\r\n lines.push(\r\n getFlatLineArrayWithSpaces([\r\n dateElements,\r\n oElements,\r\n hElements,\r\n lElements,\r\n cElements,\r\n volElements,\r\n changeElements,\r\n ])\r\n )\r\n } else if (chartBreakpoints.isS) {\r\n lines.push(getFlatLineArrayWithSpaces([dateElements, changeElements]))\r\n lines.push(getFlatLineArrayWithSpaces([oElements, hElements, lElements, cElements, volElements]))\r\n } else {\r\n lines.push(getFlatLineArrayWithSpaces([dateElements, volElements, changeElements]))\r\n lines.push(getFlatLineArrayWithSpaces([oElements, hElements, lElements, cElements]))\r\n }\r\n\r\n const startX = OFFSET.M - ChartSettings.left.width\r\n let x = startX\r\n let y = OFFSET.M + OhlcText.attrs.lineHeight / 2\r\n\r\n lines.forEach((line) => {\r\n x = startX\r\n line.forEach((lineElement, index, lineElements) => {\r\n const padding = { left: 1, right: 1, top: 0, bottom: 0 }\r\n const { text = '', color = undefined } = lineElement === 'space' ? {} : lineElement\r\n if (index === 0) {\r\n padding.left = 5\r\n } else if (index === lineElements.length - 1) {\r\n padding.right = 5\r\n } else if (lineElement === 'space') {\r\n padding.left = 7\r\n padding.right = 7\r\n if (!chartBreakpoints.isS) {\r\n padding.left = 5\r\n padding.right = 5\r\n }\r\n }\r\n OhlcText.set({ text, fillStyle: color, x, y, padding })\r\n OhlcText.render(context)\r\n x += OhlcText.width\r\n })\r\n y += OhlcText.attrs.lineHeight\r\n })\r\n }\r\n\r\n renderOverlaysLabelsChartsPage(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const chartBreakpoints = getChartBreakpoints(this.width)\r\n const LabelsText = new Text(\r\n {\r\n font: { size: FONT_SIZE.S },\r\n lineHeight: 18,\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.middle,\r\n background: getHEXWithSpecificAplha(ChartSettings.general.Colors.canvasFill, 0.8),\r\n // this function gets (indirectly) called from renderCrossText which is already \"translateX\" by ChartSettings.left.width\r\n x: OFFSET.M - ChartSettings.left.width,\r\n padding: { left: PADDING.S, right: PADDING.S, top: 0, bottom: 0 },\r\n },\r\n this.paneModel\r\n )\r\n\r\n let numberOfNewOhlcLines = 2\r\n if (chartBreakpoints.isM) {\r\n numberOfNewOhlcLines = 1\r\n } else if (chartBreakpoints.isS) {\r\n numberOfNewOhlcLines = 2\r\n }\r\n\r\n // We assume lineheight is the same as OHLC text\r\n const { lineHeight } = LabelsText.attrs\r\n let y = lineHeight * numberOfNewOhlcLines + lineHeight / 2 + OFFSET.M\r\n\r\n for (const overlay of this.overlays) {\r\n if (!overlay.isRenderedOverlaysLabel()) {\r\n continue\r\n }\r\n LabelsText.set({\r\n text: overlay.toString(),\r\n y,\r\n fillStyle: overlay.getLabelColor(),\r\n }).render(context)\r\n y += lineHeight\r\n }\r\n }\r\n\r\n renderOHLCQuotePage({\r\n context,\r\n date,\r\n open,\r\n high,\r\n low,\r\n close,\r\n volume,\r\n afterHour,\r\n isSmallIndexChart = false,\r\n isNewestOHLC = false,\r\n time,\r\n directRender = false,\r\n changePercentage,\r\n }: IRenderOHLCParameters) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const { ohlc } = ChartSettings.top\r\n const isOffscreen = this.specificChartFunctionality === SpecificChartFunctionality.offScreen\r\n const isGroupInstrument = this.data.instrument === Instrument.Group\r\n if (isOffscreen && isGroupInstrument) {\r\n ohlc.type = OHLCType.dateOnly\r\n } else if (isOffscreen && this.data.instrument !== Instrument.Stock && time) {\r\n ohlc.type = OHLCType.timeOnly\r\n }\r\n\r\n const lineTopY = ohlc.type ? ohlc.margin.top : ohlc.margin.top! - ChartSettings.top.ticker.font.size!\r\n const OHLCFontSize = ohlc.font.size!\r\n const centerXOffset =\r\n this.tickerWidth +\r\n ChartSettings.top.ticker.margin.left! +\r\n (this.width -\r\n (this.tickerWidth +\r\n ChartSettings.top.ticker.margin.left! +\r\n this.changeWidth +\r\n (isSmallIndexChart ? 0 : ChartSettings.top.change.margin.right!))) / // smallIndexChart don't have change.margin.right\r\n 2\r\n const leftXOffset = this.tickerWidth + ChartSettings.top.ticker.margin.left! + ohlc.margin.left!\r\n const hasOhlc = ![open, high, low, close, volume].some((ohlcString) => !ohlcString)\r\n const OHLC = hasOhlc\r\n ? {\r\n date: [date ?? ''],\r\n singleLine: [\r\n `${date} O:${open} H:${high} L:${low} C:${close}${\r\n afterHour ? ` AH:${afterHour}` : ''\r\n } Vol:${volume} `,\r\n /*\r\n * this is needed because of the way we render ohlc text down below in renderOHLCToCanvas\r\n * undefined is used instead of null because TS had some issues with `null` even if it is filtered out\r\n * */\r\n changePercentage ? changePercentage.string : undefined,\r\n ].filter((value) => value !== undefined),\r\n }\r\n : {\r\n date: [date ?? ''],\r\n singleLine: [`${date ?? ''}`],\r\n }\r\n\r\n const OHLC_TEXT = new Text(\r\n {\r\n font: { size: OHLCFontSize },\r\n },\r\n this.paneModel\r\n )\r\n\r\n const getOHLCType = () => {\r\n if (!isSmallIndexChart) {\r\n return OHLCType.singleLine\r\n }\r\n return OHLCType.dateOnly\r\n }\r\n\r\n const getOHLCSettings = () => {\r\n switch (ohlc.type || getOHLCType()) {\r\n case OHLCType.singleLine:\r\n return {\r\n text: OHLC.singleLine,\r\n x: [leftXOffset, leftXOffset],\r\n y: [ohlc.margin.top],\r\n textAlign: TextAlign.left,\r\n textBaseline: [TextBaseline.alphabetic],\r\n }\r\n case OHLCType.dateOnly:\r\n if (isOffscreen && isGroupInstrument) {\r\n const text = `${OHLC.date} Volume: ${volume}`\r\n const textWidth = OHLC_TEXT.set({ text }).measure(context)\r\n return {\r\n text: [text],\r\n x: [\r\n this.width - ChartSettings.top.change.margin.right! - this.changeWidth - textWidth - CHART_MARGIN.XXL,\r\n ],\r\n y: [ohlc.margin.top],\r\n textAlign: TextAlign.center,\r\n textBaseline: [TextBaseline.alphabetic],\r\n }\r\n } else if (isSmallIndexChart) {\r\n return {\r\n text: OHLC.date,\r\n x: [centerXOffset],\r\n y: [ohlc.margin.top],\r\n textAlign: TextAlign.center,\r\n textBaseline: [TextBaseline.alphabetic],\r\n }\r\n } else {\r\n const isEnoughSpace =\r\n this.width -\r\n (this.tickerWidth +\r\n ChartSettings.top.ticker.margin.left! +\r\n ohlc.margin.left! +\r\n ohlc.margin.right! +\r\n this.changeWidth +\r\n ChartSettings.top.change.margin.right!) >\r\n OHLC_TEXT.set({ text: OHLC.date[0] }).measure(context)\r\n const alignTop = !isEnoughSpace || ohlc.font.baseline === TextBaseline.top\r\n return {\r\n text: OHLC.date,\r\n x: [leftXOffset],\r\n y: alignTop ? [lineTopY] : [ohlc.margin.top],\r\n textAlign: TextAlign.left,\r\n textBaseline: alignTop ? [TextBaseline.top] : [TextBaseline.alphabetic],\r\n }\r\n }\r\n case OHLCType.timeOnly:\r\n return {\r\n text: [time],\r\n x: [centerXOffset - OHLC_TEXT.set({ text: time }).measure(context) / 2],\r\n y: [lineTopY],\r\n textAlign: TextAlign.center,\r\n textBaseline: [ohlc.font.baseline],\r\n }\r\n default:\r\n return\r\n }\r\n }\r\n\r\n if (!isNewestOHLC) {\r\n context.fillStyle = Colors.canvasFill\r\n this.lastOhlc.forEach((line) => {\r\n const x = (line.textAlign === TextAlign.left ? line.x : line.x! - line.width! / 2)!\r\n const y = (line.textBaseline === TextBaseline.top ? line.y : line.y! - OHLCFontSize)!\r\n context.fillRect(\r\n x - PADDING.XXS,\r\n y - PADDING.XXS,\r\n PADDING.XXS + line.width! + PADDING.XXS,\r\n PADDING.XXS + OHLCFontSize + PADDING.XXS\r\n )\r\n })\r\n\r\n if (this.afterChange) {\r\n context.fillRect(\r\n this.afterChange.x - this.afterChange.width - PADDING.XXS,\r\n this.afterChange.y - ChartSettings.top.change.font.size! - PADDING.XXS,\r\n PADDING.XXS + this.afterChange.width + PADDING.XXS,\r\n PADDING.XXS + ChartSettings.top.change.font.size! + PADDING.XS\r\n )\r\n }\r\n } else {\r\n this.lastOhlc = []\r\n }\r\n\r\n const ohlcSettings = getOHLCSettings()\r\n\r\n const renderOHLCToCanvas = ({\r\n ohlcSet,\r\n render = true,\r\n }: {\r\n ohlcSet?: {\r\n text: (string | undefined)[]\r\n x: number[]\r\n y: (number | undefined)[]\r\n textAlign: TextAlign\r\n textBaseline: (TextBaseline | undefined)[]\r\n }\r\n render?: boolean\r\n }) => {\r\n const isSingleLineWithChange = (ohlc.type || getOHLCType()) === OHLCType.singleLine && changePercentage\r\n ohlcSet?.text.forEach((line: string | undefined, index: number) => {\r\n let i = index\r\n let leftOffset = 0\r\n let fillStyle = Colors.text\r\n let text = line\r\n if (index > 0 && isSingleLineWithChange) {\r\n i -= 1\r\n leftOffset = OHLC_TEXT.measure(context)\r\n text = line\r\n\r\n fillStyle = getChangeColor({ change: changePercentage.points, ChartSettings })\r\n }\r\n const options = {\r\n text,\r\n x: ohlcSet.x[i] + leftOffset,\r\n y: ohlcSet.y[i],\r\n textBaseline: ohlc.font.baseline ? ohlc.font.baseline : ohlcSet.textBaseline[i],\r\n textAlign: ohlc.font.textAlign ? ohlc.font.textAlign : ohlcSet.textAlign,\r\n fillStyle,\r\n }\r\n OHLC_TEXT.set(options)\r\n if (isNewestOHLC) {\r\n this.lastOhlc[i] = { width: OHLC_TEXT.measure(context), ...options }\r\n }\r\n if (render) {\r\n OHLC_TEXT.render(context)\r\n }\r\n })\r\n }\r\n renderOHLCToCanvas({ ohlcSet: ohlcSettings, render: directRender })\r\n\r\n return {\r\n ohlcSettings,\r\n renderOHLCToCanvas,\r\n }\r\n }\r\n\r\n // only for stocks on i1/i3/i5 and one day view\r\n renderFadeExtendedHours() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const period = this.model.quote().timeframe\r\n if (this.data.instrument !== Instrument.Stock) {\r\n return\r\n }\r\n if (![TIMEFRAME.i1, TIMEFRAME.i2, TIMEFRAME.i3, TIMEFRAME.i5].includes(period)) {\r\n return\r\n }\r\n\r\n const interval = parseInt(period.substring(1), 10)\r\n const dayToOffset = this.data.getDayToOffset()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n const halfBarWidth = this.getHalfBarWidth()\r\n for (const day in dayToOffset) {\r\n // todo aftermarket\r\n const dayIndex = dayToOffset[day]\r\n let n0 = (this.data.drawMinutesPerDay / interval) * dayIndex\r\n let n1 = this.data.premarketLengthMinutes / interval + n0 // bars in 90mins from 8am to 9:30am\r\n let x0 = this.paneModel.scale.x(n0) - halfBarWidth\r\n let width = this.paneModel.scale.x(n1) - this.paneModel.scale.x(n0)\r\n this.context.set('fillStyle', Colors.premarketFade)\r\n this.context.fillRect(x0, 0, width, this.height + 1)\r\n\r\n if (this.data.aftermarketLengthMinutes > 0) {\r\n n0 =\r\n (this.data.drawMinutesPerDay / interval) * dayIndex +\r\n (this.data.drawMinutesPerDay - this.data.aftermarketLengthMinutes) / interval\r\n n1 = this.data.aftermarketLengthMinutes / interval + n0 // bars in 90mins from 4pm to 5:30pm\r\n x0 = this.paneModel.scale.x(n0) - halfBarWidth\r\n width = this.paneModel.scale.x(n1) - this.paneModel.scale.x(n0)\r\n\r\n this.context.set('fillStyle', Colors.aftermarketFade)\r\n this.context.fillRect(x0, 0, width, this.height + 1)\r\n }\r\n }\r\n translate.undo()\r\n }\r\n\r\n shouldShowPrevClose() {\r\n const quote = this.model.quote()\r\n const isStock = quote.instrument === Instrument.Stock\r\n const isIntradayWithPreMarket = TIMEFRAMES_WITH_PRE_MARKET.includes(quote.timeframe)\r\n const isIndexChart = this.specificChartFunctionality === SpecificChartFunctionality.smallIndex\r\n\r\n return isStock && (isIntradayWithPreMarket || isIndexChart)\r\n }\r\n\r\n renderPrevClose() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n if (!this.shouldShowPrevClose()) {\r\n return\r\n }\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n\r\n let y = Math.round(this.fy(this.model.quote().prevClose))\r\n if (y === this.height) y -= 1 // due pixel perfect rendering of lines, line on bottom edge is moved outside of \"chart area\" because of 0.5px translate, to compensate for this we subtract 1px\r\n\r\n new Line(\r\n {\r\n x1: 0,\r\n x2: this.width,\r\n y1: y,\r\n y2: y,\r\n strokeStyle: Colors.prevClose,\r\n dashLength: 3,\r\n },\r\n this.paneModel\r\n ).render(this.context)\r\n translate.undo()\r\n }\r\n\r\n renderChartNotAvailable() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const x = ~~((ChartSettings.left.width + ChartSettings.right.width + this.width) / 2)\r\n const y = ~~((ChartSettings.top.height + ChartSettings.bottom.height + this.height) / 2)\r\n new Text(\r\n {\r\n text: 'Chart not available',\r\n x,\r\n y,\r\n font: { size: FONT_SIZE.M, style: 'bold' },\r\n fillStyle: Colors.text,\r\n textAlign: TextAlign.center,\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.paneModel\r\n ).render(this.context)\r\n }\r\n\r\n // private\r\n setupCache() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n /*\r\n * Don't create new Cache instances, because Safari takes too long to free up memory\r\n * leading to canvas.getContext returning null. https://stackoverflow.com/questions/52532614/total-canvas-memory-use-exceeds-the-maximum-limit-safari-12\r\n *\r\n * To further improve performance, cache.set shouldn't be called when unnecessary,\r\n * because setupCache is called for many model updates. The same applies for indicators/indicator.js.\r\n */\r\n this.baseCache = this.baseCache || new Cache()\r\n\r\n this.baseCache.set(\r\n (context: CanvasRenderingContext2D) => {\r\n if (this.data.close.length === 0) {\r\n this.renderText(context)\r\n return\r\n }\r\n this.renderYAxis(context)\r\n this.renderText(context)\r\n if (!this.getIsMobileChartPage() && this.shouldRenderVolume) {\r\n this.renderVolumeAxis(context)\r\n }\r\n if (!this.getIsRedesignedChart()) {\r\n this.renderOverlaysLabels(context)\r\n }\r\n },\r\n this.width + ChartSettings.left.width + ChartSettings.right.width,\r\n this.height + ChartSettings.top.height + ChartSettings.bottom.height\r\n )\r\n }\r\n\r\n // called by controllers/pane on recountScale\r\n setupAxis(fx: ScaleAxis) {\r\n this.data = this.model.quote()\r\n const { volumeHeight } = this.getChartLayoutSettings().ChartSettings.center\r\n\r\n if (typeof fx !== 'function') {\r\n return\r\n }\r\n\r\n const halfBarWidth = this.getHalfBarWidth()\r\n\r\n const volumes = []\r\n for (let i = 0; i < this.data.volume.length; i++) {\r\n const x = fx(this.data.barIndex[i]) - halfBarWidth\r\n if (x + this.model.leftOffset < 0 || x + this.model.leftOffset > this.width) {\r\n // margin?\r\n continue\r\n }\r\n volumes.push(this.data.volume[i])\r\n }\r\n\r\n const max = utils.max(volumes) ?? 0\r\n const rangeMax = volumeHeight || 60\r\n this.volumeFY = d3.scaleLinear().range([0, rangeMax]).domain([0, max]).nice(4)\r\n this.setupAxisTimeFrame = this.data.timeframe\r\n }\r\n\r\n // private\r\n clip(addMarginBottom?: boolean) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n if (addMarginBottom == null) {\r\n addMarginBottom = false\r\n }\r\n this.context.beginPath()\r\n let marginBottom = 0\r\n if (addMarginBottom) {\r\n marginBottom = ChartSettings.bottom.height\r\n }\r\n this.context.rect(ChartSettings.left.width, ChartSettings.top.height, this.width, this.height + marginBottom)\r\n this.context.clip()\r\n }\r\n\r\n addOverlay(overlay: Overlay) {\r\n overlay.chart = this\r\n this.overlays.push(overlay)\r\n return this.trigger('change')\r\n }\r\n\r\n setOverlays(overlays: Overlay[]) {\r\n this.overlays = overlays\r\n return this.trigger('change')\r\n }\r\n\r\n removeOverlay(overlay: Overlay) {\r\n for (let index = 0; index < this.overlays.length; index++) {\r\n const el = this.overlays[index]\r\n if (el === overlay) {\r\n this.attrs.overlays.splice(index, 1)\r\n this.overlays.splice(index, 1)\r\n this.trigger('change')\r\n break\r\n }\r\n }\r\n }\r\n\r\n getMinMax(): { min: number; max: number; firstVisibleClose?: number | null } {\r\n this.data = this.model.quote()\r\n let min = Number.MAX_VALUE\r\n let max = Number.MIN_VALUE\r\n let minIndex = -1\r\n let maxIndex = -1\r\n let firstVisibleClose = null\r\n\r\n const firstBarToRenderIndex = getFirstBarToRenderIndex({\r\n leftOffset: this.model.leftOffset,\r\n scale: this.paneModel.scale,\r\n quote: this.data,\r\n compensateBarGap: false,\r\n })\r\n const lastBarToRenderIndex = getLastBarToRenderIndex({\r\n leftOffset: this.model.leftOffset,\r\n scale: this.paneModel.scale,\r\n quote: this.data,\r\n chartWidth: this.width,\r\n compensateBarGap: false,\r\n })\r\n\r\n const areNoBarsVisible =\r\n firstBarToRenderIndex.isBarGap &&\r\n lastBarToRenderIndex.isBarGap &&\r\n firstBarToRenderIndex.index === lastBarToRenderIndex.index\r\n\r\n // If no bars are visible min/max are first available bar before visible and first after\r\n if (areNoBarsVisible) {\r\n min = this.data.low[firstBarToRenderIndex.index]\r\n max = this.data.high[Math.min(lastBarToRenderIndex.index, this.data.barIndex.length - 1)]\r\n firstVisibleClose = this.data.close[firstBarToRenderIndex.index]\r\n } else {\r\n // If there is a barGap on the 1st visible index, that index represents the previous bar outside of the visible area\r\n // so by incrementning by 1 we get the 1st bar existing in visible area\r\n const firstIndexNormalized = firstBarToRenderIndex.index + (firstBarToRenderIndex.isBarGap ? 1 : 0)\r\n for (let i = firstIndexNormalized; i <= lastBarToRenderIndex.index; i++) {\r\n if (minIndex === -1 || this.data.low[minIndex] > this.data.low[i]) {\r\n minIndex = i\r\n }\r\n if (maxIndex === -1 || this.data.high[maxIndex] < this.data.high[i]) {\r\n maxIndex = i\r\n }\r\n }\r\n\r\n // If only a single bar is visible get min/max index range from closes values outside of visible area\r\n if (this.data.low[minIndex] === this.data.high[maxIndex]) {\r\n const closestMinMaxIndices = getClosestDifferentMinMaxValueIndices(\r\n minIndex,\r\n maxIndex,\r\n this.data.high,\r\n this.data.low\r\n )\r\n minIndex = closestMinMaxIndices.minIndex\r\n maxIndex = closestMinMaxIndices.maxIndex\r\n }\r\n\r\n min = this.data.low[minIndex]\r\n max = this.data.high[maxIndex]\r\n\r\n firstVisibleClose = this.data.close[firstIndexNormalized]\r\n }\r\n\r\n // Update min/max so prevClose is in range and can be rendered if it should\r\n if (this.shouldShowPrevClose() && this.data.prevClose !== null) {\r\n min = Math.min(min, this.data.prevClose)\r\n max = Math.max(max, this.data.prevClose)\r\n }\r\n\r\n // Update min/max so lastClose is in range and can be rendered if it should\r\n if (this.specificChartFunctionality === SpecificChartFunctionality.offScreen && !this.model.dateRange) {\r\n min = Math.min(min, this.data.lastClose)\r\n max = Math.max(max, this.data.lastClose)\r\n }\r\n\r\n return { min, max, firstVisibleClose }\r\n }\r\n\r\n moveBy() {}\r\n\r\n isInArea() {\r\n return false\r\n }\r\n\r\n fx = (x: number) => this.paneModel.scale.x(this.data.barIndex[x])\r\n\r\n fy = (y: number) => this.paneModel.scale.y(y)\r\n\r\n round(n: number, overridePlaces?: number) {\r\n return round({ data: this.data, num: n, overridePlaces: overridePlaces ?? this.getPlacesLastClose() })\r\n }\r\n\r\n roundOhlc(n: number) {\r\n const placesLastClose = this.getPlacesLastClose()\r\n return round({\r\n data: this.data,\r\n num: n,\r\n overridePlaces: placesLastClose ? Math.max(placesLastClose, 2) : undefined,\r\n })\r\n }\r\n\r\n toObject() {\r\n const overlays = this.overlays.map((overlay) => overlay.toObject())\r\n return merge({}, this.attrs, { type: this.type, overlays })\r\n }\r\n\r\n toConfig() {\r\n const overlays = this.overlays.map((overlay) => overlay.toConfig())\r\n return merge({}, this.attrs, { type: this.type, overlays })\r\n }\r\n\r\n getBarWithoutMarginWidth() {\r\n const { barFillWidth, barBorderWidth } = getBarWidthWithMarginByParts({\r\n chartLayout: this.model.chart_layout(),\r\n zoomFactor: this.model.zoomFactor,\r\n })\r\n return barFillWidth + barBorderWidth * 2\r\n }\r\n\r\n getHalfBarWidth() {\r\n return ~~Math.max(1, this.getBarWithoutMarginWidth() / 2)\r\n }\r\n\r\n getPlacesLastClose(price?: number) {\r\n const { lastClose, instrument } = this.data\r\n const priceAbs = price && Math.abs(price)\r\n if (lastClose >= 100000) {\r\n return 0\r\n } else if (lastClose >= 10000) {\r\n return 1\r\n } else if (instrument === Instrument.Stock && (priceAbs ?? lastClose) < 1) {\r\n return 4\r\n } else if (lastClose === undefined) {\r\n // if lastClose is not defined we'll always display 2 decimpal places, e.g. backtests, screener stats\r\n return 2\r\n }\r\n\r\n return undefined\r\n }\r\n\r\n hasOverlay(type: string) {\r\n return this.overlays.some((x) => x.type === 'overlays/' + type)\r\n }\r\n\r\n getXLine(): Line {\r\n return new Line(\r\n {\r\n y1: 0,\r\n y2: this.height,\r\n strokeStyle: this.getChartLayoutSettings().ChartSettings.general.Colors.grid,\r\n dashLength: 3,\r\n },\r\n this.paneModel\r\n )\r\n }\r\n\r\n getYLine(): Line {\r\n return new Line(\r\n {\r\n x1: 0,\r\n x2: this.width,\r\n strokeStyle: this.getChartLayoutSettings().ChartSettings.general.Colors.grid,\r\n dashLength: 3,\r\n },\r\n this.paneModel\r\n )\r\n }\r\n\r\n getChartLayoutSettings() {\r\n return getChartLayoutSettings(this.model.chart_layout())\r\n }\r\n\r\n getIsMobileChartPage() {\r\n return (\r\n this.isMobile && this.model.chart_layout().specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n )\r\n }\r\n\r\n getCandleLikeChartsRenderingColors() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const { theme, specificChartFunctionality } = this.model.chart_layout()\r\n let colors = Colors\r\n const overwrittenColors = getColorOverwrites({\r\n colors,\r\n theme,\r\n })\r\n const overwrittenColorKeys = Object.keys(overwrittenColors)\r\n const hasOverwrittenCandleColor = ['borderUp', 'wickUp', 'borderDown', 'wickDown', 'trendUp', 'trendDown'].some(\r\n (colorKey) => overwrittenColorKeys.includes(colorKey)\r\n )\r\n\r\n const shouldUseDarkerColors =\r\n theme === Theme.light &&\r\n getShouldUseDarkerWickColors({\r\n specificChartFunctionality: specificChartFunctionality,\r\n totalBarWidth: ChartSettings.center.barWidth + ChartSettings.center.border * 2,\r\n })\r\n\r\n if (shouldUseDarkerColors && !hasOverwrittenCandleColor) {\r\n colors = { ...colors, ...darkerWickColors }\r\n }\r\n const isNodeChartWithThinBars =\r\n specificChartFunctionality === SpecificChartFunctionality.offScreen && ChartSettings.center.border === 0\r\n if (isNodeChartWithThinBars && !hasOverwrittenCandleColor) {\r\n colors = { ...colors, ...thinBarColorsOverride, ...overwrittenColors }\r\n }\r\n\r\n return colors\r\n }\r\n\r\n getIsRedesignedChart() {\r\n return this.specificChartFunctionality === SpecificChartFunctionality.chartPage || isRedesignedPage(this)\r\n }\r\n}\r\n\r\nBaseChart.initClass()\r\n\r\nexport default BaseChart\r\n","import { RendererChartBarProps } from '../../types/shared'\r\nimport { ChartElementType } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport utils from '../utils'\r\nimport { getBarWidthWithMarginByParts } from '../utils/chart'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { getIsSSr } from '../utils/helpers'\r\nimport Chart from './base_chart'\r\n\r\nconst WICK_WIDTH = 1\r\n\r\nclass CandleStick extends Chart {\r\n static type = ChartElementType.CandleStick\r\n static label = 'Candle'\r\n static iconName = 'candleBarBasic'\r\n\r\n getRenderChartBarProps({ index, chartSettingsColors, hasFillAndBorder }: RendererChartBarProps) {\r\n const { trendDown, trendUp, borderDown, borderUp, wickDown, wickUp } = chartSettingsColors\r\n const open = this.data.open[index]\r\n const close = this.data.close[index]\r\n const trendColor = close < open ? trendDown : trendUp\r\n const wickColor = close < open ? wickDown : wickUp\r\n return {\r\n open,\r\n close,\r\n high: this.data.high[index],\r\n low: this.data.low[index],\r\n barFillColor: trendColor,\r\n borderColor: close < open ? borderDown : borderUp,\r\n wickColor: hasFillAndBorder ? wickColor : trendColor,\r\n }\r\n }\r\n\r\n renderChart() {\r\n if (this.setupAxisTimeFrame !== this.data.timeframe) {\r\n return\r\n }\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const Colors = this.getCandleLikeChartsRenderingColors()\r\n const { barFillWidth, barBorderWidth } = getBarWidthWithMarginByParts({\r\n chartLayout: this.model.chart_layout(),\r\n zoomFactor: this.model.zoomFactor,\r\n })\r\n const shouldRenderFillAndBorder =\r\n barFillWidth + barBorderWidth * 2 >= 2 &&\r\n !(this.type === ChartElementType.HollowCandleStick && barBorderWidth === 0)\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n const translateForWick = getTranslate({\r\n context: this.context,\r\n xOffset: WICK_WIDTH / 2,\r\n yOffset: 0,\r\n })\r\n\r\n translate.do()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.paneModel.scale,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, center: number) => {\r\n const { open, close, high, low, wickColor, borderColor, barFillColor } = this.getRenderChartBarProps({\r\n index: i,\r\n chartSettingsColors: Colors,\r\n hasFillAndBorder: shouldRenderFillAndBorder,\r\n })\r\n\r\n const candleBodyHigh = Math.round(this.fy(utils.max(open, close)))\r\n const candleBodyLow = Math.round(this.fy(utils.min(open, close)))\r\n const candleWickHigh = Math.round(this.fy(high))\r\n const candleWickLow = Math.round(this.fy(low))\r\n\r\n const candleBodyHeight = candleBodyLow - candleBodyHigh\r\n const candleBodyLeftX = center - Math.floor(barBorderWidth + barFillWidth / 2)\r\n const halfBorderWidth = barBorderWidth / 2\r\n\r\n // TODO: revisit for better approach, this solve issue with candlesticks\r\n // with even width are shifted 1px to the left and thus first candle is vertically sliced\r\n if (getIsSSr() && candleBodyLeftX + this.leftOffset < 0) {\r\n return\r\n }\r\n\r\n const isBodyHeightGreaterOrEqualBorders = candleBodyHeight >= barBorderWidth * 2\r\n const isWickLineCandleLessThanOnePixel = !shouldRenderFillAndBorder && candleWickLow - candleWickHigh < 1\r\n\r\n translateForWick.do()\r\n this.context.set('strokeStyle', wickColor)\r\n this.context.beginPath()\r\n this.context.moveTo(center, candleWickHigh)\r\n if (shouldRenderFillAndBorder) {\r\n this.context.lineTo(center, candleBodyHigh)\r\n this.context.moveTo(\r\n center,\r\n candleBodyHigh + (isBodyHeightGreaterOrEqualBorders ? candleBodyHeight : WICK_WIDTH)\r\n )\r\n }\r\n this.context.lineTo(center, isWickLineCandleLessThanOnePixel ? candleWickHigh + 1 : candleWickLow)\r\n this.context.stroke()\r\n translateForWick.undo()\r\n\r\n if (shouldRenderFillAndBorder) {\r\n const hasBorder = barBorderWidth > 0\r\n if (hasBorder) {\r\n this.context.set('strokeStyle', borderColor)\r\n if (isBodyHeightGreaterOrEqualBorders) {\r\n this.context.set('lineWidth', barBorderWidth)\r\n this.context.strokeRect(\r\n candleBodyLeftX + halfBorderWidth,\r\n candleBodyHigh + halfBorderWidth,\r\n barFillWidth + 2 * halfBorderWidth,\r\n candleBodyHeight - 2 * halfBorderWidth\r\n )\r\n this.context.set('lineWidth', WICK_WIDTH)\r\n } else {\r\n this.context.beginPath()\r\n this.context.moveTo(candleBodyLeftX, candleBodyHigh + WICK_WIDTH / 2)\r\n this.context.lineTo(candleBodyLeftX + barFillWidth + 2 * barBorderWidth, candleBodyHigh + WICK_WIDTH / 2)\r\n this.context.stroke()\r\n }\r\n }\r\n\r\n const fillHeight = candleBodyHeight - 2 * barBorderWidth\r\n const hasFill = fillHeight > 0\r\n if (hasFill || !hasBorder) {\r\n this.context.set('fillStyle', hasFill ? barFillColor : borderColor)\r\n this.context.fillRect(\r\n candleBodyLeftX + barBorderWidth,\r\n candleBodyHigh + barBorderWidth,\r\n barFillWidth,\r\n hasFill ? fillHeight : WICK_WIDTH\r\n )\r\n }\r\n }\r\n },\r\n })\r\n translate.undo()\r\n }\r\n\r\n toString() {\r\n return `Candle stick ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default CandleStick\r\n","import { ChartConfigChartPaneElement, RendererChartBarProps, RequireByKey } from '../../types/shared'\r\nimport { ChartElementType } from '../constants/common'\r\nimport CandleStick from './candle_stick'\r\n\r\nclass HollowCandleStick extends CandleStick {\r\n static type = ChartElementType.HollowCandleStick\r\n static label = 'Hollow Candle'\r\n static iconName = 'candleBarHollow'\r\n\r\n static getNumOfBarsBuffer(element: RequireByKey) {\r\n return Math.max(1, super.getNumOfBarsBuffer(element))\r\n }\r\n\r\n getRenderChartBarProps({ index, chartSettingsColors }: RendererChartBarProps) {\r\n const open = this.data.open[index]\r\n const close = this.data.close[index]\r\n const isHollow = close > open\r\n const generalTrendColor =\r\n close > this.data.close[index - 1] ? chartSettingsColors.ohlcTrendUp : chartSettingsColors.ohlcTrendDown\r\n const trendColor = index === 0 ? chartSettingsColors.zeroChange : generalTrendColor\r\n return {\r\n open,\r\n close,\r\n high: this.data.high[index],\r\n low: this.data.low[index],\r\n // hollow candles have transparend bodies that's why rgba is here\r\n barFillColor: isHollow ? 'rgba(0, 0, 0, 0)' : trendColor,\r\n borderColor: trendColor,\r\n wickColor: trendColor,\r\n }\r\n }\r\n\r\n toString() {\r\n return `Hollow Candle stick ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default HollowCandleStick\r\n","import { ChartConfigChartPaneElement, RendererChartBarProps, RequireByKey } from '../../types/shared'\r\nimport { ChartElementType, ScaleType } from '../constants/common'\r\nimport Quote from '../models/quote'\r\nimport { getTickerChangeFromCloseValues } from '../utils/chart'\r\nimport CandleStick from './candle_stick'\r\n\r\ntype OhlcKeys = 'high' | 'low' | 'open' | 'close'\r\n\r\nclass HeikinAshi extends CandleStick {\r\n static type = ChartElementType.HeikinAshi\r\n static label = 'Heikin Ashi'\r\n static iconName = 'candleBarHeikinAshi'\r\n\r\n static getNumOfBarsBuffer(element: RequireByKey) {\r\n return Math.max(1, super.getNumOfBarsBuffer(element))\r\n }\r\n\r\n getRenderChartBarProps = ({ index, chartSettingsColors, hasFillAndBorder }: RendererChartBarProps) => {\r\n const haData = this.data.getHeikinAshiData()\r\n\r\n const open = haData.open[index]\r\n const close = haData.close[index]\r\n const trendColor = close < open ? chartSettingsColors.trendDown : chartSettingsColors.trendUp\r\n const wickColor = close < open ? chartSettingsColors.wickDown : chartSettingsColors.wickUp\r\n return {\r\n open,\r\n close,\r\n high: Math.max(this.data.high[index], open, close),\r\n low: Math.min(open, close, this.data.low[index]),\r\n barFillColor: trendColor,\r\n borderColor: close < open ? chartSettingsColors.borderDown : chartSettingsColors.borderUp,\r\n wickColor: hasFillAndBorder ? wickColor : trendColor,\r\n }\r\n }\r\n\r\n getLastValues = () => {\r\n const Colors = this.getCandleLikeChartsRenderingColors()\r\n const {\r\n open: lastOpen,\r\n close: lastClose,\r\n high: lastHigh,\r\n low: lastLow,\r\n } = this.getRenderChartBarProps({\r\n index: this.data.date.length - 1,\r\n chartSettingsColors: Colors,\r\n })\r\n\r\n return { lastOpen, lastClose, lastHigh, lastLow }\r\n }\r\n\r\n getRoundedLastData() {\r\n const lastOhlc = this.getLastValues()\r\n return {\r\n open: this.roundOhlc(lastOhlc.lastOpen),\r\n high: this.roundOhlc(lastOhlc.lastHigh),\r\n low: this.roundOhlc(lastOhlc.lastLow),\r\n close: this.roundOhlc(lastOhlc.lastClose),\r\n }\r\n }\r\n\r\n renderYAxis = (context: CanvasRenderingContext2D) => {\r\n const { lastClose } = this.getLastValues()\r\n super.renderYAxis(context, { lastClose }, false)\r\n\r\n const { firstVisibleClose } = this.getMinMax()\r\n if (this.model.scale === ScaleType.Percentage && !firstVisibleClose) return\r\n\r\n const originalLatestClose = this.data.close[this.data.close.length - 1]\r\n const heikinLatestCloseLabel = this.getYAxisLastCloseLabel({ lastClose, firstVisibleClose })\r\n const originalLatestCloseLabel = this.getYAxisLastCloseLabel({ lastClose: originalLatestClose, firstVisibleClose })\r\n\r\n this.renderYAxisLabel({ context, yCoordinate: Math.round(this.fy(lastClose)), label: heikinLatestCloseLabel })\r\n\r\n if (heikinLatestCloseLabel === originalLatestCloseLabel) return\r\n\r\n this.renderYAxisLabel({\r\n context,\r\n yCoordinate: this.getYAxisSecondaryLabelYCoordinate({\r\n mainLabelValue: lastClose,\r\n secondaryLabelValue: originalLatestClose,\r\n }),\r\n label: originalLatestCloseLabel,\r\n background: this.getSecondaryLabelBackgroundColor(),\r\n })\r\n }\r\n\r\n getDataByCrossIndex(crossIndex: number, key: keyof Quote, shouldReturnRoundedString = true) {\r\n const Colors = this.getCandleLikeChartsRenderingColors()\r\n const barIndex = this.data.getDataIndexByBarIndex(crossIndex)\r\n if (barIndex > -1) {\r\n let value = null\r\n if (['high', 'low', 'open', 'close'].includes(key)) {\r\n const data = this.getRenderChartBarProps({ index: barIndex, chartSettingsColors: Colors })\r\n value = data[key as OhlcKeys]\r\n }\r\n value = value === null ? this.data.getDataByBarIndex(key, crossIndex) : value\r\n if (value !== null) {\r\n return shouldReturnRoundedString ? this.roundOhlc(value) : `${value}`\r\n }\r\n }\r\n }\r\n\r\n getCrossIndexChange(crossIndex: number) {\r\n const barIndex = this.data.getDataIndexByBarIndex(crossIndex)\r\n const haData = this.data.getHeikinAshiData()\r\n const crossClose = haData.close[barIndex] ?? null\r\n const previousClose = haData.close[barIndex - 1] ?? null\r\n if (crossClose !== null && previousClose !== null) {\r\n return getTickerChangeFromCloseValues({ data: this.data, anchorClose: crossClose, prevClose: previousClose })\r\n }\r\n\r\n return null\r\n }\r\n\r\n toString() {\r\n return `HA Candle stick ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default HeikinAshi\r\n","import { ChartElementType } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Chart from './base_chart'\r\n\r\nclass LineChart extends Chart {\r\n static type = ChartElementType.LineChart\r\n static label = 'Line'\r\n static iconName = 'lineChartType'\r\n\r\n renderChart() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n let first: number | undefined, last: number | undefined\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width + 0.5,\r\n yOffset: ChartSettings.top.height + 0.5,\r\n })\r\n translate.do()\r\n this.context.beginPath()\r\n this.context.set('lineWidth', 1)\r\n this.context.set('strokeStyle', Colors.line)\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.paneModel.scale,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n const y = Math.round(this.fy(this.data.close[i]))\r\n this.context.lineTo(x, y)\r\n last = x\r\n if (first === undefined) {\r\n first = x\r\n }\r\n },\r\n })\r\n if (first !== undefined && last !== undefined) {\r\n this.context.stroke()\r\n this.context.set('fillStyle', Colors.background)\r\n this.context.lineTo(last!, this.height)\r\n this.context.lineTo(first!, this.height)\r\n this.context.fill()\r\n }\r\n\r\n translate.undo()\r\n }\r\n\r\n toString() {\r\n return `Line chart ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default LineChart\r\n","import Text from '../canvas/text'\r\nimport { ChartElementType, TextAlign, TextBaseline } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport Pane from '../models/pane'\r\nimport { isRedesignEnabled } from '../utils'\r\nimport Chart, { BaseChartAttrs } from './base_chart'\r\n\r\nconst interval = 3\r\nconst domainMin = -1\r\nconst domainMax = 1\r\nconst red = 'rgba(200, 0, 0, 0.392)'\r\nconst redLine = 'rgb(120, 0, 0)'\r\nconst green = 'rgba(0, 180, 0, 0.392)'\r\nconst greenLine = 'rgb(0, 100, 0)'\r\n\r\nclass MarketSentiment extends Chart {\r\n static type = ChartElementType.MarketSentiment\r\n\r\n static initClass() {\r\n Object.defineProperty(this.prototype, 'width', {\r\n get() {\r\n const { MarketSentimentSettings } = this.getChartLayoutSettings()\r\n return this.model.width - MarketSentimentSettings.left.width - MarketSentimentSettings.right.width\r\n },\r\n })\r\n\r\n Object.defineProperty(this.prototype, 'height', {\r\n get() {\r\n const { MarketSentimentSettings } = this.getChartLayoutSettings()\r\n return this.paneModel.height - MarketSentimentSettings.top.height - MarketSentimentSettings.bottom.height\r\n },\r\n })\r\n }\r\n\r\n declare _data: number[]\r\n declare _dataLastIndex: number | null\r\n\r\n constructor(values: Partial, model: Pane) {\r\n super(values, model)\r\n this.renderText = this.renderText.bind(this)\r\n this.renderOverlaysLabels = this.renderOverlaysLabels.bind(this)\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n this.setupCache = this.setupCache.bind(this)\r\n }\r\n\r\n setupCache() {\r\n super.setupCache()\r\n if (!this.data) {\r\n return\r\n }\r\n const arr: number[] = []\r\n this.data.close.forEach((sum, i) => {\r\n arr[i] = sum / this.data.volume[i]\r\n })\r\n this._data = arr\r\n\r\n let lastIndex = null\r\n for (let i = this.data.volume.length - 1; i >= 0; i--) {\r\n if (this.data.volume[i] !== 0) {\r\n lastIndex = i\r\n break\r\n }\r\n }\r\n this._dataLastIndex =\r\n lastIndex === null\r\n ? null\r\n : Math.min(lastIndex, Math.round((this.data.drawMinutesPerDay - this.data.marketStartMinutes) / interval))\r\n }\r\n\r\n renderChart() {\r\n const { MarketSentimentSettings } = this.getChartLayoutSettings()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + MarketSentimentSettings.left.width + 0.5,\r\n yOffset: MarketSentimentSettings.top.height + 0.5,\r\n })\r\n translate.do()\r\n this.renderLineBullBear(this.context, this._data, 0, 0, 0)\r\n translate.undo()\r\n }\r\n\r\n renderLineBullBear(\r\n context: CanvasRenderingContext2D,\r\n array: number[],\r\n from: number,\r\n oversold: number,\r\n overbought: number\r\n ) {\r\n if (this._dataLastIndex === null) {\r\n return\r\n }\r\n const isRedesign = isRedesignEnabled()\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n\r\n const domain = [domainMax, domainMin]\r\n\r\n context.save()\r\n context.beginPath()\r\n context.rect(\r\n -this.leftOffset,\r\n this.fy(domain[1]),\r\n this.fx(this._dataLastIndex),\r\n Math.round(this.fy(oversold) - this.fy(domain[1])) - 0.5\r\n )\r\n context.clip()\r\n context.set('fillStyle', red)\r\n context.set('strokeStyle', isRedesign ? Colors.marketDown : redLine)\r\n context.beginPath()\r\n context.moveTo(this.fx(0), Math.round(this.fy(domain[0])))\r\n for (let i = from; i < this.data.close.length; i++) {\r\n context.lineTo(this.fx(i), Math.round(this.fy(array[i])))\r\n }\r\n context.lineTo(this.fx(this.data.close.length - 1), Math.round(this.fy(domain[0])))\r\n context.fill()\r\n context.stroke()\r\n context.restore()\r\n\r\n context.save()\r\n context.beginPath()\r\n context.rect(\r\n -this.leftOffset,\r\n this.fy(domain[0]),\r\n this.fx(this._dataLastIndex),\r\n Math.round(this.fy(overbought)) - 0.5\r\n )\r\n context.clip()\r\n context.set('fillStyle', green)\r\n context.set('strokeStyle', isRedesign ? Colors.marketUp : greenLine)\r\n context.beginPath()\r\n context.moveTo(this.fx(0), Math.round(this.fy(domain[1])))\r\n for (let i = from; i < this.data.close.length; i++) {\r\n context.lineTo(this.fx(i), Math.round(this.fy(array[i])))\r\n }\r\n context.lineTo(this.fx(this.data.close.length - 1), Math.round(this.fy(domain[1])))\r\n context.fill()\r\n context.stroke()\r\n context.restore()\r\n }\r\n\r\n renderXAxis() {\r\n const { MarketSentimentSettings } = this.getChartLayoutSettings()\r\n const { Colors } = MarketSentimentSettings.general\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + MarketSentimentSettings.left.width,\r\n yOffset: MarketSentimentSettings.top.height,\r\n })\r\n translate.do()\r\n\r\n const xLine = this.getXLine()\r\n const text = new Text(\r\n {\r\n y: this.height + 12,\r\n font: { size: 7 },\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.bottom,\r\n textAlign: TextAlign.center,\r\n },\r\n this.paneModel\r\n )\r\n let x\r\n\r\n x = this.fx(0)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10) + 2 /* remove overflow */\r\n text.set({ text: '10AM', x }).render(this.context)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 20)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 40)\r\n text.set({ text: '12PM', x }).render(this.context)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 60)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 80)\r\n text.set({ text: '2PM', x }).render(this.context)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 100)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n x = this.fx(10 + 120 - 1)\r\n text.set({ text: '4PM', x }).render(this.context)\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n translate.undo()\r\n }\r\n\r\n renderText() {}\r\n\r\n renderCrossText() {}\r\n\r\n renderOverlaysLabels() {}\r\n\r\n _compute() {\r\n return { min: domainMin, max: domainMax }\r\n }\r\n\r\n computeVisibleMinMax() {\r\n return this._compute()\r\n }\r\n\r\n renderYAxis(context: CanvasRenderingContext2D) {\r\n const { MarketSentimentSettings, ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const isRedesign = isRedesignEnabled()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: MarketSentimentSettings.left.width,\r\n yOffset: MarketSentimentSettings.top.height,\r\n })\r\n translate.do()\r\n\r\n const yLine = this.getYLine()\r\n for (const tick of [domainMin, 0, domainMax]) {\r\n const y = Math.round(this.fy(tick))\r\n yLine.set({ y1: y, y2: y }).render(context)\r\n }\r\n\r\n const text = new Text(\r\n {\r\n x: this.width + 27,\r\n font: { size: 8 },\r\n textBaseline: TextBaseline.middle,\r\n textAlign: TextAlign.right,\r\n },\r\n this.paneModel\r\n )\r\n\r\n const fillUp = isRedesign ? Colors.marketUp : greenLine\r\n const fillDown = isRedesign ? Colors.marketDown : redLine\r\n const last = this._data[this._dataLastIndex!]\r\n const percent = this._dataLastIndex !== null ? Math.floor(last * 50 + 50) : 50\r\n text.set({ y: this.fy(0) - 5, fillStyle: fillUp, text: `${percent}%` }).render(context)\r\n text.set({ y: this.fy(0) + 7, fillStyle: fillDown, text: `${100 - percent}%` }).render(context)\r\n\r\n translate.undo()\r\n }\r\n\r\n clip() {\r\n const { MarketSentimentSettings } = this.getChartLayoutSettings()\r\n this.context.beginPath()\r\n this.context.rect(MarketSentimentSettings.left.width, MarketSentimentSettings.top.height, this.width, this.height)\r\n this.context.clip()\r\n }\r\n\r\n getMinMax() {\r\n return this._compute()\r\n }\r\n\r\n renderVolumeAxis() {}\r\n\r\n renderVolume() {}\r\n\r\n toString() {\r\n return `Market sentiment chart`\r\n }\r\n}\r\nMarketSentiment.initClass()\r\n\r\nexport default MarketSentiment\r\n","import { ObjectHash } from '../../types/shared'\r\nimport Text from '../canvas/text'\r\nimport { ChartElementType, FONT_SIZE, LINE_HEIGHT, PADDING, TextAlign, TextBaseline } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport Pane from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport utils from '../utils'\r\nimport Chart, { BaseChartAttrs } from './base_chart'\r\n\r\ninterface MultiLineChartAttrs extends BaseChartAttrs {\r\n tickers: string[]\r\n label?: string\r\n min?: number\r\n max?: number\r\n}\r\n\r\nconst months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']\r\n\r\nclass MultiLineChart extends Chart {\r\n static type = ChartElementType.MultiLineChart\r\n tickersDimensions: number[] = []\r\n\r\n constructor(values: Partial, model: Pane) {\r\n super(values, model)\r\n this.renderText = this.renderText.bind(this)\r\n }\r\n\r\n renderChart() {\r\n const { ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width + 0.5,\r\n yOffset: ChartSettings.top.height + 0.5,\r\n })\r\n translate.do()\r\n\r\n this.context.set('lineWidth', 1)\r\n\r\n const quotes: ObjectHash = {}\r\n for (const quote of this.getQuotes()) {\r\n quotes[quote.ticker] = quote\r\n }\r\n\r\n for (let index = this.attrs.tickers.length - 1; index >= 0; index--) {\r\n const ticker = this.attrs.tickers[index]\r\n const quote = quotes[ticker]\r\n this.context.set('strokeStyle', ColorsSettings[index % ColorsSettings.length])\r\n this.context.beginPath()\r\n for (let i = 0, end = quote.close.length, asc = end >= 0; asc ? i < end : i > end; asc ? i++ : i--) {\r\n const x = this.fx(i)\r\n if (x + this.leftOffset < -10 || x + this.leftOffset > this.model.width + 10) {\r\n // margin?\r\n continue\r\n }\r\n const y = Math.round(this.fy(quote.close[i]))\r\n this.context.lineTo(x, y)\r\n }\r\n this.context.stroke()\r\n }\r\n\r\n translate.undo()\r\n }\r\n\r\n renderText(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const text = this.attrs.label || ''\r\n const y = (this.height - 4) / 2\r\n new Text(\r\n {\r\n text,\r\n x: 28,\r\n y: ChartSettings.top.height + y,\r\n angle: -90,\r\n font: { size: 10, weight: '900', family: 'Lato, sans-serif' },\r\n fillStyle: Colors.textSecondary,\r\n textAlign: TextAlign.center,\r\n textBaseline: TextBaseline.alphabetic,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n return this.renderCrossText(context, this.data.close.length - 1)\r\n }\r\n\r\n renderCrossText(context: CanvasRenderingContext2D, crossIndex: number) {\r\n const { ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const maxTickerLength = utils.max(this.attrs.tickers.map((t) => t.length))\r\n\r\n const date = utils.dateFromUnixTimestamp(this.data.getDataByBarIndex('date', crossIndex) ?? 0)\r\n const month = date.getMonth() // 20141126\r\n const year = date.getFullYear()\r\n const day = date.getDate()\r\n const isLastDate = crossIndex === this.data.close.length - 1\r\n\r\n new Text(\r\n {\r\n text: `${months[month]} ${day} ${year} `,\r\n x: ChartSettings.left.width + (maxTickerLength > 15 ? 200 : 132),\r\n y: 30,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n background: Colors.canvasFill,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n\r\n const quotes: ObjectHash = {}\r\n for (const quote of this.getQuotes()) {\r\n quotes[quote.ticker] = quote\r\n }\r\n for (let index = 0; index < this.attrs.tickers.length; index++) {\r\n const y = PADDING.S + (PADDING.S + LINE_HEIGHT.M) * index\r\n if (this.tickersDimensions[index]) {\r\n context.fillStyle = Colors.canvasFill\r\n context.fillRect(\r\n ChartSettings.left.width - PADDING.XXXS,\r\n y - PADDING.XXXS,\r\n PADDING.XXXS + this.tickersDimensions[index] + PADDING.XXXS,\r\n PADDING.XXXS + FONT_SIZE.M + PADDING.XXXS\r\n )\r\n }\r\n const ticker = this.attrs.tickers[index]\r\n const closeValue = quotes[ticker].close[crossIndex]\r\n const text = new Text(\r\n {\r\n text: `${ticker} ${typeof closeValue === 'number' ? closeValue.toFixed(2) : NaN} `,\r\n x: ChartSettings.left.width,\r\n y,\r\n font: { size: FONT_SIZE.M, style: 'bold' },\r\n lineHeight: LINE_HEIGHT.M,\r\n fillStyle: ColorsSettings[index % ColorsSettings.length],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.paneModel\r\n )\r\n if (isLastDate) {\r\n this.tickersDimensions[index] = text.measure(context)\r\n }\r\n text.render(context)\r\n }\r\n }\r\n\r\n computeVisibleMinMax(...arrays: Array) {\r\n let min = Number.MAX_VALUE\r\n let max = Number.MIN_VALUE\r\n\r\n const { leftOffset } = this.model\r\n for (const arr of arrays) {\r\n for (let i = 0, end = arr.length, asc = end >= 0; asc ? i < end : i > end; asc ? i++ : i--) {\r\n const center = this.fx(i)\r\n if (center + leftOffset < 0 || center + leftOffset > this.width) {\r\n // margin?\r\n continue\r\n }\r\n\r\n if (min > arr[i]) {\r\n min = arr[i]\r\n }\r\n if (max < arr[i]) {\r\n max = arr[i]\r\n }\r\n }\r\n }\r\n\r\n return { min, max }\r\n }\r\n\r\n getMinMax() {\r\n const quotes = this.getQuotes()\r\n let { min, max } = this.computeVisibleMinMax(...quotes.map((q) => q.close))\r\n if (typeof this.attrs.min !== 'undefined') {\r\n min = this.attrs.min\r\n }\r\n if (typeof this.attrs.max !== 'undefined') {\r\n max = this.attrs.max\r\n }\r\n return { min, max }\r\n }\r\n\r\n renderVolumeAxis() {}\r\n\r\n renderVolume() {}\r\n\r\n getQuotes() {\r\n return Quote.select(\r\n (q: Quote) =>\r\n this.attrs.tickers.includes(q.ticker) &&\r\n q.timeframe === this.data?.timeframe &&\r\n this.model.chart_layout().isIdeaId(q.ideaID)\r\n )\r\n }\r\n\r\n toString() {\r\n return `Line chart ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default MultiLineChart\r\n","import { ChartElementType } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Chart from './base_chart'\r\n\r\nclass OHLCChart extends Chart {\r\n static type = ChartElementType.OhlcChart\r\n static label = 'OHLC'\r\n static iconName = 'ohlcChartType'\r\n\r\n renderChart() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n\r\n const barWithoutMarginWidth = this.getBarWithoutMarginWidth()\r\n\r\n let lineWidth = 1\r\n if (barWithoutMarginWidth >= 40) {\r\n lineWidth = 4\r\n } else if (barWithoutMarginWidth >= 30) {\r\n lineWidth = 3\r\n } else if (barWithoutMarginWidth >= 15) {\r\n lineWidth = 2\r\n }\r\n const lineThickness = lineWidth / 2\r\n const handleLengthFromWick = Math.round(barWithoutMarginWidth / 2 - lineThickness)\r\n const lineOffset = lineWidth % 2 === 0 ? 0 : 0.5\r\n this.context.set('lineWidth', lineWidth)\r\n\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.paneModel.scale,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n const barX = ~~(x + 1) + lineOffset // move 1px to right so cursor don't cover bar of ohlc-chart & round for pixel perfect render on zoom\r\n\r\n this.context.beginPath()\r\n this.context.set(\r\n 'strokeStyle',\r\n this.data.close[i] < this.data.open[i] ? Colors.ohlcTrendDown : Colors.ohlcTrendUp\r\n )\r\n\r\n this.context.moveTo(barX, Math.round(this.fy(this.data.high[i])))\r\n this.context.lineTo(barX, Math.round(this.fy(this.data.low[i])))\r\n\r\n if (handleLengthFromWick >= 1) {\r\n const open = Math.round(this.fy(this.data.open[i]))\r\n this.context.moveTo(barX + lineThickness, open + lineOffset) // move to right edge of wick\r\n this.context.lineTo(barX - lineThickness - handleLengthFromWick, open + lineOffset) // draw line to the left\r\n\r\n const close = Math.round(this.fy(this.data.close[i]))\r\n this.context.moveTo(barX - lineThickness, close + lineOffset) // move to left edge of wick\r\n this.context.lineTo(barX + lineThickness + handleLengthFromWick, close + lineOffset) // draw line to the right\r\n }\r\n\r\n this.context.stroke()\r\n },\r\n })\r\n\r\n translate.undo()\r\n }\r\n\r\n toString() {\r\n return `OHLC ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default OHLCChart\r\n","import * as d3 from 'd3'\r\n\r\nimport { ObjectHash } from '../../types/shared'\r\nimport Text from '../canvas/text'\r\nimport { ChartElementType, FONT_SIZE, MARGIN, OFFSET, PADDING, TextAlign, TextBaseline } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport Pane from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport utils from '../utils'\r\nimport Chart, { BaseChartAttrs } from './base_chart'\r\n\r\nconst months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']\r\n\r\ninterface PerfChartAttrs extends BaseChartAttrs {\r\n tickers: string[]\r\n label?: string\r\n fromDate: string\r\n toDate: string\r\n min?: number\r\n max?: number\r\n}\r\n\r\nclass PerfChart extends Chart {\r\n static type = ChartElementType.PerfChart\r\n\r\n overlayLabelWidth: ObjectHash\r\n perf: ObjectHash = {}\r\n\r\n constructor(values: Partial, model: Pane) {\r\n super(values, model)\r\n this.renderText = this.renderText.bind(this)\r\n this.renderOverlaysLabels = this.renderOverlaysLabels.bind(this)\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n this.overlayLabelWidth = {}\r\n }\r\n\r\n renderChart() {\r\n const { ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width + 0.5,\r\n yOffset: ChartSettings.top.height + 0.5,\r\n })\r\n translate.do()\r\n\r\n this.context.beginPath()\r\n this.context.set('lineWidth', 1)\r\n for (let index = 0; index < this.attrs.tickers.length; index++) {\r\n const ticker = this.attrs.tickers[index]\r\n if ((this.perf[ticker] != null ? this.perf[ticker].length : 0) > 0) {\r\n this.context.set('strokeStyle', ColorsSettings[index % ColorsSettings.length])\r\n this.context.beginPath()\r\n for (let i = 0, end = this.data.close.length, asc = end >= 0; asc ? i < end : i > end; asc ? i++ : i--) {\r\n this.context.lineTo(this.fx(i), Math.round(this.fy(this.perf[ticker][i])))\r\n }\r\n this.context.stroke()\r\n }\r\n }\r\n\r\n translate.undo()\r\n }\r\n\r\n renderText(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const period = (() => {\r\n switch (this.model.quote().timeframe) {\r\n case 'd':\r\n return 'DAILY'\r\n case 'w':\r\n return 'WEEKLY'\r\n case 'm':\r\n return 'MONTHLY'\r\n default:\r\n return\r\n }\r\n })()\r\n const y = (this.height - 4) / 2\r\n new Text(\r\n {\r\n text: period,\r\n x: 28,\r\n y: ChartSettings.top.height + y,\r\n angle: -90,\r\n font: { size: 10, weight: '900', family: 'Lato, sans-serif' },\r\n fillStyle: Colors.textSecondary,\r\n textAlign: TextAlign.center,\r\n textBaseline: TextBaseline.alphabetic,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n\r\n renderCrossText(context: CanvasRenderingContext2D, crossIndex: number) {\r\n const { ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const date = utils.dateFromUnixTimestamp(this.data.getDataByBarIndex('date', crossIndex) ?? 0)\r\n let dateString = ''\r\n const month = date.getMonth() // 20141126\r\n const year = date.getFullYear()\r\n const day = date.getDate()\r\n switch (this.data.timeframe) {\r\n case 'd':\r\n case 'w':\r\n dateString = `${months[month]} ${day}`\r\n break\r\n case 'm':\r\n dateString = `${months[month]} ${year}`\r\n break\r\n default:\r\n return\r\n }\r\n\r\n let shouldRenderDate = false\r\n for (let index = 0; index < this.attrs.tickers.length; index++) {\r\n const ticker = this.attrs.tickers[index]\r\n const tickerData = this.perf[ticker]\r\n if (tickerData?.length) {\r\n context.fillStyle = Colors.canvasFill\r\n context.fillRect(\r\n ChartSettings.left.width - PADDING.XXXS,\r\n OFFSET.M + (FONT_SIZE.M + MARGIN.XS) * index - PADDING.XXXS,\r\n PADDING.XXXS + this.overlayLabelWidth[ticker] + PADDING.XXXS,\r\n PADDING.XXXS + FONT_SIZE.M + PADDING.XXXS\r\n )\r\n const hasData = Number.isFinite(tickerData[crossIndex])\r\n const percentageText = hasData ? `${tickerData[crossIndex].toFixed(2)}%` : ''\r\n shouldRenderDate = shouldRenderDate || hasData\r\n new Text(\r\n {\r\n text: `${ticker} ${percentageText}`,\r\n x: ChartSettings.left.width,\r\n y: OFFSET.M + (FONT_SIZE.M + MARGIN.XS) * index,\r\n font: { size: FONT_SIZE.M, style: 'bold' },\r\n fillStyle: ColorsSettings[index % ColorsSettings.length],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n }\r\n\r\n if (shouldRenderDate) {\r\n new Text(\r\n {\r\n text: `${dateString} `,\r\n x: ChartSettings.left.width + 132,\r\n y: 30,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n background: Colors.canvasFill,\r\n },\r\n this.paneModel\r\n ).render(context)\r\n }\r\n }\r\n\r\n renderOverlaysLabels(context: CanvasRenderingContext2D) {\r\n super.renderOverlaysLabels(context)\r\n const { ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n\r\n for (let index = 0; index < this.attrs.tickers.length; index++) {\r\n const ticker = this.attrs.tickers[index]\r\n const tickerData = this.perf[ticker]\r\n if (tickerData?.length) {\r\n const lastCrossIndex = this.perf[ticker].length - 1\r\n const hasData = Number.isFinite(tickerData[lastCrossIndex])\r\n const percentageText = hasData ? `${tickerData[lastCrossIndex].toFixed(2)}%` : ''\r\n const text = new Text(\r\n {\r\n text: `${ticker} ${percentageText}`,\r\n x: ChartSettings.left.width,\r\n y: OFFSET.M + (FONT_SIZE.M + MARGIN.XS) * index,\r\n font: { size: FONT_SIZE.M, style: 'bold' },\r\n fillStyle: ColorsSettings[index % ColorsSettings.length],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.paneModel\r\n )\r\n this.overlayLabelWidth = { ...this.overlayLabelWidth, [ticker]: text.measure(context) }\r\n text.render(context)\r\n }\r\n }\r\n }\r\n\r\n _compute() {\r\n this.perf = {}\r\n const quotes = this.getQuotes()\r\n\r\n const fromDate = new Date(this.attrs.fromDate + ' 00:00')\r\n const toDate = new Date(this.attrs.toDate + ' 23:59')\r\n const filteredQuotes = []\r\n for (const quote of quotes) {\r\n const closes = []\r\n for (let i = 0, end = quote.close.length, asc = end >= 0; asc ? i < end : i > end; asc ? i++ : i--) {\r\n const date = utils.dateFromUnixTimestamp(quote.date[i])\r\n if (fromDate <= date && date <= toDate) {\r\n closes.push(quote.close[i])\r\n }\r\n }\r\n filteredQuotes.push({ ticker: quote.ticker, close: closes })\r\n }\r\n\r\n const daysCount = d3.max(filteredQuotes, (q) => q.close.length) ?? 0\r\n for (const quote of filteredQuotes) {\r\n this.perf[quote.ticker] = []\r\n const first = quote.close[0]\r\n let offset = 0\r\n if (daysCount > quote.close.length) {\r\n offset = daysCount - quote.close.length\r\n for (let i = 0, end1 = offset, asc1 = end1 >= 0; asc1 ? i < end1 : i > end1; asc1 ? i++ : i--) {\r\n this.perf[quote.ticker][i] = NaN\r\n }\r\n }\r\n for (let i = 0, end2 = quote.close.length, asc2 = end2 >= 0; asc2 ? i < end2 : i > end2; asc2 ? i++ : i--) {\r\n this.perf[quote.ticker][offset + i] = (quote.close[i] * 100) / first - 100\r\n }\r\n }\r\n const { min, max } = this.computeVisibleMinMax(...Object.keys(this.perf).map((x) => this.perf[x]))\r\n return { min, max }\r\n }\r\n\r\n // TODO refactor into ?utils\r\n computeVisibleMinMax(...arrays: Array) {\r\n let min = Number.MAX_VALUE\r\n let max = Number.MIN_VALUE\r\n\r\n const { leftOffset } = this.model\r\n for (const arr of arrays) {\r\n for (let i = 0, end = arr.length, asc = end >= 0; asc ? i < end : i > end; asc ? i++ : i--) {\r\n const center = this.fx(i)\r\n if (center + leftOffset < 0 || center + leftOffset > this.width) {\r\n // margin?\r\n continue\r\n }\r\n\r\n if (min > arr[i]) {\r\n min = arr[i]\r\n }\r\n if (max < arr[i]) {\r\n max = arr[i]\r\n }\r\n }\r\n }\r\n\r\n return { min, max }\r\n }\r\n\r\n renderYAxis(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const translate = getTranslate({\r\n context,\r\n xOffset: ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n const ticks = this.paneModel.scale.y.ticks(10)\r\n const yLine = this.getYLine()\r\n const text = new Text(\r\n {\r\n x: this.width + 8,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.paneModel\r\n )\r\n for (const tick of ticks) {\r\n const y = Math.round(this.fy(tick))\r\n yLine.set({ y1: y, y2: y }).render(context)\r\n text.set({ text: tick.toFixed(2), y }).render(context)\r\n }\r\n translate.undo()\r\n }\r\n\r\n renderXAxis() {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const translate = getTranslate({\r\n context: this.context,\r\n xOffset: this.leftOffset + ChartSettings.left.width,\r\n yOffset: ChartSettings.top.height,\r\n })\r\n translate.do()\r\n const text = new Text(\r\n {\r\n y: this.height + 18,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.bottom,\r\n textAlign: TextAlign.center,\r\n },\r\n this.paneModel\r\n )\r\n const textWidth = text.set({ text: '2020' }).measure(this.context)\r\n\r\n let date = new Date(this.data.date[0] * 1000)\r\n let lastMonth = date.getMonth() + '-' + date.getFullYear()\r\n\r\n let monthsInData = 0\r\n this.data.date.forEach((d, index) => {\r\n if (index < 1) {\r\n return\r\n }\r\n\r\n const date = new Date(d * 1000)\r\n const month = date.getMonth() + '-' + date.getFullYear()\r\n if (month !== lastMonth) {\r\n monthsInData++\r\n }\r\n lastMonth = month\r\n })\r\n\r\n const availableTickSpots = ~~(this.width / textWidth)\r\n const monthsToAvail = monthsInData / availableTickSpots\r\n let renderMonth\r\n if (monthsToAvail <= 1) {\r\n renderMonth = () => true\r\n } else if (monthsToAvail <= 2) {\r\n renderMonth = (x: number) => x % 2 === 0\r\n } else if (monthsToAvail <= 3) {\r\n renderMonth = (x: number) => x % 3 === 0\r\n } else if (monthsToAvail <= 4) {\r\n renderMonth = (x: number) => x % 4 === 0\r\n } else if (monthsToAvail <= 6) {\r\n renderMonth = (x: number) => x % 6 === 0\r\n } else {\r\n renderMonth = (x: number) => x === 0\r\n }\r\n\r\n date = new Date(this.data.date[0] * 1000)\r\n lastMonth = date.getMonth() + '-' + date.getFullYear()\r\n\r\n const xLine = this.getXLine()\r\n\r\n for (let i = 0; i < this.data.date.length; i++) {\r\n date = new Date(this.data.date[i] * 1000)\r\n const month = date.getMonth() + '-' + date.getFullYear()\r\n if (month !== lastMonth) {\r\n lastMonth = month\r\n const x = this.fx(i)\r\n if (x + this.leftOffset < -15 || x + this.leftOffset > this.width + 15) {\r\n // margin?\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(this.context)\r\n\r\n if (!renderMonth(date.getMonth())) {\r\n continue\r\n }\r\n\r\n text\r\n .set({\r\n text: date.getMonth() === 0 ? date.getFullYear().toString() : months[date.getMonth()],\r\n x: x,\r\n })\r\n .render(this.context)\r\n }\r\n }\r\n\r\n translate.undo()\r\n }\r\n\r\n getMinMax() {\r\n return this._compute()\r\n }\r\n\r\n renderVolumeAxis() {}\r\n\r\n renderVolume() {}\r\n\r\n getQuotes() {\r\n return Quote.select(\r\n (q: Quote) =>\r\n this.attrs.tickers.includes(q.ticker) &&\r\n q.timeframe === this.data?.timeframe &&\r\n this.model.chart_layout().isIdeaId(q.ideaID)\r\n )\r\n }\r\n\r\n toString() {\r\n return `Perf chart ${this.data.ticker}`\r\n }\r\n}\r\n\r\nexport default PerfChart\r\n","import { ChartElementType } from '../constants/common'\r\nimport candleStick from './candle_stick'\r\nimport hollowCandleStick from './candle_stick_hollow'\r\nimport heikinAshi from './heikin_ashi'\r\nimport lineChart from './line_chart'\r\nimport marketSentiment from './market_sentiment'\r\nimport multiLineCharts from './multi_line_chart'\r\nimport ohlcChart from './ohlc_chart'\r\nimport perfChart from './perf_chart'\r\n\r\nexport const chartsByType = Object.freeze({\r\n [ChartElementType.CandleStick]: candleStick,\r\n [ChartElementType.HeikinAshi]: heikinAshi,\r\n [ChartElementType.HollowCandleStick]: hollowCandleStick,\r\n [ChartElementType.LineChart]: lineChart,\r\n [ChartElementType.MarketSentiment]: marketSentiment,\r\n [ChartElementType.MultiLineChart]: multiLineCharts,\r\n [ChartElementType.OhlcChart]: ohlcChart,\r\n [ChartElementType.PerfChart]: perfChart,\r\n})\r\n","export const FONT_SIZE = {\r\n XXS: 5,\r\n XS: 7,\r\n S: 8,\r\n M: 10,\r\n L: 11,\r\n XXL: 18,\r\n XXXL: 23,\r\n}\r\nexport const LINE_HEIGHT = {\r\n XS: 7,\r\n S: 8,\r\n M: 10,\r\n}\r\nexport const PADDING = {\r\n XXXS: 1,\r\n XXS: 2,\r\n XS: 3,\r\n S: 5,\r\n}\r\nexport const MARGIN = {\r\n XS: 4,\r\n}\r\nexport const CHART_MARGIN = {\r\n S: 15,\r\n M: 30,\r\n L: 35,\r\n XL: 38,\r\n XXL: 48,\r\n}\r\nexport const SETTINGS_HEIGHT = 44\r\nexport const TICKER_TIMEFRAME_CHANGE_HEIGHT = 20\r\nexport const OFFSET = {\r\n XXS: 2,\r\n XS: 4,\r\n S: 6,\r\n M: 8,\r\n XXL: 20,\r\n}\r\nexport const MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']\r\n\r\nexport enum ChartEditorEnum {\r\n publish = 'publish',\r\n tools = 'tools',\r\n ideas = 'ideas',\r\n settings = 'settings',\r\n timeframe = 'timeframe',\r\n}\r\n\r\nexport enum LayoutType {\r\n '1h1v' = '1h1v',\r\n '1h2v' = '1h2v',\r\n '1h3v' = '1h3v',\r\n '2h1v' = '2h1v',\r\n '2h2v' = '2h2v',\r\n '3h1v' = '3h1v',\r\n '3h2v' = '3h2v',\r\n '1l2r' = '1l2r',\r\n '1t2b' = '1t2b',\r\n}\r\n\r\nexport enum CanvasElementType {\r\n element = 'canvas/element',\r\n arrow = 'canvas/arrow',\r\n brushV1 = 'canvas/brush/brush_v1',\r\n curve = 'canvas/curve',\r\n ellipse = 'canvas/ellipse',\r\n fibonacciRetracements = 'canvas/fibonacci_retracements',\r\n horizontalLine = 'canvas/horizontal_line',\r\n line = 'canvas/line',\r\n measure = 'canvas/measure',\r\n pitchforkV1 = 'canvas/pitchfork/pitchfork_v1',\r\n polygon = 'canvas/polygon',\r\n position = 'canvas/position',\r\n rectangle = 'canvas/rectangle',\r\n rotatedRectangle = 'canvas/rotated_rectangle',\r\n scaledLine = 'canvas/scaled_line',\r\n scaledText = 'canvas/scaled_text',\r\n symbol = 'canvas/symbol',\r\n text = 'canvas/text',\r\n triangle = 'canvas/triangle',\r\n verticalLine = 'canvas/vertical_line',\r\n xabcd = 'canvas/xabcd',\r\n calloutV1 = 'canvas/callout/callout_v1',\r\n elliottWaves = 'canvas/elliott_waves/elliott_waves',\r\n ellipseV1 = 'canvas/ellipse/ellipse_v1',\r\n rotatedRectangleV1 = 'canvas/rotated_rectangle/rotated_rectangle_v1',\r\n}\r\n\r\nexport enum ChartElementType {\r\n CandleStick = 'charts/candle_stick',\r\n HeikinAshi = 'charts/heikin_ashi',\r\n HollowCandleStick = 'charts/candle_stick_hollow',\r\n LineChart = 'charts/line_chart',\r\n OhlcChart = 'charts/ohlc_chart',\r\n MarketSentiment = 'charts/market_sentiment',\r\n MultiLineChart = 'charts/multi_line_chart',\r\n PerfChart = 'charts/perf_chart',\r\n}\r\n\r\nexport enum IndicatorType {\r\n Indicator = 'indicators/indicator',\r\n None = 'indicators/none',\r\n Adx = 'indicators/adx',\r\n Aro = 'indicators/aro',\r\n Aroosc = 'indicators/aroosc',\r\n Atr = 'indicators/atr',\r\n Cci = 'indicators/cci',\r\n Cot = 'indicators/cot',\r\n Fi = 'indicators/fi',\r\n Macd = 'indicators/macd',\r\n Mfi = 'indicators/mfi',\r\n Obv = 'indicators/obv',\r\n Perf = 'indicators/perf',\r\n Rmi = 'indicators/rmi',\r\n Roc = 'indicators/roc',\r\n Rsi = 'indicators/rsi',\r\n Rvol = 'indicators/rvol',\r\n Rwi = 'indicators/rwi',\r\n Stofa = 'indicators/stofa',\r\n Stofu = 'indicators/stofu',\r\n Stosl = 'indicators/stosl',\r\n Trix = 'indicators/trix',\r\n Ult = 'indicators/ult',\r\n Vol = 'indicators/vol',\r\n Wr = 'indicators/wr',\r\n}\r\n\r\nexport enum OverlayType {\r\n Overlay = 'overlays/overlay',\r\n None = 'overlays/none',\r\n Bb = 'overlays/bb',\r\n Dch = 'overlays/dch',\r\n Ema = 'overlays/ema',\r\n Ema2 = 'overlays/ema2',\r\n Hilo = 'overlays/hilo',\r\n Hline = 'overlays/hline',\r\n Ic = 'overlays/ic',\r\n Icf = 'overlays/icf',\r\n Kch = 'overlays/kch',\r\n Patterns = 'overlays/patterns',\r\n Pp = 'overlays/pp',\r\n Sar = 'overlays/sar',\r\n Sma = 'overlays/sma',\r\n Sma2 = 'overlays/sma2',\r\n Str = 'overlays/str',\r\n Vp = 'overlays/vp',\r\n Vwap = 'overlays/vwap',\r\n}\r\n\r\nexport enum ChartEventDbType {\r\n Dividends = 'chartEvent/dividends',\r\n Split = 'chartEvent/split',\r\n Earnings = 'chartEvent/earnings',\r\n}\r\n\r\nexport enum ChartEventType {\r\n ChartEvent = 'chartEvent/chartEvent',\r\n Dividends = 'chartEvent/dividends',\r\n Split = 'chartEvent/split',\r\n Earnings = 'chartEvent/earnings',\r\n}\r\n\r\nexport enum ChartEventBadgeType {\r\n Dividends = 'chartEvent/dividends',\r\n Split = 'chartEvent/split',\r\n EarningsPositive = 'chartEvent/earnings',\r\n EarningsNegative = 'chartEvent/earningsNegative',\r\n EarningsNeutral = 'chartEvent/earningsNeutral',\r\n EarningsFuture = 'chartEvent/earningsFuture',\r\n}\r\n\r\nexport const ChartEventLabels: Record = {\r\n [ChartEventBadgeType.Dividends]: 'Dividends',\r\n [ChartEventBadgeType.Split]: 'Split',\r\n [ChartEventBadgeType.EarningsPositive]: 'Earnings & Revenue',\r\n [ChartEventBadgeType.EarningsNegative]: 'Earnings & Revenue',\r\n [ChartEventBadgeType.EarningsNeutral]: 'Earnings & Revenue',\r\n [ChartEventBadgeType.EarningsFuture]: 'Earnings & Revenue',\r\n}\r\n\r\ninterface LayoutRule {\r\n columns: number\r\n rows: number\r\n count: number\r\n gridAreas?: string[]\r\n}\r\n\r\nexport const LAYOUTS: Record = {\r\n '1h1v': { columns: 1, rows: 1, count: 1 },\r\n '1h2v': { columns: 1, rows: 2, count: 2 },\r\n '1h3v': { columns: 1, rows: 3, count: 3 },\r\n '2h1v': { columns: 2, rows: 1, count: 2 },\r\n '2h2v': { columns: 2, rows: 2, count: 4 },\r\n '3h1v': { columns: 3, rows: 1, count: 3 },\r\n '3h2v': { columns: 3, rows: 2, count: 6 },\r\n '1l2r': {\r\n columns: 2,\r\n rows: 2,\r\n count: 3,\r\n gridAreas: ['1 / 1 / 3 / 2', '1 / 2 / 2 / 3', '2 / 2 / 3 / 3'],\r\n },\r\n '1t2b': {\r\n columns: 2,\r\n rows: 2,\r\n count: 3,\r\n gridAreas: ['1 / 1 / 2 / 3', '2 / 1 / 3 / 2', '2 / 2 / 3 / 3'],\r\n },\r\n}\r\n\r\nexport const SORT_DIRECTION = {\r\n ASC: 'ASC',\r\n DESC: 'DESC',\r\n}\r\n\r\nexport const ICON_SIZE = {\r\n L: 32,\r\n}\r\n\r\n// Keep in sync with the copy in Website repo - Website/js/main/constants.ts\r\nexport enum TIMEFRAME {\r\n i1 = 'i1',\r\n i2 = 'i2',\r\n i3 = 'i3',\r\n i5 = 'i5',\r\n i10 = 'i10',\r\n i15 = 'i15',\r\n i30 = 'i30',\r\n h = 'h',\r\n h2 = 'h2',\r\n h4 = 'h4',\r\n d = 'd',\r\n w = 'w',\r\n m = 'm',\r\n}\r\n\r\nexport type TimeframeAndIntradayType = TIMEFRAME | 'intraday'\r\n\r\nexport const TIMEFRAMES_WITH_PRE_MARKET = [TIMEFRAME.i1, TIMEFRAME.i2, TIMEFRAME.i3, TIMEFRAME.i5]\r\n\r\nexport const IntradayTimeframeInterval = {\r\n [TIMEFRAME.i1]: 1,\r\n [TIMEFRAME.i2]: 2,\r\n [TIMEFRAME.i3]: 3,\r\n [TIMEFRAME.i5]: 5,\r\n [TIMEFRAME.i10]: 10,\r\n [TIMEFRAME.i15]: 15,\r\n [TIMEFRAME.i30]: 30,\r\n [TIMEFRAME.h]: 60,\r\n [TIMEFRAME.h2]: 120,\r\n [TIMEFRAME.h4]: 240,\r\n}\r\n\r\nexport const TimeframeLabelShort = {\r\n [TIMEFRAME.i1]: '1M',\r\n [TIMEFRAME.i2]: '2M',\r\n [TIMEFRAME.i3]: '3M',\r\n [TIMEFRAME.i5]: '5M',\r\n [TIMEFRAME.i10]: '10M',\r\n [TIMEFRAME.i15]: '15M',\r\n [TIMEFRAME.i30]: '30M',\r\n [TIMEFRAME.h]: '1H',\r\n [TIMEFRAME.h2]: '2H',\r\n [TIMEFRAME.h4]: '4H',\r\n [TIMEFRAME.d]: 'D',\r\n [TIMEFRAME.w]: 'W',\r\n [TIMEFRAME.m]: 'M',\r\n}\r\n\r\nexport enum DateRangeType {\r\n d1 = 'd1',\r\n d5 = 'd5',\r\n m1 = 'm1',\r\n m3 = 'm3',\r\n m6 = 'm6',\r\n ytd = 'ytd',\r\n y1 = 'y1',\r\n y2 = 'y2',\r\n y5 = 'y5',\r\n max = 'max',\r\n}\r\n\r\nexport const TIMEFRAME_SECONDS = {\r\n [TIMEFRAME.i1]: 60,\r\n [TIMEFRAME.i2]: 120,\r\n [TIMEFRAME.i3]: 180,\r\n [TIMEFRAME.i5]: 300,\r\n [TIMEFRAME.i10]: 600,\r\n [TIMEFRAME.i15]: 900,\r\n [TIMEFRAME.i30]: 1800,\r\n [TIMEFRAME.h]: 3600,\r\n [TIMEFRAME.h2]: 7200,\r\n [TIMEFRAME.h4]: 14400,\r\n [TIMEFRAME.d]: 86400,\r\n [TIMEFRAME.w]: 604800,\r\n [TIMEFRAME.m]: 2592000,\r\n}\r\n\r\nexport const CRYPTOS = {\r\n BTCUSD: 'BTCUSD',\r\n LTCUSD: 'LTCUSD',\r\n ETHUSD: 'ETHUSD',\r\n XRPUSD: 'XRPUSD',\r\n BCHUSD: 'BCHUSD',\r\n BTCEUR: 'BTCEUR',\r\n LTCEUR: 'LTCEUR',\r\n ETHEUR: 'ETHEUR',\r\n XRPEUR: 'XRPEUR',\r\n BCHEUR: 'BCHEUR',\r\n LTCBTC: 'LTCBTC',\r\n ETHBTC: 'ETHBTC',\r\n XRPBTC: 'XRPBTC',\r\n BCHBTC: 'BCHBTC',\r\n}\r\n\r\nexport enum SpecificChartFunctionality {\r\n default = 'default',\r\n quotePage = 'quotePage',\r\n quotePerf = 'quotePerf',\r\n chartPage = 'chartPage',\r\n smallIndex = 'smallIndex',\r\n offScreen = 'offScreen',\r\n forexPage = 'forexPage',\r\n futuresPage = 'futuresPage',\r\n cryptoPage = 'cryptoPage',\r\n}\r\n\r\nexport enum TextAlign {\r\n left = 'left',\r\n right = 'right',\r\n center = 'center',\r\n start = 'start',\r\n end = 'end',\r\n}\r\n\r\nexport enum TextBaseline {\r\n top = 'top',\r\n hanging_dont_use = 'hanging', // not supported - https://github.com/Automattic/node-canvas/wiki/Compatibility-Status#text-styles\r\n middle = 'middle',\r\n alphabetic = 'alphabetic',\r\n ideographic_dont_use = 'ideographic', // not supported - https://github.com/Automattic/node-canvas/wiki/Compatibility-Status#text-styles\r\n bottom = 'bottom',\r\n}\r\n\r\nexport enum ScaleType {\r\n Linear = 'linear',\r\n Percentage = 'percentage',\r\n Logarithmic = 'logarithmic',\r\n}\r\n\r\nexport enum QuotePollingIntervalInMs {\r\n Default = 3000,\r\n Free = 180000,\r\n Elite = 3000,\r\n EliteStocksReduced = 60000,\r\n}\r\n\r\nexport const EXTRA_MARKET_BUFFER_MINUTES = 30\r\n\r\nexport const ScaleLabel = {\r\n [ScaleType.Linear]: 'Linear',\r\n [ScaleType.Percentage]: 'Percentage',\r\n [ScaleType.Logarithmic]: 'Logarithmic',\r\n}\r\n\r\nexport const PANE_HEIGHT_DEFAULT = {\r\n chart: 400,\r\n indicator: 120,\r\n}\r\n\r\nexport const INDICATOR_LABEL_HEIGHT = 24\r\n\r\nexport const MOBILE_BARS_TO_VIEW = 150 // 5 months of daily bars\r\n\r\nexport const MOBILE_VIEW_BREAKPOINT_WIDTH = 768\r\n\r\nexport const FREE_DATE_RANGES = ['m1', 'm3', 'm6', 'ytd', 'y1', 'y2', 'y5', 'max']\r\n\r\nexport const getTimeframeLabel = (timeframe: string) => {\r\n switch (timeframe) {\r\n case TIMEFRAME.i1:\r\n return '1 MIN'\r\n case TIMEFRAME.i2:\r\n return '2 MIN'\r\n case TIMEFRAME.i3:\r\n return '3 MIN'\r\n case TIMEFRAME.i5:\r\n return '5 MIN'\r\n case TIMEFRAME.i10:\r\n return '10 MIN'\r\n case TIMEFRAME.i15:\r\n return '15 MIN'\r\n case TIMEFRAME.i30:\r\n return '30 MIN'\r\n case TIMEFRAME.h:\r\n return '1 HR'\r\n case TIMEFRAME.h2:\r\n return '2 HR'\r\n case TIMEFRAME.h4:\r\n return '4 HR'\r\n case TIMEFRAME.d:\r\n return 'DAILY'\r\n case TIMEFRAME.w:\r\n return 'WEEKLY'\r\n case TIMEFRAME.m:\r\n return 'MONTHLY'\r\n default:\r\n return ''\r\n }\r\n}\r\n\r\nexport type ChartsPageQueryParams = {\r\n p: string\r\n t: string\r\n l: string\r\n r?: string\r\n i?: string\r\n sidebar?: string\r\n}\r\n\r\nexport type QuotePageQueryParams = {\r\n p?: string\r\n t: string\r\n r?: string\r\n i?: string\r\n ty?: QuotePageQueryChartTypes\r\n}\r\n\r\nexport enum QuotePageQueryChartTypes {\r\n l = 'l',\r\n c = 'c',\r\n cs = 'cs',\r\n hc = 'hc',\r\n ha = 'ha',\r\n o = 'o',\r\n p = 'p',\r\n}\r\n\r\nexport type ChartsOrQuotePageQueryParams = ChartsPageQueryParams | QuotePageQueryParams\r\n\r\nexport enum MacroTimeframe {\r\n // seconds = 'seconds',\r\n minutes = 'minutes',\r\n hours = 'hours',\r\n days = 'days',\r\n weeks = 'weeks',\r\n months = 'months',\r\n}\r\n\r\nexport const MicroMacroTimeframe = {\r\n [TIMEFRAME.i1]: {\r\n micro: 1,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i2]: {\r\n micro: 2,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i3]: {\r\n micro: 3,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i5]: {\r\n micro: 5,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i10]: {\r\n micro: 10,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i15]: {\r\n micro: 15,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.i30]: {\r\n micro: 30,\r\n macro: MacroTimeframe.minutes,\r\n },\r\n [TIMEFRAME.h]: {\r\n micro: 1,\r\n macro: MacroTimeframe.hours,\r\n },\r\n [TIMEFRAME.h2]: {\r\n micro: 2,\r\n macro: MacroTimeframe.hours,\r\n },\r\n [TIMEFRAME.h4]: {\r\n micro: 4,\r\n macro: MacroTimeframe.hours,\r\n },\r\n [TIMEFRAME.d]: {\r\n micro: 1,\r\n macro: MacroTimeframe.days,\r\n },\r\n [TIMEFRAME.w]: {\r\n micro: 1,\r\n macro: MacroTimeframe.weeks,\r\n },\r\n [TIMEFRAME.m]: {\r\n micro: 1,\r\n macro: MacroTimeframe.months,\r\n },\r\n}\r\n\r\nexport const MicroTimeframeRange = (Object.keys(MicroMacroTimeframe) as TIMEFRAME[]).reduce(\r\n (prev, curr) => ({\r\n ...prev,\r\n [MicroMacroTimeframe[curr].macro]: prev[MicroMacroTimeframe[curr].macro]\r\n ? [...prev[MicroMacroTimeframe[curr].macro], MicroMacroTimeframe[curr].micro]\r\n : [MicroMacroTimeframe[curr].micro],\r\n }),\r\n {} as { [key in MacroTimeframe]: number[] }\r\n)\r\n\r\ntype IRange = {\r\n from?: number\r\n to?: number\r\n}\r\n\r\nexport type IVisibility = {\r\n [key in MacroTimeframe]?: IRange\r\n}\r\n\r\nexport enum SetVisibilityTo {\r\n currentAndAbove,\r\n currentAndBelow,\r\n currentOnly,\r\n all,\r\n}\r\n\r\nexport const QUOTE_FETCH_EVENT = 'quoteFetchEvent'\r\n\r\n// Keep in sync with the clone in Website repo in shared/is-stock-fast-refresh-available.ts\r\nexport const PREMARKET_AFTERMARKET_HOURS = 2.5\r\n","import {\r\n Notification,\r\n Paragraph,\r\n generatePathForTimeframeDateRange,\r\n getDateRangeGroupsWithHref,\r\n timeframeUtm,\r\n useNotification,\r\n} from '@finviz/website'\r\nimport React from 'react'\r\nimport { useLocation } from 'react-router-dom'\r\n\r\nimport { Instrument } from '../../../types/shared'\r\nimport { SpecificChartFunctionality, TIMEFRAME, TimeframeAndIntradayType } from '../../constants/common'\r\nimport Chart from '../../models/chart'\r\nimport Quote from '../../models/quote'\r\nimport { dateFromUnixTimestamp } from '../../utils'\r\nimport { getChartStartEndDates, getVisibleBarsNumber } from '../renderUtils'\r\nimport { useChartsPathLocation } from './use-charts-path-location'\r\nimport { getTimeframeGroupsWithHref } from './utils'\r\n\r\ninterface IPathForTimeframeDateRangeProps {\r\n timeframe: TimeframeAndIntradayType\r\n dateRange?: string | null\r\n ticker?: string\r\n}\r\n\r\nexport interface IDateRange {\r\n value: string\r\n timeframe: TIMEFRAME\r\n}\r\n\r\nexport function useChartModelCustomDateRangeValues({\r\n chartModel,\r\n isPremium,\r\n}: {\r\n chartModel: Chart | null\r\n isPremium: boolean\r\n}) {\r\n const notificationContext = useNotification()\r\n const location = useLocation()\r\n const [isFetching, setIsFetching] = React.useState(false)\r\n const chartLayoutModel = chartModel?.chart_layout() || null\r\n const chartIndex = chartLayoutModel?.getAllCharts().findIndex((chart) => chartModel!.eql(chart)) ?? -1\r\n const { getChartsToPath } = useChartsPathLocation({ chartLayoutModel, chartIndex })\r\n const specificChartFunctionality = chartLayoutModel?.specificChartFunctionality ?? SpecificChartFunctionality.default\r\n\r\n const anchorDate = React.useMemo(() => {\r\n if (!chartModel) return new Date()\r\n const quote = chartModel.quote()\r\n return dateFromUnixTimestamp(quote.date[quote.date.length - 1])\r\n }, [chartModel])\r\n\r\n const generateChartLayoutRouterPath = React.useCallback(\r\n ({ ticker, timeframe, dateRange }: IPathForTimeframeDateRangeProps) => {\r\n if (specificChartFunctionality === SpecificChartFunctionality.chartPage) {\r\n return getChartsToPath({\r\n ticker: ticker,\r\n timeframe: timeframe as TIMEFRAME,\r\n dateRange: dateRange,\r\n })\r\n }\r\n\r\n return generatePathForTimeframeDateRange({\r\n isPremium,\r\n pathname: location.pathname,\r\n timeframe: timeframe,\r\n dateRange: dateRange,\r\n utmCampaign: timeframeUtm[specificChartFunctionality],\r\n })\r\n },\r\n [getChartsToPath, isPremium, specificChartFunctionality, location.pathname]\r\n )\r\n\r\n const timeframeGroupsWithHref = (isPremium: boolean) =>\r\n getTimeframeGroupsWithHref({\r\n isPremium,\r\n generatePath: (timeFrame) => generateChartLayoutRouterPath({ timeframe: timeFrame.value, dateRange: null }),\r\n })\r\n\r\n const dateRangeGroupsWithHref = ({\r\n isPremium,\r\n customRange,\r\n instrument,\r\n }: {\r\n isPremium: boolean\r\n customRange?: string\r\n instrument: Instrument\r\n }) =>\r\n getDateRangeGroupsWithHref({\r\n isPremium,\r\n customRange,\r\n instrument,\r\n generatePath: (dateRange: { timeframe?: TIMEFRAME; value: string }) =>\r\n generateChartLayoutRouterPath({ timeframe: dateRange.timeframe!, dateRange: dateRange.value }),\r\n })\r\n\r\n const handleCustomDateRangeValidation = async (dateRangeState: { value: string | null; timeframe: TIMEFRAME }) => {\r\n if (dateRangeState.value !== null) {\r\n const { timeframe, ticker, instrument, premarket, aftermarket } = chartModel?.quote() || {}\r\n const patterns = !!chartModel?.getHasPatterns()\r\n if (!anchorDate || !instrument || !ticker || !timeframe || !dateRangeState.value) return false\r\n setIsFetching(true)\r\n const quote = await Quote.get({\r\n ticker,\r\n instrument,\r\n timeframe: dateRangeState.timeframe,\r\n options: {\r\n premarket,\r\n aftermarket,\r\n patterns,\r\n cachePredicate: (quote) => quote.ideaID === undefined,\r\n fetchNewDataOnCachedQuote: true,\r\n },\r\n })\r\n setIsFetching(false)\r\n\r\n const { numOfVisibleBars } = getVisibleBarsNumber({\r\n ...getChartStartEndDates({ dateRange: dateRangeState.value, quote }),\r\n quote,\r\n dateRange: dateRangeState.value,\r\n })\r\n if (numOfVisibleBars === 0) {\r\n notificationContext.show(\r\n } timeoutInMs={6000}>\r\n \r\n There are no data for the selected date range. Try selecting different dates.\r\n \r\n \r\n )\r\n\r\n return false\r\n }\r\n }\r\n return true\r\n }\r\n\r\n return {\r\n anchorDate,\r\n generateChartLayoutRouterPath,\r\n timeframeGroupsWithHref,\r\n dateRangeGroupsWithHref,\r\n isFetching,\r\n handleCustomDateRangeValidation,\r\n }\r\n}\r\n","import * as React from 'react'\r\nimport { useLocation } from 'react-router-dom'\r\n\r\nimport { ChartsPageQueryParams, LAYOUTS, LayoutType, TIMEFRAME } from '../../constants/common'\r\nimport { useModelState } from '../../model-hooks/use-model-state'\r\nimport { ChartSyncablePart } from '../../models/chart/contstants'\r\nimport ChartLayout from '../../models/chart_layout'\r\nimport { getIsMobilePortrait } from '../../utils'\r\nimport { decodeQueryString, encodeQueryString } from '../../utils/query_string'\r\n\r\nexport function useChartsPathLocation({\r\n chartLayoutModel: unwatchedChartLayoutModel,\r\n chartIndex = -1,\r\n}: {\r\n chartLayoutModel: ChartLayout | null\r\n chartIndex?: number\r\n}) {\r\n const location = useLocation()\r\n const chartLayoutModel = useModelState(unwatchedChartLayoutModel, {\r\n watchProperties: ['syncChartParts'],\r\n })\r\n const hasSyncedTimeframe = React.useMemo(\r\n () => !!chartLayoutModel?.getIsChartPartInSync(ChartSyncablePart.Timeframe),\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [chartLayoutModel?.syncChartParts]\r\n )\r\n const hasSyncedTicker = React.useMemo(\r\n () => !!chartLayoutModel?.getIsChartPartInSync(ChartSyncablePart.Ticker),\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [chartLayoutModel?.syncChartParts]\r\n )\r\n\r\n const getChartsToPath = React.useCallback(\r\n ({\r\n ticker,\r\n timeframe,\r\n dateRange,\r\n layout,\r\n }: {\r\n timeframe?: TIMEFRAME\r\n dateRange?: string | null\r\n ticker?: string\r\n layout?: LayoutType\r\n }) => {\r\n if (!chartLayoutModel) {\r\n return {\r\n pathname: location.pathname,\r\n search: '',\r\n }\r\n }\r\n\r\n const decodedSearch = decodeQueryString(location.search)\r\n const { count } = LAYOUTS[(layout ?? chartLayoutModel.layout) as LayoutType]\r\n const urlTickers = decodedSearch.t?.split(',') ?? []\r\n const urlTimeframes = decodedSearch.p?.split(',') ?? []\r\n const urlDateRanges = decodedSearch.r?.split(',')\r\n\r\n const chartsArrayPlaceholder = Array.from({ length: count })\r\n const tickers = chartsArrayPlaceholder\r\n .map((_, index) => {\r\n const currentTicker = urlTickers[index] ?? urlTickers[urlTickers.length - 1]\r\n return (chartIndex === index || hasSyncedTicker) && ticker ? ticker : currentTicker\r\n })\r\n .join(',')\r\n const timeframes = chartsArrayPlaceholder\r\n .map((_, index) => {\r\n const currentTimeframe = urlTimeframes[index] ?? urlTimeframes[urlTimeframes.length - 1]\r\n return (chartIndex === index || hasSyncedTimeframe) && timeframe ? timeframe : currentTimeframe\r\n })\r\n .join(',')\r\n const ranges = chartsArrayPlaceholder\r\n .map((_, index) => {\r\n const currentDaterange = urlDateRanges\r\n ? urlDateRanges[index] ?? urlDateRanges[urlDateRanges.length - 1]\r\n : undefined\r\n return (chartIndex === index || hasSyncedTimeframe) && dateRange !== undefined ? dateRange : currentDaterange\r\n })\r\n .join(',')\r\n\r\n return {\r\n pathname: location.pathname,\r\n search: `?${encodeQueryString({\r\n t: tickers,\r\n p: timeframes,\r\n r: ranges.split(',').some(Boolean) ? ranges : undefined,\r\n l: layout ?? chartLayoutModel.layout,\r\n sidebar: getIsMobilePortrait() ? undefined : decodedSearch.sidebar,\r\n })}`,\r\n }\r\n },\r\n [chartLayoutModel, chartIndex, location, hasSyncedTicker, hasSyncedTimeframe]\r\n )\r\n\r\n return { getChartsToPath }\r\n}\r\n","import { IconNameType, getTimeframeGroups } from '@finviz/website'\r\nimport { type To } from 'react-router-dom'\r\n\r\nimport { TimeframeAndIntradayType } from '../../constants/common'\r\n\r\ninterface ITimeFrame {\r\n value: TimeframeAndIntradayType\r\n label: string\r\n labelShort: string\r\n labelPageTitle?: string\r\n}\r\n\r\ninterface ITimeframeGroup {\r\n label: string\r\n timeframes: ITimeFrame[]\r\n}\r\n\r\nexport function getTimeframeGroupsWithHref({\r\n isPremium,\r\n generatePath,\r\n}: {\r\n isPremium: boolean\r\n generatePath: (timeframe: ITimeFrame) => To\r\n}) {\r\n return getTimeframeGroups(isPremium).map((timeFrameGroup: ITimeframeGroup) => ({\r\n label: timeFrameGroup.label,\r\n timeframes: timeFrameGroup.timeframes.map((timeFrame) => ({\r\n ...timeFrame,\r\n href: generatePath(timeFrame),\r\n })),\r\n }))\r\n}\r\n\r\nexport enum QuoteNodeChartTypes {\r\n candlesticksimple = 'candlesticksimple',\r\n candlestick = 'candlestick',\r\n line = 'line',\r\n ohlc = 'ohlc',\r\n heikinashi = 'heikinashi',\r\n hollowcandlestick = 'hollowcandlestick',\r\n}\r\n\r\nexport enum QuoteUrlChartTypes {\r\n cs = 'cs',\r\n c = 'c',\r\n l = 'l',\r\n o = 'o',\r\n ha = 'ha',\r\n hc = 'hc',\r\n}\r\n\r\nexport const QuoteShortToLongType = {\r\n [QuoteUrlChartTypes.cs]: QuoteNodeChartTypes.candlesticksimple,\r\n [QuoteUrlChartTypes.c]: QuoteNodeChartTypes.candlestick,\r\n [QuoteUrlChartTypes.l]: QuoteNodeChartTypes.line,\r\n [QuoteUrlChartTypes.o]: QuoteNodeChartTypes.ohlc,\r\n [QuoteUrlChartTypes.ha]: QuoteNodeChartTypes.heikinashi,\r\n [QuoteUrlChartTypes.hc]: QuoteNodeChartTypes.hollowcandlestick,\r\n} as const\r\n\r\nexport const QuoteLongToShortType = {\r\n [QuoteNodeChartTypes.candlesticksimple]: QuoteUrlChartTypes.cs,\r\n [QuoteNodeChartTypes.candlestick]: QuoteUrlChartTypes.c,\r\n [QuoteNodeChartTypes.line]: QuoteUrlChartTypes.l,\r\n [QuoteNodeChartTypes.ohlc]: QuoteUrlChartTypes.o,\r\n [QuoteNodeChartTypes.heikinashi]: QuoteUrlChartTypes.ha,\r\n [QuoteNodeChartTypes.hollowcandlestick]: QuoteUrlChartTypes.hc,\r\n} as const\r\n\r\nexport type TypeBaseOption = {\r\n label: string\r\n value: QuoteNodeChartTypes\r\n icon: IconNameType\r\n href?: string\r\n}\r\nexport const DEFAULT_TYPES: TypeBaseOption[] = [\r\n { icon: 'candleBarBasic', value: QuoteNodeChartTypes.candlestick, label: 'Candle' },\r\n { icon: 'lineChartType', value: QuoteNodeChartTypes.line, label: 'Line' },\r\n { icon: 'ohlcChartType', value: QuoteNodeChartTypes.ohlc, label: 'OHLC' },\r\n { icon: 'candleBarHollow', value: QuoteNodeChartTypes.hollowcandlestick, label: 'Hollow Candle' },\r\n { icon: 'candleBarHeikinAshi', value: QuoteNodeChartTypes.heikinashi, label: 'Heikin Ashi' },\r\n]\r\n\r\nexport const FREE_TYPES_QUOTE: TypeBaseOption[] = [\r\n { icon: 'candleBarBasic', value: QuoteNodeChartTypes.candlesticksimple, label: 'Candle - simple' },\r\n { icon: 'candleBarBasic', value: QuoteNodeChartTypes.candlestick, label: 'Candle - advanced' },\r\n // Filter out the candle from DEFAULT_TYPES, we’re naming it differently\r\n ...DEFAULT_TYPES.filter((type) => type.value !== QuoteNodeChartTypes.candlestick),\r\n]\r\n\r\nexport const FREE_TYPES_QUOTE_VALUES = ['candlesticksimple', 'candlestick', 'line']\r\n","export const chartSettingsAsyncModule = {\r\n importFn: () => import(/* webpackChunkName: \"chart-settings\" */ './module-entry'),\r\n cacheKey: 'chart-settings',\r\n}\r\n\r\nexport const useChartLayoutGlobalModelAsyncModule = {\r\n importFn: () =>\r\n import(/* webpackChunkName: \"use-chart-layout-global-model\" */ './useChartLayoutGlobalModel/module-entry'),\r\n cacheKey: 'use-chart-layout-global-model',\r\n}\r\n\r\nexport const preventClosingUnsavedChangesAsyncModule = {\r\n importFn: () =>\r\n import(/* webpackChunkName: \"prevent-closing-unsaved-changes\" */ './PreventClosingUnsavedChanges/module-entry'),\r\n cacheKey: 'prevent-closing-unsaved-changes',\r\n}\r\n","import * as dateFns from 'date-fns'\r\n\r\nimport { getChartStartEndDates } from '../controllers/renderUtils'\r\nimport Quote from '../models/quote'\r\n\r\n// **************START**************\r\n// Functions from here until END have to be in sync with\r\n// Finviz-Website: components/timeframe-bar/custom-date-range-utils.ts\r\n// *********************************\r\n\r\nexport enum CustomDateRangePrefixEnum {\r\n Range = 'range',\r\n Prev = 'prev',\r\n}\r\n\r\nexport const CUSTOM_DATE_RANGE = 'custom'\r\nexport const DATE_RANGE_PREFIX_DELMITER = '_'\r\nconst CUSTOM_DATE_RANGE_DELIMITER = 'x'\r\nconst CUSTOM_PREV_RANGE_DELIMITER = '-'\r\n\r\nexport function getParsedDateRange(dateRange: string) {\r\n return dateRange.split(DATE_RANGE_PREFIX_DELMITER)\r\n}\r\n\r\nexport function parseCustomDateRangeUrlParam({ dateRange, anchorDate }: { dateRange: string; anchorDate: Date }) {\r\n const [dateRangePrefix, dateRangeValue] = getParsedDateRange(dateRange)\r\n\r\n if (dateRangePrefix === CustomDateRangePrefixEnum.Range) {\r\n const [dateFromString, dateToString] = dateRangeValue.replace(/-/g, '/').split(CUSTOM_DATE_RANGE_DELIMITER)\r\n const dateFrom = dateFromString ? new Date(dateFromString) : null\r\n const dateTo = dateToString ? new Date(dateToString) : null\r\n return {\r\n start: dateFrom && !Number.isNaN(dateFrom.getTime()) ? dateFrom : null,\r\n end: dateTo && !Number.isNaN(dateTo.getTime()) ? dateFns.endOfDay(dateTo) : null,\r\n }\r\n }\r\n\r\n if (dateRangePrefix === CustomDateRangePrefixEnum.Prev) {\r\n const [years, months, days] = dateRangeValue.split(CUSTOM_PREV_RANGE_DELIMITER).map(Number)\r\n\r\n if ([years, months, days].some(Number.isNaN)) {\r\n return { start: null, end: null }\r\n }\r\n\r\n return {\r\n start: dateFns.startOfDay(dateFns.sub(anchorDate, { years, months, days: days - 1 })),\r\n end: anchorDate,\r\n }\r\n }\r\n\r\n return { start: null, end: anchorDate }\r\n}\r\n\r\n// **************END**************\r\n// Functions below don't need to be\r\n// in sync with Website repository\r\n// *******************************\r\n\r\nexport function getParsedDateRangeMetaData({ dateRange, quote }: { dateRange: string; quote: Quote }) {\r\n const parsedRange = getChartStartEndDates({ dateRange, quote })\r\n const [dateRangePrefix] = getParsedDateRange(dateRange)\r\n\r\n let startQuoteDate: Date | null = null\r\n let endQuoteDate: Date | null = null\r\n let numOfDaysToRender: number | null = null\r\n\r\n if (parsedRange.start && dateRangePrefix === CustomDateRangePrefixEnum.Prev) {\r\n const daysInQuote = quote.getDaysInQuote()\r\n const reversedDaysInQuote = [...daysInQuote].reverse()\r\n const startQuoteDayIndex = reversedDaysInQuote.findIndex((date) => date.getTime() <= parsedRange.start!.getTime())\r\n const endQuoteDayIndex = reversedDaysInQuote.findIndex((date) => date.getTime() <= parsedRange.end!.getTime())\r\n startQuoteDate = reversedDaysInQuote[startQuoteDayIndex] ?? null\r\n endQuoteDate = reversedDaysInQuote[endQuoteDayIndex] ?? null\r\n numOfDaysToRender = quote.interval <= 5 ? startQuoteDayIndex - endQuoteDayIndex + 1 : null\r\n }\r\n\r\n return {\r\n start: parsedRange.start,\r\n end: parsedRange.end,\r\n startQuoteDate,\r\n endQuoteDate,\r\n numOfDaysToRender,\r\n numOfBarsToRender: (numOfDaysToRender ?? 0) * (quote.getBarsInDay() ?? 0) || undefined,\r\n renderDateStart: parsedRange.start && dateFns.startOfDay(parsedRange.start),\r\n renderDateEnd: parsedRange.end && dateFns.endOfDay(parsedRange.end),\r\n }\r\n}\r\n","import * as d3 from 'd3'\r\nimport * as dateFns from 'date-fns'\r\n\r\nimport { Instrument, ObjectHash } from '../../types/shared'\r\nimport {\r\n CHART_MARGIN,\r\n DateRangeType,\r\n PREMARKET_AFTERMARKET_HOURS,\r\n ScaleType,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n} from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport ChartEventElement from '../models/chart-event-element'\r\nimport ChartLayout from '../models/chart_layout'\r\nimport { IChartSettings, IIndicatorSettings, ISettings } from '../models/chart_settings/interfaces'\r\nimport { CHART_EVENT_BADGE_SIZE } from '../models/constants'\r\nimport Element from '../models/element'\r\nimport Pane, { ScaleAxis } from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport Utils from '../utils'\r\nimport utils, { convertLocalToNyTime, dateFromUnixTimestamp, isRedesignedPage } from '../utils'\r\nimport { getBarWidthWithMargin, getZoomFactorForBarsToDisplay } from '../utils/chart'\r\nimport {\r\n DATE_RANGE_PREFIX_DELMITER,\r\n getParsedDateRangeMetaData,\r\n parseCustomDateRangeUrlParam,\r\n} from '../utils/chart-date-range-utils'\r\n\r\ninterface VisibleBarNumberProps {\r\n start: Date | null\r\n end: Date\r\n quote: Quote\r\n dateRange: string\r\n}\r\n\r\ninterface ChartZoomAndLeftOffsetProps extends Omit {\r\n chartVisibleWidth: number\r\n numOfBarsToRender?: number\r\n chartModel: Chart\r\n}\r\n\r\ninterface ChartStartEndDatesProps {\r\n dateRange: string\r\n quote: Quote\r\n}\r\n\r\nexport const getVisibleBarsNumber = ({ start, end, quote, dateRange }: VisibleBarNumberProps) => {\r\n const startInSec = start ? start.getTime() / 1000 : 0\r\n const endInSec = end.getTime() / 1000\r\n const isQuoteDateInRange = (quoteDate: number) => quoteDate >= startInSec && quoteDate <= endInSec\r\n const lastQuoteDateIndex = quote.date.length - 1\r\n let lastVisibleBarIndex = lastQuoteDateIndex\r\n let numOfVisibleBars = 0\r\n if (\r\n [DateRangeType.d1, DateRangeType.d5].includes(dateRange as DateRangeType) &&\r\n quote.instrument === Instrument.Stock\r\n ) {\r\n numOfVisibleBars = quote.drawMinutesPerDay\r\n } else {\r\n let firstVisibleBarIndex = -1\r\n lastVisibleBarIndex = -1\r\n quote.date.forEach((quoteDate, index) => {\r\n if (isQuoteDateInRange(quoteDate)) {\r\n if (firstVisibleBarIndex === -1) {\r\n firstVisibleBarIndex = index\r\n }\r\n lastVisibleBarIndex = index\r\n }\r\n })\r\n numOfVisibleBars = lastVisibleBarIndex - firstVisibleBarIndex + 1\r\n\r\n if (firstVisibleBarIndex === -1 && lastVisibleBarIndex === -1) {\r\n return { numOfVisibleBars: 0, numOfBarsOffset: 0 }\r\n }\r\n }\r\n\r\n return { numOfVisibleBars, numOfBarsOffset: lastQuoteDateIndex - lastVisibleBarIndex }\r\n}\r\n\r\nexport const getChartZoomAndLeftOffset = ({\r\n chartVisibleWidth,\r\n start,\r\n end,\r\n quote,\r\n chartModel,\r\n numOfBarsToRender,\r\n}: ChartZoomAndLeftOffsetProps) => {\r\n const { numOfVisibleBars, numOfBarsOffset } = getVisibleBarsNumber({\r\n start,\r\n end,\r\n quote,\r\n dateRange: chartModel.dateRange,\r\n })\r\n if (numOfVisibleBars === 0) {\r\n return { zoomFactor: chartModel.zoomFactor, leftOffset: chartModel.leftOffset }\r\n }\r\n\r\n const chartLayout = chartModel.chart_layout()\r\n const zoomFactor = getZoomFactorForBarsToDisplay({\r\n chartLayout,\r\n chartVisibleWidth,\r\n numOfVisibleBars: numOfBarsToRender ?? numOfVisibleBars,\r\n })\r\n const barWidth = getBarWidthWithMargin({ chartLayout, zoomFactor })\r\n const leftOffset =\r\n getLeftOffset({\r\n quote,\r\n chartModel,\r\n config: {},\r\n barWidth,\r\n numberOfBarsToDraw: numOfBarsToRender,\r\n }) +\r\n numOfBarsOffset * barWidth\r\n return { zoomFactor, leftOffset }\r\n}\r\n\r\nexport const getChartStartEndDates = ({ dateRange, quote }: ChartStartEndDatesProps) => {\r\n const daysInQuote = quote.getDaysInQuote()\r\n const lastDate = dateFromUnixTimestamp(quote.date[quote.date.length - 1])\r\n\r\n if (dateRange.includes(DATE_RANGE_PREFIX_DELMITER)) {\r\n const range = parseCustomDateRangeUrlParam({ dateRange, anchorDate: lastDate })\r\n const end = convertLocalToNyTime(\r\n range.end && range.end.getTime() <= lastDate.getTime() ? range.end : lastDate,\r\n false\r\n )\r\n return {\r\n start: range.start && convertLocalToNyTime(range.start, false),\r\n end,\r\n }\r\n }\r\n\r\n let start\r\n // No condition is needed here, but this would be dateRangePrefix === DateRangePrefixEnum.Enum\r\n switch (dateRange) {\r\n case DateRangeType.d1:\r\n lastDate.setHours(23, 59, 59, 999)\r\n start = daysInQuote.length === 0 ? lastDate : daysInQuote[daysInQuote.length - 1]\r\n break\r\n case DateRangeType.d5:\r\n lastDate.setHours(23, 59, 59, 999)\r\n const startDateIndex = daysInQuote.length === 0 ? -1 : Math.max(daysInQuote.length - 5, 0)\r\n start = startDateIndex === -1 ? lastDate : daysInQuote[startDateIndex]\r\n break\r\n case DateRangeType.m1:\r\n start = dateFns.subMonths(lastDate, 1)\r\n break\r\n case DateRangeType.m3:\r\n start = dateFns.subMonths(lastDate, 3)\r\n break\r\n case DateRangeType.m6:\r\n start = dateFns.subMonths(lastDate, 6)\r\n break\r\n case DateRangeType.ytd:\r\n start = dateFns.startOfYear(lastDate)\r\n break\r\n case DateRangeType.y1:\r\n start = dateFns.subYears(lastDate, 1)\r\n break\r\n case DateRangeType.y2:\r\n start = dateFns.subYears(lastDate, 2)\r\n break\r\n case DateRangeType.y5:\r\n start = dateFns.subYears(lastDate, 5)\r\n break\r\n case DateRangeType.max:\r\n default:\r\n start = null\r\n break\r\n }\r\n\r\n return { start: start && convertLocalToNyTime(start, false), end: convertLocalToNyTime(lastDate, false) }\r\n}\r\n\r\ninterface GetLeftOffsetProps {\r\n quote: Quote\r\n chartModel: Chart\r\n config?: { stretch?: boolean }\r\n barWidth?: number\r\n barIndex?: number\r\n numberOfBarsToDraw?: number\r\n shouldAlignDaysToLeftApplied?: boolean\r\n}\r\n\r\nexport const getMinMaxLeftOffset = ({\r\n newLeftOffset,\r\n chartModel,\r\n barWidth = getBarWidthWithMargin({ zoomFactor: chartModel.zoomFactor, chartLayout: chartModel.chart_layout() }),\r\n barIndex,\r\n}: {\r\n newLeftOffset: number\r\n chartModel: Chart\r\n barWidth?: number\r\n barIndex: number\r\n}) => {\r\n const { ChartSettings } = chartModel.getChartLayoutSettings()\r\n const width = chartModel.width - ChartSettings.left.width - ChartSettings.right.width\r\n const numOfBarsInView = Math.floor(width / barWidth)\r\n const fx = (index: number) => index * barWidth\r\n return ~~Utils.min(barWidth / 2, Utils.max(newLeftOffset, width - fx(barIndex + numOfBarsInView)))\r\n}\r\n\r\nexport function getFullChartWidth({\r\n hasAftermarket,\r\n hasPremarket,\r\n timeframeMinutes,\r\n barWidthWithMargin,\r\n}: {\r\n hasPremarket: boolean\r\n hasAftermarket: boolean\r\n timeframeMinutes: number\r\n barWidthWithMargin: number\r\n}) {\r\n const premarketHoursLength = hasPremarket ? PREMARKET_AFTERMARKET_HOURS : 0\r\n const aftermarketHoursLength = hasAftermarket ? PREMARKET_AFTERMARKET_HOURS : 0\r\n const marketMinutesLength = (6.5 + premarketHoursLength + aftermarketHoursLength) * 60\r\n // CHART_MARGIN.L as left offset + CHART_MARGIN.XXL as right offset\r\n return CHART_MARGIN.L + CHART_MARGIN.XXL + (marketMinutesLength / timeframeMinutes) * barWidthWithMargin\r\n}\r\n\r\nexport function getIntradayChartConfig({\r\n timeframeMinutes,\r\n barWidthWithMargin,\r\n hasPremarket,\r\n hasAftermarket,\r\n maxWidth,\r\n}: {\r\n hasPremarket: boolean\r\n hasAftermarket: boolean\r\n timeframeMinutes: number\r\n barWidthWithMargin: number\r\n maxWidth: number\r\n}) {\r\n const fullChartWidth = getFullChartWidth({ hasPremarket, hasAftermarket, barWidthWithMargin, timeframeMinutes })\r\n const offsetChartAfter = 16 // Int from 0-23 , if last quote date is >= this constant `offsetInPx` is applied (chart is moved to the left)\r\n const cropChartMinutesLength = PREMARKET_AFTERMARKET_HOURS * 60\r\n const offsetInPx = (cropChartMinutesLength / timeframeMinutes) * barWidthWithMargin\r\n const chartWidthWithOffset = fullChartWidth - offsetInPx\r\n const shouldCropChart =\r\n hasAftermarket && hasPremarket && maxWidth >= chartWidthWithOffset && maxWidth < fullChartWidth\r\n\r\n return {\r\n fullChartWidth,\r\n offsetInPx: shouldCropChart ? offsetInPx : 0,\r\n chartWidthWithOffset: shouldCropChart ? fullChartWidth - offsetInPx : fullChartWidth,\r\n offsetChartAfter,\r\n }\r\n}\r\n\r\nexport const getLeftOffset = ({\r\n quote,\r\n chartModel,\r\n config,\r\n barWidth = getBarWidthWithMargin({ zoomFactor: chartModel.zoomFactor, chartLayout: chartModel.chart_layout() }),\r\n barIndex = getBarIndex(quote),\r\n numberOfBarsToDraw,\r\n shouldAlignDaysToLeftApplied = true,\r\n}: GetLeftOffsetProps) => {\r\n const { ChartSettings } = chartModel.getChartLayoutSettings()\r\n const width = chartModel.width - ChartSettings.left.width - ChartSettings.right.width\r\n const specificChartFunctionality = chartModel.chart_layout().specificChartFunctionality\r\n if (config?.stretch) {\r\n return 0\r\n }\r\n if (getIsSmallIndexChart(specificChartFunctionality)) {\r\n return barWidth\r\n }\r\n const fx = (index: number) => index * barWidth\r\n let leftOffset = width - fx(barIndex) - Math.round(barWidth / 2)\r\n leftOffset = Math.round(Utils.min(barWidth / 2, Utils.max(leftOffset, width - fx(barIndex + 45))))\r\n if (\r\n shouldAlignDaysToLeftApplied &&\r\n shouldAlignDaysToLeft({\r\n quote,\r\n numberOfBarsToDraw,\r\n specificChartFunctionality,\r\n dateRange: chartModel.dateRange,\r\n })\r\n ) {\r\n let drawDaysInOneChart = 1\r\n if (numberOfBarsToDraw) {\r\n drawDaysInOneChart = Math.ceil(numberOfBarsToDraw / quote.getBarsInDay()!)\r\n } else if (quote.interval === 10 || chartModel.dateRange === DateRangeType.d5) {\r\n drawDaysInOneChart = 5\r\n } else if (quote.interval === 15) {\r\n drawDaysInOneChart = 6\r\n } else if (quote.interval === 30) {\r\n drawDaysInOneChart = 12\r\n } else if (quote.interval === 60) {\r\n drawDaysInOneChart = 22\r\n } else if (quote.interval === 120) {\r\n drawDaysInOneChart = 39\r\n } else if (quote.interval === 240) {\r\n drawDaysInOneChart = 78\r\n } else if (quote.interval > 240) {\r\n drawDaysInOneChart = (quote.interval / 30) * 10\r\n }\r\n const { offsetInPx, offsetChartAfter } = getIntradayChartConfig({\r\n hasPremarket: quote.premarket,\r\n hasAftermarket: quote.aftermarket,\r\n barWidthWithMargin: barWidth,\r\n timeframeMinutes: quote.interval,\r\n maxWidth: chartModel.width,\r\n })\r\n const drawDaysWidth = drawDaysInOneChart * quote.getBarsInDay()! * barWidth - offsetInPx\r\n\r\n // +1 is a buffer as it often happens drawDaysWidth is wider than width by tiny amount (< 1/10000 of px)\r\n if (drawDaysWidth <= width + 1) {\r\n const lastQuoteDate = quote.date.last() ? utils.dateFromUnixTimestamp(quote.date.last()!) : null\r\n // Align start of day to left if we have enough space to show all bars in day\r\n const barsToOffset = (Object.keys(quote.getDayToOffset()).length - drawDaysInOneChart) * quote.getBarsInDay()!\r\n const offsetChartInPx = (lastQuoteDate?.getHours() ?? 0) >= offsetChartAfter ? offsetInPx : 0\r\n leftOffset = Math.round(-fx(barsToOffset) + barWidth / 2) - offsetChartInPx\r\n }\r\n }\r\n // getMinMaxLeftOffset move left offset to keep at least one bar in view what isn't desired for offscreen charts\r\n if (specificChartFunctionality === SpecificChartFunctionality.offScreen) {\r\n return leftOffset\r\n }\r\n return getMinMaxLeftOffset({\r\n newLeftOffset: leftOffset,\r\n chartModel,\r\n barWidth,\r\n barIndex,\r\n })\r\n}\r\n\r\nexport const getBarIndex = (quote: Quote) => quote?.getBarIndex(quote.open?.length ? quote.open.length - 1 : 0) || 0\r\n\r\nexport const getIsSmallIndexChart = (specificChartFunctionality: SpecificChartFunctionality) =>\r\n specificChartFunctionality === SpecificChartFunctionality.smallIndex\r\n\r\ninterface ShouldAlignDaysToLeftProps {\r\n quote: Quote\r\n numberOfBarsToDraw?: number\r\n specificChartFunctionality: SpecificChartFunctionality\r\n dateRange: DateRangeType | null\r\n}\r\n\r\n/**\r\n * Evaluate if days should be aligned to the left\r\n * @param {object} object.quote - Quote model\r\n * @param {string} object.specificChartFunctionality - SpecificChartFunctionality enum\r\n * @returns {boolean} boolean\r\n * */\r\nexport const shouldAlignDaysToLeft = ({\r\n quote,\r\n dateRange,\r\n numberOfBarsToDraw,\r\n specificChartFunctionality,\r\n}: ShouldAlignDaysToLeftProps) => {\r\n const isStockIntraday = quote.isIntraday && quote.instrument === Instrument.Stock\r\n // We don't want this to affect /charts page, only if intraday daterange is applied\r\n const isQuoteOrOffscreen = [SpecificChartFunctionality.quotePage, SpecificChartFunctionality.offScreen].includes(\r\n specificChartFunctionality\r\n )\r\n const isChartPage = specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const isChartsInradayDateRange =\r\n isChartPage && !!dateRange && [DateRangeType.d1, DateRangeType.d5].includes(dateRange)\r\n const isChartPageWithFixedBars = isChartPage && numberOfBarsToDraw\r\n return isStockIntraday && (isQuoteOrOffscreen || isChartsInradayDateRange || isChartPageWithFixedBars)\r\n}\r\n\r\ninterface ClipProps {\r\n canvasCtx: RenderingContext2DType\r\n width: number\r\n height: number\r\n Settings: ISettings['ChartSettings'] | ISettings['IndicatorSettings']\r\n}\r\n// pane canvasCtx clip\r\nexport const clip = ({ canvasCtx, width, height, Settings }: ClipProps) => {\r\n const contentWidth = width - Settings.left.width - Settings.right.width\r\n const contentHeight = height - Settings.top.height - Settings.bottom.height\r\n canvasCtx.beginPath()\r\n canvasCtx.rect(Settings.left.width, Settings.top.height, contentWidth, contentHeight)\r\n canvasCtx.clip()\r\n}\r\n\r\nexport const getSettings = (paneModel: Pane): IIndicatorSettings | IChartSettings => {\r\n const { ChartSettings, IndicatorSettings } = paneModel.chart().getChartLayoutSettings()\r\n for (const element of paneModel.elements().all()) {\r\n if (element.isIndicator()) {\r\n return IndicatorSettings\r\n }\r\n }\r\n return ChartSettings\r\n}\r\n\r\ninterface RecountScaleProps {\r\n chartModel: Chart\r\n paneModel: Pane\r\n}\r\n\r\ntype ScaledFn = Partial & (d3.ScaleLinear | d3.ScaleSymLog)\r\n\r\nconst getShouldOffsetChartDomain = (elementModel: Element | ChartEventElement) => {\r\n const quote = elementModel.pane().chart().quote()\r\n\r\n return quote.chartEvents.length > 0 && ![TIMEFRAME.w, TIMEFRAME.m].includes(quote.timeframe)\r\n}\r\n\r\nexport const recountScale = ({ chartModel, paneModel }: RecountScaleProps) => {\r\n const { ChartSettings, IndicatorSettings, MarketSentimentSettings } = chartModel.getChartLayoutSettings()\r\n const chartLayout = chartModel.chart_layout()\r\n const barWidthWithMargin = getBarWidthWithMargin({ chartLayout, zoomFactor: chartModel.zoomFactor })\r\n for (const elementModel of [...paneModel.getAllElements(), ...paneModel.getAllChartEvents(false)]) {\r\n const el = elementModel.instance\r\n const isChart = elementModel.isChart()\r\n if (isChart || elementModel.isIndicator()) {\r\n let fx: ScaledFn, Settings: ISettings['MarketSentimentSettings' | 'ChartSettings' | 'IndicatorSettings'], width\r\n const scaleType = isChart ? chartModel.scale : ScaleType.Linear\r\n if (isChart) {\r\n Settings = chartModel.instrument === Instrument.MarketSentiment ? MarketSentimentSettings : ChartSettings\r\n } else {\r\n Settings = IndicatorSettings as ISettings['IndicatorSettings']\r\n }\r\n const contentHeight = paneModel.height - Settings.top.height - Settings.bottom.height\r\n\r\n if (chartModel.stretch) {\r\n width = chartModel.width - Settings.left.width - Settings.right.width\r\n fx = d3\r\n .scaleLinear()\r\n .range([0, width])\r\n .domain([0, Math.max(0, chartModel.quote().close.length - 1)]) as ScaledFn\r\n } else {\r\n fx = ((index: number) => index * barWidthWithMargin) as ScaledFn\r\n fx.invert = (x: number) => x / barWidthWithMargin\r\n fx.width = function (w) {\r\n return this.invert(w) - this.invert(0)\r\n }\r\n }\r\n paneModel.updateAttribute('scale', { x: fx }) // some elements need fx to count getMinMax\r\n\r\n const { min, max } = paneModel.scaleRange || el.getMinMax!()\r\n let fy\r\n\r\n const handleDomainOffset = (currentScale: ScaledFn, scaleCreator: any) => {\r\n if (isChart && getShouldOffsetChartDomain(elementModel)) {\r\n const protectedHeightPx = contentHeight - CHART_EVENT_BADGE_SIZE\r\n const minPx = currentScale(min)\r\n const domain = currentScale.domain()\r\n if (minPx > protectedHeightPx) {\r\n const tempScale = scaleCreator().range([0, protectedHeightPx]).domain([max, min])\r\n const extendedMin = tempScale.invert(contentHeight)\r\n currentScale.domain([domain[0], extendedMin])\r\n }\r\n }\r\n }\r\n\r\n switch (scaleType) {\r\n case ScaleType.Logarithmic:\r\n fy = d3.scaleSymlog().range([0, contentHeight]).domain([max, min]) as ScaledFn\r\n handleDomainOffset(fy, d3.scaleSymlog)\r\n break\r\n default:\r\n fy = d3.scaleLinear().range([0, contentHeight]).domain([max, min]) as ScaledFn\r\n if (!paneModel.scaleRange) {\r\n fy = fy.nice(10)\r\n handleDomainOffset(fy, d3.scaleLinear)\r\n }\r\n break\r\n }\r\n fy.height = function (h: number) {\r\n return this.invert(h) - this.invert(0)\r\n }\r\n paneModel.updateAttribute('scale', {\r\n x: fx,\r\n y: fy,\r\n })\r\n\r\n if (isChart) {\r\n el.setupAxis!(fx as ScaleAxis)\r\n }\r\n break\r\n }\r\n }\r\n}\r\n\r\n// general, only when blurry ends won't be visible or didn't matter\r\nexport const getOffsetFromLineWidth = (lineWidth: number) => (lineWidth % 2 === 0 ? 0 : 0.5)\r\n\r\ninterface IXYOffsetFromLine {\r\n lineWidth: number\r\n x1: number\r\n y1: number\r\n x2: number\r\n y2: number\r\n}\r\n\r\n// return x,y offsets for pixel perfect line rendering\r\nexport const getXYOffsetFromLine = ({ lineWidth, x1, y1, x2, y2 }: IXYOffsetFromLine) => {\r\n // don't add offset is lineWidth is even\r\n if (lineWidth % 2 === 0) {\r\n return { x: 0, y: 0 }\r\n }\r\n if (y1 === y2) {\r\n return { x: 0, y: 0.5 } // horizontal line\r\n } else if (x1 === x2) {\r\n return { x: 0.5, y: 0 } // vertical line\r\n } else {\r\n return { x: 0.5, y: 0.5 } // diagonal line\r\n }\r\n}\r\n\r\nexport const getRoundedObject = (obj: T): T => {\r\n const rounded = Object.entries(obj)\r\n for (let i = 0; i < rounded.length; i++) {\r\n rounded[i][1] = Math.round(rounded[i][1])\r\n }\r\n return Object.fromEntries(rounded) as T\r\n}\r\n\r\ninterface ITranslate {\r\n context: CanvasRenderingContext2D\r\n xOffset: number\r\n yOffset: number\r\n}\r\n\r\ninterface ITranslateObj {\r\n do: () => void\r\n undo: () => void\r\n}\r\n\r\nexport const getTranslate = ({ context, xOffset, yOffset }: ITranslate): ITranslateObj => ({\r\n do: () => context.translate(xOffset, yOffset),\r\n undo: () => context.translate(xOffset * -1, yOffset * -1),\r\n})\r\n\r\ninterface IPercentageScaleValue {\r\n number: number\r\n base: number\r\n}\r\n\r\nexport const getPercentageFromValue = ({ number, base }: IPercentageScaleValue) => ((number - base) / base) * 100\r\n\r\nexport const getValueFromPercentage = ({ number, base }: IPercentageScaleValue) => (number / 100) * base + base\r\n\r\ninterface UpdateZoomAndLeftOffsetByDateRangeProps {\r\n chartModel: Chart\r\n quote: Quote\r\n}\r\n\r\nexport function updateZoomAndLeftOffsetByDateRange({ chartModel, quote }: UpdateZoomAndLeftOffsetByDateRangeProps) {\r\n const { ChartSettings } = chartModel.getChartLayoutSettings()\r\n const chartVisibleWidth = chartModel.width - (ChartSettings.left.width + ChartSettings.right.width)\r\n\r\n const { start, end, numOfBarsToRender } = getParsedDateRangeMetaData({\r\n dateRange: chartModel.dateRange,\r\n quote,\r\n })\r\n\r\n const { zoomFactor, leftOffset } = getChartZoomAndLeftOffset({\r\n chartVisibleWidth,\r\n start,\r\n end,\r\n quote,\r\n numOfBarsToRender,\r\n chartModel: chartModel,\r\n })\r\n\r\n if (chartModel.zoomFactor !== zoomFactor || chartModel.leftOffset !== leftOffset) {\r\n chartModel.updateAttributes({ zoomFactor, leftOffset })\r\n }\r\n}\r\n\r\nexport function renderPane({\r\n chartLayoutModel,\r\n chartModel,\r\n paneModel,\r\n canvasCtx,\r\n shouldRenderCross = false,\r\n}: {\r\n chartLayoutModel: ChartLayout\r\n chartModel: Chart\r\n paneModel: Pane\r\n canvasCtx: CanvasRenderingContext2D\r\n shouldRenderCross?: boolean\r\n}) {\r\n if (paneModel.chart().instrument === Instrument.MarketSentiment) {\r\n canvasCtx.clearRect(0, 0, chartModel.width, paneModel.height)\r\n } else {\r\n canvasCtx.set('fillStyle', chartModel.getChartLayoutSettings().ChartSettings.general.Colors.canvasFill)\r\n canvasCtx.fillRect(0, 0, chartModel.width, paneModel.height)\r\n }\r\n const elements = paneModel.getAllElements()\r\n for (const { instance: elementInstance } of elements) {\r\n if (typeof elementInstance.renderGrid === 'function') {\r\n canvasCtx.save()\r\n elementInstance.renderGrid(canvasCtx)\r\n canvasCtx.restore()\r\n }\r\n }\r\n\r\n const chartEvents = paneModel.getAllChartEvents()\r\n const Settings = getSettings(paneModel)\r\n for (const { instance: elementInstance } of [...elements, ...chartEvents]) {\r\n const isDrawing = elementInstance.getIsDrawing()\r\n const isChartEvent = elementInstance.getIsChartEvent()\r\n\r\n if (isDrawing && (chartLayoutModel.isHideDrawingsActive || !elementInstance.getIsVisible())) {\r\n continue\r\n } else if ((isDrawing || isChartEvent) && !elementInstance.getIsInChartView(chartModel)) {\r\n continue\r\n }\r\n\r\n canvasCtx.save()\r\n if (elementInstance.renderContent != null) {\r\n canvasCtx.save()\r\n clip({\r\n canvasCtx,\r\n width: chartModel.width,\r\n height: paneModel.height,\r\n Settings,\r\n })\r\n canvasCtx.translate(paneModel.chart().leftOffset + Settings.left.width, Settings.top.height)\r\n elementInstance.renderContent(canvasCtx)\r\n canvasCtx.restore()\r\n if (typeof elementInstance.renderLabels === 'function') {\r\n elementInstance.renderLabels(canvasCtx)\r\n }\r\n } else {\r\n elementInstance.render(canvasCtx)\r\n }\r\n if (\r\n shouldRenderCross &&\r\n (chartLayoutModel.specificChartFunctionality === SpecificChartFunctionality.chartPage ||\r\n isRedesignedPage(chartLayoutModel)) &&\r\n elementInstance.renderCross != null\r\n ) {\r\n elementInstance.renderCross(canvasCtx)\r\n }\r\n canvasCtx.restore()\r\n }\r\n}\r\n","export const DEFAULT_WIDTHS = {\r\n min: 200,\r\n max: 400,\r\n}\r\n\r\nexport enum SidebarDirection {\r\n vertical,\r\n horizontal,\r\n}\r\n","import React from 'react'\r\n\r\nimport { DEFAULT_WIDTHS, SidebarDirection } from '../constants'\r\nimport { SidebarModule, SidebarModuleType } from '../modules/modules'\r\n\r\nexport type SidebarContextType = {\r\n isOpen: boolean\r\n isCloseVisible: boolean\r\n direction: SidebarDirection\r\n width?: {\r\n min?: number | string\r\n max?: number | string\r\n default?: { desktop?: number; mobile?: number }\r\n }\r\n activeModule: SidebarModuleType | null\r\n close: () => void\r\n onResize: () => void\r\n selectModule: (module?: SidebarModule) => void\r\n}\r\n\r\nconst DEFAULT_CONTEXT: SidebarContextType = {\r\n activeModule: null,\r\n isOpen: false,\r\n isCloseVisible: false,\r\n direction: SidebarDirection.horizontal,\r\n width: DEFAULT_WIDTHS,\r\n close: () => {},\r\n onResize: () => {},\r\n selectModule: () => {},\r\n}\r\n\r\nexport const SidebarContext = React.createContext(DEFAULT_CONTEXT)\r\nexport const useSidebarContext = () => React.useContext(SidebarContext)\r\n","import { IconNameType } from '@finviz/website'\r\n\r\nimport ChartLayout from '../../models/chart_layout'\r\n\r\nexport enum DrawingTool {\r\n Arrow = 'arrow',\r\n Brush = 'brush',\r\n Callout = 'callout',\r\n Curve = 'curve',\r\n ElliottWaves = 'elliott-wave',\r\n Ellipse = 'ellipse',\r\n FibonacciRetracements = 'fibonacci-retracements',\r\n HorizontalLine = 'horizontal-line',\r\n Measure = 'measure',\r\n Mouse = 'mouse',\r\n Pitchfork = 'pitchfork',\r\n Polygon = 'polygon',\r\n Position = 'position',\r\n Rectangle = 'rectangle',\r\n RotatedRectangle = 'rotated-rectangle',\r\n ScaledLine = 'scaled-line',\r\n ScaledText = 'scaled-text',\r\n Triangle = 'triangle',\r\n VerticalLine = 'vertical-line',\r\n Xabcd = 'xabcd',\r\n}\r\n\r\nexport enum DrawingActions {\r\n AddNote = 'add-note',\r\n DeleteDrawings = 'delete-drawings',\r\n DeleteAutoSavedDrawings = 'delete-autosaved-drawings',\r\n}\r\n\r\nexport enum DrawingSetting {\r\n PreserveDrawings = 'preserve-drawings',\r\n DrawingModeContinuous = 'drawing-mode-continuous',\r\n HideDrawings = 'hide-drawings',\r\n LockDrawings = 'lock-drawings',\r\n}\r\n\r\nexport interface IToolBarProps {\r\n chartLayoutModel: ChartLayout\r\n isSidebar?: boolean\r\n isHorizontal?: boolean\r\n isMobileOverlay?: boolean\r\n /**\r\n * Current selected tool id\r\n */\r\n activeTool: DrawingTool\r\n /**\r\n * On tool item select callback\r\n */\r\n onActiveToolChange: (activeTool: DrawingTool, trigger?: 'button' | 'select' | 'group') => void\r\n /**\r\n * On drawing actions item select callback\r\n */\r\n onDrawingActionClick?: (actionId: DrawingActions) => void\r\n /**\r\n * On drawing settings item select callback\r\n */\r\n onDrawingSettingClick?: (settingId: DrawingSetting) => void\r\n /**\r\n * On drawing end callback\r\n */\r\n onDrawingEnd?: () => void\r\n /**\r\n * Current state of drawing settings\r\n */\r\n drawingSettings: Record\r\n isAlternativeTheme?: boolean\r\n /**\r\n * Are tools disabled\r\n */\r\n areToolsDisabled?: boolean\r\n}\r\n\r\nexport interface IToolbarItemProperties {\r\n icon: IconNameType\r\n iconActive?: IconNameType\r\n iconAction?: IconNameType\r\n title: string\r\n titleActive?: string\r\n titleAction?: string\r\n}\r\n\r\nexport interface IToolbarDrawingTool extends IToolbarItemProperties {\r\n id: DrawingTool\r\n}\r\n\r\nexport interface IToolbarDrawingAction extends IToolbarItemProperties {\r\n id: DrawingActions\r\n}\r\n\r\nexport interface IToolbarDrawingSetting extends IToolbarItemProperties {\r\n id: DrawingSetting\r\n}\r\n\r\nexport interface IToolbarDrawingToolItem {\r\n defaultItem: IToolbarDrawingTool\r\n toolGroup?: Array\r\n toolGroupTitle?: string\r\n}\r\n\r\nexport interface IToolbarDrawingActionItem {\r\n defaultItem: IToolbarDrawingAction\r\n isDisabled?: boolean\r\n disabledTooltip?: string\r\n}\r\n\r\nexport interface IToolbarDrawingsSettingItem {\r\n defaultItem: IToolbarDrawingSetting\r\n isDisabled?: boolean\r\n isInAction?: boolean\r\n disabledTooltip?: string\r\n}\r\n","import { Instrument } from '../../types/shared'\r\nimport { ChartElementType } from '../constants/common'\r\nimport QuoteModel from '../models/quote'\r\n\r\nexport function getInstrumentLabel(instrument: Instrument) {\r\n switch (instrument) {\r\n case Instrument.Stock:\r\n return 'Stock'\r\n case Instrument.Futures:\r\n return 'Futures'\r\n case Instrument.Forex:\r\n return 'Forex'\r\n case Instrument.Crypto:\r\n return 'Crypto'\r\n case Instrument.MarketSentiment:\r\n return 'Market Sentiment'\r\n }\r\n}\r\n\r\nexport function getChartAlt(quoteModel: QuoteModel) {\r\n return `${quoteModel.name || quoteModel.ticker} - ${getInstrumentLabel(quoteModel.instrument)} Price Chart`\r\n}\r\n\r\nexport const getResponseChartType = (chartType: ChartElementType) => {\r\n switch (chartType) {\r\n case ChartElementType.HeikinAshi:\r\n return 'heikinashi'\r\n case ChartElementType.HollowCandleStick:\r\n return 'hollowcandlestick'\r\n case ChartElementType.LineChart:\r\n return 'line'\r\n case ChartElementType.OhlcChart:\r\n return 'ohlc'\r\n case ChartElementType.CandleStick:\r\n default:\r\n return 'candlestick'\r\n }\r\n}\r\n\r\nexport const getChartElementTypeFromResponseType = (chartResponseType: string | null) =>\r\n chartResponseType === null\r\n ? null\r\n : Object.values(ChartElementType).find(\r\n (chartType: ChartElementType) => chartResponseType === getResponseChartType(chartType)\r\n )\r\n","import utils from '../utils'\r\n\r\nclass AverageTrueRange {\r\n period: number\r\n sum: number\r\n count: number\r\n value: number\r\n\r\n constructor(period: number) {\r\n this.period = period\r\n this.sum = 0\r\n this.count = 0\r\n this.value = 0\r\n }\r\n\r\n add(high: number, low: number, prevClose: number) {\r\n const tr = utils.max([high - low, Math.abs(high - prevClose), Math.abs(low - prevClose)])\r\n\r\n if (this.count < this.period) {\r\n this.sum += tr\r\n this.value = this.sum / (this.count + 1)\r\n if (this.count === this.period - 1) {\r\n this.sum /= this.period\r\n }\r\n } else {\r\n this.value = (this.value * (this.period - 1) + tr) / this.period\r\n }\r\n this.count++\r\n }\r\n}\r\n\r\nexport default AverageTrueRange\r\n","import { Instrument, Point } from '../../types/shared'\r\n\r\ninterface LinePoints {\r\n x1: number\r\n x2: number\r\n y1: number\r\n y2: number\r\n}\r\n\r\nexport enum BigNumber {\r\n Thousand,\r\n Million,\r\n Billion,\r\n Trillion,\r\n}\r\n\r\nexport const BIG_NUMBER_VALUES = {\r\n [BigNumber.Thousand]: 1e3,\r\n [BigNumber.Million]: 1e6,\r\n [BigNumber.Billion]: 1e9,\r\n [BigNumber.Trillion]: 1e12,\r\n}\r\n\r\nconst BIG_NUMBER_ZEROES = {\r\n [BigNumber.Thousand]: 3,\r\n [BigNumber.Million]: 6,\r\n [BigNumber.Billion]: 9,\r\n [BigNumber.Trillion]: 12,\r\n}\r\n\r\nconst BIG_NUMBER_SUFFIX = {\r\n [BigNumber.Thousand]: 'K',\r\n [BigNumber.Million]: 'M',\r\n [BigNumber.Billion]: 'B',\r\n [BigNumber.Trillion]: 'T',\r\n}\r\n\r\nconst math = {\r\n dotProduct(p1: Point, p2: Point) {\r\n return p1.x * p2.x + p1.y * p2.y\r\n },\r\n\r\n crossProduct(p1: Point, p2: Point) {\r\n return p1.x * p2.y - p1.y * p2.x\r\n },\r\n\r\n distance(p1: Point, p2: Point) {\r\n return Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2))\r\n },\r\n\r\n lineEquation(line: LinePoints) {\r\n // ax + by + c = 0\r\n if (line.x1 === line.x2) {\r\n return {\r\n a: 1,\r\n b: 0,\r\n c: -line.x1,\r\n }\r\n }\r\n const k = (line.y2 - line.y1) / (line.x2 - line.x1)\r\n return {\r\n a: -k,\r\n b: 1,\r\n c: k * line.x1 - line.y1,\r\n k,\r\n }\r\n },\r\n\r\n pointInPolygon(point: Point, polygon: Point[]) {\r\n // http://alienryderflex.com/polygon/\r\n let j = polygon.length - 1\r\n let oddNodes = false\r\n for (let i = 0; i < polygon.length; i++) {\r\n const p = polygon[i]\r\n if (\r\n ((p.y < point.y && polygon[j].y >= point.y) || (polygon[j].y < point.y && p.y >= point.y)) &&\r\n (p.x <= point.x || polygon[j].x <= point.x)\r\n ) {\r\n if (p.x + ((point.y - p.y) / (polygon[j].y - p.y)) * (polygon[j].x - p.x) < point.x) {\r\n oddNodes = !oddNodes\r\n }\r\n }\r\n j = i\r\n }\r\n return oddNodes\r\n },\r\n\r\n distanceToLine(point: Point, line: LinePoints) {\r\n const { a, b, c } = this.lineEquation(line)\r\n const dist = Math.abs(a * point.x + b * point.y + c) / Math.sqrt(a * a + b * b)\r\n return dist\r\n },\r\n\r\n distanceToSegment(point: Point, line: LinePoints) {\r\n const l2 = Math.pow(line.x1 - line.x2, 2) + Math.pow(line.y1 - line.y2, 2)\r\n if (l2 === 0) {\r\n return Math.sqrt(Math.pow(point.x - line.x1, 2) + Math.pow(point.y - line.y1, 2))\r\n }\r\n const t = ((point.x - line.x1) * (line.x2 - line.x1) + (point.y - line.y1) * (line.y2 - line.y1)) / l2\r\n if (t < 0) {\r\n return Math.sqrt(Math.pow(point.x - line.x1, 2) + Math.pow(point.y - line.y1, 2))\r\n }\r\n if (t > 1) {\r\n return Math.sqrt(Math.pow(point.x - line.x2, 2) + Math.pow(point.y - line.y2, 2))\r\n }\r\n const x = line.x1 + t * (line.x2 - line.x1)\r\n const y = line.y1 + t * (line.y2 - line.y1)\r\n return Math.sqrt(Math.pow(point.x - x, 2) + Math.pow(point.y - y, 2))\r\n },\r\n\r\n getInstrumentDecimalPlaces({ value, instrument }: { value: number; instrument?: Instrument }) {\r\n if (instrument === Instrument.Crypto && value <= 0.001) {\r\n return 8\r\n }\r\n\r\n if ((instrument !== Instrument.Stock && value <= 6) || (instrument === Instrument.Stock && value < 1)) {\r\n return 4\r\n }\r\n\r\n return 2\r\n },\r\n\r\n formatBigNumber(number: number, toFixed?: number, minNumber?: BigNumber) {\r\n const absNum = Math.abs(number)\r\n const getString = ({ num, suffix, zeroes }: { num: number; suffix: string; zeroes: number }) => {\r\n const str = num.toString()\r\n if (str.includes('e')) {\r\n const splitString = str.split('e')\r\n const addZeroes = Number(splitString[1]) - zeroes\r\n return Math.round(Number(splitString[0])).toString().padEnd(Math.max(0, addZeroes), '0') + suffix\r\n }\r\n const sign = Math.sign(num)\r\n const numberByZeroesCount = Math.pow(10, zeroes)\r\n const result = (absNum / numberByZeroesCount) * sign\r\n return (Number.isInteger(result) ? result : result.toFixed(toFixed !== undefined ? toFixed : 1)) + suffix\r\n }\r\n\r\n if (absNum >= BIG_NUMBER_VALUES[BigNumber.Trillion] || minNumber === BigNumber.Trillion) {\r\n return getString({\r\n num: number,\r\n suffix: BIG_NUMBER_SUFFIX[BigNumber.Trillion],\r\n zeroes: BIG_NUMBER_ZEROES[BigNumber.Trillion],\r\n })\r\n } else if (absNum >= BIG_NUMBER_VALUES[BigNumber.Billion] || minNumber === BigNumber.Billion) {\r\n return getString({\r\n num: number,\r\n suffix: BIG_NUMBER_SUFFIX[BigNumber.Billion],\r\n zeroes: BIG_NUMBER_ZEROES[BigNumber.Billion],\r\n })\r\n } else if (absNum >= BIG_NUMBER_VALUES[BigNumber.Million] || minNumber === BigNumber.Million) {\r\n return getString({\r\n num: number,\r\n suffix: BIG_NUMBER_SUFFIX[BigNumber.Million],\r\n zeroes: BIG_NUMBER_ZEROES[BigNumber.Million],\r\n })\r\n } else if (absNum >= BIG_NUMBER_VALUES[BigNumber.Thousand] || minNumber === BigNumber.Thousand) {\r\n return getString({\r\n num: number,\r\n suffix: BIG_NUMBER_SUFFIX[BigNumber.Thousand],\r\n zeroes: BIG_NUMBER_ZEROES[BigNumber.Thousand],\r\n })\r\n } else {\r\n return toFixed !== undefined ? number.toFixed(toFixed) : number.toString()\r\n }\r\n },\r\n\r\n round({\r\n value,\r\n lastClose = 0,\r\n instrument,\r\n overridePlaces,\r\n }: {\r\n value: number\r\n lastClose?: number\r\n instrument?: Instrument\r\n overridePlaces?: number\r\n }) {\r\n if (Math.abs(value) >= BIG_NUMBER_VALUES[BigNumber.Million]) {\r\n return this.formatBigNumber(value, overridePlaces)\r\n }\r\n\r\n const places =\r\n typeof overridePlaces === 'number'\r\n ? overridePlaces\r\n : this.getInstrumentDecimalPlaces({ value: lastClose, instrument })\r\n\r\n if (value < 0.000001) {\r\n // There was an issue with getting NaN when rounding small numbers with latter method\r\n return value.toFixed(places)\r\n }\r\n return Number(`${Math.round(Number(`${value}e+${places}`))}e-${places}`).toFixed(places)\r\n },\r\n\r\n perpendicularPointToLine({ line, distance }: { line: LinePoints; distance: number }) {\r\n if (distance === 0) {\r\n return { x: line.x2, y: line.y2 }\r\n }\r\n\r\n let yAxisCoeficient\r\n let xAxisCoeficient\r\n\r\n if (line.x1 <= line.x2 && line.y1 >= line.y2) {\r\n xAxisCoeficient = -1\r\n yAxisCoeficient = -1\r\n } else if (line.x1 <= line.x2 && line.y1 <= line.y2) {\r\n xAxisCoeficient = 1\r\n yAxisCoeficient = -1\r\n } else if (line.x1 >= line.x2 && line.y1 >= line.y2) {\r\n xAxisCoeficient = -1\r\n yAxisCoeficient = 1\r\n } else {\r\n // conditions falling to else: (line.x1 >= line.x2 && line.y1 <= line.y2)\r\n xAxisCoeficient = 1\r\n yAxisCoeficient = 1\r\n }\r\n\r\n const radAngle = Math.atan2(Math.abs(line.x2 - line.x1), Math.abs(line.y2 - line.y1))\r\n const x = line.x2 + xAxisCoeficient * (distance * Math.cos(radAngle))\r\n const y = line.y2 + yAxisCoeficient * (distance * Math.sin(radAngle))\r\n return { x, y }\r\n },\r\n\r\n rotatedPointCoordinates({\r\n rotationAxisPoint,\r\n angle,\r\n pointToRotate,\r\n }: {\r\n rotationAxisPoint: Point\r\n angle: number\r\n pointToRotate: Point\r\n }) {\r\n // return newCoordinates for pointToRotate after rotation defined by\r\n // angle around rotationAxisPoint\r\n const sin = Math.sin(angle)\r\n const cos = Math.cos(angle)\r\n const rotatedX =\r\n cos * (pointToRotate.x - rotationAxisPoint.x) +\r\n sin * (pointToRotate.y - rotationAxisPoint.y) +\r\n rotationAxisPoint.x\r\n const rotatedY =\r\n cos * (pointToRotate.y - rotationAxisPoint.y) -\r\n sin * (pointToRotate.x - rotationAxisPoint.x) +\r\n rotationAxisPoint.y\r\n return { x: rotatedX, y: rotatedY }\r\n },\r\n sharedPointLinesAngle({\r\n sharedPoint,\r\n oldLinePoint,\r\n newLinePoint,\r\n }: {\r\n sharedPoint: Point\r\n oldLinePoint: Point\r\n newLinePoint: Point\r\n }) {\r\n // return angle between line from sharedPoint to oldLinePoint and\r\n // line from sharedPoint to newLinePoint\r\n const numerator =\r\n oldLinePoint.y * (sharedPoint.x - newLinePoint.x) +\r\n sharedPoint.y * (newLinePoint.x - oldLinePoint.x) +\r\n newLinePoint.y * (oldLinePoint.x - sharedPoint.x)\r\n const denominator =\r\n (oldLinePoint.x - sharedPoint.x) * (sharedPoint.x - newLinePoint.x) +\r\n (oldLinePoint.y - sharedPoint.y) * (sharedPoint.y - newLinePoint.y)\r\n const ratio = numerator / denominator\r\n\r\n return Math.atan(ratio)\r\n },\r\n\r\n twoSegmentLinesIntersection(p1: Point, p2: Point, p3: Point, p4: Point) {\r\n // line intercept math by Paul Bourke http://paulbourke.net/geometry/pointlineplane/\r\n // Determine the intersection point of two line segments\r\n // Return FALSE if the lines don't intersect\r\n\r\n // Check if none of the lines are of length 0\r\n if ((p1.x === p2.x && p1.y === p2.y) || (p3.x === p4.x && p3.y === p4.y)) {\r\n return false\r\n }\r\n\r\n const denominator = (p4.y - p3.y) * (p2.x - p1.x) - (p4.x - p3.x) * (p2.y - p1.y)\r\n\r\n // Lines are parallel\r\n if (denominator === 0) {\r\n return false\r\n }\r\n\r\n const ua = ((p4.x - p3.x) * (p1.y - p3.y) - (p4.y - p3.y) * (p1.x - p3.x)) / denominator\r\n const ub = ((p2.x - p1.x) * (p1.y - p3.y) - (p2.y - p1.y) * (p1.x - p3.x)) / denominator\r\n\r\n // is the intersection along the segments\r\n if (ua < 0 || ua > 1 || ub < 0 || ub > 1) {\r\n return false\r\n }\r\n\r\n // Return a object with the x and y coordinates of the intersection\r\n const x = p1.x + ua * (p2.x - p1.x)\r\n const y = p1.y + ua * (p2.y - p1.y)\r\n\r\n return { x, y }\r\n },\r\n\r\n // https://stackoverflow.com/a/60368757\r\n checkLineIntersection(line1_p1: Point, line1_p2: Point, line2_p1: Point, line2_p2: Point) {\r\n // if the lines intersect, the result contains the x and y of the intersection (treating the lines as infinite) and booleans for whether line segment 1 or line segment 2 contain the point\r\n let a, b\r\n const result: { x: number; y: number; onLine1: boolean; onLine2: boolean } = {\r\n x: 0,\r\n y: 0,\r\n onLine1: false,\r\n onLine2: false,\r\n }\r\n const denominator =\r\n (line2_p2.y - line2_p1.y) * (line1_p2.x - line1_p1.x) - (line2_p2.x - line2_p1.x) * (line1_p2.y - line1_p1.y)\r\n if (denominator === 0) {\r\n return false\r\n }\r\n\r\n a = line1_p1.y - line2_p1.y\r\n b = line1_p1.x - line2_p1.x\r\n const numerator1 = (line2_p2.x - line2_p1.x) * a - (line2_p2.y - line2_p1.y) * b\r\n const numerator2 = (line1_p2.x - line1_p1.x) * a - (line1_p2.y - line1_p1.y) * b\r\n a = numerator1 / denominator\r\n b = numerator2 / denominator\r\n\r\n // if we cast these lines infinitely in both directions, they intersect here:\r\n result.x = line1_p1.x + a * (line1_p2.x - line1_p1.x)\r\n result.y = line1_p1.y + a * (line1_p2.y - line1_p1.y)\r\n\r\n // if line1 is a segment and line2 is infinite, they intersect if:\r\n if (a > 0 && a < 1) {\r\n result.onLine1 = true\r\n }\r\n // if line2 is a segment and line1 is infinite, they intersect if:\r\n if (b > 0 && b < 1) {\r\n result.onLine2 = true\r\n }\r\n // if line1 and line2 are segments, they intersect if both of the above are true\r\n return result\r\n },\r\n\r\n // ray is considered line1, segment is considered line2\r\n getRayToLineSegmentIntersection(rayOrigin: Point, rayEnd: Point, segmentStart: Point, segmentEnd: Point) {\r\n const lineIntersection = this.checkLineIntersection(rayOrigin, rayEnd, segmentStart, segmentEnd)\r\n\r\n if (\r\n !lineIntersection ||\r\n lineIntersection.onLine1 ||\r\n this.dotProduct(\r\n this.subtractPoints(rayOrigin, lineIntersection as Point),\r\n this.subtractPoints(rayOrigin, rayEnd)\r\n ) <= 0\r\n )\r\n return false\r\n return { ...lineIntersection, x: Math.round(lineIntersection.x), y: Math.round(lineIntersection.y) } // sometimes edge value can have crazy precision instead of `0` something like `5.684341886080802e-14` which is basically 0.00000000000005684341886080802 we should round it\r\n },\r\n\r\n getMiddlePointOnLineSegment(P1: Point, P2: Point) {\r\n const x = (P1.x - P2.x) / 2 + P2.x\r\n const y = (P1.y - P2.y) / 2 + P2.y\r\n return { x, y }\r\n },\r\n\r\n normalizeVector(v: Point) {\r\n const length = Math.sqrt(v.x * v.x + v.y * v.y)\r\n return { x: v.x / length, y: v.y / length }\r\n },\r\n\r\n multiplyVectorByScalar(v: Point, scalar: number) {\r\n return { x: v.x * scalar, y: v.y * scalar }\r\n },\r\n\r\n addPoints(P1: Point, P2: Point) {\r\n return { x: P1.x + P2.x, y: P1.y + P2.y }\r\n },\r\n\r\n subtractPoints(P1: Point, P2: Point): Point {\r\n return { x: P1.x - P2.x, y: P1.y - P2.y }\r\n },\r\n\r\n isSamePoint(P1: Point, P2: Point, margin = { x: 0, y: 0 }) {\r\n return P1.x - margin.x <= P2.x && P2.x <= P1.x + margin.x && P1.y - margin.y <= P2.y && P2.y <= P1.y + margin.y\r\n },\r\n}\r\n\r\nexport default math\r\n","import { OverlayType } from '../constants/common'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n period: number\r\n}\r\n\r\nexport class ExponentialMovingAverage {\r\n period: number\r\n multiplier: number\r\n sum: number\r\n count: number\r\n value: number\r\n\r\n constructor(period: number) {\r\n this.period = period\r\n this.multiplier = 2 / (this.period + 1)\r\n this.sum = 0\r\n this.count = 0\r\n this.value = 0\r\n }\r\n\r\n add(d: number) {\r\n if (this.count < this.period) {\r\n this.sum += d\r\n this.count++\r\n this.value = this.sum / this.count\r\n } else {\r\n this.value = d * this.multiplier + this.value * (1 - this.multiplier)\r\n }\r\n }\r\n}\r\n\r\ntype DefaultCalculatedValuesType = {\r\n ema: number[]\r\n}\r\n\r\nexport class EMACalculation extends MainCalculation {\r\n static type = OverlayType.Ema\r\n\r\n getDefaultCalculatedValues() {\r\n return { ema: [] }\r\n }\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { period } = this.options\r\n const { close } = this.quote\r\n const lastIndex = close.length - 1\r\n const ema = new ExponentialMovingAverage(period)\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n for (let index = 0; index <= lastIndex; index++) {\r\n ema.add(close[index])\r\n this.calculatedValues.ema[index] = ema.value\r\n\r\n if (onValueCalculated?.(this.calculatedValues, index) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import { ObjectHash } from '../../types/shared'\r\nimport { IndicatorType, OverlayType } from '../constants/common'\r\nimport Quote from '../models/quote'\r\n\r\ntype OptionValuesType = ObjectHash\r\ntype CalculatedValuesType = ObjectHash\r\ninterface MainProps {\r\n quote?: Quote\r\n options: T\r\n}\r\n\r\nexport type OnValueCalculatedReturnValue = boolean | undefined\r\nexport type OnValueCalculated = ((value: T, dataIndex: number) => OnValueCalculatedReturnValue) | undefined\r\n\r\nexport class MainCalculation<\r\n TOptionValues extends OptionValuesType | undefined = undefined,\r\n TCalculatedValues extends CalculatedValuesType = CalculatedValuesType,\r\n> {\r\n static type: IndicatorType | OverlayType = IndicatorType.Indicator\r\n\r\n quote: NonNullable['quote']>\r\n options: MainProps['options']\r\n\r\n protected _calculatedValues: TCalculatedValues\r\n\r\n constructor({ quote, options }: MainProps) {\r\n this.quote = quote ?? new Quote()\r\n this.options = options\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n }\r\n\r\n get calculatedValues() {\r\n return this._calculatedValues\r\n }\r\n\r\n getDefaultCalculatedValues(): TCalculatedValues {\r\n throw Error('Implement getDefaultCalculatedValues')\r\n }\r\n\r\n calculate(_: OnValueCalculated) {\r\n throw Error('Implement calculate')\r\n }\r\n\r\n getAllCalculatedValues(lastNItems: number) {\r\n const calculatedValues = {} as TCalculatedValues\r\n Object.keys(this.calculatedValues).forEach((key) => {\r\n calculatedValues[key as keyof TCalculatedValues] = this.getCalculatedValues(key, lastNItems)\r\n })\r\n return calculatedValues\r\n }\r\n\r\n getCalculatedValues(key: keyof TCalculatedValues, lastNItems: number) {\r\n return (this.calculatedValues[key] as number[]).slice(-lastNItems) as TCalculatedValues[keyof TCalculatedValues]\r\n }\r\n\r\n /**\r\n * This function is used to construct sql script for db table creation\r\n * and also to build precalculated data object used on node server.\r\n *\r\n * Precalculated data object uses database column names as property keys to simplify data mapping on BE\r\n */\r\n getDbColumnName() {\r\n const { type } = this.constructor as typeof MainCalculation\r\n const typeLabel = type.split('/')[1]\r\n const optionKeys = Object.keys(this.options ?? {}).sort((key1, key2) => key1.localeCompare(key2))\r\n\r\n const optionsStrings = optionKeys.map((key) => `${key.slice(0, 1)}${this.options![key]}`)\r\n return [typeLabel, ...optionsStrings].join('_')\r\n }\r\n}\r\n","import Spine from '@finviz/spine'\r\nimport merge from 'lodash.merge'\r\n\r\nimport {\r\n ChartConfigChartPaneElement,\r\n CustomSpineEvents,\r\n IModalConfig,\r\n IModalConfigInput,\r\n ObjectHash,\r\n PaneArea,\r\n RequireByKey,\r\n Theme,\r\n} from '../../types/shared'\r\nimport Line from '../canvas/line'\r\nimport Text from '../canvas/text'\r\nimport tailwindColors from '../constants/colors'\r\nimport {\r\n FONT_SIZE,\r\n INDICATOR_LABEL_HEIGHT,\r\n IndicatorType,\r\n OFFSET,\r\n PADDING,\r\n SpecificChartFunctionality,\r\n TextAlign,\r\n TextBaseline,\r\n} from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport Chart from '../models/chart'\r\nimport mouseModel from '../models/mouse'\r\nimport Pane from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport { getChartLayoutSettings } from '../models/settings'\r\nimport { isRedesignEnabled } from '../utils'\r\nimport { roundedRect } from '../utils/canvas-render'\r\nimport { renderCross } from '../utils/chart'\r\nimport {\r\n drawInVisibleArea,\r\n getCompensatedFirstBarToRenderIndex,\r\n getFirstBarToRenderIndex,\r\n getLastBarToRenderIndex,\r\n} from '../utils/draw_in_visible_area'\r\nimport { getIsSSr, getParsedIntegersFromPeriodString, isInRange, isPositiveInteger } from '../utils/helpers'\r\n\r\nconst MAX_POSITIVE_DEFAULT_VALUE = Number.MAX_VALUE\r\nconst MAX_NEGATIVE_DEFAULT_VALUE = -Number.MAX_VALUE\r\n\r\nconst INDICATOR_DEFAULT_DOMAIN = (indicator: IndicatorType) => {\r\n switch (indicator) {\r\n case IndicatorType.Rvol:\r\n return { min: 0, max: 2 }\r\n case IndicatorType.Atr:\r\n return { min: 0, max: 10 }\r\n case IndicatorType.Adx:\r\n case IndicatorType.Aro:\r\n case IndicatorType.Mfi:\r\n case IndicatorType.Perf:\r\n case IndicatorType.Rmi:\r\n case IndicatorType.Rsi:\r\n case IndicatorType.Stofu:\r\n case IndicatorType.Ult:\r\n return { min: 0, max: 100 }\r\n case IndicatorType.Macd:\r\n case IndicatorType.Rwi:\r\n case IndicatorType.Trix:\r\n return { min: -1, max: 1 }\r\n case IndicatorType.Wr:\r\n return { min: -100, max: 0 }\r\n case IndicatorType.Aroosc:\r\n case IndicatorType.Roc:\r\n return { min: -100, max: 100 }\r\n case IndicatorType.Cci:\r\n case IndicatorType.Fi:\r\n return { min: -200, max: 200 }\r\n default:\r\n return { min: 0, max: 100 }\r\n }\r\n}\r\n\r\nexport interface IIndicatorIsValid {\r\n getIsValid(key: string): boolean | void\r\n}\r\n\r\nclass Indicator extends Spine.Module implements IIndicatorIsValid {\r\n static type = IndicatorType.Indicator\r\n static label = 'Indicator'\r\n\r\n static initClass() {\r\n Object.defineProperty(this.prototype, 'height', {\r\n get() {\r\n return this.model.height\r\n },\r\n })\r\n Object.defineProperty(this.prototype, 'contentHeight', {\r\n get() {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n return this.height - IndicatorSettings.top.height - IndicatorSettings.bottom.height\r\n },\r\n })\r\n }\r\n\r\n static fromObject(values: ObjectHash, model: Pane) {\r\n const indicator = new this(values, model)\r\n indicator.set(values)\r\n return indicator\r\n }\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [periodInt = 0] = getParsedIntegersFromPeriodString(period)\r\n return periodInt\r\n }\r\n\r\n declare data: Quote\r\n declare min: number\r\n declare max: number\r\n declare contentHeight: number\r\n declare height: number\r\n\r\n attrs: Attrs\r\n model: Pane\r\n labelWidth = 0\r\n fetchedAt = -1\r\n leftOffset = 0\r\n width = 0\r\n contentWidth = 0\r\n lastValue: number | null = null\r\n shouldUpdate = true\r\n tickers: string | null = null\r\n period?: string | number\r\n\r\n constructor(attrs: Attrs, model: Pane) {\r\n super(attrs, model)\r\n this.attrs = attrs\r\n this.model = model\r\n this.data = this.model.chart().quote()\r\n\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n this.renderCrossText = this.renderCrossText.bind(this)\r\n\r\n this.model.chart().bind('update', this.trigger.bind(this, 'change'))\r\n this.model.bind('update change', this.trigger.bind(this, 'change'))\r\n const mouseModelChangeHandler = this.trigger.bind(this, 'change', 'cross')\r\n this.model.bind('destroy', () => {\r\n mouseModel.unbind('change', mouseModelChangeHandler)\r\n })\r\n mouseModel.bind('change', mouseModelChangeHandler)\r\n\r\n this.model.chart().chart_layout().bind('theme', this.setupCache.bind(this))\r\n }\r\n\r\n get type() {\r\n return (this.constructor as typeof Indicator).type\r\n }\r\n\r\n get label() {\r\n return (this.constructor as typeof Indicator).label\r\n }\r\n\r\n render(context: CanvasRenderingContext2D) {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n this.data = this.model.chart().quote()\r\n this.leftOffset = this.model.chart().leftOffset\r\n this.width = this.model.chart().width\r\n this.contentWidth = this.width - IndicatorSettings.left.width - IndicatorSettings.right.width\r\n\r\n this.compute()\r\n\r\n this.setupCache()\r\n\r\n this.renderYAxis(context)\r\n\r\n context.save()\r\n this.clip(context)\r\n this.renderXAxis(context)\r\n const translate = getTranslate({\r\n context,\r\n xOffset: this.leftOffset + IndicatorSettings.left.width,\r\n yOffset: IndicatorSettings.top.height,\r\n })\r\n translate.do()\r\n this.renderIndicator(context)\r\n translate.undo()\r\n context.restore()\r\n\r\n if (!this.getIsChartPageSpecificFunctionality()) {\r\n this.renderLabel(context)\r\n }\r\n }\r\n\r\n isComputeNecessary() {\r\n // if quote was updated (this.fetchedAt !== this.data.fetchedAt)\r\n // or indicator setting was changed via modal (this.shouldUpdate)\r\n // allow compute and update variables to prevent another unless\r\n // those variables change again\r\n if (this.fetchedAt !== this.data.fetchedAt || this.shouldUpdate) {\r\n this.fetchedAt = this.data.fetchedAt\r\n this.shouldUpdate = false\r\n return true\r\n }\r\n return false\r\n }\r\n\r\n renderYAxis(context: CanvasRenderingContext2D) {\r\n const { IndicatorSettings, ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n let y\r\n const translate = getTranslate({\r\n context,\r\n xOffset: IndicatorSettings.left.width,\r\n yOffset: IndicatorSettings.top.height,\r\n })\r\n translate.do()\r\n const ticks = this.model.scale.y.ticks(10)\r\n const tickTextStep = Math.abs(ticks[2] - ticks[0])\r\n const yLine = new Line(\r\n {\r\n x1: 0,\r\n x2: this.contentWidth,\r\n strokeStyle: Colors.grid,\r\n dashLength: 3,\r\n },\r\n this.model\r\n )\r\n const text = new Text(\r\n {\r\n x: this.contentWidth + OFFSET.M + IndicatorSettings.right.axis.margin.left!,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.right.axis.font),\r\n fillStyle: Colors.text,\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.model\r\n )\r\n for (let index = 0; index < ticks.length; index++) {\r\n const tick = ticks[index]\r\n y = Math.round(this.fy(tick))\r\n yLine.set({ y1: y, y2: y }).render(context)\r\n if (index % 2 === 0) {\r\n text.set({ text: this.formatAxis(tick, tickTextStep), y }).render(context)\r\n }\r\n }\r\n\r\n const minY = 0\r\n const maxY = this.contentHeight\r\n const valueY = this.lastValue === null ? 0 : Math.round(this.fy(this.lastValue))\r\n if (this.lastValue != null && valueY >= minY && valueY <= maxY) {\r\n new Text(\r\n {\r\n text: math.formatBigNumber(this.lastValue, 2),\r\n x: this.contentWidth + OFFSET.M - PADDING.XXS + IndicatorSettings.right.axis.margin.left!,\r\n y: valueY,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.right.axis.font),\r\n lineHeight: IndicatorSettings.right.axis.font.lineHeight,\r\n padding: {\r\n top: IndicatorSettings.right.axis.font?.padding?.top ?? PADDING.XXS,\r\n right: IndicatorSettings.right.axis.font?.padding?.right ?? PADDING.XXS,\r\n bottom: IndicatorSettings.right.axis.font?.padding?.bottom ?? PADDING.XXS,\r\n left: IndicatorSettings.right.axis.font?.padding?.left ?? PADDING.XXS,\r\n },\r\n textBaseline: TextBaseline.middle,\r\n fillStyle: Colors.indicatorCurrentText,\r\n background: Colors.indicatorCurrentBackground,\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n\r\n translate.undo()\r\n }\r\n\r\n renderXAxis(context: CanvasRenderingContext2D) {\r\n const { IndicatorSettings, ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const xLine = new Line(\r\n {\r\n x1: 0,\r\n x2: 0,\r\n y1: 0,\r\n y2: this.contentHeight,\r\n strokeStyle: Colors.grid,\r\n dashLength: 3,\r\n },\r\n this.model\r\n )\r\n const translate = getTranslate({\r\n context,\r\n xOffset: IndicatorSettings.left.width,\r\n yOffset: IndicatorSettings.top.height,\r\n })\r\n translate.do()\r\n for (let tick = 0, end = this.data.date.length; tick < end; tick += 10) {\r\n const x = Math.round(this.fx(tick) + this.leftOffset)\r\n if (x < -15 || x > this.width + 15) {\r\n // margin?\r\n continue\r\n }\r\n xLine.set({ x1: x, x2: x }).render(context)\r\n }\r\n translate.undo()\r\n }\r\n\r\n renderLabel(context: CanvasRenderingContext2D) {\r\n if (this.getIsChartPageSpecificFunctionality()) {\r\n this.renderLabelChartsPage(context)\r\n } else {\r\n this.renderLabelQuotePage(context)\r\n }\r\n }\r\n\r\n renderLabelQuotePage(context: CanvasRenderingContext2D) {\r\n const { IndicatorSettings, ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const label = new Text(\r\n {\r\n text: this.toString(),\r\n x: IndicatorSettings.left.indicatorLabel.margin.left,\r\n y: IndicatorSettings.left.indicatorLabel.margin.top,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.left.indicatorLabel.font),\r\n fillStyle: Colors.text,\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.model\r\n )\r\n this.labelWidth = label.measure(context)\r\n return label.render(context)\r\n }\r\n\r\n renderLabelChartsPage(context: CanvasRenderingContext2D): { x: number; y: number; labelWidth: number } | void {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n const { theme, specificChartFunctionality } = this.model.chart().chart_layout()\r\n const isDarkMode = theme === Theme.dark\r\n const x =\r\n specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n ? OFFSET.S\r\n : IndicatorSettings.left.indicatorLabel.margin.left!\r\n const y = IndicatorSettings.left.indicatorLabel.margin.top!\r\n const label = new Text(\r\n {\r\n text: this.toString(),\r\n x: x * 2,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.left.indicatorLabel.font),\r\n fillStyle: tailwindColors.gray[isDarkMode ? 50 : 900],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.model\r\n )\r\n this.labelWidth = label.measure(context) + IndicatorSettings.left.indicatorLabel.margin.left! * 2\r\n label.set({ y: y + (INDICATOR_LABEL_HEIGHT - label.attrs.lineHeight / 2) })\r\n roundedRect({\r\n ctx: context,\r\n x,\r\n y,\r\n height: INDICATOR_LABEL_HEIGHT,\r\n width: this.labelWidth,\r\n radius: 6,\r\n color: `${tailwindColors.gray[isDarkMode ? 700 : 50]}cc`,\r\n })\r\n label.render(context)\r\n\r\n return { x, y, labelWidth: this.labelWidth }\r\n }\r\n\r\n renderCross(context: CanvasRenderingContext2D) {\r\n renderCross({\r\n context,\r\n mouseModel,\r\n paneModel: this.model,\r\n quote: this.data,\r\n contentWidth: this.contentWidth,\r\n contentHeight: this.contentHeight,\r\n isIndicator: true,\r\n isPerfIndicator: this.type === IndicatorType.Perf,\r\n onRenderCrossText: !this.getIsChartPageSpecificFunctionality() ? this.renderCrossText : undefined,\r\n })\r\n\r\n if (this.getIsChartPageSpecificFunctionality()) {\r\n this.renderCrossText(context, mouseModel.getCrossIndexForPane(this.model))\r\n }\r\n }\r\n\r\n renderCrossText(context: CanvasRenderingContext2D, crossIndex: number) {\r\n this.data = this.model.chart().quote()\r\n const index = Number.isNaN(crossIndex) ? this.data.close.length - 1 : crossIndex\r\n if (this.getIsChartPageSpecificFunctionality()) {\r\n this.renderLabelChartsPage(context)\r\n\r\n this.renderCrossTextChartsPage(context, index)\r\n } else {\r\n this.renderCrossTextQuotePage(context, index)\r\n }\r\n }\r\n\r\n renderCrossTextChartsPage(_: CanvasRenderingContext2D, __: number) {}\r\n\r\n renderCrossTextQuotePage(_: CanvasRenderingContext2D, __: number) {}\r\n\r\n renderOversoldOverbought(\r\n context: CanvasRenderingContext2D,\r\n array: number[],\r\n from: number,\r\n oversold: number,\r\n zero: number,\r\n overbought: number,\r\n drawLines?: boolean\r\n ) {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n if (this.data.close.length === 0) return\r\n const drawInVisibleAreaProps = {\r\n quote: this.data,\r\n scale: this.model.scale,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n fromIndexOffset: from,\r\n }\r\n\r\n const firstBarToRenderIndex = getCompensatedFirstBarToRenderIndex(drawInVisibleAreaProps)\r\n\r\n if (drawLines == null) {\r\n drawLines = true\r\n }\r\n\r\n context.save()\r\n\r\n let clipHeight = Math.round(this.fy(oversold) - this.fy(this.model.scale.y.domain()[1]))\r\n if (clipHeight <= 0 || getIsSSr()) {\r\n context.beginPath()\r\n context.rect(\r\n -this.leftOffset,\r\n this.fy(this.model.scale.y.domain()[1]) + 1, // compensation to addition of 1 in clip function\r\n this.contentWidth,\r\n clipHeight < 0 ? clipHeight - 1 : -1 // clipHeight - 1 is a compensation to addition of 1 in clip function ; fix bug in skia-canvas when clip is incorrect if height is 0 or clip is outside of previous clip https://github.com/samizdatco/skia-canvas/issues/87\r\n )\r\n }\r\n context.clip()\r\n context.set('fillStyle', '#87ceef')\r\n\r\n context.beginPath()\r\n context.moveTo(this.fx(firstBarToRenderIndex), Math.round(this.fy(this.model.scale.y.domain()[0])))\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(array[i])))\r\n },\r\n })\r\n context.lineTo(this.fx(this.data.close.length - 1), Math.round(this.fy(this.model.scale.y.domain()[0])))\r\n context.fill()\r\n context.restore()\r\n if (drawLines) {\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(oversold)),\r\n y2: Math.round(this.fy(oversold)),\r\n strokeStyle: '#69c1ea',\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n\r\n if (drawLines) {\r\n this.renderZeroLine(context, zero)\r\n }\r\n\r\n context.save()\r\n clipHeight = Math.round(this.fy(overbought))\r\n if (clipHeight >= 0 || getIsSSr()) {\r\n context.beginPath()\r\n context.rect(\r\n -this.leftOffset,\r\n this.fy(this.model.scale.y.domain()[0]),\r\n this.contentWidth,\r\n clipHeight > 0 ? clipHeight : 1 // // fix bug in skia-canvas when clip is incorrect if height is 0 or clip is outside of previous clip https://github.com/samizdatco/skia-canvas/issues/87\r\n )\r\n }\r\n\r\n context.clip()\r\n context.set('fillStyle', '#dc9fe5')\r\n context.beginPath()\r\n context.moveTo(this.fx(firstBarToRenderIndex), Math.round(this.fy(this.model.scale.y.domain()[1])))\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(array[i])))\r\n },\r\n })\r\n context.lineTo(this.fx(this.data.close.length - 1), Math.round(this.fy(this.model.scale.y.domain()[1]) + 1))\r\n context.fill()\r\n context.restore()\r\n if (drawLines) {\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(overbought)),\r\n y2: Math.round(this.fy(overbought)),\r\n strokeStyle: '#d386df',\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n\r\n context.set('strokeStyle', IndicatorSettings.general.Colors.line)\r\n context.set('fillStyle', '#dc9fe5')\r\n\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(Math.round(x), Math.round(this.fy(array[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n renderZeroLine(context: CanvasRenderingContext2D, zero: number) {\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(zero)),\r\n y2: Math.round(this.fy(zero)),\r\n strokeStyle: '#ff8787',\r\n dashLength: 3,\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n\r\n setupCache() {}\r\n\r\n clip(context: CanvasRenderingContext2D) {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n context.beginPath()\r\n context.rect(IndicatorSettings.left.width, IndicatorSettings.top.height, this.contentWidth, this.contentHeight + 1) // +1 shows one more pixel which is needed to be able to see a line at very bottom of an indicaor\r\n return context.clip()\r\n }\r\n\r\n formatAxis(value: number, tickStep?: number) {\r\n if (tickStep !== undefined && 10 > tickStep) {\r\n return value.toFixed(2)\r\n }\r\n return value.toString()\r\n }\r\n\r\n fx = (x: number) => this.model.scale.x(this.data.barIndex[x])\r\n\r\n fy = (y: number) => this.model.scale.y(y)\r\n\r\n set(values: Partial) {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n this.shouldUpdate = true\r\n for (const key in values) {\r\n if (key !== 'type') {\r\n // @ts-expect-error - values keys don't have to always match variables on the instance\r\n this[key] = values[key]\r\n }\r\n }\r\n this.width = this.model.chart().width\r\n this.contentWidth = this.width - IndicatorSettings.left.width - IndicatorSettings.right.width\r\n\r\n const newAttrs = this.getModalConfig()\r\n .inputs.map(({ value }) => value.toString())\r\n .join(',')\r\n if (newAttrs) this.attrs = { ...this.attrs, period: newAttrs }\r\n\r\n this.model.trigger(CustomSpineEvents.ManualChange)\r\n }\r\n\r\n parsePeriodInt(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n this.period = Number.parseInt(values.period, 10)\r\n this.model.trigger(CustomSpineEvents.ManualChange)\r\n }\r\n }\r\n\r\n setModel(model: Pane) {\r\n return (this.model = model)\r\n }\r\n\r\n isInArea(area: PaneArea) {\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n const x = IndicatorSettings.left.indicatorLabel.margin.left!\r\n const y = IndicatorSettings.left.indicatorLabel.margin.top!\r\n let width = OFFSET.M * 2 + this.labelWidth\r\n let height = OFFSET.S * 2 + FONT_SIZE.M\r\n\r\n if (this.getIsChartPageSpecificFunctionality()) {\r\n width = this.labelWidth\r\n height = INDICATOR_LABEL_HEIGHT\r\n }\r\n\r\n if (x < area.cursorX && area.cursorX < width + x && y < area.cursorY && area.cursorY < height + y) {\r\n return true\r\n }\r\n return false\r\n }\r\n\r\n getIsInChartView(_: Chart) {\r\n return true\r\n }\r\n\r\n moveBy() {}\r\n\r\n thumbsAreInArea() {\r\n return false\r\n }\r\n\r\n computeVisibleMinMax(...arrays: number[][]) {\r\n let min = MAX_POSITIVE_DEFAULT_VALUE\r\n let max = MAX_NEGATIVE_DEFAULT_VALUE\r\n\r\n const { leftOffset } = this.model.chart()\r\n\r\n const firstBarToRenderIndex = getFirstBarToRenderIndex({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n leftOffset,\r\n }).index\r\n const lastBarToRenderIndex = getLastBarToRenderIndex({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n leftOffset,\r\n chartWidth: this.contentWidth,\r\n }).index\r\n\r\n for (const arr of arrays) {\r\n for (let i = firstBarToRenderIndex; i <= lastBarToRenderIndex; i++) {\r\n if (!isNaN(arr[i])) {\r\n min = Math.min(min, arr[i])\r\n max = Math.max(max, arr[i])\r\n }\r\n }\r\n }\r\n\r\n return min !== max && min !== MAX_POSITIVE_DEFAULT_VALUE && max !== MAX_NEGATIVE_DEFAULT_VALUE\r\n ? { min, max }\r\n : this.getDomainDefaults(this.type)\r\n }\r\n\r\n getModalConfig(): IModalConfig {\r\n return {\r\n title: '',\r\n inputs: [],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n getDomainDefaults = (indicatorType: IndicatorType) => INDICATOR_DEFAULT_DOMAIN(indicatorType)\r\n\r\n getMinMax() {\r\n this.data = this.model.chart().quote()\r\n this.compute()\r\n return { min: this.min, max: this.max }\r\n }\r\n\r\n toObject() {\r\n return merge({}, this.attrs, { type: this.type, tickers: this.tickers })\r\n }\r\n\r\n toConfig(): T['attrs'] & { type: T['type'] } {\r\n return {\r\n type: this.type,\r\n period: this.getModalConfig()\r\n .inputs.map((input: IModalConfigInput) => input.value.toString())\r\n .join(','),\r\n }\r\n }\r\n\r\n getChartLayoutSettings() {\r\n return getChartLayoutSettings(this.model.chart().chart_layout())\r\n }\r\n\r\n renderIndicator(_: CanvasRenderingContext2D) {\r\n throw Error('Implement renderIndicator method')\r\n }\r\n\r\n getIsValid(_: string): boolean | undefined {\r\n throw Error('Implement')\r\n }\r\n\r\n getIsNumberInputValid({ key, integerOnly = true }: { key: string; integerOnly?: boolean }): boolean {\r\n const input = this.getModalConfig().inputs.find(({ name }: { name: string }) => key === name)\r\n return !!input && isInRange(input) && (!integerOnly || isPositiveInteger(input.value))\r\n }\r\n\r\n getIsChartPageSpecificFunctionality() {\r\n const { specificChartFunctionality } = this.model.chart().chart_layout()\r\n const isCharts = specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n const isRedesignedFuturesForexCrypto =\r\n isRedesignEnabled() &&\r\n [\r\n SpecificChartFunctionality.futuresPage,\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n SpecificChartFunctionality.quotePage,\r\n ].includes(specificChartFunctionality)\r\n\r\n return isCharts || isRedesignedFuturesForexCrypto\r\n }\r\n\r\n getIsDrawing() {\r\n return false\r\n }\r\n\r\n getIsChartEvent() {\r\n return false\r\n }\r\n\r\n compute() {\r\n throw Error('Implement compute method')\r\n }\r\n}\r\n\r\nIndicator.initClass()\r\n\r\nexport default Indicator\r\n","export function roundedRect({\r\n ctx,\r\n x,\r\n y,\r\n width,\r\n height,\r\n radius,\r\n color,\r\n}: {\r\n ctx: CanvasRenderingContext2D\r\n x: number\r\n y: number\r\n width: number\r\n height: number\r\n radius: number\r\n color: string\r\n}) {\r\n ctx.translate(0.5, 0.5)\r\n ctx.set('strokeStyle', color)\r\n ctx.set('fillStyle', color)\r\n ctx.beginPath()\r\n ctx.moveTo(x, y + radius)\r\n ctx.lineTo(x, y + height - radius)\r\n ctx.arcTo(x, y + height, x + radius, y + height, radius)\r\n ctx.lineTo(x + width - radius, y + height)\r\n ctx.arcTo(x + width, y + height, x + width, y + height - radius, radius)\r\n ctx.lineTo(x + width, y + radius)\r\n ctx.arcTo(x + width, y, x + width - radius, y, radius)\r\n ctx.lineTo(x + radius, y)\r\n ctx.arcTo(x, y, x, y + radius, radius)\r\n ctx.stroke()\r\n ctx.fill()\r\n ctx.translate(-0.5, -0.5)\r\n}\r\n","import { IndicatorType } from '../constants/common'\r\nimport utils from '../utils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass ADX extends Indicator {\r\n static type = IndicatorType.Adx\r\n static label = 'ADX'\r\n\r\n declare period: number\r\n pdi: number[] = []\r\n mdi: number[] = []\r\n adx: number[] = []\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n let adx, amdm, apdm, mdi, pdi\r\n this.pdi = []\r\n this.mdi = []\r\n this.adx = []\r\n let atr = (apdm = amdm = adx = 0)\r\n for (let i = this.period; i < this.data.close.length; i++) {\r\n const deltaHigh = this.data.high[i] - this.data.high[i - 1]\r\n const deltaLow = this.data.low[i - 1] - this.data.low[i]\r\n\r\n let pdm = 0\r\n if (deltaHigh > 0 && deltaHigh > deltaLow) {\r\n pdm = deltaHigh\r\n }\r\n\r\n let mdm = 0\r\n if (deltaLow > 0 && deltaLow > deltaHigh) {\r\n mdm = deltaLow\r\n }\r\n\r\n const tr = utils.max([\r\n this.data.high[i] - this.data.low[i],\r\n Math.abs(this.data.high[i] - this.data.close[i - 1]),\r\n Math.abs(this.data.low[i] - this.data.close[i - 1]),\r\n ])\r\n\r\n atr = (atr * (this.period - 1) + tr) / this.period\r\n apdm = (apdm * (this.period - 1) + pdm) / this.period\r\n amdm = (amdm * (this.period - 1) + mdm) / this.period\r\n\r\n pdi = atr > 0 ? (apdm * 100) / atr : 0\r\n mdi = atr > 0 ? (amdm * 100) / atr : 0\r\n const di = Math.abs(pdi - mdi)\r\n const dx = pdi + mdi > 0 ? (di * 100) / (pdi + mdi) : 0\r\n adx = (adx * (this.period - 1) + dx) / this.period\r\n\r\n this.pdi[i] = pdi\r\n this.mdi[i] = mdi\r\n this.adx[i] = adx\r\n }\r\n this.lastValue = this.adx.last() ?? null\r\n }\r\n const { min, max } =\r\n this.pdi.length > 0 || this.mdi.length > 0 || this.adx.length > 0\r\n ? this.computeVisibleMinMax(this.pdi, this.mdi, this.adx)\r\n : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n if (this.data.close.length === 0) return\r\n\r\n context.translate(0.5, 0.5)\r\n context.set('strokeStyle', '#2eb12e')\r\n context.beginPath()\r\n\r\n const drawInVisibleAreaProps = {\r\n quote: this.data,\r\n scale: this.model.scale,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n fromIndexOffset: this.period,\r\n }\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.pdi[i])))\r\n },\r\n })\r\n\r\n context.stroke()\r\n\r\n context.set('strokeStyle', '#d43737')\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.mdi[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.set('strokeStyle', this.getChartLayoutSettings().IndicatorSettings.general.Colors.line)\r\n context.beginPath()\r\n\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.adx[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `ADX ${this.period}`\r\n }\r\n}\r\n\r\nexport default ADX\r\n","import { IndicatorType } from '../constants/common'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n period: number\r\n}\r\n\r\ntype DefaultCalculatedValuesType = {\r\n aroonUp: number[]\r\n aroonDown: number[]\r\n oscillator: number[]\r\n}\r\n\r\nexport class AroonCalculation extends MainCalculation {\r\n static type = IndicatorType.Aro\r\n\r\n getDefaultCalculatedValues() {\r\n return {\r\n aroonUp: [],\r\n aroonDown: [],\r\n oscillator: [],\r\n }\r\n }\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { period } = this.options\r\n const { low, high } = this.quote\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n for (let i = period; i < high.length; i++) {\r\n const highPeriod = high.slice(i - period, i + 1)\r\n const highestInPeriod = Math.max(...highPeriod)\r\n const periodSinceHigh = period - highPeriod.lastIndexOf(highestInPeriod)\r\n this._calculatedValues.aroonUp[i] = 100 * ((period - periodSinceHigh) / period)\r\n\r\n const lowPeriod = low.slice(i - period, i + 1)\r\n const lowestInPeriod = Math.min(...lowPeriod)\r\n const periodSinceLow = period - lowPeriod.lastIndexOf(lowestInPeriod)\r\n this._calculatedValues.aroonDown[i] = 100 * ((period - periodSinceLow) / period)\r\n\r\n this._calculatedValues.oscillator[i] = this._calculatedValues.aroonUp[i] - this._calculatedValues.aroonDown[i]\r\n\r\n if (onValueCalculated?.(this.calculatedValues, i) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import Text from '../canvas/text'\r\nimport { IndicatorType, OFFSET, PADDING, TextBaseline } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport { AroonCalculation } from '../indicator-calculation/aroon'\r\nimport Pane from '../models/pane'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nconst COLORS = {\r\n aroonUp: '#00a000',\r\n aroonDown: '#c80000',\r\n}\r\n\r\nclass Aroon extends Indicator {\r\n static type = IndicatorType.Aro\r\n static label = 'Aroon'\r\n\r\n aroonCalculation: AroonCalculation | null = null\r\n declare period: number\r\n\r\n constructor(attrs: Attrs, model: Pane) {\r\n super(attrs, model)\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n }\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary() && this.aroonCalculation !== null) return\r\n\r\n this.aroonCalculation = new AroonCalculation({\r\n quote: this.data,\r\n options: { period: this.period },\r\n })\r\n\r\n this.aroonCalculation.calculate()\r\n\r\n const { min, max } = this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n if (this.data.close.length === 0 || !this.aroonCalculation) return\r\n\r\n context.translate(0.5, 0.5)\r\n context.set('strokeStyle', COLORS.aroonUp)\r\n context.beginPath()\r\n const drawInVisibleAreaProps = {\r\n quote: this.data,\r\n scale: this.model.scale,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n fromIndexOffset: this.period,\r\n }\r\n const { aroonUp, aroonDown } = this.aroonCalculation.calculatedValues\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(aroonUp[i])))\r\n },\r\n })\r\n context.stroke()\r\n\r\n context.set('strokeStyle', COLORS.aroonDown)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(aroonDown[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n renderYAxis(context: CanvasRenderingContext2D) {\r\n super.renderYAxis(context)\r\n if (!this.aroonCalculation) return\r\n const { IndicatorSettings, ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const { aroonUp, aroonDown } = this.aroonCalculation.calculatedValues\r\n\r\n const translate = getTranslate({\r\n context,\r\n xOffset: IndicatorSettings.left.width,\r\n yOffset: IndicatorSettings.top.height,\r\n })\r\n translate.do()\r\n const text = new Text(\r\n {\r\n x: this.contentWidth + OFFSET.M - PADDING.XXS + IndicatorSettings.right.axis.margin.left!,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.right.axis.font),\r\n lineHeight: IndicatorSettings.right.axis.font.lineHeight,\r\n padding: {\r\n top: IndicatorSettings.right.axis.font?.padding?.top ?? PADDING.XXS,\r\n right: IndicatorSettings.right.axis.font?.padding?.right ?? PADDING.XXS,\r\n bottom: IndicatorSettings.right.axis.font?.padding?.bottom ?? PADDING.XXS,\r\n left: IndicatorSettings.right.axis.font?.padding?.left ?? PADDING.XXS,\r\n },\r\n textBaseline: TextBaseline.middle,\r\n fillStyle: Colors.indicatorCurrentText,\r\n },\r\n this.model\r\n )\r\n const textLabels = []\r\n if (aroonDown.length > 0) {\r\n textLabels.push({\r\n text: aroonDown.last()!.toFixed(2),\r\n y: Math.round(this.fy(aroonDown.last()!)),\r\n background: COLORS.aroonDown,\r\n })\r\n }\r\n if (aroonUp.length > 0) {\r\n textLabels.push({\r\n text: aroonUp.last()!.toFixed(2),\r\n y: Math.round(this.fy(aroonUp.last()!)),\r\n background: COLORS.aroonUp,\r\n })\r\n }\r\n\r\n const minY = 0\r\n const maxY = this.height - IndicatorSettings.bottom.height - IndicatorSettings.top.height\r\n textLabels.forEach((labelSetting) => {\r\n if (labelSetting.y >= minY && labelSetting.y <= maxY) {\r\n text.set(labelSetting).render(context)\r\n }\r\n })\r\n\r\n translate.undo()\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 25,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `Aroon ${this.period}`\r\n }\r\n}\r\n\r\nexport default Aroon\r\n","import { IndicatorType } from '../constants/common'\r\nimport { AroonCalculation } from '../indicator-calculation/aroon'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass AroonOscillator extends Indicator {\r\n static type = IndicatorType.Aroosc\r\n static label = 'Aroon Oscillator'\r\n\r\n aroonCalculation: AroonCalculation | null = null\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary() && this.aroonCalculation !== null) return\r\n\r\n this.aroonCalculation = new AroonCalculation({\r\n quote: this.data,\r\n options: { period: this.period },\r\n })\r\n\r\n this.aroonCalculation.calculate()\r\n\r\n this.lastValue = this.aroonCalculation.calculatedValues.oscillator.last() ?? null\r\n const { min, max } = this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(\r\n context,\r\n this.aroonCalculation?.calculatedValues.oscillator ?? [],\r\n this.period,\r\n 0,\r\n 0,\r\n 0,\r\n false\r\n )\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 25,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `Aroon Oscillator ${this.period}`\r\n }\r\n}\r\n\r\nexport default AroonOscillator\r\n","import { IndicatorType } from '../constants/common'\r\nimport AverageTrueRange from '../helpers/atr'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass ATR extends Indicator {\r\n static type = IndicatorType.Atr\r\n static label = 'Average True Range'\r\n\r\n atr: number[] = []\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.atr = []\r\n const atr = new AverageTrueRange(this.period)\r\n for (let i = 0; i < this.data.close.length; i++) {\r\n atr.add(this.data.high[i], this.data.low[i], this.data.close[i - 1])\r\n this.atr[i] = atr.value\r\n }\r\n\r\n this.lastValue = this.atr.last() ?? null\r\n }\r\n const { min, max } = this.atr.length > 0 ? this.computeVisibleMinMax(this.atr) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n context.set('strokeStyle', this.getChartLayoutSettings().IndicatorSettings.general.Colors.line)\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n context.lineTo(x, Math.round(this.fy(this.atr[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `ATR ${this.period}`\r\n }\r\n}\r\n\r\nexport default ATR\r\n","import { IndicatorType } from '../constants/common'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nconst constant = 0.015\r\nclass CommodityChannelIndex extends Indicator {\r\n static type = IndicatorType.Cci\r\n static label = 'Commodity Channel Index'\r\n\r\n cci: number[] = []\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n let smaCount\r\n const tp = []\r\n this.cci = []\r\n let smaSum = (smaCount = 0)\r\n for (let i = 0; i < this.data.close.length; i++) {\r\n let devCount\r\n const typicalPrice = (this.data.close[i] + this.data.low[i] + this.data.high[i]) / 3\r\n tp[i] = typicalPrice\r\n\r\n smaSum += typicalPrice\r\n smaCount++\r\n if (smaCount > this.period) {\r\n smaSum -= tp[i - this.period]\r\n smaCount--\r\n }\r\n const sma = smaSum / smaCount\r\n\r\n if (i < this.period - 1) {\r\n continue\r\n }\r\n\r\n let devSum = (devCount = 0)\r\n for (let j = i - this.period + 1; j <= i; j++) {\r\n devSum += Math.abs(tp[j] - sma)\r\n devCount++\r\n }\r\n\r\n const dev = devSum / devCount\r\n this.cci[i] = 0\r\n if (dev > 0) {\r\n this.cci[i] = (typicalPrice - sma) / (constant * dev)\r\n }\r\n }\r\n\r\n this.lastValue = this.cci.last() ?? null\r\n }\r\n\r\n const { min, max } = this.cci.length > 0 ? this.computeVisibleMinMax(this.cci) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.cci, this.period, -100, 0, 100)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 20,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `CCI ${this.period}`\r\n }\r\n}\r\n\r\nexport default CommodityChannelIndex\r\n","import * as d3 from 'd3'\r\n\r\nimport { ObjectHash, Theme } from '../../types/shared'\r\nimport Text from '../canvas/text'\r\nimport tailwindColors from '../constants/colors'\r\nimport { INDICATOR_LABEL_HEIGHT, IndicatorType, TextAlign, TextBaseline } from '../constants/common'\r\nimport utils from '../utils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\nexport interface ICOT {\r\n code: string\r\n name: string\r\n units: string\r\n commercialHedgers: number[]\r\n largeTraders: number[]\r\n smallTraders: number[]\r\n}\r\n\r\ninterface Attrs {\r\n period: string\r\n code: string\r\n}\r\n\r\ntype ColorsKeys = keyof Pick\r\n\r\nclass COT extends Indicator {\r\n static type = IndicatorType.Cot\r\n static label = 'COT'\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n declare colors: ObjectHash\r\n\r\n compute() {\r\n if (!this.isComputeNecessary() || !this.data.COTs) return\r\n const cotQuoteCode = Object.keys(this.data.COTs)[0]\r\n if (!this.attrs.code && cotQuoteCode) {\r\n this.attrs.code = cotQuoteCode\r\n }\r\n const cot = this.data.COTs[this.attrs.code]\r\n const [min, max] = utils.minMax(cot.commercialHedgers, cot.largeTraders, cot.smallTraders)\r\n this.max = Math.max(Math.abs(max), Math.abs(min))\r\n this.min = -this.max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n if (!this.data.COTs) return\r\n context.translate(0.5, 0.5)\r\n for (const key in this.colors) {\r\n context.set('strokeStyle', this.colors[key as ColorsKeys])\r\n context.beginPath()\r\n const data = this.data.COTs[this.attrs.code][key as ColorsKeys]\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n context.lineTo(x, Math.round(this.fy(data[i])))\r\n },\r\n })\r\n context.stroke()\r\n }\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n renderLabel(context: CanvasRenderingContext2D) {\r\n if (!this.data.COTs) return\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const name = new Text(\r\n {\r\n text: this.toString(),\r\n x: 8,\r\n y: 16,\r\n font: { size: 10, style: 'bold' },\r\n fillStyle: Colors.text,\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.bottom,\r\n },\r\n this.model\r\n )\r\n name.render(context)\r\n\r\n new Text(\r\n {\r\n text: this.data.COTs[this.attrs.code].units as string,\r\n x: 38 + name.measure(),\r\n y: 16,\r\n font: { size: 8 },\r\n fillStyle: Colors.text,\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.bottom,\r\n },\r\n this.model\r\n ).render(context)\r\n\r\n this.renderAdditionalLabels(context)\r\n }\r\n\r\n renderLabelChartsPage(context: CanvasRenderingContext2D) {\r\n const { x, y, labelWidth } = super.renderLabelChartsPage(context) as { x: number; y: number; labelWidth: number }\r\n\r\n const { IndicatorSettings } = this.getChartLayoutSettings()\r\n const isDarkMode = this.model.chart().chart_layout().theme === Theme.dark\r\n const secondarylabelX = labelWidth + x * 2\r\n const fontSettings = IndicatorSettings.left.indicatorLabel.font\r\n const scaleCoefficient = 0.7\r\n\r\n const secondarylabel = new Text(\r\n {\r\n text: this.data.COTs[this.attrs.code].units as string,\r\n x: secondarylabelX + x,\r\n font: Text.getMergedPropsWithDefaults('font', {\r\n ...fontSettings,\r\n size: fontSettings.size ? fontSettings.size * scaleCoefficient : undefined,\r\n style: 'normal',\r\n }),\r\n fillStyle: tailwindColors.gray[isDarkMode ? 50 : 900],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.middle,\r\n },\r\n this.model\r\n )\r\n secondarylabel.set({\r\n y: y + (INDICATOR_LABEL_HEIGHT * scaleCoefficient - (secondarylabel.attrs.lineHeight * scaleCoefficient) / 2),\r\n })\r\n secondarylabel.render(context)\r\n\r\n this.renderAdditionalLabels(context)\r\n }\r\n\r\n renderAdditionalLabels(context: CanvasRenderingContext2D) {\r\n const { ChartSettings, IndicatorSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n\r\n new Text(\r\n {\r\n text: 'COT',\r\n x: 23,\r\n y: IndicatorSettings.top.height + (IndicatorSettings.bottom.height + this.contentHeight) / 2,\r\n angle: -90,\r\n font: { size: 10, weight: '900', family: 'Lato, sans-serif' },\r\n fillStyle: Colors.textSecondary,\r\n textAlign: TextAlign.center,\r\n textBaseline: TextBaseline.alphabetic,\r\n },\r\n this.model\r\n ).render(context)\r\n\r\n const text = new Text(\r\n {\r\n text: 'Commercial Hedgers',\r\n x: IndicatorSettings.left.width,\r\n y: IndicatorSettings.top.height + this.contentHeight + IndicatorSettings.bottom.height - 1, // allign to very bottom of indicator with 1 pixel bottom padding\r\n font: { size: 8, style: 'bold' },\r\n fillStyle: this.colors.commercialHedgers,\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.bottom,\r\n },\r\n this.model\r\n )\r\n text.render(context)\r\n\r\n let x = text.get('x')! + 8 + text.measure()\r\n text.set({ text: 'Large Traders', x, fillStyle: this.colors.largeTraders })\r\n text.render(context)\r\n\r\n x += 8 + text.measure()\r\n text.set({ text: 'Small Traders', x, fillStyle: this.colors.smallTraders })\r\n text.render(context)\r\n }\r\n\r\n formatAxis(value: number) {\r\n // https://github.com/d3/d3-format/blob/master/README.md#locale_formatPrefix\r\n const scaleY = this.model.scale.y as unknown as d3.ScaleLinear\r\n return scaleY.tickFormat(4, 's')(value).replace(/G/, 'B')\r\n }\r\n\r\n getModalConfig() {\r\n return {\r\n title: 'COT',\r\n inputs: [],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n toString() {\r\n return this.data?.COTs ? (this.data.COTs[this.attrs.code].name as string) : undefined\r\n }\r\n\r\n toConfig(): T['attrs'] & { type: T['type'] } {\r\n return {\r\n type: this.type,\r\n code: this.attrs.code,\r\n }\r\n }\r\n}\r\n\r\nCOT.prototype.colors = {\r\n commercialHedgers: '#10cc10',\r\n largeTraders: '#cc1010',\r\n smallTraders: '#1010cc',\r\n}\r\n\r\nexport default COT\r\n","import { IndicatorType } from '../constants/common'\r\nimport { ExponentialMovingAverage } from './ema'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n period: number\r\n}\r\n\r\ntype DefaultCalculatedValuesType = {\r\n fi: number[]\r\n}\r\n\r\nexport class FICalculation extends MainCalculation {\r\n static type = IndicatorType.Fi\r\n\r\n getDefaultCalculatedValues() {\r\n return { fi: [] }\r\n }\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { period } = this.options\r\n const { close, volume } = this.quote\r\n const ema = new ExponentialMovingAverage(period)\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n for (let index = 1; index < close.length; index++) {\r\n const value = ((close[index] - close[index - 1]) * volume[index]) / 1000000\r\n ema.add(value)\r\n this.calculatedValues.fi[index] = ema.value\r\n\r\n if (onValueCalculated?.(this.calculatedValues, index) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import { IndicatorType } from '../constants/common'\r\nimport { FICalculation } from '../indicator-calculation/fi'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass ForceIndex extends Indicator {\r\n static type = IndicatorType.Fi\r\n static label = 'Force Index'\r\n\r\n fiCalculation: FICalculation | null = null\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.fiCalculation = new FICalculation({\r\n quote: this.data,\r\n options: {\r\n period: this.period,\r\n },\r\n })\r\n this.fiCalculation.calculate()\r\n this.lastValue = this.fiCalculation.calculatedValues.fi.last() ?? null\r\n }\r\n const fi = this.fiCalculation?.calculatedValues.fi ?? []\r\n const { min, max } = fi.length > 0 ? this.computeVisibleMinMax(fi) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.fiCalculation?.calculatedValues.fi ?? [], 1, 0, 0, 0, false)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 13,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `FORCE ${this.period}`\r\n }\r\n}\r\n\r\nexport default ForceIndex\r\n","import { IndicatorType } from '../constants/common'\r\nimport { ExponentialMovingAverage } from './ema'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n fastPeriod: number\r\n slowPeriod: number\r\n signalPeriod: number\r\n}\r\n\r\ntype DefaultCalculatedValuesType = {\r\n macd: number[]\r\n signal: number[]\r\n histogram: number[]\r\n}\r\n\r\nexport class MACDCalculation extends MainCalculation {\r\n static type = IndicatorType.Macd\r\n\r\n getDefaultCalculatedValues() {\r\n return {\r\n macd: [],\r\n signal: [],\r\n histogram: [],\r\n }\r\n }\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { close } = this.quote\r\n const { fastPeriod, slowPeriod, signalPeriod } = this.options\r\n const emaFast = new ExponentialMovingAverage(fastPeriod)\r\n const emaSlow = new ExponentialMovingAverage(slowPeriod)\r\n const emaSignal = new ExponentialMovingAverage(signalPeriod)\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n for (let i = 0; i < close.length; i++) {\r\n const d = close[i]\r\n\r\n emaFast.add(d)\r\n emaSlow.add(d)\r\n const macd = emaFast.value - emaSlow.value\r\n emaSignal.add(macd)\r\n\r\n this.calculatedValues.macd[i] = macd\r\n this.calculatedValues.signal[i] = emaSignal.value\r\n this.calculatedValues.histogram[i] = macd - emaSignal.value\r\n\r\n if (onValueCalculated?.(this.calculatedValues, i) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { IndicatorType } from '../constants/common'\r\nimport { MACDCalculation } from '../indicator-calculation/macd'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n fastPeriod: number\r\n slowPeriod: number\r\n signalPeriod: number\r\n}\r\n\r\nclass MACD extends Indicator {\r\n static type = IndicatorType.Macd\r\n static label = 'MACD'\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [fastPeriod = 0, slowPeriod = 0, signalPeriod = 0] = getParsedIntegersFromPeriodString(period)\r\n return Math.max(fastPeriod, slowPeriod, signalPeriod)\r\n }\r\n\r\n macdCalculation: MACDCalculation | null = null\r\n\r\n declare fastPeriod: number\r\n declare slowPeriod: number\r\n declare signalPeriod: number\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [fastPeriod = 0, slowPeriod = 0, signalPeriod = 0] = getParsedIntegersFromPeriodString(this.attrs.period)\r\n super.set({ ...values, fastPeriod, slowPeriod, signalPeriod })\r\n } else {\r\n super.set(values)\r\n }\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary() || this.macdCalculation === null) {\r\n this.macdCalculation = new MACDCalculation({\r\n quote: this.data,\r\n options: {\r\n signalPeriod: this.signalPeriod,\r\n fastPeriod: this.fastPeriod,\r\n slowPeriod: this.slowPeriod,\r\n },\r\n })\r\n this.macdCalculation.calculate()\r\n\r\n this.lastValue = this.macdCalculation.calculatedValues.macd.last() ?? null\r\n }\r\n\r\n const { macd, histogram, signal } = this.macdCalculation.calculatedValues\r\n\r\n const { min, max } =\r\n macd.length > 0 || signal.length > 0 || histogram.length > 0\r\n ? this.computeVisibleMinMax(macd, signal, histogram)\r\n : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n const { IndicatorSettings, ChartSettings } = this.getChartLayoutSettings()\r\n if (this.macdCalculation === null || this.data.close.length === 0) return\r\n const y = Math.round(this.fy(0))\r\n const w = ChartSettings.center.barWidth + ChartSettings.center.border * 2\r\n const { macd, histogram, signal } = this.macdCalculation.calculatedValues\r\n const drawInVisibleAreaProps = {\r\n quote: this.data,\r\n scale: this.model.scale,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n }\r\n\r\n context.set('fillStyle', '#79c3e8')\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.rect(x - ~~(ChartSettings.center.barWidth / 2), y, w, Math.round(this.fy(histogram[i]) - y))\r\n },\r\n })\r\n context.fill()\r\n\r\n context.translate(0.5, 0.5)\r\n context.set('strokeStyle', IndicatorSettings.general.Colors.line)\r\n context.beginPath()\r\n\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(macd[i])))\r\n },\r\n })\r\n context.stroke()\r\n\r\n context.set('strokeStyle', IndicatorSettings.general.Colors.signalLine)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(signal[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const fastPeriod = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'fastPeriod',\r\n value: this.fastPeriod ?? 12,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const slowPeriod = {\r\n type: 'number',\r\n label: 'Slow',\r\n name: 'slowPeriod',\r\n value: this.slowPeriod ?? 26,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const signalPeriod = {\r\n type: 'number',\r\n label: 'Signal',\r\n name: 'signalPeriod',\r\n value: this.signalPeriod ?? 9,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [fastPeriod, slowPeriod, signalPeriod],\r\n inputsErrorMessages: {\r\n fastPeriod: `${fastPeriod.label} must be a whole number between ${fastPeriod.min} and ${fastPeriod.max}`,\r\n slowPeriod: `${slowPeriod.label} must be a whole number between ${slowPeriod.min} and ${slowPeriod.max}`,\r\n signalPeriod: `${signalPeriod.label} must be a whole number between ${signalPeriod.min} and ${signalPeriod.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'fastPeriod':\r\n case 'slowPeriod':\r\n case 'signalPeriod':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `MACD ${this.fastPeriod},${this.slowPeriod},${this.signalPeriod}`\r\n }\r\n}\r\n\r\nexport default MACD\r\n","import { IndicatorType } from '../constants/common'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass MFI extends Indicator {\r\n static type = IndicatorType.Mfi\r\n static label = 'Money Flow Index'\r\n\r\n mfi: number[] = []\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary()) return\r\n\r\n let negativeMoneyFlow\r\n const mf = []\r\n this.mfi = []\r\n let prevTypicalPrice = (this.data.close[0] + this.data.low[0] + this.data.high[0]) / 3\r\n let positiveMoneyFlow = (negativeMoneyFlow = 0)\r\n for (let i = 1; i < this.data.close.length; i++) {\r\n const typicalPrice = (this.data.close[i] + this.data.low[i] + this.data.high[i]) / 3\r\n const moneyFlow = typicalPrice * this.data.volume[i]\r\n\r\n if (typicalPrice > prevTypicalPrice) {\r\n positiveMoneyFlow += moneyFlow\r\n mf[i] = moneyFlow\r\n } else if (typicalPrice < prevTypicalPrice) {\r\n negativeMoneyFlow += moneyFlow\r\n mf[i] = -moneyFlow\r\n }\r\n\r\n if (i > this.period) {\r\n const oldMF = mf[i - this.period]\r\n if (oldMF > 0) {\r\n positiveMoneyFlow -= oldMF\r\n } else if (oldMF < 0) {\r\n negativeMoneyFlow += oldMF\r\n }\r\n\r\n if (positiveMoneyFlow + negativeMoneyFlow > 0) {\r\n this.mfi[i] = (positiveMoneyFlow * 100) / (positiveMoneyFlow + negativeMoneyFlow)\r\n } else {\r\n this.mfi[i] = 50\r\n }\r\n }\r\n\r\n prevTypicalPrice = typicalPrice\r\n }\r\n\r\n this.lastValue = this.mfi.last() ?? null\r\n const { min, max } = this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.mfi, this.period, 20, 50, 80)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `MFI ${this.period}`\r\n }\r\n}\r\n\r\nexport default MFI\r\n","import { IndicatorType } from '../constants/common'\r\nimport Indicator from './indicator'\r\n\r\nclass None extends Indicator {\r\n static type = IndicatorType.None\r\n static label = 'None'\r\n\r\n compute() {}\r\n\r\n renderIndicator() {}\r\n\r\n toString() {\r\n return ''\r\n }\r\n}\r\n\r\nexport default None\r\n","import { IndicatorType } from '../constants/common'\r\nimport math from '../helpers/math'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\nclass OBV extends Indicator {\r\n static type = IndicatorType.Obv\r\n static label = 'On-Balance Volume'\r\n\r\n obv: number[] = []\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.obv = [0]\r\n\r\n for (let i = 1; i < this.data.volume.length; i++) {\r\n let currentObv = this.obv[i - 1]\r\n if (this.data.close[i] > this.data.close[i - 1]) {\r\n currentObv += this.data.volume[i]\r\n } else if (this.data.close[i] < this.data.close[i - 1]) {\r\n currentObv -= this.data.volume[i]\r\n }\r\n\r\n this.obv[i] = currentObv\r\n }\r\n\r\n this.lastValue = this.obv.last() ?? null\r\n }\r\n const { min, max } = this.obv.length > 0 ? this.computeVisibleMinMax(this.obv) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n context.set('strokeStyle', this.getChartLayoutSettings().IndicatorSettings.general.Colors.line)\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n context.lineTo(x, Math.round(this.fy(this.obv[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n formatAxis(value: number) {\r\n return math.formatBigNumber(value, 2)\r\n }\r\n\r\n getModalConfig() {\r\n return {\r\n title: this.label,\r\n inputs: [],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n toString() {\r\n return 'OBV'\r\n }\r\n}\r\n\r\nexport default OBV\r\n","import * as d3 from 'd3'\r\n\r\nimport { ObjectHash } from '../../types/shared'\r\nimport Line from '../canvas/line'\r\nimport Text from '../canvas/text'\r\nimport {\r\n INDICATOR_LABEL_HEIGHT,\r\n IndicatorType,\r\n MOBILE_VIEW_BREAKPOINT_WIDTH,\r\n OFFSET,\r\n PADDING,\r\n TextAlign,\r\n TextBaseline,\r\n} from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport Pane from '../models/pane'\r\nimport Quote from '../models/quote'\r\nimport { getSanitizedTicker } from '../utils'\r\nimport { getInstrument } from '../utils/chart'\r\nimport { getHEXWithSpecificAplha } from '../utils/colors'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n tickers?: string\r\n}\r\n\r\nconst DEFAULT_TICKERS = 'SPY,QQQ'\r\n\r\nclass PricePerformance extends Indicator {\r\n static type = IndicatorType.Perf\r\n static label = 'Price Performance %'\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n timeframe: string\r\n tickers = ''\r\n ready = false\r\n firstFetchCalled = false\r\n first: ObjectHash = {}\r\n perf: ObjectHash = {}\r\n quotes: ObjectHash = {}\r\n indicatorLabelWidth: ObjectHash = {}\r\n\r\n constructor(attrs: Attrs, model: Pane) {\r\n super(attrs, model)\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n\r\n this.timeframe = this.model.chart().timeframe\r\n this.fy = d3.scaleLinear().range([0, this.contentHeight])\r\n if (this.attrs.period && !this.tickers) {\r\n this.tickers = this.attrs.period\r\n }\r\n }\r\n\r\n async compute() {\r\n const tickers = this.getTickers()\r\n const chartLayoutModel = this.model.chart().chart_layout()\r\n const chartUuid = chartLayoutModel.uuid\r\n const hasCachedData = this.getTickersAndTimeframe().every(\r\n ({ ticker, instrument, timeframe }) =>\r\n Quote.select(\r\n (q: Quote) =>\r\n q.ticker === ticker &&\r\n q.instrument === instrument &&\r\n q.timeframe === timeframe &&\r\n chartLayoutModel.isIdeaId(q.ideaID) &&\r\n chartUuid === q.chartUuid &&\r\n !q.isFetching\r\n ).length > 0\r\n )\r\n\r\n if (this.timeframe !== this.model.chart().quote().timeframe || (!this.ready && !this.firstFetchCalled)) {\r\n this.timeframe = this.model.chart().quote().timeframe\r\n this.firstFetchCalled = true\r\n\r\n if (!hasCachedData) {\r\n const data = await Quote.getAll(this.getTickersAndTimeframe())\r\n if (data) {\r\n this._compute(tickers, data)\r\n this.trigger('change')\r\n }\r\n } else {\r\n this.ready = true\r\n this.compute()\r\n }\r\n } else if (this.ready) {\r\n const data: ObjectHash = {}\r\n for (const ticker of tickers) {\r\n data[ticker] = Quote.select(\r\n (q: Quote) =>\r\n q.ticker === ticker &&\r\n q.timeframe === this.timeframe &&\r\n chartUuid === q.chartUuid &&\r\n chartLayoutModel.isIdeaId(q.ideaID)\r\n )[0]\r\n }\r\n this._compute(tickers, data)\r\n }\r\n }\r\n\r\n _compute(tickers: string[], data: ObjectHash) {\r\n const { leftOffset } = this.model.chart()\r\n let firstBarTime = null\r\n let lastBarTime = null\r\n for (let i = 0; i < this.data.close.length; i++) {\r\n const center = this.fx(i)\r\n if (center + leftOffset < 0 || center + leftOffset > this.contentWidth) {\r\n // margin?\r\n continue\r\n }\r\n\r\n // Rendering one extra bar out of viewport ensures continuity of line, if there are missing data on intraday the indicator may have gaps\r\n if (firstBarTime === null) {\r\n firstBarTime = this.data.date[i]\r\n }\r\n\r\n lastBarTime = this.data.date[i]\r\n }\r\n\r\n data[this.data.ticker] = this.data\r\n this.quotes = data\r\n this.perf = {}\r\n const dateToIndex = this.data.getDateToIndex()\r\n for (const ticker of [this.data.ticker, ...tickers]) {\r\n this.perf[ticker] = []\r\n const d = data[ticker]\r\n if (!d) {\r\n continue\r\n }\r\n let first = null\r\n let index = -1\r\n for (let i = 0; i < d.close.length; i++) {\r\n const date = d.date[i]\r\n if (date < firstBarTime! || date > lastBarTime!) {\r\n continue\r\n }\r\n\r\n index = dateToIndex[date]\r\n if (index === undefined || index === null) {\r\n continue\r\n }\r\n\r\n if (first === null) {\r\n first = d.close[i]\r\n this.first[ticker] = first\r\n if (index > 0) {\r\n this.perf[ticker][index - 1] = (d.close[i] * 100) / first - 100\r\n }\r\n }\r\n\r\n this.perf[ticker][index] = (d.close[i] * 100) / first - 100\r\n }\r\n\r\n if (index < this.data.date.length - 1 && first !== null) {\r\n this.perf[ticker][index + 1] = this.perf[ticker][index]\r\n }\r\n }\r\n\r\n const perfArrays = Object.keys(this.perf).map((x) => this.perf[x])\r\n const { min, max } = perfArrays.some((array) => array.length > 0)\r\n ? this.computeVisibleMinMax(...perfArrays)\r\n : this.getDomainDefaults(this.type)\r\n\r\n this.min = min\r\n this.max = max\r\n\r\n const fy = d3\r\n .scaleLinear()\r\n .range([0, this.contentHeight])\r\n .domain([this.model.scaleRange?.max ?? this.max, this.model.scaleRange?.min ?? this.min])\r\n if (!this.model.scaleRange) {\r\n fy.nice(10)\r\n }\r\n // @ts-expect-error - TODO scale.y types dont match\r\n this.model.scale.y = this.fy = fy\r\n this.ready = true\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n if (!this.ready) {\r\n return\r\n }\r\n const { ColorsSettings, IndicatorSettings } = this.getChartLayoutSettings()\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(0)),\r\n y2: Math.round(this.fy(0)),\r\n strokeStyle: '#ff8787',\r\n dashLength: 3,\r\n },\r\n this.model\r\n ).render(context)\r\n\r\n context.translate(0.5, 0.5)\r\n const iterable = this.getTickers()\r\n for (let index = 0; index < iterable.length; index++) {\r\n const ticker = iterable[index]\r\n if (this.perf[ticker].length > 0) {\r\n context.set('strokeStyle', ColorsSettings[index % ColorsSettings.length])\r\n context.beginPath()\r\n for (let i = 0; i < this.perf[ticker].length; i++) {\r\n const y = Math.round(this.fy(this.perf[ticker][i]))\r\n context.lineTo(this.fx(i), y)\r\n }\r\n context.stroke()\r\n }\r\n }\r\n\r\n context.set('strokeStyle', IndicatorSettings.general.Colors.line)\r\n context.beginPath()\r\n for (let i = 0; i < this.perf[this.data.ticker].length; i++) {\r\n const y = Math.round(this.fy(this.perf[this.data.ticker][i]))\r\n if (!isNaN(y)) {\r\n context.lineTo(this.fx(i), y)\r\n }\r\n }\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n renderCrossTextQuotePage(context: CanvasRenderingContext2D, crossIndex: number) {\r\n if (!context || !crossIndex) {\r\n return\r\n }\r\n const { ColorsSettings, ChartSettings, IndicatorSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const tickers = [this.data.ticker, ...this.getTickers()]\r\n tickers.forEach((key, index) => {\r\n const crossIndexTickerTimeStamp = this.quotes?.[this.data.ticker]?.getDataByBarIndex('date', crossIndex)\r\n const tickerDateToIndex = crossIndexTickerTimeStamp\r\n ? this.quotes?.[key]?.getDateToIndex()?.[crossIndexTickerTimeStamp]\r\n : null\r\n const tickerPerformance = tickerDateToIndex\r\n ? (this.quotes?.[key]?.close?.[tickerDateToIndex] * 100) / this.first[key] - 100\r\n : null\r\n if (tickerPerformance !== null && !isNaN(tickerPerformance)) {\r\n context.fillStyle = Colors.canvasFill\r\n context.fillRect(\r\n IndicatorSettings.left.indicatorLabel.margin.left! - PADDING.XXXS,\r\n (IndicatorSettings.left.indicatorLabel.font.lineHeight! +\r\n IndicatorSettings.left.indicatorLabel.labelSpacing) *\r\n (index + 1) +\r\n IndicatorSettings.left.indicatorLabel.margin.top! -\r\n PADDING.XXXS,\r\n PADDING.XXXS + this.indicatorLabelWidth[key] + PADDING.XXXS,\r\n PADDING.XXXS + IndicatorSettings.left.indicatorLabel.font.size! + PADDING.XXXS\r\n )\r\n new Text(\r\n {\r\n text: `${key} ${tickerPerformance.toFixed(2)}%`,\r\n x: IndicatorSettings.left.indicatorLabel.margin.left,\r\n y:\r\n (IndicatorSettings.left.indicatorLabel.font.lineHeight! +\r\n IndicatorSettings.left.indicatorLabel.labelSpacing) *\r\n (index + 1) +\r\n IndicatorSettings.left.indicatorLabel.margin.top!,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.left.indicatorLabel.font),\r\n fillStyle:\r\n index === 0 ? Colors.performanceIndicatorLabel : ColorsSettings[index - (1 % ColorsSettings.length)],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n })\r\n }\r\n\r\n renderCrossTextChartsPage(context: CanvasRenderingContext2D, crossIndex: number) {\r\n if (!context || !crossIndex) {\r\n return\r\n }\r\n\r\n const { ColorsSettings, ChartSettings, IndicatorSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n let isVertical = true\r\n const labelBottom = IndicatorSettings.left.indicatorLabel.margin.top! + INDICATOR_LABEL_HEIGHT\r\n const tickers = [this.data.ticker, ...this.getTickers()]\r\n const tickerText = new Text(\r\n {\r\n font: Text.getMergedPropsWithDefaults('font', {\r\n ...IndicatorSettings.left.indicatorLabel.font,\r\n style: 'normal',\r\n }),\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.middle,\r\n background: getHEXWithSpecificAplha(Colors.canvasFill, 0.8),\r\n padding: { top: 0, bottom: 0, left: 5, right: 5 },\r\n },\r\n this.model\r\n )\r\n let x = IndicatorSettings.left.indicatorLabel.margin.left!\r\n let y =\r\n IndicatorSettings.left.indicatorLabel.margin.top! + (2 * INDICATOR_LABEL_HEIGHT - tickerText.attrs.lineHeight) / 2\r\n\r\n const maxHeight = tickerText.attrs.lineHeight * tickers.length\r\n\r\n const canFitItemsVertically = maxHeight + labelBottom <= this.height\r\n if (this.width <= MOBILE_VIEW_BREAKPOINT_WIDTH || !canFitItemsVertically) {\r\n isVertical = false\r\n x += x + this.labelWidth\r\n } else {\r\n y += IndicatorSettings.left.indicatorLabel.margin.top! + INDICATOR_LABEL_HEIGHT\r\n }\r\n\r\n const tickerQuote = this.quotes?.[this.data.ticker]\r\n const maxCrossIndex = Math.min(crossIndex, (tickerQuote?.close.length ?? Infinity) - 1)\r\n tickers.forEach((key, index) => {\r\n const crossIndexTickerTimeStamp = tickerQuote?.getDataByBarIndex('date', maxCrossIndex)\r\n const tickerDateToIndex = crossIndexTickerTimeStamp\r\n ? this.quotes?.[key]?.getDateToIndex()?.[crossIndexTickerTimeStamp]\r\n : null\r\n const tickerPerformance = tickerDateToIndex\r\n ? (this.quotes?.[key]?.close?.[tickerDateToIndex] * 100) / this.first[key] - 100\r\n : null\r\n if (tickerPerformance !== null && !isNaN(tickerPerformance)) {\r\n tickerText.set({\r\n x,\r\n y,\r\n fillStyle:\r\n index === 0 ? Colors.performanceIndicatorLabel : ColorsSettings[index - (1 % ColorsSettings.length)],\r\n text: `${key} ${tickerPerformance.toFixed(2)}%`,\r\n })\r\n const tickerTextWidth =\r\n tickerText.measure(context) + tickerText.attrs.padding.left + tickerText.attrs.padding.right\r\n if (\r\n !isVertical &&\r\n this.width - IndicatorSettings.left.indicatorLabel.margin.left! - IndicatorSettings.right.width! <=\r\n x + tickerTextWidth\r\n ) {\r\n x = 2 * IndicatorSettings.left.indicatorLabel.margin.left! + this.labelWidth\r\n y += tickerText.attrs.lineHeight\r\n tickerText.set({ x, y })\r\n }\r\n tickerText.render(context)\r\n\r\n if (isVertical) {\r\n y += tickerText.attrs.lineHeight\r\n } else {\r\n x += tickerTextWidth\r\n }\r\n }\r\n })\r\n }\r\n\r\n renderXAxis(context: CanvasRenderingContext2D) {\r\n if (!this.ready) {\r\n return\r\n }\r\n return super.renderXAxis(context)\r\n }\r\n\r\n renderYAxis(context: CanvasRenderingContext2D) {\r\n let ticker\r\n super.renderYAxis(context)\r\n const { IndicatorSettings, ChartSettings, ColorsSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n if (!this.ready) {\r\n return\r\n }\r\n if (this.perf[this.data.ticker].length === 0) {\r\n return\r\n }\r\n const translate = getTranslate({\r\n context,\r\n xOffset: IndicatorSettings.left.width,\r\n yOffset: IndicatorSettings.top.height,\r\n })\r\n translate.do()\r\n const { lineHeight, padding, size } = IndicatorSettings.right.axis.font\r\n const text = new Text(\r\n {\r\n x: this.contentWidth + OFFSET.M - padding!.left! + IndicatorSettings.right.axis.margin.left!,\r\n font: Text.getMergedPropsWithDefaults('font', { size }),\r\n lineHeight,\r\n padding: {\r\n left: padding!.left!,\r\n right: padding!.right!,\r\n top: padding!.top!,\r\n bottom: padding!.bottom!,\r\n },\r\n textBaseline: TextBaseline.middle,\r\n fillStyle: Colors.crossText,\r\n },\r\n this.model\r\n )\r\n const iterable = this.getTickers()\r\n const textLabels = []\r\n for (let index = 0; index < iterable.length; index++) {\r\n ticker = iterable[index]\r\n if (this.perf[ticker].length > 0) {\r\n textLabels.push({\r\n text: this.perf[ticker].last().toFixed(2) + '%',\r\n y: Math.round(this.fy(this.perf[ticker].last())),\r\n background: ColorsSettings[index % ColorsSettings.length],\r\n })\r\n }\r\n }\r\n textLabels.push({\r\n text: this.perf[this.data.ticker].last().toFixed(2) + '%',\r\n y: Math.round(this.fy(this.perf[this.data.ticker].last())),\r\n background: Colors.performanceIndicatorLabel,\r\n })\r\n\r\n const minY = 0\r\n const maxY = this.contentHeight\r\n textLabels.forEach((labelSetting) => {\r\n if (labelSetting.y >= minY && labelSetting.y <= maxY) {\r\n text.set(labelSetting).render(context)\r\n }\r\n })\r\n\r\n translate.undo()\r\n }\r\n\r\n renderLabelQuotePage(context: CanvasRenderingContext2D) {\r\n super.renderLabelQuotePage(context)\r\n const { ColorsSettings, ChartSettings, IndicatorSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n if (this.ready) {\r\n const tickers = this.getTickers()\r\n const tickerPerformance = [\r\n { [this.data.ticker]: this.perf[this.data.ticker][this.perf[this.data.ticker].length - 1] },\r\n ...tickers.map((ticker) => ({ [ticker]: this.perf[ticker][this.perf[ticker].length - 1] })),\r\n ].reduce((prev, current) => ({ ...prev, ...current }), {})\r\n Object.keys(tickerPerformance).forEach((key, index) => {\r\n if (tickerPerformance[key]) {\r\n const text = new Text(\r\n {\r\n text: `${key} ${tickerPerformance[key].toFixed(2)}%`,\r\n x: IndicatorSettings.left.indicatorLabel.margin.left,\r\n y:\r\n (IndicatorSettings.left.indicatorLabel.font.lineHeight! +\r\n IndicatorSettings.left.indicatorLabel.labelSpacing) *\r\n (index + 1) +\r\n IndicatorSettings.left.indicatorLabel.margin.top!,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.left.indicatorLabel.font),\r\n fillStyle:\r\n index === 0 ? Colors.performanceIndicatorLabel : ColorsSettings[index - (1 % ColorsSettings.length)],\r\n textAlign: TextAlign.left,\r\n textBaseline: TextBaseline.top,\r\n },\r\n this.model\r\n )\r\n this.indicatorLabelWidth = { ...this.indicatorLabelWidth, [key]: text.measure(context) }\r\n text.render(context)\r\n }\r\n })\r\n }\r\n }\r\n\r\n getTickers() {\r\n return this.tickers\r\n .split(',')\r\n .map((ticker) => ticker)\r\n .filter((x) => x)\r\n }\r\n\r\n getTickersAndTimeframe() {\r\n const { timeframe } = this.model.chart().quote()\r\n return this.getTickers().map((ticker) => ({\r\n ticker,\r\n instrument: getInstrument(ticker),\r\n timeframe,\r\n }))\r\n }\r\n\r\n set(values: Partial) {\r\n this.ready = false\r\n this.firstFetchCalled = false\r\n super.set({ ...values, tickers: values.period || (values.tickers ? getSanitizedTicker(values.tickers, true) : '') })\r\n this.tickers = (this.tickers || '').toUpperCase()\r\n }\r\n\r\n getModalConfig() {\r\n return {\r\n title: this.label,\r\n inputs: [\r\n {\r\n type: 'text',\r\n label: 'Tickers',\r\n name: 'tickers',\r\n value: !!this.tickers ? this.tickers : DEFAULT_TICKERS,\r\n required: true,\r\n },\r\n ],\r\n inputsErrorMessages: {\r\n tickers: 'At least one ticker has to be provided',\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'tickers':\r\n return this[key].length > 0\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return this.getIsChartPageSpecificFunctionality() ? 'PERF %' : `PERF% ${this.tickers}`\r\n }\r\n}\r\n\r\nexport default PricePerformance\r\n","import { IndicatorType } from '../constants/common'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: number | string\r\n momentum: number\r\n}\r\n\r\nclass RMI extends Indicator {\r\n static type = IndicatorType.Rmi\r\n static label = 'Relative Momentum Index'\r\n\r\n rmi: number[] = []\r\n declare momentum: number\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [period = 0, momentum = 0] = getParsedIntegersFromPeriodString(values.period)\r\n super.set({ ...values, period, momentum })\r\n } else {\r\n super.set(values)\r\n }\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary()) return\r\n\r\n this.rmi = []\r\n let count = 0\r\n let sumu = 0\r\n let sumd = 0\r\n let u: number, d: number, ad: number, au: number\r\n for (let i = this.momentum; i < this.data.close.length; i++) {\r\n u = d = 0\r\n if (this.data.close[i] > this.data.close[i - this.momentum]) {\r\n u = this.data.close[i] - this.data.close[i - this.momentum]\r\n }\r\n if (this.data.close[i] < this.data.close[i - this.momentum]) {\r\n d = this.data.close[i - this.momentum] - this.data.close[i]\r\n }\r\n\r\n if (count < this.period) {\r\n sumu += u\r\n sumd += d\r\n count++\r\n au = sumu / count\r\n ad = sumd / count\r\n } else {\r\n au = (au! * (this.period - 1) + u) / this.period\r\n ad = (ad! * (this.period - 1) + d) / this.period\r\n }\r\n\r\n const rs = ad > 0 ? au / ad : 1\r\n this.rmi[i] = 100 - 100 * (1 / (1 + rs))\r\n }\r\n\r\n this.lastValue = this.rmi.last() ?? null\r\n const { min, max } = this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.rmi, this.momentum, 30, 50, 70)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 20,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const momentum = {\r\n type: 'number',\r\n label: 'Momentum',\r\n name: 'momentum',\r\n value: this.momentum ?? 5,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, momentum],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n momentum: `${momentum.label} must be a whole number between ${momentum.min} and ${momentum.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n case 'momentum':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `RMI ${this.period},${this.momentum}`\r\n }\r\n}\r\n\r\nexport default RMI\r\n","import Line from '../canvas/line'\r\nimport { IndicatorType } from '../constants/common'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass ROC extends Indicator {\r\n static type = IndicatorType.Roc\r\n static label = 'Rate of Change %'\r\n\r\n roc: number[] = []\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.roc = []\r\n for (let i = this.period; i < this.data.close.length; i++) {\r\n this.roc[i] = ((this.data.close[i] - this.data.close[i - this.period]) / this.data.close[i - this.period]) * 100\r\n }\r\n\r\n this.lastValue = this.roc.last() ?? null\r\n }\r\n const { min, max } = this.roc.length > 0 ? this.computeVisibleMinMax(this.roc) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(0)),\r\n y2: Math.round(this.fy(0)),\r\n strokeStyle: '#ff8787',\r\n dashLength: 3,\r\n },\r\n this.model\r\n ).render(context)\r\n context.set('strokeStyle', this.getChartLayoutSettings().IndicatorSettings.general.Colors.line)\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n context.lineTo(x, Math.round(this.fy(this.roc[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 12,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `ROC ${this.period}`\r\n }\r\n}\r\n\r\nexport default ROC\r\n","import { IndicatorType } from '../constants/common'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n period: number\r\n}\r\n\r\ntype DefaultCalculatedValuesType = {\r\n rsi: number[]\r\n}\r\n\r\nexport class RsiCalculation extends MainCalculation {\r\n static type = IndicatorType.Rsi\r\n\r\n getDefaultCalculatedValues() {\r\n return { rsi: [] }\r\n }\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { period } = this.options\r\n const { close } = this.quote\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n let sumu = 0\r\n let sumd = 0\r\n let u: number, d: number, ad: number, au: number\r\n for (let i = 1; i < close.length; i++) {\r\n u = d = 0\r\n if (close[i] > close[i - 1]) {\r\n u = close[i] - close[i - 1]\r\n }\r\n if (close[i] < close[i - 1]) {\r\n d = close[i - 1] - close[i]\r\n }\r\n\r\n if (i <= period) {\r\n sumu += u\r\n sumd += d\r\n au = sumu / i\r\n ad = sumd / i\r\n } else {\r\n au = (au! * (period - 1) + u) / period\r\n ad = (ad! * (period - 1) + d) / period\r\n }\r\n\r\n const rs = ad > 0 ? au / ad : 1\r\n this.calculatedValues.rsi[i] = 100 - 100 * (1 / (1 + rs))\r\n\r\n if (onValueCalculated?.(this.calculatedValues, i) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import { IndicatorType } from '../constants/common'\r\nimport { RsiCalculation } from '../indicator-calculation/rsi'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass RSI extends Indicator {\r\n static type = IndicatorType.Rsi\r\n static label = 'Relative Strength Index'\r\n\r\n rsiCalculation: RsiCalculation | null = null\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary() && this.rsiCalculation !== null) return\r\n\r\n this.rsiCalculation = new RsiCalculation({\r\n quote: this.data,\r\n options: { period: this.period },\r\n })\r\n\r\n this.rsiCalculation.calculate()\r\n\r\n this.lastValue = this.rsiCalculation.calculatedValues.rsi.last() ?? null\r\n const { min, max } = this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.rsiCalculation?.calculatedValues.rsi ?? [], this.period, 30, 50, 70)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `RSI ${this.period}`\r\n }\r\n}\r\n\r\nexport default RSI\r\n","import Line from '../canvas/line'\r\nimport { IndicatorType } from '../constants/common'\r\nimport { getBarWidthWithMarginByParts } from '../utils/chart'\r\nimport { getHEXWithSpecificAplha } from '../utils/colors'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: number | string\r\n baseLine: number\r\n}\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n Period: 50,\r\n BaseLine: 1.0,\r\n}\r\n\r\nfunction parsePeriod(periodStr: string) {\r\n const values = periodStr.split(',')\r\n const period = parseInt(values[0]) || DEFAULT_PARAMETERS.Period\r\n const baseLine = parseFloat(values[1]) || DEFAULT_PARAMETERS.BaseLine\r\n\r\n return [period, baseLine]\r\n}\r\n\r\nclass RelativeVolume extends Indicator {\r\n static type = IndicatorType.Rvol\r\n static label = 'Relative Volume'\r\n\r\n rvol: number[] = []\r\n declare period: number\r\n declare baseLine: number\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [period = 0, baseLine = 0] = parsePeriod(values.period)\r\n super.set({ ...values, period, baseLine })\r\n } else {\r\n super.set(values)\r\n }\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.rvol = []\r\n\r\n let sum = 0\r\n for (let i = 0; i < this.period; i++) {\r\n sum += this.data.volume[i]\r\n }\r\n for (let i = this.period; i < this.data.volume.length; i++) {\r\n sum = sum - this.data.volume[i - this.period] + this.data.volume[i]\r\n this.rvol[i] = this.data.volume[i] / (sum / this.period)\r\n }\r\n\r\n this.lastValue = this.rvol.last() ?? null\r\n }\r\n\r\n const { min, max } =\r\n this.rvol.length > 0\r\n ? this.computeVisibleMinMax([...this.rvol, this.baseLine])\r\n : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const chartModel = this.model.chart()\r\n const { zoomFactor } = chartModel\r\n const { barFillWidth, barBorderWidth } = getBarWidthWithMarginByParts({\r\n zoomFactor,\r\n chartLayout: chartModel.chart_layout(),\r\n })\r\n const barWidthWithoutMargin = barFillWidth + barBorderWidth * 2\r\n const halfBarWidth = ~~Math.max(1, barWidthWithoutMargin / 2)\r\n\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n fromIndexOffset: this.period + 1,\r\n drawBarCallback: (i, x) => {\r\n if (this.rvol[i] === undefined) return\r\n\r\n const baseLine = Math.round(this.fy(this.baseLine))\r\n const y = Math.round(this.fy(this.rvol[i]))\r\n\r\n context.fillStyle = this.rvol[i] < this.baseLine ? Colors.volumeTrendDown : Colors.volumeTrendUp\r\n context.fillRect(x - halfBarWidth, baseLine, barWidthWithoutMargin, y - baseLine)\r\n },\r\n })\r\n\r\n const baseLineY = this.fy(this.baseLine)\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(baseLineY),\r\n y2: Math.round(baseLineY),\r\n strokeStyle: getHEXWithSpecificAplha(Colors.zeroChange, 0.5),\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? DEFAULT_PARAMETERS.Period,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n const baseLine = {\r\n type: 'number',\r\n label: 'Baseline',\r\n name: 'baseLine',\r\n value: this.baseLine ?? DEFAULT_PARAMETERS.BaseLine,\r\n required: true,\r\n step: 0.1,\r\n allowDecimal: true,\r\n min: 0,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, baseLine],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n baseLine: `${baseLine.label} must be a number between ${baseLine.min} and ${baseLine.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'baseLine':\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `RVOL ${this.period}, ${this.baseLine}, SMA`\r\n }\r\n}\r\n\r\nexport default RelativeVolume\r\n","import Text from '../canvas/text'\r\nimport { IndicatorType, OFFSET, PADDING, TextBaseline } from '../constants/common'\r\nimport { getTranslate } from '../controllers/renderUtils'\r\nimport Pane from '../models/pane'\r\nimport utils from '../utils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass RWI extends Indicator {\r\n static type = IndicatorType.Rwi\r\n static label = 'Random Walk Index'\r\n\r\n tr: number[] = []\r\n atr: number[] = []\r\n rwiHi: number[] = []\r\n rwiLo: number[] = []\r\n declare period: number\r\n\r\n constructor(attrs: Attrs, model: Pane) {\r\n super(attrs, model)\r\n this.renderYAxis = this.renderYAxis.bind(this)\r\n }\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.tr = []\r\n this.atr = []\r\n this.rwiHi = []\r\n this.rwiLo = []\r\n let atr = 0\r\n\r\n for (let i = 0; i < this.data.close.length; i++) {\r\n const tr = utils.max([\r\n this.data.high[i] - this.data.low[i],\r\n Math.abs(this.data.high[i] - this.data.close[i - 1]),\r\n Math.abs(this.data.low[i] - this.data.close[i - 1]),\r\n ])\r\n this.tr[i] = tr\r\n\r\n if (i < this.period) {\r\n atr += tr\r\n this.atr[i] = atr / (i + 1)\r\n if (i === this.period - 1) {\r\n atr /= this.period\r\n }\r\n } else {\r\n this.atr[i] = (this.atr[i - 1] * (this.period - 1) + tr) / this.period\r\n }\r\n }\r\n\r\n for (let i = this.period + 2; i < this.data.close.length; i++) {\r\n const h = this.data.high[i]\r\n const l = this.data.low[i]\r\n let trSum = this.tr[i - 1] + this.tr[i - 2]\r\n let count = 2\r\n let atrWeight = (trSum / count) * Math.sqrt(count)\r\n let maxHi = atrWeight > 0 ? (h - this.data.low[i - 1]) / atrWeight : -1\r\n let maxLo = atrWeight > 0 ? (this.data.high[i - 1] - l) / atrWeight : -1\r\n for (let j = i - 1; j > i - this.period + 1; j--) {\r\n trSum += this.tr[j - 2]\r\n count++\r\n atrWeight = (trSum / count) * Math.sqrt(count)\r\n if (atrWeight === 0) {\r\n continue\r\n }\r\n\r\n const hi = (h - this.data.low[j - 1]) / atrWeight\r\n if (hi > maxHi) {\r\n maxHi = hi\r\n }\r\n\r\n const lo = (this.data.high[j - 1] - l) / atrWeight\r\n if (lo > maxLo) {\r\n maxLo = lo\r\n }\r\n }\r\n this.rwiHi[i] = maxHi\r\n this.rwiLo[i] = maxLo\r\n }\r\n }\r\n const { min, max } =\r\n this.rwiHi.length > 0 || this.rwiLo.length > 0\r\n ? this.computeVisibleMinMax(this.rwiHi, this.rwiLo)\r\n : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n if (this.data.close.length === 0) return\r\n\r\n const drawInVisibleAreaProps = {\r\n quote: this.data,\r\n scale: this.model.scale,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n fromIndexOffset: this.period,\r\n }\r\n\r\n context.translate(0.5, 0.5)\r\n context.set('strokeStyle', '#c80000')\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i: number, x: number) => {\r\n context.lineTo(x, Math.round(this.fy(this.rwiLo[i])))\r\n },\r\n })\r\n context.stroke()\r\n\r\n context.set('strokeStyle', '#00a000')\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i: number, x: number) => {\r\n context.lineTo(x, Math.round(this.fy(this.rwiHi[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n renderYAxis(context: CanvasRenderingContext2D) {\r\n super.renderYAxis(context)\r\n const { IndicatorSettings, ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const translate = getTranslate({\r\n context,\r\n xOffset: IndicatorSettings.left.width,\r\n yOffset: IndicatorSettings.top.height,\r\n })\r\n translate.do()\r\n const text = new Text(\r\n {\r\n x: this.contentWidth + OFFSET.M - PADDING.XXS + IndicatorSettings.right.axis.margin.left!,\r\n font: Text.getMergedPropsWithDefaults('font', IndicatorSettings.right.axis.font),\r\n lineHeight: IndicatorSettings.right.axis.font.lineHeight,\r\n padding: {\r\n top: IndicatorSettings.right.axis.font?.padding?.top ?? PADDING.XXS,\r\n right: IndicatorSettings.right.axis.font?.padding?.right ?? PADDING.XXS,\r\n bottom: IndicatorSettings.right.axis.font?.padding?.bottom ?? PADDING.XXS,\r\n left: IndicatorSettings.right.axis.font?.padding?.left ?? PADDING.XXS,\r\n },\r\n textBaseline: TextBaseline.middle,\r\n fillStyle: Colors.indicatorCurrentText,\r\n },\r\n this.model\r\n )\r\n const textLabels = []\r\n if (this.rwiLo.length > 0) {\r\n textLabels.push({\r\n text: this.rwiLo.last()!.toFixed(2),\r\n y: Math.round(this.fy(this.rwiLo.last()!)),\r\n background: '#c80000',\r\n })\r\n }\r\n if (this.rwiHi.length > 0) {\r\n textLabels.push({\r\n text: this.rwiHi.last()!.toFixed(2),\r\n y: Math.round(this.fy(this.rwiHi.last()!)),\r\n background: '#00a000',\r\n })\r\n }\r\n\r\n const minY = 0\r\n const maxY = this.height - IndicatorSettings.bottom.height - IndicatorSettings.top.height\r\n textLabels.forEach((labelSetting) => {\r\n if (labelSetting.y >= minY && labelSetting.y <= maxY) {\r\n text.set(labelSetting).render(context)\r\n }\r\n })\r\n\r\n translate.undo()\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 9,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `RWI ${this.period}`\r\n }\r\n}\r\n\r\nexport default RWI\r\n","import Line from '../canvas/line'\r\nimport { IndicatorType } from '../constants/common'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string | number\r\n dPeriod: number\r\n kPeriod: number\r\n}\r\n\r\nclass Stochastics extends Indicator {\r\n static type = IndicatorType.Stofu\r\n static label = 'Stochastics FULL'\r\n\r\n k: number[] = []\r\n k1: number[] = []\r\n d: number[] = []\r\n declare kPeriod: number\r\n declare period: number\r\n declare dPeriod: number\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [period = 0, kPeriod = 0, dPeriod = 0] = getParsedIntegersFromPeriodString(values.period)\r\n super.set({ ...values, period, dPeriod, kPeriod })\r\n } else {\r\n super.set(values)\r\n }\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary()) return\r\n\r\n const period = Math.min(this.period, this.data.close.length - 1)\r\n let dCount, dSum, k\r\n this.k1 = []\r\n this.k = []\r\n this.d = []\r\n let kSum = (dSum = 0)\r\n let kCount = (dCount = 0)\r\n for (let i = 0; i < this.data.close.length; i++) {\r\n let highestHigh = this.data.high[i]\r\n let lowestLow = this.data.low[i]\r\n\r\n for (let j = i - period + 1; j <= i; j++) {\r\n if (this.data.high[j] > highestHigh) {\r\n highestHigh = this.data.high[j]\r\n }\r\n if (this.data.low[j] < lowestLow) {\r\n lowestLow = this.data.low[j]\r\n }\r\n }\r\n\r\n k = ((this.data.close[i] - lowestLow) / (highestHigh - lowestLow)) * 100\r\n if (highestHigh === lowestLow) {\r\n k = 100\r\n }\r\n this.k1[i] = k\r\n if (this.kPeriod > 1) {\r\n kSum += k\r\n kCount++\r\n if (kCount > this.kPeriod) {\r\n kSum -= this.k1[i - this.kPeriod]\r\n kCount--\r\n }\r\n k = kSum / kCount\r\n }\r\n\r\n dSum += k\r\n dCount++\r\n if (dCount > this.dPeriod) {\r\n dSum -= this.k[i - this.dPeriod]\r\n dCount--\r\n }\r\n\r\n const d = dSum / dCount\r\n this.k[i] = k\r\n this.d[i] = d\r\n }\r\n\r\n this.lastValue = this.k.last() ?? null\r\n const { min, max } = this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n if (this.data.close.length === 0) return\r\n\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(50)),\r\n y2: Math.round(this.fy(50)),\r\n strokeStyle: '#ff8787',\r\n dashLength: 3,\r\n },\r\n this.model\r\n ).render(context)\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(20)),\r\n y2: Math.round(this.fy(20)),\r\n strokeStyle: '#69c1ea',\r\n },\r\n this.model\r\n ).render(context)\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(80)),\r\n y2: Math.round(this.fy(80)),\r\n strokeStyle: '#d386df',\r\n },\r\n this.model\r\n ).render(context)\r\n\r\n context.set('strokeStyle', this.getChartLayoutSettings().IndicatorSettings.general.Colors.line)\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n const drawInVisibleAreaProps = {\r\n quote: this.data,\r\n scale: this.model.scale,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n fromIndexOffset: this.period,\r\n }\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.k[i])))\r\n },\r\n })\r\n context.stroke()\r\n\r\n context.set('strokeStyle', '#c80000')\r\n context.beginPath()\r\n drawInVisibleArea({\r\n ...drawInVisibleAreaProps,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.d[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const kPeriod = {\r\n type: 'number',\r\n label: 'K Period',\r\n name: 'kPeriod',\r\n value: this.kPeriod ?? 3,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const dPeriod = {\r\n type: 'number',\r\n label: 'D Period',\r\n name: 'dPeriod',\r\n value: this.dPeriod ?? 3,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, kPeriod, dPeriod],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n dPeriod: `${dPeriod.label} must be a whole number between ${dPeriod.min} and ${dPeriod.max}`,\r\n kPeriod: `${kPeriod.label} must be a whole number between ${kPeriod.min} and ${kPeriod.max}`,\r\n } as {\r\n period: string\r\n dPeriod: string\r\n kPeriod?: string\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n case 'dPeriod':\r\n case 'kPeriod':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `Stochastics FULL ${this.period},${this.kPeriod},${this.dPeriod}`\r\n }\r\n}\r\n\r\nexport default Stochastics\r\n","import { IndicatorType } from '../constants/common'\r\nimport Pane from '../models/pane'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport Stochastics from './stofu'\r\n\r\ninterface Attrs {\r\n period: string | number\r\n dPeriod: number\r\n kPeriod: number\r\n}\r\n\r\nclass StochasticsFast extends Stochastics {\r\n static type = IndicatorType.Stofa\r\n static label = 'Stochastics FAST'\r\n\r\n declare kPeriod: number\r\n declare period: number\r\n declare dPeriod: number\r\n\r\n constructor(attrs: Attrs, model: Pane) {\r\n super(attrs, model)\r\n this.kPeriod = 1\r\n }\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [period = 0, dPeriod = 0] = getParsedIntegersFromPeriodString(values.period)\r\n super.set({ ...values, period, dPeriod, kPeriod: 1 })\r\n } else {\r\n super.set(values)\r\n }\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const dPeriod = {\r\n type: 'number',\r\n label: 'D Period',\r\n name: 'dPeriod',\r\n value: this.dPeriod ?? 3,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, dPeriod],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n dPeriod: `${dPeriod.label} must be a whole number between ${dPeriod.min} and ${dPeriod.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n case 'dPeriod':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `Stochastics FAST ${this.period},${this.dPeriod}`\r\n }\r\n}\r\n\r\nexport default StochasticsFast\r\n","import { IndicatorType } from '../constants/common'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport Stochastics from './stofu'\r\n\r\ninterface Attrs {\r\n period: string | number\r\n dPeriod: number\r\n kPeriod: number\r\n}\r\n\r\nclass StochasticsSlow extends Stochastics {\r\n static type = IndicatorType.Stosl\r\n static label = 'Stochastics SLOW'\r\n\r\n kPeriod = 3\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [period = 0, dPeriod = 0] = getParsedIntegersFromPeriodString(values.period)\r\n super.set({ ...values, period, dPeriod, kPeriod: 3 })\r\n } else {\r\n super.set(values)\r\n }\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const dPeriod = {\r\n type: 'number',\r\n label: 'D Period',\r\n name: 'dPeriod',\r\n value: this.dPeriod ?? 3,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, dPeriod],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n dPeriod: `${dPeriod.label} must be a whole number between ${dPeriod.min} and ${dPeriod.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n case 'dPeriod':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `Stochastics SLOW ${this.period},${this.dPeriod}`\r\n }\r\n}\r\n\r\nexport default StochasticsSlow\r\n","import { IndicatorType } from '../constants/common'\r\nimport { ExponentialMovingAverage } from './ema'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n period: number\r\n}\r\n\r\ntype DefaultCalculatedValuesType = {\r\n trix: number[]\r\n}\r\n\r\nexport class TrixCalculation extends MainCalculation {\r\n static type = IndicatorType.Trix\r\n\r\n getDefaultCalculatedValues() {\r\n return { trix: [] }\r\n }\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { period } = this.options\r\n const { close } = this.quote\r\n const lastIndex = close.length - 1\r\n const ema1 = new ExponentialMovingAverage(period)\r\n const ema2 = new ExponentialMovingAverage(period)\r\n const ema3 = new ExponentialMovingAverage(period)\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n let prev = 0\r\n for (let index = 0; index <= lastIndex; index++) {\r\n ema1.add(close[index])\r\n ema2.add(ema1.value)\r\n ema3.add(ema2.value)\r\n if (prev > 0) {\r\n this.calculatedValues.trix[index] = (ema3.value * 100) / prev - 100\r\n }\r\n prev = ema3.value\r\n\r\n if (onValueCalculated?.(this.calculatedValues, index) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import Line from '../canvas/line'\r\nimport { IndicatorType } from '../constants/common'\r\nimport { TrixCalculation } from '../indicator-calculation/trix'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass Trix extends Indicator {\r\n static type = IndicatorType.Trix\r\n static label = 'TRIX'\r\n\r\n trixCalculation: TrixCalculation | null = null\r\n declare period: number\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.trixCalculation = new TrixCalculation({\r\n quote: this.data,\r\n options: {\r\n period: this.period,\r\n },\r\n })\r\n this.trixCalculation.calculate()\r\n this.lastValue = this.trixCalculation.calculatedValues.trix.last() ?? null\r\n }\r\n const trix = this.trixCalculation?.calculatedValues.trix ?? []\r\n const { min, max } = trix.length > 0 ? this.computeVisibleMinMax(trix) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n new Line(\r\n {\r\n x1: -this.leftOffset,\r\n x2: -this.leftOffset + this.contentWidth,\r\n y1: Math.round(this.fy(0)),\r\n y2: Math.round(this.fy(0)),\r\n strokeStyle: '#ff8787',\r\n dashLength: 3,\r\n },\r\n this.model\r\n ).render(context)\r\n context.set('strokeStyle', this.getChartLayoutSettings().IndicatorSettings.general.Colors.line)\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i: number, x: number) => {\r\n const value = this.trixCalculation?.calculatedValues.trix[i]\r\n if (value) context.lineTo(x, ~~this.fy(value))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 9,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `TRIX ${this.period}`\r\n }\r\n}\r\n\r\nexport default Trix\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { IndicatorType } from '../constants/common'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n period1: number\r\n period2: number\r\n period3: number\r\n}\r\n\r\nclass UltimateOscillator extends Indicator {\r\n static type = IndicatorType.Ult\r\n static label = 'Ultimate Oscillator'\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [period1 = 0, period2 = 0, period3 = 0] = getParsedIntegersFromPeriodString(period)\r\n return Math.max(period1, period2, period3)\r\n }\r\n\r\n declare period1: number\r\n declare period2: number\r\n declare period3: number\r\n ult: number[] = []\r\n tr: number[] = []\r\n bp: number[] = []\r\n\r\n set(values: Partial) {\r\n if (typeof values.period === 'string') {\r\n const [period1 = 0, period2 = 0, period3 = 0] = getParsedIntegersFromPeriodString(values.period)\r\n super.set({ ...values, period1, period2, period3 })\r\n } else {\r\n super.set(values)\r\n }\r\n }\r\n\r\n compute() {\r\n if (!this.isComputeNecessary()) return\r\n\r\n this.ult = []\r\n let bpSum2, bpSum3, count2, count3, trSum2, trSum3\r\n const tr = []\r\n const bp = []\r\n let bpSum1 = (bpSum2 = bpSum3 = 0)\r\n let trSum1 = (trSum2 = trSum3 = 0)\r\n let count1 = (count2 = count3 = 0)\r\n let avg2, avg3\r\n for (let i = 1; i < this.data.close.length; i++) {\r\n bp[i] = this.data.close[i] - Math.min(this.data.low[i], this.data.close[i - 1])\r\n tr[i] = Math.max(this.data.high[i], this.data.close[i - 1]) - Math.min(this.data.low[i], this.data.close[i - 1])\r\n\r\n bpSum1 += bp[i]\r\n trSum1 += tr[i]\r\n count1++\r\n if (count1 > this.period1) {\r\n bpSum1 -= bp[i - this.period1]\r\n trSum1 -= tr[i - this.period1]\r\n }\r\n\r\n bpSum2 += bp[i]\r\n trSum2 += tr[i]\r\n count2++\r\n if (count2 > this.period2) {\r\n bpSum2 -= bp[i - this.period2]\r\n trSum2 -= tr[i - this.period2]\r\n }\r\n\r\n bpSum3 += bp[i]\r\n trSum3 += tr[i]\r\n count3++\r\n if (count3 > this.period3) {\r\n bpSum3 -= bp[i - this.period3]\r\n trSum3 -= tr[i - this.period3]\r\n }\r\n\r\n let avg1 = (avg2 = avg3 = 0)\r\n if (trSum1 > 0) {\r\n avg1 = bpSum1 / trSum1\r\n }\r\n if (trSum2 > 0) {\r\n avg2 = bpSum2 / trSum2\r\n }\r\n if (trSum3 > 0) {\r\n avg3 = bpSum3 / trSum3\r\n }\r\n\r\n this.ult[i] = (100 * (4 * avg1 + 2 * avg2 + avg3)) / 7\r\n }\r\n\r\n this.lastValue = this.ult.last() ?? null\r\n const { min, max } = this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.ult, 1, 30, 50, 70)\r\n }\r\n\r\n getModalConfig() {\r\n const period1 = {\r\n type: 'number',\r\n label: 'Period 1',\r\n name: 'period1',\r\n value: this.period1 ?? 7,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const period2 = {\r\n type: 'number',\r\n label: 'Period 2',\r\n name: 'period2',\r\n value: this.period2 ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const period3 = {\r\n type: 'number',\r\n label: 'Period 3',\r\n name: 'period3',\r\n value: this.period3 ?? 28,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period1, period2, period3],\r\n inputsErrorMessages: {\r\n period1: `${period1.label} must be a whole number between ${period1.min} and ${period1.max}`,\r\n period2: `${period2.label} must be a whole number between ${period2.min} and ${period2.max}`,\r\n period3: `${period3.label} must be a whole number between ${period3.min} and ${period3.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period1':\r\n case 'period2':\r\n case 'period3':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `ULT ${this.period1},${this.period2},${this.period3}`\r\n }\r\n}\r\n\r\nexport default UltimateOscillator\r\n","import { IndicatorType } from '../constants/common'\r\nimport math from '../helpers/math'\r\nimport { getBarWidthWithMarginByParts } from '../utils/chart'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Indicator from './indicator'\r\n\r\nclass Volume extends Indicator {\r\n static type = IndicatorType.Vol\r\n static label = 'Volume'\r\n\r\n compute() {\r\n const { min, max } =\r\n this.data.volume.length > 0 ? this.computeVisibleMinMax(this.data.volume) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n this.lastValue = this.data.volume.last() ?? null\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const chartModel = this.model.chart()\r\n const { zoomFactor } = chartModel\r\n const { barFillWidth, barBorderWidth } = getBarWidthWithMarginByParts({\r\n zoomFactor,\r\n chartLayout: chartModel.chart_layout(),\r\n })\r\n const barWidthWithoutMargin = barFillWidth + barBorderWidth * 2\r\n const halfBarWidth = ~~Math.max(1, barWidthWithoutMargin / 2)\r\n\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n leftOffset: this.leftOffset,\r\n width: this.width,\r\n drawBarCallback: (i, x) => {\r\n context.fillStyle = this.data.close[i] < this.data.open[i] ? Colors.volumeTrendDown : Colors.volumeTrendUp\r\n const y = Math.round(this.fy(this.data.volume[i]))\r\n context.fillRect(x - halfBarWidth, y, barWidthWithoutMargin, context.canvas.height - y)\r\n },\r\n })\r\n }\r\n\r\n formatAxis(value: number) {\r\n return math.formatBigNumber(value, 2)\r\n }\r\n\r\n getModalConfig() {\r\n return {\r\n title: this.label,\r\n inputs: [],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n toString() {\r\n return `Volume`\r\n }\r\n}\r\n\r\nexport default Volume\r\n","import { IndicatorType } from '../constants/common'\r\nimport Indicator from './indicator'\r\n\r\ninterface Attrs {\r\n period: string\r\n}\r\n\r\nclass WilliamsR extends Indicator {\r\n static type = IndicatorType.Wr\r\n static label = 'Williams %R'\r\n\r\n declare period: number\r\n r: number[] = []\r\n\r\n set(values: Partial) {\r\n super.set(values)\r\n this.parsePeriodInt(values)\r\n }\r\n\r\n compute() {\r\n if (this.isComputeNecessary()) {\r\n this.r = []\r\n for (let i = this.period; i < this.data.close.length; i++) {\r\n let highestHigh = this.data.high[i]\r\n let lowestLow = this.data.low[i]\r\n for (let j = i - this.period + 1; j <= i; j++) {\r\n if (this.data.high[j] > highestHigh) {\r\n highestHigh = this.data.high[j]\r\n }\r\n if (this.data.low[j] < lowestLow) {\r\n lowestLow = this.data.low[j]\r\n }\r\n }\r\n\r\n this.r[i] = 0\r\n if (highestHigh - lowestLow > 0) {\r\n this.r[i] = ((highestHigh - this.data.close[i]) / (highestHigh - lowestLow)) * -100\r\n }\r\n }\r\n\r\n this.lastValue = this.r.last() ?? null\r\n }\r\n const { min, max } = this.r.length > 0 ? this.computeVisibleMinMax(this.r) : this.getDomainDefaults(this.type)\r\n this.min = min\r\n this.max = max\r\n }\r\n\r\n renderIndicator(context: CanvasRenderingContext2D) {\r\n this.renderOversoldOverbought(context, this.r, this.period, -80, -50, -20)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.period ?? 14,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `W%R ${this.period}`\r\n }\r\n}\r\n\r\nexport default WilliamsR\r\n","import { IndicatorType } from '../constants/common'\r\nimport adx from './adx'\r\nimport aro from './aro'\r\nimport aroosc from './aroosc'\r\nimport atr from './atr'\r\nimport cci from './cci'\r\nimport cot from './cot'\r\nimport fi from './fi'\r\nimport indicator from './indicator'\r\nimport macd from './macd'\r\nimport mfi from './mfi'\r\nimport none from './none'\r\nimport obv from './obv'\r\nimport perf from './perf'\r\nimport rmi from './rmi'\r\nimport roc from './roc'\r\nimport rsi from './rsi'\r\nimport rvol from './rvol'\r\nimport rwi from './rwi'\r\nimport stofa from './stofa'\r\nimport stofu from './stofu'\r\nimport stosl from './stosl'\r\nimport trix from './trix'\r\nimport ult from './ult'\r\nimport vol from './vol'\r\nimport wr from './wr'\r\n\r\n// TODO check if this doesn't break saved charts\r\nexport const indicatorsByType = Object.freeze({\r\n [IndicatorType.Indicator]: indicator,\r\n [IndicatorType.None]: none,\r\n [IndicatorType.Adx]: adx,\r\n [IndicatorType.Aro]: aro,\r\n [IndicatorType.Aroosc]: aroosc,\r\n [IndicatorType.Atr]: atr,\r\n [IndicatorType.Cci]: cci,\r\n [IndicatorType.Cot]: cot,\r\n [IndicatorType.Fi]: fi,\r\n [IndicatorType.Macd]: macd,\r\n [IndicatorType.Mfi]: mfi,\r\n [IndicatorType.Obv]: obv,\r\n [IndicatorType.Perf]: perf,\r\n [IndicatorType.Rmi]: rmi,\r\n [IndicatorType.Roc]: roc,\r\n [IndicatorType.Rsi]: rsi,\r\n [IndicatorType.Rvol]: rvol,\r\n [IndicatorType.Rwi]: rwi,\r\n [IndicatorType.Stofa]: stofa,\r\n [IndicatorType.Stofu]: stofu,\r\n [IndicatorType.Stosl]: stosl,\r\n [IndicatorType.Trix]: trix,\r\n [IndicatorType.Ult]: ult,\r\n [IndicatorType.Vol]: vol,\r\n [IndicatorType.Wr]: wr,\r\n})\r\n\r\nexport const indicatorsWithoutPeriod = Object.freeze([IndicatorType.Obv, IndicatorType.Vol])\r\n","import Spine from '@finviz/spine'\r\nimport * as React from 'react'\r\n\r\nimport { DefaultSpineEvents } from '../../types/shared'\r\nimport ElementModule from '../canvas/element'\r\nimport IndicatorModule from '../indicators/indicator'\r\nimport { useForceUpdate } from '../utils/force-update'\r\nimport { getJSONReplacerFunc } from '../utils/helpers'\r\n\r\ninterface UseModelStateOptions {\r\n watchProperties?: T extends null ? never[] : Array\r\n listenOnEvents?: string[]\r\n}\r\n\r\nconst getIsSpineObject = (value: any) =>\r\n [Spine.Model, Spine.Module, Spine.Collection].some((spineObject) => value instanceof spineObject)\r\n\r\nconst getWatchedPropValue = (\r\n watchedProp: Model[keyof Model] | ElementModule | IndicatorModule | undefined,\r\n model: Model | null\r\n) => {\r\n if (typeof watchedProp === 'function') {\r\n const value = watchedProp.call(model)\r\n\r\n if (value && !getIsSpineObject(value)) {\r\n throw Error('Watched prop should have a primitive value or a spine object')\r\n }\r\n\r\n if (typeof value?.all === 'function') {\r\n return value.all()\r\n }\r\n\r\n return value\r\n }\r\n\r\n if (typeof watchedProp === 'object') {\r\n const hasToObject = !!watchedProp && 'toObject' in watchedProp\r\n return JSON.stringify(hasToObject ? watchedProp.toObject() : watchedProp, getJSONReplacerFunc())\r\n }\r\n\r\n return watchedProp\r\n}\r\n\r\nconst getWatchedProps = (model: Model | null, props?: Array) =>\r\n props?.reduce(\r\n (acc, propKey) => ({\r\n ...acc,\r\n [propKey]: getWatchedPropValue(model?.[propKey], model),\r\n }),\r\n {} as Partial\r\n )\r\n\r\nconst getAreWatchedPropsEqual = (\r\n currentValue: Value,\r\n previousValue: Value\r\n) => {\r\n if (currentValue instanceof Spine.Model) {\r\n return currentValue.eql(previousValue)\r\n }\r\n\r\n return currentValue === previousValue\r\n}\r\n\r\nconst DEFAULT_SPINE_EVENTS = Object.values(DefaultSpineEvents)\r\n\r\nexport function useModelState(\r\n model: Model,\r\n options: UseModelStateOptions = {}\r\n) {\r\n const { watchProperties = [], listenOnEvents = DEFAULT_SPINE_EVENTS } = options\r\n const stringifiedOptions = JSON.stringify(options)\r\n const { forceUpdate } = useForceUpdate()\r\n const watchedPropertiesRef = React.useRef(getWatchedProps(model, watchProperties))\r\n\r\n React.useEffect(() => {\r\n const handleModelChange = () => {\r\n const hasChange = watchProperties.some((propKey) => {\r\n const currentValue = getWatchedPropValue(model?.[propKey], model)\r\n const previousValue = watchedPropertiesRef.current?.[propKey]\r\n\r\n if (Array.isArray(currentValue)) {\r\n return (\r\n !Array.isArray(previousValue) ||\r\n currentValue.length !== previousValue.length ||\r\n currentValue.some((record, index) => !getAreWatchedPropsEqual(record, previousValue[index]))\r\n )\r\n }\r\n\r\n return !getAreWatchedPropsEqual(currentValue, previousValue)\r\n })\r\n\r\n if (hasChange) {\r\n watchedPropertiesRef.current = getWatchedProps(model, watchProperties)\r\n forceUpdate()\r\n }\r\n }\r\n\r\n const spineEvents = listenOnEvents.join(' ')\r\n\r\n model?.bind(spineEvents, handleModelChange)\r\n\r\n forceUpdate()\r\n\r\n return () => {\r\n model?.unbind(spineEvents, handleModelChange)\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [model?.cid, stringifiedOptions, forceUpdate])\r\n\r\n return model\r\n}\r\n","/*\r\n * it converts it to numbered index and it causes problems later on\r\n * the reason it's not just numbered enum is that it when used in const below\r\n * */\r\nexport enum ChartSyncablePart {\r\n Crosshair = 'crosshair',\r\n Ticker = 'ticker',\r\n Timeframe = 'timeframe',\r\n}\r\n\r\nexport const ChartPartToAttrsSyncMap = {\r\n [ChartSyncablePart.Ticker]: ['ticker'],\r\n [ChartSyncablePart.Timeframe]: ['timeframe', 'dateRange'],\r\n}\r\n\r\nexport const ChartSyncableParts = [\r\n { value: ChartSyncablePart.Ticker, label: 'Ticker' },\r\n { value: ChartSyncablePart.Timeframe, label: 'Timeframe' },\r\n { value: ChartSyncablePart.Crosshair, label: 'Crosshair' },\r\n]\r\n","import { ObjectHash, Theme } from '../../../types/shared'\r\nimport { IChartThemeColors, chartDarkTheme, chartLightTheme } from '../constants'\r\n\r\nfunction normalizeHexAlpha(hexString = '') {\r\n const hexValue = hexString.replace('#', '')\r\n if (hexValue.length === 6) {\r\n return `${hexString}FF`\r\n }\r\n return hexString\r\n}\r\n\r\nexport const getColorOverwrites = ({\r\n theme,\r\n colors,\r\n}: {\r\n theme: Theme\r\n colors: ObjectHash, Theme>\r\n}) => {\r\n const customColors = colors[theme]\r\n const customColorKeys = Object.keys(customColors) as Array>\r\n const defaultColors = theme === Theme.light ? chartLightTheme : chartDarkTheme\r\n\r\n return customColorKeys.reduce((acc, colorKey) => {\r\n const isDefaultOverWritten =\r\n normalizeHexAlpha(customColors[colorKey]).toLowerCase() !==\r\n normalizeHexAlpha(defaultColors[colorKey]).toLowerCase()\r\n\r\n return isDefaultOverWritten\r\n ? {\r\n ...acc,\r\n [colorKey]: customColors[colorKey],\r\n }\r\n : acc\r\n }, {})\r\n}\r\n","import tailwindColors from '../constants/colors'\r\nimport { getHEXWithSpecificAplha } from '../utils/colors'\r\n\r\nexport interface IChartThemeColors {\r\n aftermarketFade: string\r\n background: string\r\n borderDown: string\r\n borderUp: string\r\n canvasFill: string\r\n cross: string\r\n crossText: string\r\n crossTextBackground: string\r\n currentBackground: string\r\n currentText: string\r\n grid: string\r\n gridSecondary: string\r\n indicatorCurrentBackground: string\r\n indicatorCurrentText: string\r\n line: string\r\n marketDown: string\r\n marketUp: string\r\n negativeChange: string\r\n ohlcTrendDown: string\r\n ohlcTrendUp: string\r\n overlayTransparentBackground: string\r\n percentageZeroLineText: string\r\n performanceIndicatorLabel: string\r\n positiveChange: string\r\n premarketFade: string\r\n prevClose: string\r\n text: string\r\n textSecondary: string\r\n trendDown: string\r\n trendUp: string\r\n volumeTrendDown: string\r\n volumeTrendUp: string\r\n wickDown: string\r\n wickUp: string\r\n zeroChange: string\r\n}\r\n\r\nexport interface IIndicatorThemeColors {\r\n line: string\r\n signalLine: string\r\n}\r\n\r\nexport interface IElementThemeColors {\r\n line: string\r\n border: string\r\n textWithoutBackground: string\r\n}\r\n\r\ninterface IDarkerWickColors {\r\n borderUp: string\r\n wickUp: string\r\n borderDown: string\r\n wickDown: string\r\n}\r\n\r\nexport const chartLightTheme: IChartThemeColors = {\r\n aftermarketFade: '#FFFFFF99',\r\n background: '#008CFF0E',\r\n borderDown: '#000000FF',\r\n borderUp: '#000000FF',\r\n canvasFill: '#FFFFFFFF',\r\n cross: '#0000004C',\r\n crossText: '#fff',\r\n crossTextBackground: '#111',\r\n currentBackground: tailwindColors.brightYellow[100],\r\n currentText: tailwindColors.gray[800],\r\n grid: '#D2D2D2FF',\r\n gridSecondary: '#ECECEC',\r\n indicatorCurrentBackground: tailwindColors.gray[600],\r\n indicatorCurrentText: '#fff',\r\n line: '#1E6DC0FF',\r\n marketDown: tailwindColors.red[500],\r\n marketUp: tailwindColors.green[500],\r\n negativeChange: '#C80000FF',\r\n ohlcTrendDown: '#E54040FF',\r\n ohlcTrendUp: '#40A140FF',\r\n overlayTransparentBackground: getHEXWithSpecificAplha('#C9CCD6', 0.25),\r\n percentageZeroLineText: '#111',\r\n performanceIndicatorLabel: '#646464',\r\n positiveChange: '#009600FF',\r\n premarketFade: '#FFFFFF99',\r\n prevClose: '#C80000FF',\r\n text: '#828282',\r\n textSecondary: '#dedede',\r\n trendDown: '#FF0000FF',\r\n trendUp: '#00FF00FF',\r\n volumeTrendDown: '#ffc0c0',\r\n volumeTrendUp: '#a8e0a8',\r\n wickDown: '#000000FF',\r\n wickUp: '#000000FF',\r\n zeroChange: '#000',\r\n}\r\n\r\nexport const chartDarkTheme: IChartThemeColors = {\r\n aftermarketFade: '#4C526133',\r\n background: '#1E6DC019',\r\n borderDown: '#F63538FF',\r\n borderUp: '#30CC5AFF',\r\n canvasFill: tailwindColors.gray[800],\r\n cross: '#404553',\r\n crossText: '#fff',\r\n crossTextBackground: '#111',\r\n currentBackground: tailwindColors.yellow[200],\r\n currentText: tailwindColors.gray[700],\r\n grid: '#363A46FF',\r\n gridSecondary: '#2C303A',\r\n indicatorCurrentBackground: tailwindColors.gray[500],\r\n indicatorCurrentText: '#fff',\r\n line: '#1E6DC0FF',\r\n marketDown: tailwindColors.red[300],\r\n marketUp: tailwindColors.green[300],\r\n negativeChange: tailwindColors.red[400],\r\n ohlcTrendDown: '#E54040FF',\r\n ohlcTrendUp: '#40A140FF',\r\n overlayTransparentBackground: getHEXWithSpecificAplha('#0C0E13', 0.35),\r\n percentageZeroLineText: '#fff',\r\n performanceIndicatorLabel: '#646464',\r\n positiveChange: tailwindColors.green[400],\r\n premarketFade: '#4C526133',\r\n prevClose: '#C80000FF',\r\n text: '#929cb3',\r\n textSecondary: '#929CB399',\r\n trendDown: '#F63538FF',\r\n trendUp: '#30CC5AFF',\r\n volumeTrendDown: '#F635387F',\r\n volumeTrendUp: '#30CC5A7F',\r\n wickDown: '#F63538FF',\r\n wickUp: '#30CC5AFF',\r\n zeroChange: '#929cb3',\r\n}\r\n\r\nexport const darkerWickColors: IDarkerWickColors = {\r\n borderUp: '#006400FF',\r\n wickUp: '#006400',\r\n borderDown: '#6E0000FF',\r\n wickDown: '#6E0000FF',\r\n}\r\n\r\nexport const indicatorLightTheme: IIndicatorThemeColors = {\r\n line: '#000000',\r\n signalLine: tailwindColors.red[400],\r\n}\r\n\r\nexport const indicatorDarkTheme: IIndicatorThemeColors = {\r\n line: '#D07933',\r\n signalLine: tailwindColors.red[400],\r\n}\r\n\r\nexport const elementLightTheme: IElementThemeColors = {\r\n line: '#000000',\r\n border: '#000000',\r\n textWithoutBackground: '#000000',\r\n}\r\n\r\nexport const elementDarkTheme: IElementThemeColors = {\r\n line: '#5faaf4',\r\n border: '#5192D1',\r\n textWithoutBackground: '#929cb3',\r\n}\r\nexport const generalColors: Array = [\r\n '#1f77b4',\r\n '#ff7f0e',\r\n '#2ca02c',\r\n '#d62728',\r\n '#9467bd',\r\n '#8c564b',\r\n '#e377c2',\r\n '#7f7f7f',\r\n '#bcbd22',\r\n '#17becf',\r\n]\r\n\r\n// node chart with thin bars color override\r\nexport const thinBarColorsOverride = {\r\n trendUp: '#00b400',\r\n trendDown: '#b40000',\r\n}\r\n\r\nexport enum AutoSaveState {\r\n Off,\r\n Saved,\r\n Unsaved,\r\n Saving,\r\n}\r\n\r\nexport const CHART_EVENT_BADGE_SIZE = 24\r\n","import Spine from '@finviz/spine'\r\nimport merge from 'lodash.merge'\r\n\r\nimport { TodoObjectHashAnyType } from '../../types/shared'\r\nimport { drawingToolsByType } from '../canvas/drawingTools'\r\nimport CanvasElement from '../canvas/element'\r\nimport { CanvasElementType } from '../constants/common'\r\nimport { getIsSSr, getUuid } from '../utils/helpers'\r\nimport Pane from './pane'\r\nimport { changeElementZIndexes } from './utils'\r\n\r\nclass Element extends Spine.Model {\r\n static initClass(paneModel: typeof Pane) {\r\n this.configure('Element', 'instance', 'lastChange', 'zIndex', 'elementId')\r\n this.belongsTo('pane', paneModel)\r\n }\r\n\r\n declare instance: CanvasElement\r\n declare pane_id: string\r\n declare destroyed: true | undefined\r\n declare pane: () => Pane\r\n lastChange: number | null = null\r\n elementId: string | null = null\r\n zIndex = -1\r\n\r\n generateUuid = getIsSSr() ? undefined : getUuid\r\n\r\n constructor(...args: any[]) {\r\n super(...args)\r\n const elementAttrs = args[0]\r\n this.elementId = elementAttrs?.elementId ?? this.generateUuid?.()\r\n this.one('create', () => {\r\n this.updateAttributes({\r\n zIndex: elementAttrs?.zIndex ?? this.pane().getElementZIndexRange().max + 1,\r\n })\r\n })\r\n }\r\n\r\n replace(instance: CanvasElement) {\r\n const oldInstance = this.instance\r\n this.updateAttribute('instance', instance)\r\n this.trigger('replace', this, oldInstance)\r\n }\r\n\r\n makeClone() {\r\n const { instance, pane_id } = this\r\n const { attrs } = instance\r\n const { scale } = instance.model\r\n const clonedObj = merge({ pane_id }, attrs)\r\n const cloned = drawingToolsByType[instance.type as CanvasElementType].fromObject(clonedObj, instance.model)\r\n const { ThumbSettings } = this.pane().getChartLayoutSettings()\r\n const offset = ThumbSettings.size + ThumbSettings.borderWidth * 2\r\n cloned.moveBy(scale.x.invert(offset), scale.y.invert(offset) - scale.y.invert(0))\r\n cloned.cachePointPositionTimestamp()\r\n Element.create({ instance: cloned, pane_id })\r\n this.trigger('makeClone', this, cloned)\r\n }\r\n\r\n moveToZIndex(zIndex: number) {\r\n const currentZIndex = this.zIndex\r\n const directionCoef = zIndex > currentZIndex ? 1 : -1\r\n\r\n if (this.isChart() || this.isIndicator()) {\r\n if (this.zIndex !== 0) {\r\n this.updateAttributes({ zIndex: 0 })\r\n }\r\n this.pane()\r\n .getAllElements()\r\n .filter((element) => {\r\n const shouldMove = directionCoef === 1 ? element.zIndex <= zIndex : element.zIndex >= zIndex\r\n return shouldMove && element.isDrawing()\r\n })\r\n .forEach((element) => element.moveToZIndex(directionCoef * -1))\r\n\r\n return\r\n }\r\n\r\n const newZIndex = zIndex === 0 ? directionCoef : zIndex // 0 is protected value for chart/indicator element\r\n const { min, max } = this.pane().getElementZIndexRange()\r\n if (\r\n currentZIndex === newZIndex ||\r\n (currentZIndex === min && directionCoef === -1) ||\r\n (currentZIndex === max && directionCoef === 1)\r\n ) {\r\n return\r\n }\r\n const { elementsBelowZero, elementsAboveZero } = this.pane().getBelowAboveZeroElements()\r\n\r\n changeElementZIndexes({\r\n elementsArray: elementsBelowZero,\r\n addElement: newZIndex < 0 ? this : undefined,\r\n oldZIndex: currentZIndex,\r\n newZIndex,\r\n isBelowZero: true,\r\n })\r\n\r\n changeElementZIndexes({\r\n elementsArray: elementsAboveZero,\r\n addElement: newZIndex > 0 ? this : undefined,\r\n oldZIndex: currentZIndex,\r\n newZIndex,\r\n })\r\n }\r\n\r\n bringToFront() {\r\n this.moveToZIndex(this.pane().getElementZIndexRange().max + 1)\r\n }\r\n\r\n sendToBack() {\r\n this.moveToZIndex(this.pane().getElementZIndexRange().min - 1)\r\n }\r\n\r\n bringForward() {\r\n this.moveToZIndex(this.zIndex + 1)\r\n }\r\n\r\n sendBackward() {\r\n this.moveToZIndex(this.zIndex - 1)\r\n }\r\n\r\n isChart() {\r\n return !!this.instance?.type.startsWith('charts/')\r\n }\r\n\r\n isIndicator() {\r\n return !!this.instance?.type.startsWith('indicators/')\r\n }\r\n\r\n isOverlay() {\r\n return !!this.instance?.type.startsWith('overlays/')\r\n }\r\n\r\n isDrawing() {\r\n return !!this.instance?.type.startsWith('canvas/')\r\n }\r\n\r\n isChartEvent() {\r\n return !!this.instance?.type.startsWith('chartEvent/')\r\n }\r\n\r\n isMouseDown() {\r\n return !!this.instance?.isMouseDown\r\n }\r\n\r\n hasOngoingInteraction() {\r\n return this.isMouseDown() || this.instance.isEditInProgress\r\n }\r\n\r\n toObject() {\r\n return {\r\n ...this.instance.toObject(),\r\n elementId: this.elementId,\r\n zIndex: this.zIndex,\r\n }\r\n }\r\n\r\n toConfig() {\r\n return {\r\n ...this.instance.toConfig(),\r\n elementId: this.elementId,\r\n zIndex: this.zIndex,\r\n }\r\n }\r\n\r\n destroyCascade(options?: TodoObjectHashAnyType) {\r\n return this.destroy(options)\r\n }\r\n\r\n refreshElementId() {\r\n this.updateAttribute('elementId', this.generateUuid?.())\r\n }\r\n}\r\n\r\nexport default Element\r\n","import endOfDay from 'date-fns/endOfDay'\r\nimport lastDayOfMonth from 'date-fns/lastDayOfMonth'\r\nimport lastDayOfWeek from 'date-fns/lastDayOfWeek'\r\nimport setDate from 'date-fns/set'\r\n\r\nimport { TIMEFRAME, TIMEFRAMES_WITH_PRE_MARKET } from '../../constants/common'\r\nimport { convertLocalToNyTime, dateFromUnixTimestamp } from '../../utils'\r\nimport Chart from '../chart'\r\n\r\nconst MARKET_START = { hours: 9, minutes: 30 }\r\nconst END_OF_DAY = { hours: 23, minutes: 59 }\r\n\r\nfunction getIsDateBeforeMarketStart(date: Date) {\r\n const hours = date.getHours()\r\n const minutes = date.getMinutes()\r\n return hours < MARKET_START.hours || (hours === MARKET_START.hours && minutes < MARKET_START.minutes)\r\n}\r\n\r\nexport function roundTimeForSyncedPane({\r\n sourceChart,\r\n targetChart,\r\n timestamp,\r\n}: {\r\n sourceChart: Chart\r\n targetChart: Chart\r\n timestamp: number\r\n}) {\r\n let dateToReturn = dateFromUnixTimestamp(timestamp)\r\n const sourceChartHasPremarket =\r\n sourceChart.quote().premarket && TIMEFRAMES_WITH_PRE_MARKET.includes(sourceChart.timeframe)\r\n const targetChartHasPremarket =\r\n targetChart.quote().premarket && TIMEFRAMES_WITH_PRE_MARKET.includes(targetChart.timeframe)\r\n\r\n if ([TIMEFRAME.d, TIMEFRAME.w, TIMEFRAME.m].includes(sourceChart.timeframe)) {\r\n dateToReturn = setDate(dateToReturn, MARKET_START)\r\n }\r\n\r\n if (targetChart.timeframe === TIMEFRAME.m) {\r\n dateToReturn = setDate(lastDayOfMonth(dateToReturn), END_OF_DAY)\r\n } else if (targetChart.timeframe === TIMEFRAME.w) {\r\n dateToReturn = setDate(lastDayOfWeek(dateToReturn, { weekStartsOn: 1 }), END_OF_DAY)\r\n } else if (targetChart.timeframe === TIMEFRAME.d && targetChart.quote().instrument !== 'stock') {\r\n dateToReturn = endOfDay(dateToReturn)\r\n }\r\n\r\n if (sourceChartHasPremarket && !targetChartHasPremarket && targetChart.quote().instrument === 'stock') {\r\n dateToReturn = getIsDateBeforeMarketStart(dateToReturn) ? setDate(dateToReturn, MARKET_START) : dateToReturn\r\n }\r\n\r\n return ~~(convertLocalToNyTime(dateToReturn, false).getTime() / 1000)\r\n}\r\n","import Spine from '@finviz/spine'\r\n\r\nimport { ChartSyncablePart } from '../chart/contstants'\r\nimport Pane from '../pane'\r\nimport { roundTimeForSyncedPane } from './mouse-utils'\r\n\r\nexport class Mouse extends Spine.Model {\r\n static initClass() {\r\n this.configure('Mouse', 'position')\r\n this.belongsTo('pane', Pane)\r\n }\r\n\r\n declare position: { x: number; y: number } | undefined\r\n declare pane: () => Pane | null\r\n\r\n getIsCrossSyncOn = () => !!this.pane()?.chart().getIsChartPartInSync(ChartSyncablePart.Crosshair)\r\n\r\n getIsMouseInChartOfPane = (pane: Pane) => !!this.pane()?.chart().eql(pane.chart())\r\n\r\n getShouldRenderCrossInPane = (pane: Pane) => this.getIsCrossSyncOn() || this.getIsMouseInChartOfPane(pane)\r\n\r\n getCrossIndexForPane = (pane: Pane) => {\r\n if (this.position) {\r\n if (this.getIsMouseInChartOfPane(pane)) {\r\n return Math.round(this.position.x)\r\n }\r\n const paneOfMouse = this.pane()\r\n if (this.getIsCrossSyncOn() && paneOfMouse) {\r\n const mouseInChart = paneOfMouse.chart()\r\n const currentPaneChart = pane.chart()\r\n const mousePositionTimestamp = mouseInChart.quote().getTimestampFomPositionX(Math.round(this.position.x))\r\n const currentPanePositionX = currentPaneChart.quote().getPositionXFromTimestamp(\r\n roundTimeForSyncedPane({\r\n sourceChart: mouseInChart,\r\n targetChart: currentPaneChart,\r\n timestamp: mousePositionTimestamp,\r\n })\r\n )\r\n return Math.floor(currentPanePositionX)\r\n }\r\n }\r\n\r\n return Number.NaN\r\n }\r\n\r\n getPriceForPane = (pane: Pane) => {\r\n const positionY = this.position?.y ?? null\r\n\r\n if (this.pane()?.eql(pane)) {\r\n return positionY\r\n }\r\n\r\n if (this.getIsCrossSyncOn() && this.pane()) {\r\n const mousePaneIndex = this.pane()?.getIndexInChart()\r\n const currentPaneIndex = pane.getIndexInChart()\r\n return mousePaneIndex === currentPaneIndex ? positionY : null\r\n }\r\n\r\n return null\r\n }\r\n}\r\n\r\n/**\r\n * Mouse is a singleton, so `initClass` must be called before we create the instance\r\n * otherwise it wouldn’t work\r\n */\r\nMouse.initClass()\r\n\r\nconst mouse = Mouse.create()\r\nmouse.save()\r\n\r\nexport default mouse as Mouse\r\n","import Spine, { Collection } from '@finviz/spine'\r\nimport omit from 'lodash.omit'\r\n\r\nimport { Position, TodoObjectHashAnyType } from '../../types/shared'\r\nimport CanvasElement from '../canvas/element'\r\nimport { ChartEventBadgeType, PANE_HEIGHT_DEFAULT } from '../constants/common'\r\nimport { getChartLayoutSettings } from '../models/settings'\r\nimport Chart from './chart'\r\nimport ChartEventElement from './chart-event-element'\r\nimport Element from './element'\r\nimport { rebuildElementZIndexes } from './utils'\r\n\r\nexport interface ScaleAxis {\r\n (index: number): number\r\n invert: (x: number) => number\r\n domain: () => [currentDomainMax: number, currentDomainMin: number]\r\n width: (x: number) => number\r\n height: (y: number) => number\r\n ticks: (y: number) => number[]\r\n}\r\n\r\nconst CHART_EVENT_BADGE_TYPE_ORDER = [\r\n ChartEventBadgeType.Split,\r\n ChartEventBadgeType.Dividends,\r\n ChartEventBadgeType.EarningsPositive,\r\n ChartEventBadgeType.EarningsNegative,\r\n ChartEventBadgeType.EarningsNeutral,\r\n ChartEventBadgeType.EarningsFuture,\r\n]\r\n\r\nclass Pane extends Spine.Model {\r\n static initClass(\r\n elementModel: typeof Element,\r\n chartEventElementModel: typeof ChartEventElement,\r\n chartModel: typeof Chart\r\n ) {\r\n this.configure('Pane', 'height', 'scale', 'scaleRange', 'instance', 'selection')\r\n this.hasMany('elements', elementModel)\r\n this.hasMany('chartEvents', chartEventElementModel)\r\n this.belongsTo('mainElement', elementModel)\r\n this.belongsTo('chart', chartModel)\r\n }\r\n\r\n declare id: string\r\n declare chart_id: string\r\n declare height: number\r\n declare scale: {\r\n x: ScaleAxis\r\n y: ScaleAxis\r\n }\r\n\r\n declare instance: any\r\n declare chart: () => Chart\r\n declare mainElement: () => T | null\r\n declare elements: () => Collection\r\n declare chartEvents: () => Collection\r\n selection: CanvasElement | null = null\r\n scaleRange: { min: number; max: number } | null = null\r\n\r\n destroyCascade(options?: TodoObjectHashAnyType) {\r\n this.elements()\r\n .all()\r\n .forEach((element) => {\r\n element.destroyCascade()\r\n })\r\n return this.destroy(options)\r\n }\r\n\r\n toObject() {\r\n const elements = this.elements()\r\n .all()\r\n .map((el) => el.toObject())\r\n return {\r\n height: this.height,\r\n scale: this.scale,\r\n scaleRange: this.scaleRange,\r\n elements,\r\n }\r\n }\r\n\r\n toConfig(omitKeys = [] as string[]) {\r\n const elements = this.elements()\r\n .all()\r\n .map((el) => el.toConfig())\r\n return omit(\r\n {\r\n height: this.height,\r\n scaleRange: this.scaleRange,\r\n elements,\r\n },\r\n omitKeys\r\n )\r\n }\r\n\r\n move(direction: Position) {\r\n const chartPanes = this.chart().getAllPanes()\r\n const chartPane = chartPanes.find((pane) => !pane.getIsIndicatorPane())\r\n const targetPane = chartPanes.find((pane) => this.eql(pane))\r\n\r\n if (!chartPane || !targetPane) return\r\n\r\n const currentChartPaneRecords = Pane.records.filter((pane) => pane.chart_id === targetPane.chart_id)\r\n const ohterChartPaneRecords = Pane.records.filter((pane) => pane.chart_id !== targetPane.chart_id)\r\n\r\n const targetRecordIndex = currentChartPaneRecords.findIndex((record) => record.id === targetPane.id)\r\n const arrayWithoutTargetRecord = currentChartPaneRecords.filter((_, index) => index !== targetRecordIndex)\r\n const chartRecordIndex = arrayWithoutTargetRecord.findIndex((record) => record.id === chartPane.id)\r\n\r\n const panesAbove = arrayWithoutTargetRecord.slice(0, chartRecordIndex)\r\n const panesBelow = arrayWithoutTargetRecord.slice(chartRecordIndex + 1)\r\n if (direction === Position.Above) {\r\n panesAbove.push(currentChartPaneRecords[targetRecordIndex])\r\n panesAbove.sort((a, b) => a.getNumericId() - b.getNumericId())\r\n }\r\n if (direction === Position.Below) {\r\n panesBelow.push(currentChartPaneRecords[targetRecordIndex])\r\n panesBelow.sort((a, b) => a.getNumericId() - b.getNumericId())\r\n }\r\n\r\n Pane.records = ohterChartPaneRecords.concat([\r\n ...panesAbove,\r\n arrayWithoutTargetRecord[chartRecordIndex],\r\n ...panesBelow,\r\n ])\r\n this.chart().trigger('change', this.chart())\r\n }\r\n\r\n getChartLayoutSettings() {\r\n return getChartLayoutSettings(this.chart().chart_layout())\r\n }\r\n\r\n getAllElements() {\r\n return this.elements()\r\n .all()\r\n .sort((a, b) => a.zIndex - b.zIndex)\r\n }\r\n\r\n getAllChartEvents(isSorted = true) {\r\n const chartEvents = [...this.chartEvents().all()]\r\n return isSorted ? chartEvents.sort((a, b) => a.zIndex - b.zIndex) : chartEvents\r\n }\r\n\r\n getChartOrIndicatorElement() {\r\n return this.getAllElements().find((el) => el.isChart() || el.isIndicator()) ?? null\r\n }\r\n\r\n getIsIndicatorPane() {\r\n return !!this.mainElement()?.isIndicator()\r\n }\r\n\r\n getIsChartPane() {\r\n return !!this.mainElement()?.isChart()\r\n }\r\n\r\n resetHeight() {\r\n if (this.getIsIndicatorPane()) {\r\n this.updateAttribute('height', PANE_HEIGHT_DEFAULT.indicator)\r\n }\r\n if (this.getIsChartPane()) {\r\n this.updateAttribute('height', PANE_HEIGHT_DEFAULT.chart)\r\n }\r\n }\r\n\r\n getIndexInChart() {\r\n return this.chart()\r\n .getAllPanes()\r\n .findIndex((chartPane) => chartPane.eql(this))\r\n }\r\n\r\n getElementZIndexRange() {\r\n let max = -1\r\n let min = 1\r\n this.getAllElements().forEach((el) => {\r\n if (el.zIndex > max) {\r\n max = el.zIndex\r\n }\r\n if (el.zIndex < min) {\r\n min = el.zIndex\r\n }\r\n })\r\n return { min, max }\r\n }\r\n\r\n getBelowAboveZeroElements() {\r\n const allPaneElements = this.getAllElements()\r\n const elementsBelowZero: Element[] = []\r\n const elementsAboveZero: Element[] = []\r\n allPaneElements.forEach((el) => {\r\n if (el.zIndex < 0) {\r\n elementsBelowZero.push(el)\r\n }\r\n if (el.zIndex > 0) {\r\n elementsAboveZero.push(el)\r\n }\r\n })\r\n\r\n return { elementsBelowZero, elementsAboveZero }\r\n }\r\n\r\n normalizeZIndexes() {\r\n const { elementsBelowZero, elementsAboveZero } = this.getBelowAboveZeroElements()\r\n rebuildElementZIndexes({ elementsArray: elementsBelowZero, isBelowZero: true })\r\n rebuildElementZIndexes({ elementsArray: elementsAboveZero, isBelowZero: false })\r\n }\r\n\r\n getQuoteRawTicker() {\r\n return this.chart().getQuoteRawTicker()\r\n }\r\n\r\n getNumericId() {\r\n return Number(this.id.replace('c-', ''))\r\n }\r\n\r\n updateChartEventsZIndexes() {\r\n if (!this.scale || !this.scale.hasOwnProperty('x')) {\r\n return\r\n }\r\n\r\n const chartEvents = this.getAllChartEvents(false).sort(\r\n (a, b) => a.instance.attrs.positionTimestamps!.x - b.instance.attrs.positionTimestamps!.x\r\n )\r\n const hoveredChartEvent = chartEvents.find((chartEvent) => chartEvent.instance.isHovered)\r\n const openedChartEvent = chartEvents.find((chartEvent) => chartEvent.instance.isOpen)\r\n\r\n const hoveredTypeChartEventElements: ChartEventElement[] = []\r\n const openedTypeChartEventElements: ChartEventElement[] = []\r\n const nonActiveChartEventElements: ChartEventElement[] = []\r\n\r\n chartEvents.forEach((chartEvent, index) => {\r\n const chartEventsOnSameXPoint = chartEvents.filter(\r\n (chartEvent_B, i) =>\r\n i < index && Math.round(chartEvent.instance.attrs.x) === Math.round(chartEvent_B!.instance.attrs.x)\r\n )\r\n chartEvent.updateAttributes({ yIndex: chartEventsOnSameXPoint.length })\r\n const isHovered = chartEvent.instance === hoveredChartEvent?.instance\r\n const isOpened = chartEvent.instance === openedChartEvent?.instance\r\n const isHoveredType = chartEvent.instance.type === hoveredChartEvent?.instance.type\r\n const isOpenType = chartEvent.instance.type === openedChartEvent?.instance.type\r\n if (!isHovered || !isOpened) {\r\n if (isHoveredType) {\r\n hoveredTypeChartEventElements.push(chartEvent)\r\n } else if (isOpenType) {\r\n openedTypeChartEventElements.push(chartEvent)\r\n } else {\r\n nonActiveChartEventElements.push(chartEvent)\r\n }\r\n }\r\n })\r\n\r\n nonActiveChartEventElements.sort(\r\n (a, b) =>\r\n CHART_EVENT_BADGE_TYPE_ORDER.indexOf(a.instance.getChartEvenBadgeType()) -\r\n CHART_EVENT_BADGE_TYPE_ORDER.indexOf(b.instance.getChartEvenBadgeType())\r\n )\r\n\r\n const chartEventElements = [\r\n ...nonActiveChartEventElements,\r\n ...openedTypeChartEventElements,\r\n openedChartEvent,\r\n ...hoveredTypeChartEventElements,\r\n hoveredChartEvent,\r\n ].filter(Boolean)\r\n chartEventElements.forEach((chartEvent, index) => {\r\n chartEvent!.updateAttributes({ zIndex: index })\r\n })\r\n }\r\n}\r\n\r\nexport default Pane\r\n","import { ObjectHash, RequireByKey } from '../../types/shared'\r\n\r\ninterface HeikinAshiData {\r\n HAOpen: number[]\r\n HAClose: number[]\r\n}\r\n\r\ninterface QuoteValues {\r\n cachedAt: null | number\r\n dayToOffset: ObjectHash[]\r\n dateToIndex: ObjectHash[]\r\n heikinAshiData?: HeikinAshiData\r\n daysInQuote: Date[]\r\n}\r\n\r\ninterface QuoteCacheFunctionProps {\r\n cid: string\r\n key: keyof QuoteValues\r\n fetchedAt: number\r\n value: any\r\n}\r\n\r\nconst quoteCache = {} as ObjectHash\r\n\r\nexport function getCachedQuote({\r\n cid,\r\n key,\r\n fetchedAt,\r\n}: RequireByKey>, 'cid'>) {\r\n const quote = quoteCache[cid]\r\n if (quote?.cachedAt === fetchedAt && key) {\r\n return quote[key]\r\n } else if (!key) {\r\n return quote\r\n }\r\n return null\r\n}\r\n\r\nexport function setCachedQuote({\r\n cid,\r\n key,\r\n value,\r\n fetchedAt,\r\n}: Pick) {\r\n quoteCache[cid] = {\r\n ...(quoteCache[cid]?.cachedAt === fetchedAt ? quoteCache[cid] : {}),\r\n [key]: value,\r\n cachedAt: fetchedAt,\r\n } as QuoteValues\r\n}\r\n\r\nexport function deleteCachedQuote({ cid }: Pick) {\r\n delete quoteCache[cid]\r\n}\r\n","import Spine from '@finviz/spine'\r\nimport { isSameMonth, isSameWeek } from 'date-fns'\r\nimport queryString from 'query-string'\r\n\r\nimport { Instrument, ObjectHash, TodoObjectHashAnyType } from '../../types/shared'\r\nimport { ChartEventDbType, ChartEventType, IntradayTimeframeInterval, TIMEFRAME } from '../constants/common'\r\nimport type { ICOT } from '../indicators/cot'\r\nimport { dateFromUnixTimestamp, dateStringFromDate } from '../utils'\r\nimport { getIsAbortError } from '../utils/abort_controller'\r\nimport { getPositionXFromTimestamp, getTimestampFromPositionX } from '../utils/chart'\r\nimport { IDividends, IEarnings, ISplit } from '../utils/chart-events-utils'\r\nimport fetchApi, { NotFoundError } from '../utils/fetch_api'\r\nimport { getIsSSr } from '../utils/helpers'\r\nimport { QuoteFetchType, QuoteFetchTypeUrlOption, QuoteUrlOptions } from './quote/constants'\r\nimport { deleteCachedQuote, getCachedQuote, setCachedQuote } from './quoteCache'\r\nimport { getRawTickerForInstrument } from './utils'\r\n\r\nconst quoteRefreshChecksBeforeFullRefresh = 15\r\n\r\ntype TodoPattern = TodoObjectHashAnyType\r\n\r\nexport interface TickerTimeframesProps {\r\n ticker: string\r\n instrument: string\r\n timeframe: string\r\n}\r\n\r\ninterface QuoteFetchOptions {\r\n aftermarket?: boolean\r\n premarket?: boolean\r\n patterns?: boolean\r\n events?: boolean\r\n maxBars?: number\r\n}\r\n\r\ninterface QuoteInternalOptions {\r\n cachePredicate?: (quote: Quote) => boolean\r\n fetchNewDataOnCachedQuote?: boolean\r\n}\r\n\r\ninterface UrlOptions extends QuoteFetchOptions {\r\n ticker: string\r\n instrument: string\r\n timeframe: string\r\n}\r\n\r\ntype ChartEventDataRaw = Omit & { eventType: ChartEventDbType }\r\n\r\nexport interface DataResponse {\r\n COTs: COTData\r\n name: string\r\n ticker: string\r\n instrument: string\r\n interval: number\r\n timeframe: string\r\n open: number[]\r\n high: number[]\r\n low: number[]\r\n close: number[]\r\n date: number[]\r\n volume: number[]\r\n lastOpen: number\r\n lastHigh: number\r\n lastLow: number\r\n lastClose: number\r\n lastDate: number\r\n lastTime: string | null\r\n lastVolume: number\r\n dataId: string\r\n prevClose: number\r\n afterClose: number\r\n afterChange: number\r\n afterTime: string | null\r\n drawMinutesPerDay: number\r\n marketStartMinutes: number\r\n premarketLengthMinutes: number\r\n aftermarketLengthMinutes: number\r\n aftermarket: boolean\r\n premarket: boolean\r\n hasPatterns: boolean\r\n patterns: Array\r\n patternsMinRange: number\r\n patternsMaxRange: number\r\n relativeVolume: number\r\n isIntraday: boolean\r\n noNewData?: boolean\r\n chartEvents?: ChartEventDataRaw[]\r\n}\r\n\r\ninterface COTData {\r\n [code: string]: ICOT\r\n}\r\n\r\nconst emptyQuote = {\r\n open: [],\r\n high: [],\r\n low: [],\r\n close: [],\r\n volume: [],\r\n date: [],\r\n fetchedAt: -1,\r\n numberOfRefreshChecks: 0,\r\n isFetching: false,\r\n is404: false,\r\n COTs: undefined,\r\n name: undefined,\r\n drawMinutesPerDay: undefined,\r\n marketStartMinutes: undefined,\r\n premarketLengthMinutes: undefined,\r\n aftermarketLengthMinutes: undefined,\r\n patterns: [],\r\n patternsMinRange: undefined,\r\n patternsMaxRange: undefined,\r\n relativeVolume: undefined,\r\n lastOpen: undefined,\r\n lastHigh: undefined,\r\n lastLow: undefined,\r\n lastClose: undefined,\r\n lastVolume: undefined,\r\n dataId: undefined,\r\n lastDate: undefined,\r\n prevClose: undefined,\r\n afterClose: undefined,\r\n afterChange: undefined,\r\n chartEvents: [],\r\n}\r\n\r\ninterface ICacheAvailabilityCheckFunctionsArguments {\r\n quote: Quote\r\n options?: QuoteFetchOptions & QuoteInternalOptions\r\n}\r\n\r\nconst doesQuoteAndOptionsMatch = ({ quote, options }: ICacheAvailabilityCheckFunctionsArguments) =>\r\n !quote.premarket === !options?.premarket &&\r\n !quote.aftermarket === !options?.aftermarket &&\r\n !quote.hasPatterns === !options?.patterns &&\r\n // if options.events is false we can reuse quote with events\r\n (!options?.events || !!quote.events)\r\n\r\nconst doesQuoteAndFetchParamsMatch = ({\r\n quote,\r\n ticker,\r\n instrument,\r\n timeframe,\r\n}: {\r\n quote: Quote\r\n ticker: string\r\n instrument: Instrument\r\n timeframe: TIMEFRAME\r\n}) => quote.ticker === ticker && quote.instrument === instrument && quote.timeframe === timeframe\r\n\r\n// either we don't care about matching uuid at all, or they have to match\r\nconst isSameOrNoChartUuid = ({ quote, uuid }: { quote: Quote; uuid?: string }) => !uuid || quote.chartUuid === uuid\r\n\r\nconst isCacheAllowed = ({ quote, options }: ICacheAvailabilityCheckFunctionsArguments) =>\r\n !options?.cachePredicate || options.cachePredicate(quote)\r\n\r\nconst isNotEmptyQuote = (quote: Quote) => quote.fetchedAt !== -1 || quote.isFetching\r\n\r\nexport type QuoteGetParams = {\r\n ticker: string\r\n instrument: Instrument\r\n timeframe: TIMEFRAME\r\n options?: QuoteFetchOptions & QuoteInternalOptions\r\n abortController?: null | AbortController\r\n shouldUseCache?: boolean\r\n chartUuid?: string\r\n}\r\n\r\nfunction getChartEventsWithId({ ticker, chartEvents }: { ticker: string; chartEvents?: ChartEventDataRaw[] }) {\r\n return (\r\n chartEvents?.map((item) => {\r\n let eventType: ChartEventType\r\n switch (item.eventType) {\r\n case ChartEventDbType.Dividends:\r\n eventType = ChartEventType.Dividends\r\n break\r\n case ChartEventDbType.Split:\r\n eventType = ChartEventType.Split\r\n break\r\n case ChartEventDbType.Earnings:\r\n eventType = ChartEventType.Earnings\r\n break\r\n }\r\n return {\r\n ...item,\r\n elementId: `${ticker.toLowerCase()}-${item.eventType}-${item.dateTimestamp}`,\r\n eventType,\r\n }\r\n }) ?? []\r\n )\r\n}\r\n\r\nclass Quote extends Spine.Model {\r\n static initClass() {\r\n this.configure(\r\n 'Quote',\r\n 'ticker',\r\n 'name',\r\n 'instrument',\r\n 'timeframe',\r\n 'open',\r\n 'high',\r\n 'low',\r\n 'close',\r\n 'date',\r\n 'volume',\r\n 'lastOpen',\r\n 'lastHigh',\r\n 'lastLow',\r\n 'lastClose',\r\n 'lastDate',\r\n 'lastVolume',\r\n 'lastTime',\r\n 'dataId',\r\n 'prevClose',\r\n 'COTs',\r\n 'chartEvents',\r\n 'afterClose',\r\n 'afterChange',\r\n 'afterTime',\r\n 'drawMinutesPerDay',\r\n 'marketStartMinutes',\r\n 'premarketLengthMinutes',\r\n 'aftermarketLengthMinutes',\r\n 'aftermarket',\r\n 'premarket',\r\n 'events',\r\n 'hasPatterns',\r\n 'patterns',\r\n 'patternsMinRange',\r\n 'patternsMaxRange',\r\n 'relativeVolume',\r\n 'fetchedAt',\r\n 'isIntraday',\r\n 'interval',\r\n 'drawDays',\r\n 'barIndex',\r\n 'barToDataIndex',\r\n 'fetchingPromise',\r\n 'isFetching',\r\n 'wasFetchAborted',\r\n 'chartUuid',\r\n 'numberOfRefreshChecks',\r\n 'maxBars',\r\n 'ideaID',\r\n 'is404'\r\n )\r\n }\r\n\r\n static async get({\r\n ticker: tickerRaw,\r\n instrument,\r\n timeframe,\r\n options,\r\n abortController,\r\n shouldUseCache = true,\r\n chartUuid,\r\n }: QuoteGetParams): Promise {\r\n const ticker = tickerRaw.replace('@', '')\r\n const [quote] = shouldUseCache\r\n ? Quote.select(\r\n (q) =>\r\n doesQuoteAndFetchParamsMatch({ quote: q, ticker, instrument, timeframe }) &&\r\n isSameOrNoChartUuid({ quote: q, uuid: chartUuid }) &&\r\n isNotEmptyQuote(q) &&\r\n isCacheAllowed({ quote: q, options }) &&\r\n (q.instrument !== Instrument.Stock ||\r\n Number.isInteger(q.ideaID) ||\r\n doesQuoteAndOptionsMatch({ quote: q, options }))\r\n )\r\n : []\r\n\r\n if (quote) {\r\n if (quote.isFetching) {\r\n await quote.getResolvedFetchingPromise()\r\n } else if (options?.fetchNewDataOnCachedQuote) {\r\n await quote.fetchData({ fetchType: QuoteFetchType.NewerData, abortController })\r\n }\r\n return quote\r\n }\r\n\r\n const newQuote = Quote.create({\r\n ...emptyQuote,\r\n ticker,\r\n timeframe,\r\n instrument,\r\n chartUuid,\r\n maxBars: options?.maxBars,\r\n premarket: !!options?.premarket,\r\n aftermarket: !!options?.aftermarket,\r\n hasPatterns: !!options?.patterns,\r\n events: !!options?.events,\r\n })\r\n\r\n await newQuote.fetchData({ fetchType: QuoteFetchType.Refetch, abortController })\r\n\r\n return newQuote\r\n }\r\n\r\n static async getAll(tickersAndTimeframes: Array<{ ticker: string; instrument: Instrument; timeframe: TIMEFRAME }>) {\r\n // TODO: fetch in 1 request\r\n if (tickersAndTimeframes.length === 0) {\r\n return {}\r\n }\r\n\r\n try {\r\n await Promise.all(\r\n tickersAndTimeframes.map(({ ticker, instrument, timeframe }) =>\r\n this.get({ ticker: ticker, instrument, timeframe })\r\n )\r\n )\r\n const data = tickersAndTimeframes.reduce(\r\n (accumulator, currentValue) => ({\r\n ...accumulator,\r\n [currentValue.ticker]: Quote.select(\r\n (q: Quote) =>\r\n q.ticker === currentValue.ticker &&\r\n q.instrument === currentValue.instrument &&\r\n q.timeframe === currentValue.timeframe\r\n )[0],\r\n }),\r\n {}\r\n )\r\n return data\r\n } catch (err) {\r\n // TODO: handle somehow\r\n }\r\n }\r\n\r\n declare ticker: string\r\n declare name: string\r\n declare instrument: Instrument\r\n declare interval: number\r\n declare timeframe: TIMEFRAME\r\n declare open: number[]\r\n declare high: number[]\r\n declare low: number[]\r\n declare close: number[]\r\n declare date: number[]\r\n declare volume: number[]\r\n declare lastOpen: number\r\n declare lastHigh: number\r\n declare lastLow: number\r\n declare lastClose: number\r\n declare lastDate: number\r\n declare lastVolume: number\r\n declare dataId: string\r\n declare prevClose: number\r\n declare COTs: COTData\r\n declare afterClose: number\r\n declare afterChange: number\r\n declare drawMinutesPerDay: number\r\n declare marketStartMinutes: number\r\n declare premarketLengthMinutes: number\r\n declare aftermarketLengthMinutes: number\r\n declare hasPatterns: boolean\r\n declare patterns: Array\r\n declare patternsMinRange: number\r\n declare patternsMaxRange: number\r\n declare relativeVolume: number\r\n declare isIntraday: boolean\r\n declare drawDays?: number\r\n declare barIndex: number[]\r\n /**\r\n * Array of length the same as number of bars\r\n *\r\n * If there's a gap and a bar index has no corresponding data index,\r\n * the last data index is used (or 0 if there's no last data index)\r\n *\r\n * @type {number[]}\r\n */\r\n declare barToDataIndex: number[]\r\n declare chartUuid?: string\r\n declare aftermarket: boolean\r\n declare premarket: boolean\r\n declare fetchedAt: number\r\n declare numberOfRefreshChecks: number\r\n declare isFetching: boolean\r\n declare fetchingPromise?: Promise\r\n declare wasFetchAborted: boolean\r\n declare maxBars?: number\r\n declare ideaID?: number\r\n declare is404?: boolean\r\n declare chartEvents: Array\r\n declare events?: boolean\r\n\r\n async fetchRequest({\r\n abortController,\r\n options = { type: QuoteFetchTypeUrlOption.New },\r\n }: {\r\n abortController?: null | AbortController\r\n options?: QuoteUrlOptions\r\n }) {\r\n let data: DataResponse | null = null\r\n let is404 = false\r\n let wasFetchAborted = false\r\n\r\n const fetchingPromise = fetchApi({\r\n location: this.getUrl(options),\r\n throwOnStatusCodes: [404],\r\n abortController,\r\n })\r\n\r\n this.updateAttributes({\r\n isFetching: true,\r\n fetchingPromise,\r\n })\r\n\r\n try {\r\n data = await fetchingPromise\r\n } catch (err) {\r\n if (getIsAbortError(err as Error)) {\r\n wasFetchAborted = true\r\n } else if (process.env.IS_E2E_TESTING) {\r\n throw new Error('Quote fetch error', { cause: err })\r\n }\r\n is404 = err instanceof NotFoundError\r\n // Ignore network/notfound errors\r\n }\r\n\r\n const shouldUseEmptyQuote = !data && !wasFetchAborted && options.type === QuoteFetchTypeUrlOption.New\r\n\r\n if (process.env.IS_E2E_TESTING && shouldUseEmptyQuote) {\r\n throw new Error('Quote fetch new fail', { cause: { options, is404, wasFetchAborted, data } })\r\n }\r\n\r\n this.updateAttributes({\r\n ...(shouldUseEmptyQuote ? emptyQuote : {}),\r\n is404,\r\n wasFetchAborted,\r\n isFetching: false,\r\n })\r\n\r\n return data\r\n }\r\n\r\n async isPossibleToFetchSequentialData({\r\n abortController,\r\n }: {\r\n abortController?: null | AbortController\r\n } = {}) {\r\n const data = await this.fetchRequest({ abortController })\r\n if (data && data.date.length > 0 && this.date.length > 0) {\r\n return this.date[this.date.length - 1] >= data.date[0]\r\n }\r\n return false\r\n }\r\n\r\n async fetchData({\r\n fetchType,\r\n abortController,\r\n }: {\r\n fetchType: QuoteFetchType\r\n abortController?: null | AbortController\r\n }) {\r\n let options: QuoteUrlOptions\r\n if (fetchType === QuoteFetchType.Refetch) {\r\n options = { type: QuoteFetchTypeUrlOption.New }\r\n } else if (fetchType === QuoteFetchType.NewerData) {\r\n options = { type: QuoteFetchTypeUrlOption.Newer }\r\n if ((this.numberOfRefreshChecks ?? 0) < quoteRefreshChecksBeforeFullRefresh) {\r\n options.dataId = this.dataId\r\n }\r\n } else {\r\n return\r\n }\r\n if (this.instrument === Instrument.Stock) {\r\n options.events = this.events == null ? true : this.events\r\n }\r\n\r\n const data = await this.fetchRequest({ abortController, options })\r\n\r\n if (!data || data.noNewData === true) {\r\n this.updateAttributes({\r\n numberOfRefreshChecks: (this.numberOfRefreshChecks ?? 0) + 1,\r\n })\r\n return\r\n }\r\n if (this.timeframe !== data.timeframe || this.ticker.toLowerCase() !== data.ticker?.toLowerCase()) {\r\n return\r\n }\r\n\r\n const newQuoteData = {\r\n COTs: data.COTs,\r\n name: data.name,\r\n open: data.open,\r\n high: data.high,\r\n low: data.low,\r\n close: data.close,\r\n volume: data.volume,\r\n date: data.date,\r\n drawMinutesPerDay: data.drawMinutesPerDay,\r\n marketStartMinutes: data.marketStartMinutes,\r\n premarketLengthMinutes: data.premarketLengthMinutes,\r\n aftermarketLengthMinutes: data.aftermarketLengthMinutes,\r\n patterns: data.patterns ?? [],\r\n patternsMinRange: data.patternsMinRange,\r\n patternsMaxRange: data.patternsMaxRange,\r\n relativeVolume: data.relativeVolume,\r\n lastOpen: data.lastOpen,\r\n lastHigh: data.lastHigh,\r\n lastLow: data.lastLow,\r\n lastClose: data.lastClose,\r\n lastVolume: data.lastVolume,\r\n dataId: data.dataId,\r\n lastDate: data.lastDate,\r\n lastTime: data.lastTime,\r\n prevClose: data.prevClose,\r\n afterClose: data.afterClose,\r\n afterChange: data.afterChange,\r\n afterTime: data.afterTime,\r\n numberOfRefreshChecks: 0,\r\n chartEvents: data.chartEvents ?? [],\r\n fetchedAt: Date.now(),\r\n }\r\n\r\n if (\r\n !(\r\n fetchType === QuoteFetchType.Refetch ||\r\n [Instrument.Futures, Instrument.Forex, Instrument.Crypto].includes(this.instrument)\r\n )\r\n ) {\r\n /*\r\n * Merges current and new data taking date as index\r\n */\r\n let AIndex = 0\r\n let BIndex = 0\r\n let mergeIndex = -1\r\n while (AIndex < this.date.length || BIndex < data.date.length) {\r\n const ADate = this.date[AIndex]\r\n const BDate = data.date[BIndex]\r\n if (BDate === undefined) {\r\n break\r\n } else if (ADate === BDate) {\r\n // Same date, update OHLCV\r\n this.open[AIndex] = data.open[BIndex]\r\n this.high[AIndex] = data.high[BIndex]\r\n this.low[AIndex] = data.low[BIndex]\r\n this.close[AIndex] = data.close[BIndex]\r\n this.volume[AIndex] = data.volume[BIndex]\r\n AIndex++\r\n BIndex++\r\n } else if (ADate > BDate || ADate === undefined) {\r\n // New bar for a date not yet in our dataset\r\n // If weekly or monthly timeframe & wasn't merged on AIndex\r\n if (mergeIndex === -1 && [TIMEFRAME.w, TIMEFRAME.m].includes(this.timeframe)) {\r\n const prevAIndex = AIndex - 1\r\n const prevDate = dateFromUnixTimestamp(this.date[prevAIndex])\r\n const newDate = dateFromUnixTimestamp(data.date[BIndex])\r\n // If merge bar for weekly is sameWeek or for monthly is sameMonth perform merge on AIndex\r\n if (\r\n (TIMEFRAME.w === this.timeframe && isSameWeek(prevDate, newDate, { weekStartsOn: 1 })) ||\r\n (TIMEFRAME.m === this.timeframe && isSameMonth(prevDate, newDate))\r\n ) {\r\n this.date[prevAIndex] = data.date[BIndex]\r\n this.open[prevAIndex] = data.open[BIndex]\r\n this.high[prevAIndex] = data.high[BIndex]\r\n this.low[prevAIndex] = data.low[BIndex]\r\n this.close[prevAIndex] = data.close[BIndex]\r\n this.volume[prevAIndex] = data.volume[BIndex]\r\n mergeIndex = prevAIndex\r\n // Incrementing BIndex only because we're mergin arrays on AIndex\r\n BIndex++\r\n continue\r\n }\r\n }\r\n this.date.splice(AIndex, 0, data.date[BIndex])\r\n this.open.splice(AIndex, 0, data.open[BIndex])\r\n this.high.splice(AIndex, 0, data.high[BIndex])\r\n this.low.splice(AIndex, 0, data.low[BIndex])\r\n this.close.splice(AIndex, 0, data.close[BIndex])\r\n this.volume.splice(AIndex, 0, data.volume[BIndex])\r\n // Incrementing AIndex because we're changing the array in-place\r\n AIndex++\r\n BIndex++\r\n } else if (ADate < BDate) {\r\n AIndex++\r\n } else {\r\n console.warn('fetchNewerData merge warning')\r\n window.Sentry?.captureMessage('quote.ts fetchNewerData merge warning', {\r\n extra: {\r\n thisDateLength: this.date.length,\r\n dataDateLength: data.date.length,\r\n AIndex,\r\n BIndex,\r\n ADate,\r\n BDate,\r\n },\r\n })\r\n }\r\n }\r\n\r\n newQuoteData.date = this.date\r\n newQuoteData.open = this.open\r\n newQuoteData.high = this.high\r\n newQuoteData.low = this.low\r\n newQuoteData.close = this.close\r\n newQuoteData.volume = this.volume\r\n }\r\n\r\n const hasUpdatedSuccessfully = this.updateAttributes(newQuoteData)\r\n // https://github.com/finvizhq/charts/issues/510\r\n if (!hasUpdatedSuccessfully) {\r\n // attempt to find if this.model.quote() => null is comming from this.save() validation fail\r\n window.Sentry?.captureMessage('quote.ts fetchNewerData save() validation failed', { extra: this })\r\n }\r\n if (!this) {\r\n // or this somehow became null / falsy\r\n window.Sentry?.captureMessage('quote.ts fetchNewerData this is falsy', { extra: this })\r\n }\r\n this.trigger(fetchType, this, fetchType)\r\n }\r\n\r\n async getResolvedFetchingPromise() {\r\n try {\r\n return await this.fetchingPromise\r\n } catch {\r\n // do nothing\r\n }\r\n }\r\n\r\n fetchOlderData() {\r\n return // not yet implemented\r\n // TODO cancel previous request\r\n }\r\n\r\n load(atts: ObjectHash) {\r\n super.load(atts)\r\n const { fetchedAt = 0 } = atts\r\n const { cachedAt } = (getCachedQuote({ cid: this.cid }) as { cachedAt: number } | null) || {}\r\n if (this.timeframe && cachedAt !== fetchedAt) {\r\n setCachedQuote({ cid: this.cid, key: 'cachedAt', value: fetchedAt, fetchedAt })\r\n this.isIntraday = [\r\n TIMEFRAME.i1,\r\n TIMEFRAME.i2,\r\n TIMEFRAME.i3,\r\n TIMEFRAME.i5,\r\n TIMEFRAME.i10,\r\n TIMEFRAME.i15,\r\n TIMEFRAME.i30,\r\n TIMEFRAME.h,\r\n TIMEFRAME.h2,\r\n TIMEFRAME.h4,\r\n ].includes(this.timeframe)\r\n this.interval = this.isIntraday\r\n ? IntradayTimeframeInterval[this.timeframe as keyof typeof IntradayTimeframeInterval]\r\n : 0\r\n this.drawDays = this.getDrawDays()\r\n this.barIndex = this.getBarIndexes()\r\n this.patterns = this.patterns ?? []\r\n this.barToDataIndex = this.barIndex.flatMap((barIndex, index) => {\r\n const lastIndex = this.barIndex[index - 1] ?? -1\r\n return [...Array.from({ length: barIndex - lastIndex - 1 }).fill(Math.max(0, index - 1)), index] as number[]\r\n })\r\n }\r\n if (this.timeframe && this.ticker) {\r\n this.chartEvents = getChartEventsWithId({\r\n ticker: this.ticker,\r\n chartEvents: this.chartEvents as unknown as ChartEventDataRaw[],\r\n })\r\n }\r\n return this\r\n }\r\n\r\n destroy(options?: ObjectHash) {\r\n super.destroy(options)\r\n deleteCachedQuote({ cid: this.cid })\r\n return this\r\n }\r\n\r\n getDrawDays() {\r\n if (this.instrument !== Instrument.Stock) {\r\n return Infinity\r\n }\r\n switch (this.timeframe) {\r\n case TIMEFRAME.i1:\r\n case TIMEFRAME.i2:\r\n case TIMEFRAME.i3:\r\n case TIMEFRAME.i5:\r\n case TIMEFRAME.i10:\r\n return 10\r\n case TIMEFRAME.i15:\r\n case TIMEFRAME.i30:\r\n case TIMEFRAME.h:\r\n case TIMEFRAME.h2:\r\n case TIMEFRAME.h4:\r\n return 15\r\n default:\r\n break\r\n }\r\n }\r\n\r\n getHeikinAshiData() {\r\n const cachedHeikinAshiData = getCachedQuote({ cid: this.cid, key: 'heikinAshiData', fetchedAt: this.fetchedAt })\r\n if (cachedHeikinAshiData) {\r\n return cachedHeikinAshiData as unknown as { open: number[]; close: number[] }\r\n }\r\n\r\n const HAClose = this.open.map((_, i) => (this.open[i] + this.high[i] + this.close[i] + this.low[i]) / 4)\r\n const HAOpen = this.open.reduce(\r\n (acc, open, i) => [...acc, (i === 0 ? open + HAClose[0] : acc[i - 1] + HAClose[i - 1]) / 2],\r\n [] as number[]\r\n )\r\n\r\n const heikAshiData = { open: HAOpen, close: HAClose }\r\n\r\n setCachedQuote({ cid: this.cid, key: 'heikinAshiData', value: heikAshiData, fetchedAt: this.fetchedAt })\r\n\r\n return heikAshiData\r\n }\r\n\r\n getDayToOffset(): ObjectHash {\r\n const cachedDayToOffset = getCachedQuote({ cid: this.cid, key: 'dayToOffset', fetchedAt: this.fetchedAt })\r\n if (cachedDayToOffset) {\r\n return cachedDayToOffset as unknown as ObjectHash\r\n }\r\n const dayToOffset: ObjectHash = {}\r\n let day = 0\r\n let lastDay\r\n for (let i = 0, end = this.date.length, asc = end >= 0; asc ? i < end : i > end; asc ? i++ : i--) {\r\n const date = dateFromUnixTimestamp(this.date[i])\r\n const dateString = dateStringFromDate(date)\r\n if (dateString !== lastDay) {\r\n dayToOffset[dateString] = day\r\n day++\r\n lastDay = dateString\r\n }\r\n }\r\n // for ofscreen renderer we need to add lastDate to have correct dayToOffset because if\r\n // premarket=false in fetch query there isn't other way to distinguish that\r\n if (getIsSSr() && this.lastDate) {\r\n // YYYYMMDD / 20211118 => YYYY-MM-DD\r\n const [yyyy, mm, dd] = [~~(this.lastDate / 10000), ~~(this.lastDate / 100) % 100, this.lastDate % 100]\r\n const lastDate = `${yyyy}-${String(mm).padStart(2, '0')}-${String(dd).padStart(2, '0')}`\r\n\r\n if (lastDay !== lastDate) {\r\n dayToOffset[lastDate] = day\r\n }\r\n }\r\n\r\n setCachedQuote({ cid: this.cid, key: 'dayToOffset', value: dayToOffset, fetchedAt: this.fetchedAt })\r\n return dayToOffset\r\n }\r\n\r\n getDaysInQuote() {\r\n const cachedDayToOffset = getCachedQuote({ cid: this.cid, key: 'daysInQuote', fetchedAt: this.fetchedAt })\r\n if (cachedDayToOffset) {\r\n return cachedDayToOffset as unknown as Date[]\r\n }\r\n const dayToOffset = this.getDayToOffset()\r\n const daysInQuote = Object.keys(dayToOffset)\r\n .map((dateString) => {\r\n const [year, month, day] = dateString.split('-')\r\n return new Date(Number.parseInt(year), Number.parseInt(month) - 1, Number.parseInt(day))\r\n })\r\n .sort((a, b) => a.getTime() - b.getTime())\r\n\r\n setCachedQuote({ cid: this.cid, key: 'daysInQuote', value: daysInQuote, fetchedAt: this.fetchedAt })\r\n return daysInQuote\r\n }\r\n\r\n getBarIndexes() {\r\n if (!this.isIntraday || this.instrument !== Instrument.Stock) {\r\n return Array.from({ length: this.date.length }).map((_, index) => index)\r\n }\r\n\r\n const barIndex = []\r\n const dayToOffset = this.getDayToOffset()\r\n\r\n for (let i = 0; i < this.date.length; i += 1) {\r\n const date = dateFromUnixTimestamp(this.date[i])\r\n let x = Math.ceil((date.getHours() * 60 + date.getMinutes() - this.marketStartMinutes) / this.interval)\r\n x += dayToOffset[dateStringFromDate(date)] * this.getBarsInDay()! // add days\r\n barIndex[i] = x\r\n }\r\n\r\n return barIndex\r\n }\r\n\r\n getBarIndex(i: number) {\r\n if (!this.isIntraday || this.instrument !== Instrument.Stock) {\r\n return i\r\n }\r\n return this.barIndex[i]\r\n }\r\n\r\n getBarsInDay() {\r\n if (!this.isIntraday || this.instrument !== Instrument.Stock) {\r\n return\r\n }\r\n return Math.ceil(this.drawMinutesPerDay / this.interval)\r\n }\r\n\r\n getDataIndexByBarIndex(index: number) {\r\n if (this.barIndex) {\r\n for (let i = 0; i < this.barIndex.length; i++) {\r\n if (this.barIndex[i] === index) {\r\n return i\r\n }\r\n }\r\n }\r\n return -1\r\n }\r\n\r\n getDataByBarIndex(key: keyof Quote, index: number) {\r\n const dataIndex = this.getDataIndexByBarIndex(index)\r\n if (dataIndex > -1) {\r\n const quoteData = this[key as keyof Quote]! as number[]\r\n return quoteData[dataIndex] ?? null\r\n }\r\n return null\r\n }\r\n\r\n getDateToIndex() {\r\n const cachedDateToIndex = getCachedQuote({ cid: this.cid, key: 'dateToIndex', fetchedAt: this.fetchedAt })\r\n if (cachedDateToIndex) {\r\n return cachedDateToIndex as unknown as ObjectHash\r\n }\r\n const dateToIndex: ObjectHash = {}\r\n for (let i = 0; i < this.date.length; i++) {\r\n dateToIndex[this.date[i]] = i\r\n }\r\n setCachedQuote({ cid: this.cid, key: 'dateToIndex', value: dateToIndex, fetchedAt: this.fetchedAt })\r\n return dateToIndex\r\n }\r\n\r\n getTimestampFomPositionX(positionX: number) {\r\n if (this.date.length === 0) {\r\n return 0\r\n }\r\n return getTimestampFromPositionX({\r\n positionX,\r\n quote: this,\r\n })\r\n }\r\n\r\n getPositionXFromTimestamp(timestamp: number) {\r\n if (this.date.length === 0) {\r\n return 0\r\n }\r\n return getPositionXFromTimestamp({\r\n timestamp,\r\n quote: this,\r\n })\r\n }\r\n\r\n getUrl(options: QuoteUrlOptions) {\r\n const config: UrlOptions = {\r\n ticker: this.ticker,\r\n instrument: this.instrument,\r\n timeframe: this.timeframe || 'd1',\r\n aftermarket: this.aftermarket,\r\n premarket: this.premarket,\r\n patterns: this.hasPatterns,\r\n maxBars: this.maxBars,\r\n ...options,\r\n }\r\n\r\n const isStock = config.instrument === Instrument.Stock\r\n const isBrowserElite = !getIsSSr() && document.location.host === 'elite.finviz.com'\r\n let domain = isBrowserElite && isStock ? 'https://api.finviz.com' : ''\r\n\r\n if (getIsSSr()) {\r\n domain = process.env.BE_API_URL!\r\n }\r\n\r\n return `${domain}/api/quote.ashx?${queryString.stringify({ rev: Date.now(), ...config })}`\r\n }\r\n\r\n getRawTicker() {\r\n return getRawTickerForInstrument(this.instrument, this.ticker)\r\n }\r\n\r\n clearData() {\r\n this.updateAttributes(emptyQuote)\r\n }\r\n}\r\n\r\nQuote.initClass()\r\n\r\nexport default Quote\r\n","export enum QuoteFetchType {\r\n Refetch = 'refetch',\r\n NewerData = 'newerData',\r\n}\r\n\r\nexport enum QuoteFetchTypeUrlOption {\r\n New = 'new',\r\n Newer = 'newer',\r\n}\r\n\r\nexport interface QuoteUrlOptions {\r\n type: QuoteFetchTypeUrlOption\r\n dataId?: string\r\n events?: boolean\r\n}\r\n","export const largeChartFontSize = {\r\n S: 8,\r\n M: 10,\r\n XXL: 16,\r\n XXXL: 24,\r\n}\r\n","import { Theme } from '../../../types/shared'\r\nimport {\r\n CHART_MARGIN,\r\n FONT_SIZE,\r\n LINE_HEIGHT,\r\n OFFSET,\r\n PADDING,\r\n SETTINGS_HEIGHT,\r\n TICKER_TIMEFRAME_CHANGE_HEIGHT,\r\n TextBaseline,\r\n} from '../../constants/common'\r\nimport {\r\n chartDarkTheme,\r\n chartLightTheme,\r\n elementDarkTheme,\r\n elementLightTheme,\r\n generalColors,\r\n indicatorDarkTheme,\r\n indicatorLightTheme,\r\n} from '../constants'\r\nimport { ISettings } from './interfaces'\r\n\r\nexport const INTERACTIVE_CHART_SETTINGS = (theme: Theme): ISettings => ({\r\n ChartSettings: {\r\n general: {\r\n Colors: {\r\n ...(theme === Theme.light ? chartLightTheme : chartDarkTheme),\r\n [Theme.light]: chartLightTheme,\r\n [Theme.dark]: chartDarkTheme,\r\n },\r\n settingsHeight: SETTINGS_HEIGHT,\r\n tickerTimeframeChangeHeight: TICKER_TIMEFRAME_CHANGE_HEIGHT,\r\n },\r\n center: {\r\n barWidth: 3,\r\n barMargin: 1,\r\n border: 1,\r\n },\r\n top: {\r\n height: CHART_MARGIN.XL,\r\n baseline: TextBaseline.alphabetic,\r\n ticker: {\r\n margin: {\r\n top: 30,\r\n left: 0,\r\n },\r\n font: {\r\n size: FONT_SIZE.XXXL,\r\n style: 'bold',\r\n },\r\n },\r\n ohlc: {\r\n margin: {\r\n top: 30,\r\n left: 30,\r\n right: 30,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n },\r\n },\r\n change: {\r\n margin: {\r\n top: 30,\r\n right: 0,\r\n },\r\n font: {\r\n size: FONT_SIZE.M,\r\n style: 'bold',\r\n },\r\n },\r\n },\r\n right: {\r\n width: CHART_MARGIN.XXL,\r\n axis: {\r\n margin: {\r\n left: 0,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n lineHeight: LINE_HEIGHT.S,\r\n padding: {\r\n top: PADDING.XXS,\r\n bottom: PADDING.XXS,\r\n left: PADDING.XXS,\r\n right: PADDING.XXS,\r\n },\r\n },\r\n },\r\n },\r\n bottom: {\r\n height: CHART_MARGIN.M,\r\n baseline: TextBaseline.top,\r\n axis: {\r\n margin: {\r\n top: 8,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n },\r\n },\r\n },\r\n left: {\r\n width: CHART_MARGIN.L,\r\n overlayLabel: {\r\n labelSpacing: 12,\r\n margin: {\r\n top: -8,\r\n left: 6,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n weight: 'bold',\r\n },\r\n },\r\n timeframe: {\r\n margin: {\r\n top: 0,\r\n left: 28,\r\n },\r\n font: {\r\n size: FONT_SIZE.M,\r\n weight: '900',\r\n family: 'Lato, sans-serif',\r\n },\r\n },\r\n volumeAxis: {\r\n margin: {\r\n left: 33,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n },\r\n },\r\n },\r\n },\r\n IndicatorSettings: {\r\n general: {\r\n height: 140,\r\n Colors: theme === Theme.light ? indicatorLightTheme : indicatorDarkTheme,\r\n },\r\n center: {\r\n barWidth: 3,\r\n barMargin: 2,\r\n border: 1,\r\n },\r\n top: {\r\n height: CHART_MARGIN.S,\r\n },\r\n right: {\r\n width: CHART_MARGIN.XXL,\r\n axis: {\r\n margin: {\r\n left: 0,\r\n },\r\n font: {\r\n size: FONT_SIZE.S,\r\n lineHeight: LINE_HEIGHT.S,\r\n padding: {\r\n top: PADDING.XXS,\r\n bottom: PADDING.XXS,\r\n left: PADDING.XXS,\r\n right: PADDING.XXS,\r\n },\r\n },\r\n },\r\n },\r\n bottom: {\r\n height: CHART_MARGIN.S,\r\n },\r\n left: {\r\n width: CHART_MARGIN.L,\r\n indicatorLabel: {\r\n labelSpacing: 4,\r\n margin: {\r\n top: OFFSET.S,\r\n left: OFFSET.M,\r\n },\r\n font: {\r\n size: FONT_SIZE.M,\r\n style: 'bold',\r\n lineHeight: LINE_HEIGHT.M,\r\n },\r\n },\r\n },\r\n },\r\n MarketSentimentSettings: {\r\n general: {\r\n Colors: theme === Theme.light ? chartLightTheme : chartDarkTheme,\r\n },\r\n center: {\r\n barWidth: 3,\r\n barMargin: 1,\r\n border: 1,\r\n },\r\n top: {\r\n height: 0,\r\n },\r\n bottom: {\r\n height: 12,\r\n },\r\n left: {\r\n width: 0,\r\n },\r\n right: {\r\n width: 30,\r\n },\r\n },\r\n ColorsSettings: generalColors,\r\n ThumbSettings: {\r\n size: 8,\r\n touchSize: 16,\r\n color: '#ddd',\r\n borderWidth: 1,\r\n borderColor: '#999',\r\n },\r\n ElementSettings: {\r\n Colors: theme === Theme.light ? elementLightTheme : elementDarkTheme,\r\n defaultFill: '#1e6dc066',\r\n defaultTransparentFill: '#1e6dc000',\r\n },\r\n})\r\n","import merge from 'lodash.merge'\r\n\r\nimport { ChartConfigChart } from '../../server/chartConfig'\r\nimport { Instrument, ObjectHash, Theme } from '../../types/shared'\r\nimport { SpecificChartFunctionality } from '../constants/common'\r\nimport Utils, { isRedesignedPage } from '../utils'\r\nimport LayoutModel from './chart_layout'\r\nimport { getColorOverwrites } from './chart_settings'\r\nimport { largeChartFontSize } from './chart_settings/constants'\r\nimport { INTERACTIVE_CHART_SETTINGS } from './chart_settings/interactive_chart_settings'\r\nimport { ISettings } from './chart_settings/interfaces'\r\nimport {\r\n IChartThemeColors,\r\n chartDarkTheme,\r\n chartLightTheme,\r\n elementDarkTheme,\r\n elementLightTheme,\r\n indicatorDarkTheme,\r\n indicatorLightTheme,\r\n} from './constants'\r\n\r\ninterface Config {\r\n theme: Theme\r\n barMargin?: number\r\n barWidth?: number\r\n border?: number\r\n charts?: ChartConfigChart[]\r\n colorsOverride?: Array\r\n volumeHeight?: number\r\n colors?: ObjectHash, Theme>\r\n specificChartFunctionality?: SpecificChartFunctionality\r\n isOurSiteRequest?: boolean\r\n}\r\n\r\nexport function getSettings(config: Config, chartSettings?: ISettings): ISettings {\r\n const settings = merge({}, chartSettings ?? INTERACTIVE_CHART_SETTINGS(config.theme))\r\n\r\n if (config.barWidth != null) {\r\n settings.ChartSettings.center.barWidth = config.barWidth\r\n settings.IndicatorSettings.center.barWidth = config.barWidth\r\n }\r\n if (config.barMargin != null) {\r\n settings.ChartSettings.center.barMargin = config.barMargin\r\n settings.IndicatorSettings.center.barMargin = config.barMargin\r\n }\r\n if (config.border != null) {\r\n settings.ChartSettings.center.border = config.border\r\n settings.IndicatorSettings.center.border = config.border\r\n }\r\n if (config.colorsOverride) {\r\n settings.ColorsSettings = config.colorsOverride\r\n }\r\n if (config.volumeHeight) {\r\n settings.ChartSettings.center.volumeHeight = config.volumeHeight\r\n }\r\n if (config.colors) {\r\n const settingColors = settings.ChartSettings.general.Colors\r\n settings.ChartSettings.general.Colors = {\r\n ...settingColors,\r\n [Theme.light]: {\r\n ...settingColors[Theme.light],\r\n ...getColorOverwrites({ theme: Theme.light, colors: config.colors }),\r\n },\r\n [Theme.dark]: {\r\n ...settingColors[Theme.dark],\r\n ...getColorOverwrites({ theme: Theme.dark, colors: config.colors }),\r\n },\r\n }\r\n }\r\n if (config.specificChartFunctionality === SpecificChartFunctionality.chartPage && Utils.isMobile()) {\r\n settings.ChartSettings.left.width = 0\r\n settings.ChartSettings.top.ticker.margin.left = settings.ChartSettings.left.overlayLabel.margin.left\r\n settings.IndicatorSettings.left.width = 0\r\n }\r\n if (SpecificChartFunctionality.chartPage === config.specificChartFunctionality || isRedesignedPage(config)) {\r\n settings.ChartSettings.top.height = 10\r\n }\r\n\r\n if (config.specificChartFunctionality === SpecificChartFunctionality.offScreen) {\r\n const isGroupInstrument = config.charts?.some(({ instrument }) => instrument === Instrument.Group)\r\n if (isGroupInstrument) {\r\n settings.ChartSettings.top.ohlc.margin.top = 4\r\n settings.ChartSettings.top.ticker.margin.top = 0\r\n settings.ChartSettings.top.ticker.font = {\r\n size: largeChartFontSize.XXL,\r\n style: 'bold',\r\n }\r\n settings.ChartSettings.left.timeframe.margin.top = 12\r\n settings.ChartSettings.left.timeframe.font = {\r\n size: largeChartFontSize.S,\r\n style: 'bold',\r\n }\r\n }\r\n }\r\n\r\n if (config.isOurSiteRequest !== undefined) {\r\n settings.isOurSiteRequest = config.isOurSiteRequest\r\n }\r\n\r\n return settings\r\n}\r\n\r\nexport function updateSettings(chart_layout: LayoutModel, theme: string): ISettings {\r\n const settings = merge({}, chart_layout.settings)\r\n const isLight = theme === Theme.light\r\n settings.MarketSentimentSettings.general.Colors = isLight ? { ...chartLightTheme } : { ...chartDarkTheme }\r\n settings.IndicatorSettings.general.Colors = isLight ? { ...indicatorLightTheme } : { ...indicatorDarkTheme }\r\n settings.ElementSettings.Colors = isLight ? { ...elementLightTheme } : { ...elementDarkTheme }\r\n\r\n return settings\r\n}\r\n\r\nexport function getChartLayoutSettings(chart_layout: LayoutModel): ISettings {\r\n const settings = chart_layout.settings\r\n\r\n return {\r\n ...settings,\r\n ChartSettings: {\r\n ...settings.ChartSettings,\r\n general: {\r\n ...settings.ChartSettings.general,\r\n Colors: {\r\n ...settings.ChartSettings.general.Colors,\r\n ...settings.ChartSettings.general.Colors[chart_layout.theme],\r\n },\r\n },\r\n },\r\n }\r\n}\r\n","import { Instrument } from '../../types/shared'\r\nimport ChartLayoutModel from './chart_layout'\r\nimport Element from './element'\r\n\r\nexport const handleRemoveIndicatorPane = ({\r\n paneIndex,\r\n chartLayoutModel,\r\n}: {\r\n paneIndex: number\r\n chartLayoutModel: ChartLayoutModel\r\n}) => {\r\n const charts = chartLayoutModel.getAllCharts()\r\n charts.forEach((chart) => chart.getAllPanes()[paneIndex].destroyCascade())\r\n}\r\n\r\nexport function getNormalizedZIndex({ index, isBelowZero }: { index: number; isBelowZero: boolean }) {\r\n return (index + 1) * (isBelowZero ? -1 : 1)\r\n}\r\n\r\nexport function rebuildElementZIndexes({\r\n elementsArray,\r\n isBelowZero,\r\n}: {\r\n elementsArray: Element[]\r\n isBelowZero: boolean\r\n}) {\r\n const elements = isBelowZero ? [...elementsArray].reverse() : elementsArray\r\n elements.forEach((element, index) => {\r\n const newZIndex = getNormalizedZIndex({ index, isBelowZero })\r\n if (newZIndex !== element.zIndex) {\r\n element.updateAttributes({ zIndex: newZIndex })\r\n }\r\n })\r\n}\r\n\r\nexport function changeElementZIndexes({\r\n elementsArray,\r\n addElement,\r\n oldZIndex,\r\n newZIndex,\r\n isBelowZero = false,\r\n}: {\r\n elementsArray: Element[]\r\n addElement: Element | undefined\r\n oldZIndex: number\r\n newZIndex: number\r\n isBelowZero?: boolean\r\n}) {\r\n const array = isBelowZero ? [...elementsArray].reverse() : elementsArray\r\n const elements =\r\n elementsArray.length === 0 && addElement\r\n ? [...array, addElement]\r\n : array\r\n .filter((_, index) => getNormalizedZIndex({ index, isBelowZero }) !== oldZIndex)\r\n .flatMap((el, index) =>\r\n getNormalizedZIndex({ index, isBelowZero }) === newZIndex && addElement ? [addElement, el] : el\r\n )\r\n\r\n // If there are only 2 drawings and we move a drawing from index 1 to index 2 to have to push it to the array because it's the last element and it didn't get into the array in the flatMap above\r\n if (elements.length < Math.abs(newZIndex) && addElement) {\r\n elements.push(addElement)\r\n }\r\n\r\n rebuildElementZIndexes({ elementsArray: isBelowZero ? [...elements].reverse() : elements, isBelowZero })\r\n}\r\n\r\nexport function getRawTickerForInstrument(instrument: Instrument, ticker: string) {\r\n return `${\r\n [Instrument.Crypto, Instrument.Forex, Instrument.Futures].includes(instrument) && !ticker.includes('@') ? '@' : ''\r\n }${ticker}`\r\n}\r\n","import { OverlayType } from '../constants/common'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n period: number\r\n deviations: number\r\n}\r\n\r\ntype DefaultCalculatedValuesType = {\r\n sma: number[]\r\n stdDev: number[]\r\n upperBand: number[]\r\n lowerBand: number[]\r\n}\r\n\r\nexport class BbCalculation extends MainCalculation {\r\n static type = OverlayType.Bb\r\n\r\n getDefaultCalculatedValues() {\r\n return {\r\n sma: [],\r\n stdDev: [],\r\n upperBand: [],\r\n lowerBand: [],\r\n }\r\n }\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { period, deviations } = this.options\r\n const { close } = this.quote\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n let sum = 0\r\n for (let i = 0; i < period; i++) {\r\n sum += close[i]\r\n }\r\n for (let i = period; i < close.length; i++) {\r\n sum = sum - close[i - period] + close[i]\r\n this.calculatedValues.sma[i] = sum / period\r\n\r\n let stdDevSum = 0\r\n for (let j = i - period + 1; j <= i; j++) {\r\n stdDevSum += Math.pow(close[j] - this.calculatedValues.sma[i], 2)\r\n }\r\n this.calculatedValues.stdDev[i] = Math.sqrt(stdDevSum / period)\r\n\r\n this.calculatedValues.upperBand[i] = this.calculatedValues.sma[i] + this.calculatedValues.stdDev[i] * deviations\r\n this.calculatedValues.lowerBand[i] = this.calculatedValues.sma[i] - this.calculatedValues.stdDev[i] * deviations\r\n\r\n if (onValueCalculated?.(this.calculatedValues, i) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import {\r\n ChartConfigChartPaneElement,\r\n IModalConfig,\r\n IModalConfigInput,\r\n ObjectHash,\r\n RequireByKey,\r\n} from '../../types/shared'\r\nimport Element from '../canvas/element'\r\nimport BaseChart from '../charts/base_chart'\r\nimport { OverlayType } from '../constants/common'\r\nimport Quote from '../models/quote'\r\nimport { convertColorToHEX, getRGBAValueFromValidColorString } from '../utils/colors'\r\nimport { getParsedIntegersFromPeriodString, isInRange, isPositiveInteger } from '../utils/helpers'\r\n\r\nexport interface IOverlayIsValid {\r\n getIsValid(key: string): boolean | void\r\n}\r\n\r\nconst DEFAULT_LABEL_COLOR = '#0587cd'\r\n\r\nclass Overlay extends Element implements IOverlayIsValid {\r\n static type = OverlayType.Overlay\r\n static label = 'Overlay'\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [periodInt] = getParsedIntegersFromPeriodString(period)\r\n return periodInt\r\n }\r\n\r\n declare data: Quote\r\n declare chart: BaseChart\r\n\r\n get type() {\r\n return (this.constructor as typeof Overlay).type\r\n }\r\n\r\n get label() {\r\n return (this.constructor as typeof Overlay).label\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.color ? convertColorToHEX(this.attrs.color) : DEFAULT_LABEL_COLOR\r\n }\r\n\r\n getFreeColor() {\r\n return this.getChartLayoutSettings().ColorsSettings[0]\r\n // TODO proper implementation - example how this could be done:\r\n // let colorsUsed = []\r\n // for (let overlay of this.chart.overlays) {\r\n // let object = overlay.getModalConfig().inputs\r\n // for (let _ in object) {\r\n // let input = object[_]\r\n // if (input.type === 'color') {\r\n // colorsUsed.push(input.value)\r\n // }\r\n // }\r\n // }\r\n // for (let color of colors) {\r\n // if (!colorsUsed.includes(color)) {\r\n // return color\r\n // }\r\n // }\r\n // return colors[0]\r\n }\r\n\r\n renderContent(_?: RenderingContext2DType) {\r\n this.data = this.model.chart().quote()\r\n }\r\n\r\n fx = (x: number) => this.model.scale.x(this.data.barIndex[x])\r\n\r\n getIsValid(_: string): boolean | undefined {\r\n throw Error('Implement')\r\n }\r\n\r\n getIsNumberInputValid({ key, integerOnly = true }: { key: string; integerOnly?: boolean }): boolean {\r\n const input = this.getModalConfig().inputs.find(({ name }: { name: string }) => key === name)\r\n return !!input && isInRange(input) && (!integerOnly || isPositiveInteger(input.value))\r\n }\r\n\r\n isRendered() {\r\n return true\r\n }\r\n\r\n isRenderedOverlaysLabel() {\r\n return this.isRendered()\r\n }\r\n\r\n getModalConfig(): IModalConfig {\r\n return {\r\n title: '',\r\n inputs: [],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n toConfig() {\r\n const colors: string[] = []\r\n const periods: string[] = []\r\n\r\n this.getModalConfig().inputs.forEach((input: IModalConfigInput) => {\r\n if (input.type === 'color') {\r\n colors.push(getRGBAValueFromValidColorString(input.value.toString()))\r\n } else {\r\n periods.push(input.value.toString())\r\n }\r\n })\r\n\r\n return { type: this.type, period: periods.join(','), color: colors.join('|') }\r\n }\r\n}\r\n\r\nexport default Overlay\r\n","import { ChartConfigChartPaneElement, RequireByKey, Theme } from '../../types/shared'\r\nimport { OverlayType } from '../constants/common'\r\nimport { BbCalculation } from '../indicator-calculation/bb'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport Overlay from './overlay'\r\n\r\nconst BB_COLORS = {\r\n [Theme.light]: {\r\n TOP: '#D386DF',\r\n BOTTOM: '#69C1EA',\r\n MIDDLE: '#CFD2F2',\r\n },\r\n [Theme.dark]: {\r\n TOP: '#D38BFB',\r\n BOTTOM: '#57AEFB',\r\n MIDDLE: '#E1B6FC',\r\n },\r\n}\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n Period: 20,\r\n Deviations: 2.0,\r\n}\r\n\r\ninterface Attrs {\r\n period: number | string\r\n deviations: number\r\n topColor?: string\r\n bottomColor?: string\r\n}\r\n\r\nfunction parsePeriod(periodStr: string) {\r\n const values = periodStr.split(',')\r\n const period = parseInt(values[0]) || DEFAULT_PARAMETERS.Period\r\n const deviations = parseFloat(values[1]) || DEFAULT_PARAMETERS.Deviations\r\n\r\n return [period, deviations]\r\n}\r\n\r\nclass BollingerBands extends Overlay {\r\n static type = OverlayType.Bb\r\n static label = 'Bollinger Bands'\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [periodInt = 0] = getParsedIntegersFromPeriodString(period)\r\n return periodInt + 1 // +1 offsets rendering so it doesn't start on first bar which doesn't look OK in SSR rendered charts\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n const [periodInt, deviations] = parsePeriod(period)\r\n this.attrs.period = periodInt\r\n this.attrs.deviations = deviations\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n if (typeof this.attrs.period !== 'number') {\r\n return\r\n }\r\n super.renderContent()\r\n const { Colors } = this.getChartLayoutSettings().ChartSettings.general\r\n const theme = this.model.chart().chart_layout().theme as Theme\r\n const { leftOffset, width } = this.model.chart()\r\n const [top, bottom] = this.model.scale.y.domain()\r\n const scaledTop = this.fy(top)\r\n const scaledBottom = this.fy(bottom)\r\n const { close } = this.data\r\n const period = Math.min(this.attrs.period, close.length - 1)\r\n\r\n let firstBarToRender: number | undefined\r\n let lastBarToRender = 0\r\n\r\n // middle line && find first & last bar to render\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', BB_COLORS[theme].MIDDLE)\r\n\r\n const bbCalculation = new BbCalculation({\r\n quote: this.data,\r\n options: {\r\n period,\r\n deviations: this.attrs.deviations,\r\n },\r\n })\r\n\r\n bbCalculation.calculate(({ sma }, dataIndex) => {\r\n if (this.fx(dataIndex + 1) + leftOffset < 0) {\r\n return\r\n }\r\n if (firstBarToRender === undefined) firstBarToRender = dataIndex\r\n\r\n context.lineTo(this.fx(dataIndex), Math.round(this.fy(sma[dataIndex])))\r\n\r\n if (this.fx(dataIndex - 1) + leftOffset > width) {\r\n return false\r\n }\r\n lastBarToRender = dataIndex\r\n })\r\n\r\n if (firstBarToRender === undefined) return\r\n context.stroke()\r\n context.set('fillStyle', Colors.overlayTransparentBackground)\r\n\r\n // top line\r\n context.beginPath()\r\n context.moveTo(this.fx(firstBarToRender), scaledTop)\r\n context.set('strokeStyle', BB_COLORS[theme].TOP)\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n context.lineTo(this.fx(i), Math.round(this.fy(bbCalculation.calculatedValues.upperBand[i])))\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), scaledTop)\r\n context.fill()\r\n\r\n // bottom line\r\n context.beginPath()\r\n context.moveTo(this.fx(firstBarToRender), scaledBottom)\r\n context.set('strokeStyle', BB_COLORS[theme].BOTTOM)\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n context.lineTo(this.fx(i), Math.round(this.fy(bbCalculation.calculatedValues.lowerBand[i])))\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), scaledBottom)\r\n context.fill()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.attrs.period ?? DEFAULT_PARAMETERS.Period,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const deviations = {\r\n type: 'number',\r\n label: 'Deviations',\r\n name: 'deviations',\r\n value: this.attrs.deviations ?? DEFAULT_PARAMETERS.Deviations,\r\n required: true,\r\n min: 0.1,\r\n max: 999,\r\n step: 0.1,\r\n }\r\n const topColor = {\r\n type: 'color',\r\n label: 'Top Color',\r\n name: 'topColor',\r\n value: this.attrs.topColor ?? this.getFreeColor(),\r\n }\r\n const bottomColor = {\r\n type: 'color',\r\n label: 'Bottom Color',\r\n name: 'bottomColor',\r\n value: this.attrs.bottomColor ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, deviations, topColor, bottomColor],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n deviations: `${deviations.label} must be a number between ${deviations.min} and ${deviations.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'deviations':\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n case 'topColor':\r\n case 'bottomColor':\r\n // Some users have wrong colors which break the form validation\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n const theme = this.model.chart().chart_layout().theme as Theme\r\n return this.attrs.topColor || BB_COLORS[theme].TOP\r\n }\r\n\r\n toString() {\r\n return `BB ${this.attrs.period},${this.attrs.deviations}`\r\n }\r\n}\r\n\r\nBollingerBands.prototype.defaults = { topColor: '#69c1ea', bottomColor: '#d386df' }\r\n\r\nexport default BollingerBands\r\n","import { OverlayType } from '../constants/common'\r\nimport utils from '../utils'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period: number\r\n channelStrokeColor: string\r\n channelFillColor: string\r\n medianBandColor: string\r\n}\r\n\r\nconst DEFAULT_PERIOD = 20\r\n\r\nconst COLORS = {\r\n ChannelStroke: '#69c1ea',\r\n ChannelFill: '#69C1EA12',\r\n MedianBandStroke: '#ffa75f',\r\n}\r\n\r\nclass DonchianChannels extends Overlay {\r\n static type = OverlayType.Dch\r\n static label = 'Donchian Channels'\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n this.attrs.period = parseInt(period, 10)\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n const { period } = this.attrs\r\n const upperBand: number[] = []\r\n const lowerBand: number[] = []\r\n const medianBand: number[] = []\r\n let firstBarToRender = -1\r\n let lastBarToRender = 0\r\n if (this.data.close.length === undefined) {\r\n return\r\n }\r\n\r\n context.save()\r\n context.translate(0.5, 0.5)\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', COLORS.ChannelStroke)\r\n context.set('fillStyle', COLORS.ChannelFill)\r\n\r\n //upper band + clip\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n leftOffset,\r\n width,\r\n drawBarCallback: (i, x) => {\r\n firstBarToRender = firstBarToRender === -1 ? i : firstBarToRender\r\n upperBand[i] = utils.max(this.data.high.slice(Math.max(0, i - period), i + 1))\r\n lowerBand[i] = utils.min(this.data.low.slice(Math.max(0, i - period), i + 1))\r\n medianBand[i] = (upperBand[i] + lowerBand[i]) / 2\r\n\r\n context.lineTo(x, Math.round(this.fy(upperBand[i])))\r\n lastBarToRender = i\r\n },\r\n })\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), context.canvas.height)\r\n context.lineTo(this.fx(firstBarToRender), context.canvas.height)\r\n context.clip()\r\n\r\n // lower band + fill\r\n context.beginPath()\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n const x = this.fx(i)\r\n context.lineTo(x, Math.round(this.fy(lowerBand[i])))\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), 0)\r\n context.lineTo(0, 0)\r\n context.fill()\r\n\r\n // median band\r\n context.set('strokeStyle', COLORS.MedianBandStroke)\r\n context.beginPath()\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n const x = this.fx(i)\r\n context.lineTo(x, Math.round(this.fy(medianBand[i])))\r\n }\r\n context.stroke()\r\n context.restore()\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.attrs.period ?? DEFAULT_PERIOD,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n const strokeColor = {\r\n type: 'color',\r\n label: 'Channels Stroke Color',\r\n name: 'strokeColor',\r\n value: this.attrs.channelStrokeColor ?? this.getFreeColor(),\r\n }\r\n const fillColor = {\r\n type: 'color',\r\n label: 'Channels Fill Color',\r\n name: 'fillColor',\r\n value: this.attrs.channelFillColor ?? this.getFreeColor(),\r\n }\r\n const medianBandColor = {\r\n type: 'color',\r\n label: 'Median Band Color',\r\n name: 'medianBandColor',\r\n value: this.attrs.medianBandColor ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, medianBandColor, strokeColor, fillColor],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'medianBandColor':\r\n case 'strokeColor':\r\n case 'fillColor':\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.medianBandColor\r\n }\r\n\r\n toString() {\r\n return `Donchian ${this.attrs.period}`\r\n }\r\n}\r\n\r\nDonchianChannels.prototype.defaults = {\r\n medianBandColor: COLORS.MedianBandStroke,\r\n channelStrokeColor: COLORS.ChannelStroke,\r\n channelFillColor: COLORS.ChannelFill,\r\n}\r\n\r\nexport default DonchianChannels\r\n","import { OverlayType } from '../constants/common'\r\nimport { EMACalculation } from '../indicator-calculation/ema'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period: number\r\n deviations: number\r\n color: string\r\n}\r\n\r\nclass EMA extends Overlay {\r\n static type = OverlayType.Ema\r\n static label = 'Exponential Moving Average'\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n this.attrs.period = parseInt(period, 10)\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', this.attrs.color)\r\n const emaCalculation = new EMACalculation({\r\n quote: this.data,\r\n options: {\r\n period: this.attrs.period,\r\n },\r\n })\r\n emaCalculation.calculate(({ ema }, dataIndex) => {\r\n const x = this.fx(dataIndex)\r\n if (this.fx(dataIndex + 1) + leftOffset < 0) {\r\n return\r\n }\r\n if (this.fx(dataIndex - 1) + leftOffset > width) {\r\n return false\r\n }\r\n context.lineTo(x, Math.round(this.fy(ema[dataIndex])))\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.attrs.period ?? 5,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const color = {\r\n type: 'color',\r\n label: 'Color',\r\n name: 'color',\r\n value: this.attrs.color ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, color],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'color':\r\n return !!this.attrs[key] // use real color validation, we got isValidHexColor but it might be also RGBA\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `EMA ${this.attrs.period}`\r\n }\r\n}\r\n\r\nEMA.prototype.defaults = { color: '#ffa75f' }\r\n\r\nexport default EMA\r\n","import { OverlayType } from '../constants/common'\r\nimport EMA from './ema'\r\n\r\nclass EMA2 extends EMA {\r\n static type = OverlayType.Ema2\r\n}\r\n\r\nEMA2.prototype.defaults = { color: '#ff6400' }\r\n\r\nexport default EMA2\r\n","import { OverlayType } from '../constants/common'\r\nimport PaneModel from '../models/pane'\r\nimport { getBarWidthWithMargin } from '../utils/chart'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period: number\r\n lowColor: string\r\n highColor: string\r\n}\r\n\r\nclass HighLow extends Overlay {\r\n static type = OverlayType.Hilo\r\n static label = 'High/Low'\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.renderContent = this.renderContent.bind(this)\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n this.attrs.period = parseInt(period, 10)\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const chartModel = this.model.chart()\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const { Colors } = ChartSettings.general\r\n const { leftOffset, width, zoomFactor } = chartModel\r\n const barWidth = getBarWidthWithMargin({\r\n zoomFactor,\r\n chartLayout: chartModel.chart_layout(),\r\n })\r\n const halfWidth = barWidth / 2\r\n const period = Math.min(this.attrs.period, this.data.close.length - 1)\r\n let firstBarToRender\r\n let lastBarToRender = 0\r\n context.translate(0.5, 0.5)\r\n context.set('fillStyle', Colors.overlayTransparentBackground)\r\n context.beginPath()\r\n context.set('strokeStyle', this.attrs.highColor)\r\n let prevHigh = -1\r\n for (let i = 0; i < this.data.close.length; i++) {\r\n let highestHigh = this.data.high[i]\r\n for (let j = i - period + 1; j <= i; j++) {\r\n if (this.data.high[j] > highestHigh) {\r\n highestHigh = this.data.high[j]\r\n }\r\n }\r\n\r\n const x = this.fx(i)\r\n if (this.fx(i + 1) + leftOffset < -10) {\r\n prevHigh = highestHigh\r\n continue\r\n }\r\n if (firstBarToRender === undefined) firstBarToRender = i\r\n if (this.fx(i - 1) + leftOffset > width) {\r\n break\r\n }\r\n\r\n const diff = this.data.barIndex[i] - this.data.barIndex[lastBarToRender]\r\n if (diff > 1 && prevHigh !== highestHigh && prevHigh > 0) {\r\n context.lineTo(Math.round(x - halfWidth), Math.round(this.fy(prevHigh)))\r\n }\r\n context.lineTo(Math.round(x - halfWidth), Math.round(this.fy(highestHigh)))\r\n context.lineTo(Math.round(x + halfWidth), Math.round(this.fy(highestHigh)))\r\n\r\n prevHigh = highestHigh\r\n lastBarToRender = i\r\n }\r\n context.stroke()\r\n if (firstBarToRender === undefined) return\r\n\r\n // return to start and fill with background color\r\n context.lineTo(this.fx(lastBarToRender) + halfWidth, 0)\r\n context.lineTo(this.fx(firstBarToRender) - halfWidth, 0)\r\n context.fill()\r\n\r\n context.beginPath()\r\n context.set('strokeStyle', this.attrs.lowColor)\r\n let prevLow = -1\r\n let prevBar = firstBarToRender\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n let lowestLow = this.data.low[i]\r\n for (let j = i - period + 1; j <= i; j++) {\r\n if (this.data.low[j] < lowestLow) {\r\n lowestLow = this.data.low[j]\r\n }\r\n }\r\n\r\n const x = this.fx(i)\r\n const diff = this.data.barIndex[i] - this.data.barIndex[prevBar]\r\n if (diff > 1 && prevLow !== lowestLow && prevLow > 0) {\r\n context.lineTo(Math.round(x - halfWidth), Math.round(this.fy(prevLow)))\r\n }\r\n context.lineTo(Math.round(x - halfWidth), Math.round(this.fy(lowestLow)))\r\n context.lineTo(Math.round(x + halfWidth), Math.round(this.fy(lowestLow)))\r\n\r\n prevLow = lowestLow\r\n prevBar = i\r\n }\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n\r\n // return to start and fill with background color\r\n context.lineTo(this.fx(lastBarToRender), context.canvas.height)\r\n context.lineTo(this.fx(firstBarToRender) - halfWidth, context.canvas.height)\r\n context.fill()\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.attrs.period ?? 50,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const highColor = {\r\n type: 'color',\r\n label: 'High Color',\r\n name: 'highColor',\r\n value: this.attrs.highColor ?? this.getFreeColor(),\r\n }\r\n const lowColor = {\r\n type: 'color',\r\n label: 'Low Color',\r\n name: 'lowColor',\r\n value: this.attrs.lowColor ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, highColor, lowColor],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'highColor':\r\n case 'lowColor':\r\n // Some users have wrong colors which break the form validation\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.highColor\r\n }\r\n\r\n toString() {\r\n return `HILO ${this.attrs.period}`\r\n }\r\n}\r\n\r\nHighLow.prototype.defaults = {\r\n lowColor: '#69c1ea',\r\n highColor: '#d386df',\r\n}\r\n\r\nexport default HighLow\r\n","import { OverlayType } from '../constants/common'\r\nimport { isPositiveFloat } from '../utils/helpers'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period: number\r\n price: number\r\n color: string\r\n}\r\n\r\nclass HorizontalLine extends Overlay {\r\n static type = OverlayType.Hline\r\n static label = 'Horizontal Line'\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n if (typeof this.attrs.period === 'string' && this.attrs.price === undefined) {\r\n this.attrs.price = parseFloat(this.attrs.period)\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const y = Math.round(this.fy(this.attrs.price))\r\n context.set('strokeStyle', this.attrs.color)\r\n context.translate(0, 0.5)\r\n context.beginPath()\r\n context.moveTo(-this.model.chart().leftOffset, y)\r\n context.lineTo(-this.model.chart().leftOffset + this.model.chart().width, y)\r\n context.stroke()\r\n context.translate(0, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const price = {\r\n type: 'number',\r\n label: 'Price',\r\n name: 'price',\r\n value: this.attrs.price || this.model?.scale?.y?.domain().reduce((a: number, b: number) => a + b, 0) / 2,\r\n required: true,\r\n step: 0.1,\r\n }\r\n const color = {\r\n type: 'color',\r\n label: 'Color',\r\n name: 'color',\r\n value: this.attrs.color ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [price, color],\r\n inputsErrorMessages: {\r\n price: `${price.label} must be number`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'price':\r\n return isPositiveFloat(this.attrs[key])\r\n case 'color':\r\n return !!this.attrs[key] // use real color validation, we got isValidHexColor but it might be also RGBA\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `HL ${this.attrs.price}`\r\n }\r\n}\r\n\r\nHorizontalLine.prototype.defaults = { color: '#0587cd' }\r\n\r\nexport default HorizontalLine\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { OverlayType } from '../constants/common'\r\nimport { drawInVisibleArea } from '../utils/draw_in_visible_area'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period?: string\r\n conversion: number\r\n base: number\r\n spanB: number\r\n spanAStrokeColor: string\r\n spanAFillColor: string\r\n spanBStrokeColor: string\r\n spanBFillColor: string\r\n conversionLineColor: string\r\n baseLineColor: string\r\n laggingSpanColor: string\r\n}\r\n\r\nconst COLORS = {\r\n SpanA: {\r\n Stroke: '#009600',\r\n Fill: '#00960022',\r\n },\r\n SpanB: {\r\n Stroke: '#C80000',\r\n Fill: '#C8000022',\r\n },\r\n ConversionLine: '#69C1EA',\r\n BaseLine: '#E54040',\r\n LaggingSpan: '#FFA75F',\r\n}\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n Conversion: 9,\r\n Base: 26,\r\n SpanB: 52,\r\n}\r\n\r\nfunction parsePeriod(period: string) {\r\n const [conversion = DEFAULT_PARAMETERS.Conversion, base = DEFAULT_PARAMETERS.Base, spanB = DEFAULT_PARAMETERS.SpanB] =\r\n getParsedIntegersFromPeriodString(period)\r\n return [conversion, base, spanB]\r\n}\r\n\r\nclass IchimokuCloud extends Overlay {\r\n static type = OverlayType.Ic\r\n static label = 'Ichimoku Cloud'\r\n static renderFull = false\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n return Math.max(...parsePeriod(period))\r\n }\r\n\r\n get renderFull() {\r\n return (this.constructor as typeof IchimokuCloud).renderFull\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n if (\r\n typeof this.attrs.period === 'string' &&\r\n (this.attrs.conversion === undefined || this.attrs.base === undefined || this.attrs.spanB === undefined)\r\n ) {\r\n const [conversion, base, spanB] = parsePeriod(this.attrs.period)\r\n this.attrs.conversion = conversion\r\n this.attrs.base = base\r\n this.attrs.spanB = spanB\r\n }\r\n this.trigger('change')\r\n return this\r\n }\r\n\r\n fx = (x: number) => {\r\n const lastIndex = this.data.close.length - 1\r\n const outsideBar = this.data.barIndex[lastIndex] + x - lastIndex\r\n\r\n return this.model.scale.x(this.data.barIndex[x] ?? outsideBar)\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n const { high, low, close } = this.data\r\n\r\n const {\r\n conversion,\r\n base,\r\n spanB,\r\n spanAFillColor,\r\n spanAStrokeColor,\r\n spanBFillColor,\r\n spanBStrokeColor,\r\n baseLineColor,\r\n conversionLineColor,\r\n laggingSpanColor,\r\n } = this.attrs\r\n\r\n const conversionLine: number[] = []\r\n const baseLine: number[] = []\r\n const senkouSpanA: number[] = []\r\n const senkouSpanB: number[] = []\r\n const conversionStartIndex = conversion - 1\r\n const baseStartIndex = base - 1\r\n const spanBIndex = spanB - 1\r\n const start = Math.min(baseStartIndex, conversionStartIndex)\r\n const end = close.length + baseStartIndex\r\n\r\n if (this.data.close.length === 0) return\r\n\r\n // Calculation\r\n for (let i = start; i < end; i++) {\r\n if (i >= conversionStartIndex && i < close.length) {\r\n const highestHi = Math.max(...high.slice(i - conversionStartIndex, i + 1))\r\n const lowestLo = Math.min(...low.slice(i - conversionStartIndex, i + 1))\r\n conversionLine[i] = (highestHi + lowestLo) / 2\r\n }\r\n\r\n if (i >= baseStartIndex && i < close.length) {\r\n const highestHi = Math.max(...high.slice(i - baseStartIndex, i + 1))\r\n const lowestLo = Math.min(...low.slice(i - baseStartIndex, i + 1))\r\n baseLine[i] = (highestHi + lowestLo) / 2\r\n\r\n senkouSpanA[i + baseStartIndex] = (baseLine[i] + conversionLine[i]) / 2 // + baseStart because it needs to be shifted to the future\r\n }\r\n\r\n if (i >= spanBIndex) {\r\n const highestHi = Math.max(...high.slice(i - spanBIndex, i + 1))\r\n const lowestLo = Math.min(...low.slice(i - spanBIndex, i + 1))\r\n senkouSpanB[i + baseStartIndex] = (highestHi + lowestLo) / 2 // + baseStart because it needs to be shifted to the future\r\n }\r\n }\r\n\r\n let lastSpanAX = 0\r\n let lastSpanBX = 0\r\n const cloudStartingX = this.fx(spanBIndex + baseStartIndex)\r\n\r\n context.set('lineWidth', 1)\r\n context.translate(0.5, 0.5)\r\n context.save()\r\n // 1. Senkou Span A\r\n // 1.1 Stroke\r\n context.set('strokeStyle', spanAStrokeColor)\r\n context.set('fillStyle', spanAFillColor)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n fxOverride: this.fx,\r\n toIndexOffset: baseStartIndex,\r\n leftOffset,\r\n width,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(senkouSpanA[i])))\r\n lastSpanAX = x\r\n },\r\n })\r\n context.stroke()\r\n // 1.2 Clipping area\r\n context.lineTo(lastSpanAX, context.canvas.height)\r\n context.lineTo(cloudStartingX, context.canvas.height)\r\n context.clip()\r\n // 1.3 Fill\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n fxOverride: this.fx,\r\n toIndexOffset: baseStartIndex,\r\n leftOffset,\r\n width,\r\n drawBarCallback: (i, x) => {\r\n if (i >= senkouSpanA.length) return\r\n context.lineTo(x, Math.round(this.fy(senkouSpanB[i])))\r\n lastSpanBX = x\r\n },\r\n })\r\n context.lineTo(lastSpanBX, 0)\r\n context.lineTo(cloudStartingX, 0)\r\n context.fill()\r\n context.restore()\r\n\r\n // 2. Senkou Span B\r\n // 2.1 Stroke\r\n context.save()\r\n context.set('strokeStyle', spanBStrokeColor)\r\n context.set('fillStyle', spanBFillColor)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n fxOverride: this.fx,\r\n toIndexOffset: baseStartIndex,\r\n leftOffset,\r\n width,\r\n drawBarCallback: (i, x) => {\r\n if (i >= senkouSpanA.length) return\r\n context.lineTo(x, Math.round(this.fy(senkouSpanB[i])))\r\n },\r\n })\r\n context.stroke()\r\n // 2.2 Clipping area\r\n context.lineTo(lastSpanBX, context.canvas.height)\r\n context.lineTo(cloudStartingX, context.canvas.height)\r\n context.clip()\r\n // 2.3 Fill\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n fxOverride: this.fx,\r\n toIndexOffset: baseStartIndex,\r\n leftOffset,\r\n width,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(senkouSpanA[i])))\r\n },\r\n })\r\n context.lineTo(lastSpanBX, 0)\r\n context.lineTo(cloudStartingX, 0)\r\n context.fill()\r\n context.restore()\r\n context.translate(-0.5, -0.5)\r\n\r\n if (this.renderFull) {\r\n // conversion line\r\n context.set('strokeStyle', conversionLineColor)\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n fxOverride: this.fx,\r\n toIndexOffset: baseStartIndex,\r\n leftOffset,\r\n width,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(conversionLine[i])))\r\n },\r\n })\r\n context.stroke()\r\n\r\n // base line\r\n context.set('strokeStyle', baseLineColor)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n fxOverride: this.fx,\r\n toIndexOffset: baseStartIndex,\r\n leftOffset,\r\n width,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(baseLine[i])))\r\n },\r\n })\r\n context.stroke()\r\n\r\n // lagging span\r\n context.set('strokeStyle', laggingSpanColor)\r\n context.beginPath()\r\n drawInVisibleArea({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n fxOverride: (x: number) => this.fx(x - base),\r\n leftOffset,\r\n width,\r\n drawBarCallback: (i, x) => {\r\n context.lineTo(x, Math.round(this.fy(this.data.close[i])))\r\n },\r\n })\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n }\r\n\r\n getModalConfig() {\r\n const conversion = {\r\n type: 'number',\r\n label: 'Conversion Line',\r\n name: 'conversion',\r\n value: this.attrs.conversion ?? DEFAULT_PARAMETERS.Conversion,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const base = {\r\n type: 'number',\r\n label: 'Base Line Length',\r\n name: 'base',\r\n value: this.attrs.base ?? DEFAULT_PARAMETERS.Base,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const spanB = {\r\n type: 'number',\r\n label: 'Leading Span B Length',\r\n name: 'spanB',\r\n value: this.attrs.spanB ?? DEFAULT_PARAMETERS.SpanB,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n const spanAStrokeColor = {\r\n type: 'color',\r\n label: 'Span A Stroke Color',\r\n name: 'spanAStrokeColor',\r\n value: this.attrs.spanAStrokeColor ?? this.getFreeColor(),\r\n }\r\n const spanAFillColor = {\r\n type: 'color',\r\n label: 'Span A Fill Color',\r\n name: 'spanAFillColor',\r\n value: this.attrs.spanAFillColor ?? this.getFreeColor(),\r\n }\r\n const spanBStrokeColor = {\r\n type: 'color',\r\n label: 'Span B Stroke Color',\r\n name: 'spanBStrokeColor',\r\n value: this.attrs.spanBStrokeColor ?? this.getFreeColor(),\r\n }\r\n const spanBFillColor = {\r\n type: 'color',\r\n label: 'Span B Fill Color',\r\n name: 'spanBFillColor',\r\n value: this.attrs.spanBFillColor ?? this.getFreeColor(),\r\n }\r\n const conversionLineColor = {\r\n type: 'color',\r\n label: 'Conversion Line Color',\r\n name: 'conversionLineColor',\r\n value: this.attrs.conversionLineColor ?? this.getFreeColor(),\r\n }\r\n const baseLineColor = {\r\n type: 'color',\r\n label: 'Base Line Color',\r\n name: 'baseLineColor',\r\n value: this.attrs.baseLineColor ?? this.getFreeColor(),\r\n }\r\n const laggingSpanColor = {\r\n type: 'color',\r\n label: 'Lagging Span Color',\r\n name: 'laggingSpanColor',\r\n value: this.attrs.laggingSpanColor ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [\r\n conversion,\r\n base,\r\n spanB,\r\n spanAStrokeColor,\r\n spanAFillColor,\r\n spanBStrokeColor,\r\n spanBFillColor,\r\n conversionLineColor,\r\n baseLineColor,\r\n laggingSpanColor,\r\n ],\r\n inputsErrorMessages: {\r\n conversion: `${conversion.label} must be a whole number between ${conversion.min} and ${conversion.max}`,\r\n base: `${base.label} must be a whole number between ${base.min} and ${base.max}`,\r\n spanB: `${spanB.label} must be a whole number between ${spanB.min} and ${spanB.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'conversion':\r\n case 'base':\r\n case 'spanB':\r\n case 'lagging':\r\n return this.getIsNumberInputValid({ key })\r\n case 'spanAStrokeColor':\r\n case 'spanAFillColor':\r\n case 'spanBStrokeColor':\r\n case 'spanBFillColor':\r\n case 'conversionLineColor':\r\n case 'baseLineColor':\r\n case 'laggingSpanColor':\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.spanAStrokeColor\r\n }\r\n\r\n toString() {\r\n return `Ichimoku ${this.attrs.conversion},${this.attrs.base},${this.attrs.spanB}`\r\n }\r\n}\r\n\r\nIchimokuCloud.prototype.defaults = {\r\n spanAStrokeColor: COLORS.SpanA.Stroke,\r\n spanAFillColor: COLORS.SpanA.Fill,\r\n spanBStrokeColor: COLORS.SpanB.Stroke,\r\n spanBFillColor: COLORS.SpanB.Fill,\r\n conversionLineColor: COLORS.ConversionLine,\r\n baseLineColor: COLORS.BaseLine,\r\n laggingSpanColor: COLORS.LaggingSpan,\r\n}\r\n\r\nexport default IchimokuCloud\r\n","import { OverlayType } from '../constants/common'\r\nimport IchimokuCloud from './ic'\r\n\r\nclass IchimokuCloudFull extends IchimokuCloud {\r\n static type = OverlayType.Icf\r\n static label = 'Ichimoku Cloud (Full)'\r\n static renderFull = true\r\n}\r\n\r\nexport default IchimokuCloudFull\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { OverlayType } from '../constants/common'\r\nimport AverageTrueRange from '../helpers/atr'\r\nimport { ExponentialMovingAverage } from '../indicator-calculation/ema'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period?: string\r\n emaPeriod: number\r\n multiplier: number\r\n atrPeriod: number\r\n strokeColor: string\r\n fillColor: string\r\n}\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n emaPeriod: 20,\r\n multiplier: 2.0,\r\n atrPeriod: 10,\r\n}\r\n\r\nconst COLORS = {\r\n Stroke: '#69C1EA',\r\n Fill: '#69C1EA33',\r\n}\r\n\r\nfunction parsePeriod(period: string) {\r\n const values = period.split(',')\r\n const emaPeriod = parseInt(values[0])\r\n const multiplier = parseFloat(values[1])\r\n const atrPeriod = parseInt(values[2])\r\n\r\n return [emaPeriod, multiplier, atrPeriod]\r\n}\r\n\r\nclass KeltnerChannel extends Overlay {\r\n static type = OverlayType.Kch\r\n static label = 'Keltner Channel'\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n return Math.max(...parsePeriod(period)) * 2\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n if (\r\n typeof this.attrs.period === 'string' &&\r\n (this.attrs.emaPeriod === undefined || this.attrs.multiplier === undefined || this.attrs.atrPeriod === undefined)\r\n ) {\r\n const [emaPeriod, multiplier, atrPeriod] = parsePeriod(this.attrs.period)\r\n this.attrs.emaPeriod = emaPeriod\r\n this.attrs.multiplier = multiplier\r\n this.attrs.atrPeriod = atrPeriod\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n const { emaPeriod, multiplier, atrPeriod, strokeColor, fillColor } = this.attrs\r\n const ema = new ExponentialMovingAverage(emaPeriod)\r\n const atr = new AverageTrueRange(atrPeriod)\r\n const middleLine: number[] = []\r\n const upperBand: number[] = []\r\n const lowerBand: number[] = []\r\n const start = Math.max(emaPeriod, atrPeriod)\r\n let firstBarToRender\r\n let lastBarToRender = 0\r\n\r\n context.save()\r\n context.translate(0.5, 0.5)\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', strokeColor)\r\n context.set('fillStyle', fillColor)\r\n\r\n //top line + clip\r\n context.beginPath()\r\n for (let i = 1; i < this.data.close.length; i++) {\r\n ema.add(this.data.close[i])\r\n atr.add(this.data.high[i], this.data.low[i], this.data.close[i - 1])\r\n if (i < start) {\r\n continue\r\n }\r\n\r\n const x = this.fx(i)\r\n if (this.fx(i + 1) + leftOffset < 0) {\r\n continue\r\n }\r\n if (this.fx(i - 1) + leftOffset > width) {\r\n break\r\n }\r\n if (firstBarToRender === undefined) firstBarToRender = i\r\n\r\n middleLine[i] = ema.value\r\n upperBand[i] = ema.value + multiplier * atr.value\r\n lowerBand[i] = ema.value - multiplier * atr.value\r\n\r\n context.lineTo(x, Math.round(this.fy(upperBand[i])))\r\n lastBarToRender = i\r\n }\r\n if (firstBarToRender === undefined) {\r\n context.restore()\r\n return\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), context.canvas.height)\r\n context.lineTo(this.fx(firstBarToRender), context.canvas.height)\r\n context.clip()\r\n\r\n // bottom line + fill\r\n context.beginPath()\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n const x = this.fx(i)\r\n context.lineTo(x, Math.round(this.fy(lowerBand[i])))\r\n }\r\n context.stroke()\r\n context.lineTo(this.fx(lastBarToRender), 0)\r\n context.lineTo(0, 0)\r\n context.fill()\r\n\r\n // middle line\r\n context.beginPath()\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n const x = this.fx(i)\r\n context.lineTo(x, Math.round(this.fy(middleLine[i])))\r\n }\r\n context.stroke()\r\n context.restore()\r\n }\r\n\r\n getModalConfig() {\r\n const emaPeriod = {\r\n type: 'number',\r\n label: 'EMA Period',\r\n name: 'emaPeriod',\r\n value: this.attrs.emaPeriod ?? DEFAULT_PARAMETERS.emaPeriod,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n const multiplier = {\r\n type: 'number',\r\n label: 'Multiplier',\r\n name: 'multiplier',\r\n value: this.attrs.multiplier ?? DEFAULT_PARAMETERS.multiplier,\r\n required: true,\r\n step: 0.1,\r\n min: 0.0,\r\n max: 999,\r\n }\r\n\r\n const atrPeriod = {\r\n type: 'number',\r\n label: 'ATR Period',\r\n name: 'atrPeriod',\r\n value: this.attrs.atrPeriod ?? DEFAULT_PARAMETERS.atrPeriod,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n\r\n const strokeColor = {\r\n type: 'color',\r\n label: 'Stroke Color',\r\n name: 'strokeColor',\r\n value: this.attrs.strokeColor ?? this.getFreeColor(),\r\n }\r\n const fillColor = {\r\n type: 'color',\r\n label: 'Fill Color',\r\n name: 'fillColor',\r\n value: this.attrs.fillColor ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [emaPeriod, multiplier, atrPeriod, strokeColor, fillColor],\r\n inputsErrorMessages: {\r\n emaPeriod: `${emaPeriod.label} must be a whole number between ${emaPeriod.min} and ${emaPeriod.max}`,\r\n multiplier: `${multiplier.label} must be a number between ${multiplier.min} and ${multiplier.max}`,\r\n atrPeriod: `${atrPeriod.label} must be a whole number between ${atrPeriod.min} and ${atrPeriod.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'emaPeriod':\r\n return this.getIsNumberInputValid({ key })\r\n case 'multiplier':\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n case 'atrPeriod':\r\n return this.getIsNumberInputValid({ key })\r\n case 'strokeColor':\r\n case 'fillColor':\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.strokeColor\r\n }\r\n\r\n toString() {\r\n return `Keltner Channel ${this.attrs.emaPeriod},${this.attrs.multiplier},${this.attrs.atrPeriod}`\r\n }\r\n}\r\n\r\nKeltnerChannel.prototype.defaults = { strokeColor: COLORS.Stroke, fillColor: COLORS.Fill }\r\n\r\nexport default KeltnerChannel\r\n","import { OverlayType } from '../constants/common'\r\nimport Overlay from './overlay'\r\n\r\n// This indicator is used as a placeholder when we need to render TA like chart but don't need any overlay or indicator in the chart\r\nclass None extends Overlay {\r\n static type = OverlayType.None\r\n static label = 'None'\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n isRendered() {\r\n return false\r\n }\r\n\r\n getIsValid() {\r\n return true\r\n }\r\n}\r\n\r\nexport default None\r\n","import Text from '../canvas/text'\r\nimport { OverlayType, TextAlign, TextBaseline } from '../constants/common'\r\nimport { getRoundedObject, getXYOffsetFromLine } from '../controllers/renderUtils'\r\nimport Overlay from './overlay'\r\n\r\ntype aboveBelowType = 'above' | 'below'\r\n\r\nclass Patterns extends Overlay {\r\n static type = OverlayType.Patterns\r\n static label = 'Patterns (daily charts)'\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { ChartSettings } = this.getChartLayoutSettings()\r\n const data = this.data\r\n if (data.patterns.length === 0) {\r\n return\r\n }\r\n\r\n const originalScale = {\r\n width: 600,\r\n height: 300,\r\n barsInDay: Math.min(data.close.length, 200),\r\n high: data.patternsMaxRange,\r\n low: data.patternsMinRange,\r\n barWidth: 0,\r\n }\r\n originalScale.barWidth = originalScale.width / 200\r\n\r\n const scaleY = (originalScale.high - originalScale.low) / originalScale.height\r\n const fx = (x: number) => {\r\n if (x === 0) {\r\n return this.fx(0)\r\n }\r\n return this.fx(data.close.length - 1 - ~~(originalScale.barsInDay - x / originalScale.barWidth))\r\n }\r\n const fy = (y: number) => this.fy(originalScale.high - y * scaleY)\r\n const line = (color: string, x1: number, y1: number, x2: number, y2: number) => {\r\n const roundedXY = getRoundedObject({\r\n x1: fx(x1),\r\n y1: fy(y1),\r\n x2: fx(x2),\r\n y2: fy(y2),\r\n })\r\n const translateXY = getXYOffsetFromLine({ lineWidth: 1, ...roundedXY })\r\n context.translate(translateXY.x, translateXY.y)\r\n\r\n context.beginPath()\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', color)\r\n context.lineTo(roundedXY.x1, roundedXY.y1)\r\n context.lineTo(roundedXY.x2, roundedXY.y2)\r\n context.stroke()\r\n\r\n context.translate(translateXY.x * -1, translateXY.y * -1)\r\n }\r\n const text = (text: string, aboveBelow: aboveBelowType, color: string, x1: number, x2: number, y1: number) => {\r\n new Text(\r\n {\r\n x: fx((x1 + x2) / 2),\r\n y: fy(y1) + (aboveBelow === 'above' ? -1 : 2),\r\n font: { size: 8, style: 'bold' },\r\n textBaseline: aboveBelow === 'above' ? TextBaseline.bottom : TextBaseline.top,\r\n fillStyle: color,\r\n textAlign: TextAlign.center,\r\n text,\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n const textHS = (text: string, aboveBelow: aboveBelowType, color: string, x1: number, y1: number) => {\r\n new Text(\r\n {\r\n x: fx(x1) + 5,\r\n y: fy(y1) + (aboveBelow === 'above' ? -1 : 2),\r\n font: { size: 9, style: 'bold' },\r\n textBaseline: aboveBelow === 'above' ? TextBaseline.bottom : TextBaseline.top,\r\n fillStyle: color,\r\n textAlign: TextAlign.center,\r\n text,\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n const above = (y: number) =>\r\n fy(y) + 10 >= this.model.height - ChartSettings.top.height - ChartSettings.bottom.height ? 'above' : 'below'\r\n const below = (y: number) => (fy(y) <= 15 ? 'below' : 'above')\r\n\r\n const supportColor = 'rgb(0, 150, 220)'\r\n const resistColor = 'rgb(180, 50, 200)'\r\n\r\n for (const pattern of data.patterns) {\r\n const { x1, x2, x3, y3 } = pattern\r\n let { y1, y2 } = pattern\r\n switch (pattern.kind) {\r\n case 1: // Horiz S/R\r\n line('rgba(50, 50, 180, 0.588)', x1, y1, x2, y2)\r\n break\r\n\r\n case 2: // tl resist\r\n line(resistColor, x1, y1, x2, y2)\r\n break\r\n\r\n case 3: // tl support\r\n if (y1 === originalScale.height && y2 === originalScale.height) {\r\n y1 = y2 = originalScale.height - 1\r\n // Maybe just need to check on the new scale?\r\n } // support \"pod grafom\"\r\n line(supportColor, x1, y1, x2, y2)\r\n break\r\n\r\n case 12: // double top\r\n text('Double Top', below(y1), resistColor, x1, x2, y1)\r\n break\r\n\r\n case 13: // double bottom\r\n text('Double Bottom', above(y1), supportColor, x1, x2, y1)\r\n break\r\n\r\n case 14: // multi top\r\n text('Multiple Top', below(y1), resistColor, x1, x2, y1)\r\n break\r\n\r\n case 15: // multi bottom\r\n text('Multiple Bottom', above(y1), supportColor, x1, x2, y1)\r\n break\r\n\r\n case 16: // h&s top\r\n textHS('L', below(y1), resistColor, x1, y1)\r\n textHS('H', below(y2), resistColor, x2, y2)\r\n textHS('R', below(y3), resistColor, x3, y3)\r\n break\r\n\r\n case 17: // h&s bot\r\n textHS('L', above(y1), supportColor, x1, y1)\r\n textHS('H', above(y2), supportColor, x2, y2)\r\n textHS('R', above(y3), supportColor, x3, y3)\r\n break\r\n default:\r\n break\r\n }\r\n }\r\n }\r\n\r\n getModalConfig() {\r\n const supportColor = {\r\n type: 'color',\r\n label: 'Support Color',\r\n name: 'supportColor',\r\n value: this.attrs.supportColor ?? this.getFreeColor(),\r\n }\r\n const resistColor = {\r\n type: 'color',\r\n label: 'Resist Color',\r\n name: 'resistColor',\r\n value: this.attrs.resistColor ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [supportColor, resistColor],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n getIsValid() {\r\n return true\r\n }\r\n\r\n isRenderedOverlaysLabel() {\r\n return false\r\n }\r\n\r\n toString() {\r\n return ''\r\n }\r\n}\r\n\r\nPatterns.prototype.defaults = { supportColor: '#69c1ea', resistColor: '#d386df' }\r\n\r\nexport default Patterns\r\n","import * as dateFns from 'date-fns'\r\n\r\nimport { Instrument } from '../../types/shared'\r\nimport Text from '../canvas/text'\r\nimport { OverlayType, TIMEFRAME, TextBaseline } from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport Utils from '../utils'\r\nimport { getBarWidthWithMargin, round } from '../utils/chart'\r\nimport { getFirstBarToRenderIndex, getLastBarToRenderIndex } from '../utils/draw_in_visible_area'\r\nimport Overlay from './overlay'\r\n\r\nenum Calculation {\r\n standard = 'Standard',\r\n fibonacci = 'Fibonacci',\r\n}\r\ntype CalculationType = keyof typeof Calculation\r\n\r\nenum PivotPeriod {\r\n day,\r\n week,\r\n month,\r\n year,\r\n}\r\n\r\ntype PivotPointType = {\r\n pivot: number\r\n res1: number\r\n res2: number\r\n res3: number\r\n sup1: number\r\n sup2: number\r\n sup3: number\r\n}\r\n\r\ninterface Attrs {\r\n period?: string\r\n calculationType: CalculationType\r\n color: string\r\n}\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n CalculationType: 'standard' as CalculationType,\r\n Color: '#FFA75F',\r\n}\r\nconst FIB_LVL_1 = 0.382\r\nconst FIB_LVL_2 = 0.618\r\nconst DAY_SECONDS = 86400\r\nconst MINUTES_PER_DAY = 1440\r\n\r\nclass PivotPoints extends Overlay {\r\n static type = OverlayType.Pp\r\n static label = 'Pivot Points'\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (period) {\r\n this.attrs.calculationType = period as CalculationType\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n getPeriodType() {\r\n switch (this.data.timeframe) {\r\n case TIMEFRAME.i30:\r\n case TIMEFRAME.h:\r\n case TIMEFRAME.h2:\r\n return PivotPeriod.week\r\n case TIMEFRAME.h4:\r\n case TIMEFRAME.d:\r\n return PivotPeriod.month\r\n case TIMEFRAME.w:\r\n case TIMEFRAME.m:\r\n return PivotPeriod.year\r\n default:\r\n return PivotPeriod.day\r\n }\r\n }\r\n\r\n getIsEnoughData(startIndex: number, endIndex: number, periodType: PivotPeriod) {\r\n let dayGap = 7 // one week for week period\r\n if (periodType === PivotPeriod.month) dayGap = 28 // shortest month\r\n if (periodType === PivotPeriod.year) dayGap = 365\r\n\r\n if (startIndex !== endIndex) {\r\n if (startIndex === 0) {\r\n const daysDiff = (this.data.date[endIndex] - this.data.date[startIndex]) / DAY_SECONDS\r\n // we need to somehow determine if we have data if it starts from index 0\r\n // and we can't easily check if day before is different (different month/week/year)\r\n // so we are at least checking if it is [dayGap] days between start and end date\r\n return daysDiff >= dayGap\r\n } else {\r\n const startDay = Utils.dateFromUnixTimestamp(this.data.date[startIndex])\r\n const beforeDay = Utils.dateFromUnixTimestamp(this.data.date[startIndex - 1])\r\n if (periodType === PivotPeriod.week) {\r\n return beforeDay.getDate() !== startDay.getDate()\r\n } else {\r\n return beforeDay.getMonth() !== startDay.getMonth()\r\n }\r\n }\r\n }\r\n return false\r\n }\r\n\r\n fx = (x: number) => {\r\n const lastIndex = this.data.close.length - 1\r\n const outsideBar = this.data.barIndex[lastIndex] + x - lastIndex\r\n\r\n return this.model.scale.x(this.data.barIndex[x] ?? outsideBar)\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n if (this.data.close.length === 0) return\r\n\r\n const chartModel = this.model.chart() as Chart\r\n const { leftOffset, width, zoomFactor } = chartModel\r\n const { left, right } = chartModel.getChartLayoutSettings().ChartSettings\r\n const chartWidth = width - left.width - right.width\r\n const barWidth = getBarWidthWithMargin({\r\n zoomFactor,\r\n chartLayout: chartModel.chart_layout(),\r\n })\r\n\r\n const firstBarToRender = getFirstBarToRenderIndex({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n leftOffset,\r\n }).index\r\n const lastBarToRender = getLastBarToRenderIndex({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n leftOffset,\r\n chartWidth,\r\n }).index\r\n\r\n const text = (label: string, price: number, calculatedX: number) => {\r\n new Text(\r\n {\r\n x: calculatedX,\r\n y: this.fy(price) - 13,\r\n font: { size: 8, weight: '900' },\r\n textBaseline: TextBaseline.top,\r\n fillStyle: this.attrs.color,\r\n text: `${label} (${round({ data: this.data, num: price })})`,\r\n },\r\n this.model\r\n ).render(context)\r\n }\r\n\r\n const line = (fromX: number, toX: number, y: number) => {\r\n context.moveTo(fromX, this.fy(y))\r\n context.lineTo(toX, this.fy(y))\r\n }\r\n\r\n let startIndex = -1\r\n let endIndex = -1\r\n const isStock = this.data.instrument === Instrument.Stock\r\n const periodType = this.getPeriodType()\r\n let currentDate = new Date()\r\n let lastDate: Date | undefined\r\n\r\n context.translate(0.5, 0.5)\r\n context.set('strokeStyle', this.attrs.color)\r\n\r\n for (let index = firstBarToRender; index <= lastBarToRender; index++) {\r\n currentDate = Utils.dateFromUnixTimestamp(this.data.date[index])\r\n\r\n // check if new calculation/render is necessary\r\n switch (periodType) {\r\n case PivotPeriod.day: // only if it is a new day\r\n if (currentDate.getDate() === lastDate?.getDate()) {\r\n continue\r\n }\r\n break\r\n case PivotPeriod.week: // only if it is a new week\r\n if (lastDate && dateFns.isSameWeek(lastDate, currentDate, { weekStartsOn: 1 })) {\r\n continue\r\n }\r\n break\r\n case PivotPeriod.month: // only if it is a new month\r\n if (currentDate.getMonth() === lastDate?.getMonth()) {\r\n continue\r\n }\r\n break\r\n case PivotPeriod.year: // only if it is a new year\r\n if (currentDate.getFullYear() === lastDate?.getFullYear()) {\r\n continue\r\n }\r\n break\r\n }\r\n lastDate = currentDate\r\n\r\n // Find start/end indexes for the entire previous period\r\n switch (periodType) {\r\n case PivotPeriod.day:\r\n if (index > 0) {\r\n let previousTradingDay = new Date()\r\n for (let i = index - 1; i >= 0; i--) {\r\n previousTradingDay = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (previousTradingDay.getDate() !== currentDate.getDate()) break\r\n }\r\n previousTradingDay.setHours(0, 0, 0, 0)\r\n const previousNYMidnightTimestamp = Utils.convertLocalToNyTime(previousTradingDay, false).getTime() / 1000\r\n const currentMidnight = new Date(currentDate)\r\n currentMidnight.setHours(0, 0, 0, 0)\r\n const currentNYMidnightTimestamp = Utils.convertLocalToNyTime(currentMidnight, false).getTime() / 1000\r\n\r\n startIndex = this.data.date.findIndex((ts) => ts >= previousNYMidnightTimestamp)\r\n endIndex = this.data.date.findIndex((ts) => ts > currentNYMidnightTimestamp)\r\n\r\n // check if we have data for entire day\r\n if (startIndex !== endIndex) {\r\n const diff = this.data.date[endIndex] - this.data.date[startIndex]\r\n const isNonStockFullDay = !isStock && diff >= DAY_SECONDS\r\n const isStockFullDay = isStock && previousTradingDay.getDate() !== currentDate.getDate()\r\n if (!isNonStockFullDay && !isStockFullDay) {\r\n startIndex = endIndex = Number.MIN_SAFE_INTEGER\r\n }\r\n }\r\n }\r\n break\r\n case PivotPeriod.week:\r\n const firstDayCurrentWeek = dateFns.startOfWeek(currentDate, { weekStartsOn: 1 })\r\n const firstDayCurrentWeekTimestamp = Utils.convertLocalToNyTime(firstDayCurrentWeek, false).getTime() / 1000\r\n const firstDayPreviousWeek = dateFns.sub(firstDayCurrentWeek, { weeks: 1 })\r\n const firstDayPreviousWeekTimestamp = Utils.convertLocalToNyTime(firstDayPreviousWeek, false).getTime() / 1000\r\n\r\n startIndex = this.data.date.findIndex((ts) => ts >= firstDayPreviousWeekTimestamp)\r\n endIndex = this.data.date.findIndex((ts) => ts > firstDayCurrentWeekTimestamp)\r\n\r\n if (!this.getIsEnoughData(startIndex, endIndex, periodType)) {\r\n startIndex = endIndex = Number.MIN_SAFE_INTEGER\r\n }\r\n break\r\n case PivotPeriod.month:\r\n const firstDayCurrentMonth = dateFns.startOfMonth(currentDate)\r\n const firstDayCurrentMonthTimestamp = Utils.convertLocalToNyTime(firstDayCurrentMonth, false).getTime() / 1000\r\n const firstDayPreviousMonth = dateFns.sub(firstDayCurrentMonth, { months: 1 })\r\n const firstDayPreviousMonthTimestamp =\r\n Utils.convertLocalToNyTime(firstDayPreviousMonth, false).getTime() / 1000\r\n\r\n startIndex = this.data.date.findIndex((ts) => ts >= firstDayPreviousMonthTimestamp)\r\n endIndex = this.data.date.findIndex((ts) => ts > firstDayCurrentMonthTimestamp)\r\n\r\n if (!this.getIsEnoughData(startIndex, endIndex, periodType)) {\r\n startIndex = endIndex = Number.MIN_SAFE_INTEGER\r\n }\r\n break\r\n case PivotPeriod.year:\r\n const firstDayCurrentYear = dateFns.startOfYear(currentDate)\r\n const firstDayCurrentYearTimestamp = Utils.convertLocalToNyTime(firstDayCurrentYear, false).getTime() / 1000\r\n const firstDayPreviousYear = dateFns.sub(firstDayCurrentYear, { years: 1 })\r\n const firstDayPreviousYearTimestamp = Utils.convertLocalToNyTime(firstDayPreviousYear, false).getTime() / 1000\r\n\r\n startIndex = this.data.date.findIndex((ts) => ts >= firstDayPreviousYearTimestamp)\r\n endIndex = this.data.date.findIndex((ts) => ts > firstDayCurrentYearTimestamp)\r\n\r\n if (!this.getIsEnoughData(startIndex, endIndex, periodType)) {\r\n startIndex = endIndex = Number.MIN_SAFE_INTEGER\r\n }\r\n break\r\n }\r\n\r\n // calculate pivot point if it was found\r\n if (!(startIndex !== -1 && endIndex !== -1 && startIndex < endIndex)) continue\r\n\r\n let pivot, sup1, sup2, sup3, res1, res2, res3\r\n const previousHigh = Math.max(...this.data.high.slice(startIndex, endIndex))\r\n const previousLow = Math.min(...this.data.low.slice(startIndex, endIndex))\r\n const previousClose = this.data.close[endIndex - 1] // endIndex is the beginning of the next period\r\n\r\n if (this.attrs.calculationType === 'standard') {\r\n pivot = (previousHigh + previousLow + previousClose) / 3\r\n sup1 = 2 * pivot - previousHigh\r\n sup2 = pivot - (previousHigh - previousLow)\r\n sup3 = previousLow - 2 * (previousHigh - pivot)\r\n res1 = 2 * pivot - previousLow\r\n res2 = pivot + (previousHigh - previousLow)\r\n res3 = previousHigh + 2 * (pivot - previousLow)\r\n } else {\r\n pivot = (previousHigh + previousLow + previousClose) / 3\r\n sup1 = pivot - (previousHigh - previousLow) * FIB_LVL_1\r\n sup2 = pivot - (previousHigh - previousLow) * FIB_LVL_2\r\n sup3 = pivot - (previousHigh - previousLow)\r\n res1 = pivot + (previousHigh - previousLow) * FIB_LVL_1\r\n res2 = pivot + (previousHigh - previousLow) * FIB_LVL_2\r\n res3 = pivot + (previousHigh - previousLow)\r\n }\r\n\r\n const pivotPoint: PivotPointType = { pivot, sup1, sup2, sup3, res1, res2, res3 }\r\n\r\n // prepare x coordinates for lines rendering\r\n let fromX = this.fx(index)\r\n let toX = this.fx(index)\r\n switch (periodType) {\r\n case PivotPeriod.day:\r\n const interval = this.data.interval\r\n const currentX = fromX\r\n\r\n const toDate = new Date(currentDate)\r\n toDate.setHours(16, 0, 0, 0)\r\n if (this.data.aftermarket && interval <= 5) toDate.setHours(18, 30, 0, 0)\r\n if (interval <= 15 && !isStock) toDate.setHours(23, 59, 59, 99)\r\n const toTimestamp = toDate.getTime() / 1000\r\n const toDiffMinutes = (toTimestamp - currentDate.getTime() / 1000) / 60\r\n const toBars = toDiffMinutes / interval\r\n toX = Math.min(currentX + toBars * barWidth, -leftOffset + width)\r\n\r\n const fromDate = new Date(currentDate)\r\n fromDate.setHours(9, 30, 0, 0)\r\n if (this.data.premarket && interval <= 5) fromDate.setHours(7, 0, 0, 0)\r\n if (interval <= 15 && !isStock) fromDate.setHours(0, 0, 0, 0)\r\n const fromTimestamp = fromDate.getTime() / 1000\r\n const fromDiffMinutes = (fromTimestamp - currentDate.getTime() / 1000) / 60\r\n const fromBars = fromDiffMinutes / interval\r\n fromX = currentX + fromBars * barWidth\r\n break\r\n\r\n case PivotPeriod.week:\r\n for (let i = index + 1; i <= lastBarToRender; i++) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (!dateFns.isSameWeek(currentDate, nextDate, { weekStartsOn: 1 })) {\r\n toX = this.fx(i)\r\n break\r\n }\r\n }\r\n for (let i = index - 1; i >= firstBarToRender; i--) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (!dateFns.isSameWeek(currentDate, nextDate, { weekStartsOn: 1 })) {\r\n fromX = this.fx(i + 1) // because we need start from current week\r\n break\r\n }\r\n }\r\n\r\n if (fromX === toX) {\r\n // we need line to imaginary end of the week\r\n const barsPerDay = Math.ceil((this.data.drawMinutesPerDay ?? MINUTES_PER_DAY) / this.data.interval)\r\n toX += (isStock ? 5 : 7) * barsPerDay * barWidth\r\n }\r\n break\r\n\r\n case PivotPeriod.month:\r\n for (let i = index + 1; i <= lastBarToRender; i++) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (nextDate.getMonth() !== currentDate.getMonth()) {\r\n toX = this.fx(i)\r\n break\r\n }\r\n }\r\n for (let i = index - 1; i >= firstBarToRender; i--) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (nextDate.getMonth() !== currentDate.getMonth()) {\r\n fromX = this.fx(i + 1) // because we need start from current month\r\n break\r\n }\r\n }\r\n\r\n if (fromX === toX) {\r\n // we need line to imaginary end of the month\r\n const barsPerDay = this.data.isIntraday\r\n ? Math.ceil((this.data.drawMinutesPerDay ?? MINUTES_PER_DAY) / this.data.interval)\r\n : 1\r\n toX += (isStock ? 20 : 30) * barsPerDay * barWidth\r\n }\r\n break\r\n default:\r\n for (let i = index + 1; i <= lastBarToRender; i++) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (nextDate.getFullYear() !== currentDate.getFullYear()) {\r\n toX = this.fx(i)\r\n break\r\n }\r\n }\r\n for (let i = index - 1; i >= firstBarToRender; i--) {\r\n const nextDate = Utils.dateFromUnixTimestamp(this.data.date[i])\r\n if (nextDate.getFullYear() !== currentDate.getFullYear()) {\r\n fromX = this.fx(i + 1) // because we need start from current year\r\n break\r\n }\r\n }\r\n\r\n if (fromX === toX) {\r\n // we need line to imaginary end of the year\r\n toX += (this.data.timeframe === TIMEFRAME.w ? 49 : 12) * barWidth\r\n }\r\n break\r\n }\r\n fromX = Math.max(fromX, -leftOffset)\r\n\r\n // render pivot line\r\n context.beginPath()\r\n line(fromX, toX, pivotPoint.pivot)\r\n context.stroke()\r\n\r\n // render resistance and support lines\r\n context.save()\r\n context.setLineDash([3, 3])\r\n context.beginPath()\r\n line(fromX, toX, pivotPoint.res1)\r\n line(fromX, toX, pivotPoint.res2)\r\n line(fromX, toX, pivotPoint.res3)\r\n line(fromX, toX, pivotPoint.sup1)\r\n line(fromX, toX, pivotPoint.sup2)\r\n line(fromX, toX, pivotPoint.sup3)\r\n context.stroke()\r\n context.restore()\r\n\r\n // render labels if there is enough space\r\n if (toX - fromX >= 48) {\r\n text('P', pivotPoint.pivot, fromX)\r\n text('R1', pivotPoint.res1, fromX)\r\n text('R2', pivotPoint.res2, fromX)\r\n text('R3', pivotPoint.res3, fromX)\r\n text('S1', pivotPoint.sup1, fromX)\r\n text('S2', pivotPoint.sup2, fromX)\r\n text('S3', pivotPoint.sup3, fromX)\r\n }\r\n }\r\n\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const calculationType = {\r\n type: 'select',\r\n label: 'Calculation Type',\r\n name: 'calculationType',\r\n value: this.attrs.calculationType ?? DEFAULT_PARAMETERS.CalculationType,\r\n required: true,\r\n items: [\r\n {\r\n value: 'standard',\r\n label: 'Standard',\r\n },\r\n {\r\n value: 'fibonacci',\r\n label: 'Fibonacci',\r\n },\r\n ],\r\n }\r\n const color = {\r\n type: 'color',\r\n label: 'Color',\r\n name: 'color',\r\n value: this.attrs.color ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [calculationType, color],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'calculationType':\r\n case 'color':\r\n return !!this.attrs[key]\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `Pivot Points (${Calculation[this.attrs.calculationType]})`\r\n }\r\n}\r\n\r\nPivotPoints.prototype.defaults = {\r\n calculationType: DEFAULT_PARAMETERS.CalculationType,\r\n color: DEFAULT_PARAMETERS.Color,\r\n}\r\n\r\nexport default PivotPoints\r\n","import { OverlayType } from '../constants/common'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n step: number\r\n period: string\r\n maxStep: number\r\n risingColor: string\r\n fallingColor: string\r\n}\r\n\r\nclass SAR extends Overlay {\r\n static type = OverlayType.Sar\r\n static label = 'Parabolic SAR'\r\n\r\n static getNumOfBarsBuffer() {\r\n return 0\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n if (typeof this.attrs.period === 'string' && (this.attrs.step === undefined || this.attrs.maxStep === undefined)) {\r\n const [step = 0, maxStep = 0] = this.attrs.period.split(',').map((x) => parseFloat(x))\r\n this.attrs.step = step\r\n this.attrs.maxStep = maxStep\r\n }\r\n this.trigger('change')\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const data = this.data\r\n const deltaHigh = data.high[1] - data.high[0]\r\n const deltaLow = data.low[0] - data.low[1]\r\n const pdm = deltaHigh > 0 && deltaHigh > deltaLow ? deltaHigh : 0\r\n const mdm = deltaLow > 0 && deltaLow > deltaHigh ? deltaLow : 0\r\n let isLong = pdm >= mdm\r\n\r\n let sar = isLong ? data.low[0] : data.high[0]\r\n let ep = isLong ? data.high[1] : data.low[1]\r\n let newHigh = data.high[0]\r\n let newLow = data.low[0]\r\n let af = this.attrs.step\r\n\r\n for (let i = 1, end = data.close.length, asc = end >= 1; asc ? i < end : i > end; asc ? i++ : i--) {\r\n let sarToDraw\r\n const prevHigh = newHigh\r\n const prevLow = newLow\r\n newHigh = data.high[i]\r\n newLow = data.low[i]\r\n\r\n if (isLong) {\r\n if (newLow <= sar) {\r\n isLong = false\r\n sar = ep\r\n\r\n if (sar < prevHigh) {\r\n sar = prevHigh\r\n }\r\n if (sar < newHigh) {\r\n sar = newHigh\r\n }\r\n\r\n sarToDraw = sar\r\n\r\n af = this.attrs.step\r\n ep = newLow\r\n\r\n sar = sar + af * (ep - sar)\r\n\r\n if (sar < prevHigh) {\r\n sar = prevHigh\r\n }\r\n if (sar < newHigh) {\r\n sar = newHigh\r\n }\r\n } else {\r\n sarToDraw = sar\r\n\r\n if (newHigh > ep) {\r\n ep = newHigh\r\n af += this.attrs.step\r\n if (af > this.attrs.maxStep) {\r\n af = this.attrs.maxStep\r\n }\r\n }\r\n\r\n sar = sar + af * (ep - sar)\r\n\r\n if (sar > prevLow) {\r\n sar = prevLow\r\n }\r\n if (sar > newLow) {\r\n sar = newLow\r\n }\r\n }\r\n } else {\r\n if (newHigh >= sar) {\r\n isLong = true\r\n sar = ep\r\n\r\n if (sar > prevLow) {\r\n sar = prevLow\r\n }\r\n if (sar > newLow) {\r\n sar = newLow\r\n }\r\n\r\n sarToDraw = sar\r\n\r\n af = this.attrs.step\r\n ep = newHigh\r\n\r\n sar = sar + af * (ep - sar)\r\n\r\n if (sar > prevLow) {\r\n sar = prevLow\r\n }\r\n if (sar > newLow) {\r\n sar = newLow\r\n }\r\n } else {\r\n sarToDraw = sar\r\n\r\n if (newLow < ep) {\r\n ep = newLow\r\n af += this.attrs.step\r\n if (af > this.attrs.maxStep) {\r\n af = this.attrs.maxStep\r\n }\r\n }\r\n\r\n sar = sar + af * (ep - sar)\r\n\r\n if (sar < prevHigh) {\r\n sar = prevHigh\r\n }\r\n if (sar < newHigh) {\r\n sar = newHigh\r\n }\r\n }\r\n }\r\n\r\n const x = Math.round(this.fx(i) - 1.5)\r\n const y = Math.round(this.fy(sarToDraw) - 1.5)\r\n context.set('fillStyle', isLong ? this.attrs.risingColor : this.attrs.fallingColor)\r\n context.fillRect(x, y, 3, 3)\r\n }\r\n }\r\n\r\n getModalConfig() {\r\n const step = {\r\n type: 'number',\r\n step: 0.01,\r\n min: 0.01,\r\n max: 999,\r\n label: 'Step',\r\n name: 'step',\r\n value: this.attrs.step ?? 0.02,\r\n required: true,\r\n }\r\n const maxStep = {\r\n type: 'number',\r\n step: 0.01,\r\n min: 0.01,\r\n max: 999,\r\n label: 'Maximum Step',\r\n name: 'maxStep',\r\n value: this.attrs.maxStep ?? 0.2,\r\n required: true,\r\n }\r\n const risingColor = {\r\n type: 'color',\r\n label: 'Rising Color',\r\n name: 'risingColor',\r\n value: this.attrs.risingColor ?? this.getFreeColor(),\r\n customizable: false,\r\n }\r\n const fallingColor = {\r\n type: 'color',\r\n label: 'Falling Color',\r\n name: 'fallingColor',\r\n value: this.attrs.fallingColor ?? this.getFreeColor(),\r\n customizable: false,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [step, maxStep, risingColor, fallingColor],\r\n inputsErrorMessages: {\r\n step: `${step.label} must be a number between ${step.min} and ${step.max}`,\r\n maxStep: `${maxStep.label} must be a number between ${maxStep.min} and ${maxStep.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'step':\r\n case 'maxStep': {\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n }\r\n case 'risingColor':\r\n case 'fallingColor':\r\n // Some users have wrong colors which break the form validation\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.risingColor\r\n }\r\n\r\n toString() {\r\n return `SAR ${this.attrs.step},${this.attrs.maxStep}`\r\n }\r\n}\r\n\r\nSAR.prototype.defaults = {\r\n risingColor: '#69c1ea',\r\n fallingColor: '#d386df',\r\n}\r\n\r\nexport default SAR\r\n","import { OverlayType } from '../constants/common'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n period: number\r\n}\r\n\r\ntype DefaultCalculatedValuesType = {\r\n sma: number[]\r\n}\r\n\r\nexport class SMACalculation extends MainCalculation {\r\n static type = OverlayType.Sma\r\n declare options: Options\r\n\r\n getDefaultCalculatedValues() {\r\n return { sma: [] }\r\n }\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { close } = this.quote\r\n const lastIndex = close.length - 1\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n let sum = 0\r\n for (let i = 0; i < this.options.period; i++) {\r\n sum += close[i]\r\n }\r\n for (let i = this.options.period; i <= lastIndex; i++) {\r\n sum = sum - close[i - this.options.period] + close[i]\r\n this.calculatedValues.sma[i] = sum / this.options.period\r\n\r\n if (onValueCalculated?.(this.calculatedValues, i) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { OverlayType } from '../constants/common'\r\nimport { SMACalculation } from '../indicator-calculation/sma'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n step: number\r\n period: string\r\n maxStep: number\r\n risingColor: string\r\n color: string\r\n}\r\n\r\nclass SMA extends Overlay {\r\n static type = OverlayType.Sma\r\n static label = 'Simple Moving Average'\r\n\r\n static getNumOfBarsBuffer(chartConfig: RequireByKey) {\r\n const numOfBarsBuffer = Overlay.getNumOfBarsBuffer(chartConfig)\r\n return numOfBarsBuffer + 1 // +1 offsets rendering so it doesn't start on first bar which doesn't look OK in SSR rendered charts\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n this.attrs.period = parseInt(period, 10)\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n const period = Math.min(this.attrs.period, this.data.close.length - 1)\r\n context.beginPath()\r\n context.translate(0.5, 0.5)\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', this.attrs.color)\r\n\r\n const smaCalculation = new SMACalculation({\r\n quote: this.data,\r\n options: { period },\r\n })\r\n\r\n smaCalculation.calculate(({ sma }, dataIndex) => {\r\n const x = this.fx(dataIndex)\r\n if (this.fx(dataIndex + 1) + leftOffset < 0) {\r\n return\r\n }\r\n if (this.fx(dataIndex - 1) + leftOffset > width) {\r\n return false\r\n }\r\n context.lineTo(x, Math.round(this.fy(sma[dataIndex])))\r\n })\r\n\r\n context.translate(-0.5, -0.5)\r\n context.stroke()\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.attrs.period ?? 5,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const color = {\r\n type: 'color',\r\n label: 'Color',\r\n name: 'color',\r\n value: this.attrs.color ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, color],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'color':\r\n return !!this.attrs[key] // use real color validation, we got isValidHexColor but it might be also RGBA\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n toString() {\r\n return `SMA ${this.attrs.period}`\r\n }\r\n}\r\n\r\nSMA.prototype.defaults = { color: '#ffa75f' }\r\n\r\nexport default SMA\r\n","import { OverlayType } from '../constants/common'\r\nimport SMA from './sma'\r\n\r\nclass SMA2 extends SMA {\r\n static type = OverlayType.Sma2\r\n}\r\n\r\nSMA2.prototype.defaults = { color: '#ff6400' }\r\n\r\nexport default SMA2\r\n","import { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { OverlayType } from '../constants/common'\r\nimport AverageTrueRange from '../helpers/atr'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period: number\r\n multiplier: number\r\n uptrendColor: string\r\n downtrendColor: string\r\n}\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n Period: 7,\r\n Multiplier: 3.0,\r\n}\r\n\r\nconst COLORS = {\r\n Uptrend: '#00a000',\r\n Downtrend: '#c80000',\r\n}\r\n\r\nfunction parsePeriod(periodStr: string) {\r\n const values = periodStr.split(',')\r\n const period = parseInt(values[0]) || DEFAULT_PARAMETERS.Period\r\n const multiplier = parseFloat(values[1]) || DEFAULT_PARAMETERS.Multiplier\r\n\r\n return [period, multiplier]\r\n}\r\n\r\nclass Supertrend extends Overlay {\r\n static type = OverlayType.Str\r\n static label = 'Supertrend'\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [periodInt] = parsePeriod(period)\r\n return periodInt + 1\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n const [periodInt, multiplier] = parsePeriod(period)\r\n this.attrs.period = periodInt\r\n this.attrs.multiplier = multiplier\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n const { leftOffset, width } = this.model.chart()\r\n const { period, multiplier } = this.attrs\r\n const { high, low, close } = this.data\r\n const atr = new AverageTrueRange(period)\r\n const finalUpperBand: number[] = []\r\n const finalLowerBand: number[] = []\r\n const supertrend: boolean[] = []\r\n let firstBarToRender\r\n let lastBarToRender = 0\r\n\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', this.attrs.uptrendColor)\r\n for (let i = 1; i < close.length; i++) {\r\n atr.add(high[i], low[i], close[i - 1])\r\n\r\n // compute bands\r\n const avg = (high[i] + low[i]) / 2\r\n const upperBand = avg + multiplier * atr.value\r\n const lowerBand = avg - multiplier * atr.value\r\n\r\n finalUpperBand[i] = upperBand\r\n finalLowerBand[i] = lowerBand\r\n\r\n // identify supertrend\r\n if (close[i] > finalUpperBand[i - 1]) {\r\n supertrend[i] = true\r\n } else if (close[i] < finalLowerBand[i - 1]) {\r\n supertrend[i] = false\r\n } else {\r\n supertrend[i] = supertrend[i - 1]\r\n }\r\n\r\n // adjust bands\r\n if (supertrend[i] && finalLowerBand[i] < finalLowerBand[i - 1]) {\r\n finalLowerBand[i] = finalLowerBand[i - 1]\r\n }\r\n if (!supertrend[i] && finalUpperBand[i] > finalUpperBand[i - 1]) {\r\n finalUpperBand[i] = finalUpperBand[i - 1]\r\n }\r\n\r\n const x = this.fx(i)\r\n if (i < period || x + leftOffset < 0) {\r\n continue\r\n }\r\n if (this.fx(i - 1) + leftOffset > width) {\r\n break\r\n }\r\n if (firstBarToRender === undefined) firstBarToRender = i\r\n\r\n if (supertrend[i] && !supertrend[i - 1]) {\r\n // buy\r\n context.moveTo(this.fx(i - 1), Math.round(this.fy(finalUpperBand[i - 1])))\r\n context.lineTo(x, Math.round(this.fy(finalLowerBand[i])))\r\n } else if (supertrend[i]) {\r\n // keep buying\r\n context.lineTo(x, Math.round(this.fy(finalLowerBand[i])))\r\n } else {\r\n // keep selling\r\n context.moveTo(x, Math.round(this.fy(finalLowerBand[i])))\r\n }\r\n lastBarToRender = i\r\n }\r\n context.stroke()\r\n\r\n if (firstBarToRender === undefined) {\r\n context.translate(-0.5, -0.5)\r\n return\r\n }\r\n\r\n context.beginPath()\r\n context.set('strokeStyle', this.attrs.downtrendColor)\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n const x = this.fx(i)\r\n if (!supertrend[i] && supertrend[i - 1]) {\r\n // sell\r\n context.moveTo(this.fx(i - 1), Math.round(this.fy(finalLowerBand[i - 1])))\r\n context.lineTo(x, Math.round(this.fy(finalUpperBand[i])))\r\n } else if (!supertrend[i]) {\r\n // keep selling\r\n context.lineTo(x, Math.round(this.fy(finalUpperBand[i])))\r\n } else {\r\n // keep buying\r\n context.moveTo(x, Math.round(this.fy(finalUpperBand[i])))\r\n }\r\n }\r\n context.stroke()\r\n\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'period',\r\n value: this.attrs.period ?? DEFAULT_PARAMETERS.Period,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const multiplier = {\r\n type: 'number',\r\n label: 'Period',\r\n name: 'multiplier',\r\n value: this.attrs.multiplier ?? DEFAULT_PARAMETERS.Multiplier,\r\n required: true,\r\n step: 0.1,\r\n min: 0.0,\r\n max: 999,\r\n }\r\n\r\n const uptrendColor = {\r\n type: 'color',\r\n label: 'Uptrend Color',\r\n name: 'uptrendColor',\r\n value: this.attrs.uptrendColor ?? this.getFreeColor(),\r\n }\r\n const downtrendColor = {\r\n type: 'color',\r\n label: 'Downtrend Color',\r\n name: 'downtrendColor',\r\n value: this.attrs.downtrendColor ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, multiplier, uptrendColor, downtrendColor],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n multiplier: `${multiplier.label} must be a number between ${multiplier.min} and ${multiplier.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'multiplier':\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n case 'uptrendColor':\r\n case 'downtrendColor':\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor(): string {\r\n return this.attrs.uptrendColor\r\n }\r\n\r\n toString() {\r\n return `Supertrend ${this.attrs.period},${this.attrs.multiplier}`\r\n }\r\n}\r\n\r\nSupertrend.prototype.defaults = {\r\n uptrendColor: COLORS.Uptrend,\r\n downtrendColor: COLORS.Downtrend,\r\n}\r\n\r\nexport default Supertrend\r\n","import * as d3 from 'd3'\r\n\r\nimport { ChartConfigChartPaneElement, RequireByKey } from '../../types/shared'\r\nimport { OverlayType } from '../constants/common'\r\nimport Chart from '../models/chart'\r\nimport utils from '../utils'\r\nimport { convertColorToHEX, getHEXWithSpecificAplha } from '../utils/colors'\r\nimport { getFirstBarToRenderIndex, getLastBarToRenderIndex } from '../utils/draw_in_visible_area'\r\nimport { getParsedIntegersFromPeriodString } from '../utils/helpers'\r\nimport Overlay from './overlay'\r\n\r\nconst VP_COLORS = {\r\n UP: '#00FF00',\r\n DOWN: '#FF0000',\r\n}\r\n\r\nconst DEFAULT_PARAMETERS = {\r\n Period: 20,\r\n Opacity: 0.3,\r\n}\r\n\r\ninterface Attrs {\r\n period: number | string\r\n opacity: number\r\n upColor?: string\r\n downColor?: string\r\n}\r\n\r\nfunction applyOpacityToColor(color: string, opacity: number) {\r\n return getHEXWithSpecificAplha(convertColorToHEX(color), opacity)\r\n}\r\n\r\nfunction getColorsWithAppliedOpacity(attrs: Attrs) {\r\n return [\r\n applyOpacityToColor(attrs.upColor ?? VP_COLORS.UP, attrs.opacity),\r\n applyOpacityToColor(attrs.downColor ?? VP_COLORS.DOWN, attrs.opacity),\r\n ]\r\n}\r\n\r\n// Only time when we want value to be able to equal start of segment is first segment,\r\n// because start of next segment is equal to end of previous and value would match two segments\r\nfunction isInSegment(val: number, start: number, end: number, notEqualStart: boolean) {\r\n return (notEqualStart ? val > start : val >= start) && val <= end\r\n}\r\n\r\nfunction parsePeriod(periodStr: string) {\r\n const values = periodStr.split(',')\r\n const period = parseInt(values[0]) || DEFAULT_PARAMETERS.Period\r\n const opacity = parseFloat(values[1]) || DEFAULT_PARAMETERS.Opacity\r\n\r\n return [period, opacity]\r\n}\r\n\r\nclass VolumeProfile extends Overlay {\r\n static type = OverlayType.Vp\r\n static label = 'Volume Profile'\r\n\r\n static getNumOfBarsBuffer({ period }: RequireByKey) {\r\n const [periodInt = 0] = getParsedIntegersFromPeriodString(period)\r\n return periodInt + 1 // +1 offsets rendering so it doesn't start on first bar which doesn't look OK in SSR rendered charts\r\n }\r\n\r\n set(obj: Partial) {\r\n super.set(obj)\r\n const { period } = obj\r\n if (typeof period === 'string') {\r\n const [periodInt, opacity] = parsePeriod(period)\r\n this.attrs.period = periodInt\r\n this.attrs.opacity = opacity\r\n this.trigger('change')\r\n }\r\n return this\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n if (typeof this.attrs.period !== 'number') {\r\n return\r\n }\r\n super.renderContent()\r\n\r\n const chartModel = this.model.chart() as Chart\r\n const { leftOffset, width } = chartModel\r\n const { left, right } = chartModel.getChartLayoutSettings().ChartSettings\r\n const chartWidth = width - left.width - right.width\r\n\r\n if (this.data.close.length === 0) return\r\n\r\n const firstBarToRender = getFirstBarToRenderIndex({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n leftOffset,\r\n }).index\r\n\r\n const lastBarToRender = getLastBarToRenderIndex({\r\n quote: this.data,\r\n scale: this.model.scale,\r\n leftOffset,\r\n chartWidth,\r\n }).index\r\n\r\n const [upColor, downColor] = getColorsWithAppliedOpacity(this.attrs)\r\n const [minClose, maxClose] = utils.minMax(this.data.close.slice(firstBarToRender, lastBarToRender + 1))\r\n\r\n const segment = Math.abs(maxClose - minClose) / this.attrs.period\r\n const segments = [] // create an empty array to hold the segments\r\n\r\n for (let i = 0; i < this.attrs.period; i++) {\r\n const segmentStart = minClose + segment * i // calculate start of current segment\r\n const segmentEnd = segmentStart + segment // calculate end of current segment\r\n segments.push({ start: segmentStart, end: segmentEnd, up: 0, down: 0 }) // add segment to array\r\n }\r\n\r\n // loop through visible bars and assign volumes to segments\r\n for (let i = firstBarToRender; i <= lastBarToRender; i++) {\r\n const segmentIndex: number = segments.findIndex((item, segmentIndex) =>\r\n isInSegment(this.data.close[i], item.start, item.end, !!segmentIndex)\r\n )\r\n if (segmentIndex === -1) continue\r\n const volumeTrend = this.data.close[i] < this.data.open[i] ? 'down' : 'up'\r\n segments[segmentIndex][volumeTrend] += this.data.volume[i]\r\n }\r\n\r\n const max = utils.max(segments.map((item) => item.up + item.down))\r\n const rangeMax = chartWidth * 0.4 // maximum range in pixels where longest bar would reach (now it's 40% of chart width)\r\n const volumeFX = d3.scaleLinear().range([0, rangeMax]).domain([0, max])\r\n\r\n segments.forEach((item) => {\r\n const y = Math.round(this.fy(item.start))\r\n const segmentHeightRaw = Math.round(this.fy(item.end)) - y // raw segment height without gap between segments\r\n const segmentHeight = segmentHeightRaw + (Math.abs(segmentHeightRaw) > 5 ? 2 : 1) // apply gap to segment based on how high segment is\r\n const x = Math.abs(leftOffset) // segments are alligned to left side of chart which equal to absoulute value of leftOffset\r\n const upSegmentWidth = Math.round(volumeFX(item.up))\r\n const downSegmentWidth = Math.round(volumeFX(item.down))\r\n\r\n context.fillStyle = upColor\r\n context.fillRect(x, y, upSegmentWidth, segmentHeight)\r\n context.fillStyle = downColor\r\n context.fillRect(x + upSegmentWidth, y, downSegmentWidth, segmentHeight)\r\n })\r\n }\r\n\r\n getModalConfig() {\r\n const period = {\r\n type: 'number',\r\n label: 'Zones',\r\n name: 'period',\r\n value: this.attrs.period ?? DEFAULT_PARAMETERS.Period,\r\n required: true,\r\n min: 1,\r\n max: 999999,\r\n }\r\n const opacity = {\r\n type: 'number',\r\n label: 'Opacity',\r\n name: 'opacity',\r\n value: this.attrs.opacity ?? DEFAULT_PARAMETERS.Opacity,\r\n required: true,\r\n min: 0,\r\n max: 1,\r\n step: 0.1,\r\n }\r\n const upColor = {\r\n type: 'color',\r\n label: 'Up Color',\r\n name: 'upColor',\r\n value: this.attrs.upColor ?? VP_COLORS.UP,\r\n }\r\n const downColor = {\r\n type: 'color',\r\n label: 'Down Color',\r\n name: 'downColor',\r\n value: this.attrs.downColor ?? VP_COLORS.DOWN,\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [period, opacity, upColor, downColor],\r\n inputsErrorMessages: {\r\n period: `${period.label} must be a whole number between ${period.min} and ${period.max}`,\r\n opacity: `${opacity.label} must be a number between ${opacity.min} and ${opacity.max}`,\r\n },\r\n }\r\n }\r\n\r\n getIsValid(key: string): boolean {\r\n switch (key) {\r\n case 'period':\r\n return this.getIsNumberInputValid({ key })\r\n case 'opacity':\r\n return this.getIsNumberInputValid({ key, integerOnly: false })\r\n case 'upColor':\r\n case 'downColor':\r\n // Some users have wrong colors which break the form validation\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n getLabelColor() {\r\n return this.attrs.upColor || VP_COLORS.UP\r\n }\r\n\r\n toString() {\r\n return `VP ${this.attrs.period}`\r\n }\r\n}\r\n\r\nVolumeProfile.prototype.defaults = { upColor: VP_COLORS.UP, downColor: VP_COLORS.DOWN }\r\n\r\nexport default VolumeProfile\r\n","import { OverlayType } from '../constants/common'\r\nimport { dateFromUnixTimestamp } from '../utils'\r\nimport { MainCalculation, OnValueCalculated } from './main'\r\n\r\ntype Options = {\r\n period: number\r\n}\r\n\r\nconst datesAreOnSameDay = (first: Date, second: Date) =>\r\n first.getFullYear() === second.getFullYear() &&\r\n first.getMonth() === second.getMonth() &&\r\n first.getDate() === second.getDate()\r\n\r\ntype DefaultCalculatedValuesType = {\r\n vwap: number[]\r\n}\r\n\r\nexport class VWapCalculation extends MainCalculation {\r\n static type = OverlayType.Vwap\r\n\r\n getDefaultCalculatedValues() {\r\n return { vwap: [] }\r\n }\r\n\r\n calculate(onValueCalculated?: OnValueCalculated) {\r\n const { date, close, low, high, volume } = this.quote\r\n const lastIndex = date.length - 1\r\n this._calculatedValues = this.getDefaultCalculatedValues()\r\n\r\n let cumulativePV = 0\r\n let cumulativeVolume = 0\r\n\r\n for (let i = 0; i <= lastIndex; i++) {\r\n if (i > 0) {\r\n const prevDate = dateFromUnixTimestamp(date[i - 1])\r\n if (!datesAreOnSameDay(prevDate, dateFromUnixTimestamp(date[i]))) {\r\n cumulativePV = 0\r\n cumulativeVolume = 0\r\n }\r\n }\r\n\r\n const typicalPrice = (close[i] + low[i] + high[i]) / 3\r\n const pv = typicalPrice * volume[i]\r\n\r\n cumulativePV += pv\r\n cumulativeVolume += volume[i]\r\n\r\n this.calculatedValues.vwap[i] = cumulativePV / cumulativeVolume\r\n\r\n if (onValueCalculated?.(this.calculatedValues, i) === false) {\r\n break\r\n }\r\n }\r\n }\r\n}\r\n","import { OverlayType } from '../constants/common'\r\nimport { VWapCalculation } from '../indicator-calculation/vwap'\r\nimport PaneModel from '../models/pane'\r\nimport Overlay from './overlay'\r\n\r\ninterface Attrs {\r\n period: number\r\n color: string\r\n}\r\n\r\nclass VWAP extends Overlay {\r\n static type = OverlayType.Vwap\r\n static label = 'VWAP (intraday charts)'\r\n\r\n static getNumOfBarsBuffer() {\r\n return 1\r\n }\r\n\r\n constructor(values: Partial, model: PaneModel) {\r\n super(values, model)\r\n this.attrs.period = 5\r\n }\r\n\r\n renderContent(context: CanvasRenderingContext2D) {\r\n super.renderContent()\r\n if (!this.isRendered()) {\r\n return\r\n }\r\n\r\n const { leftOffset, width } = this.model.chart()\r\n context.translate(0.5, 0.5)\r\n context.beginPath()\r\n context.set('lineWidth', 1)\r\n context.set('strokeStyle', this.attrs.color)\r\n\r\n const vwapCalculation = new VWapCalculation({\r\n quote: this.data,\r\n options: { period: this.attrs.period },\r\n })\r\n\r\n vwapCalculation.calculate(({ vwap }, dataIndex) => {\r\n const x = this.fx(dataIndex)\r\n if (this.fx(dataIndex + 1) + leftOffset < 0) {\r\n return // continue\r\n }\r\n if (this.fx(dataIndex - 1) + leftOffset > width) {\r\n return false // break\r\n }\r\n const y = Math.round(this.fy(vwap[dataIndex]))\r\n context.lineTo(x, y)\r\n })\r\n\r\n context.stroke()\r\n context.translate(-0.5, -0.5)\r\n }\r\n\r\n getModalConfig() {\r\n const color = {\r\n type: 'color',\r\n label: 'Color',\r\n name: 'color',\r\n value: this.attrs.color ?? this.getFreeColor(),\r\n }\r\n\r\n return {\r\n title: this.label,\r\n inputs: [color],\r\n inputsErrorMessages: {},\r\n }\r\n }\r\n\r\n getIsValid(key: string) {\r\n switch (key) {\r\n case 'color':\r\n // Some users have wrong colors which break the form validation\r\n return true\r\n default:\r\n return false\r\n }\r\n }\r\n\r\n isRendered() {\r\n return this.model.chart().quote().isIntraday\r\n }\r\n\r\n isRenderedOverlaysLabel() {\r\n return this.isRendered()\r\n }\r\n\r\n toString() {\r\n return `VWAP`\r\n }\r\n}\r\n\r\nVWAP.prototype.defaults = { color: '#9467bd' }\r\n\r\nexport default VWAP\r\n","import { OverlayType } from '../constants/common'\r\nimport bb from './bb'\r\nimport dch from './dch'\r\nimport ema from './ema'\r\nimport ema2 from './ema2'\r\nimport hilo from './hilo'\r\nimport hline from './hline'\r\nimport ic from './ic'\r\nimport icf from './icf'\r\nimport kch from './kch'\r\nimport none from './none'\r\nimport overlay from './overlay'\r\nimport patterns from './patterns'\r\nimport pp from './pp'\r\nimport sar from './sar'\r\nimport sma from './sma'\r\nimport sma2 from './sma2'\r\nimport str from './str'\r\nimport vp from './vp'\r\nimport vwap from './vwap'\r\n\r\nexport const overlaysByType = Object.freeze({\r\n [OverlayType.Overlay]: overlay,\r\n [OverlayType.None]: none,\r\n [OverlayType.Bb]: bb,\r\n [OverlayType.Dch]: dch,\r\n [OverlayType.Ema]: ema,\r\n [OverlayType.Ema2]: ema2,\r\n [OverlayType.Hilo]: hilo,\r\n [OverlayType.Hline]: hline,\r\n [OverlayType.Ic]: ic,\r\n [OverlayType.Icf]: icf,\r\n [OverlayType.Kch]: kch,\r\n [OverlayType.Patterns]: patterns,\r\n [OverlayType.Pp]: pp,\r\n [OverlayType.Sar]: sar,\r\n [OverlayType.Sma]: sma,\r\n [OverlayType.Sma2]: sma2,\r\n [OverlayType.Str]: str,\r\n [OverlayType.Vp]: vp,\r\n [OverlayType.Vwap]: vwap,\r\n})\r\n","import {\r\n MOBILE_VIEW_BREAKPOINT_WIDTH,\r\n PREMARKET_AFTERMARKET_HOURS,\r\n SpecificChartFunctionality,\r\n} from './constants/common'\r\nimport { captureException, getIsSSr } from './utils/helpers'\r\n\r\nexport { getSanitizedTicker } from './utils/ticker-sanitizer'\r\n\r\nfunction getIsDstInNy(date: Date) {\r\n const dayNumber = date.getDate()\r\n const monthIndex = date.getMonth()\r\n const dayOfWeek = date.getDay()\r\n const previousSunday = dayNumber - dayOfWeek\r\n if (monthIndex < 2 || monthIndex > 10) {\r\n return false\r\n }\r\n if (monthIndex > 2 && monthIndex < 10) {\r\n return true\r\n }\r\n return monthIndex === 2 ? previousSunday >= 8 : previousSunday <= 0\r\n}\r\n\r\nclass Utils {\r\n static min(...args: T[]): number {\r\n if (typeof args[0] === 'number') {\r\n return args[0] < +args[1] ? args[0] : (args[1] as number)\r\n }\r\n let min = args[0][0]\r\n for (const arg of args) {\r\n for (const el of arg as number[]) {\r\n if (el < min) {\r\n min = el\r\n }\r\n }\r\n }\r\n return min\r\n }\r\n\r\n static max(...args: T[]): number {\r\n if (typeof args[0] === 'number') {\r\n return args[0] > +args[1] ? args[0] : (args[1] as number)\r\n }\r\n let max = args[0][0]\r\n for (const arg of args) {\r\n for (const el of arg as number[]) {\r\n if (el > max) {\r\n max = el\r\n }\r\n }\r\n }\r\n return max\r\n }\r\n\r\n static minMax(...args: number[][]) {\r\n let max\r\n let min = (max = args[0][0] as number)\r\n for (const arg of args) {\r\n for (const el of arg) {\r\n if (el < min) {\r\n min = el\r\n }\r\n if (el > max) {\r\n max = el\r\n }\r\n }\r\n }\r\n return [min, max]\r\n }\r\n\r\n static getScaleRatio() {\r\n return (typeof window !== 'undefined' && window.devicePixelRatio) || 1\r\n }\r\n\r\n static setSizeOnCanvasElement({\r\n canvasElement,\r\n width,\r\n height,\r\n ratio = Utils.getScaleRatio(),\r\n }: {\r\n canvasElement: HTMLCanvasElement | null\r\n width: number\r\n height: number\r\n ratio?: number\r\n }) {\r\n if (canvasElement) {\r\n canvasElement.width = width * ratio\r\n canvasElement.height = height * ratio\r\n canvasElement.style.width = width + 'px'\r\n canvasElement.style.height = height + 'px'\r\n }\r\n }\r\n\r\n static getQuoteDateTimestampOffsetInSeconds(referenceDate?: Date) {\r\n const date = referenceDate || new Date()\r\n const dateAsNY = new Date(\r\n date.getUTCFullYear(),\r\n date.getUTCMonth(),\r\n date.getUTCDate(),\r\n date.getUTCHours() - 5,\r\n date.getUTCMinutes(),\r\n date.getUTCSeconds()\r\n )\r\n const isDst = getIsDstInNy(dateAsNY)\r\n return (isDst ? 4 : 5) * 60 * 60\r\n }\r\n\r\n static convertLocalToNyTime(referenceDate: Date, addOffset: boolean) {\r\n const date = new Date(referenceDate)\r\n const quoteDateTimeOffsetInMs = Utils.getQuoteDateTimestampOffsetInSeconds(date) * 1000\r\n const localTimeOffsetInMs = date.getTimezoneOffset() * 60 * 1000\r\n const offsetDirectionCoefficient = addOffset ? 1 : -1\r\n date.setTime(date.getTime() + (localTimeOffsetInMs - quoteDateTimeOffsetInMs) * offsetDirectionCoefficient)\r\n return date\r\n }\r\n\r\n // Keep in sync with the clone in Website repo in shared/isStockFastRefreshAvailable.ts\r\n static isStockFastRefreshAvailable(hasPremarket = true, hasAftermarket = true, bufferMinutes = 30) {\r\n const MARKET_START = { hours: 9, minutes: 30 }\r\n const MARKET_END = { hours: 16, minutes: 0 }\r\n const getMinutes = ({ hours, minutes }: { hours: number; minutes: number }) => hours * 60 + minutes\r\n\r\n const date = convertLocalToNyTime(new Date(), true)\r\n const dayOfWeek = date.getDay()\r\n const currentDayMinutes = date.getHours() * 60 + date.getMinutes()\r\n\r\n const premarketMinutes = hasPremarket ? PREMARKET_AFTERMARKET_HOURS * 60 : 0\r\n const aftermarketMinutes = hasAftermarket ? PREMARKET_AFTERMARKET_HOURS * 60 : 0\r\n\r\n const isWeekend = dayOfWeek === 0 || dayOfWeek === 6\r\n const isOpen = getMinutes(MARKET_START) - premarketMinutes - bufferMinutes <= currentDayMinutes\r\n const isClosed = getMinutes(MARKET_END) + aftermarketMinutes + bufferMinutes <= currentDayMinutes\r\n return !isWeekend && isOpen && !isClosed\r\n }\r\n\r\n static dateFromUnixTimestamp(timestamp: number) {\r\n /*\r\n * Passing 0 as a param is needed in order to setUTCSeconds work properly.\r\n * The function adds seconds to the date instance if it exceeds 60.\r\n * For more info see the docs https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setUTCSeconds\r\n * */\r\n const date = new Date(0)\r\n date.setUTCSeconds(timestamp)\r\n return Utils.convertLocalToNyTime(date, true)\r\n }\r\n\r\n static dateStringFromDate(date: Date) {\r\n return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(\r\n 2,\r\n '0'\r\n )}`\r\n }\r\n\r\n static dateFromDateString(dateString: string) {\r\n const [yyyy, mm, dd] = dateString.split('-')\r\n\r\n const date = new Date(Number.parseInt(yyyy), Number.parseInt(mm) - 1, Number.parseInt(dd))\r\n if (Number.isNaN(date.getTime())) {\r\n captureException(new Error('Invalid Date'), { extra: { date } })\r\n }\r\n\r\n return date\r\n }\r\n\r\n static isMobile(testTouchPoints?: boolean) {\r\n if (getIsSSr()) return false\r\n let isMobileOs = false\r\n\r\n // New iOS versions no longer report iPad in user agent\r\n if (navigator.userAgent.indexOf('Macintosh') > -1) {\r\n try {\r\n document.createEvent('TouchEvent')\r\n isMobileOs = true\r\n } catch (e) {}\r\n } else {\r\n isMobileOs = !!navigator.userAgent.match(\r\n /\\b(Android|webOS|i(?:Phone|Pad|Pod)|BlackBerry|Windows (?:Phone|Mobile))\\b/i\r\n )\r\n }\r\n\r\n if (testTouchPoints) {\r\n try {\r\n return (\r\n isMobileOs &&\r\n (window.navigator.msMaxTouchPoints ||\r\n window.navigator.maxTouchPoints ||\r\n 'ontouchstart' in document.createElement('div'))\r\n )\r\n } catch (e) {}\r\n }\r\n\r\n return isMobileOs\r\n }\r\n\r\n static isIPad() {\r\n const matchesIPad = navigator.userAgent.match(/iPad/i)\r\n const matchesIPhone = navigator.userAgent.match(/iPhone/i)\r\n const matchesIPod = navigator.userAgent.match(/iPod/i)\r\n const matchesIOSLike = navigator.userAgent.match(/Mac/) && navigator.maxTouchPoints > 0\r\n\r\n return (matchesIOSLike && !matchesIPhone && !matchesIPod) || matchesIPad\r\n }\r\n\r\n static getCookie(name: string) {\r\n const re = new RegExp('(?:(?:^|.*;\\\\s*)' + name + '\\\\s*\\\\=\\\\s*([^;]*).*$)|^.*$')\r\n return document.cookie.replace(re, '$1')\r\n }\r\n\r\n static setCookie(name: string, value: string, expires: Date) {\r\n let cookie = name + '=' + value + '; expires=' + expires.toUTCString()\r\n if (document.location.hostname !== 'localhost') {\r\n cookie += '; domain=.finviz.com'\r\n }\r\n document.cookie = cookie\r\n }\r\n}\r\n\r\nexport default Utils\r\nexport const convertLocalToNyTime = Utils.convertLocalToNyTime\r\nexport const dateFromUnixTimestamp = Utils.dateFromUnixTimestamp\r\nexport const dateStringFromDate = Utils.dateStringFromDate\r\nexport const dateFromDateString = Utils.dateFromDateString\r\n\r\nexport function getFullscreenStatus(): boolean {\r\n return (\r\n document.fullscreenElement ??\r\n document.webkitFullscreenElement ??\r\n document.mozFullScreenElement ??\r\n document.msFullscreenElement ??\r\n false\r\n )\r\n}\r\n\r\nexport function getRequestFullscreen(element: HTMLElement) {\r\n return (\r\n element.requestFullscreen ??\r\n element.webkitRequestFullScreen ??\r\n element.mozRequestFullScreen ??\r\n element.msRequestFullscreen\r\n )\r\n}\r\n\r\nexport function getExitFullscreen() {\r\n return (\r\n document.exitFullscreen ?? document.webkitExitFullscreen ?? document.mozExitFullScreen ?? document.msExitFullscreen\r\n )\r\n}\r\n\r\nexport function ready(fn: () => void) {\r\n if (document.readyState !== 'loading') {\r\n fn()\r\n return\r\n }\r\n\r\n document.addEventListener('DOMContentLoaded', fn)\r\n}\r\n\r\nexport function getChartsDimensions(chartElementId: string) {\r\n const PADDING = 2 // Border widths\r\n const containerElement = document.getElementById(chartElementId)\r\n\r\n const box = containerElement?.getBoundingClientRect()\r\n\r\n return {\r\n width: Math.max((box?.width ?? 0) - PADDING, 0),\r\n height: Math.max((box?.height ?? 0) - PADDING, 0),\r\n }\r\n}\r\n\r\nexport function getIsMobileScreenSize() {\r\n return window.innerWidth < MOBILE_VIEW_BREAKPOINT_WIDTH\r\n}\r\n\r\nexport function getIsMobilePortrait(isMobile?: boolean) {\r\n if (isMobile ?? Utils.isMobile()) {\r\n return window.orientation % 180 === 0\r\n }\r\n return false\r\n}\r\n\r\nexport function numberToStringWithUnitsSuffix(value: number) {\r\n let suffix = ''\r\n if (value >= 1000000000) {\r\n value /= 1000000000\r\n suffix = 'B'\r\n } else if (value >= 1000000) {\r\n value /= 1000000\r\n suffix = 'M'\r\n } else if (value >= 1000) {\r\n value /= 1000\r\n suffix = 'K'\r\n }\r\n\r\n return value.toFixed(2) + suffix\r\n}\r\n\r\nexport function isRedesignEnabled() {\r\n return typeof window !== 'undefined' && window.FinvizSettings?.hasRedesignEnabled\r\n}\r\n\r\nexport function isRedesignedPage(\r\n obj: { specificChartFunctionality?: SpecificChartFunctionality | null },\r\n matchingPages = [\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.futuresPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n ]\r\n) {\r\n return (\r\n (isRedesignEnabled() && matchingPages.includes(obj.specificChartFunctionality!)) ||\r\n // Legacy design on quote uses redesigned elements (page header + chart controls)\r\n obj.specificChartFunctionality === SpecificChartFunctionality.quotePage\r\n )\r\n}\r\n","import { ObjectHash } from '../../types/shared'\r\n\r\nconst requestsAbortControllersCache: ObjectHash = {}\r\n\r\nexport function removeFromAbortCache(key: string) {\r\n delete requestsAbortControllersCache[key]\r\n}\r\n\r\nexport function abortRequest(key: string) {\r\n requestsAbortControllersCache[key]?.abort()\r\n removeFromAbortCache(key)\r\n}\r\n\r\nexport function getIsAbortError(error: Error) {\r\n return error.name === 'AbortError'\r\n}\r\n\r\nexport function createRequestAbortController({\r\n key,\r\n shouldAbortRunningRequest = false,\r\n}: {\r\n key: string\r\n shouldAbortRunningRequest?: boolean\r\n}) {\r\n if (shouldAbortRunningRequest) {\r\n abortRequest(key)\r\n }\r\n const controller = 'AbortController' in window ? new AbortController() : undefined\r\n if (controller) {\r\n requestsAbortControllersCache[key] = controller\r\n }\r\n return controller\r\n}\r\n","import * as websiteShared from '@finviz/website'\r\n\r\nimport { captureException } from './helpers'\r\n\r\n/**\r\n * Hook used to asynchronously load a module\r\n *\r\n * Usage: [wiki](https://github.com/finvizhq/Finviz-Website/wiki/Loading-modules-asynchronously#useasyncmodule)\r\n */\r\nexport const useAsyncModule = (props: {\r\n importFn: () => Promise\r\n onError?: () => void\r\n cacheKey: string\r\n captureException?: (exception: Error, captureContext?: { extra: Record }) => void\r\n errorSeverity?: 'medium' | 'high'\r\n shouldLoadModule?: boolean\r\n isSuspenseMode?: SuspenseMode\r\n}) =>\r\n websiteShared.useAsyncModule({ captureException, ...props }) as [\r\n SuspenseMode extends true ? T : T | null,\r\n { isLoading: boolean; loadModule: () => Promise; isError: boolean },\r\n ]\r\n","import { getIsSSr } from './helpers'\r\n\r\n// Extracted from isMobile, and modified to fit usage\r\nfunction isFirefoxDesktop() {\r\n const matchesAndroid = navigator.userAgent.match(/Android/i)\r\n const matchesWebOS = navigator.userAgent.match(/webOS/i)\r\n const matchesIPhone = navigator.userAgent.match(/iPhone/i)\r\n const matchesiPad = navigator.userAgent.match(/iPad/i)\r\n const matchesIPod = navigator.userAgent.match(/iPod/i)\r\n const matchesBlackBerry = navigator.userAgent.match(/BlackBerry/i)\r\n const matchesWindowsPhone = navigator.userAgent.match(/Windows Phone/i)\r\n const matchesIOSLike = navigator.userAgent.match(/Mac/) && navigator.maxTouchPoints > 0\r\n\r\n const isMobileDevice =\r\n matchesAndroid ||\r\n matchesWebOS ||\r\n matchesIPhone ||\r\n matchesiPad ||\r\n matchesIPod ||\r\n matchesBlackBerry ||\r\n matchesWindowsPhone ||\r\n matchesIOSLike\r\n\r\n const matchesFirefox = !!navigator.userAgent.match(/firefox/i)\r\n\r\n return matchesFirefox && !isMobileDevice\r\n}\r\n\r\n// Due bug in FireFox, when if HW acceleration is used canvas is blurry\r\n// we need to set canvas as CPU only\r\nconst shouldUseCPUOnly = getIsSSr() ? false : isFirefoxDesktop()\r\n\r\nexport function getContextWithCache(canvas: HTMLCanvasElement | null): CanvasRenderingContext2D | null {\r\n if (!canvas) {\r\n return null\r\n }\r\n\r\n const context = canvas.getContext('2d', shouldUseCPUOnly ? { willReadFrequently: true } : undefined)\r\n if (!context) {\r\n window.Sentry?.captureMessage('Context unavailable')\r\n return null\r\n }\r\n\r\n context._cache = {}\r\n\r\n const _restore = CanvasRenderingContext2D.prototype.restore\r\n context.restore = function () {\r\n this._cache = {}\r\n return _restore.apply(this)\r\n }\r\n\r\n context.set = function (key, value) {\r\n if (this._cache[key] !== value) {\r\n this[key] = value\r\n this._cache[key] = value\r\n }\r\n }\r\n\r\n return context\r\n}\r\n","import { Theme } from '../../types/shared'\r\nimport twColors from '../constants/colors'\r\nimport { ChartEventType } from '../constants/common'\r\nimport math, { BIG_NUMBER_VALUES, BigNumber } from '../helpers/math'\r\nimport utils from '../utils'\r\nimport { formatDateToStringUS } from '../utils/helpers'\r\n\r\ninterface IChartEventBase {\r\n elementId: string\r\n eventType: ChartEventType\r\n dateTimestamp: number // represent 'earningsDate' column of earnings and 'exdate' column for dividends & split\r\n}\r\n\r\nexport interface IEarnings extends IChartEventBase {\r\n epsActual?: number\r\n epsEstimate?: number\r\n epsReportedActual?: number\r\n epsReportedEstimate?: number\r\n fiscalEndDate: number\r\n fiscalPeriod: string\r\n salesActual?: number\r\n salesEstimate?: number\r\n}\r\n\r\nexport interface IDividends extends IChartEventBase {\r\n ordinary: number\r\n special: number\r\n}\r\n\r\nexport interface ISplit extends IChartEventBase {\r\n factorFrom: number\r\n factorTo: number\r\n}\r\n\r\nexport enum ChartEventBadgeState {\r\n default = 'default',\r\n hover = 'hover',\r\n selected = 'selected',\r\n}\r\n\r\nexport interface IChartEventBadgeProps {\r\n theme: Theme\r\n state: ChartEventBadgeState\r\n width: number\r\n}\r\n\r\ninterface IGetChartEventBadgeColors {\r\n theme: Theme\r\n state: ChartEventBadgeState\r\n colors: IBadgeColors\r\n}\r\n\r\ninterface IBadgeStateColors {\r\n default: string\r\n hover: string\r\n selected: string\r\n}\r\n\r\ninterface IBadgeThemeColors {\r\n outerStroke: string\r\n innerStroke: string\r\n innerFill: IBadgeStateColors\r\n textFill: IBadgeStateColors\r\n}\r\n\r\ninterface IBadgeColors {\r\n light: IBadgeThemeColors\r\n dark: IBadgeThemeColors\r\n}\r\n\r\nexport function getChartEventBadgeColors({ theme, state, colors }: IGetChartEventBadgeColors) {\r\n return {\r\n outerStroke: colors[theme].outerStroke,\r\n innerStroke: colors[theme].innerStroke,\r\n innerFill: colors[theme].innerFill[state],\r\n textFill: colors[theme].textFill[state],\r\n }\r\n}\r\n\r\nexport function getFormattedEventDate(\r\n exdate: number,\r\n hasEarningsDateSuffix = false,\r\n options: ObjectHash = {\r\n month: 'short',\r\n }\r\n) {\r\n const parsedDate = utils.dateFromUnixTimestamp(exdate)\r\n\r\n const hours = parsedDate.getHours()\r\n const formattedDate = formatDateToStringUS(parsedDate, options)\r\n\r\n if (hasEarningsDateSuffix) {\r\n let suffix = ''\r\n\r\n if (hours <= 9) {\r\n suffix = 'BMO'\r\n } else if (hours >= 16) {\r\n suffix = 'AMC'\r\n }\r\n\r\n return `${formattedDate} ${suffix}`\r\n }\r\n\r\n return formattedDate\r\n}\r\n\r\nexport function getFormattedValue({\r\n value,\r\n bigNumberUnit,\r\n maxDecimalPlaces = 3,\r\n}: {\r\n value: number\r\n bigNumberUnit?: BigNumber\r\n maxDecimalPlaces?: number\r\n}) {\r\n let numberString = ''\r\n let suffix = ''\r\n\r\n if (bigNumberUnit === undefined) {\r\n numberString = math.round({ value, overridePlaces: 3 })\r\n } else {\r\n const bigNumber = math.formatBigNumber(value * BIG_NUMBER_VALUES[bigNumberUnit], 3, BigNumber.Million)\r\n numberString = parseFloat(bigNumber.substring(0, bigNumber.length - 1)).toString() // parseFloat with toString are removing trailing zeroes\r\n suffix = bigNumber.substring(bigNumber.length - 1)\r\n }\r\n\r\n const [wholeNumber, decimalNumber] = numberString.split('.')\r\n\r\n if (decimalNumber === undefined) return `${wholeNumber}${suffix}`\r\n\r\n let formattedDecimalNumber = decimalNumber\r\n if (maxDecimalPlaces === 2 || decimalNumber[decimalNumber.length - 1] === '0') {\r\n formattedDecimalNumber = decimalNumber.slice(0, -1)\r\n }\r\n\r\n return `${[wholeNumber, formattedDecimalNumber].join('.')}${suffix}`\r\n}\r\n\r\nexport function getChartEventBageColors(colorKey: 'violet' | 'blue' | 'red' | 'gray' | 'purple' | 'green') {\r\n return {\r\n light: {\r\n outerStroke: twColors.white,\r\n innerStroke: twColors[colorKey][400],\r\n innerFill: {\r\n default: twColors[colorKey][50],\r\n hover: twColors[colorKey][100],\r\n selected: twColors[colorKey][400],\r\n },\r\n textFill: {\r\n default: twColors[colorKey][500],\r\n hover: twColors[colorKey][600],\r\n selected: twColors.white,\r\n },\r\n },\r\n dark: {\r\n outerStroke: twColors.gray[900],\r\n innerStroke: twColors[colorKey][400],\r\n innerFill: {\r\n default: twColors[colorKey][800],\r\n hover: twColors[colorKey][600],\r\n selected: twColors[colorKey][400],\r\n },\r\n textFill: {\r\n default: twColors.white,\r\n hover: twColors.white,\r\n selected: twColors.white,\r\n },\r\n },\r\n } as IBadgeColors\r\n}\r\n","import * as dateFns from 'date-fns'\r\n\r\nimport { ChartConfigChartPane, Instrument, ObjectHash } from '../../types/shared'\r\nimport Line from '../canvas/line'\r\nimport Text from '../canvas/text'\r\nimport { chartsByType } from '../charts/charts'\r\nimport {\r\n CRYPTOS,\r\n ChartEditorEnum,\r\n ChartElementType,\r\n OFFSET,\r\n PADDING,\r\n ScaleType,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n TIMEFRAME_SECONDS,\r\n TextBaseline,\r\n} from '../constants/common'\r\nimport { getPercentageFromValue } from '../controllers/renderUtils'\r\nimport math from '../helpers/math'\r\nimport ChartLayoutModel from '../models/chart_layout'\r\nimport { IChartSettings } from '../models/chart_settings/interfaces'\r\nimport { Mouse } from '../models/mouse'\r\nimport Pane from '../models/pane'\r\nimport Quote, { QuoteGetParams } from '../models/quote'\r\nimport { getChartLayoutSettings } from '../models/settings'\r\nimport Utils, { dateFromUnixTimestamp } from '../utils'\r\nimport { captureException } from './helpers'\r\n\r\nconst DAY_IN_SECONDS = 86400\r\nconst TWO_MIN_IN_MS = 2 * 60 * 1000\r\nconst virtualDatesCache: ObjectHash<{\r\n fromSeconds: number\r\n toSeconds: number\r\n lastUsed: number\r\n virtualDates: number[]\r\n}> = {}\r\n\r\n// The reason to use this func instead of dateFns.isSameDay is performance as this is way faster\r\nfunction areTimestampsFromSameDay({ ts1, ts2 }: { ts1: number; ts2: number }) {\r\n const ts1Utc = ts1\r\n const ts2Utc = ts2\r\n return Math.floor(ts1Utc / DAY_IN_SECONDS) === Math.floor(ts2Utc / DAY_IN_SECONDS)\r\n}\r\n\r\nfunction getVirtualDatesCacheId({\r\n idRevision,\r\n ticker,\r\n timeframe,\r\n}: {\r\n idRevision: number\r\n ticker: string\r\n timeframe: string\r\n}) {\r\n return `${ticker}-${timeframe}-${idRevision}`\r\n}\r\n\r\nfunction getCachedVirtualDates({\r\n idRevision,\r\n ticker,\r\n timeframe,\r\n fromSeconds,\r\n toSeconds,\r\n}: {\r\n idRevision: number\r\n ticker: string\r\n timeframe: string\r\n fromSeconds: number\r\n toSeconds: number\r\n}) {\r\n const id = getVirtualDatesCacheId({ idRevision, ticker, timeframe })\r\n const cache = virtualDatesCache[id]\r\n if (cache?.fromSeconds <= fromSeconds && cache?.toSeconds >= toSeconds) {\r\n cache.lastUsed = Date.now()\r\n if (cache.fromSeconds === fromSeconds && cache.toSeconds === toSeconds) {\r\n return cache.virtualDates\r\n }\r\n return cache.virtualDates.filter(\r\n (virtualDateSeconds) => virtualDateSeconds >= fromSeconds && virtualDateSeconds <= toSeconds\r\n )\r\n }\r\n return null\r\n}\r\n\r\nfunction checkVirtualCacheSize() {\r\n const now = Date.now()\r\n Object.keys(virtualDatesCache).forEach((virtualDatesCacheId) => {\r\n if (virtualDatesCache[virtualDatesCacheId].lastUsed < now - TWO_MIN_IN_MS) {\r\n delete virtualDatesCache[virtualDatesCacheId]\r\n }\r\n })\r\n}\r\n\r\nfunction setCachedVirtualDates({\r\n idRevision,\r\n ticker,\r\n timeframe,\r\n fromSeconds,\r\n toSeconds,\r\n virtualDates,\r\n}: {\r\n idRevision: number\r\n ticker: string\r\n timeframe: string\r\n fromSeconds: number\r\n toSeconds: number\r\n virtualDates: number[]\r\n}) {\r\n const id = getVirtualDatesCacheId({ idRevision, ticker, timeframe })\r\n checkVirtualCacheSize()\r\n virtualDatesCache[id] = {\r\n fromSeconds,\r\n toSeconds,\r\n virtualDates,\r\n lastUsed: Date.now(),\r\n }\r\n}\r\n\r\nconst MAX_BAR_BORDER_WIDTH = 1\r\nconst MIN_BAR_MARGIN_WIDTH = 0\r\nconst MAX_BAR_MARGIN_WIDTH = 16\r\n\r\nexport function getBarWidthWithMarginByParts({\r\n zoomFactor = 1,\r\n chartLayout,\r\n}: {\r\n zoomFactor?: number\r\n chartLayout: ChartLayoutModel\r\n}) {\r\n const { ChartSettings } = chartLayout.settings\r\n const settingsCenter = ChartSettings.center\r\n const barMargin =\r\n zoomFactor > 1 && settingsCenter.barMargin === 0\r\n ? Math.min(settingsCenter.barWidth, 1 - 1 / zoomFactor)\r\n : settingsCenter.barMargin\r\n\r\n const barFillWidth = settingsCenter.barWidth * zoomFactor\r\n const barBorderWidth = Math.min(settingsCenter.border * zoomFactor, MAX_BAR_BORDER_WIDTH)\r\n const barMarginWidth = Math.max(MIN_BAR_MARGIN_WIDTH, Math.min(barMargin * zoomFactor, MAX_BAR_MARGIN_WIDTH))\r\n\r\n return {\r\n barFillWidth,\r\n barBorderWidth,\r\n barMarginWidth,\r\n }\r\n}\r\n\r\nexport function getBarWidthWithMargin({\r\n zoomFactor = 1,\r\n chartLayout,\r\n shouldRound = true,\r\n}: {\r\n zoomFactor?: number\r\n chartLayout: ChartLayoutModel\r\n shouldRound?: boolean\r\n}) {\r\n const { barFillWidth, barBorderWidth, barMarginWidth } = getBarWidthWithMarginByParts({ zoomFactor, chartLayout })\r\n\r\n const barWidth = barFillWidth + barBorderWidth * 2 + barMarginWidth\r\n if (!shouldRound) {\r\n return barWidth\r\n }\r\n const roundDecimalPlaces = barWidth > 100 ? 10 : 10000\r\n return Math.round(barWidth * roundDecimalPlaces) / roundDecimalPlaces\r\n}\r\n\r\nconst DEFAULT_ZOOM_GUESS_INCREMENT = 0.001\r\n\r\nconst zoomFactorForBarsToDisplayCache: ObjectHash = {}\r\nconst zoomFactorForBarsToDisplayCacheKeys: string[] = []\r\nconst NUMBER_OF_CACHED_ZOOM_FACTORS = 10\r\nconst getZoomFactorFromCache = (key: string) => zoomFactorForBarsToDisplayCache[key] ?? null\r\nconst setZoomFactorToCache = (key: string, value: number) => {\r\n if (!zoomFactorForBarsToDisplayCacheKeys.includes(key)) {\r\n zoomFactorForBarsToDisplayCacheKeys.unshift(key)\r\n if (zoomFactorForBarsToDisplayCacheKeys.length > NUMBER_OF_CACHED_ZOOM_FACTORS) {\r\n const poppedKey = zoomFactorForBarsToDisplayCacheKeys.pop()\r\n if (poppedKey) {\r\n delete zoomFactorForBarsToDisplayCache[poppedKey]\r\n }\r\n }\r\n }\r\n\r\n zoomFactorForBarsToDisplayCache[key] = value\r\n}\r\n\r\nexport function getZoomFactorForBarsToDisplay({\r\n chartVisibleWidth,\r\n numOfVisibleBars,\r\n chartLayout,\r\n}: {\r\n chartVisibleWidth: number\r\n numOfVisibleBars: number\r\n chartLayout: ChartLayoutModel\r\n}) {\r\n const defaultBarWidthWithMargin = getBarWidthWithMargin({ chartLayout })\r\n const barWidthWithMargin = chartVisibleWidth / numOfVisibleBars\r\n const cacheKey = `${defaultBarWidthWithMargin}-${barWidthWithMargin}`\r\n let zoomIncrement = 0\r\n let currentZoomFactor = 1\r\n let finalZoomFactor = getZoomFactorFromCache(cacheKey)\r\n let iteration = 0\r\n if (barWidthWithMargin <= defaultBarWidthWithMargin) {\r\n finalZoomFactor = barWidthWithMargin / defaultBarWidthWithMargin\r\n }\r\n while (finalZoomFactor === null) {\r\n iteration += 1\r\n const threshold = 0.01\r\n currentZoomFactor += zoomIncrement\r\n const barWidth = getBarWidthWithMargin({ zoomFactor: currentZoomFactor, chartLayout, shouldRound: false })\r\n const barWidthDiff = barWidthWithMargin - barWidth\r\n if (barWidthDiff > threshold) {\r\n zoomIncrement = zoomIncrement > 0 ? zoomIncrement * 2 : DEFAULT_ZOOM_GUESS_INCREMENT\r\n } else if (barWidthDiff < -threshold) {\r\n zoomIncrement = zoomIncrement < 0 ? zoomIncrement * 2 : -DEFAULT_ZOOM_GUESS_INCREMENT\r\n } else {\r\n finalZoomFactor = currentZoomFactor\r\n }\r\n\r\n if (iteration === 1000) {\r\n captureException(new Error('Invalid zoom factor from getZoomFactorForBarsToDisplay'), {\r\n extra: {\r\n iteration,\r\n zoomIncrement,\r\n barWidthWithMargin,\r\n barWidth,\r\n barWidthDiff,\r\n currentZoomFactor,\r\n chartLayout: chartLayout.toConfig(['colors', 'panes']),\r\n },\r\n })\r\n return currentZoomFactor\r\n }\r\n }\r\n\r\n setZoomFactorToCache(cacheKey, finalZoomFactor)\r\n\r\n return finalZoomFactor\r\n}\r\n\r\nexport function getTimeframeSeconds({\r\n lowerIndex,\r\n dates,\r\n timeframe,\r\n}: {\r\n lowerIndex: number\r\n dates: number[]\r\n timeframe: TIMEFRAME\r\n}) {\r\n const upperIndex = lowerIndex + 1\r\n const areBoundsDefined = ![dates[upperIndex], dates[lowerIndex]].some((index) => index === undefined)\r\n return areBoundsDefined ? dates[upperIndex] - dates[lowerIndex] : TIMEFRAME_SECONDS[timeframe]\r\n}\r\n\r\nfunction getVirtualTradedDays({\r\n dateStartSeconds,\r\n dateEndSeconds,\r\n datesSeconds,\r\n marketStartMinutes,\r\n}: {\r\n dateStartSeconds: number\r\n dateEndSeconds: number\r\n datesSeconds: number[]\r\n marketStartMinutes: number\r\n}) {\r\n const dateStart = dateFromUnixTimestamp(dateStartSeconds)\r\n const dateEnd = dateFromUnixTimestamp(dateEndSeconds)\r\n const isStartBeforeDates = dateStartSeconds < datesSeconds[0]\r\n const isEndAfterDates = datesSeconds.length > 0 && datesSeconds[datesSeconds.length - 1] < dateEndSeconds\r\n const firstDate = dateFromUnixTimestamp(datesSeconds[0])\r\n const lastDate = dateFromUnixTimestamp(datesSeconds[datesSeconds.length - 1])\r\n return dateFns\r\n .eachDayOfInterval({\r\n start:\r\n isStartBeforeDates && (dateFns.isWeekend(dateStart) || dateStart.getMinutes() < marketStartMinutes)\r\n ? dateFns.addBusinessDays(dateStart, -1)\r\n : dateStart,\r\n end: isEndAfterDates ? dateFns.addBusinessDays(dateEnd, 1) : dateEnd,\r\n })\r\n .filter((date) => {\r\n const ts2 = date.getTime() / 1000 - date.getTimezoneOffset() * 60\r\n return (\r\n !dateFns.isWithinInterval(date, { start: dateFns.startOfDay(firstDate), end: dateFns.endOfDay(lastDate) }) ||\r\n datesSeconds.some((dateTime) =>\r\n areTimestampsFromSameDay({\r\n ts1: dateTime - Utils.getQuoteDateTimestampOffsetInSeconds(new Date(dateTime * 1000)),\r\n ts2,\r\n })\r\n )\r\n )\r\n })\r\n}\r\n\r\nexport function getVirtualTimeframeTradedDates({\r\n dateStart,\r\n dateEnd,\r\n quote,\r\n}: {\r\n dateStart: number\r\n dateEnd: number\r\n quote: Quote\r\n}) {\r\n const { date: dates, ticker, timeframe, instrument, isIntraday, marketStartMinutes } = quote\r\n const barsInDay = quote.getBarsInDay() ?? 0\r\n\r\n // Currently we're passing first and last quote dates to dateStart / dateEnd so this is always true\r\n // but this function can be used on other places in the future where it will work with dates out of quote dates range\r\n const isWithinRangeOfQuoteDate = dateStart === dates[0] && dateEnd === dates[dates.length - 1]\r\n\r\n const commonVirtualCacheProps = {\r\n idRevision: dates.length,\r\n ticker,\r\n timeframe,\r\n fromSeconds: dateStart,\r\n toSeconds: dateEnd,\r\n }\r\n const cachedDates = getCachedVirtualDates(commonVirtualCacheProps)\r\n if (cachedDates) {\r\n return cachedDates\r\n }\r\n if (!isIntraday || instrument !== Instrument.Stock) {\r\n if (isWithinRangeOfQuoteDate) {\r\n return dates\r\n }\r\n const timeframeSeconds = TIMEFRAME_SECONDS[timeframe]\r\n const firstDate = dates[0]\r\n const lastDate = dates[dates.length - 1]\r\n const numOfDatesBefore = Math.ceil((firstDate - dateStart) / timeframeSeconds)\r\n const numOfDatesAfter = Math.ceil((dateEnd - lastDate) / timeframeSeconds)\r\n return [\r\n ...Array.from({ length: numOfDatesBefore })\r\n .map((_, index) => firstDate - (index + 1) * timeframeSeconds)\r\n .reverse(),\r\n ...dates,\r\n ...Array.from({ length: numOfDatesAfter }).map((_, index) => lastDate + (index + 1) * timeframeSeconds),\r\n ]\r\n }\r\n\r\n const virtualTradedDays = isWithinRangeOfQuoteDate\r\n ? quote.getDaysInQuote()\r\n : getVirtualTradedDays({\r\n dateStartSeconds: dateStart,\r\n dateEndSeconds: dateEnd,\r\n datesSeconds: dates,\r\n marketStartMinutes,\r\n })\r\n\r\n const marketStartSeconds = marketStartMinutes * 60\r\n const barTimeframeSeconds = Array.from({ length: barsInDay }).map((_, i) => i * TIMEFRAME_SECONDS[timeframe])\r\n const quoteDatesTimestampOffset = Utils.getQuoteDateTimestampOffsetInSeconds(new Date(dateStart * 1000))\r\n const virtualDates = virtualTradedDays.flatMap((date) => {\r\n const daySeconds =\r\n date.getTime() / 1000 + Utils.getQuoteDateTimestampOffsetInSeconds(date) - date.getTimezoneOffset() * 60\r\n const dayStartSeconds = daySeconds + marketStartSeconds\r\n return barTimeframeSeconds.map(\r\n // Hourly market starts at 9:30 but all other time ticks should be rounded down to :00 of the current hour\r\n (barSeconds, index) =>\r\n ([TIMEFRAME.h, TIMEFRAME.h2, TIMEFRAME.h4].includes(timeframe) && index > 0 ? -1800 : 0) +\r\n dayStartSeconds +\r\n barSeconds\r\n )\r\n })\r\n\r\n if (!isWithinRangeOfQuoteDate) {\r\n virtualDates.filter((date, index, virtualTimeframeTradedDates) => {\r\n const isLowerBounded =\r\n date >= dateStart ||\r\n areTimestampsFromSameDay({\r\n ts1: date - Utils.getQuoteDateTimestampOffsetInSeconds(new Date(date * 1000)),\r\n ts2: dateStart - quoteDatesTimestampOffset,\r\n })\r\n const isOneBeforeLowerBoundStarts = dateStart > date && dateStart < virtualTimeframeTradedDates[index + 1]\r\n return isLowerBounded || isOneBeforeLowerBoundStarts\r\n })\r\n }\r\n\r\n setCachedVirtualDates({\r\n ...commonVirtualCacheProps,\r\n virtualDates,\r\n })\r\n\r\n return virtualDates\r\n}\r\n\r\ninterface TimestampPositionGettersProps {\r\n quote: Quote\r\n}\r\n\r\nexport function getTimestampFromPositionX({ positionX, quote }: TimestampPositionGettersProps & { positionX: number }) {\r\n const { date, timeframe } = quote\r\n const dates = getVirtualTimeframeTradedDates({\r\n dateStart: date[0],\r\n dateEnd: date[date.length - 1],\r\n quote,\r\n })\r\n const dateStart = dates[0]\r\n const dateEnd = dates[dates.length - 1]\r\n const lastDateIndex = dates.length - 1\r\n if (positionX >= 0 && positionX <= lastDateIndex) {\r\n const lowerIndex = Math.floor(positionX)\r\n const timeframeSeconds = getTimeframeSeconds({ lowerIndex, dates, timeframe })\r\n return dates[lowerIndex] + (positionX - lowerIndex) * timeframeSeconds\r\n }\r\n const isLookingBack = positionX < 0\r\n const averageBarDate = (dateEnd - dateStart) / dates.length\r\n const numOfSecondsOutOfBounds = isLookingBack\r\n ? Math.abs(positionX) * averageBarDate\r\n : (positionX - lastDateIndex) * averageBarDate\r\n return Math.round(isLookingBack ? dateStart - numOfSecondsOutOfBounds : dateEnd + numOfSecondsOutOfBounds)\r\n}\r\n\r\nexport function getPositionXFromTimestamp({ timestamp, quote }: TimestampPositionGettersProps & { timestamp: number }) {\r\n const { date, timeframe } = quote\r\n const dates = getVirtualTimeframeTradedDates({\r\n dateStart: date[0],\r\n dateEnd: date[date.length - 1],\r\n quote,\r\n })\r\n const dateStart = dates[0]\r\n const dateEnd = dates[dates.length - 1]\r\n const lastDateIndex = dates.length - 1\r\n if (timestamp >= dates[0] && timestamp <= dates[dates.length - 1]) {\r\n const upperIndex = timestamp === dateEnd ? lastDateIndex : dates.findIndex((date) => date > timestamp)\r\n const timeframeSeconds = getTimeframeSeconds({ lowerIndex: upperIndex - 1, dates, timeframe })\r\n const positionDiffUpperTimestamp = (dates[upperIndex] - timestamp) / timeframeSeconds\r\n return upperIndex - positionDiffUpperTimestamp\r\n }\r\n const isLookingBack = timestamp < dateStart\r\n const averageBarDate = (dateEnd - dateStart) / dates.length\r\n return isLookingBack\r\n ? -((dateStart - timestamp) / averageBarDate)\r\n : lastDateIndex + (timestamp - dateEnd) / averageBarDate\r\n}\r\n\r\n// counterpart in Finviz-Website 'Finviz-Website/js/main/util.ts'\r\nexport function getInstrument(tickerRaw: string) {\r\n if (tickerRaw.indexOf('@') === 0) {\r\n const ticker = tickerRaw.substring(1) as keyof typeof CRYPTOS\r\n\r\n if (CRYPTOS[ticker]) {\r\n return Instrument.Crypto\r\n } else if (ticker.length === 6) {\r\n return Instrument.Forex\r\n } else {\r\n return Instrument.Futures\r\n }\r\n }\r\n return Instrument.Stock\r\n}\r\n\r\nexport function getPerfIndicatorTickerAndTimeframes({\r\n paneWithPerfIndicator,\r\n timeframe,\r\n}: {\r\n paneWithPerfIndicator: ChartConfigChartPane\r\n timeframe: TIMEFRAME\r\n}) {\r\n const { elements } = paneWithPerfIndicator\r\n const perfIndicatorElement = elements.find(({ type }) => type === 'indicators/perf')\r\n const tickers = perfIndicatorElement?.period?.split(',') ?? []\r\n return tickers.map((ticker) => ({\r\n ticker,\r\n instrument: getInstrument(ticker),\r\n timeframe,\r\n }))\r\n}\r\n\r\ninterface PrefetchPerfIndicatorAllQuotesProps extends Pick {\r\n paneWithPerfIndicator: ChartConfigChartPane\r\n chartUuid?: string\r\n}\r\n\r\nexport async function prefetchPerfIndicatorAllQuotes({\r\n paneWithPerfIndicator,\r\n timeframe,\r\n options,\r\n chartUuid,\r\n}: PrefetchPerfIndicatorAllQuotesProps) {\r\n const tickersAndTimeframes = getPerfIndicatorTickerAndTimeframes({ paneWithPerfIndicator, timeframe })\r\n\r\n if (tickersAndTimeframes.length > 0) {\r\n const promises = tickersAndTimeframes.map(({ ticker, instrument, timeframe }) =>\r\n Quote.get({\r\n ticker,\r\n instrument,\r\n timeframe,\r\n options,\r\n chartUuid,\r\n })\r\n )\r\n return Promise.all(promises)\r\n }\r\n return Promise.resolve([])\r\n}\r\n\r\ninterface RenderCrossProps {\r\n context: CanvasRenderingContext2D\r\n mouseModel: Mouse\r\n paneModel: Pane\r\n quote: Quote\r\n contentWidth: number\r\n contentHeight: number\r\n onRenderCrossText?: (context: CanvasRenderingContext2D, crossIndex: number) => void\r\n getRoundDecimalPlaces?: (price?: number) => number | undefined\r\n isIndicator?: boolean\r\n isPerfIndicator?: boolean\r\n}\r\n\r\nexport function renderCross({\r\n context,\r\n mouseModel,\r\n paneModel,\r\n quote,\r\n contentWidth,\r\n contentHeight,\r\n onRenderCrossText,\r\n getRoundDecimalPlaces,\r\n isIndicator = false,\r\n isPerfIndicator = false,\r\n}: RenderCrossProps) {\r\n const crossIndex = mouseModel.getCrossIndexForPane(paneModel)\r\n const chartModel = paneModel.chart()\r\n const { ChartSettings, IndicatorSettings } = getChartLayoutSettings(chartModel.chart_layout())\r\n const settings = isIndicator ? IndicatorSettings : ChartSettings\r\n const { Colors } = ChartSettings.general\r\n\r\n if (!mouseModel.getShouldRenderCrossInPane(paneModel)) {\r\n return false\r\n }\r\n\r\n const price = mouseModel.getPriceForPane(paneModel)\r\n const middle = paneModel.scale.x(crossIndex) + chartModel.leftOffset\r\n const isXAxisInView = middle > 0 && middle <= contentWidth\r\n if (isXAxisInView) {\r\n const x = middle + settings.left.width\r\n new Line(\r\n {\r\n x1: x,\r\n x2: x,\r\n y1: settings.top.height,\r\n y2: settings.top.height + contentHeight,\r\n strokeStyle: Colors.cross,\r\n },\r\n paneModel\r\n ).render(context)\r\n\r\n onRenderCrossText?.(context, crossIndex)\r\n }\r\n\r\n const domainRange = paneModel.scale.y\r\n .domain()\r\n .slice()\r\n .sort((a, b) => a - b)\r\n\r\n if (price === null || !(domainRange[0] <= price && price <= domainRange[1])) {\r\n return isXAxisInView\r\n }\r\n\r\n const priceFy = paneModel.scale.y(price)\r\n const y = Math.round(priceFy + settings.top.height)\r\n new Line(\r\n {\r\n x1: settings.left.width,\r\n x2: settings.left.width + contentWidth,\r\n y1: y,\r\n y2: y,\r\n strokeStyle: Colors.cross,\r\n },\r\n paneModel\r\n ).render(context)\r\n const YAxisLeftMargin = quote.instrument === Instrument.Crypto && quote.lastClose <= 0.001 ? 3 : 8\r\n\r\n const getCrossText = () => {\r\n if (chartModel.scale === ScaleType.Percentage && !isIndicator) {\r\n return `${math.round({\r\n value: getPercentageFromValue({ number: price, base: chartModel.firstBarClose }),\r\n lastClose: quote.lastClose,\r\n instrument: quote.instrument,\r\n overridePlaces: 2,\r\n })}%`\r\n }\r\n return `${math.round({\r\n value: price,\r\n lastClose: quote.lastClose,\r\n instrument: quote.instrument,\r\n overridePlaces: getRoundDecimalPlaces?.(price) ?? (paneModel.getIsChartPane() ? undefined : 2),\r\n })}${isPerfIndicator ? '%' : ''}`\r\n }\r\n\r\n new Text(\r\n {\r\n text: getCrossText(),\r\n x:\r\n settings.left.width +\r\n settings.right.axis.margin.left! +\r\n contentWidth +\r\n (isIndicator ? OFFSET.S : YAxisLeftMargin - PADDING.XXS),\r\n padding: isIndicator\r\n ? Text.getMergedPropsWithDefaults('padding', IndicatorSettings.right.axis.font.padding)\r\n : {\r\n top: PADDING.XXS,\r\n right: PADDING.XXS,\r\n bottom: PADDING.XXS,\r\n left: PADDING.XXS,\r\n },\r\n ...{\r\n y,\r\n textBaseline: TextBaseline.middle,\r\n fillStyle: Colors.crossText,\r\n background: Colors.crossTextBackground,\r\n font: Text.getMergedPropsWithDefaults('font', { ...settings.right.axis.font, style: 'bold' }),\r\n lineHeight: settings.right.axis.font.lineHeight,\r\n },\r\n },\r\n paneModel\r\n ).render(context)\r\n\r\n return true\r\n}\r\n\r\n/**\r\n * Set canvas width and height to 0 which fixes Safari memory problems\r\n *\r\n * @see https://stackoverflow.com/questions/52532614/total-canvas-memory-use-exceeds-the-maximum-limit-safari-12\r\n */\r\nexport function unmountCanvas(canvas?: HTMLCanvasElement | null) {\r\n if (!canvas) return\r\n\r\n canvas.width = 0\r\n canvas.height = 0\r\n canvas.style.width = '0px'\r\n canvas.style.height = '0px'\r\n}\r\n\r\nexport function getChangeColor({ change, ChartSettings }: { change: number; ChartSettings: IChartSettings }) {\r\n const { Colors } = ChartSettings.general\r\n if (change === 0) {\r\n return Colors.zeroChange\r\n }\r\n return change > 0 ? Colors.positiveChange : Colors.negativeChange\r\n}\r\n\r\nexport function round({ data, num, overridePlaces }: { data: Quote; num: number; overridePlaces?: number }) {\r\n return math.round({\r\n value: num,\r\n lastClose: data.lastClose,\r\n instrument: data.instrument,\r\n overridePlaces: overridePlaces,\r\n })\r\n}\r\n\r\nexport interface ITickerChange {\r\n points: number\r\n string: string\r\n percentString: string\r\n}\r\ninterface ITickerChangeResult {\r\n tickerChange: ITickerChange | null\r\n tickerAfterChange: ITickerChange | null\r\n}\r\n\r\nexport function getTickerChangeFromCloseValues({\r\n anchorClose,\r\n prevClose,\r\n data,\r\n}: {\r\n anchorClose: number\r\n prevClose: number\r\n data: Quote\r\n}): ITickerChange {\r\n const changePoints = anchorClose - prevClose\r\n const changePercent = (anchorClose / prevClose - 1) * 100\r\n const sign = changePoints < 0 ? '-' : changePoints > 0 ? '+' : ''\r\n const changePercentString = `${round({\r\n data,\r\n num: Math.abs(changePercent),\r\n overridePlaces: 2,\r\n })}%`\r\n const changePointsString = `${sign}${round({\r\n data,\r\n num: Math.abs(changePoints),\r\n })} (${changePercentString})`\r\n\r\n return {\r\n points: changePoints,\r\n string: changePointsString,\r\n percentString: `${sign}${changePercentString}`,\r\n }\r\n}\r\nexport function getTickerChange({ data }: { data: Quote }) {\r\n const result: ITickerChangeResult = { tickerChange: null, tickerAfterChange: null }\r\n const isChange = Number.isFinite(data.prevClose) // if not new stock always present\r\n if (isChange) {\r\n result.tickerChange = getTickerChangeFromCloseValues({\r\n data,\r\n anchorClose: data.lastClose,\r\n prevClose: data.prevClose,\r\n })\r\n }\r\n\r\n const isAfterChange = Number.isFinite(data.afterClose) && data.afterClose !== data.lastClose\r\n if (isAfterChange) {\r\n const tickerAfterChange = getTickerChangeFromCloseValues({\r\n data,\r\n anchorClose: data.afterClose,\r\n prevClose: data.lastClose,\r\n })\r\n result.tickerAfterChange = {\r\n ...tickerAfterChange,\r\n string: `AH: ${tickerAfterChange.string}`,\r\n }\r\n }\r\n\r\n return result\r\n}\r\n\r\nexport function isForexFuturesCryptoPage(specificChartFunctionality: SpecificChartFunctionality) {\r\n return [\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n SpecificChartFunctionality.futuresPage,\r\n ].includes(specificChartFunctionality)\r\n}\r\n\r\nexport function getShouldUseDarkerWickColors({\r\n specificChartFunctionality,\r\n totalBarWidth,\r\n}: {\r\n specificChartFunctionality: SpecificChartFunctionality\r\n timeFrame?: TIMEFRAME\r\n totalBarWidth: number\r\n}) {\r\n const isForexFuturesCrypto = isForexFuturesCryptoPage(specificChartFunctionality)\r\n const isOffscreenChartWithNarrowBars =\r\n specificChartFunctionality === SpecificChartFunctionality.offScreen && totalBarWidth < 5\r\n const isQuoteChartWithNarrowBars =\r\n specificChartFunctionality === SpecificChartFunctionality.quotePage && totalBarWidth < 5\r\n\r\n return isForexFuturesCrypto || isOffscreenChartWithNarrowBars || isQuoteChartWithNarrowBars\r\n}\r\n\r\nexport const DRAWING_COOKIE_NAME = 'charts-draw'\r\nexport function getIsDrawingEnabled() {\r\n return Utils.getCookie(DRAWING_COOKIE_NAME) === 'on'\r\n}\r\n\r\nexport function setIsDrawingEnabled(value: boolean) {\r\n const expires = new Date()\r\n expires.setMonth(expires.getMonth() + 1)\r\n Utils.setCookie(DRAWING_COOKIE_NAME, value ? 'on' : 'off', expires)\r\n}\r\n\r\nexport function getIsSidebarEnabled(specificChartFunctionality?: SpecificChartFunctionality) {\r\n return specificChartFunctionality === SpecificChartFunctionality.chartPage\r\n}\r\n\r\nexport const handleTypeChange = ({\r\n type,\r\n chartLayoutModel,\r\n}: {\r\n type: ChartElementType\r\n chartLayoutModel: ChartLayoutModel\r\n}) => {\r\n const elements = chartLayoutModel.getAllElements()\r\n elements.forEach((element) => {\r\n if (element.isChart() && element.instance.attrs.type !== type) {\r\n const pane = element.pane()\r\n const instance = chartsByType[type].fromObject(\r\n {\r\n ...element.instance.attrs,\r\n type,\r\n },\r\n pane\r\n )\r\n element.replace(instance)\r\n }\r\n })\r\n}\r\n\r\nexport const getIsPreserveDrawingsAndAutosaveAvailable = (args: {\r\n specificChartFunctionality: SpecificChartFunctionality\r\n editable: boolean\r\n editors: ChartEditorEnum[]\r\n}) => {\r\n const { specificChartFunctionality, editable, editors } = args\r\n\r\n return (\r\n editable &&\r\n editors?.includes(ChartEditorEnum.tools) &&\r\n specificChartFunctionality &&\r\n [\r\n SpecificChartFunctionality.chartPage,\r\n SpecificChartFunctionality.quotePage,\r\n SpecificChartFunctionality.forexPage,\r\n SpecificChartFunctionality.futuresPage,\r\n SpecificChartFunctionality.cryptoPage,\r\n ].includes(specificChartFunctionality)\r\n )\r\n}\r\n","/**\r\n * Keep this file in sync with `Website/js/main/components/color-picker/util.ts` in website repo\r\n * */\r\n\r\nexport interface RGBA {\r\n r: number\r\n g: number\r\n b: number\r\n a: number\r\n}\r\n\r\nexport interface HSVA {\r\n h: number\r\n s: number\r\n v: number\r\n a: number\r\n}\r\n\r\nexport interface HSLA {\r\n h: number\r\n s: number\r\n l: number\r\n a: number\r\n}\r\n\r\n/**\r\n * Convert Hex string to RGBA object.\r\n * @see https://css-tricks.com/converting-color-spaces-in-javascript/\r\n *\r\n * Input: color in hex3, hex4, hex6 or hex8 format (#fff)\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hexStringToRGBA(hexString: string): RGBA {\r\n const hexColor = removeHashSymbol(hexString)\r\n let r: string | number = 0\r\n let g: string | number = 0\r\n let b: string | number = 0\r\n let a: string | number = 255\r\n\r\n // 3 digits\r\n if (hexColor.length === 3 || hexColor.length === 4) {\r\n r = '0x' + hexColor[0] + hexColor[0]\r\n g = '0x' + hexColor[1] + hexColor[1]\r\n b = '0x' + hexColor[2] + hexColor[2]\r\n // Get channel if defined\r\n a = hexColor.length === 4 ? '0x' + hexColor[3] + hexColor[3] : a\r\n\r\n // 6 digits\r\n } else if (hexColor.length === 6 || hexColor.length === 8) {\r\n r = '0x' + hexColor[0] + hexColor[1]\r\n g = '0x' + hexColor[2] + hexColor[3]\r\n b = '0x' + hexColor[4] + hexColor[5]\r\n // Get channel if defined\r\n a = hexColor.length === 8 ? '0x' + hexColor[6] + hexColor[7] : a\r\n }\r\n\r\n return { r: Number(r), g: Number(g), b: Number(b), a: Math.min(Math.round((Number(a) / 255) * 100) / 100, 1) }\r\n}\r\n\r\n/**\r\n * Convert HEX string to HSVA color representation.\r\n *\r\n * Input: color in hex3, hex4, hex6 or hex8 format (#fff)\r\n *\r\n * Output: { h: [0,360], s: [0,1], v: [0,1], a: [0,1]}\r\n */\r\nexport function hexStringToHSVA(hexString: string) {\r\n return rgbaToHSVA(hexStringToRGBA(hexString))\r\n}\r\n\r\n/**\r\n * Convert HEX string to HSLA color representation.\r\n *\r\n * Input: color in hex3, hex4, hex6 or hex8 format (#fff)\r\n *\r\n * Output: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n */\r\nexport function hexStringToHSLA(hexString: string) {\r\n return rgbaToHSLA(hexStringToRGBA(hexString))\r\n}\r\n\r\n/**\r\n * Convert alpha value to hex value\r\n *\r\n * Input: [0,1]\r\n *\r\n * Output: alpha in HEX format\r\n */\r\nexport function alphaToHex(alpha: number) {\r\n return Math.max(Math.min(Math.round(alpha * 255), 255), 0)\r\n .toString(16)\r\n .padStart(2, '0')\r\n}\r\n\r\n/**\r\n * Convert RGBA color to HEX string.\r\n *\r\n * Input: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n *\r\n * Output: color in hex6 or hex8 depending on whether or not alpha is enabled\r\n */\r\nexport function rgbaToHexString(color: RGBA, alpha = false) {\r\n const r = color.r.toString(16)\r\n const g = color.g.toString(16)\r\n const b = color.b.toString(16)\r\n const hexString = '#' + r.padStart(2, '0') + g.padStart(2, '0') + b.padStart(2, '0')\r\n\r\n if (!alpha || color.a === 1) {\r\n return hexString\r\n }\r\n\r\n return `${hexString}${alphaToHex(color.a)}`\r\n}\r\n\r\n/**\r\n * Convert HSVA object to HEX string\r\n *\r\n * @see https://css-tricks.com/converting-color-spaces-in-javascript/\r\n *\r\n * Input: { h: [0,360], s: [0,1], v: [0,1], a: [0,1]}\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hsvaToHEXString(color: HSVA, alpha = false) {\r\n const rgbaColor = hsvaToRGBA(color)\r\n\r\n return rgbaToHexString(rgbaColor, alpha)\r\n}\r\n\r\n/**\r\n * Convert HSLA object to HEX string\r\n *\r\n * @see https://css-tricks.com/converting-color-spaces-in-javascript/\r\n *\r\n * Input: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hslaToHexString(color: HSLA, alpha = false) {\r\n const rgbaColor = hslaToRGBA(color)\r\n\r\n return rgbaToHexString(rgbaColor, alpha)\r\n}\r\n\r\n/**\r\n * Convert RGBA color to HSVA\r\n * @see https://stackoverflow.com/a/54070620/6662683\r\n *\r\n * Input: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n *\r\n * Output: { h: [0,360], s: [0,1], v: [0,1], a: [0,1]}\r\n */\r\nexport function rgbaToHSVA(color: RGBA): HSVA {\r\n const r = color.r / 255\r\n const g = color.g / 255\r\n const b = color.b / 255\r\n\r\n const v = Math.max(r, g, b)\r\n const c = v - Math.min(r, g, b)\r\n const h = c && (v === r ? (g - b) / c : v === g ? 2 + (b - r) / c : 4 + (r - g) / c)\r\n\r\n return {\r\n h: 60 * (h < 0 ? h + 6 : h),\r\n s: v ? c / v : 0,\r\n v: v,\r\n a: color.a,\r\n }\r\n}\r\n\r\n/**\r\n * Convert RGBA to HSLA\r\n * @see https://stackoverflow.com/a/54071699/6662683\r\n *\r\n * Input: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n *\r\n * Output: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n */\r\nexport function rgbaToHSLA(color: RGBA): HSLA {\r\n const r = color.r / 255\r\n const g = color.g / 255\r\n const b = color.b / 255\r\n\r\n const v = Math.max(r, g, b)\r\n const c = v - Math.min(r, g, b)\r\n const f = 1 - Math.abs(v + v - c - 1)\r\n const h = c && (v === r ? (g - b) / c : v === g ? 2 + (b - r) / c : 4 + (r - g) / c)\r\n\r\n return {\r\n h: 60 * (h < 0 ? h + 6 : h),\r\n s: f ? c / f : 0,\r\n l: (v + v - c) / 2,\r\n a: color.a,\r\n }\r\n}\r\n\r\n/**\r\n * Convert HSVA color to RGBA\r\n * @see https://stackoverflow.com/a/54024653/6662683\r\n *\r\n * Input: { h: [0,360], s: [0,1], v: [0,1], a: [0,1]}\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hsvaToRGBA(color: HSVA): RGBA {\r\n const f = (n: number, k = (n + color.h / 60) % 6) => color.v - color.v * color.s * Math.max(Math.min(k, 4 - k, 1), 0)\r\n\r\n return {\r\n r: Math.round(f(5) * 255),\r\n g: Math.round(f(3) * 255),\r\n b: Math.round(f(1) * 255),\r\n a: Math.round(color.a * 100) / 100,\r\n }\r\n}\r\n\r\n/**\r\n * Convert HSLA color to RGBA\r\n * @see https://stackoverflow.com/a/54014428/6662683\r\n *\r\n * Input: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function hslaToRGBA(color: HSLA): RGBA {\r\n const a = color.s * Math.min(color.l, 1 - color.l)\r\n const f = (n: number, k = (n + color.h / 30) % 12) => color.l - a * Math.max(Math.min(k - 3, 9 - k, 1), -1)\r\n\r\n return {\r\n r: Math.round(f(0) * 255),\r\n g: Math.round(f(8) * 255),\r\n b: Math.round(f(4) * 255),\r\n a: color.a,\r\n }\r\n}\r\n\r\n/**\r\n * Convert RGBA color to rgba() string\r\n *\r\n * Input: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n *\r\n * Output: rgba(r, g, b, a)\r\n */\r\nexport function rgbaToRGBAString(color: RGBA) {\r\n return `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a})`\r\n}\r\n\r\n/**\r\n * Convert rgba() string to RGBA color\r\n *\r\n * Input: rgba(r, g, b, a)\r\n *\r\n * Output: { r: [0,255], g: [0,255], b: [0,255], a: [0,1]}\r\n */\r\nexport function rgbaStringToObject(color: string) {\r\n const colorParts = /^rgba?\\(([0-9]{1,3})[ ,]+([0-9]{1,3})[ ,]+([0-9]{1,3})[ ,]*([01].?[0-9]*)?\\)$/.exec(color)\r\n const [red, green, blue, alpha = '1'] = colorParts?.slice(1) || [0, 0, 0, 1].map(String)\r\n return {\r\n r: Number.parseInt(red),\r\n g: Number.parseInt(green),\r\n b: Number.parseInt(blue),\r\n a: Number.parseFloat(alpha),\r\n }\r\n}\r\n\r\n/**\r\n * Convert HSLA color to hsla() string\r\n *\r\n * Input: { h: [0,360], s: [0,1], l: [0,1], a: [0,1]}\r\n *\r\n * Output: hsla(h, s, l, a)\r\n */\r\nexport function hslaToHSLAString(color: HSLA) {\r\n return `hsla(${Math.round(color.h)}, ${Math.round(color.s * 10000) / 100}%, ${Math.round(color.l * 10000) / 100}%, ${\r\n color.a\r\n })`\r\n}\r\n\r\nexport function removeHashSymbol(strColor: string) {\r\n return strColor.replace(/#/g, '')\r\n}\r\n\r\n/**\r\n * Check if the param is a valid color by setting it as style\r\n */\r\nexport function isValidColor(strColor: string) {\r\n const isRgb = strColor.startsWith('rgba')\r\n const s = new Option().style\r\n\r\n s.color = isRgb ? strColor : `#${removeHashSymbol(strColor)}`\r\n\r\n return s.color !== ''\r\n}\r\n\r\n/**\r\n * Normalize color to be a hex value\r\n */\r\nexport function convertColorToHEX(strColor: string, allowAlpha = true) {\r\n const isRgb = getIsRgb(strColor)\r\n const hexColor = isRgb ? rgbaToHexString(rgbaStringToObject(strColor), allowAlpha) : strColor\r\n\r\n if (allowAlpha) {\r\n return hexColor\r\n }\r\n return hexColor.slice(0, 7)\r\n}\r\n\r\n/**\r\n * Returns true if color is rgb or rgba\r\n */\r\nexport function getIsRgb(strColor: string, isAlphaAllowed = true) {\r\n const rgbKeys = ['rgb']\r\n if (isAlphaAllowed) {\r\n rgbKeys.push('rgba')\r\n }\r\n return rgbKeys.some((startsWith) => strColor.startsWith(startsWith))\r\n}\r\n\r\n/**\r\n * Convert any color format to HSVA (internal color picker representation)\r\n */\r\nexport function getHSVAFromColor(strColor: string) {\r\n if (getIsRgb(strColor)) {\r\n return rgbaToHSVA(rgbaStringToObject(strColor))\r\n }\r\n\r\n return hexStringToHSVA(strColor)\r\n}\r\n\r\n/**\r\n * Stringify HSVA color representation into a output format\r\n */\r\nexport function stringifyHSVAColor(color: HSVA, output: 'rgba' | 'hex', canSelectAlpha?: boolean) {\r\n switch (output) {\r\n case 'rgba':\r\n return rgbaToRGBAString(hsvaToRGBA(color))\r\n default:\r\n return hsvaToHEXString(color, canSelectAlpha)\r\n }\r\n}\r\n\r\n/**\r\n * Get luma value from RGBA color using the Rec. 709 coefficients\r\n * @see https://en.wikipedia.org/wiki/Luma_%28video%29\r\n *\r\n * If luma is >= 165 the foreground color should be dark\r\n */\r\nexport function getLumaFromRGBA(color: RGBA) {\r\n return 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b\r\n}\r\n\r\n/**\r\n * Checks if luma is >= 165 or alpha < 0.3\r\n */\r\nexport function getIsColorTooLightOrTransparent(color: RGBA) {\r\n return getLumaFromRGBA(color) >= 165 || color.a < 0.5\r\n}\r\n\r\n/**\r\n * Set specific alpha for a hex color\r\n */\r\nexport function getHEXWithSpecificAplha(color: string, alpha = 1) {\r\n const rgbaColor = hexStringToRGBA(color)\r\n return rgbaToHexString({ ...rgbaColor, a: alpha }, true)\r\n}\r\n\r\n/**\r\n * Get rgba from valid color string\r\n */\r\nexport function getRGBAValueFromValidColorString(value: string) {\r\n if (getIsRgb(value)) return rgbaToRGBAString(rgbaStringToObject(value))\r\n return rgbaToRGBAString(hexStringToRGBA(value))\r\n}\r\n","// if conditionalCursor provided, cursor is set only if current cursor !== conditionalCursor\r\n// otherwise cursor is set if element exists\r\nexport const setElementCursor = ({\r\n elementId,\r\n cursor,\r\n conditionalCursor,\r\n}: {\r\n elementId: string\r\n cursor: string\r\n conditionalCursor?: string\r\n}) => {\r\n const element = document.getElementById(elementId)\r\n if (element && (conditionalCursor ? element.style.cursor !== conditionalCursor : true)) {\r\n element.style.cursor = cursor\r\n }\r\n}\r\n","/*\r\n * We want to be able to render only bars/parts of line that are visible to users,\r\n * but without introducing visual artifacts like bars missing in front of users while scrolling\r\n * or lines that start in middle of chart for sparse intraday stock data.\r\n *\r\n * In general we want to start rendering lines one bar sooner than what is visible to user and stop rendering\r\n * one bar outside of visible area to create a continuous line.\r\n */\r\nimport { ScaleAxis } from '../models/pane'\r\nimport type Quote from '../models/quote'\r\n\r\nexport const drawInVisibleArea = ({\r\n quote,\r\n scale,\r\n fxOverride,\r\n fromIndexOffset = 0,\r\n toIndexOffset = 0,\r\n leftOffset,\r\n drawBarCallback,\r\n width,\r\n}: {\r\n quote: Quote\r\n scale: { x: ScaleAxis }\r\n fromIndexOffset?: number\r\n toIndexOffset?: number\r\n fxOverride?: (index: number) => number\r\n leftOffset: number\r\n width: number\r\n drawBarCallback: (i: number, x: number) => void\r\n}) => {\r\n const fx = fxOverride ?? ((index: number) => scale.x(quote.barIndex[index]))\r\n\r\n // We want to start rendering one bar outside of the visible area for two reasons:\r\n // 1. To create a seamless transition for bars entering/leaving the view, avoiding them from\r\n // abruptly dis/appearing when half the bar is outside.\r\n // 2. To prevent disconnected lines in case there's a bar gap.\r\n // However, if a `fromIndex` is provided and it's higher than the first visible bar,\r\n // we need to start rendering from that specific index. This ensures correct starting\r\n // points for elements like indicators that rely on this value.\r\n const firstBarToRenderIndex = getCompensatedFirstBarToRenderIndex({ quote, scale, leftOffset, fromIndexOffset })\r\n\r\n let lastBarToRender = -1\r\n for (let i = firstBarToRenderIndex; i < quote.close.length + toIndexOffset; i++) {\r\n const x = fx(i)\r\n if (x + leftOffset > width) {\r\n lastBarToRender = i\r\n break\r\n }\r\n drawBarCallback(i, x)\r\n }\r\n\r\n if (lastBarToRender > -1) {\r\n const x = fx(lastBarToRender)\r\n drawBarCallback(lastBarToRender, x)\r\n }\r\n}\r\n\r\nexport const getFirstBarToRenderIndex = ({\r\n leftOffset,\r\n quote,\r\n scale,\r\n compensateBarGap = true,\r\n}: {\r\n quote: Quote\r\n scale: { x: ScaleAxis }\r\n leftOffset: number\r\n compensateBarGap?: boolean\r\n}) => {\r\n const barIndex = Math.ceil(scale.x.invert(-leftOffset))\r\n const calculatedIndex = quote.barToDataIndex[Math.max(barIndex, 0)]\r\n const isBarGap = scale.x(quote.barIndex[calculatedIndex]) + leftOffset < 0\r\n\r\n // not all the time there is bar present on barIndex calculated via inverted leftOffset\r\n // there might be a gap between bars, if there is, barToDataIndex on that gap spot will have value of\r\n // previous bar which isn't visible, if compensateBarGap === true we need to check if that happend\r\n // and correct it if so by increasing calculated index by 1\r\n\r\n return { index: compensateBarGap && isBarGap ? calculatedIndex + 1 : calculatedIndex, isBarGap }\r\n}\r\n\r\nexport const getLastBarToRenderIndex = ({\r\n leftOffset,\r\n quote,\r\n scale,\r\n chartWidth,\r\n compensateBarGap = true,\r\n}: {\r\n quote: Quote\r\n scale: { x: ScaleAxis }\r\n leftOffset: number\r\n chartWidth: number\r\n compensateBarGap?: boolean\r\n}) => {\r\n const { barToDataIndex } = quote\r\n const barIndex = Math.ceil(scale.x.invert(-leftOffset + chartWidth))\r\n const calculatedIndex = barToDataIndex[Math.max(barIndex, 0)] ?? barToDataIndex[barToDataIndex.length - 1]\r\n const isBarGap = scale.x(quote.barIndex[calculatedIndex]) + leftOffset < 0\r\n\r\n return { index: compensateBarGap && isBarGap ? calculatedIndex + 1 : calculatedIndex, isBarGap }\r\n}\r\n\r\n// Get first bar to render compensated for fromIndexOffset\r\nexport function getCompensatedFirstBarToRenderIndex({\r\n quote,\r\n scale,\r\n leftOffset,\r\n fromIndexOffset = 0,\r\n}: {\r\n quote: Quote\r\n scale: { x: ScaleAxis }\r\n fromIndexOffset?: number\r\n leftOffset: number\r\n}) {\r\n return Math.max(0, getFirstBarToRenderIndex({ quote, scale, leftOffset }).index - 1, fromIndexOffset)\r\n}\r\n","import queryString from 'query-string'\r\n\r\nimport { ObjectHash } from '../../types/shared'\r\n\r\ninterface FetchApiProps {\r\n location: string\r\n queryParameters?: ObjectHash\r\n method?: string\r\n body?: RequestInit['body']\r\n contentType?: ContentType\r\n abortController?: null | AbortController\r\n throwOnStatusCodes?: number[]\r\n throwOnPredicate?: (response: Response) => boolean\r\n keepalive?: boolean\r\n}\r\n\r\nexport const getFormDataFromObject = (object: ObjectHash) =>\r\n Object.keys(object).reduce((formData, key) => {\r\n formData.append(key, object[key])\r\n return formData\r\n }, new FormData())\r\n\r\n// Keep in sync with ContentType in https://github.com/finvizhq/Finviz-Website/blob/master/Website/js/main/services/api.ts\r\n// START\r\nexport enum ContentType {\r\n ApplicationJson = 'application/json',\r\n ApplicationJsonUTF = 'application/json; charset=utf-8', // WriteAsJsonAsync\r\n FormUrlEncoded = 'application/x-www-form-urlencoded',\r\n Html = 'text/html; charset=utf-8',\r\n}\r\n\r\nfunction parseResponseForContentType(response: string, contentType: ContentType) {\r\n switch (contentType) {\r\n case ContentType.ApplicationJson:\r\n case ContentType.ApplicationJsonUTF:\r\n case ContentType.FormUrlEncoded:\r\n return JSON.parse(response)\r\n default:\r\n return response\r\n }\r\n}\r\n// END\r\n\r\nconst fetchApi = async ({\r\n location,\r\n queryParameters,\r\n method,\r\n body,\r\n contentType,\r\n abortController,\r\n throwOnStatusCodes,\r\n throwOnPredicate,\r\n keepalive = false,\r\n}: FetchApiProps) => {\r\n const url = `${location}${queryParameters ? `?${queryString.stringify(queryParameters)}` : ''}`\r\n const parameters: RequestInit = {\r\n method: method || 'GET',\r\n credentials: 'include',\r\n headers: contentType && {\r\n 'Content-Type': contentType,\r\n },\r\n signal: abortController?.signal,\r\n body: body,\r\n keepalive,\r\n }\r\n try {\r\n const response = await fetch(url, parameters)\r\n const responseContentType: ContentType = (response.headers.get('Content-Type') as any) ?? ContentType.Html\r\n const responseData = parseResponseForContentType(await response.text(), responseContentType)\r\n if (throwOnStatusCodes?.includes(response.status) || throwOnPredicate?.(response)) {\r\n const StatusCodeError = getStatusCodeError(response.status)\r\n throw new StatusCodeError(`${url} returned ${response.status}`, responseData as T, response.status)\r\n }\r\n return responseData as T\r\n } catch (err) {\r\n throw err\r\n }\r\n}\r\n\r\nfunction getStatusCodeError(statusCode: number): typeof GenericStatusCodeError {\r\n switch (statusCode) {\r\n case 403:\r\n return ForbiddenError\r\n case 404:\r\n return NotFoundError\r\n case 410:\r\n return GoneError\r\n case 500:\r\n return InternalServerError\r\n default:\r\n return GenericStatusCodeError\r\n }\r\n}\r\n\r\nexport class GenericStatusCodeError extends Error {\r\n response: ObjectHash | string\r\n statusCode: number\r\n\r\n constructor(message: string, response: ObjectHash | string, statusCode: number) {\r\n super(message)\r\n this.response = response\r\n this.statusCode = statusCode\r\n }\r\n}\r\nexport class ForbiddenError extends GenericStatusCodeError {}\r\nexport class NotFoundError extends GenericStatusCodeError {}\r\nexport class InternalServerError extends GenericStatusCodeError {}\r\nexport class GoneError extends GenericStatusCodeError {}\r\n\r\nexport default fetchApi\r\n","import React from 'react'\r\n\r\nexport function useForceUpdate() {\r\n const [forceUpdateKey, increment] = React.useState(0)\r\n const forceUpdate = React.useCallback(() => {\r\n increment((prev) => prev + 1)\r\n }, [])\r\n return { forceUpdate, forceUpdateKey }\r\n}\r\n","import { EmptyObject, ObjectHash } from '../../types/shared'\r\n\r\nexport function getRoundedString({ number, numOfDecimalPlaces }: { number: number; numOfDecimalPlaces: number }) {\r\n const precision = Math.pow(10, numOfDecimalPlaces)\r\n return String(Math.round(number * precision) / precision)\r\n}\r\n\r\nexport function getIsSSr() {\r\n return typeof process !== 'undefined' && !!process?.env.IS_OFFSCREEN_RENDERER\r\n}\r\n\r\nexport function isValidHexColor(color: string) {\r\n const regex = /^#([\\da-f]{3}){1,2}$|^#([\\da-f]{4}){1,2}$/i\r\n return !!color && regex.test(color)\r\n}\r\n\r\nexport function getParsedIntegersFromPeriodString(periodString: string) {\r\n const periodParts = periodString.split(',')\r\n return periodParts.map((part) => Number.parseInt(part, 10))\r\n}\r\n\r\nexport function captureException(exception: Error, captureContext?: { extra: ObjectHash }) {\r\n if (process.env.NODE_ENV === 'development' || process.env.IS_E2E_TESTING) {\r\n console.error(exception)\r\n } else if (process.env.IS_OFFSCREEN_RENDERER) {\r\n import('@sentry/node').then((client) => {\r\n client.captureException(exception, captureContext)\r\n })\r\n } else {\r\n window.Sentry.captureException(exception, captureContext)\r\n }\r\n}\r\n\r\nexport function isPositiveFloat(value: string | number) {\r\n const parsedNumber = Number.parseFloat(`${value}`)\r\n return !Number.isNaN(parsedNumber) && isFinite(parsedNumber) && parsedNumber > 0\r\n}\r\n\r\nexport function isPositiveInteger(value: string | number) {\r\n const string = `${value}`\r\n return isPositiveFloat(value) && Number.parseInt(string, 10) === Number.parseFloat(string)\r\n}\r\n\r\nexport function isInRange({\r\n value,\r\n min = Number.MIN_SAFE_INTEGER,\r\n max = Number.MAX_SAFE_INTEGER,\r\n}: {\r\n value: string | number\r\n min?: number\r\n max?: number\r\n}) {\r\n const parsedNumber = Number.parseFloat(`${value}`)\r\n return !Number.isNaN(parsedNumber) && parsedNumber >= min && parsedNumber <= max\r\n}\r\n\r\nexport function tryJsonParse(json: string | null = '') {\r\n try {\r\n return JSON.parse(json ?? '') as Result\r\n } catch {\r\n return null\r\n }\r\n}\r\n\r\nexport function getValueInRange({ value, min, max }: { value: number; min: number; max: number }) {\r\n return Math.min(Math.max(value, min), max)\r\n}\r\n\r\nexport function isPrimaryClick(e: React.Touch | React.TouchEvent | React.MouseEvent) {\r\n // cypress trigger mouseevent has button: undefined if button option isn't explicitly specified\r\n // as cy.get('.target').trigger('mousedown', { button: 0 })\r\n if (e.hasOwnProperty('button') && (e as unknown as MouseEvent).button !== undefined) {\r\n return (e as unknown as MouseEvent).button === 0\r\n } else {\r\n return true\r\n }\r\n}\r\n\r\n// this function is used to fix the issue with circular reference when stringifying an object using JSON.stringify\r\nexport function getJSONReplacerFunc() {\r\n const visited = new WeakSet()\r\n return (key: string, value: any) => {\r\n if (typeof value === 'object' && value !== null) {\r\n if (visited.has(value)) {\r\n return\r\n }\r\n visited.add(value)\r\n }\r\n return value\r\n }\r\n}\r\n\r\n// This is a duplicate from Website repo which is accessible on window.FLibs but this doesn't work on SSR charts\r\nexport const formatDateToStringUS = (date: Date, options?: Intl.DateTimeFormatOptions | undefined) =>\r\n date.toLocaleDateString('en-US', {\r\n day: '2-digit',\r\n month: '2-digit',\r\n year: 'numeric',\r\n ...options,\r\n })\r\n\r\n// randomUUID source: https://stackoverflow.com/questions/105034/how-do-i-create-a-guid-uuid/2117523#2117523\r\nexport function randomUUID() {\r\n return `${1e7}-${1e3}-${4e3}-${8e3}-${1e11}`.replace(/[018]/g, (substring) => {\r\n const c = Number(substring)\r\n return (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16)\r\n })\r\n}\r\n\r\nexport function getUuid() {\r\n return window.crypto?.randomUUID?.() ?? randomUUID()\r\n}\r\n","import { useChartLayoutGlobalModelAsyncModule } from '../controllers/chart-settings/async-modules'\r\nimport { useAsyncModule } from './async-modules-utils'\r\n\r\nexport function useChartLayoutGlobalModelAsync() {\r\n const [useChartLayoutGlobalModelModule] = useAsyncModule({\r\n ...useChartLayoutGlobalModelAsyncModule,\r\n isSuspenseMode: true,\r\n })\r\n return useChartLayoutGlobalModelModule.useChartLayoutGlobalModel()\r\n}\r\n","import { CanvasRenderingContext2D as NodeCanvasRenderingContext2D } from 'skia-canvas'\r\n\r\nimport {\r\n CanvasElementType,\r\n ChartEditorEnum,\r\n ChartElementType,\r\n ChartEventType,\r\n IndicatorType,\r\n LayoutType,\r\n OverlayType,\r\n ScaleType,\r\n SpecificChartFunctionality,\r\n TIMEFRAME,\r\n TextAlign,\r\n TextBaseline,\r\n} from '../app/constants/common'\r\nimport ChartModel from '../app/models/chart'\r\nimport ChartLayout from '../app/models/chart_layout'\r\nimport { IChartThemeColors } from '../app/models/constants'\r\n\r\ninterface ISentry {\r\n captureException: (exception: any, captureContext?: { extra: ObjectHash }) => any\r\n captureMessage: (message: string, captureContext?: { extra: ObjectHash }) => any\r\n}\r\n\r\ndeclare global {\r\n interface Window {\r\n Sentry: ISentry\r\n FinvizSettings: ObjectHash\r\n FinvizChartsSettings: ObjectHash\r\n globalChartConfig: RootChartConfigObject\r\n isRenderInProgress: boolean | number\r\n rendersInProgress: number[]\r\n FinvizQuoteTypeCurrent: string\r\n handleScriptNotLoaded: () => void\r\n renderScriptNotLoaded: () => void\r\n gtag?: any\r\n }\r\n\r\n interface Document {\r\n fullscreenElement: any\r\n webkitFullscreenElement?: () => void\r\n mozFullScreenElement?: () => void\r\n msFullscreenElement?: () => void\r\n\r\n webkitExitFullscreen?: () => void\r\n mozExitFullScreen?: () => void\r\n msExitFullscreen?: () => void\r\n }\r\n\r\n interface HTMLElement {\r\n webkitRequestFullScreen?: () => void\r\n mozRequestFullScreen?: () => void\r\n msRequestFullscreen?: () => void\r\n }\r\n\r\n interface Navigator {\r\n msMaxTouchPoints: any\r\n }\r\n\r\n interface Array {\r\n last(): T | undefined\r\n }\r\n\r\n interface String {\r\n padLeft(paddingValue: string): string\r\n startsWith(str: string): boolean\r\n }\r\n\r\n type CanvasCache = Partial>\r\n\r\n interface CanvasRenderingContext2D {\r\n _cache: CanvasCache\r\n // We need to omit `canvas` because it is read only\r\n set>(\r\n key: Key,\r\n value: CanvasRenderingContext2D[Key]\r\n ): void\r\n }\r\n\r\n interface HTMLCanvasElement {\r\n _cache: CanvasCache\r\n }\r\n\r\n interface ImageBitmapRenderingContext {\r\n _cache: CanvasCache\r\n }\r\n\r\n type RenderingContext2DType = CanvasRenderingContext2D | NodeCanvasRenderingContext2D\r\n}\r\n\r\ndeclare module 'skia-canvas' {\r\n interface CanvasRenderingContext2D {\r\n _cache: CanvasCache\r\n\r\n set>(\r\n key: Key,\r\n value: CanvasRenderingContext2D[Key]\r\n ): void\r\n }\r\n}\r\n\r\nexport type TodoObjectHashAnyType = Record\r\nexport type TodoAreaObject = Record\r\nexport type ObjectHash = Record\r\nexport type EmptyObject = Record\r\n\r\nexport type TodoAnyType = any\r\n\r\nexport type ThumbType = string\r\n\r\nexport type PaneArea = {\r\n mouseDown?: boolean\r\n x: number\r\n y: number\r\n scaled: {\r\n x: number\r\n y: number\r\n }\r\n width: number\r\n height: number\r\n cursorX: number\r\n cursorY: number\r\n isCursorInChartWidthBoundaries: boolean\r\n} & T\r\n\r\nexport type Maybe = T | null | undefined\r\n\r\nexport interface DrawingBorder {\r\n color: string\r\n width: number\r\n}\r\n\r\nexport interface TextAttrs {\r\n text?: string\r\n background: string\r\n border?: { width: number; color: string }\r\n lineWidth?: number\r\n font: {\r\n size: number\r\n family?: string\r\n style?: string\r\n weight?: string\r\n }\r\n fillStyle?: string\r\n strokeStyle?: string\r\n angle?: number\r\n lineHeight: number\r\n textAlign?: TextAlign\r\n textBaseline: TextBaseline\r\n padding: {\r\n top: number\r\n right: number\r\n bottom: number\r\n left: number\r\n }\r\n}\r\n\r\nexport interface Point {\r\n x: number\r\n y: number\r\n}\r\n\r\nexport type RequireByKey = Omit & Required>\r\n\r\nexport interface ResizeByThumbFuncProps {\r\n type: ThumbType\r\n difX: number\r\n difY: number\r\n area: PaneArea\r\n}\r\n\r\nexport type ResizeByThumbWithTypeAndDifs = RequireByKey\r\n\r\nexport interface ChartConfigChartPaneElement {\r\n type: ChartElementType | CanvasElementType | IndicatorType | OverlayType | ChartEventType\r\n overlays?: OverlayConfigObject[]\r\n period?: string\r\n code?: string\r\n elementId?: string | null\r\n zIndex?: number\r\n}\r\n\r\nexport interface RendererChartBarProps {\r\n index: number\r\n chartSettingsColors: IChartThemeColors\r\n hasFillAndBorder?: boolean\r\n}\r\n\r\nexport interface ChartConfigChartPane {\r\n elements: ChartConfigChartPaneElement[]\r\n height: number\r\n chart?: ChartConfigObject | ChartModel\r\n}\r\n\r\nexport interface IIdea {\r\n id?: number\r\n date?: string\r\n note: string\r\n}\r\n\r\nexport interface ChartConfigObjectExtended {\r\n editable: boolean\r\n canChangeTicker: boolean\r\n scrollable: boolean\r\n cross: boolean\r\n ideas: boolean\r\n editors: ChartEditorEnum[]\r\n specificChartFunctionality: SpecificChartFunctionality\r\n theme: Theme\r\n layout: LayoutType\r\n uuid?: string\r\n idea?: IIdea\r\n}\r\n\r\nexport interface ChartConfigObject {\r\n width: number\r\n height: number\r\n panes: ChartConfigChartPane[]\r\n premarket: boolean\r\n aftermarket: boolean\r\n dateRange: string | null\r\n hasChartEvents?: boolean\r\n stretch?: boolean\r\n ticker: string\r\n instrument: Instrument\r\n timeframe: TIMEFRAME\r\n chart_layout: ChartLayout\r\n zoomFactor: number\r\n leftOffset: number | null\r\n refreshData: boolean | number\r\n isHideDrawingsActive: boolean\r\n isScrolled?: boolean\r\n scale: ScaleType\r\n}\r\n\r\nexport type RootChartConfigObjectChart = Omit<\r\n ChartConfigObject,\r\n 'chart_layout' | 'leftOffset' | 'zoomFactor' | 'isHideDrawingsActive'\r\n>\r\nexport interface RootChartConfigObject extends Partial {\r\n charts: Array\r\n width: number\r\n height: number\r\n newCharts?: boolean\r\n useGrid?: boolean\r\n}\r\n\r\nexport interface OverlayConfigObject {\r\n color: string\r\n period: string\r\n type: OverlayType\r\n}\r\n\r\nexport enum Instrument {\r\n Stock = 'stock',\r\n Crypto = 'crypto',\r\n MarketSentiment = 'market_sentiment',\r\n Futures = 'futures',\r\n Forex = 'forex',\r\n Group = 'group',\r\n}\r\n\r\nexport enum Theme {\r\n light = 'light',\r\n dark = 'dark',\r\n}\r\n\r\nexport interface IModalConfig {\r\n title: string\r\n inputs: IModalConfigInput[]\r\n inputsErrorMessages: ObjectHash\r\n}\r\nexport interface IOptionType {\r\n value: string | number\r\n label: string\r\n}\r\nexport interface IModalConfigInput {\r\n type: React.HTMLInputTypeAttribute\r\n label: string\r\n name: string\r\n value: number | string\r\n required?: boolean\r\n min?: number\r\n color?: string\r\n step?: number\r\n items?: IOptionType[]\r\n}\r\n\r\n// Keep in sync with config/types/globals.d.ts\r\nexport enum Position {\r\n Above = 'above',\r\n Below = 'below',\r\n}\r\n\r\nexport enum DefaultSpineEvents {\r\n Change = 'change',\r\n Destroy = 'destroy',\r\n Refresh = 'refresh',\r\n Update = 'update',\r\n}\r\n\r\nexport enum CustomSpineEvents {\r\n IndicatorsChange = 'indicatorsChange',\r\n ManualChange = 'manualChange',\r\n}\r\n\r\nexport enum DrawingSpineOptionsEvent {\r\n Remove = 'remove',\r\n}\r\n\r\nexport interface DrawingSpineOptions {\r\n eventType: DrawingSpineOptionsEvent\r\n}\r\n\r\nexport type TodoButtonProps = ObjectHash\r\nexport type TodoButtonTheme = string\r\n"],"names":["module","exports","white","black","inherit","transparent","current","finviz","blue","gray","red","orange","amber","yellow","brightYellow","lime","green","emerald","teal","violet","purple","pink","Array","prototype","last","this","length","String","padLeft","paddingValue","slice","startsWith","str","indexOf","_callbackCache","Spine","bind","ev","callback","that","cb","record","fkey","id","_len","arguments","rest","_key","push","newCb","origCb","model","unbind","item","findIndex","element","iterable","all","index","el","eql","defaults","enabled","collapsed","duration","timestamp","logErrors","withStackTrace","level","logger","console","filterChanges","attrs","props","Object","keys","constructor","name","errorTransformer","error","titleFormatter","title","time","took","parts","toFixed","join","colors","prevState","action","nextState","pad","num","maxLength","repeat","times","toString","printLogEntry","logEntry","options","startedTime","data","formattedTime","getHours","getMinutes","getSeconds","getMilliseconds","titleCSS","headerCSS","formattedTitle","groupCollapsed","group","e","log","styles","trace","groupEnd","initialize","window","protoModelLoad","load","started","Date","now","cid","attributes","returnedValue","apply","ChartEvent","Element","static","ChartEventType","isOpen","left","top","values","super","scale","getBoundingPointKeys","x","y","type","label","getChartEvenBadgeType","Dividends","ChartEventBadgeType","Split","EarningsNeutral","getChartEventModel","chartEventModel","chartEvents","findByAttribute","getXYPosition","bottom","getChartLayoutSettings","ChartSettings","scaled","roundedXY","getRoundedObject","height","CHART_EVENT_BADGE_SIZE","yIndex","getIsVisible","TIMEFRAME","w","m","includes","chart","quote","timeframe","renderContent","context","Math","round","chartLayout","chart_layout","buffer","leftOffset","width","getChartEventBadgeImage","theme","state","chartEvent","ChartEventBadgeState","selected","isHovered","hover","default","badgeType","drawImage","setIsHovered","updateChartEventsZIndexes","trigger","toggleIsOpen","isOpenOverride","isCurrentEventActive","activeChartEvent","elementId","instance","updateAttribute","undefined","isInArea","area","scaledArea","getIsInChartView","ChartEventLabels","Earnings","eventItem","getChartEventData","epsActual","epsEstimate","dateTimestamp","EarningsFuture","EarningsNegative","EarningsPositive","chartEventsByType","freeze","dividends","split","earnings","canvasElements","overlaysByType","indicatorsByType","drawingToolsByType","chartsByType","getCanvasElementByType","elementType","Chart","initClass","paneModel","quoteModel","chartLayoutModel","configure","hasMany","belongsTo","getChartPane","panes","find","pane","elements","some","isChart","getChartElement","getChartType","getRefreshInterval","defaultRefreshInterval","refreshData","QuotePollingIntervalInMs","Default","isStock","instrument","Instrument","Stock","isPremium","FinvizSettings","hasUserPremium","customRefreshInterval","Elite","Utils","isStockFastRefreshAvailable","EliteStocksReduced","Free","max","toObject","map","dateRange","ticker","zoomFactor","stretch","chartId","isHideDrawingsActive","isScrolled","premarket","aftermarket","hasChartEvents","toConfig","omitKeys","omit","destroyCascade","forEach","destroy","getIsDisabled","close","getIsScrollable","scrollable","getAllPanes","getAllValidPanes","cotKeys","COTs","filter","mainElement","IndicatorType","Cot","code","getAllElements","flatMap","getAllQuotes","perfQuotes","_ref","Perf","_ref2","quotes","quotePerfTickers","specificChartFunctionality","SpecificChartFunctionality","quotePerf","perfChart","Quote","select","q","tickers","d","createPaneCascade","paneProperties","create","_ref3","zIndex","fromObject","CustomSpineEvents","IndicatorsChange","chartOrIndicator","getChartOrIndicatorElement","updateAttributes","updateAttributesAndSync","value","attrsInSync","entries","ChartPartToAttrsSyncMap","_ref4","key","getIsChartPartInSync","_ref5","_","modelAttr","getAllCharts","chartModel","newAttrs","hasOwnProperty","setSyncChartParts","chartParts","isInSync","chartPart","getHasPatterns","hasOverlay","getQuoteRawTicker","getRawTicker","setChartEvents","shouldClear","chartPane","allChartEvents","events","_ref6","_ref7","eventType","positionTimestamps","updateScales","chartEventsAsyncModule","importFn","cacheKey","badgeImages","getSvgImageCacheKey","ChartEventElement","ElementModel","badgeImage","isLoaded","image","async","onBadgeInitLoad","importWithRetry","chartBadgeSvgByType","handleImageResolve","badgeState","Theme","svgHTML","img","Image","src","encodeURIComponent","onload","onerror","captureException","Error","extra","fetchAndCacheChartEventBadges","stockEvent","ChartLayout","drawingsInternalStoreModel","getPaneWithSelection","selection","charts","layout","isPreserveDrawingsActive","JSON","parse","stringify","settings","center","general","Colors","editors","editable","newCharts","test","location","pathname","chartPartsToSync","isArray","newSyncedChartParts","syncChartParts","getIsIndicatorPresent","first","isIndicator","getHTMLElementId","exitIdea","ideaID","fetchData","fetchType","QuoteFetchType","Refetch","isIdeaId","idea","initHlc","uuid","ts","count","compareHlc","one","two","incrementHlc","local","receiveHlc","remote","DrawingsInternalStore","latestRemoteUpdateTimestamp","latestLocalUpdateTimestamp","instanceUUID","autoSaveState","getUuid","AutoSaveState","Off","setAutoSaveState","newAutoSaveState","Indicator","Overlay","Pane","document","hostname","BackgroundInput","onChange","_jsx","InputColorPicker","inputDataTestId","toLocaleLowerCase","color","convertColorToHEX","ColorRangeRowInput","colorValue","colorTestId","rangeValue","rangeTestId","rangeLabel","rangeProps","handleRangeChange","useCallback","currentTarget","handleColorChange","_jsxs","className","children","RangeSlider","rightContent","Paragraph","as","size","Number","BorderInput","min","step","CheckBox","Checkbox","checked","FONT_VALUES","FontInput","family","setFamily","useState","setSize","style","setStyle","weight","setWeight","setValue","valueSetter","Label","Select","items","Input","LineInput","MultilineStringInput","required","Textarea","placeholder","target","autoFocus","NumberInput","allowDecimal","pattern","parseFloat","parseInt","StringInput","Trend","active","trend","valueAsNumber","VisibilityInput","isCheckboxOnly","isOff","setIsOff","React","from","setFrom","to","setTo","macroKey","macroLabel","charAt","toUpperCase","_Fragment","disabled","DEFAULTS","MacroTimeframe","minutes","hours","days","weeks","months","INPUTS_AVAILABLE","getInitialState","visibilities","merge","visibility","macroTimeframe","valueMacroTimeframe","getIsVisibilityOutsideAvailableTimeframes","every","macrotimeframe","macroRange","MicroTimeframeRange","isInRange","Visibility","initialVisibilityRef","handleChange","result","handleDisableSubmit","TAB_BUTTON_COMMON_PROPS","contentClass","getValuesFromFormState","formState","reduce","acc","cur","DialogTabs","ElementStyleDialog","config","getModalConfig","initialFormStateRef","inputs","setFormState","finalFocusRef","querySelector","body","selectedTab","setSelectedTab","Style","isSubmitDisabled","setIsSubmitDisabled","isDrawingElement","getIsDrawing","isEditInProgress","handleValuesChange","shouldSubmit","shouldDismiss","hasOnSubmit","onSubmit","hasOnDismiss","onDismiss","set","hide","handleValuesChangeDebounceRef","debounce","newFormState","maxWait","cancel","preventDefault","checkValidity","handleCloseDialog","Dialog","isDraggable","onOverlayClick","onHide","DialogHeader","onCloseClick","DialogBody","ButtonGroup","hasDivider","Button","onClick","input","InputComponent","getInputForType","inputType","stateInput","DialogFooter","animating","ElementStyleDialogContext","ElementStyleDialogWrapper","setElement","setOnSubmit","setOnDismiss","dialog","useDialogState","modal","Provider","openDialog","show","getContainerType","indicatorType","None","getTickersAndContainerTypesInLayoutModel","containerTypes","containerType","getInitialStoreDrawings","initialDrawings","initialDrawingsStore","FinvizChartsSettings","drawings","getAutosaveElementFromDBRecord","handleCallMethodOnAllDrawings","elementMethod","isDrawing","getNoteElementId","getElementNoteText","noteElement","elementAttrs","text","getTickerNoteText","changeType","lastChange","lastChangeTimestamp","lastChangeCounter","lastChangeNodeUUID","DRAWINGS_SAVE_INTERVAL_MS","RETRY_LIMIT","useDrawingAutoSaveApi","postRetryCountRef","deleteRetryCountRef","notificationContext","useNotification","fetchDrawings","fetchApi","queryParameters","throwOnStatusCodes","drawing","saveDrawings","bodyJsonString","getDBRecordFromAutosaveElement","keepalive","s","n","i","l","hi","charCodeAt","lo","getByteLengthOfString","Sentry","method","contentType","ContentType","ApplicationJson","latestChangeHlc","sort","a","b","InternalServerError","Promise","r","setTimeout","ForbiddenError","GoneError","newTicker","response","message","Notification","actions","timeoutInMs","GenericStatusCodeError","invalidItems","deleteAllDrawings","lastLocalChange","newHlc","useDrawingAutoSaveControls","isAutoSaveActive","useModelState","watchProperties","isInit","getIsPreserveDrawingsAndAutosaveAvailable","useIsAutoSaveActive","drawingsInternalStore","saveTimeoutRef","clearTimeout","saveLatestChanges","withDelayInMs","saveQueueExtraFilterCallback","saveQueue","Unsaved","save","Saving","Saved","syncChartLayoutDrawings","isRemove","paneContainerType","paneInternalStoreElements","autoSaveElement","paneElement","isCreator","paneDrawing","parsedElementAttrs","toAutosaveConfig","hasOngoingInteraction","handleAutoSaveNoteChange","note","newNoteElement","handleIdeaNoteChange","activeChart","checkDrawingUpdate","isRefetchAll","updatedDrawings","newLastUpdateTimestamp","updatedElementIds","newInternalStore","currentInternalStore","lastUpdateTimestamp","drawingIndex","currentDrawing","currentNote","autoSavedNote","mergeUpdatedDrawingsToInternalStore","allElements","normalizeZIndexes","quotePage","activeTicker","updateInternalStoreWithElement","updateResult","destroyed","instanceJson","newDrawing","updateDrawingIndex","drawingElement","shouldSyncAndSave","updatedRecord","hasChangedZIndex","hasChangedType","hasChangedAttrs","hasChange","updateInternalStoreWithChangedElement","deleteAllAutoSavedElements","onElementChange","elementPane","elementContainerType","elementPaneTicker","DrawingSpineOptionsEvent","Remove","useDrawingAutoSave","drawingsInternalStoreUnwatched","prevIsAutoSaveActive","ref","usePrevious","runInitialSaveAndRefetchUpdate","onChartOrIndicatorChange","newTickers","newContainerTypes","ChartModel","checkDrawingUpdateInterval","setInterval","clearInterval","getIdeaUrl","period","searchObject","t","p","isQuotePage","isStockOnQute","queryString","ta","IdeaItem","onIdeaDeleted","isDeleting","setIsDeleting","isConfirmDelete","setIsConfirmDelete","currentIdea","decodeQueryString","onDeleteIdeaClick","search","row","fetch","headers","href","url","ideaChart","globalChartConfig","reload","classNames","company","date","Icon","TimeframeLabelShort","appearance","stopPropagation","IdeasTabs","hasError","setHasError","hasFetched","setHasFetched","categorizedIdeas","setCategorizedIdeas","params","useSearchParams","queryTickers","get","gtag","event_category","ideas","dateParts","getInstrument","replace","processed","tickerIdeas","unshift","categorizeIdeas","fetchIdeas","handleIdeaDeleted","prev","modifiedCategories","categoryIndex","c","updatedCategory","updatedAll","Tabs","TabList","category","Tab","Badge","TabPanel","IdeasDialog","hasPadding","IdeasDropdown","rounding","dropdownButtonClassName","tooltipState","useTooltipState","placement","isAnyQuoteLoading","setIsAnyQuoteLoading","dropdown","useDropdownState","hideTooltip","dropdownItemProps","TooltipTrigger","checkIfAnyQuoteIsLoading","fetchingQuotes","isFetching","fetchedAt","visible","Dropdown","leftContent","DropdownItem","closeOnClick","layoutModel","activeChartQuote","toJSON","LayoutType","barWidth","barMargin","layoutModelObjectPanes","tickersString","getChartTickers","array","quotesJsonString","quoteTickersTimeframes","getFormDataFromObject","ideaUrl","open","saveIdea","DialogTrigger","Tooltip","Spinner","classnames","getIsMobileScreenSize","encodeQueryString","utm_source","utm_medium","utm_campaign","publishModalAsyncModule","Publish","publishModalModule","isLoading","useAsyncModule","shouldLoadModule","errorSeverity","onError","PublishDialog","buttonProps","Delayed","delayComponent","TourButton","page","tour","useTour","pageTours","steps","getRequestFullscreen","documentElement","chartPage","overlayPadding","isRedesignEnabled","Boolean","getTour","userTour","setCurrentTour","getStepsForUser","buttonTheme","hasNewTours","activeTour","startTour","once","ChartTypesSelect","chartTypes","getCurrentType","useLocation","ty","taInt","defaultType","QuoteShortToLongType","FinvizQuoteTypeCurrent","QuoteNodeChartTypes","candlestick","candlesticksimple","generateRouterPath","FREE_TYPES_QUOTE_VALUES","QuoteLongToShortType","DEFAULT_TYPES","FREE_TYPES_QUOTE","reloadDocument","useChartTypes","currentType","selectedType","setSelectedType","icon","nativeSelect","CHANGE_UPATE_EVENTS","QUOTE_MODEL_CHANGE_EVENTS","ChangeLabel","changePoints","isTiny","DailyChangeDisplay","withSuspense","chartIndex","useChartLayoutGlobalModelAsync","listenOnEvents","tickerChange","getTickerChange","math","getInstrumentDecimalPlaces","lastClose","tickerAfterChange","points","string","prevProps","nextProps","utmCampaign","futuresPage","forexPage","cryptoPage","testId","DrawButton","newValue","getIsDrawingEnabled","setCookieRequest","DRAWING_COOKIE_NAME","catch","expires","setMonth","getMonth","utils","setCookie","finally","getLayoutType","tickersCount","FullscreenButton","urlTickers","Search","onTickerSelected","dropdownState","saveToPortfolioDialogState","createAlertDialogState","saveToPortfolioModule","isLoadingSaveToPortfolio","saveToPortfolioAsyncModule","createAlertModule","isLoadingCreateAlert","createAlertAsyncModule","SaveToPortfolio","CreateAlert","detailLink","formattedTicker","Futures","Forex","Crypto","WebsiteSearchComponent","inputClass","isSearchIcon","isSearchItemLink","isShowAllVisible","onClose","SETTINGS_WIDTH","BUTTON_POPOVER_GUTTER","SETTINGS_POPOVER_ID","ScrollableChartSettingsPopover","elementWidth","bodyWidth","useElementMeasure","chartSettingsModule","chartSettingsAsyncModule","preventClosingUnsavedChangesModule","preventClosingUnsavedChangesAsyncModule","checkForUnsavedChangesAndCloseRef","PreventClosingUnsavedChanges","isFullyClosed","getExtendedDialogState","chartElement","getElementById","popoverContentElement","settingsButton","unstable_referenceRef","popoverStyles","newPopoverStyles","buttonRect","getBoundingClientRect","topOffset","maxHeight","innerHeight","position","scrollY","chartHeight","clientHeight","popoverContentHeight","offsetHeight","emptySpaceDiff","maxOffset","rightOffset","wrapper","marginRight","hasAsyncModules","Popover","popoverWrapperStyle","focusOnHide","hideOnClickOutside","checkForUnsavedChangesAndClose","ChartSettingsButton","settingsPopoverState","usePopoverState","PopoverTrigger","focusRing","getQuoteRequestKey","useChartControls","unwatchedChartModel","isInteractive","navigate","useNavigate","chartModelRef","modelRef","useModelRef","setIsLoading","abortControllerKeyRef","isIdeaChart","updateChartModelWithNewQuote","isSameTicker","getLeftOffset","chartQuote","NewerData","getAllChartEvents","isChartEvent","fetchQuote","patterns","currentQuote","abortController","createRequestAbortController","shouldAbortRunningRequest","cachePredicate","fetchNewDataOnCachedQuote","wasFetchAborted","isQuoteUsedInOtherCharts","removeFromAbortCache","decodedQueryString","rangesArray","ranges","shouldRecalculateOnCharts","hasSameBarWidth","IndicatorSettings","hasSameBarMargin","hasRedesignEnabled","ChartControls","favoriteTimeframes","toggleFavoriteTimeframe","useFavoriteTimeframes","anchorDate","generateChartLayoutRouterPath","timeframeGroupsWithHref","dateRangeGroupsWithHref","handleCustomDateRangeValidation","useChartModelCustomDateRangeValues","onDialogSubmit","customDateRangeDialogState","handleDateRangeSelect","getDateRangeTimeframe","useCustomDateRangeDialog","pathGenerator","handleTickerSelect","upperCaseTicker","handleCustomRangeSubmit","dateRangeTimeframe","timeframeBarProps","timeFrameGroups","dateRangeGroups","customRange","selectedTimeframe","onTimeframeSelect","selectedDateRange","loadingTimeframe","onDateRangeSelect","isFavoritesEnabled","onFavoriteTimeframeToggle","canChangeTicker","TimeframeBar","CustomDateRange","dialogState","hasTimeframe","ChartEditorEnum","Heading","tools","compactViewMaxBreakpointPx","grow","publish","CHART_LAYOUT_CHILD_CHANGE_EVENT","ContextMenu","contextMenu","selector","componentDidMount","update","componentWillUnmount","forceUpdate","render","shown","classList","remove","onContextMenu","ContextMenuComponent","add","ready","ReactDOM","event","clientY","pageYOffset","clientX","ChartEventPopoverWithState","unwatchedChartLayout","popoverState","chartEventsModule","isChartEventOfThisChart","setData","clickAwayRef","isListening","refCallback","isMobile","handler","contains","addEventListener","removeEventListener","useClickAway","unstable_popoverRef","popoverShow","popoverHide","newData","ZIndexContext","tabIndex","hasBackdrop","focusOnShow","hasViewportHeightLimit","ChartEventPopoverContent","LoadLatestDataButton","chartModelUnwatched","getIsMounted","isMountedRef","useIsMounted","hasNewDataAvailable","setHasNewDataAvailable","isPossibleToFetchSequentialData","then","hasNewData","promises","ZOOM_CONTROLS_ACTIVE_CLASS","ZOOM_CONTROLS_IS_IN_AREA_CLASS","buttonCommonProps","getDefaultLeftOffset","ZoomControls","zoomControlsRef","isVisible","onZoomIn","onZoomOut","onZoomReset","isGoToRecentVisible","setIsGoToRecentVisible","defaultZoomFactor","isZoomResetVisible","setIsZoomResetVisible","handleGoToMostRecent","handleChartModelChangeDebounced","hidden","rafId","crossRafId","paneRef","scalerRef","zoomerRef","canvasWrapperRef","canvasRef","crossCanvasRef","paneHammer","scalerHammer","zoomerHammer","canvasWrapperHammer","mouseDown","lastClientX","lastClientY","currentViewRange","lastX","lastY","lastActiveTool","scalerLastY","isElementHovered","hoveredElement","isDisableTouchCrossAvailable","canvas","canvasCtx","crossCanvas","crossCanvasCtx","isIndicatorPane","hasSeenCrossNotification","localStorage","getItem","onModelUpdate","onElementCreate","onElementDestroy","onElementReplace","onElementSelect","onElementClone","immediateRecountScaleOnChartIndicatorChange","recountScale","ManualChange","onChartUpdate","activeTool","MouseModel","getIsIndicatorPane","renderAll","renderCross","initialStoreDrawings","cachePointPositionTimestamp","getContextWithCache","Hammer","touchAction","threshold","on","onPress","onTouchMove","passive","onScalerReset","onZoomerReset","onDoubleClick","unmountCanvas","touchEventsDisabled","onPaneClick","paneIndex","getIsHammerAllowScrollActive","isChartPane","getIsChartPane","onMouseMove","onPaneMouseMove","onMouseLeave","onPaneMouseLeave","onTouchStart","onMouseDown","onResizerMouseDown","initialScrollable","onScalerMouseDown","onMouseEnter","onScalerMouseEnter","onScalerTouchStart","onZoomerMouseDown","onZoomerMouseMove","onZoomerTouchStart","DrawingTool","Mouse","onAddToZoomFactor","diff","shouldCalculateRightAlign","onCanvasInteractionStart","onCanvasInteractionMove","onTouchEnd","onBlur","getChartAlt","cross","isTouchCrossActive","oldElementInstance","isDrawingModeContinuousActive","setSelection","onPaneDestroy","setSelectedElement","clonedElementInstance","setCanvasSize","getArea","onMouseMoveOnScrolling","activeChartInteraction","TouchEvent","targetTouches","dif","addToLeftOffset","scaleRange","difY","ScaleType","Logarithmic","invert","getMinMax","onScalerTouchMove","onScalerMouseMove","onScalerTouchEnd","onScalerMouseUp","setActiveChartInteraction","MouseEvent","button","currentDomainMax","currentDomainMin","domain","originalMinMax","currentDiff","abs","originalDiff","getBarWidthWithMargin","getMinMaxLeftOffset","newLeftOffset","barIndex","fetchOlderData","getElement","openElementStyleDialog","pointerType","onCanvasPress","elementInArea","thumbsAreInArea","elementModel","hasProperties","isElementDrawing","makeClone","setVisibilityTo","SetVisibilityTo","currentAndAbove","currentAndBelow","currentOnly","bringToFront","sendToBack","bringForward","sendBackward","handleRemoveIndicatorPane","element_type","updateType","getIsCreator","getIsCreatorDialogOpen","requestAnimationFrame","process","_renderAll","getIsUpdatedDesign","renderPane","isCharts","isRedesignedFuturesForexCrypto","isRedesignedPage","isMouseInPane","getShouldRenderCrossInPane","clearRect","isCrossDisabled","PaneModel","elementInstance","renderCrossText","NaN","restore","additionalData","Settings","getSettings","areaRectangle","areaRectangleCursorX","areaRectangleCursorY","chartLeftX","chartRightX","right","cursorX","cursorY","isCursorInChartWidthBoundaries","ratio","getScaleRatio","canvasElement","setSizeOnCanvasElement","smallIndex","isChartsPage","setState","setItem","inline","_this","isMouseDownIgnored","zoomControls","paneHeight","touchEvent","setMousePosition","getMousePositionInBoundaries","isTouch","getIsChartEvent","onCanvasInteractionEnd","Touch","isPrimaryClick","setElementCursor","cursor","CanvasElement","activeThumb","moveBy","isSelected","canvasAreaRectangle","chartLeft","chartRight","chartTop","chartBottom","getValueInRange","_ref8","isSameMouseModel","setIsSelected","isSelectionCanvas","getCanvasDOMNode","withNotificationContext","Component","withElementStyleDialogState","ChartSpinnerOverlay","shouldDisplay","setIsVisible","timeout","DEFAULT_WRAPPER_COMPONENT","preventDefaultFunc","lastWidth","mouseWheelTimeout","setStateWithPanesTimeout","lastHeight","resizerPaneIndex","minimalPaneHeight","zoomerRightAlign","onLayoutModelChange","panesWrapperElement","onPaneCreate","calculateMinimalPaneHeight","handleQuoteChange","onModelChange","onOlderDataLoaded","onDataLoaded","componentDidUpdate","isWheelZoomEnabled","handleSetPanesWrapperRef","renderChartToolbar","showSettings","resetMouseModel","onPinchStart","onWheel","onMouseWheel","addToZoomFactor","calcZoomerRightAlign","activePane","paneId","chartModelParam","panesHeight","sum","newPaneHeight","isNaN","newChartPaneHeight","newIsScrolled","onResizerMouseMove","onResizerMouseUp","resizePanesAccordingly","minHeight","total","optiMinHeight","floor","basePane","touches","onZoomerTouchMove","onZoomerTouchEnd","onZoomerMouseUp","getRawDistance","p1","p2","distance","onPinchMove","onPinchEnd","fx","currentLeftOffset","isIntraday","getBarIndex","offsetDiff","shouldAlignDaysToLeftApplied","offsetBars","offset","normalizeWheelDeltaY","deltaY","sign","isMouseWheel","difX","diffCoefficient","currentZoomFactor","minBarWidthInPx","maxBarWidthInPx","minZoomFactor","getZoomFactorForBarsToDisplay","chartVisibleWidth","numOfVisibleBars","maxZoomFactor","isNegativeDirection","newZoomFactor","newZoomFactorInRange","getZoomFactor","getIsSmallIndexChart","updateZoomAndLeftOffsetByDateRange","newQuote","shouldForceLeftOffsetUpdate","isMouseDown","WrapperComp","gridArea","isModelDestroyedRef","initChartRef","panesConfig","overlays","overlay","panesWithPerfIndicator","allSettled","paneWithPerfIndicator","prefetchPerfIndicatorAllQuotes","shouldResize","chartsDimensions","getChartsDimensions","handleModelBeforeDestroy","isChartPage","isFuturesForexCryptoPage","isModelReady","loadingStyle","hasOutline","withWatchedPanesOnChartModel","ModuleLoadFailed","DefaultErrorBoundary","portfolioWatchlistAsyncModule","SidebarModule","sidebarModules","portfolio","description","content","asyncModule","withInitialLoading","isComponentReady","setIsComponentReady","sidebarModule","isError","isSuspenseMode","withModuleAsyncLoad","mobile","SidebarContent","direction","onResize","useSidebarContext","minWidth","DEFAULT_WIDTHS","maxWidth","defaultMobile","defaultDesktop","desktop","SidebarDirection","vertical","Resizable","enable","handleClasses","defaultSize","isIPad","horizontal","MOBILE_TOOLBAR_DIV_ID","SidebarTabs","activeModule","selectModule","unstable_timeout","isActive","isBlurAfterClick","SIDEBAR_QUERY_PARAM","Sidebar","onShouldResize","tabsClassName","urlSearchParams","sidebarModuleKey","setActiveModule","handleSelectModule","newUrlSearchParams","URLSearchParams","delete","handleCloseSidebar","getIsMobilePortrait","contextValue","isCloseVisible","SidebarContext","ErrorBoundary","FallbackComponent","fallback","drawingCreatorsAsyncModule","drawingActions","DrawingActions","AddNote","DeleteDrawings","DeleteAutoSavedDrawings","getToolbarDrawingActions","isAddNoteAvailable","isIdea","defaultItem","isDisabled","disabledTooltip","drawingSettings","DrawingSetting","PreserveDrawings","iconActive","titleActive","DrawingModeContinuous","HideDrawings","LockDrawings","preserveDrawingsAutosaveOverride","iconAction","titleAction","getToolbarDrawingSettings","isPreserveDrawingsAndAutosaveAvailable","isAutoSaveInProgress","isInAction","drawingTools","Measure","ScaledLine","Arrow","VerticalLine","HorizontalLine","Rectangle","RotatedRectangle","Triangle","Ellipse","Curve","Pitchfork","Polygon","Xabcd","ScaledText","Brush","ElliottWaves","FibonacciRetracements","Position","Callout","toolbarDrawingTools","toolGroup","toolGroupTitle","DISABLED_ITEM_TOOLTIP_LABEL","Toolbar","isSidebar","isHorizontal","isMobileOverlay","onActiveToolChange","onDrawingActionClick","onDrawingSettingClick","onDrawingEnd","isAlternativeTheme","areToolsDisabled","drawingCreatorsModule","isDrawingCreatorsModuleLoading","setIsDrawing","availableDrawingSettings","availableDrawingActions","isDrawingModeContinuous","hasData","hasHiddenDrawings","tool","drawingToolsTouchCreatorsByType","drawingToolsCreatorsByType","ToolClass","ToolbarComponent","isToolLoading","ToolbarItem","groupItems","groupTitle","useNativeSelect","ToolbarDivider","ChartAutoSaveNote","onNoteChange","rows","ChartAutoSaveNotes","setTickers","unwatchedInternalStore","handleChartChange","tickerNoteMap","AutoSaveNotesDialog","isBackdropDisabled","ConfirmationDialog","onCancel","onAction","isAutosaveDialogContent","dialogContent","getDialogContent","ConfirmationDialogComponent","ToolButton","ToolbarMobile","isToolbarVisible","setIsToolbarVisible","setUrlSearchParams","toolbarMobileElement","setToolbarMobileElement","handleActiveToolChange","drawingTool","wrapperRef","handleClickOutside","openSelect","actionId","has","AutoSaveStateIndicator","setVisibilityTimeout","newIsVisible","checkIfNeededPreventLeaving","returnValue","hasRedesign","ChartLayoutAutoSaveNote","chartLayoutModelUnwatched","ideaNoteRef","getPublishChartHtmlElements","publishChartElements","getElementsByClassName","getChartImgUrl","imgElement","PublishOldButtonClickListener","dialogConfig","setDialogConfig","isCanvas","chartImgUrl","publishChartHtmlElements","clickHandler","dataset","indexInt","IdeaDrawingsConfirmationOptions","IdeaLeaveDialog","actionCallback","Cancel","Override","Merge","Nothing","getChartElementTypeFromQueryType","queryType","QuotePageQueryChartTypes","ChartElementType","LineChart","hc","HollowCandleStick","ha","HeikinAshi","o","OhlcChart","PerfChart","cs","CandleStick","getChartElementTypeFromResponseType","TA","useChartRouteChange","useTrackPageView","trackInitial","dateFns","updateChartConfig","decodedSearch","urlType","handleTypeChange","urlTicker","urlTimeframe","urlDateRange","newChartConfig","getRawTickerForInstrument","defaultPeriod","defaultDateRange","handleIdeaLeave","getDefaultZoomFactor","innerWidth","MOBILE_VIEW_BREAKPOINT_WIDTH","MOBILE_BARS_TO_VIEW","OnInitListener","onRegisterChartLayoutModel","parentElement","setIsInit","checkIfInitIsComplete","isReady","elementIndex","opacity","withCompleteLayoutModelInit","newConfig","light","dark","concat","isQuotePageWithDrawingsOff","getCookie","noteDrawing","ideaObject","indicatorElement","getContainerTypeFromPaneConfig","newElements","ChartLayoutModel","toolsState","isLockDrawingsActive","withQuotePolling","pollingIntervalToCharts","setPollingIntervalToCharts","checkForChartsWithPolling","newPollingIntervalToCharts","chartRefreshInterval","intervalIdsRef","checkForChartsWithPollingDebounced","chartsCheckerIntervalId","EXTRA_MARKET_BUFFER_MINUTES","timeoutDurations","allCharts","timeoutDurationsMin","timeoutId","chartIds","quotesToUpdate","quoteToUpdate","dispatchEvent","Event","QUOTE_FETCH_EVENT","ChartLayoutComponentBase","orientationChangeTimeout","preserveDrawingAbortController","AbortController","chartConfig","modelProperties","isToolbarHorizontal","handleInitialPreserveDrawingsState","DELETE","keyCode","ThumbSettings","touchSize","onChartDestroy","setToolbarPosition","onWindowResize","handleOrientationChange","checkTouchEventsDisabled","abort","throttledResize","preserveDrawings","handlePreserveDrawingsSettings","setPreserveDrawings","val","tools_state","handleResize","modelAttrs","throttle","newIsToolbarHorizontal","getFullscreenStatus","getVisualViewportScale","visualViewport","handleDrawingAction","noteDialogState","toggle","confirmationDialogState","handleConfirmationDialogCloseBtn","handleConfirmationDialogDeleteBtn","drawingToRemove","handleDrawingsSetting","settingId","newObj","toggleHideDrawings","handleLockDrawings","event_label","renderToolbar","args","isOverlayToolbar","useGrid","LAYOUTS","isMobilePortrait","isSidebarEnabled","getIsSidebarEnabled","ChartGrid","border","columns","ChartGridCell","gridAreas","hasChartTools","renderTools","ideaTitleContainer","ideaTitle","clear","updateLayout","removeCharts","addCharts","rowStart","columnStart","rowEnd","columnEnd","numOfRowsCovered","numOfColumnsCovered","percentageOfRowsCovered","percentageOfColumnsCovered","newWidth","newHeight","settingsHeight","wantedCount","pop","ChartLayoutComponent","flowRight","checkQuoteCacheDebounce","cleanupQuoteCache","allQuotes","allChartQuotes","usedQuote","updateChartsTitle","defaultDocumentTitleRef","afterClose","prevClose","percentageChange","overridePlaces","useChartPageTitle","handleChartsUpdate","getChartLayoutWithChartRouteChange","isWithNotifications","Wrapper","NotificationWrapper","ChartLayoutWithGlobalState","setChartLayoutModel","getChartLayoutModelConfig","lastGlobalRerender","IPAD_FULLSCREEN_CLASS","isFullscreen","setIsFullscreen","requestFullscreen","exitFullscreen","getExitFullscreen","call","checkFullscreen","SORTED_LAYOUT_KEYS","arr","option","sortBy","sortDirection","SORT_DIRECTION","ASC","directionMultiplier","sortObjects","ChartLayoutDropdown","parsedQuery","getChartsToPath","useChartsPathLocation","orientation","DropdownSeparator","ChartSyncableParts","isChartPartInSync","ThemeToggleButton","isDarkMode","updateSettings","BREAKPOINTS","Infinity","marketBadgeText","timeFormat","ChartLayoutHeaderComponent","onSettingsOpen","hasPublish","Time","breakpointMode","breakpoints","ChartLayoutHeader","StockDetailTimeframeBar","isDateRangeAvailable","isLoadingOverride","isScrollIntoViewEnabled","containerElement","pushIndicators","indicator","hasPaneWithCOTCode","PANE_HEIGHT_DEFAULT","parameters","getChartTypeByTaConfigStyle","heikinashi","hollowcandlestick","line","ohlc","mergeChartAndTAConfig","taConfig","linear","Linear","percentage","Percentage","logarithmic","indicators","Above","Below","getPanes","SettingsTab","getCurrentDateInMs","valueOf","getIsDocumentVisible","visibilityState","notifyOnVisibilityChange","promisifiedCallback","waitForPreviousPromise","unsubscribe","intervalCallbackOnWindowVisible","interval","getInterval","refreshPromise","nextRefresh","refreshTimeout","refresh","handleVisibilityChange","currentDateMs","AdsProvider","getAdsProvider","adsProvider","Freestar","InvestingChannel","trackPageView","query","freestarPageView","freestar","queue","trackPageview","portfolioWatchlistTableAsyncModule","assets","logo","logo_light","ColorVariant","CheckboxSize","CheckboxComponent","defaultChecked","forwardRef","clamp","getRelativePosition","node","rect","pointer","pageX","pageXOffset","pageY","preventDefaultMove","DraggablePickerComponent","onMove","onKey","container","useRef","hasTouched","isDragging","setDragging","isValid","handleMove","buttons","handleMoveStart","nativeEvent","handleKeyDown","which","handleMoveEnd","toggleDocumentEvents","toggleEvent","useLayoutEffect","onKeyDown","DraggablePicker","memo","Pointer","backgroundColor","hexStringToRGBA","hexString","hexColor","removeHashSymbol","g","hexStringToHSVA","rgbaToHSVA","alphaToHex","alpha","padStart","rgbaToHexString","hsvaToHEXString","hsvaToRGBA","v","h","f","k","rgbaToRGBAString","rgbaStringToObject","colorParts","exec","strColor","isValidColor","isRgb","Option","getIsRgb","rgbKeys","getHSVAFromColor","Alpha","changeLightness","pos","gradientPreview","useMemo","backgroundImage","DEFAULT_COLORS","ColorPalette","lowerCaseColor","toLowerCase","colorObj","HueSaturation","getPositionFromHSLA","colorPreview","changeSaturation","Lightness","ColorPreview","isTooLight","getLumaFromRGBA","getIsColorTooLightOrTransparent","isValidIconName","PickerInput","hasColorPreview","colorInput","setColorInput","colorUtil","isRgba","useEffect","handleColorInputChange","ColorPicker","canSelectCustom","canSelectAlpha","outputFormat","onPaletteItemClick","cachedColor","hsvaColor","setColor","currentColor","newColor","onChangeCallback","stringColor","output","onSetCustomCodeClick","prompt","trim","alert","_hex","orignalColor","isMobileDevice","MultiColorPicker","colorInputLabel","ColorTabButton","ButtonRounding","small","ButtonColorPicker","buttonPickerDataTestId","isMultiPicker","activeColorIndex","setActiveColorIndex","originalColor","colorObject","childComponent","CopyToClipboard","bottomLeftContent","isCopied","setIsCopied","handleCopyToClipboard","copy","resetTimer","readOnly","DatePickerComponent","StatelessDatePicker","triggerProps","child","Box","locale","minDetail","DatePicker","popover","DEFAULT_OFFSETS","menuMaxHeight","popperElement","setPopperElement","virtualRef","scrollX","getVirtualRef","hasBeenOpen","usePopper","modifiers","popper","ContextMenuDropdown","isStatic","ContextMenuInner","MAX_SAFE_INTEGER","innerState","maxHeightStyle","usePopoverMaxHeight","maxHeightLimit","offsets","assign","menu_option","GridLayout","gridTemplateColumns","gridTemplateRows","defaultValueAccessor","InnerState","asComponent","valueKey","changeKey","valueAccessor","RangeSize","inputClassName","hasTrack","setHasTrack","trackRef","thumbRef","thumbLeft","track","thumb","valuePercent","trackBox","thumbBox","ToolbarTheme","ToolbarDirection","ToolbarContext","chipTransparent","isWrapped","isStretched","useToolbarContext","getToolbarSettings","alternative","toolbarRef","contextProviderValue","toolbarSettings","isSafariDesktop","forceReflow","originalWidth","offsetWidth","ToolbarButton","isInActionProp","buttonSettings","includeRedesign","getButtonThemeSettings","getMainIcon","delay","ToolbarGroup","listState","useListState","currentId","selectedItem","setSelectedItem","groupId","useHoverPopover","useList","NativeSelect","List","onItemChange","ListItem","isItemActive","StepContent","shepherdLibrary","loadShepherdLibrary","setLoading","shepherdPromise","buttonClasses","BUTTON_BASE_CLASS","BUTTON_FOCUS_STYLES","ButtonSize","regular","getStepButtons","complete","classes","getButtonTheme","ButtonTheme","ButtonPadding","back","backButton","next","nextButton","getTourKey","tours","lastFinishedTour","lastTourIndex","allToursViewed","skip","toursToView","initialTour","completeTour","DEFAULT_OPTIONS","exitOnEsc","useModalOverlay","currentTour","setTour","controller","loadingSetter","signal","aborted","definition","setComplete","tourUtils","Tour","removeStep","processedSteps","attachTo","popperOptions","modalOverlayOpeningRadius","overlayRadius","modalOverlayOpeningPadding","addSteps","start","TabsContext","useTabsContext","useTabState","TabSpacing","spacing","Reakit","itemProps","ariaLabel","BadgeSize","BadgePadding","padding","badgePadding","badgeSize","hasArrow","popoverMaxHeight","hasButtonWidthLimit","useZIndex","useWindowSize","isWatching","buttonElement","popoverId","getAttribute","popoverWrapper","setProperty","Portal","unstable_autoFocusOnShow","unstable_autoFocusOnHide","unstable_finalFocusRef","onTransitionEnd","onAnimationEnd","innerProps","TooltipArrow","BoxTheme","DEFAULT_OFFSET","HOVER_TIMEOUT","unstable_offset","animated","COMPONENT_ANIMATION_DURATION","showTimeout","hideTimeout","clearTimeouts","showPopover","hidePopover","onMouseOver","onMouseOut","showPlaceholder","handleNativeSelectChange","itemIndex","selectedIndex","flattenItems","newUrl","URL","hash","isSelectItemGroup","optionIndex","NativeSelectInRouterContext","onChangeWithNavigate","ItemsGroup","Ariakit","getDefaultTheme","InternalOption","subtitle","ariaSelected","dataActiveItem","activeTheme","defaultTheme","align","SelectOption","isComboBox","combobox","getCollectionItem","SelectItemsVirtualized","listItems","isSelectItem","hasGroups","SelectRenderer","itemSize","overscan","groupOritem","restProps","itemRenderer","paddingStart","paddingEnd","rendererProps","restItem","SelectItems","searchValue","parentTestId","virtualized","isInRouterContext","useInRouterContext","filteredItems","filterSelectOptions","innerItem","providedProps","getSelectItemProps","truncate","ListRounding","ListTheme","focusWithoutScroll","focus","preventScroll","onBackdropClick","SelectList","gutter","unmountOnHide","hasItemChildren","ListElement","wrapperProps","hasChildren","preventBodyScroll","autoFocusOnHide","backdrop","none","autoSelect","TooltipInner","tooltipContext","currentPlacement","subscription","focusable","TooltipBox","SelectTooltipWrapper","isPopoverOpen","hasShownTooltip","onFocusVisible","DesktopSelect","defaultValue","tooltip","onInteractionChange","comboBox","onSearch","listProps","internalSearch","setInternalSearch","SelectWrapper","resetValueOnHide","includesBaseElement","ButtonWrapper","buttonWrapperProps","warn","focusLoop","virtualFocus","setOpen","DEFAULT_RIGHT_ICON","SelectButton","valueOverride","selectedValue","buttonText","rightIcon","xxsmall","providedValue","providedDefaultValue","triggerContent","dataTestid","findSelectedValue","selectTrigger","NativeSelectComponent","findSelectedIndex","inRouterContext","Link","matchesSearchTerm","searchTerm","lowerSearch","isSameItem","obj1","obj2","finalResults","filtered","foundItem","itemOrGroup","DATERANGE_TOOLTIP","DateRangeSelect","flatDateRanges","dateRanges","withReload","linkProps","_createElement","LabelWithDelayedSpinner","invisible","TIMEFRAME_TOOLTIP","TimeframeSelect","isCompactView","isCompactOnly","flatTimeframes","timeframes","getSelectedTimeframeLabel","selectedTimeframeItem","labelShort","groupIndex","isIconButtonActive","getTimeframeChipElementId","getButtonPadding","xsmall","medium","large","isTimeframeSelectEnabled","scrollWrapperElement","setScrollWrapperElement","timeframeButtonsScrollLocation","setTimeframeButtonsScrollLocation","isOnLeftEdge","isOnRightEdge","setElementRef","timeframesInExpandedPanel","checkTimeframeWrapperScrollPosition","scrollLeft","ceil","scrollWidth","timeframeElement","offsetLeft","clientWidth","scrollTo","onScroll","absDx","deltaX","generateTimeframeGroups","premiumTimeframes","i1","i2","i3","i5","i10","i15","i30","labelPageTitle","h2","h4","freeTimeframes","getTimeframeGroups","generateDateRangeGroups","DateRangeType","d1","d5","m1","m3","m6","ytd","y1","y2","y5","getDateRangeGroups","isCustomAvailable","rangeGroups","dateRangePrefix","DATE_RANGE_PREFIX_DELMITER","CustomDateRangePrefixEnum","CUSTOM_DATE_RANGE","getDateRangeGroupsWithHref","generatePath","dateRangeGroup","FREE_PERIODS_STOCK","generatePathForTimeframeDateRange","dateRangeQueryKey","timeframeUtm","daterangeUtm","CUSTOM_DATE_RANGE_DELIMITER","CUSTOM_PREV_RANGE_DELIMITER","getParsedDateRange","parseCustomDateRangeUrlParam","dateRangeValue","Range","dateFromString","dateToString","dateFrom","dateTo","getTime","end","Prev","years","DAYS_IN_YEAR","getTimeframeFromDateRange","getTimeframeForDateRangeType","startNyTime","startToReferenceDateNumOfDays","rangeNumOfDays","DATE_PICKER_MIN_DATE","YEARS_MAX_VALUE","getFullYear","CustomRangeType","DEFAULT_MANUAL_RANGE","kind","Manual","DEFAULT_START_END_RANGE","StartEnd","getDefaultSelectedTab","getDefaultSelectedDate","newState","newEnd","isAbsolute","fromDate","toDate","manualRange","isValidStartEndRangeState","startString","formatDateToStringUS","endString","getCustomStartEndDateRangeUrlParam","isValidManualRangeState","getPrevPeriodDateRangeUrlParam","minDate","shouldReloadOnNavigate","path","newTimeframe","TIMEFRAME_FAVORITE_DEFAULTS","TIMEFRAME_FAVORITE_DEFAULTS_FREE","intraday","LOCAL_STORAGE_KEY","storageKey","storage","valueGetter","useSyncLocalStorage","TooltipInputWrapper","tooltipContent","tooltipColor","tooltipSettings","isHideOnClickOutside","TooltipInputComponent","TooltipInput","MAX_HEIGHT_PROPERTY","POPOVER_HEIGHT_LIMIT_STYLE","offsetY","elementMaxHeight","trackAutomatically","initialRender","handleTrackView","tracking","throttleWaitInMs","PortfolioQuery","PortfolioMapSizeKey","PortfolioView","PortfolioTableView","PortfolioTableViewLabels","Ticker","Trade","PortfolioSymbolType","PortfolioTransaction","ColumnId","RowKind","ActionKind","cache","errorsCache","ErrorSeverity","defaultCaptureException","exception","captureContext","setIsError","handleError","high","handleScriptNotLoaded","renderScriptNotLoaded","loadModule","cachedModule","mod","err","NUM_OF_RETRIES","retries","emitter","subscribeToChanges","changeCallback","EventEmitter","getValue","onStorageChange","addListener","removeListener","emit","valueToStore","Function","removeValue","removeItem","migrateValue","transformValue","oldValue","callbackPromise","CanvasElementType","arrow","resize","_thumbs","Thumb","x1","x2","getDefaults","ElementSettings","translateXY","getXYOffsetFromLine","lineWidth","translate","beginPath","angle","PI","moveTo","lineTo","stroke","lineAngle","atan2","cos","angle1","topx","topy","sin","angle2","botx","boty","getShouldRenderThumbs","renderThumbs","isDrawingElementLockedOrInvisible","distanceToSegment","modalConfig","brushV1","untranslatedContext","brushPath","cachedFill","previousFill","shouldRenderFill","createElement","setFillCache","fill","defaultTransparentFill","isPolyLineClosed","getShouldRenderFill","Path2D","fy","xc","yc","quadraticCurveTo","point","closePath","getThumbs","firstX","firstY","moveByThumb","onMouseUp","roundToFixed","roundY","isPointInPath","positionPointsTimestamps","getTimestampFomPositionX","getPositionXFromTimestamp","places","domainDiff","numberOfLeadingZeros","log10","getAutosaveOmittedProperties","getEdgeXYValues","edgeXYValues","minX","minY","maxX","maxY","TailDirection","getTailHalfWidth","halfWidth","dist","Text","calloutV1","getModalConfigBase","textWithoutBackground","font","fillStyle","lineHeight","textAlign","textBaseline","background","defaultFill","setupContext","setupTextMetricsCache","ctx","lastAttrs","lines","getLines","metrics","measureText","measuredHeight","currentIndex","actualBoundingBoxAscent","actualBoundingBoxDescent","PADDING","S","renderText","previousDescent","fillText","getCalloutProperties","textWidth","requiredTailHalfWidth","radius","rectangleSides","topLeft","topRight","rightTop","rightBottom","bottomRight","bottomLeft","leftBottom","leftTop","getRectangleSidesCoordinates","tail","tailRoot","tailTip","getTailCoordinates","tailDirection","twoSegmentLinesIntersection","topLeftCorner","topRightCorner","bottomLeftCorner","bottomRightCorner","topSide","rightSide","bottomSide","leftSide","noTail","getTailToSideIntersection","renderBackground","lineJoin","arcTo","tailLineToTopLineIntersection","tailHalfWidth","tailLineToRightLineIntersection","tailLineToBottomLineIntersection","tailLineToLeftLineIntersection","renderCallout","renderBorder","tailP1","perpendicularPointToLine","pointOffsetX","pointOffsetY","tailP2","polygon","pointInPolygon","curve","x3","y3","drawQuadraticCurve","Bezier","quadraticFromPoints","cp1x","cp2x","cp1y","cp2y","project","ellipse","getCoordinates","centerLeftX","centerLeftY","centerRightX","centerRightY","boundingPointKeys","bottomCenterX","bottomCenterY","bezierCurveTo","bottomRightX","bottomRightY","topRightX","topRightY","topCenterX","topCenterY","topLeftX","topLeftY","bottomLeftX","bottomLeftY","rotationAngle","atan","radiusX","radiusY","width_two_thirds","dx1","dy1","dx2","dy2","rotatedRectangle","getRectCoordinates","coords","mx1","mx2","my1","my2","nk","dx","sqrt","dy","x4","y4","SymbolElement","symbol","sx","getRotatedCoordinates","scaleX","sy","textHeight","scaleY","xScale","yScale","xOffset","yOffset","rotate","cx","cy","halfHeight","brush_v1","callout_v1","elliottWaves","ellipseV1","ellipse_v1","fibonacciRetracements","fibonacci","horizontalLine","measure","pitchforkV1","pitchfork_v1","rectangle","rotatedRectangleV1","rotatedRectangle_v1","scaledLine","scaledText","symbolElement","triangle","verticalLine","xabcd","obj","getNumOfBarsBuffer","isCreatorDialogOpen","__","getIsPaneSelection","attrsSubset","customizer","objValue","srcValue","mergewith","defineProperty","globalAlpha","startEditing","xPointKeys","positionX","pointPoitionsFromTimestamp","replaceMyself","captureMessage","oldElement","newElement","release","micro","macro","MicroMacroTimeframe","timeframesToSet","attrsToSet","xPoints","yPoints","positionY","omitX","isMaxXInvalid","isMinXInvalid","omitY","topBound","bottomBound","waves","getOffsetFromLineWidth","TextBaseline","middle","TextAlign","wave","positionWavesTimestamps","EllipseV1","getEllipsePoints","P2","P4","coordinates","P3","P1","CP4","CP1","CP2","CP3","ellipsePath","inverted","cursorTargetX","cursorTargetY","perpendicularPoint","distanceToLine","lineCenterX","lineCenterY","invertX","invertY","perpendicularPointEllipseOffsetX","perpendicularPointEllipseOffsetY","P1WithOffsetX","P1WithOffsetY","P3WithOffsetX","P3WithOffsetY","controlPointOffsetX","controlPointOffsetY","getRotatedPointCoordinates","rotationAxisPoint","pointToRotate","oldLinePoint","newLinePoint","sharedPointLinesAngle","sharedPoint","rotatedPoinCoordinates","rotatedPointCoordinates","newLeftPoint","leftRotatedCursorPoint","newRightPoint","rightRotatedCursorPoint","parseCoefficients","coefficients","parsed","getMaxCoefficientUnscaledY","heightScaled","splice","maxCoefficientY","decimalPlaces","updateDecimalPlaces","renderLabels","Line","strokeStyle","dashLength","setLineDash","x1Dif","x2Dif","startingX1","startingX2","getVolumeSumString","volume","roundedX1","roundedX2","minIndexLimit","maxIndexLimit","volMinIndex","volMaxIndex","volumeSum","volumeIndex","numberToStringWithUnitsSuffix","fillRect","priceDif","heightStr","getRoundedString","number","numOfDecimalPlaces","baseX","baseY","getHeight","addToCoordinates","difs","newX1","newX2","paneArea","getEdgeIntersectionPoint","sides","rayOrigin","rayDirection","intersection","intersectionDistance","rayToLineIntersection","getRayToLineSegmentIntersection","getPitchforkCoordinates","rayDirectionControlPoint1","rayDirectionControlPoint2","trend1","trend2","chartVisibleAreaLeftX","chartVisibleAreaRightX","chartVisibleAreaBottomY","chartVisibleAreaTopLeftPoint","chartVisibleAreaTopRightPoint","chartVisibleAreaBottomLeftPoint","chartVisibleAreaBottomRightPoint","getChartVisibleAreaBoundaries","medianRay","trend1Ray1","trend2Ray1","trend1Ray2","trend2Ray2","medianRayDirectionPoint","getMiddlePointOnLineSegment","rayOriginToRayDirectionVector","rayDirectionControlPoint1ToPoint2Vector","normalizedRayDirectionControlPoint1ToPoint2Vector","normalizeVector","medianRayDirectionPointToRayDirectionControlPoint1Distance","trend1Ray","getTrendRayCoordinates","medianToControlPointDistance","normalizedControlToControlPointVector","trendRay1","trendRay2","trend2Ray","medianToTrendLineDistance","trendRayPoint1Origin","addPoints","multiplyVectorByScalar","trendPoint2RayOriginPoint2","subtractPoints","trendRayPoint1DirectionPoint","trendPoint2RayDirectionPoint","median","trendLines","line1","line2","trendLine","trendLineIndex","solidTrendColor","getHEXWithSpecificAplha","nextTrendLine","outerTrendLines","isPolygon","scaledPoints","xPoint","yPoint","targetY","stopY","centerY","stopBaseline","targetBaseline","targetColor","stopColor","targetDif","targetPerc","targetStr","stopDif","stopPerc","stopStr","middle1","roundDif","coordType","coordIndex","strokeRect","RotatedRectangleV1","newMiddleLeftPoint","middleLeftRotatedCursorPoint","newMiddleRightPoint","middleRightRotatedCursorPoint","XXXS","XXS","textBoxX","textBoxY","textBoxWidth","textBoxHeight","alphabetic","getMergedPropsWithDefaults","propKey","MIN_SAFE_INTEGER","testArea","convertArea","rawHight","borderWidth","borderColor","thumbWidth","getThumbWidth","XABCD","xx","xy","ax","ay","bx","by","retLabel","len","ret","xab","bcd","result1","rendered","cWidth","cHeight","sWidth","screen","sHeight","OHLCType","ChartMinWidthBreakpoints","getChartBreakpoints","chartWidthInPx","isXs","xs","isS","isM","isL","getDateString","dateString","month","year","day","getDate","MONTHS","getClosestDifferentMinMaxValueIndices","currentMinIndex","currentMaxIndex","low","hasPreviousIndex","hasNextIndex","minIndex","maxIndex","gray300","tailwindColors","BaseChart","tickerWidth","changeWidth","lastOhlc","isLargeChart","shouldRenderVolume","afterChange","overlayDefinition","addOverlay","renderYAxis","setupCache","renderOverlaysLabels","handleIndicatorsChange","mouseModelChangeHandler","mouseModel","baseCache","updateShouldRenderVolume","renderChart","renderChartNotAvailable","getIsRedesignedChart","renderTicker","clip","renderVolume","renderOverlays","renderPrevClose","renderFadeExtendedHours","renderGrid","renderXAxis","tickerText","margin","FONT_SIZE","OFFSET","baseline","renderTimeframe","volumeFY","range","Group","getTimeframeLabel","textSecondary","isOurSiteRequest","L","offScreen","XS","M","renderChange","getOHLC","directRender","changePercentage","lastDate","renderOHLC","isSmallIndexChart","isNewestOHLC","afterHour","isFinite","roundOhlc","lastVolume","toLocaleTimeString","hour","minute","getRoundedLastData","lastOpen","lastHigh","lastLow","renderOverlaysLabelsChartsPage","renderOverlaysLabelsQuotePage","overlayLabel","isRenderedOverlaysLabel","labelSpacing","getLabelColor","getYAxisLeftMargin","getYAxisLastCloseLabel","firstVisibleClose","getPercentageFromValue","base","lineTicks","textTicks","lastCloseLabel","getTranslate","do","tickCount","minMax","placesAxis","stepPrice","minPerc","maxPerc","d3","nice","ticks","tick","getValueFromPercentage","pixelGap","negativeScale","previousNegativeTick","positiveScale","previousTick","positiveScaleY","getYLineText","yTickText","axis","yTickLine","getYLine","resetYTicksStyles","percentageZeroLineText","undo","renderYAxisLabel","yCoordinate","getSecondaryLabelBackgroundColor","stringifyHSVAColor","currentBackground","getYAxisSecondaryLabelYCoordinate","mainLabelValue","secondaryLabelValue","LINE_HEIGHT","mainLabelValuePosition","secondaryLabelValuePosition","offsetedY","currentText","getDrawDays","MarketSentiment","textRenderer","startBarIndex","getFirstBarToRenderIndex","endBarIndex","getLastBarToRenderIndex","chartWidth","render15MinXAxis","renderIntradayXAxis","renderIntradayXAxisFutures","renderDailyXAxis","renderWeeklyXAxis","renderMonthlyXAxis","isXPointVisible","renderXAxisLabels","_ref9","labels","allowedOverflow","sortedLabels","renderedLabelRanges","reverse","newLabel","hasPriority","_ref10","halfOfTextWidth","overflowLeft","overflowRight","labelX","getIsOverlapping","IntradayTimeframeInterval","marketStartHour","marketStartMinutes","marketEndHour","aftermarketLengthMinutes","xLine","getXLine","dayToOffset","getDayToOffset","dayIndex","dateFromDateString","drawMinutesPerDay","roundedX","premarketLengthMinutes","_ref11","lastDay","lastHours","_ref12","indexOffset","getBarsInDay","_ref13","lastMonth","_ref14","gridSecondary","isYearLabel","substring","_ref15","lastYear","isJanuary","Vol","getVolumeTicks","fontHeight","renderVolumeAxis","relativeVolume","grid","rangeMax","volumeAxisFontSize","volumeAxis","format","tickFormat","domainFrom","domainTo","setupAxisTimeFrame","halfBarWidth","getHalfBarWidth","barWidthWithoutMargin","getBarWithoutMarginWidth","drawInVisibleArea","drawBarCallback","volumeTrendDown","volumeTrendUp","isRendered","contentWidth","contentHeight","getRoundDecimalPlaces","price","getPlacesLastClose","onRenderCrossText","getCrossIndexForPane","conditionalCursor","getDataByCrossIndex","crossIndex","shouldReturnRoundedString","getDataByBarIndex","getCrossIndexChange","crossDataIndex","getDataIndexByBarIndex","crossClose","previousClose","getTickerChangeFromCloseValues","anchorClose","dateByBarIndex","virtualTradedDates","getVirtualTimeframeTradedDates","dateStart","dateEnd","_ref16","change","isOffscreen","isGroupInstrument","finvizWatermarkOffset","changeText","percentString","getChangeColor","afterChangeText","afterChangeTextWidth","oneLineAHChangeWidth","renderOHLCChartsPage","renderOHLCQuotePage","_ref17","chartBreakpoints","OhlcText","canvasFill","dateElements","trendColor","oElements","hElements","lElements","cElements","volElements","changeElements","getFlatLineArrayWithSpaces","lineElements","startX","lineElement","LabelsText","numberOfNewOhlcLines","_ref18","dateOnly","timeOnly","lineTopY","OHLCFontSize","centerXOffset","leftXOffset","OHLC","ohlcString","singleLine","OHLC_TEXT","getOHLCType","ohlcSettings","getOHLCSettings","CHART_MARGIN","XXL","alignTop","renderOHLCToCanvas","_ref19","ohlcSet","isSingleLineWithChange","n0","n1","x0","premarketFade","aftermarketFade","shouldShowPrevClose","isIntradayWithPreMarket","TIMEFRAMES_WITH_PRE_MARKET","isIndexChart","Cache","getIsMobileChartPage","setupAxis","volumeHeight","volumes","addMarginBottom","marginBottom","setOverlays","removeOverlay","MAX_VALUE","MIN_VALUE","firstBarToRenderIndex","compensateBarGap","lastBarToRenderIndex","isBarGap","firstIndexNormalized","closestMinMaxIndices","placesLastClose","barFillWidth","barBorderWidth","getBarWidthWithMarginByParts","priceAbs","getCandleLikeChartsRenderingColors","overwrittenColors","getColorOverwrites","overwrittenColorKeys","hasOverwrittenCandleColor","colorKey","getShouldUseDarkerWickColors","totalBarWidth","darkerWickColors","thinBarColorsOverride","getRenderChartBarProps","chartSettingsColors","hasFillAndBorder","trendDown","trendUp","borderDown","borderUp","wickDown","wickUp","wickColor","barFillColor","shouldRenderFillAndBorder","translateForWick","WICK_WIDTH","candleBodyHigh","candleBodyLow","candleWickHigh","candleWickLow","candleBodyHeight","candleBodyLeftX","halfBorderWidth","getIsSSr","isBodyHeightGreaterOrEqualBorders","isWickLineCandleLessThanOnePixel","hasBorder","fillHeight","hasFill","isHollow","generalTrendColor","ohlcTrendUp","ohlcTrendDown","zeroChange","haData","getHeikinAshiData","getLastValues","originalLatestClose","heikinLatestCloseLabel","originalLatestCloseLabel","redLine","greenLine","MarketSentimentSettings","_data","lastIndex","_dataLastIndex","renderLineBullBear","oversold","overbought","isRedesign","marketDown","marketUp","_compute","computeVisibleMinMax","yLine","fillUp","fillDown","percent","MultiLineChart","tickersDimensions","ColorsSettings","getQuotes","asc","maxTickerLength","isLastDate","closeValue","arrays","OHLCChart","barWithoutMarginWidth","lineThickness","handleLengthFromWick","lineOffset","barX","overlayLabelWidth","perf","shouldRenderDate","tickerData","MARGIN","percentageText","lastCrossIndex","filteredQuotes","closes","daysCount","end1","asc1","end2","asc2","monthsInData","availableTickSpots","monthsToAvail","renderMonth","candleStick","heikinAshi","hollowCandleStick","lineChart","marketSentiment","multiLineCharts","ohlcChart","XXXL","XL","SETTINGS_HEIGHT","TICKER_TIMEFRAME_CHANGE_HEIGHT","OverlayType","ChartEventDbType","DESC","TIMEFRAME_SECONDS","CRYPTOS","BTCUSD","LTCUSD","ETHUSD","XRPUSD","BCHUSD","BTCEUR","LTCEUR","ETHEUR","XRPEUR","BCHEUR","LTCBTC","ETHBTC","XRPBTC","BCHBTC","ScaleLabel","INDICATOR_LABEL_HEIGHT","FREE_DATE_RANGES","curr","PREMARKET_AFTERMARKET_HOURS","setIsFetching","dateFromUnixTimestamp","getTimeframeGroupsWithHref","timeFrame","dateRangeState","getVisibleBarsNumber","getChartStartEndDates","unwatchedChartLayoutModel","hasSyncedTimeframe","ChartSyncablePart","Timeframe","hasSyncedTicker","urlTimeframes","urlDateRanges","chartsArrayPlaceholder","currentTicker","currentTimeframe","currentDaterange","sidebar","timeFrameGroup","QuoteUrlChartTypes","useChartLayoutGlobalModelAsyncModule","startInSec","endInSec","lastQuoteDateIndex","lastVisibleBarIndex","firstVisibleBarIndex","quoteDate","isQuoteDateInRange","numOfBarsOffset","getChartZoomAndLeftOffset","numOfBarsToRender","numberOfBarsToDraw","daysInQuote","getDaysInQuote","convertLocalToNyTime","setHours","startDateIndex","numOfBarsInView","getIntradayChartConfig","timeframeMinutes","barWidthWithMargin","hasPremarket","hasAftermarket","fullChartWidth","marketMinutesLength","getFullChartWidth","offsetInPx","shouldCropChart","chartWidthWithOffset","offsetChartAfter","shouldAlignDaysToLeft","drawDaysInOneChart","lastQuoteDate","barsToOffset","offsetChartInPx","isStockIntraday","isQuoteOrOffscreen","isChartsInradayDateRange","getShouldOffsetChartDomain","scaleType","handleDomainOffset","currentScale","scaleCreator","protectedHeightPx","minPx","extendedMin","rounded","fromEntries","parsedRange","startQuoteDate","endQuoteDate","numOfDaysToRender","reversedDaysInQuote","startQuoteDayIndex","endQuoteDayIndex","renderDateStart","renderDateEnd","getParsedDateRangeMetaData","shouldRenderCross","DEFAULT_CONTEXT","getInstrumentLabel","getResponseChartType","chartType","chartResponseType","tr","BigNumber","BIG_NUMBER_VALUES","Thousand","Million","Billion","Trillion","BIG_NUMBER_ZEROES","BIG_NUMBER_SUFFIX","dotProduct","crossProduct","pow","lineEquation","j","oddNodes","l2","formatBigNumber","minNumber","absNum","getString","suffix","zeroes","splitString","addZeroes","padEnd","numberByZeroesCount","isInteger","yAxisCoeficient","xAxisCoeficient","radAngle","p3","p4","denominator","ua","ub","checkLineIntersection","line1_p1","line1_p2","line2_p1","line2_p2","onLine1","onLine2","numerator1","numerator2","rayEnd","segmentStart","segmentEnd","lineIntersection","scalar","isSamePoint","ExponentialMovingAverage","multiplier","EMACalculation","MainCalculation","Ema","getDefaultCalculatedValues","ema","calculate","onValueCalculated","_calculatedValues","calculatedValues","getAllCalculatedValues","lastNItems","getCalculatedValues","getDbColumnName","key1","key2","localeCompare","MAX_POSITIVE_DEFAULT_VALUE","MAX_NEGATIVE_DEFAULT_VALUE","periodInt","getParsedIntegersFromPeriodString","labelWidth","lastValue","shouldUpdate","compute","renderIndicator","getIsChartPageSpecificFunctionality","renderLabel","isComputeNecessary","tickTextStep","formatAxis","valueY","indicatorCurrentText","indicatorCurrentBackground","renderLabelChartsPage","renderLabelQuotePage","indicatorLabel","roundedRect","isPerfIndicator","renderCrossTextChartsPage","renderCrossTextQuotePage","renderOversoldOverbought","zero","drawLines","drawInVisibleAreaProps","fromIndexOffset","getCompensatedFirstBarToRenderIndex","clipHeight","renderZeroLine","tickStep","parsePeriodInt","setModel","getDomainDefaults","inputsErrorMessages","Rvol","Atr","Adx","Aro","Mfi","Rmi","Rsi","Stofu","Ult","Macd","Rwi","Trix","Wr","Aroosc","Roc","Cci","Fi","INDICATOR_DEFAULT_DOMAIN","getIsValid","getIsNumberInputValid","integerOnly","isPositiveInteger","ADX","pdi","mdi","adx","amdm","apdm","atr","deltaHigh","deltaLow","pdm","mdm","di","AroonCalculation","aroonUp","aroonDown","oscillator","highPeriod","highestInPeriod","periodSinceHigh","lastIndexOf","lowPeriod","lowestInPeriod","periodSinceLow","COLORS","Aroon","aroonCalculation","textLabels","labelSetting","AroonOscillator","ATR","AverageTrueRange","CommodityChannelIndex","cci","smaCount","tp","smaSum","devCount","typicalPrice","sma","devSum","dev","COT","cotQuoteCode","cot","commercialHedgers","largeTraders","smallTraders","units","renderAdditionalLabels","secondarylabelX","fontSettings","secondarylabel","FICalculation","fi","ForceIndex","fiCalculation","MACDCalculation","macd","histogram","fastPeriod","slowPeriod","signalPeriod","emaFast","emaSlow","emaSignal","MACD","macdCalculation","signalLine","MFI","mfi","negativeMoneyFlow","mf","prevTypicalPrice","positiveMoneyFlow","moneyFlow","oldMF","OBV","Obv","obv","currentObv","PricePerformance","firstFetchCalled","indicatorLabelWidth","getTickers","chartUuid","hasCachedData","getTickersAndTimeframe","getAll","firstBarTime","lastBarTime","dateToIndex","getDateToIndex","perfArrays","crossIndexTickerTimeStamp","tickerDateToIndex","tickerPerformance","performanceIndicatorLabel","isVertical","labelBottom","canFitItemsVertically","tickerQuote","maxCrossIndex","tickerTextWidth","crossText","getSanitizedTicker","RMI","rmi","momentum","u","ad","au","sumu","sumd","rs","ROC","roc","RsiCalculation","rsi","RSI","rsiCalculation","DEFAULT_PARAMETERS","RelativeVolume","rvol","baseLine","periodStr","parsePeriod","baseLineY","RWI","rwiHi","rwiLo","trSum","atrWeight","maxHi","maxLo","Stochastics","k1","kPeriod","dPeriod","dCount","dSum","kSum","kCount","highestHigh","lowestLow","StochasticsFast","Stofa","StochasticsSlow","Stosl","TrixCalculation","trix","ema1","ema2","ema3","trixCalculation","UltimateOscillator","period1","period2","period3","ult","bp","bpSum2","bpSum3","count2","count3","trSum2","trSum3","avg2","avg3","bpSum1","trSum1","count1","avg1","Volume","WilliamsR","aro","aroosc","rwi","stofa","stofu","stosl","vol","wr","getWatchedPropValue","watchedProp","spineObject","getIsSpineObject","hasToObject","getJSONReplacerFunc","getWatchedProps","getAreWatchedPropsEqual","currentValue","previousValue","DEFAULT_SPINE_EVENTS","DefaultSpineEvents","stringifiedOptions","useForceUpdate","watchedPropertiesRef","handleModelChange","spineEvents","Crosshair","normalizeHexAlpha","customColors","customColorKeys","defaultColors","chartLightTheme","chartDarkTheme","crossTextBackground","negativeChange","overlayTransparentBackground","positiveChange","indicatorLightTheme","indicatorDarkTheme","elementLightTheme","elementDarkTheme","generalColors","generateUuid","getElementZIndexRange","oldInstance","pane_id","clonedObj","cloned","moveToZIndex","currentZIndex","directionCoef","newZIndex","elementsBelowZero","elementsAboveZero","getBelowAboveZeroElements","changeElementZIndexes","elementsArray","addElement","oldZIndex","isBelowZero","isOverlay","refreshElementId","MARKET_START","END_OF_DAY","roundTimeForSyncedPane","sourceChart","targetChart","dateToReturn","sourceChartHasPremarket","targetChartHasPremarket","setDate","lastDayOfMonth","lastDayOfWeek","weekStartsOn","endOfDay","getIsDateBeforeMarketStart","getIsCrossSyncOn","getIsMouseInChartOfPane","paneOfMouse","mouseInChart","currentPaneChart","mousePositionTimestamp","currentPanePositionX","getPriceForPane","mousePaneIndex","getIndexInChart","mouse","CHART_EVENT_BADGE_TYPE_ORDER","chartEventElementModel","move","chartPanes","targetPane","currentChartPaneRecords","records","chart_id","ohterChartPaneRecords","targetRecordIndex","arrayWithoutTargetRecord","chartRecordIndex","panesAbove","panesBelow","getNumericId","isSorted","resetHeight","allPaneElements","rebuildElementZIndexes","hoveredChartEvent","openedChartEvent","hoveredTypeChartEventElements","openedTypeChartEventElements","nonActiveChartEventElements","chartEventsOnSameXPoint","chartEvent_B","isOpened","isHoveredType","isOpenType","quoteCache","getCachedQuote","cachedAt","setCachedQuote","emptyQuote","numberOfRefreshChecks","is404","patternsMinRange","patternsMaxRange","dataId","tickerRaw","shouldUseCache","doesQuoteAndFetchParamsMatch","isSameOrNoChartUuid","isNotEmptyQuote","isCacheAllowed","hasPatterns","doesQuoteAndOptionsMatch","getResolvedFetchingPromise","maxBars","tickersAndTimeframes","accumulator","fetchRequest","QuoteFetchTypeUrlOption","New","fetchingPromise","getUrl","getIsAbortError","NotFoundError","shouldUseEmptyQuote","Newer","noNewData","newQuoteData","lastTime","afterTime","AIndex","BIndex","mergeIndex","ADate","BDate","prevAIndex","prevDate","newDate","isSameWeek","isSameMonth","thisDateLength","dataDateLength","atts","drawDays","getBarIndexes","barToDataIndex","getChartEventsWithId","deleteCachedQuote","cachedHeikinAshiData","HAClose","heikAshiData","cachedDayToOffset","dateStringFromDate","yyyy","mm","dd","dataIndex","cachedDateToIndex","getTimestampFromPositionX","host","env","BE_API_URL","rev","clearData","largeChartFontSize","INTERACTIVE_CHART_SETTINGS","tickerTimeframeChangeHeight","chartSettings","colorsOverride","settingColors","isLight","getNormalizedZIndex","BbCalculation","Bb","stdDev","upperBand","lowerBand","deviations","stdDevSum","getFreeColor","periods","getRGBAValueFromValidColorString","BB_COLORS","TOP","BOTTOM","MIDDLE","BollingerBands","scaledTop","scaledBottom","firstBarToRender","lastBarToRender","bbCalculation","topColor","bottomColor","DonchianChannels","Dch","medianBand","strokeColor","channelStrokeColor","fillColor","channelFillColor","medianBandColor","EMA","EMA2","Ema2","HighLow","Hilo","highColor","prevHigh","lowColor","prevLow","prevBar","Hline","isPositiveFloat","Stroke","Fill","Conversion","Base","SpanB","conversion","spanB","IchimokuCloud","Ic","renderFull","outsideBar","spanAFillColor","spanAStrokeColor","spanBFillColor","spanBStrokeColor","baseLineColor","conversionLineColor","laggingSpanColor","conversionLine","senkouSpanA","senkouSpanB","conversionStartIndex","baseStartIndex","spanBIndex","highestHi","lowestLo","lastSpanAX","lastSpanBX","cloudStartingX","fxOverride","toIndexOffset","IchimokuCloudFull","Icf","KeltnerChannel","Kch","emaPeriod","atrPeriod","middleLine","Patterns","originalScale","barsInDay","aboveBelow","textHS","above","below","supportColor","resistColor","Calculation","PivotPeriod","PivotPoints","Pp","calculationType","getPeriodType","week","getIsEnoughData","startIndex","endIndex","periodType","dayGap","startDay","beforeDay","calculatedX","fromX","toX","currentDate","previousTradingDay","previousNYMidnightTimestamp","currentMidnight","currentNYMidnightTimestamp","isNonStockFullDay","isStockFullDay","firstDayCurrentWeek","firstDayCurrentWeekTimestamp","firstDayPreviousWeek","firstDayPreviousWeekTimestamp","firstDayCurrentMonth","firstDayCurrentMonthTimestamp","firstDayPreviousMonth","firstDayPreviousMonthTimestamp","firstDayCurrentYear","firstDayCurrentYearTimestamp","firstDayPreviousYear","firstDayPreviousYearTimestamp","pivot","sup1","sup2","sup3","res1","res2","res3","previousHigh","previousLow","pivotPoint","currentX","toBars","nextDate","SAR","Sar","maxStep","isLong","sar","ep","newHigh","newLow","af","sarToDraw","risingColor","fallingColor","customizable","SMACalculation","Sma","SMA","SMA2","Sma2","Supertrend","Str","finalUpperBand","finalLowerBand","supertrend","uptrendColor","avg","downtrendColor","VP_COLORS","applyOpacityToColor","VolumeProfile","Vp","upColor","downColor","minClose","maxClose","segment","segments","up","down","segmentIndex","isInSegment","volumeTrend","volumeFX","segmentHeightRaw","segmentHeight","upSegmentWidth","downSegmentWidth","VWapCalculation","Vwap","vwap","cumulativePV","cumulativeVolume","second","datesAreOnSameDay","VWAP","bb","dch","hilo","hline","ic","icf","kch","pp","sma2","vp","arg","_len2","_key2","_len3","_key3","devicePixelRatio","getQuoteDateTimestampOffsetInSeconds","referenceDate","dayNumber","monthIndex","previousSunday","getDay","getIsDstInNy","getUTCFullYear","getUTCMonth","getUTCDate","getUTCHours","getUTCMinutes","getUTCSeconds","addOffset","quoteDateTimeOffsetInMs","localTimeOffsetInMs","getTimezoneOffset","offsetDirectionCoefficient","setTime","bufferMinutes","dayOfWeek","currentDayMinutes","premarketMinutes","aftermarketMinutes","isWeekend","isClosed","setUTCSeconds","testTouchPoints","isMobileOs","navigator","userAgent","createEvent","match","msMaxTouchPoints","maxTouchPoints","matchesIPad","matchesIPhone","matchesIPod","re","RegExp","cookie","toUTCString","fullscreenElement","webkitFullscreenElement","mozFullScreenElement","msFullscreenElement","webkitRequestFullScreen","mozRequestFullScreen","msRequestFullscreen","webkitExitFullscreen","mozExitFullScreen","msExitFullscreen","fn","readyState","chartElementId","box","matchingPages","requestsAbortControllersCache","abortRequest","websiteShared","shouldUseCPUOnly","matchesAndroid","matchesWebOS","matchesiPad","matchesBlackBerry","matchesWindowsPhone","matchesIOSLike","isFirefoxDesktop","getContext","willReadFrequently","_cache","_restore","CanvasRenderingContext2D","getChartEventBadgeColors","outerStroke","innerStroke","innerFill","textFill","getFormattedEventDate","exdate","hasEarningsDateSuffix","parsedDate","formattedDate","getFormattedValue","bigNumberUnit","maxDecimalPlaces","numberString","bigNumber","wholeNumber","decimalNumber","formattedDecimalNumber","getChartEventBageColors","twColors","DAY_IN_SECONDS","TWO_MIN_IN_MS","virtualDatesCache","areTimestampsFromSameDay","ts1","ts2","ts1Utc","ts2Utc","getVirtualDatesCacheId","idRevision","setCachedVirtualDates","fromSeconds","toSeconds","virtualDates","virtualDatesCacheId","lastUsed","checkVirtualCacheSize","MAX_BAR_BORDER_WIDTH","MIN_BAR_MARGIN_WIDTH","MAX_BAR_MARGIN_WIDTH","settingsCenter","barMarginWidth","shouldRound","roundDecimalPlaces","DEFAULT_ZOOM_GUESS_INCREMENT","zoomFactorForBarsToDisplayCache","zoomFactorForBarsToDisplayCacheKeys","getZoomFactorFromCache","setZoomFactorToCache","poppedKey","defaultBarWidthWithMargin","zoomIncrement","finalZoomFactor","iteration","barWidthDiff","getTimeframeSeconds","lowerIndex","dates","upperIndex","isWithinRangeOfQuoteDate","commonVirtualCacheProps","cachedDates","virtualDateSeconds","getCachedVirtualDates","timeframeSeconds","firstDate","numOfDatesBefore","numOfDatesAfter","virtualTradedDays","dateStartSeconds","dateEndSeconds","datesSeconds","isStartBeforeDates","isEndAfterDates","dateTime","getVirtualTradedDays","marketStartSeconds","barTimeframeSeconds","quoteDatesTimestampOffset","dayStartSeconds","barSeconds","virtualTimeframeTradedDates","isLowerBounded","isOneBeforeLowerBoundStarts","lastDateIndex","isLookingBack","averageBarDate","numOfSecondsOutOfBounds","perfIndicatorElement","getPerfIndicatorTickerAndTimeframes","resolve","isXAxisInView","domainRange","priceFy","YAxisLeftMargin","firstBarClose","_ref20","changePercent","changePercentString","_ref21","isForexFuturesCryptoPage","_ref22","isForexFuturesCrypto","isOffscreenChartWithNarrowBars","isQuoteChartWithNarrowBars","_ref23","allowAlpha","calculatedIndex","object","formData","append","FormData","statusCode","throwOnPredicate","credentials","responseContentType","Html","responseData","ApplicationJsonUTF","FormUrlEncoded","parseResponseForContentType","status","getStatusCodeError","forceUpdateKey","increment","precision","periodString","part","parsedNumber","visited","WeakSet","toLocaleDateString","crypto","randomUUID","getRandomValues","Uint8Array","useChartLayoutGlobalModelModule","useChartLayoutGlobalModel"],"sourceRoot":""}