openalgo-charts 1.0.16 → 1.0.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /** Library version string. Matches package.json (published npm release). */
2
- declare const VERSION = "1.0.16";
2
+ declare const VERSION = "1.0.18";
3
3
  /** Returns the current library version. */
4
4
  declare function version(): string;
5
5
 
@@ -828,6 +828,7 @@ declare function plotStyleKeys(plot: IndicatorPlot): {
828
828
  width: string;
829
829
  lineStyle: string;
830
830
  opacity: string;
831
+ type: string;
831
832
  };
832
833
  /**
833
834
  * Per-plot appearance inputs, generated from the descriptor rather than
@@ -846,6 +847,20 @@ declare const INDICATOR_SOURCES: readonly {
846
847
  }[];
847
848
  type IndicatorSettings = Record<string, unknown>;
848
849
  /** One plotted line/band/histogram. `type` is any registered chart type. */
850
+ /** A shaded band between two of an indicator's plots. */
851
+ interface IndicatorFillSpec {
852
+ /** The two plot keys to fill between. */
853
+ between: readonly [string, string];
854
+ /** Colour where the first plot is above the second. */
855
+ colorUp?: string;
856
+ /** Colour where the second is above the first. */
857
+ colorDown?: string;
858
+ /** Settings keys holding those colours, so the band is restyleable. */
859
+ colorUpKey?: string;
860
+ colorDownKey?: string;
861
+ /** 0..1. Defaults to 0.12. */
862
+ opacity?: number;
863
+ }
849
864
  interface IndicatorPlot {
850
865
  /** Key into the `calc` result. */
851
866
  key: string;
@@ -896,6 +911,13 @@ interface IndicatorDescriptor {
896
911
  placement: 'onchart' | 'pane';
897
912
  inputs: readonly IndicatorInput[];
898
913
  plots: readonly IndicatorPlot[];
914
+ /**
915
+ * Shaded bands between pairs of plots — the Ichimoku cloud, a Bollinger
916
+ * channel. A pair of lines is not the same picture as a filled region: the
917
+ * fill is what makes "price is above the cloud" readable at a glance, and
918
+ * which side leads is itself the signal, hence the two colours.
919
+ */
920
+ fills?: readonly IndicatorFillSpec[];
899
921
  /**
900
922
  * Full recompute over every bar. Must return arrays the same length as
901
923
  * `bars` (use `null` for warmup gaps — the line renderer breaks across them
@@ -1105,6 +1127,51 @@ declare class PaneLegend implements IPrimitive {
1105
1127
  hitTest(x: number, y: number): PrimitiveHit | null;
1106
1128
  }
1107
1129
 
1130
+ /**
1131
+ * Shaded band between two indicator plots — the Ichimoku cloud, a Bollinger
1132
+ * channel, a Keltner envelope.
1133
+ *
1134
+ * A pair of lines is not the same picture as a filled region: the fill is what
1135
+ * makes "price is above the cloud" or "the cloud flipped" readable at a glance,
1136
+ * and which side is on top is itself the signal. So the band is drawn as two
1137
+ * runs — one where A leads, one where B does — and the crossings between them
1138
+ * are split at the exact intersection rather than at the nearest bar, or the
1139
+ * colours would bleed a bar past every flip.
1140
+ */
1141
+
1142
+ interface IndicatorFillOptions {
1143
+ /** Fill colour where the first series is above the second. */
1144
+ colorUp: string;
1145
+ /** Fill colour where the second is above the first. */
1146
+ colorDown: string;
1147
+ /** 0..1. Defaults to 0.12 — a band must not drown the candles it sits behind. */
1148
+ opacity?: number;
1149
+ }
1150
+ /** One bar's pair of values; `null` where either plot has no value yet. */
1151
+ interface FillPoint {
1152
+ /** Logical index on the shared time axis (fractional is fine). */
1153
+ index: number;
1154
+ a: number | null;
1155
+ b: number | null;
1156
+ }
1157
+ declare class IndicatorFill implements IPrimitive {
1158
+ private _points;
1159
+ private _opts;
1160
+ private _host;
1161
+ private _visible;
1162
+ constructor(options: IndicatorFillOptions);
1163
+ attached(host: PrimitiveHost): void;
1164
+ detached(): void;
1165
+ /** Behind the series, so the lines and candles stay crisp on top of it. */
1166
+ zOrder(): ZOrder;
1167
+ /** The plots it spans already drive the scale; the fill must not widen it. */
1168
+ autoscaleInfo(): null;
1169
+ setPoints(points: readonly FillPoint[]): void;
1170
+ setOptions(patch: Partial<IndicatorFillOptions>): void;
1171
+ setVisible(on: boolean): void;
1172
+ draw(ctx: CanvasRenderingContext2D, rc: PrimitiveRenderContext): void;
1173
+ }
1174
+
1108
1175
  /**
1109
1176
  * Indicator runtime (ARCHITECTURE.md §8). Turns an `IndicatorDescriptor` into
1110
1177
  * live chart objects: one series per plot, optional reference levels, an
@@ -1132,6 +1199,9 @@ interface IndicatorHost {
1132
1199
  addIndicatorSeries(type: string, paneIndex: number, style: Record<string, unknown> | undefined, priceScaleId: string | undefined): SeriesApi;
1133
1200
  addIndicatorLevel(price: number, color: string, dashed: boolean, label: string, id: string, paneIndex: number): PriceLine;
1134
1201
  removeIndicatorLevel(line: PriceLine): void;
1202
+ /** Attach a band drawn behind the plots (an Ichimoku cloud). */
1203
+ addIndicatorFill(fill: IndicatorFill, paneIndex: number): void;
1204
+ removeIndicatorFill(fill: IndicatorFill): void;
1135
1205
  /** Bars of the primary price series — the calculation input. */
1136
1206
  sourceBars(): readonly Bar[];
1137
1207
  /** Index of a fresh pane for an indicator that wants its own. */
@@ -3115,4 +3185,4 @@ declare function lerp(a: number, b: number, t: number): number;
3115
3185
  */
3116
3186
  declare function roundToTick(value: number, step: number): number;
3117
3187
 
3118
- export { ALT_PRESET, type AddSeriesOptions, type AggTick, BUILTIN_COMMANDS, type Bar, type BarUpdate, type BarsRequest, BuySellButtons, type BuySellButtonsOptions, CHART_STATE_VERSION, CandleBuilder, type CandleBuilderOptions, type CandleStyle, type CandleUpdate, Chart, type ChartEvent, type ChartOptions, type ChartState, type ChartTheme, type CrosshairMoveEvent, type CustomShortcut, DEFAULT_CANDLE_BUILDER_OPTIONS, DEFAULT_CANDLE_STYLE, DEFAULT_HISTOGRAM_STYLE, DEFAULT_KEYMAP, DEFAULT_PRICE_SCALE_OPTIONS, DEFAULT_THEME, DEFAULT_TIME_NAVIGATOR_OPTIONS, DEFAULT_TIME_SCALE_OPTIONS, DEFAULT_TRADING_COLORS, type DataFeed, DataLayer, type DepthLevel, type DrawItem, EventMarkers, FakeDataFeed, type FeedScheduler, type HistogramStyle, INDICATOR_LINE_STYLES, INDICATOR_SOURCES, type IPrimitive, IST_OFFSET_SECONDS, type IndexedBar, type IndicatorApi, type IndicatorAttachContext, type IndicatorDescriptor, type IndicatorHost, type IndicatorInput, type IndicatorLevel, type IndicatorPlot, type IndicatorSettings, type IndicatorSource, type IndicatorState, type IndicatorStore, type IndicatorValues, InvalidationLevel, type KeymapEntry, type LateTickPolicy, type LegendValue, type LinePoint, type LogicalRange, LogoWatermark, type LogoWatermarkOptions, type LtpEvent, type MarkerPosition, type MarkerShape, type MarkerSize, type MarketDepth, type OpenAlgoConfig, OpenAlgoDataFeed, type OpenAlgoLiveConfig, OpenAlgoLiveDataFeed, type OpenAlgoTradeConfig, OpenAlgoTradeFeed, type OpenAlgoWsConfig, OpenAlgoWsFeed, type OrderSide$1 as OrderSide, type OrderType$1 as OrderType, type OriginalTime, Pane, type PaneInvalidation, PaneLegend, type PaneLegendAction, type PaneLegendOptions, type PaneState, type PlaceOrder, type PositionSide, PriceLine, type PriceLineOptions, type PriceRange, PriceScale, type PriceScaleId, type PriceScaleMode, type PriceScaleOptions, type PriceScaleState, type PrimitiveHit, type PrimitiveHost, type PrimitiveRenderContext, type RendererEntry, type RestoreReport, type SeriesApi, type SeriesDataItem, type SeriesId, type SeriesMarker, SeriesMarkers, type SeriesRenderContext, type SeriesState, type SeriesStyle, type SeriesType, type ShortcutListItem, ShortcutManager, type ShortcutManagerOptions, type ShortcutPreset, type ShortcutScope, type ShortcutTriggerEvent, type Size, type SocketFactory, type SocketLike, type SupertrendPoint, type Tick, TickBarAggregator, type TickMarkType, type TickTimeframe, TimeNavigator, type TimeNavigatorAction, type TimeNavigatorOptions, TimeScale, type TimeScaleOp, type TimeScaleOptions, type TradeFeed, type TradeMarkerVariant, TradeMarkersPrimitive, type TradingColors, TradingController, type TradingHost, type TradingLineStyle, type TradingLineVariant, type TradingOrder, type TradingOrderSide, type TradingOrderType, type TradingPosition, type TradingSettings, type TradingSyncPayload, type TradingTrade, type UTCSeconds, type UnsubscribeFn, VERSION, type VolumeMode, type WatermarkPosition, type Whitespace, type WsControlMessage, type WsMode, type WsState, type ZOrder, atr, autoscaleRange, bestHit, bitmapSize, clamp, compactVolume, conflateBars, conflateItems, conflationGroupSize, createChart, darkTheme, drawShape, effectiveMarkerPx, ema, emaSeries, epochMsToUtcSeconds, eventToCombo, formatCombo, formatIstDate, formatIstTime, formatIstTimeSeconds, formatSubscribe, formatUnsubscribe, generateBars, getChartType, getIndicator, hasIndicator, indicatorDefaults, indicatorStyleInputs, intervalToSeconds, isNewIstDay, isReservedCombo, isValidCombo, isWhitespace, istStringToUtcSeconds, lerp, lightTheme, mapHistoryResponse, mapOrder, mapPosition, markerSizePx, mergeBars, niceTicks, normalizeCombo, optimalBarWidth, parseCombo, parseMessage, plotStyleKeys, precisionForStep, registerChartType, registerIndicator, registeredChartTypes, registeredIndicators, roundToTick, rowTimeToUtcSeconds, rsi, rsiSeries, snapToDevicePixel, sourceValue, sourceValues, supertrend, supertrendSeries, toBar, trueRange, utcSecondsToIstDateString, utcSecondsToIstParts, version, verticalGradient, watermarkRect };
3188
+ export { ALT_PRESET, type AddSeriesOptions, type AggTick, BUILTIN_COMMANDS, type Bar, type BarUpdate, type BarsRequest, BuySellButtons, type BuySellButtonsOptions, CHART_STATE_VERSION, CandleBuilder, type CandleBuilderOptions, type CandleStyle, type CandleUpdate, Chart, type ChartEvent, type ChartOptions, type ChartState, type ChartTheme, type CrosshairMoveEvent, type CustomShortcut, DEFAULT_CANDLE_BUILDER_OPTIONS, DEFAULT_CANDLE_STYLE, DEFAULT_HISTOGRAM_STYLE, DEFAULT_KEYMAP, DEFAULT_PRICE_SCALE_OPTIONS, DEFAULT_THEME, DEFAULT_TIME_NAVIGATOR_OPTIONS, DEFAULT_TIME_SCALE_OPTIONS, DEFAULT_TRADING_COLORS, type DataFeed, DataLayer, type DepthLevel, type DrawItem, EventMarkers, FakeDataFeed, type FeedScheduler, type FillPoint, type HistogramStyle, INDICATOR_LINE_STYLES, INDICATOR_SOURCES, type IPrimitive, IST_OFFSET_SECONDS, type IndexedBar, type IndicatorApi, type IndicatorAttachContext, type IndicatorDescriptor, IndicatorFill, type IndicatorFillOptions, type IndicatorFillSpec, type IndicatorHost, type IndicatorInput, type IndicatorLevel, type IndicatorPlot, type IndicatorSettings, type IndicatorSource, type IndicatorState, type IndicatorStore, type IndicatorValues, InvalidationLevel, type KeymapEntry, type LateTickPolicy, type LegendValue, type LinePoint, type LogicalRange, LogoWatermark, type LogoWatermarkOptions, type LtpEvent, type MarkerPosition, type MarkerShape, type MarkerSize, type MarketDepth, type OpenAlgoConfig, OpenAlgoDataFeed, type OpenAlgoLiveConfig, OpenAlgoLiveDataFeed, type OpenAlgoTradeConfig, OpenAlgoTradeFeed, type OpenAlgoWsConfig, OpenAlgoWsFeed, type OrderSide$1 as OrderSide, type OrderType$1 as OrderType, type OriginalTime, Pane, type PaneInvalidation, PaneLegend, type PaneLegendAction, type PaneLegendOptions, type PaneState, type PlaceOrder, type PositionSide, PriceLine, type PriceLineOptions, type PriceRange, PriceScale, type PriceScaleId, type PriceScaleMode, type PriceScaleOptions, type PriceScaleState, type PrimitiveHit, type PrimitiveHost, type PrimitiveRenderContext, type RendererEntry, type RestoreReport, type SeriesApi, type SeriesDataItem, type SeriesId, type SeriesMarker, SeriesMarkers, type SeriesRenderContext, type SeriesState, type SeriesStyle, type SeriesType, type ShortcutListItem, ShortcutManager, type ShortcutManagerOptions, type ShortcutPreset, type ShortcutScope, type ShortcutTriggerEvent, type Size, type SocketFactory, type SocketLike, type SupertrendPoint, type Tick, TickBarAggregator, type TickMarkType, type TickTimeframe, TimeNavigator, type TimeNavigatorAction, type TimeNavigatorOptions, TimeScale, type TimeScaleOp, type TimeScaleOptions, type TradeFeed, type TradeMarkerVariant, TradeMarkersPrimitive, type TradingColors, TradingController, type TradingHost, type TradingLineStyle, type TradingLineVariant, type TradingOrder, type TradingOrderSide, type TradingOrderType, type TradingPosition, type TradingSettings, type TradingSyncPayload, type TradingTrade, type UTCSeconds, type UnsubscribeFn, VERSION, type VolumeMode, type WatermarkPosition, type Whitespace, type WsControlMessage, type WsMode, type WsState, type ZOrder, atr, autoscaleRange, bestHit, bitmapSize, clamp, compactVolume, conflateBars, conflateItems, conflationGroupSize, createChart, darkTheme, drawShape, effectiveMarkerPx, ema, emaSeries, epochMsToUtcSeconds, eventToCombo, formatCombo, formatIstDate, formatIstTime, formatIstTimeSeconds, formatSubscribe, formatUnsubscribe, generateBars, getChartType, getIndicator, hasIndicator, indicatorDefaults, indicatorStyleInputs, intervalToSeconds, isNewIstDay, isReservedCombo, isValidCombo, isWhitespace, istStringToUtcSeconds, lerp, lightTheme, mapHistoryResponse, mapOrder, mapPosition, markerSizePx, mergeBars, niceTicks, normalizeCombo, optimalBarWidth, parseCombo, parseMessage, plotStyleKeys, precisionForStep, registerChartType, registerIndicator, registeredChartTypes, registeredIndicators, roundToTick, rowTimeToUtcSeconds, rsi, rsiSeries, snapToDevicePixel, sourceValue, sourceValues, supertrend, supertrendSeries, toBar, trueRange, utcSecondsToIstDateString, utcSecondsToIstParts, version, verticalGradient, watermarkRect };
@@ -1,2 +1,2 @@
1
- function t(t,e,i,n){const s=n.x-i.x,o=n.y-i.y,l=s*s+o*o;if(0===l)return Math.hypot(t-i.x,e-i.y);let r=((t-i.x)*s+(e-i.y)*o)/l;return r=r<0?0:r>1?1:r,Math.hypot(t-(i.x+r*s),e-(i.y+r*o))}function e(t,e,i,n){const s=n.x-i.x,o=n.y-i.y,l=Math.hypot(s,o);return 0===l?Math.hypot(t-i.x,e-i.y):Math.abs(o*(t-i.x)-s*(e-i.y))/l}function i(t,e){return Math.abs(t-e)}function n(t,e){return Math.abs(t-e)}function s(e,i,n){let s=1/0;for(let o=1;o<n.length;o++){const l=t(e,i,n[o-1],n[o]);l<s&&(s=l)}return s}function o(t,e){return{x0:Math.min(t.x,e.x),y0:Math.min(t.y,e.y),x1:Math.max(t.x,e.x),y1:Math.max(t.y,e.y)}}function l(e,i,n,s,l){const r=o(n,s);if(e>=r.x0&&e<=r.x1&&i>=r.y0&&i<=r.y1&&l)return 0;const a=[{x:r.x0,y:r.y0},{x:r.x1,y:r.y0},{x:r.x1,y:r.y1},{x:r.x0,y:r.y1}];let c=1/0;for(let n=0;n<4;n++){const s=t(e,i,a[n],a[(n+1)%4]);s<c&&(c=s)}return c}function r(t,e,i,n,s){const l=o(i,n),r=(l.x0+l.x1)/2,a=(l.y0+l.y1)/2,c=Math.max(1e-6,(l.x1-l.x0)/2),h=Math.max(1e-6,(l.y1-l.y0)/2),x=(t-r)/c,d=(e-a)/h,p=Math.hypot(x,d);return s&&p<=1?0:Math.abs(p-1)*Math.min(c,h)}function a(t,e,i,n,s){const o=e.x-t.x;if(0===o)return[t,e];const l=(e.y-t.y)/o;return[n?{x:0,y:t.y+(0-t.x)*l}:t,s?{x:i,y:t.y+(i-t.x)*l}:e]}function c(t){const e=function(t){const e=t.trim();if(e.startsWith("#")){const t=e.slice(1);if(3===t.length||4===t.length){const[e,i,n,s]=[...t].map(t=>parseInt(t+t,16));return[e,i,n].some(Number.isNaN)?null:{r:e,g:i,b:n,a:4===t.length?s/255:1}}if(6===t.length||8===t.length){const e=parseInt(t.slice(0,6),16);if(Number.isNaN(e))return null;const i=8===t.length?parseInt(t.slice(6,8),16)/255:1;return{r:e>>16&255,g:e>>8&255,b:255&e,a:Number.isNaN(i)?1:i}}return null}const i=/^rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)\s*(?:,\s*([\d.]+)\s*)?\)$/i.exec(e);return null===i?null:{r:Number(i[1]),g:Number(i[2]),b:Number(i[3]),a:void 0===i[4]?1:Number(i[4])}}(t);if(null===e)return.5;const i=t=>{const e=t/255;return e<=.03928?e/12.92:Math.pow((e+.055)/1.055,2.4)};return.2126*i(e.r)+.7152*i(e.g)+.0722*i(e.b)}function h(t){return c(t)>.45?"#10131a":"#ffffff"}function x(t,e,i,n,s,o){const l=t.roundRect;"function"==typeof l?l.call(t,e,i,n,s,Math.max(0,Math.min(o,n/2,s/2))):t.rect(e,i,n,s)}const d=new Map;function p(t){d.set(t.id,t)}function y(t){const e=d.get(t);if(void 0===e)throw new Error(`openalgo-charts: unknown drawing tool "${t}"`);return e}function u(t){return d.has(t)}function f(){return Array.from(d.values())}function g(t){const{ctx:e,rc:i,style:n}=t,s=i.dpr;e.strokeStyle=n.color,e.lineWidth=Math.max(1,Math.round(n.lineWidth*s)),e.lineJoin="round",e.lineCap="round",e.setLineDash("dashed"===n.lineStyle?[6*s,4*s]:"dotted"===n.lineStyle?[1*s,3*s]:[])}function m(t){return t.style.fillColor??t.style.color}function b(t,e){if(!0!==t.style.fill)return;const{ctx:i}=t;i.save(),i.globalAlpha=t.style.fillOpacity??.12,i.fillStyle=m(t),e(),i.restore()}function _(t,e,i,n,s){const{ctx:o,rc:l,style:r}=t,a=(r.fontSize??11)*l.dpr;o.save(),o.setLineDash([]),o.font=`${a}px ui-sans-serif, system-ui, sans-serif`,o.textBaseline="middle",o.textAlign="left";const c=o.measureText(e).width;o.globalAlpha=.85,o.fillStyle=l.theme.background,o.fillRect(i-2*l.dpr,n-.75*a,c+4*l.dpr,1.5*a),o.globalAlpha=1,o.fillStyle=s??r.color,o.fillText(e,i,n),o.restore()}function w(t,e,i,n,s,o={}){const{ctx:l,rc:r}=t,a=r.dpr,c=(t.style.fontSize??11)*a;l.save(),l.setLineDash([]),l.globalAlpha=1,l.font=`${c}px ui-sans-serif, system-ui, sans-serif`,l.textBaseline="middle",l.textAlign="left";const d=5*a,p=3*a,y=1.35*c;let u=0;for(const t of e)u=Math.max(u,l.measureText(t).width);const f=u+2*d,g=y*e.length+2*p,m=o.align??"left",b="center"===m?i-f/2:"right"===m?i-f:i,_=o.place??"above",w="above"===_?n-g-4*a:"below"===_?n+4*a:n-g/2;l.beginPath(),x(l,b,w,f,g,3*a),l.fillStyle=s,l.fill(),l.fillStyle=h(s);for(let t=0;t<e.length;t++)l.fillText(e[t],b+d,w+p+y*(t+.5));return l.restore(),g}function M(t,e=0){const[i,n]=Math.abs(t).toFixed(e).split(".");return(t<0?"-":"")+i.replace(/\B(?=(\d{3})+(?!\d))/g,",")+(void 0===n?"":"."+n)}function v(t){const e=new Date(1e3*t),i=t=>String(t).padStart(2,"0");return`${e.getUTCFullYear()}-${i(e.getUTCMonth()+1)}-${i(e.getUTCDate())}`}function T(t){const e=Math.max(0,Math.round(Math.abs(t))),i=Math.floor(e/86400),n=Math.floor(e%86400/3600),s=Math.floor(e%3600/60);return i>0?`${i}d ${n}h`:n>0?`${n}h ${s}m`:`${s}m`}const S="#26a69a",P="#ef5350",L=[0,.236,.382,.5,.618,.786,1];function k(i,n,s,o){return{id:i,name:n,points:2,defaultStyle:{extendLeft:s,extendRight:o},draw:t=>{const[e,i]=a(t.pts[0],t.pts[1],t.rc.plotWidth*t.rc.dpr,t.style.extendLeft??s,t.style.extendRight??o);g(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.lineTo(i.x,i.y),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(i,n,l)=>{const r=l.drawing.style.extendLeft??s,c=l.drawing.style.extendRight??o;if(r&&c)return e(i,n,l.pts[0],l.pts[1]);const[h,x]=a(l.pts[0],l.pts[1],l.rc.plotWidth,r,c);return t(i,n,h,x)}}}const D=k("trend-line","Trend Line",!1,!1),$=k("ray","Ray",!1,!0),O=k("extended-line","Extended Line",!0,!0),F={id:"arrow",name:"Arrow",points:2,draw:t=>{const[e,i]=t.pts;g(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.lineTo(i.x,i.y),t.ctx.stroke();const n=Math.max(8,5*t.style.lineWidth)*t.rc.dpr,s=Math.atan2(i.y-e.y,i.x-e.x);t.ctx.beginPath(),t.ctx.moveTo(i.x,i.y),t.ctx.lineTo(i.x-n*Math.cos(s-.4),i.y-n*Math.sin(s-.4)),t.ctx.lineTo(i.x-n*Math.cos(s+.4),i.y-n*Math.sin(s+.4)),t.ctx.closePath(),t.ctx.fillStyle=t.style.color,t.ctx.fill(),t.ctx.setLineDash([])},distance:(e,i,n)=>t(e,i,n.pts[0],n.pts[1])},A={id:"horizontal-line",name:"Horizontal Line",points:1,defaultStyle:{showLabels:!0},draw:t=>{const e=Math.round(t.pts[0].y)+.5;g(t),t.ctx.beginPath(),t.ctx.moveTo(0,e),t.ctx.lineTo(t.rc.plotWidth*t.rc.dpr,e),t.ctx.stroke(),t.ctx.setLineDash([]),!1!==t.style.showLabels&&_(t,t.formatPrice(t.drawing.points[0].price),4*t.rc.dpr,e-8*t.rc.dpr)},distance:(t,e,n)=>i(e,n.pts[0].y)},N={id:"horizontal-ray",name:"Horizontal Ray",points:1,defaultStyle:{showLabels:!0},draw:t=>{const e=Math.round(t.pts[0].y)+.5;g(t),t.ctx.beginPath(),t.ctx.moveTo(t.pts[0].x,e),t.ctx.lineTo(t.rc.plotWidth*t.rc.dpr,e),t.ctx.stroke(),t.ctx.setLineDash([]),!1!==t.style.showLabels&&_(t,t.formatPrice(t.drawing.points[0].price),t.pts[0].x+4*t.rc.dpr,e-8*t.rc.dpr)},distance:(t,e,n)=>t<n.pts[0].x?null:i(e,n.pts[0].y)},W={id:"vertical-line",name:"Vertical Line",points:1,draw:t=>{const e=Math.round(t.pts[0].x)+.5;g(t),t.ctx.beginPath(),t.ctx.moveTo(e,0),t.ctx.lineTo(e,t.rc.plotHeight*t.rc.dpr),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>n(t,i.pts[0].x)},C={id:"cross-line",name:"Cross Line",points:1,draw:t=>{const e=Math.round(t.pts[0].x)+.5,i=Math.round(t.pts[0].y)+.5;g(t),t.ctx.beginPath(),t.ctx.moveTo(e,0),t.ctx.lineTo(e,t.rc.plotHeight*t.rc.dpr),t.ctx.moveTo(0,i),t.ctx.lineTo(t.rc.plotWidth*t.rc.dpr,i),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,s)=>Math.min(n(t,s.pts[0].x),i(e,s.pts[0].y))},I={id:"rectangle",name:"Rectangle",points:2,defaultStyle:{fill:!0,fontSize:14,textAlign:"left",textVAlign:"top",textPosition:"inside"},draw:t=>{const e=o(t.pts[0],t.pts[1]);b(t,()=>t.ctx.fillRect(e.x0,e.y0,e.x1-e.x0,e.y1-e.y0)),g(t),t.ctx.strokeRect(e.x0,e.y0,e.x1-e.x0,e.y1-e.y0),t.ctx.setLineDash([]),Z(t,e.x0,e.y0,e.x1,e.y1)},distance:(t,e,i)=>l(t,e,i.pts[0],i.pts[1],!0===i.drawing.style.fill)},R={id:"ellipse",name:"Ellipse",points:2,defaultStyle:{fill:!0,fontSize:14,textAlign:"center",textVAlign:"middle",textPosition:"inside"},draw:t=>{const e=o(t.pts[0],t.pts[1]),i=(e.x0+e.x1)/2,n=(e.y0+e.y1)/2,s=Math.max(1,(e.x1-e.x0)/2),l=Math.max(1,(e.y1-e.y0)/2),r=()=>{t.ctx.beginPath(),t.ctx.ellipse(i,n,s,l,0,0,2*Math.PI)};b(t,()=>{r(),t.ctx.fill()}),g(t),r(),t.ctx.stroke(),t.ctx.setLineDash([]),Z(t,e.x0,e.y0,e.x1,e.y1)},distance:(t,e,i)=>r(t,e,i.pts[0],i.pts[1],!0===i.drawing.style.fill)},z={id:"parallel-channel",name:"Parallel Channel",points:3,defaultStyle:{fill:!0},draw:t=>{const[e,i,n]=t.pts,s=n.y-(e.y+.5*(i.y-e.y)),o={x:e.x,y:e.y+s},l={x:i.x,y:i.y+s};b(t,()=>{t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.lineTo(i.x,i.y),t.ctx.lineTo(l.x,l.y),t.ctx.lineTo(o.x,o.y),t.ctx.closePath(),t.ctx.fill()}),g(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.lineTo(i.x,i.y),t.ctx.moveTo(o.x,o.y),t.ctx.lineTo(l.x,l.y),t.ctx.stroke(),t.ctx.setLineDash([]),Z(t,Math.min(e.x,i.x),Math.min(e.y,i.y,o.y,l.y),Math.max(e.x,i.x),Math.max(e.y,i.y,o.y,l.y))},distance:(e,i,n)=>{const[s,o,l]=n.pts,r=l.y-(s.y+.5*(o.y-s.y)),a=t(e,i,s,o),c=t(e,i,{x:s.x,y:s.y+r},{x:o.x,y:o.y+r});return Math.min(a,c)}};function j(t,e,i){return{id:t,name:e,points:i,defaultStyle:{showLabels:!0,levels:[...L],fill:!0,fillOpacity:.06},draw:t=>{const e=t.style.levels??L,n=t.drawing.points,s=2===i?n[0].price:n[2].price,o=n[1].price-n[0].price,l=Math.min(t.pts[0].x,t.pts[i-1].x),r=Math.max(t.pts[0].x,t.pts[i-1].x),a=!0===t.style.extendRight?t.rc.plotWidth*t.rc.dpr:r;g(t);let c=null;for(const i of e){const e=s+o*i,n=Math.round(t.rc.priceScale.priceToY(e)*t.rc.dpr)+.5;!0===t.style.fill&&null!==c&&(t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.06,t.ctx.fillStyle=m(t),t.ctx.fillRect(l,Math.min(c,n),a-l,Math.abs(n-c)),t.ctx.restore()),c=n,t.ctx.beginPath(),t.ctx.moveTo(l,n),t.ctx.lineTo(a,n),t.ctx.stroke(),!1!==t.style.showLabels&&_(t,`${(100*i).toFixed(1)}% ${t.formatPrice(e)}`,l+4*t.rc.dpr,n-8*t.rc.dpr)}t.ctx.setLineDash([])},distance:(t,e,n)=>{const s=n.drawing.style.levels??L,o=n.drawing.points,l=2===i?o[0].price:o[2].price,r=o[1].price-o[0].price,a=Math.min(n.pts[0].x,n.pts[i-1].x),c=!0===n.drawing.style.extendRight?n.rc.plotWidth:Math.max(n.pts[0].x,n.pts[i-1].x);if(t<a-4||t>c+4)return null;let h=1/0;for(const t of s){const i=Math.abs(e-n.rc.priceScale.priceToY(l+r*t));i<h&&(h=i)}return h}}}const U=j("fib-retracement","Fib Retracement",2),B=j("fib-extension","Fib Extension",3),H={id:"measure",name:"Measure",points:2,defaultStyle:{fill:!0,showLabels:!0,fillOpacity:.1},draw:t=>{const e=o(t.pts[0],t.pts[1]),i=t.drawing.points,n=i[1].price-i[0].price,s=0!==i[0].price?n/i[0].price*100:0,l=n>=0,r=l?"#26a69a":"#ef5350";t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.1,t.ctx.fillStyle=r,t.ctx.fillRect(e.x0,e.y0,e.x1-e.x0,e.y1-e.y0),t.ctx.restore(),g(t),t.ctx.strokeStyle=r,t.ctx.strokeRect(e.x0,e.y0,e.x1-e.x0,e.y1-e.y0),t.ctx.setLineDash([]);const a=t.rc.dataLayer.timeToIndexFloat(i[0].time),c=t.rc.dataLayer.timeToIndexFloat(i[1].time),h=Math.abs(Math.round(c-a)),x=l?"+":"";_(t,`${x}${t.formatPrice(n)} (${x}${s.toFixed(2)}%) ${h} bars`,e.x0+4*t.rc.dpr,e.y0-10*t.rc.dpr,r)},distance:(t,e,i)=>l(t,e,i.pts[0],i.pts[1],!0)};function J(t,e,i){return{id:t,name:e,points:1,defaultStyle:{showLabels:!0,fillOpacity:.13,accountSize:1e5,risk:1},expand:(t,e)=>{const n=t[0],s=.01*Math.abs(n.price)||1,o=Math.max(5,Math.round(.08*e.visibleBars)),l=n.time+Math.max(1,e.barSeconds)*o;return i?[n,{time:l,price:n.price+s},{time:l,price:n.price-s}]:[n,{time:l,price:n.price-s},{time:l,price:n.price+s}]},draw:t=>{if(t.drawing.points.length<3||t.pts.length<3)return;const[e,n,s]=t.drawing.points,o=t.rc.dpr,l=Math.min(t.pts[0].x,t.pts[1].x,t.pts[2].x),r=Math.max(t.pts[0].x,t.pts[1].x,t.pts[2].x),a=t.rc.priceScale.priceToY(e.price)*o,c=t.rc.priceScale.priceToY(n.price)*o,h=t.rc.priceScale.priceToY(s.price)*o,x=(e,i,n)=>{t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.13,t.ctx.fillStyle=n,t.ctx.fillRect(l,Math.min(e,i),r-l,Math.abs(i-e)),t.ctx.restore()};x(a,c,S),x(a,h,P),g(t);for(const e of[a,c,h]){const i=Math.round(e)+.5;t.ctx.beginPath(),t.ctx.moveTo(l,i),t.ctx.lineTo(r,i),t.ctx.stroke()}if(t.ctx.setLineDash([]),!1===t.style.showLabels)return;const d=Math.abs(e.price-s.price),p=Math.abs(n.price-e.price),y=d>0?p/d:0,u=t.style.accountSize??0,f=t.style.risk??0,m=d>0&&u>0?Math.floor(u*f/100/d):0,b=t=>(0!==e.price?t/e.price*100:0).toFixed(3),_=t=>m>0?`, Amount: ${M(m*t)}`:"",v=(l+r)/2;w(t,[`Target: ${t.formatPrice(p)} (${b(p)}%)${_(p)}`],v,c,S,{align:"center",place:c<=a?"above":"below"}),w(t,[`Stop: ${t.formatPrice(d)} (${b(d)}%)${_(d)}`],v,h,P,{align:"center",place:h>=a?"below":"above"}),w(t,[`${i?"Long":"Short"} · Qty: ${m>0?M(m):"—"}`,`Risk/reward ratio: ${y.toFixed(2)}`],v,a,t.rc.theme.background,{align:"center",place:"middle"})},distance:(t,e,i)=>{if(i.pts.length<3)return null;const n=Math.min(i.pts[0].x,i.pts[1].x,i.pts[2].x),s=Math.max(i.pts[0].x,i.pts[1].x,i.pts[2].x);if(t<n-4||t>s+4)return null;const o=i.drawing.points.map(t=>i.rc.priceScale.priceToY(t.price)),l=Math.min(...o),r=Math.max(...o);return e>=l&&e<=r?0:Math.min(Math.abs(e-l),Math.abs(e-r))}}}const E=J("long-position","Long Position",!0),Y=J("short-position","Short Position",!1),q=1.35,V="ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif";function G(t,e){const i="bold"===t.fontWeight?"700 ":"";return`${"italic"===t.fontStyle?"italic ":""}${i}${e}px ${t.fontFamily??V}`}function Q(t,e,i){const n=(e.text??"").split("\n");if(!0!==e.wrap)return n;const s=[];for(const e of n){const n=e.split(/\s+/).filter(t=>""!==t);if(0===n.length){s.push("");continue}let o=n[0];for(let e=1;e<n.length;e++){const l=`${o} ${n[e]}`;t.measureText(l).width>i?(s.push(o),o=n[e]):o=l}s.push(o)}return s}function X(t,e,i){const n=(e.fontSize??13)*i;t.font=G(e,n);const s=Q(t,e,(e.wrapWidth??220)*i);let o=0;for(const e of s)o=Math.max(o,t.measureText(e).width);const l=n*q;return{lines:s,width:o+10*i,height:s.length*l+10*i,lineHeight:l}}function Z(t,e,i,n,s){const{ctx:o,rc:l,style:r}=t,a=r.text;if(void 0===a||""===a)return;const c=l.dpr,h=(r.fontSize??14)*c,x=6*c;o.save(),o.setLineDash([]),o.font=G(r,h),o.fillStyle=r.fontColor??r.color,o.textBaseline="top";const d=!0===r.wrap?Q(o,r,Math.max(20*c,n-e-2*x)):a.split("\n"),p=h*q,y=d.length*p,u=r.textAlign??"left";o.textAlign=u;const f="center"===u?(e+n)/2:"right"===u?n-x:e+x;let g;if("outside"===r.textPosition)g=i-y-x;else{const t=r.textVAlign??"top";g="middle"===t?(i+s-y)/2:"bottom"===t?s-y-x:i+x}for(const t of d)o.fillText(t,f,g),g+=p;o.restore()}const K={id:"text",name:"Text",points:1,defaultStyle:{text:"Text",fontSize:14,fontWeight:"normal",fontStyle:"normal",background:!1,backgroundOpacity:1,border:!1,wrap:!1,wrapWidth:220,textAlign:"left"},draw:t=>{const{ctx:e,rc:i,style:n}=t,s=i.dpr,o=X(e,n,s),l=t.pts[0].x,r=t.pts[0].y;e.save(),e.setLineDash([]),!0===n.background&&(e.globalAlpha=n.backgroundOpacity??1,e.fillStyle=n.backgroundColor??i.theme.background,e.beginPath(),e.roundRect(l,r,o.width,o.height,4*s),e.fill(),e.globalAlpha=1),!0===n.border&&(e.strokeStyle=n.borderColor??n.color,e.lineWidth=Math.max(1,n.lineWidth*s),e.beginPath(),e.roundRect(l,r,o.width,o.height,4*s),e.stroke()),e.font=G(n,(n.fontSize??13)*s),e.fillStyle=n.color,e.textBaseline="top";const a=n.textAlign??"left";e.textAlign=a;const c="center"===a?l+o.width/2:"right"===a?l+o.width-5*s:l+5*s;let h=r+5*s;for(const t of o.lines)e.fillText(t,c,h),h+=o.lineHeight;e.restore()},distance:(t,e,i)=>{const n=i.drawing.style,s=n.fontSize??13,o=i.pts[0],l=function(){if(void 0!==tt)return tt;try{tt="undefined"==typeof document?null:document.createElement("canvas").getContext("2d")}catch{tt=null}return tt}(),r=null===l?{width:(n.text??"").length*s*.6+10,height:s*q+10}:X(l,n,1);return t>=o.x-3&&t<=o.x+r.width+3&&e>=o.y-3&&e<=o.y+r.height+3?0:null}};let tt;const et={id:"path",name:"Path",points:0,draw:t=>{if(!(t.pts.length<2)){g(t),t.ctx.beginPath(),t.ctx.moveTo(t.pts[0].x,t.pts[0].y);for(let e=1;e<t.pts.length;e++)t.ctx.lineTo(t.pts[e].x,t.pts[e].y);t.ctx.stroke(),t.ctx.setLineDash([]),function(t,e,i){const n=Math.max(8,5*t.style.lineWidth)*t.rc.dpr,s=Math.atan2(i.y-e.y,i.x-e.x);t.ctx.beginPath(),t.ctx.moveTo(i.x,i.y),t.ctx.lineTo(i.x-n*Math.cos(s-.4),i.y-n*Math.sin(s-.4)),t.ctx.lineTo(i.x-n*Math.cos(s+.4),i.y-n*Math.sin(s+.4)),t.ctx.closePath(),t.ctx.fillStyle=t.style.color,t.ctx.fill()}(t,t.pts[t.pts.length-2],t.pts[t.pts.length-1])}},distance:(t,e,i)=>i.pts.length<2?null:s(t,e,i.pts)},it={id:"brush",name:"Brush",points:0,freehand:!0,defaultStyle:{lineWidth:2},draw:t=>{if(!(t.pts.length<2)){g(t),t.ctx.lineCap="round",t.ctx.lineJoin="round",t.ctx.beginPath(),t.ctx.moveTo(t.pts[0].x,t.pts[0].y);for(let e=1;e<t.pts.length;e++)t.ctx.lineTo(t.pts[e].x,t.pts[e].y);t.ctx.stroke(),t.ctx.setLineDash([])}},distance:(t,e,i)=>i.pts.length<2?null:s(t,e,i.pts)},nt={id:"rotated-rectangle",name:"Rotated Rectangle",points:3,defaultStyle:{fill:!0,fillOpacity:.12},draw:t=>{if(t.pts.length<3)return;const e=st(t.pts[0],t.pts[1],t.pts[2]);t.ctx.beginPath(),t.ctx.moveTo(e[0].x,e[0].y);for(let i=1;i<4;i++)t.ctx.lineTo(e[i].x,e[i].y);t.ctx.closePath(),!0===t.style.fill&&(t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.12,t.ctx.fillStyle=m(t),t.ctx.fill(),t.ctx.restore()),g(t),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(e,i,n)=>{if(n.pts.length<3)return null;const s=st(n.pts[0],n.pts[1],n.pts[2]);if(!0===n.drawing.style.fill&&function(t,e,i){let n=!1;for(let s=0,o=i.length-1;s<i.length;o=s++){const l=i[s],r=i[o];l.y>e!=r.y>e&&t<(r.x-l.x)*(e-l.y)/(r.y-l.y)+l.x&&(n=!n)}return n}(e,i,s))return 0;let o=1/0;for(let n=0;n<4;n++)o=Math.min(o,t(e,i,s[n],s[(n+1)%4]));return o}};function st(t,e,i){const n=e.x-t.x,s=e.y-t.y,o=Math.hypot(n,s)||1,l=-s/o,r=n/o,a=(i.x-e.x)*l+(i.y-e.y)*r;return[t,e,{x:e.x+l*a,y:e.y+r*a},{x:t.x+l*a,y:t.y+r*a}]}const ot={id:"double-curve",name:"Double Curve",points:3,draw:t=>{if(t.pts.length<3)return;const[e,i,n]=t.pts;g(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.bezierCurveTo(i.x,i.y,e.x+n.x-i.x,e.y+n.y-i.y,n.x,n.y),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>{if(i.pts.length<3)return null;const[n,o,l]=i.pts;return s(t,e,function(t,e,i,n,s){const o=[];for(let l=0;l<=s;l++){const r=l/s,a=1-r,c=a*a*a,h=3*a*a*r,x=3*a*r*r,d=r*r*r;o.push({x:c*t.x+h*e.x+x*i.x+d*n.x,y:c*t.y+h*e.y+x*i.y+d*n.y})}return o}(n,o,{x:n.x+l.x-o.x,y:n.y+l.y-o.y},l,24))}};const lt={id:"cyclic-lines",name:"Cyclic Lines",points:2,defaultStyle:{lineStyle:"dashed"},draw:t=>{const[e,i]=t.pts,n=i.x-e.x;if(!Number.isFinite(n)||Math.abs(n)<.5)return;const s=t.rc.plotHeight*t.rc.dpr,o=t.rc.plotWidth*t.rc.dpr;g(t),t.ctx.beginPath();for(let i=0;i<=12;i++){const l=Math.round(e.x+n*i)+.5;l<0||l>o||(t.ctx.moveTo(l,0),t.ctx.lineTo(l,s))}t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>{const n=i.pts[1].x-i.pts[0].x;if(!Number.isFinite(n)||Math.abs(n)<.5)return null;const s=Math.round((t-i.pts[0].x)/n);return s<0||s>12?null:Math.abs(t-(i.pts[0].x+n*s))}},rt={id:"time-cycles",name:"Time Cycles",points:2,draw:t=>{const[e,i]=t.pts,n=i.x-e.x;if(!Number.isFinite(n)||Math.abs(n)<1)return;const s=Math.abs(n)/2;g(t),t.ctx.beginPath();for(let i=0;i<12;i++){const o=e.x+n*i+n/2;o+s<0||o-s>t.rc.plotWidth*t.rc.dpr||(t.ctx.moveTo(o+s,e.y),t.ctx.arc(o,e.y,s,0,Math.PI,!0))}t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>{const[n,s]=i.pts,o=s.x-n.x;if(!Number.isFinite(o)||Math.abs(o)<1)return null;const l=Math.abs(o)/2;let r=1/0;for(let i=0;i<12;i++){const s=n.x+o*i+o/2;e>n.y+2||(r=Math.min(r,Math.abs(Math.hypot(t-s,e-n.y)-l)))}return Number.isFinite(r)?r:null}},at={id:"sine-line",name:"Sine Line",points:2,draw:t=>{const e=ct(t.pts[0],t.pts[1]);if(null!==e){g(t),t.ctx.beginPath(),t.ctx.moveTo(e[0].x,e[0].y);for(let i=1;i<e.length;i++)t.ctx.lineTo(e[i].x,e[i].y);t.ctx.stroke(),t.ctx.setLineDash([])}},distance:(t,e,i)=>{const n=ct(i.pts[0],i.pts[1]);return null===n?null:s(t,e,n)}};function ct(t,e){const i=e.x-t.x,n=e.y-t.y;if(!Number.isFinite(i)||Math.abs(i)<1)return null;const s=[];for(let e=0;e<=64;e++){const o=e/64;s.push({x:t.x+i*o,y:t.y+n*Math.sin(o*Math.PI*2)})}return s}const ht={id:"price-label",name:"Price Label",points:1,defaultStyle:{fontSize:12},draw:t=>{const e=t.pts[0],i=t.rc.dpr,n=void 0!==t.style.text&&""!==t.style.text?t.style.text:t.formatPrice(t.drawing.points[0].price),s=dt(t,[n],e.x+18*i,e.y-30*i);pt(t,s,e,t.style.color),yt(t,s,[n],t.style.color)},distance:(t,e,i)=>{const n=i.pts[0],s=n.x+18,o=n.y-30-11;return t>=s&&t<=s+64&&e>=o&&e<=o+22||Math.hypot(t-n.x,e-n.y)<=10?0:null}},xt={id:"callout",name:"Callout",points:2,defaultStyle:{fontSize:12,text:"Note"},draw:t=>{if(t.pts.length<2)return;const[e,i]=t.pts,n=(t.style.text??"Note").split("\n"),s=dt(t,n,i.x,i.y);pt(t,s,e,t.style.color),yt(t,s,n,t.style.color)},distance:(e,i,n)=>{if(n.pts.length<2)return null;const[s,o]=n.pts;return Math.abs(e-o.x)<=60&&Math.abs(i-o.y)<=16?0:t(e,i,s,o)}};function dt(t,e,i,n){const s=t.rc.dpr,o=(t.style.fontSize??12)*s;t.ctx.save(),t.ctx.font=`${o}px ui-sans-serif, system-ui, sans-serif`;let l=0;for(const i of e)l=Math.max(l,t.ctx.measureText(i).width);t.ctx.restore();const r=l+14*s,a=1.4*o*e.length+8*s;return{x:i-r/2,y:n-a/2,w:r,h:a}}function pt(t,e,i,n){const s=t.rc.dpr,o=e.x+e.w/2,l=e.y+e.h/2,r=Math.atan2(i.y-l,i.x-o),a=5*s,c=o+Math.cos(r)*(e.w/2-a),h=l+Math.sin(r)*(e.h/2-a);t.ctx.save(),t.ctx.setLineDash([]),t.ctx.fillStyle=n,t.ctx.beginPath(),t.ctx.moveTo(i.x,i.y),t.ctx.lineTo(c-Math.sin(r)*a,h+Math.cos(r)*a),t.ctx.lineTo(c+Math.sin(r)*a,h-Math.cos(r)*a),t.ctx.closePath(),t.ctx.fill(),t.ctx.beginPath(),x(t.ctx,e.x,e.y,e.w,e.h,5*s),t.ctx.fill(),t.ctx.beginPath(),t.ctx.arc(i.x,i.y,2.5*s,0,2*Math.PI),t.ctx.fill(),t.ctx.restore()}function yt(t,e,i,n){const s=t.rc.dpr,o=(t.style.fontSize??12)*s;t.ctx.save(),t.ctx.setLineDash([]),t.ctx.font=`${o}px ui-sans-serif, system-ui, sans-serif`,t.ctx.textAlign="center",t.ctx.textBaseline="middle",t.ctx.fillStyle=t.style.fontColor??h(n);const l=1.4*o,r=e.y+e.h/2-l*(i.length-1)/2;for(let n=0;n<i.length;n++)t.ctx.fillText(i[n],e.x+e.w/2,r+l*n);t.ctx.restore()}const ut={id:"flag-mark",name:"Flag Mark",points:1,defaultStyle:{fill:!0,fillOpacity:.95},draw:t=>{const e=t.pts[0],i=t.rc.dpr,n=22*i,s=15*i,o=11*i;g(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.lineTo(e.x,e.y-n),t.ctx.stroke(),t.ctx.setLineDash([]),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y-n),t.ctx.lineTo(e.x+s,e.y-n+.28*o),t.ctx.lineTo(e.x+.72*s,e.y-n+.5*o),t.ctx.lineTo(e.x+s,e.y-n+.72*o),t.ctx.lineTo(e.x,e.y-n+o),t.ctx.closePath(),t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.95,t.ctx.fillStyle=m(t),t.ctx.fill(),t.ctx.restore()},distance:(t,e,i)=>{const n=i.pts[0];return t>=n.x-4&&t<=n.x+16&&e>=n.y-24&&e<=n.y+2||Math.hypot(t-n.x,e-n.y)<=8?0:null}},ft={id:"price-range",name:"Price Range",points:2,defaultStyle:{fill:!0,showLabels:!0,fillOpacity:.1},draw:t=>{const e=t.rc.dpr,i=t.drawing.points,n=i[1].price-i[0].price,s=0!==i[0].price?n/i[0].price*100:0,o=n>=0,l=o?"#26a69a":"#ef5350",r=Math.min(t.pts[0].x,t.pts[1].x),a=Math.max(t.pts[0].x,t.pts[1].x)+(t.pts[0].x===t.pts[1].x?60*e:0),c=t.pts[0].y,h=t.pts[1].y;t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.1,t.ctx.fillStyle=l,t.ctx.fillRect(r,Math.min(c,h),a-r,Math.abs(h-c)),t.ctx.restore(),g(t),t.ctx.strokeStyle=l,t.ctx.beginPath();for(const e of[c,h])t.ctx.moveTo(r,Math.round(e)+.5),t.ctx.lineTo(a,Math.round(e)+.5);const x=(r+a)/2;t.ctx.moveTo(x,c),t.ctx.lineTo(x,h);const d=h>c?1:-1;t.ctx.moveTo(x-4*e,h-5*e*d),t.ctx.lineTo(x,h),t.ctx.lineTo(x+4*e,h-5*e*d),t.ctx.moveTo(x-4*e,c+5*e*d),t.ctx.lineTo(x,c),t.ctx.lineTo(x+4*e,c+5*e*d),t.ctx.stroke(),t.ctx.setLineDash([]);const p=o?"+":"";_(t,`${p}${t.formatPrice(n)} (${p}${s.toFixed(2)}%)`,x+6*e,(c+h)/2,l)},distance:(t,e,i)=>l(t,e,i.pts[0],i.pts[1],!0)},gt={id:"date-range",name:"Date Range",points:2,defaultStyle:{fill:!0,showLabels:!0,fillOpacity:.1},draw:t=>{const e=t.rc.dpr,i=t.drawing.points,n=t.style.color,s=t.pts[0].x,o=t.pts[1].x,l=Math.min(t.pts[0].y,t.pts[1].y),r=Math.max(t.pts[0].y,t.pts[1].y)+(t.pts[0].y===t.pts[1].y?40*e:0);t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.1,t.ctx.fillStyle=n,t.ctx.fillRect(Math.min(s,o),l,Math.abs(o-s),r-l),t.ctx.restore(),g(t),t.ctx.beginPath();for(const e of[s,o])t.ctx.moveTo(Math.round(e)+.5,l),t.ctx.lineTo(Math.round(e)+.5,r);const a=(l+r)/2;t.ctx.moveTo(s,a),t.ctx.lineTo(o,a);const c=o>s?1:-1;t.ctx.moveTo(o-5*e*c,a-4*e),t.ctx.lineTo(o,a),t.ctx.lineTo(o-5*e*c,a+4*e),t.ctx.moveTo(s+5*e*c,a-4*e),t.ctx.lineTo(s,a),t.ctx.lineTo(s+5*e*c,a+4*e),t.ctx.stroke(),t.ctx.setLineDash([]);const h=t.rc.dataLayer.timeToIndexFloat(i[0].time),x=t.rc.dataLayer.timeToIndexFloat(i[1].time);_(t,`${Math.abs(Math.round(x-h))} bars`,(s+o)/2,l-10*e,n)},distance:(t,e,i)=>l(t,e,i.pts[0],i.pts[1],!0)},mt={id:"forecast",name:"Forecast",points:2,defaultStyle:{fill:!0,showLabels:!0,fillOpacity:.12,lineStyle:"dashed"},draw:t=>{const e=t.rc.dpr,i=t.drawing.points,[n,s]=t.pts,o=i[1].price-i[0].price,l=0!==i[0].price?o/i[0].price*100:0,r=o>=0,a=r?"#26a69a":"#ef5350",c=.35*Math.abs(s.y-n.y)+6*e;if(t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.12,t.ctx.fillStyle=a,t.ctx.beginPath(),t.ctx.moveTo(n.x,n.y),t.ctx.lineTo(s.x,s.y-c),t.ctx.lineTo(s.x,s.y+c),t.ctx.closePath(),t.ctx.fill(),t.ctx.restore(),g(t),t.ctx.strokeStyle=a,t.ctx.beginPath(),t.ctx.moveTo(n.x,n.y),t.ctx.lineTo(s.x,s.y),t.ctx.stroke(),t.ctx.setLineDash([]),t.ctx.beginPath(),t.ctx.arc(n.x,n.y,3*e,0,2*Math.PI),t.ctx.fillStyle=a,t.ctx.fill(),!1===t.style.showLabels)return;const h=r?"+":"";w(t,[t.formatPrice(i[0].price),v(i[0].time)],n.x,n.y,a,{align:"center"}),w(t,[`${h}${t.formatPrice(o)} (${h}${l.toFixed(2)}%) in ${T(i[1].time-i[0].time)}`,`${t.formatPrice(i[1].price)} · ${v(i[1].time)}`],s.x,s.y,a,{align:"center",place:"below"});const x=t.rc.bars?.();if(void 0!==x&&x.length>0&&x[x.length-1].time>=i[1].time){let n=!1;for(const t of x)if(!(t.time<i[0].time)){if(t.time>i[1].time)break;if(r?t.high>=i[1].price:t.low<=i[1].price){n=!0;break}}w(t,[n?"SUCCESS":"MISSED"],s.x,s.y+36*e,n?"#4a934a":"#8a4a4a",{align:"center",place:"below"})}},distance:(e,i,n)=>t(e,i,n.pts[0],n.pts[1])},bt={id:"circle",name:"Circle",points:2,defaultStyle:{fill:!0},draw:t=>{const[e,i]=t.pts,n=Math.hypot(i.x-e.x,i.y-e.y);t.ctx.beginPath(),t.ctx.arc(e.x,e.y,n,0,2*Math.PI),b(t,()=>t.ctx.fill()),g(t),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>{const[n,s]=i.pts,o=Math.hypot(s.x-n.x,s.y-n.y),l=Math.hypot(t-n.x,e-n.y);return!0===i.drawing.style.fill&&l<=o?0:Math.abs(l-o)}},_t={id:"triangle",name:"Triangle",points:3,defaultStyle:{fill:!0},draw:t=>{t.ctx.beginPath(),t.ctx.moveTo(t.pts[0].x,t.pts[0].y),t.ctx.lineTo(t.pts[1].x,t.pts[1].y),t.ctx.lineTo(t.pts[2].x,t.pts[2].y),t.ctx.closePath(),b(t,()=>t.ctx.fill()),g(t),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>s(t,e,[...i.pts,i.pts[0]])},wt={id:"polyline",name:"Polyline",points:0,defaultStyle:{fill:!1},draw:t=>{if(!(t.pts.length<2)){t.ctx.beginPath(),t.ctx.moveTo(t.pts[0].x,t.pts[0].y);for(let e=1;e<t.pts.length;e++)t.ctx.lineTo(t.pts[e].x,t.pts[e].y);!0===t.style.fill&&(t.ctx.closePath(),b(t,()=>t.ctx.fill())),g(t),t.ctx.stroke(),t.ctx.setLineDash([])}},distance:(t,e,i)=>s(t,e,i.pts)};const Mt={id:"arc",name:"Arc",points:3,draw:t=>{const[e,i,n]=t.pts;g(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.quadraticCurveTo(2*i.x-(e.x+n.x)/2,2*i.y-(e.y+n.y)/2,n.x,n.y),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>s(t,e,function(t,e,i){const n=2*e.x-(t.x+i.x)/2,s=2*e.y-(t.y+i.y)/2,o=[];for(let e=0;e<=16;e++){const l=e/16,r=1-l;o.push({x:r*r*t.x+2*r*l*n+l*l*i.x,y:r*r*t.y+2*r*l*s+l*l*i.y})}return o}(i.pts[0],i.pts[1],i.pts[2]))},vt={id:"curve",name:"Curve",points:3,draw:t=>{const[e,i,n]=t.pts;g(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.quadraticCurveTo(i.x,i.y,n.x,n.y),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>{const[n,o,l]=i.pts,r=[];for(let t=0;t<=16;t++){const e=t/16,i=1-e;r.push({x:i*i*n.x+2*i*e*o.x+e*e*l.x,y:i*i*n.y+2*i*e*o.y+e*e*l.y})}return s(t,e,r)}};function Tt(t,e,i){return{id:t,name:e,points:1,defaultStyle:{fill:!0,fillOpacity:.9},draw:t=>{const e=t.rc.dpr,{x:n,y:s}=t.pts[0],o=16*e,l=6*e,r=i?1:-1,a=s+2*r*e;t.ctx.beginPath(),t.ctx.moveTo(n,a),t.ctx.lineTo(n-l,a+r*l),t.ctx.lineTo(n-l/2.4,a+r*l),t.ctx.lineTo(n-l/2.4,a+r*o),t.ctx.lineTo(n+l/2.4,a+r*o),t.ctx.lineTo(n+l/2.4,a+r*l),t.ctx.lineTo(n+l,a+r*l),t.ctx.closePath(),t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.9,t.ctx.fillStyle=m(t),t.ctx.fill(),t.ctx.restore(),g(t),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,n)=>{const s=n.pts[0],o=i?e-s.y:s.y-e;return Math.abs(t-s.x)<=8&&o>=-4&&o<=20?0:null}}}const St=Tt("arrow-up","Arrow Up",!0),Pt=Tt("arrow-down","Arrow Down",!1),Lt={id:"highlighter",name:"Highlighter",points:0,freehand:!0,defaultStyle:{lineWidth:12,fillOpacity:.28},draw:t=>{if(t.pts.length<2)return;const e=t.rc.dpr;t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.28,t.ctx.strokeStyle=t.style.color,t.ctx.lineWidth=Math.max(2,(t.style.lineWidth||12)*e),t.ctx.lineCap="round",t.ctx.lineJoin="round",t.ctx.beginPath(),t.ctx.moveTo(t.pts[0].x,t.pts[0].y);for(let e=1;e<t.pts.length;e++)t.ctx.lineTo(t.pts[e].x,t.pts[e].y);t.ctx.stroke(),t.ctx.restore()},distance:(t,e,i)=>{const n=s(t,e,i.pts);return n<=Math.max(6,(i.drawing.style.lineWidth??12)/2)?0:n}},kt={id:"fib-channel",name:"Fib Channel",points:3,defaultStyle:{showLabels:!0,levels:[...L]},draw:t=>{const e=t.style.levels??L,[i,n,s]=t.pts,o=s.x-n.x,l=s.y-n.y;g(t);for(const s of e)t.ctx.beginPath(),t.ctx.moveTo(i.x+o*s,i.y+l*s),t.ctx.lineTo(n.x+o*s,n.y+l*s),t.ctx.stroke(),!1!==t.style.showLabels&&_(t,`${(100*s).toFixed(1)}%`,n.x+o*s+4*t.rc.dpr,n.y+l*s);t.ctx.setLineDash([])},distance:(e,i,n)=>{const s=n.drawing.style.levels??L,[o,l,r]=n.pts;let a=1/0;for(const n of s){const s=t(e,i,{x:o.x+(r.x-l.x)*n,y:o.y+(r.y-l.y)*n},{x:l.x+(r.x-l.x)*n,y:l.y+(r.y-l.y)*n});s<a&&(a=s)}return a}},Dt=[0,1,2,3,5,8,13,21,34,55],$t={id:"fib-time-zone",name:"Fib Time Zone",points:2,defaultStyle:{showLabels:!0},draw:t=>{const[e,i]=t.pts,n=i.x-e.x;if(Math.abs(n)<.5)return;const s=t.rc.dpr,o=t.rc.plotWidth*s;g(t);for(const i of Dt){const l=e.x+n*i;l<-10||l>o+10||(t.ctx.beginPath(),t.ctx.moveTo(Math.round(l)+.5,0),t.ctx.lineTo(Math.round(l)+.5,t.rc.plotHeight*s),t.ctx.stroke(),!1!==t.style.showLabels&&_(t,String(i),l+3*s,12*s))}t.ctx.setLineDash([])},distance:(t,e,i)=>{const[n,s]=i.pts,o=s.x-n.x;if(Math.abs(o)<.5)return null;let l=1/0;for(const e of Dt)l=Math.min(l,Math.abs(t-(n.x+o*e)));return l}},Ot=[.236,.382,.5,.618,.786,1],Ft={id:"fib-fan",name:"Fib Speed Fan",points:2,defaultStyle:{showLabels:!0,levels:[...Ot]},draw:t=>{const e=t.style.levels??Ot,[i,n]=t.pts,s=t.rc.dpr,o=t.rc.plotWidth*s;g(t);for(const l of e){const e=a(i,{x:n.x,y:i.y+(n.y-i.y)*l},o,!1,!0)[1];t.ctx.beginPath(),t.ctx.moveTo(i.x,i.y),t.ctx.lineTo(e.x,e.y),t.ctx.stroke(),!1!==t.style.showLabels&&_(t,`${(100*l).toFixed(1)}%`,n.x+4*s,i.y+(n.y-i.y)*l)}t.ctx.setLineDash([])},distance:(e,i,n)=>{const s=n.drawing.style.levels??Ot,[o,l]=n.pts;let r=1/0;for(const c of s)r=Math.min(r,t(e,i,o,a(o,{x:l.x,y:o.y+(l.y-o.y)*c},n.rc.plotWidth,!1,!0)[1]));return r}},At=[[1,.125],[1,.25],[1,.5],[1,1],[.5,1],[.25,1],[.125,1]],Nt=[D,$,O,F,A,N,W,C,I,R,z,U,B,E,Y,mt,H,ft,gt,bt,_t,wt,Mt,vt,nt,ot,St,Pt,Lt,it,kt,$t,Ft,{id:"gann-fan",name:"Gann Fan",points:2,defaultStyle:{showLabels:!0},draw:t=>{const[e,i]=t.pts,n=t.rc.dpr,s=t.rc.plotWidth*n,o=i.x-e.x,l=i.y-e.y;if(!(Math.abs(o)<.5)){g(t);for(const[i,n]of At){const r=a(e,{x:e.x+o*i,y:e.y+l*n},s,!1,!0)[1];t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.lineTo(r.x,r.y),t.ctx.stroke()}!1!==t.style.showLabels&&_(t,"1x1",i.x+4*n,i.y),t.ctx.setLineDash([])}},distance:(e,i,n)=>{const[s,o]=n.pts,l=o.x-s.x,r=o.y-s.y;let c=1/0;for(const[o,h]of At)c=Math.min(c,t(e,i,s,a(s,{x:s.x+l*o,y:s.y+r*h},n.rc.plotWidth,!1,!0)[1]));return c}},{id:"gann-box",name:"Gann Box",points:2,defaultStyle:{fill:!0,fillOpacity:.05},draw:t=>{const e=o(t.pts[0],t.pts[1]);b(t,()=>t.ctx.fillRect(e.x0,e.y0,e.x1-e.x0,e.y1-e.y0)),g(t);const i=e.x1-e.x0,n=e.y1-e.y0;t.ctx.beginPath();for(let s=0;s<=8;s++){const o=Math.round(e.x0+i*s/8)+.5,l=Math.round(e.y0+n*s/8)+.5;t.ctx.moveTo(o,e.y0),t.ctx.lineTo(o,e.y1),t.ctx.moveTo(e.x0,l),t.ctx.lineTo(e.x1,l)}t.ctx.moveTo(e.x0,e.y1),t.ctx.lineTo(e.x1,e.y0),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>l(t,e,i.pts[0],i.pts[1],!0===i.drawing.style.fill)},lt,rt,at,K,et,ht,xt,ut];let Wt=!1;function Ct(){if(!Wt){Wt=!0;for(const t of Nt)p(t)}}function It(t,e){return u(t)&&!0===y(t).freehand&&e>2?[0,e-1]:Array.from({length:e},(t,e)=>e)}class Rt{constructor(){Object.defineProperty(this,"_drawings",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"_host",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_selected",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_preview",{enumerable:!0,configurable:!0,writable:!0,value:null})}attached(t){this._host=t}detached(){this._host=null}zOrder(){return"top"}autoscaleInfo(){return null}setDrawings(t){this._drawings=t.slice(),this._host?.requestUpdate()}setSelected(t){t!==this._selected&&(this._selected=t,this._host?.requestUpdate())}setPreview(t){this._preview=t,this._host?.requestUpdate()}_project(t,e,i){return{x:t.timeScale.indexToX(t.dataLayer.timeToIndexFloat(e)),y:t.priceScale.priceToY(i)}}_points(t,e){return e.points.map(e=>this._project(t,e.time,e.price))}draw(t,e){const i=null===this._preview?this._drawings:[...this._drawings,this._preview];for(const n of i){if(!1===n.visible||!u(n.tool))continue;const i=y(n.tool);if(n.points.length<Math.max(1,i.points))continue;const s=this._points(e,n);if(!s.some(t=>Number.isFinite(t.x)&&Number.isFinite(t.y)))continue;const o={color:n.style.color??e.theme.lineColor,lineWidth:n.style.lineWidth??1.5,...n.style},l=e.dpr;t.save(),n===this._preview&&(t.globalAlpha=.7),i.draw({ctx:t,rc:e,drawing:n,selected:n.id===this._selected,pts:s.map(t=>({x:t.x*l,y:t.y*l})),style:{...o,color:o.color,lineWidth:o.lineWidth},formatPrice:t=>e.priceScale.format(t)}),t.restore(),n.id===this._selected&&!0!==n.locked&&this._drawHandles(t,e,s,n.tool)}}_drawHandles(t,e,i,n){const s=e.dpr;t.save(),t.setLineDash([]),t.lineWidth=Math.max(1,Math.round(1.5*s));for(const o of It(n,i.length)){const n=i[o];t.beginPath(),t.arc(n.x*s,n.y*s,5*s,0,2*Math.PI),t.fillStyle=e.theme.background,t.fill(),t.strokeStyle=e.theme.lineColor,t.stroke()}t.restore()}hitTest(t,e,i){if(null!==this._selected){const n=this._drawings.find(t=>t.id===this._selected);if(void 0!==n&&!0!==n.locked){const s=this._points(i,n);for(const i of It(n.tool,s.length))if(Math.hypot(t-s[i].x,e-s[i].y)<=7)return{externalId:`draw:${n.id}#${i}`,zOrder:"top",distance:0,cursor:"grabbing",draggable:!0}}}let n=null;for(let s=this._drawings.length-1;s>=0;s--){const o=this._drawings[s];if(!1===o.visible||!0===o.locked||!u(o.tool))continue;const l=y(o.tool);if(o.points.length<Math.max(1,l.points))continue;const r=l.distance(t,e,{pts:this._points(i,o),drawing:o,rc:i});null===r||!Number.isFinite(r)||r>6||(null===n||r<n.distance)&&(n={id:o.id,distance:r})}return null===n?null:{externalId:`draw:${n.id}`,zOrder:"top",distance:n.distance,cursor:"move",draggable:!0}}}let zt=1;class jt{constructor(t,e={}){Object.defineProperty(this,"_chart",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_opts",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_layers",{enumerable:!0,configurable:!0,writable:!0,value:new Map}),Object.defineProperty(this,"_drawings",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"_tool",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_pending",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"_pendingPane",{enumerable:!0,configurable:!0,writable:!0,value:0}),Object.defineProperty(this,"_selected",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_undo",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"_redo",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"_dragStart",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_off",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"_lastCursor",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_lastBar",{enumerable:!0,configurable:!0,writable:!0,value:null}),this._chart=t,this._opts={magnet:e.magnet??!1,stayInDrawingMode:e.stayInDrawingMode??!1,historyLimit:e.historyLimit??50,defaultStyle:e.defaultStyle??{}},this._off.push(t.on("click",t=>this._onClick(t))),this._off.push(t.on("crosshair:move",t=>this._onCrosshair(t))),this._off.push(t.on("drag",t=>this._onDrag(t))),this._off.push(t.on("drag:end",()=>this._onDragEnd())),this._off.push(t.on("dblclick",()=>{this.finish()}));const i=t.drawingState();Array.isArray(i)&&(this._drawings=i.map(t=>({...t}))),this._sync()}setTool(t){if(null!==t&&!u(t))throw new Error(`openalgo-charts: unknown drawing tool "${t}"`);this._tool=t,this._pending=[],this._setPlacementMode(null!==t),this._syncPreview(),this._chart.emit("draw:tool",{tool:t})}_setPlacementMode(t){const e=this._chart;e.setPlacementMode?.(t)}activeTool(){return this._tool}setOptions(t){this._opts={...this._opts,...t,defaultStyle:t.defaultStyle??this._opts.defaultStyle}}drawings(){return this._drawings}get(t){return this._drawings.find(e=>e.id===t)}add(t){this._pushUndo();const e=y(t.tool),i={...t,id:t.id??"d"+zt++,style:{...this._opts.defaultStyle,...e.defaultStyle,...t.style}};return this._drawings.push(i),this._sync(),this._chart.emit("draw:add",{drawing:i}),i}update(t,e){const i=this.get(t);return void 0!==i&&(this._pushUndo(),void 0!==e.points&&(i.points=e.points.map(t=>({...t}))),void 0!==e.style&&(i.style={...i.style,...e.style}),void 0!==e.locked&&(i.locked=e.locked),void 0!==e.visible&&(i.visible=e.visible),this._sync(),this._chart.emit("draw:update",{drawing:i}),!0)}remove(t){const e=this._drawings.findIndex(e=>e.id===t);if(e<0)return!1;this._pushUndo();const[i]=this._drawings.splice(e,1);return this._selected===t&&(this._selected=null),this._sync(),this._chart.emit("draw:remove",{drawing:i}),!0}clear(){0!==this._drawings.length&&(this._pushUndo(),this._drawings=[],this._selected=null,this._sync())}select(t){this._selected=t;for(const e of this._layers.values())e.setSelected(t);this._chart.emit("draw:select",{id:t})}selected(){return this._selected}undo(){const t=this._undo.pop();return void 0!==t&&(this._redo.push(JSON.stringify(this._drawings)),this._drawings=JSON.parse(t),this._drawings.some(t=>t.id===this._selected)||(this._selected=null),this._sync(),!0)}redo(){const t=this._redo.pop();return void 0!==t&&(this._undo.push(JSON.stringify(this._drawings)),this._drawings=JSON.parse(t),this._sync(),!0)}canUndo(){return this._undo.length>0}canRedo(){return this._redo.length>0}toJSON(){return this._drawings.map(t=>({...t,points:t.points.map(t=>({...t})),style:{...t.style}}))}fromJSON(t){this._drawings=Array.isArray(t)?t.map(t=>({...t})):[],this._selected=null,this._undo=[],this._redo=[],this._sync()}destroy(){this._setPlacementMode(!1);for(const t of this._off)t();this._off.length=0;for(const[t,e]of this._layers)this._chart.removePrimitive(e);this._layers.clear()}_onCrosshair(t){const e=t.time,i=t.price,n=t.paneIndex??null;this._lastCursor=null===e||null===i||null===n?null:{time:e,price:i,paneIndex:n},this._lastBar=t.bar??null,null!==this._tool&&!0===t.pressed&&this._isFreehand()&&null!==e&&null!==i&&null!==n&&Number.isFinite(e)&&Number.isFinite(i)?this._inkPoint({time:e,price:i},n):null!==this._tool&&this._pending.length>0&&this._syncPreview()}_expand(t,e){if(void 0===t.expand)return e;const i=this._chart.dataLayer,n=i.baseIndex,s=n>0?i.indexToTime(n-1):void 0,o=n>=0?i.indexToTime(n):void 0,l=void 0!==s&&void 0!==o&&o>s?o-s:60,r=this._chart.getVisibleLogicalRange(),a=null===r?60:Math.max(1,r.to-r.from);return t.expand(e,{barSeconds:l,visibleBars:a})}_isFreehand(){return null!==this._tool&&!0===y(this._tool).freehand}_inkPoint(t,e){if(0===this._pending.length)this._pendingPane=e;else{if(e!==this._pendingPane)return;{const e=this._pending[this._pending.length-1];if(e.time===t.time&&e.price===t.price)return}}this._pending.push(t),this._syncPreview()}_commit(t){const e=y(this._tool),i=this.add({tool:e.id,points:t,style:{},paneIndex:this._pendingPane});this._pending=[],this._opts.stayInDrawingMode||(this._tool=null,this._setPlacementMode(!1)),this._syncPreview(),this.select(i.id),this._chart.emit("draw:tool",{tool:this._tool})}_finishFreehand(){const t=this._pending;this._pending=[],t.length<2?this._syncPreview():this._commit(t)}finish(){if(null===this._tool||0===this._pending.length)return!1;const t=y(this._tool);if(0!==t.points||!0===t.freehand)return!1;const e=this._pending;return e.length<2?(this._pending=[],this._syncPreview(),!1):(this._commit(e),!0)}_onClick(t){if(null===this._tool)null!==t.id&&t.id.startsWith("draw:")?this.select(t.id.slice(5).split("#")[0]):null===t.id&&this.select(null);else{if(this._isFreehand())return void(!0===t.viaDrag&&this._finishFreehand());if(!0===t.viaDrag&&0===this._pending.length)return;if(null===t.price||!Number.isFinite(t.price)||!Number.isFinite(t.time))return;this._placePoint({time:t.time,price:this._snap(t.price,t.paneIndex)},t.paneIndex)}}_placePoint(t,e){0===this._pending.length&&(this._pendingPane=e),this._pending.push(t);const i=y(this._tool);i.points>0&&this._pending.length>=i.points?this._commit(this._expand(i,this._pending)):this._syncPreview()}_snap(t,e){if(!this._opts.magnet||0!==e)return t;const i=this._lastBar;if(null===i)return t;let n=t,s=1/0;for(const e of[i.open,i.high,i.low,i.close]){const i=Math.abs(e-t);i<s&&(s=i,n=e)}return n}_onDrag(t){if(!t.id.startsWith("draw:"))return;const[e,i]=t.id.slice(5).split("#"),n=this.get(e);if(void 0===n||!0===n.locked)return;const s=void 0===i?null:Number(i);null!==this._dragStart&&this._dragStart.id===e&&this._dragStart.handle===s||(this._pushUndo(),this._dragStart={id:e,handle:s,points:n.points.map(t=>({...t})),from:{time:t.fromTime??t.time,price:t.fromPrice??t.price}});const o=this._dragStart;if(null===s){const e=t.time-o.from.time,i=t.price-o.from.price;n.points=o.points.map(t=>({time:t.time+e,price:t.price+i}))}else s>=0&&s<n.points.length&&(n.points=o.points.map((e,i)=>i===s?{time:t.time,price:t.price}:{...e}));this._sync()}_onDragEnd(){if(null===this._dragStart)return;const t=this.get(this._dragStart.id);this._dragStart=null,void 0!==t&&this._chart.emit("draw:update",{drawing:t})}_layerFor(t){let e=this._layers.get(t);return void 0===e&&(e=new Rt,this._chart.addPrimitive(e,t),this._layers.set(t,e)),e}_sync(){const t=new Map;for(const e of this._drawings){const i=t.get(e.paneIndex)??[];i.push(e),t.set(e.paneIndex,i)}for(const[e,i]of t)this._layerFor(e).setDrawings(i);for(const[e,i]of this._layers)t.has(e)||i.setDrawings([]),i.setSelected(this._selected);this._chart.setDrawingState(this.toJSON())}_syncPreview(){for(const t of this._layers.values())t.setPreview(null);if(null===this._tool||0===this._pending.length)return;const t=this._lastCursor,e=null===t?this._pending:[...this._pending,{time:t.time,price:t.price}];this._layerFor(this._pendingPane).setPreview({id:"__preview",tool:this._tool,points:e,style:this._opts.defaultStyle,paneIndex:this._pendingPane})}_pushUndo(){this._undo.push(JSON.stringify(this._drawings)),this._undo.length>this._opts.historyLimit&&this._undo.shift(),this._redo=[]}}const Ut="draw";Ct();export{F as ARROW,Nt as BUILTIN_DRAWING_TOOLS,C as CROSS_LINE,Ut as DRAW_TIER,jt as DrawingController,Rt as DrawingLayer,R as ELLIPSE,O as EXTENDED_LINE,B as FIB_EXTENSION,U as FIB_RETRACEMENT,A as HORIZONTAL_LINE,N as HORIZONTAL_RAY,E as LONG_POSITION,H as MEASURE,z as PARALLEL_CHANNEL,et as PATH,$ as RAY,I as RECTANGLE,Y as SHORT_POSITION,K as TEXT,D as TREND_LINE,W as VERTICAL_LINE,r as distToEllipse,e as distToLine,s as distToPolyline,l as distToRect,t as distToSegment,a as extendSegment,y as getDrawingTool,u as hasDrawingTool,o as rectOf,Ct as registerBuiltinDrawingTools,p as registerDrawingTool,f as registeredDrawingTools};
1
+ function t(t,e,i,n){const s=n.x-i.x,o=n.y-i.y,l=s*s+o*o;if(0===l)return Math.hypot(t-i.x,e-i.y);let r=((t-i.x)*s+(e-i.y)*o)/l;return r=r<0?0:r>1?1:r,Math.hypot(t-(i.x+r*s),e-(i.y+r*o))}function e(t,e,i,n){const s=n.x-i.x,o=n.y-i.y,l=Math.hypot(s,o);return 0===l?Math.hypot(t-i.x,e-i.y):Math.abs(o*(t-i.x)-s*(e-i.y))/l}function i(t,e){return Math.abs(t-e)}function n(t,e){return Math.abs(t-e)}function s(e,i,n){let s=1/0;for(let o=1;o<n.length;o++){const l=t(e,i,n[o-1],n[o]);l<s&&(s=l)}return s}function o(t,e){return{x0:Math.min(t.x,e.x),y0:Math.min(t.y,e.y),x1:Math.max(t.x,e.x),y1:Math.max(t.y,e.y)}}function l(e,i,n,s,l){const r=o(n,s);if(e>=r.x0&&e<=r.x1&&i>=r.y0&&i<=r.y1&&l)return 0;const a=[{x:r.x0,y:r.y0},{x:r.x1,y:r.y0},{x:r.x1,y:r.y1},{x:r.x0,y:r.y1}];let c=1/0;for(let n=0;n<4;n++){const s=t(e,i,a[n],a[(n+1)%4]);s<c&&(c=s)}return c}function r(t,e,i,n,s){const l=o(i,n),r=(l.x0+l.x1)/2,a=(l.y0+l.y1)/2,c=Math.max(1e-6,(l.x1-l.x0)/2),h=Math.max(1e-6,(l.y1-l.y0)/2),x=(t-r)/c,d=(e-a)/h,p=Math.hypot(x,d);return s&&p<=1?0:Math.abs(p-1)*Math.min(c,h)}function a(t,e,i,n,s){const o=e.x-t.x;if(0===o)return[t,e];const l=(e.y-t.y)/o;return[n?{x:0,y:t.y+(0-t.x)*l}:t,s?{x:i,y:t.y+(i-t.x)*l}:e]}function c(t){const e=function(t){const e=t.trim();if(e.startsWith("#")){const t=e.slice(1);if(3===t.length||4===t.length){const[e,i,n,s]=[...t].map(t=>parseInt(t+t,16));return[e,i,n].some(Number.isNaN)?null:{r:e,g:i,b:n,a:4===t.length?s/255:1}}if(6===t.length||8===t.length){const e=parseInt(t.slice(0,6),16);if(Number.isNaN(e))return null;const i=8===t.length?parseInt(t.slice(6,8),16)/255:1;return{r:e>>16&255,g:e>>8&255,b:255&e,a:Number.isNaN(i)?1:i}}return null}const i=/^rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)\s*(?:,\s*([\d.]+)\s*)?\)$/i.exec(e);return null===i?null:{r:Number(i[1]),g:Number(i[2]),b:Number(i[3]),a:void 0===i[4]?1:Number(i[4])}}(t);if(null===e)return.5;const i=t=>{const e=t/255;return e<=.03928?e/12.92:Math.pow((e+.055)/1.055,2.4)};return.2126*i(e.r)+.7152*i(e.g)+.0722*i(e.b)}function h(t){return c(t)>.45?"#10131a":"#ffffff"}function x(t,e,i,n,s,o){const l=t.roundRect;"function"==typeof l?l.call(t,e,i,n,s,Math.max(0,Math.min(o,n/2,s/2))):t.rect(e,i,n,s)}const d=new Map;function p(t){d.set(t.id,t)}function y(t){const e=d.get(t);if(void 0===e)throw new Error(`openalgo-charts: unknown drawing tool "${t}"`);return e}function u(t){return d.has(t)}function f(){return Array.from(d.values())}function g(t){const{ctx:e,rc:i,style:n}=t,s=i.dpr;e.strokeStyle=n.color,e.lineWidth=Math.max(1,Math.round(n.lineWidth*s)),e.lineJoin="round",e.lineCap="round",e.setLineDash("dashed"===n.lineStyle?[6*s,4*s]:"dotted"===n.lineStyle?[1*s,3*s]:[])}function m(t){return t.style.fillColor??t.style.color}function b(t,e){if(!0!==t.style.fill)return;const{ctx:i}=t;i.save(),i.globalAlpha=t.style.fillOpacity??.12,i.fillStyle=m(t),e(),i.restore()}function _(t,e,i,n,s){const{ctx:o,rc:l,style:r}=t,a=(r.fontSize??11)*l.dpr;o.save(),o.setLineDash([]),o.font=`${a}px ui-sans-serif, system-ui, sans-serif`,o.textBaseline="middle",o.textAlign="left";const c=o.measureText(e).width;o.globalAlpha=.85,o.fillStyle=l.theme.background,o.fillRect(i-2*l.dpr,n-.75*a,c+4*l.dpr,1.5*a),o.globalAlpha=1,o.fillStyle=s??r.color,o.fillText(e,i,n),o.restore()}function w(t,e,i,n,s,o={}){const{ctx:l,rc:r}=t,a=r.dpr,c=(t.style.fontSize??11)*a;l.save(),l.setLineDash([]),l.globalAlpha=1,l.font=`${c}px ui-sans-serif, system-ui, sans-serif`,l.textBaseline="middle",l.textAlign="left";const d=5*a,p=3*a,y=1.35*c;let u=0;for(const t of e)u=Math.max(u,l.measureText(t).width);const f=u+2*d,g=y*e.length+2*p,m=o.align??"left",b="center"===m?i-f/2:"right"===m?i-f:i,_=o.place??"above",w="above"===_?n-g-4*a:"below"===_?n+4*a:n-g/2;l.beginPath(),x(l,b,w,f,g,3*a),l.fillStyle=s,l.fill(),l.fillStyle=h(s);for(let t=0;t<e.length;t++)l.fillText(e[t],b+d,w+p+y*(t+.5));return l.restore(),g}function M(t,e=0){const[i,n]=Math.abs(t).toFixed(e).split(".");return(t<0?"-":"")+i.replace(/\B(?=(\d{3})+(?!\d))/g,",")+(void 0===n?"":"."+n)}function v(t){const e=new Date(1e3*t),i=t=>String(t).padStart(2,"0");return`${e.getUTCFullYear()}-${i(e.getUTCMonth()+1)}-${i(e.getUTCDate())}`}function T(t){const e=Math.max(0,Math.round(Math.abs(t))),i=Math.floor(e/86400),n=Math.floor(e%86400/3600),s=Math.floor(e%3600/60);return i>0?`${i}d ${n}h`:n>0?`${n}h ${s}m`:`${s}m`}function S(t,e,i){const n=Math.max(8,5*t.style.lineWidth)*t.rc.dpr,s=Math.atan2(i.y-e.y,i.x-e.x);t.ctx.beginPath(),t.ctx.moveTo(i.x,i.y),t.ctx.lineTo(i.x-n*Math.cos(s-.4),i.y-n*Math.sin(s-.4)),t.ctx.lineTo(i.x-n*Math.cos(s+.4),i.y-n*Math.sin(s+.4)),t.ctx.closePath(),t.ctx.fillStyle=t.style.color,t.ctx.fill()}const P="#26a69a",L="#ef5350",k=[0,.236,.382,.5,.618,.786,1];function D(i,n,s,o){return{id:i,name:n,points:2,defaultStyle:{extendLeft:s,extendRight:o},draw:t=>{const[e,i]=a(t.pts[0],t.pts[1],t.rc.plotWidth*t.rc.dpr,t.style.extendLeft??s,t.style.extendRight??o);g(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.lineTo(i.x,i.y),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(i,n,l)=>{const r=l.drawing.style.extendLeft??s,c=l.drawing.style.extendRight??o;if(r&&c)return e(i,n,l.pts[0],l.pts[1]);const[h,x]=a(l.pts[0],l.pts[1],l.rc.plotWidth,r,c);return t(i,n,h,x)}}}const $=D("trend-line","Trend Line",!1,!1),O=D("ray","Ray",!1,!0),F=D("extended-line","Extended Line",!0,!0),A={id:"arrow",name:"Arrow",points:2,draw:t=>{const[e,i]=t.pts;g(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.lineTo(i.x,i.y),t.ctx.stroke();const n=Math.max(8,5*t.style.lineWidth)*t.rc.dpr,s=Math.atan2(i.y-e.y,i.x-e.x);t.ctx.beginPath(),t.ctx.moveTo(i.x,i.y),t.ctx.lineTo(i.x-n*Math.cos(s-.4),i.y-n*Math.sin(s-.4)),t.ctx.lineTo(i.x-n*Math.cos(s+.4),i.y-n*Math.sin(s+.4)),t.ctx.closePath(),t.ctx.fillStyle=t.style.color,t.ctx.fill(),t.ctx.setLineDash([])},distance:(e,i,n)=>t(e,i,n.pts[0],n.pts[1])},N={id:"horizontal-line",name:"Horizontal Line",points:1,defaultStyle:{showLabels:!0},draw:t=>{const e=Math.round(t.pts[0].y)+.5;g(t),t.ctx.beginPath(),t.ctx.moveTo(0,e),t.ctx.lineTo(t.rc.plotWidth*t.rc.dpr,e),t.ctx.stroke(),t.ctx.setLineDash([]),!1!==t.style.showLabels&&_(t,t.formatPrice(t.drawing.points[0].price),4*t.rc.dpr,e-8*t.rc.dpr)},distance:(t,e,n)=>i(e,n.pts[0].y)},W={id:"horizontal-ray",name:"Horizontal Ray",points:1,defaultStyle:{showLabels:!0},draw:t=>{const e=Math.round(t.pts[0].y)+.5;g(t),t.ctx.beginPath(),t.ctx.moveTo(t.pts[0].x,e),t.ctx.lineTo(t.rc.plotWidth*t.rc.dpr,e),t.ctx.stroke(),t.ctx.setLineDash([]),!1!==t.style.showLabels&&_(t,t.formatPrice(t.drawing.points[0].price),t.pts[0].x+4*t.rc.dpr,e-8*t.rc.dpr)},distance:(t,e,n)=>t<n.pts[0].x?null:i(e,n.pts[0].y)},C={id:"vertical-line",name:"Vertical Line",points:1,draw:t=>{const e=Math.round(t.pts[0].x)+.5;g(t),t.ctx.beginPath(),t.ctx.moveTo(e,0),t.ctx.lineTo(e,t.rc.plotHeight*t.rc.dpr),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>n(t,i.pts[0].x)},I={id:"cross-line",name:"Cross Line",points:1,draw:t=>{const e=Math.round(t.pts[0].x)+.5,i=Math.round(t.pts[0].y)+.5;g(t),t.ctx.beginPath(),t.ctx.moveTo(e,0),t.ctx.lineTo(e,t.rc.plotHeight*t.rc.dpr),t.ctx.moveTo(0,i),t.ctx.lineTo(t.rc.plotWidth*t.rc.dpr,i),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,s)=>Math.min(n(t,s.pts[0].x),i(e,s.pts[0].y))},R={id:"rectangle",name:"Rectangle",points:2,defaultStyle:{fill:!0,fontSize:14,textAlign:"left",textVAlign:"top",textPosition:"inside"},draw:t=>{const e=o(t.pts[0],t.pts[1]);b(t,()=>t.ctx.fillRect(e.x0,e.y0,e.x1-e.x0,e.y1-e.y0)),g(t),t.ctx.strokeRect(e.x0,e.y0,e.x1-e.x0,e.y1-e.y0),t.ctx.setLineDash([]),Z(t,e.x0,e.y0,e.x1,e.y1)},distance:(t,e,i)=>l(t,e,i.pts[0],i.pts[1],!0===i.drawing.style.fill)},z={id:"ellipse",name:"Ellipse",points:2,defaultStyle:{fill:!0,fontSize:14,textAlign:"center",textVAlign:"middle",textPosition:"inside"},draw:t=>{const e=o(t.pts[0],t.pts[1]),i=(e.x0+e.x1)/2,n=(e.y0+e.y1)/2,s=Math.max(1,(e.x1-e.x0)/2),l=Math.max(1,(e.y1-e.y0)/2),r=()=>{t.ctx.beginPath(),t.ctx.ellipse(i,n,s,l,0,0,2*Math.PI)};b(t,()=>{r(),t.ctx.fill()}),g(t),r(),t.ctx.stroke(),t.ctx.setLineDash([]),Z(t,e.x0,e.y0,e.x1,e.y1)},distance:(t,e,i)=>r(t,e,i.pts[0],i.pts[1],!0===i.drawing.style.fill)},j={id:"parallel-channel",name:"Parallel Channel",points:3,defaultStyle:{fill:!0},draw:t=>{const[e,i,n]=t.pts,s=n.y-(e.y+.5*(i.y-e.y)),o={x:e.x,y:e.y+s},l={x:i.x,y:i.y+s};b(t,()=>{t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.lineTo(i.x,i.y),t.ctx.lineTo(l.x,l.y),t.ctx.lineTo(o.x,o.y),t.ctx.closePath(),t.ctx.fill()}),g(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.lineTo(i.x,i.y),t.ctx.moveTo(o.x,o.y),t.ctx.lineTo(l.x,l.y),t.ctx.stroke(),t.ctx.setLineDash([]),Z(t,Math.min(e.x,i.x),Math.min(e.y,i.y,o.y,l.y),Math.max(e.x,i.x),Math.max(e.y,i.y,o.y,l.y))},distance:(e,i,n)=>{const[s,o,l]=n.pts,r=l.y-(s.y+.5*(o.y-s.y)),a=t(e,i,s,o),c=t(e,i,{x:s.x,y:s.y+r},{x:o.x,y:o.y+r});return Math.min(a,c)}};function U(t,e,i){return{id:t,name:e,points:i,defaultStyle:{showLabels:!0,levels:[...k],fill:!0,fillOpacity:.06},draw:t=>{const e=t.style.levels??k,n=t.drawing.points,s=2===i?n[0].price:n[2].price,o=n[1].price-n[0].price,l=Math.min(t.pts[0].x,t.pts[i-1].x),r=Math.max(t.pts[0].x,t.pts[i-1].x),a=!0===t.style.extendRight?t.rc.plotWidth*t.rc.dpr:r;g(t);let c=null;for(const i of e){const e=s+o*i,n=Math.round(t.rc.priceScale.priceToY(e)*t.rc.dpr)+.5;!0===t.style.fill&&null!==c&&(t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.06,t.ctx.fillStyle=m(t),t.ctx.fillRect(l,Math.min(c,n),a-l,Math.abs(n-c)),t.ctx.restore()),c=n,t.ctx.beginPath(),t.ctx.moveTo(l,n),t.ctx.lineTo(a,n),t.ctx.stroke(),!1!==t.style.showLabels&&_(t,`${(100*i).toFixed(1)}% ${t.formatPrice(e)}`,l+4*t.rc.dpr,n-8*t.rc.dpr)}t.ctx.setLineDash([])},distance:(t,e,n)=>{const s=n.drawing.style.levels??k,o=n.drawing.points,l=2===i?o[0].price:o[2].price,r=o[1].price-o[0].price,a=Math.min(n.pts[0].x,n.pts[i-1].x),c=!0===n.drawing.style.extendRight?n.rc.plotWidth:Math.max(n.pts[0].x,n.pts[i-1].x);if(t<a-4||t>c+4)return null;let h=1/0;for(const t of s){const i=Math.abs(e-n.rc.priceScale.priceToY(l+r*t));i<h&&(h=i)}return h}}}const B=U("fib-retracement","Fib Retracement",2),H=U("fib-extension","Fib Extension",3),J={id:"measure",name:"Measure",points:2,defaultStyle:{fill:!0,showLabels:!0,fillOpacity:.14},draw:t=>{const e=o(t.pts[0],t.pts[1]),i=t.rc.dpr,n=t.drawing.points,s=n[1].price-n[0].price,l=0!==n[0].price?s/n[0].price*100:0,r=s>=0,a=r?P:L;t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.14,t.ctx.fillStyle=a,t.ctx.fillRect(e.x0,e.y0,e.x1-e.x0,e.y1-e.y0),t.ctx.restore(),g(t),t.ctx.strokeStyle=a,t.ctx.strokeRect(e.x0,e.y0,e.x1-e.x0,e.y1-e.y0),t.ctx.setLineDash([]);const c=(e.x0+e.x1)/2,h=t.pts[0].y,x=t.pts[1].y;if(t.ctx.strokeStyle=a,t.ctx.beginPath(),t.ctx.moveTo(e.x0,h),t.ctx.lineTo(e.x1,h),t.ctx.stroke(),S(t,{x:e.x0,y:h},{x:e.x1,y:h}),t.ctx.beginPath(),t.ctx.moveTo(c,h),t.ctx.lineTo(c,x),t.ctx.stroke(),S(t,{x:c,y:h},{x:c,y:x}),!1===t.style.showLabels)return;const d=t.rc.dataLayer.timeToIndexFloat(n[0].time),p=t.rc.dataLayer.timeToIndexFloat(n[1].time),y=Math.abs(Math.round(p-d)),u=r?"+":"",f=[`${u}${t.formatPrice(s)} (${u}${l.toFixed(2)}%)`,`${M(y)} bars, ${T(n[1].time-n[0].time)}`],m=t.rc.bars?.();if(void 0!==m&&m.length>0){const t=Math.min(n[0].time,n[1].time),e=Math.max(n[0].time,n[1].time);let i=0,s=!1;for(const n of m)if(!(n.time<t)){if(n.time>e)break;void 0!==n.volume&&(i+=n.volume,s=!0)}s&&f.push(`Vol ${function(t){const e=Math.abs(t);return e>=1e9?`${(t/1e9).toFixed(2)}B`:e>=1e6?`${(t/1e6).toFixed(2)}M`:e>=1e3?`${(t/1e3).toFixed(2)}K`:M(t)}(i)}`)}w(t,f,c,Math.max(h,x)+6*i,a,{align:"center",place:"below"})},distance:(t,e,i)=>l(t,e,i.pts[0],i.pts[1],!0)};function E(t,e,i){return{id:t,name:e,points:1,defaultStyle:{showLabels:!0,fillOpacity:.13,accountSize:1e5,risk:1},expand:(t,e)=>{const n=t[0],s=.01*Math.abs(n.price)||1,o=Math.max(5,Math.round(.08*e.visibleBars)),l=n.time+Math.max(1,e.barSeconds)*o;return i?[n,{time:l,price:n.price+s},{time:l,price:n.price-s}]:[n,{time:l,price:n.price-s},{time:l,price:n.price+s}]},draw:t=>{if(t.drawing.points.length<3||t.pts.length<3)return;const[e,n,s]=t.drawing.points,o=t.rc.dpr,l=Math.min(t.pts[0].x,t.pts[1].x,t.pts[2].x),r=Math.max(t.pts[0].x,t.pts[1].x,t.pts[2].x),a=t.rc.priceScale.priceToY(e.price)*o,c=t.rc.priceScale.priceToY(n.price)*o,h=t.rc.priceScale.priceToY(s.price)*o,x=(e,i,n)=>{t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.13,t.ctx.fillStyle=n,t.ctx.fillRect(l,Math.min(e,i),r-l,Math.abs(i-e)),t.ctx.restore()};x(a,c,P),x(a,h,L),g(t);for(const e of[a,c,h]){const i=Math.round(e)+.5;t.ctx.beginPath(),t.ctx.moveTo(l,i),t.ctx.lineTo(r,i),t.ctx.stroke()}if(t.ctx.setLineDash([]),!1===t.style.showLabels)return;const d=Math.abs(e.price-s.price),p=Math.abs(n.price-e.price),y=d>0?p/d:0,u=t.style.accountSize??0,f=t.style.risk??0,m=d>0&&u>0?Math.floor(u*f/100/d):0,b=t=>(0!==e.price?t/e.price*100:0).toFixed(3),_=t=>m>0?`, Amount: ${M(m*t)}`:"",v=(l+r)/2;w(t,[`Target: ${t.formatPrice(p)} (${b(p)}%)${_(p)}`],v,c,P,{align:"center",place:c<=a?"above":"below"}),w(t,[`Stop: ${t.formatPrice(d)} (${b(d)}%)${_(d)}`],v,h,L,{align:"center",place:h>=a?"below":"above"}),w(t,[`${i?"Long":"Short"} · Qty: ${m>0?M(m):"—"}`,`Risk/reward ratio: ${y.toFixed(2)}`],v,a,t.rc.theme.background,{align:"center",place:"middle"})},distance:(t,e,i)=>{if(i.pts.length<3)return null;const n=Math.min(i.pts[0].x,i.pts[1].x,i.pts[2].x),s=Math.max(i.pts[0].x,i.pts[1].x,i.pts[2].x);if(t<n-4||t>s+4)return null;const o=i.drawing.points.map(t=>i.rc.priceScale.priceToY(t.price)),l=Math.min(...o),r=Math.max(...o);return e>=l&&e<=r?0:Math.min(Math.abs(e-l),Math.abs(e-r))}}}const Y=E("long-position","Long Position",!0),V=E("short-position","Short Position",!1),q=1.35,G="ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, sans-serif";function K(t,e){const i="bold"===t.fontWeight?"700 ":"";return`${"italic"===t.fontStyle?"italic ":""}${i}${e}px ${t.fontFamily??G}`}function Q(t,e,i){const n=(e.text??"").split("\n");if(!0!==e.wrap)return n;const s=[];for(const e of n){const n=e.split(/\s+/).filter(t=>""!==t);if(0===n.length){s.push("");continue}let o=n[0];for(let e=1;e<n.length;e++){const l=`${o} ${n[e]}`;t.measureText(l).width>i?(s.push(o),o=n[e]):o=l}s.push(o)}return s}function X(t,e,i){const n=(e.fontSize??13)*i;t.font=K(e,n);const s=Q(t,e,(e.wrapWidth??220)*i);let o=0;for(const e of s)o=Math.max(o,t.measureText(e).width);const l=n*q;return{lines:s,width:o+10*i,height:s.length*l+10*i,lineHeight:l}}function Z(t,e,i,n,s){const{ctx:o,rc:l,style:r}=t,a=r.text;if(void 0===a||""===a)return;const c=l.dpr,h=(r.fontSize??14)*c,x=6*c;o.save(),o.setLineDash([]),o.font=K(r,h),o.fillStyle=r.fontColor??r.color,o.textBaseline="top";const d=!0===r.wrap?Q(o,r,Math.max(20*c,n-e-2*x)):a.split("\n"),p=h*q,y=d.length*p,u=r.textAlign??"left";o.textAlign=u;const f="center"===u?(e+n)/2:"right"===u?n-x:e+x;let g;if("outside"===r.textPosition)g=i-y-x;else{const t=r.textVAlign??"top";g="middle"===t?(i+s-y)/2:"bottom"===t?s-y-x:i+x}for(const t of d)o.fillText(t,f,g),g+=p;o.restore()}const tt={id:"text",name:"Text",points:1,defaultStyle:{text:"Text",fontSize:14,fontWeight:"normal",fontStyle:"normal",background:!1,backgroundOpacity:1,border:!1,wrap:!1,wrapWidth:220,textAlign:"left"},draw:t=>{const{ctx:e,rc:i,style:n}=t,s=i.dpr,o=X(e,n,s),l=t.pts[0].x,r=t.pts[0].y;e.save(),e.setLineDash([]),!0===n.background&&(e.globalAlpha=n.backgroundOpacity??1,e.fillStyle=n.backgroundColor??i.theme.background,e.beginPath(),e.roundRect(l,r,o.width,o.height,4*s),e.fill(),e.globalAlpha=1),!0===n.border&&(e.strokeStyle=n.borderColor??n.color,e.lineWidth=Math.max(1,n.lineWidth*s),e.beginPath(),e.roundRect(l,r,o.width,o.height,4*s),e.stroke()),e.font=K(n,(n.fontSize??13)*s),e.fillStyle=n.color,e.textBaseline="top";const a=n.textAlign??"left";e.textAlign=a;const c="center"===a?l+o.width/2:"right"===a?l+o.width-5*s:l+5*s;let h=r+5*s;for(const t of o.lines)e.fillText(t,c,h),h+=o.lineHeight;e.restore()},distance:(t,e,i)=>{const n=i.drawing.style,s=n.fontSize??13,o=i.pts[0],l=function(){if(void 0!==et)return et;try{et="undefined"==typeof document?null:document.createElement("canvas").getContext("2d")}catch{et=null}return et}(),r=null===l?{width:(n.text??"").length*s*.6+10,height:s*q+10}:X(l,n,1);return t>=o.x-3&&t<=o.x+r.width+3&&e>=o.y-3&&e<=o.y+r.height+3?0:null}};let et;const it={id:"path",name:"Path",points:0,draw:t=>{if(!(t.pts.length<2)){g(t),t.ctx.beginPath(),t.ctx.moveTo(t.pts[0].x,t.pts[0].y);for(let e=1;e<t.pts.length;e++)t.ctx.lineTo(t.pts[e].x,t.pts[e].y);t.ctx.stroke(),t.ctx.setLineDash([]),S(t,t.pts[t.pts.length-2],t.pts[t.pts.length-1])}},distance:(t,e,i)=>i.pts.length<2?null:s(t,e,i.pts)},nt={id:"brush",name:"Brush",points:0,freehand:!0,defaultStyle:{lineWidth:2},draw:t=>{if(!(t.pts.length<2)){g(t),t.ctx.lineCap="round",t.ctx.lineJoin="round",t.ctx.beginPath(),t.ctx.moveTo(t.pts[0].x,t.pts[0].y);for(let e=1;e<t.pts.length;e++)t.ctx.lineTo(t.pts[e].x,t.pts[e].y);t.ctx.stroke(),t.ctx.setLineDash([])}},distance:(t,e,i)=>i.pts.length<2?null:s(t,e,i.pts)},st={id:"rotated-rectangle",name:"Rotated Rectangle",points:3,defaultStyle:{fill:!0,fillOpacity:.12},draw:t=>{if(t.pts.length<3)return;const e=ot(t.pts[0],t.pts[1],t.pts[2]);t.ctx.beginPath(),t.ctx.moveTo(e[0].x,e[0].y);for(let i=1;i<4;i++)t.ctx.lineTo(e[i].x,e[i].y);t.ctx.closePath(),!0===t.style.fill&&(t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.12,t.ctx.fillStyle=m(t),t.ctx.fill(),t.ctx.restore()),g(t),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(e,i,n)=>{if(n.pts.length<3)return null;const s=ot(n.pts[0],n.pts[1],n.pts[2]);if(!0===n.drawing.style.fill&&function(t,e,i){let n=!1;for(let s=0,o=i.length-1;s<i.length;o=s++){const l=i[s],r=i[o];l.y>e!=r.y>e&&t<(r.x-l.x)*(e-l.y)/(r.y-l.y)+l.x&&(n=!n)}return n}(e,i,s))return 0;let o=1/0;for(let n=0;n<4;n++)o=Math.min(o,t(e,i,s[n],s[(n+1)%4]));return o}};function ot(t,e,i){const n=e.x-t.x,s=e.y-t.y,o=Math.hypot(n,s)||1,l=-s/o,r=n/o,a=(i.x-e.x)*l+(i.y-e.y)*r;return[t,e,{x:e.x+l*a,y:e.y+r*a},{x:t.x+l*a,y:t.y+r*a}]}const lt={id:"double-curve",name:"Double Curve",points:3,draw:t=>{if(t.pts.length<3)return;const[e,i,n]=t.pts;g(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.bezierCurveTo(i.x,i.y,e.x+n.x-i.x,e.y+n.y-i.y,n.x,n.y),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>{if(i.pts.length<3)return null;const[n,o,l]=i.pts;return s(t,e,function(t,e,i,n,s){const o=[];for(let l=0;l<=s;l++){const r=l/s,a=1-r,c=a*a*a,h=3*a*a*r,x=3*a*r*r,d=r*r*r;o.push({x:c*t.x+h*e.x+x*i.x+d*n.x,y:c*t.y+h*e.y+x*i.y+d*n.y})}return o}(n,o,{x:n.x+l.x-o.x,y:n.y+l.y-o.y},l,24))}};const rt={id:"cyclic-lines",name:"Cyclic Lines",points:2,defaultStyle:{lineStyle:"dashed"},draw:t=>{const[e,i]=t.pts,n=i.x-e.x;if(!Number.isFinite(n)||Math.abs(n)<.5)return;const s=t.rc.plotHeight*t.rc.dpr,o=t.rc.plotWidth*t.rc.dpr;g(t),t.ctx.beginPath();for(let i=0;i<=12;i++){const l=Math.round(e.x+n*i)+.5;l<0||l>o||(t.ctx.moveTo(l,0),t.ctx.lineTo(l,s))}t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>{const n=i.pts[1].x-i.pts[0].x;if(!Number.isFinite(n)||Math.abs(n)<.5)return null;const s=Math.round((t-i.pts[0].x)/n);return s<0||s>12?null:Math.abs(t-(i.pts[0].x+n*s))}},at={id:"time-cycles",name:"Time Cycles",points:2,draw:t=>{const[e,i]=t.pts,n=i.x-e.x;if(!Number.isFinite(n)||Math.abs(n)<1)return;const s=Math.abs(n)/2;g(t),t.ctx.beginPath();for(let i=0;i<12;i++){const o=e.x+n*i+n/2;o+s<0||o-s>t.rc.plotWidth*t.rc.dpr||(t.ctx.moveTo(o+s,e.y),t.ctx.arc(o,e.y,s,0,Math.PI,!0))}t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>{const[n,s]=i.pts,o=s.x-n.x;if(!Number.isFinite(o)||Math.abs(o)<1)return null;const l=Math.abs(o)/2;let r=1/0;for(let i=0;i<12;i++){const s=n.x+o*i+o/2;e>n.y+2||(r=Math.min(r,Math.abs(Math.hypot(t-s,e-n.y)-l)))}return Number.isFinite(r)?r:null}},ct={id:"sine-line",name:"Sine Line",points:2,draw:t=>{const e=ht(t.pts[0],t.pts[1]);if(null!==e){g(t),t.ctx.beginPath(),t.ctx.moveTo(e[0].x,e[0].y);for(let i=1;i<e.length;i++)t.ctx.lineTo(e[i].x,e[i].y);t.ctx.stroke(),t.ctx.setLineDash([])}},distance:(t,e,i)=>{const n=ht(i.pts[0],i.pts[1]);return null===n?null:s(t,e,n)}};function ht(t,e){const i=e.x-t.x,n=e.y-t.y;if(!Number.isFinite(i)||Math.abs(i)<1)return null;const s=[];for(let e=0;e<=64;e++){const o=e/64;s.push({x:t.x+i*o,y:t.y+n*Math.sin(o*Math.PI*2)})}return s}const xt={id:"price-label",name:"Price Label",points:1,defaultStyle:{fontSize:12},draw:t=>{const e=t.pts[0],i=t.rc.dpr,n=void 0!==t.style.text&&""!==t.style.text?t.style.text:t.formatPrice(t.drawing.points[0].price),s=pt(t,[n],e.x+18*i,e.y-30*i);yt(t,s,e,t.style.color),ut(t,s,[n],t.style.color)},distance:(t,e,i)=>{const n=i.pts[0],s=n.x+18,o=n.y-30-11;return t>=s&&t<=s+64&&e>=o&&e<=o+22||Math.hypot(t-n.x,e-n.y)<=10?0:null}},dt={id:"callout",name:"Callout",points:2,defaultStyle:{fontSize:12,text:"Note"},draw:t=>{if(t.pts.length<2)return;const[e,i]=t.pts,n=(t.style.text??"Note").split("\n"),s=pt(t,n,i.x,i.y);yt(t,s,e,t.style.color),ut(t,s,n,t.style.color)},distance:(e,i,n)=>{if(n.pts.length<2)return null;const[s,o]=n.pts;return Math.abs(e-o.x)<=60&&Math.abs(i-o.y)<=16?0:t(e,i,s,o)}};function pt(t,e,i,n){const s=t.rc.dpr,o=(t.style.fontSize??12)*s;t.ctx.save(),t.ctx.font=`${o}px ui-sans-serif, system-ui, sans-serif`;let l=0;for(const i of e)l=Math.max(l,t.ctx.measureText(i).width);t.ctx.restore();const r=l+14*s,a=1.4*o*e.length+8*s;return{x:i-r/2,y:n-a/2,w:r,h:a}}function yt(t,e,i,n){const s=t.rc.dpr,o=e.x+e.w/2,l=e.y+e.h/2,r=Math.atan2(i.y-l,i.x-o),a=5*s,c=o+Math.cos(r)*(e.w/2-a),h=l+Math.sin(r)*(e.h/2-a);t.ctx.save(),t.ctx.setLineDash([]),t.ctx.fillStyle=n,t.ctx.beginPath(),t.ctx.moveTo(i.x,i.y),t.ctx.lineTo(c-Math.sin(r)*a,h+Math.cos(r)*a),t.ctx.lineTo(c+Math.sin(r)*a,h-Math.cos(r)*a),t.ctx.closePath(),t.ctx.fill(),t.ctx.beginPath(),x(t.ctx,e.x,e.y,e.w,e.h,5*s),t.ctx.fill(),t.ctx.beginPath(),t.ctx.arc(i.x,i.y,2.5*s,0,2*Math.PI),t.ctx.fill(),t.ctx.restore()}function ut(t,e,i,n){const s=t.rc.dpr,o=(t.style.fontSize??12)*s;t.ctx.save(),t.ctx.setLineDash([]),t.ctx.font=`${o}px ui-sans-serif, system-ui, sans-serif`,t.ctx.textAlign="center",t.ctx.textBaseline="middle",t.ctx.fillStyle=t.style.fontColor??h(n);const l=1.4*o,r=e.y+e.h/2-l*(i.length-1)/2;for(let n=0;n<i.length;n++)t.ctx.fillText(i[n],e.x+e.w/2,r+l*n);t.ctx.restore()}const ft={id:"flag-mark",name:"Flag Mark",points:1,defaultStyle:{fill:!0,fillOpacity:.95},draw:t=>{const e=t.pts[0],i=t.rc.dpr,n=22*i,s=15*i,o=11*i;g(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.lineTo(e.x,e.y-n),t.ctx.stroke(),t.ctx.setLineDash([]),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y-n),t.ctx.lineTo(e.x+s,e.y-n+.28*o),t.ctx.lineTo(e.x+.72*s,e.y-n+.5*o),t.ctx.lineTo(e.x+s,e.y-n+.72*o),t.ctx.lineTo(e.x,e.y-n+o),t.ctx.closePath(),t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.95,t.ctx.fillStyle=m(t),t.ctx.fill(),t.ctx.restore()},distance:(t,e,i)=>{const n=i.pts[0];return t>=n.x-4&&t<=n.x+16&&e>=n.y-24&&e<=n.y+2||Math.hypot(t-n.x,e-n.y)<=8?0:null}},gt={id:"price-range",name:"Price Range",points:2,defaultStyle:{fill:!0,showLabels:!0,fillOpacity:.1},draw:t=>{const e=t.rc.dpr,i=t.drawing.points,n=i[1].price-i[0].price,s=0!==i[0].price?n/i[0].price*100:0,o=n>=0,l=o?"#26a69a":"#ef5350",r=Math.min(t.pts[0].x,t.pts[1].x),a=Math.max(t.pts[0].x,t.pts[1].x)+(t.pts[0].x===t.pts[1].x?60*e:0),c=t.pts[0].y,h=t.pts[1].y;t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.1,t.ctx.fillStyle=l,t.ctx.fillRect(r,Math.min(c,h),a-r,Math.abs(h-c)),t.ctx.restore(),g(t),t.ctx.strokeStyle=l,t.ctx.beginPath();for(const e of[c,h])t.ctx.moveTo(r,Math.round(e)+.5),t.ctx.lineTo(a,Math.round(e)+.5);const x=(r+a)/2;t.ctx.moveTo(x,c),t.ctx.lineTo(x,h);const d=h>c?1:-1;t.ctx.moveTo(x-4*e,h-5*e*d),t.ctx.lineTo(x,h),t.ctx.lineTo(x+4*e,h-5*e*d),t.ctx.moveTo(x-4*e,c+5*e*d),t.ctx.lineTo(x,c),t.ctx.lineTo(x+4*e,c+5*e*d),t.ctx.stroke(),t.ctx.setLineDash([]);const p=o?"+":"";_(t,`${p}${t.formatPrice(n)} (${p}${s.toFixed(2)}%)`,x+6*e,(c+h)/2,l)},distance:(t,e,i)=>l(t,e,i.pts[0],i.pts[1],!0)},mt={id:"date-range",name:"Date Range",points:2,defaultStyle:{fill:!0,showLabels:!0,fillOpacity:.1},draw:t=>{const e=t.rc.dpr,i=t.drawing.points,n=t.style.color,s=t.pts[0].x,o=t.pts[1].x,l=Math.min(t.pts[0].y,t.pts[1].y),r=Math.max(t.pts[0].y,t.pts[1].y)+(t.pts[0].y===t.pts[1].y?40*e:0);t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.1,t.ctx.fillStyle=n,t.ctx.fillRect(Math.min(s,o),l,Math.abs(o-s),r-l),t.ctx.restore(),g(t),t.ctx.beginPath();for(const e of[s,o])t.ctx.moveTo(Math.round(e)+.5,l),t.ctx.lineTo(Math.round(e)+.5,r);const a=(l+r)/2;t.ctx.moveTo(s,a),t.ctx.lineTo(o,a);const c=o>s?1:-1;t.ctx.moveTo(o-5*e*c,a-4*e),t.ctx.lineTo(o,a),t.ctx.lineTo(o-5*e*c,a+4*e),t.ctx.moveTo(s+5*e*c,a-4*e),t.ctx.lineTo(s,a),t.ctx.lineTo(s+5*e*c,a+4*e),t.ctx.stroke(),t.ctx.setLineDash([]);const h=t.rc.dataLayer.timeToIndexFloat(i[0].time),x=t.rc.dataLayer.timeToIndexFloat(i[1].time);_(t,`${Math.abs(Math.round(x-h))} bars`,(s+o)/2,l-10*e,n)},distance:(t,e,i)=>l(t,e,i.pts[0],i.pts[1],!0)},bt={id:"forecast",name:"Forecast",points:2,defaultStyle:{fill:!0,showLabels:!0,fillOpacity:.12,lineStyle:"dashed"},draw:t=>{const e=t.rc.dpr,i=t.drawing.points,[n,s]=t.pts,o=i[1].price-i[0].price,l=0!==i[0].price?o/i[0].price*100:0,r=o>=0,a=r?"#26a69a":"#ef5350",c=.35*Math.abs(s.y-n.y)+6*e;if(t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.12,t.ctx.fillStyle=a,t.ctx.beginPath(),t.ctx.moveTo(n.x,n.y),t.ctx.lineTo(s.x,s.y-c),t.ctx.lineTo(s.x,s.y+c),t.ctx.closePath(),t.ctx.fill(),t.ctx.restore(),g(t),t.ctx.strokeStyle=a,t.ctx.beginPath(),t.ctx.moveTo(n.x,n.y),t.ctx.lineTo(s.x,s.y),t.ctx.stroke(),t.ctx.setLineDash([]),t.ctx.beginPath(),t.ctx.arc(n.x,n.y,3*e,0,2*Math.PI),t.ctx.fillStyle=a,t.ctx.fill(),!1===t.style.showLabels)return;const h=r?"+":"";w(t,[t.formatPrice(i[0].price),v(i[0].time)],n.x,n.y,a,{align:"center"}),w(t,[`${h}${t.formatPrice(o)} (${h}${l.toFixed(2)}%) in ${T(i[1].time-i[0].time)}`,`${t.formatPrice(i[1].price)} · ${v(i[1].time)}`],s.x,s.y,a,{align:"center",place:"below"});const x=t.rc.bars?.();if(void 0!==x&&x.length>0&&x[x.length-1].time>=i[1].time){let n=!1;for(const t of x)if(!(t.time<i[0].time)){if(t.time>i[1].time)break;if(r?t.high>=i[1].price:t.low<=i[1].price){n=!0;break}}w(t,[n?"SUCCESS":"MISSED"],s.x,s.y+36*e,n?"#4a934a":"#8a4a4a",{align:"center",place:"below"})}},distance:(e,i,n)=>t(e,i,n.pts[0],n.pts[1])},_t={id:"circle",name:"Circle",points:2,defaultStyle:{fill:!0},draw:t=>{const[e,i]=t.pts,n=Math.hypot(i.x-e.x,i.y-e.y);t.ctx.beginPath(),t.ctx.arc(e.x,e.y,n,0,2*Math.PI),b(t,()=>t.ctx.fill()),g(t),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>{const[n,s]=i.pts,o=Math.hypot(s.x-n.x,s.y-n.y),l=Math.hypot(t-n.x,e-n.y);return!0===i.drawing.style.fill&&l<=o?0:Math.abs(l-o)}},wt={id:"triangle",name:"Triangle",points:3,defaultStyle:{fill:!0},draw:t=>{t.ctx.beginPath(),t.ctx.moveTo(t.pts[0].x,t.pts[0].y),t.ctx.lineTo(t.pts[1].x,t.pts[1].y),t.ctx.lineTo(t.pts[2].x,t.pts[2].y),t.ctx.closePath(),b(t,()=>t.ctx.fill()),g(t),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>s(t,e,[...i.pts,i.pts[0]])},Mt={id:"polyline",name:"Polyline",points:0,defaultStyle:{fill:!1},draw:t=>{if(!(t.pts.length<2)){t.ctx.beginPath(),t.ctx.moveTo(t.pts[0].x,t.pts[0].y);for(let e=1;e<t.pts.length;e++)t.ctx.lineTo(t.pts[e].x,t.pts[e].y);!0===t.style.fill&&(t.ctx.closePath(),b(t,()=>t.ctx.fill())),g(t),t.ctx.stroke(),t.ctx.setLineDash([])}},distance:(t,e,i)=>s(t,e,i.pts)};const vt={id:"arc",name:"Arc",points:3,draw:t=>{const[e,i,n]=t.pts;g(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.quadraticCurveTo(2*i.x-(e.x+n.x)/2,2*i.y-(e.y+n.y)/2,n.x,n.y),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>s(t,e,function(t,e,i){const n=2*e.x-(t.x+i.x)/2,s=2*e.y-(t.y+i.y)/2,o=[];for(let e=0;e<=16;e++){const l=e/16,r=1-l;o.push({x:r*r*t.x+2*r*l*n+l*l*i.x,y:r*r*t.y+2*r*l*s+l*l*i.y})}return o}(i.pts[0],i.pts[1],i.pts[2]))},Tt={id:"curve",name:"Curve",points:3,draw:t=>{const[e,i,n]=t.pts;g(t),t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.quadraticCurveTo(i.x,i.y,n.x,n.y),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>{const[n,o,l]=i.pts,r=[];for(let t=0;t<=16;t++){const e=t/16,i=1-e;r.push({x:i*i*n.x+2*i*e*o.x+e*e*l.x,y:i*i*n.y+2*i*e*o.y+e*e*l.y})}return s(t,e,r)}};function St(t,e,i){return{id:t,name:e,points:1,defaultStyle:{fill:!0,fillOpacity:.9},draw:t=>{const e=t.rc.dpr,{x:n,y:s}=t.pts[0],o=16*e,l=6*e,r=i?1:-1,a=s+2*r*e;t.ctx.beginPath(),t.ctx.moveTo(n,a),t.ctx.lineTo(n-l,a+r*l),t.ctx.lineTo(n-l/2.4,a+r*l),t.ctx.lineTo(n-l/2.4,a+r*o),t.ctx.lineTo(n+l/2.4,a+r*o),t.ctx.lineTo(n+l/2.4,a+r*l),t.ctx.lineTo(n+l,a+r*l),t.ctx.closePath(),t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.9,t.ctx.fillStyle=m(t),t.ctx.fill(),t.ctx.restore(),g(t),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,n)=>{const s=n.pts[0],o=i?e-s.y:s.y-e;return Math.abs(t-s.x)<=8&&o>=-4&&o<=20?0:null}}}const Pt=St("arrow-up","Arrow Up",!0),Lt=St("arrow-down","Arrow Down",!1),kt={id:"highlighter",name:"Highlighter",points:0,freehand:!0,defaultStyle:{lineWidth:12,fillOpacity:.28},draw:t=>{if(t.pts.length<2)return;const e=t.rc.dpr;t.ctx.save(),t.ctx.globalAlpha=t.style.fillOpacity??.28,t.ctx.strokeStyle=t.style.color,t.ctx.lineWidth=Math.max(2,(t.style.lineWidth||12)*e),t.ctx.lineCap="round",t.ctx.lineJoin="round",t.ctx.beginPath(),t.ctx.moveTo(t.pts[0].x,t.pts[0].y);for(let e=1;e<t.pts.length;e++)t.ctx.lineTo(t.pts[e].x,t.pts[e].y);t.ctx.stroke(),t.ctx.restore()},distance:(t,e,i)=>{const n=s(t,e,i.pts);return n<=Math.max(6,(i.drawing.style.lineWidth??12)/2)?0:n}},Dt={id:"fib-channel",name:"Fib Channel",points:3,defaultStyle:{showLabels:!0,levels:[...k]},draw:t=>{const e=t.style.levels??k,[i,n,s]=t.pts,o=s.x-n.x,l=s.y-n.y;g(t);for(const s of e)t.ctx.beginPath(),t.ctx.moveTo(i.x+o*s,i.y+l*s),t.ctx.lineTo(n.x+o*s,n.y+l*s),t.ctx.stroke(),!1!==t.style.showLabels&&_(t,`${(100*s).toFixed(1)}%`,n.x+o*s+4*t.rc.dpr,n.y+l*s);t.ctx.setLineDash([])},distance:(e,i,n)=>{const s=n.drawing.style.levels??k,[o,l,r]=n.pts;let a=1/0;for(const n of s){const s=t(e,i,{x:o.x+(r.x-l.x)*n,y:o.y+(r.y-l.y)*n},{x:l.x+(r.x-l.x)*n,y:l.y+(r.y-l.y)*n});s<a&&(a=s)}return a}},$t=[0,1,2,3,5,8,13,21,34,55],Ot={id:"fib-time-zone",name:"Fib Time Zone",points:2,defaultStyle:{showLabels:!0},draw:t=>{const[e,i]=t.pts,n=i.x-e.x;if(Math.abs(n)<.5)return;const s=t.rc.dpr,o=t.rc.plotWidth*s;g(t);for(const i of $t){const l=e.x+n*i;l<-10||l>o+10||(t.ctx.beginPath(),t.ctx.moveTo(Math.round(l)+.5,0),t.ctx.lineTo(Math.round(l)+.5,t.rc.plotHeight*s),t.ctx.stroke(),!1!==t.style.showLabels&&_(t,String(i),l+3*s,12*s))}t.ctx.setLineDash([])},distance:(t,e,i)=>{const[n,s]=i.pts,o=s.x-n.x;if(Math.abs(o)<.5)return null;let l=1/0;for(const e of $t)l=Math.min(l,Math.abs(t-(n.x+o*e)));return l}},Ft=[.236,.382,.5,.618,.786,1],At={id:"fib-fan",name:"Fib Speed Fan",points:2,defaultStyle:{showLabels:!0,levels:[...Ft]},draw:t=>{const e=t.style.levels??Ft,[i,n]=t.pts,s=t.rc.dpr,o=t.rc.plotWidth*s;g(t);for(const l of e){const e=a(i,{x:n.x,y:i.y+(n.y-i.y)*l},o,!1,!0)[1];t.ctx.beginPath(),t.ctx.moveTo(i.x,i.y),t.ctx.lineTo(e.x,e.y),t.ctx.stroke(),!1!==t.style.showLabels&&_(t,`${(100*l).toFixed(1)}%`,n.x+4*s,i.y+(n.y-i.y)*l)}t.ctx.setLineDash([])},distance:(e,i,n)=>{const s=n.drawing.style.levels??Ft,[o,l]=n.pts;let r=1/0;for(const c of s)r=Math.min(r,t(e,i,o,a(o,{x:l.x,y:o.y+(l.y-o.y)*c},n.rc.plotWidth,!1,!0)[1]));return r}},Nt=[[1,.125],[1,.25],[1,.5],[1,1],[.5,1],[.25,1],[.125,1]],Wt=[$,O,F,A,N,W,C,I,R,z,j,B,H,Y,V,bt,J,gt,mt,_t,wt,Mt,vt,Tt,st,lt,Pt,Lt,kt,nt,Dt,Ot,At,{id:"gann-fan",name:"Gann Fan",points:2,defaultStyle:{showLabels:!0},draw:t=>{const[e,i]=t.pts,n=t.rc.dpr,s=t.rc.plotWidth*n,o=i.x-e.x,l=i.y-e.y;if(!(Math.abs(o)<.5)){g(t);for(const[i,n]of Nt){const r=a(e,{x:e.x+o*i,y:e.y+l*n},s,!1,!0)[1];t.ctx.beginPath(),t.ctx.moveTo(e.x,e.y),t.ctx.lineTo(r.x,r.y),t.ctx.stroke()}!1!==t.style.showLabels&&_(t,"1x1",i.x+4*n,i.y),t.ctx.setLineDash([])}},distance:(e,i,n)=>{const[s,o]=n.pts,l=o.x-s.x,r=o.y-s.y;let c=1/0;for(const[o,h]of Nt)c=Math.min(c,t(e,i,s,a(s,{x:s.x+l*o,y:s.y+r*h},n.rc.plotWidth,!1,!0)[1]));return c}},{id:"gann-box",name:"Gann Box",points:2,defaultStyle:{fill:!0,fillOpacity:.05},draw:t=>{const e=o(t.pts[0],t.pts[1]);b(t,()=>t.ctx.fillRect(e.x0,e.y0,e.x1-e.x0,e.y1-e.y0)),g(t);const i=e.x1-e.x0,n=e.y1-e.y0;t.ctx.beginPath();for(let s=0;s<=8;s++){const o=Math.round(e.x0+i*s/8)+.5,l=Math.round(e.y0+n*s/8)+.5;t.ctx.moveTo(o,e.y0),t.ctx.lineTo(o,e.y1),t.ctx.moveTo(e.x0,l),t.ctx.lineTo(e.x1,l)}t.ctx.moveTo(e.x0,e.y1),t.ctx.lineTo(e.x1,e.y0),t.ctx.stroke(),t.ctx.setLineDash([])},distance:(t,e,i)=>l(t,e,i.pts[0],i.pts[1],!0===i.drawing.style.fill)},rt,at,ct,tt,it,xt,dt,ft];let Ct=!1;function It(){if(!Ct){Ct=!0;for(const t of Wt)p(t)}}function Rt(t,e){return u(t)&&!0===y(t).freehand&&e>2?[0,e-1]:Array.from({length:e},(t,e)=>e)}class zt{constructor(){Object.defineProperty(this,"_drawings",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"_host",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_selected",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_preview",{enumerable:!0,configurable:!0,writable:!0,value:null})}attached(t){this._host=t}detached(){this._host=null}zOrder(){return"top"}autoscaleInfo(){return null}setDrawings(t){this._drawings=t.slice(),this._host?.requestUpdate()}setSelected(t){t!==this._selected&&(this._selected=t,this._host?.requestUpdate())}setPreview(t){this._preview=t,this._host?.requestUpdate()}_project(t,e,i){return{x:t.timeScale.indexToX(t.dataLayer.timeToIndexFloat(e)),y:t.priceScale.priceToY(i)}}_points(t,e){return e.points.map(e=>this._project(t,e.time,e.price))}draw(t,e){const i=null===this._preview?this._drawings:[...this._drawings,this._preview];for(const n of i){if(!1===n.visible||!u(n.tool))continue;const i=y(n.tool);if(n.points.length<Math.max(1,i.points))continue;const s=this._points(e,n);if(!s.some(t=>Number.isFinite(t.x)&&Number.isFinite(t.y)))continue;const o={color:n.style.color??e.theme.lineColor,lineWidth:n.style.lineWidth??1.5,...n.style},l=e.dpr;t.save(),n===this._preview&&(t.globalAlpha=.7),i.draw({ctx:t,rc:e,drawing:n,selected:n.id===this._selected,pts:s.map(t=>({x:t.x*l,y:t.y*l})),style:{...o,color:o.color,lineWidth:o.lineWidth},formatPrice:t=>e.priceScale.format(t)}),t.restore(),n.id===this._selected&&!0!==n.locked&&this._drawHandles(t,e,s,n.tool)}}_drawHandles(t,e,i,n){const s=e.dpr;t.save(),t.setLineDash([]),t.lineWidth=Math.max(1,Math.round(1.5*s));for(const o of Rt(n,i.length)){const n=i[o];t.beginPath(),t.arc(n.x*s,n.y*s,5*s,0,2*Math.PI),t.fillStyle=e.theme.background,t.fill(),t.strokeStyle=e.theme.lineColor,t.stroke()}t.restore()}hitTest(t,e,i){if(null!==this._selected){const n=this._drawings.find(t=>t.id===this._selected);if(void 0!==n&&!0!==n.locked){const s=this._points(i,n);for(const i of Rt(n.tool,s.length))if(Math.hypot(t-s[i].x,e-s[i].y)<=7)return{externalId:`draw:${n.id}#${i}`,zOrder:"top",distance:0,cursor:"grabbing",draggable:!0}}}let n=null;for(let s=this._drawings.length-1;s>=0;s--){const o=this._drawings[s];if(!1===o.visible||!0===o.locked||!u(o.tool))continue;const l=y(o.tool);if(o.points.length<Math.max(1,l.points))continue;const r=l.distance(t,e,{pts:this._points(i,o),drawing:o,rc:i});null===r||!Number.isFinite(r)||r>6||(null===n||r<n.distance)&&(n={id:o.id,distance:r})}return null===n?null:{externalId:`draw:${n.id}`,zOrder:"top",distance:n.distance,cursor:"move",draggable:!0}}}let jt=1;class Ut{constructor(t,e={}){Object.defineProperty(this,"_chart",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_opts",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"_layers",{enumerable:!0,configurable:!0,writable:!0,value:new Map}),Object.defineProperty(this,"_drawings",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"_tool",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_pending",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"_pendingPane",{enumerable:!0,configurable:!0,writable:!0,value:0}),Object.defineProperty(this,"_selected",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_undo",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"_redo",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"_dragStart",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_off",{enumerable:!0,configurable:!0,writable:!0,value:[]}),Object.defineProperty(this,"_lastCursor",{enumerable:!0,configurable:!0,writable:!0,value:null}),Object.defineProperty(this,"_lastBar",{enumerable:!0,configurable:!0,writable:!0,value:null}),this._chart=t,this._opts={magnet:e.magnet??!1,stayInDrawingMode:e.stayInDrawingMode??!1,historyLimit:e.historyLimit??50,defaultStyle:e.defaultStyle??{}},this._off.push(t.on("click",t=>this._onClick(t))),this._off.push(t.on("crosshair:move",t=>this._onCrosshair(t))),this._off.push(t.on("drag",t=>this._onDrag(t))),this._off.push(t.on("drag:end",()=>this._onDragEnd())),this._off.push(t.on("dblclick",()=>{this.finish()}));const i=t.drawingState();Array.isArray(i)&&(this._drawings=i.map(t=>({...t}))),this._sync()}setTool(t){if(null!==t&&!u(t))throw new Error(`openalgo-charts: unknown drawing tool "${t}"`);this._tool=t,this._pending=[],this._setPlacementMode(null!==t),this._syncPreview(),this._chart.emit("draw:tool",{tool:t})}_setPlacementMode(t){const e=this._chart;e.setPlacementMode?.(t)}activeTool(){return this._tool}setOptions(t){this._opts={...this._opts,...t,defaultStyle:t.defaultStyle??this._opts.defaultStyle}}drawings(){return this._drawings}get(t){return this._drawings.find(e=>e.id===t)}add(t){this._pushUndo();const e=y(t.tool),i={...t,id:t.id??"d"+jt++,style:{...this._opts.defaultStyle,...e.defaultStyle,...t.style}};return this._drawings.push(i),this._sync(),this._chart.emit("draw:add",{drawing:i}),i}update(t,e){const i=this.get(t);return void 0!==i&&(this._pushUndo(),void 0!==e.points&&(i.points=e.points.map(t=>({...t}))),void 0!==e.style&&(i.style={...i.style,...e.style}),void 0!==e.locked&&(i.locked=e.locked),void 0!==e.visible&&(i.visible=e.visible),this._sync(),this._chart.emit("draw:update",{drawing:i}),!0)}remove(t){const e=this._drawings.findIndex(e=>e.id===t);if(e<0)return!1;this._pushUndo();const[i]=this._drawings.splice(e,1);return this._selected===t&&(this._selected=null),this._sync(),this._chart.emit("draw:remove",{drawing:i}),!0}clear(){0!==this._drawings.length&&(this._pushUndo(),this._drawings=[],this._selected=null,this._sync())}select(t){this._selected=t;for(const e of this._layers.values())e.setSelected(t);this._chart.emit("draw:select",{id:t})}selected(){return this._selected}undo(){const t=this._undo.pop();return void 0!==t&&(this._redo.push(JSON.stringify(this._drawings)),this._drawings=JSON.parse(t),this._drawings.some(t=>t.id===this._selected)||(this._selected=null),this._sync(),!0)}redo(){const t=this._redo.pop();return void 0!==t&&(this._undo.push(JSON.stringify(this._drawings)),this._drawings=JSON.parse(t),this._sync(),!0)}canUndo(){return this._undo.length>0}canRedo(){return this._redo.length>0}toJSON(){return this._drawings.map(t=>({...t,points:t.points.map(t=>({...t})),style:{...t.style}}))}fromJSON(t){this._drawings=Array.isArray(t)?t.map(t=>({...t})):[],this._selected=null,this._undo=[],this._redo=[],this._sync()}destroy(){this._setPlacementMode(!1);for(const t of this._off)t();this._off.length=0;for(const[t,e]of this._layers)this._chart.removePrimitive(e);this._layers.clear()}_onCrosshair(t){const e=t.time,i=t.price,n=t.paneIndex??null;this._lastCursor=null===e||null===i||null===n?null:{time:e,price:i,paneIndex:n},this._lastBar=t.bar??null,null!==this._tool&&!0===t.pressed&&this._isFreehand()&&null!==e&&null!==i&&null!==n&&Number.isFinite(e)&&Number.isFinite(i)?this._inkPoint({time:e,price:i},n):null!==this._tool&&this._pending.length>0&&this._syncPreview()}_expand(t,e){if(void 0===t.expand)return e;const i=this._chart.dataLayer,n=i.baseIndex,s=n>0?i.indexToTime(n-1):void 0,o=n>=0?i.indexToTime(n):void 0,l=void 0!==s&&void 0!==o&&o>s?o-s:60,r=this._chart.getVisibleLogicalRange(),a=null===r?60:Math.max(1,r.to-r.from);return t.expand(e,{barSeconds:l,visibleBars:a})}_isFreehand(){return null!==this._tool&&!0===y(this._tool).freehand}_inkPoint(t,e){if(0===this._pending.length)this._pendingPane=e;else{if(e!==this._pendingPane)return;{const e=this._pending[this._pending.length-1];if(e.time===t.time&&e.price===t.price)return}}this._pending.push(t),this._syncPreview()}_commit(t){const e=y(this._tool),i=this.add({tool:e.id,points:t,style:{},paneIndex:this._pendingPane});this._pending=[],this._opts.stayInDrawingMode||(this._tool=null,this._setPlacementMode(!1)),this._syncPreview(),this.select(i.id),this._chart.emit("draw:tool",{tool:this._tool})}_finishFreehand(){const t=this._pending;this._pending=[],t.length<2?this._syncPreview():this._commit(t)}finish(){if(null===this._tool||0===this._pending.length)return!1;const t=y(this._tool);if(0!==t.points||!0===t.freehand)return!1;const e=this._pending;return e.length<2?(this._pending=[],this._syncPreview(),!1):(this._commit(e),!0)}_onClick(t){if(null===this._tool)null!==t.id&&t.id.startsWith("draw:")?this.select(t.id.slice(5).split("#")[0]):null===t.id&&this.select(null);else{if(this._isFreehand())return void(!0===t.viaDrag&&this._finishFreehand());if(!0===t.viaDrag&&0===this._pending.length)return;if(null===t.price||!Number.isFinite(t.price)||!Number.isFinite(t.time))return;this._placePoint({time:t.time,price:this._snap(t.price,t.paneIndex)},t.paneIndex)}}_placePoint(t,e){0===this._pending.length&&(this._pendingPane=e),this._pending.push(t);const i=y(this._tool);i.points>0&&this._pending.length>=i.points?this._commit(this._expand(i,this._pending)):this._syncPreview()}_snap(t,e){if(!this._opts.magnet||0!==e)return t;const i=this._lastBar;if(null===i)return t;let n=t,s=1/0;for(const e of[i.open,i.high,i.low,i.close]){const i=Math.abs(e-t);i<s&&(s=i,n=e)}return n}_onDrag(t){if(!t.id.startsWith("draw:"))return;const[e,i]=t.id.slice(5).split("#"),n=this.get(e);if(void 0===n||!0===n.locked)return;const s=void 0===i?null:Number(i);null!==this._dragStart&&this._dragStart.id===e&&this._dragStart.handle===s||(this._pushUndo(),this._dragStart={id:e,handle:s,points:n.points.map(t=>({...t})),from:{time:t.fromTime??t.time,price:t.fromPrice??t.price}});const o=this._dragStart;if(null===s){const e=t.time-o.from.time,i=t.price-o.from.price;n.points=o.points.map(t=>({time:t.time+e,price:t.price+i}))}else s>=0&&s<n.points.length&&(n.points=o.points.map((e,i)=>i===s?{time:t.time,price:t.price}:{...e}));this._sync()}_onDragEnd(){if(null===this._dragStart)return;const t=this.get(this._dragStart.id);this._dragStart=null,void 0!==t&&this._chart.emit("draw:update",{drawing:t})}_layerFor(t){let e=this._layers.get(t);return void 0===e&&(e=new zt,this._chart.addPrimitive(e,t),this._layers.set(t,e)),e}_sync(){const t=new Map;for(const e of this._drawings){const i=t.get(e.paneIndex)??[];i.push(e),t.set(e.paneIndex,i)}for(const[e,i]of t)this._layerFor(e).setDrawings(i);for(const[e,i]of this._layers)t.has(e)||i.setDrawings([]),i.setSelected(this._selected);this._chart.setDrawingState(this.toJSON())}_syncPreview(){for(const t of this._layers.values())t.setPreview(null);if(null===this._tool||0===this._pending.length)return;const t=this._lastCursor,e=null===t?this._pending:[...this._pending,{time:t.time,price:t.price}];this._layerFor(this._pendingPane).setPreview({id:"__preview",tool:this._tool,points:e,style:this._opts.defaultStyle,paneIndex:this._pendingPane})}_pushUndo(){this._undo.push(JSON.stringify(this._drawings)),this._undo.length>this._opts.historyLimit&&this._undo.shift(),this._redo=[]}}const Bt="draw";It();export{A as ARROW,Wt as BUILTIN_DRAWING_TOOLS,I as CROSS_LINE,Bt as DRAW_TIER,Ut as DrawingController,zt as DrawingLayer,z as ELLIPSE,F as EXTENDED_LINE,H as FIB_EXTENSION,B as FIB_RETRACEMENT,N as HORIZONTAL_LINE,W as HORIZONTAL_RAY,Y as LONG_POSITION,J as MEASURE,j as PARALLEL_CHANNEL,it as PATH,O as RAY,R as RECTANGLE,V as SHORT_POSITION,tt as TEXT,$ as TREND_LINE,C as VERTICAL_LINE,r as distToEllipse,e as distToLine,s as distToPolyline,l as distToRect,t as distToSegment,a as extendSegment,y as getDrawingTool,u as hasDrawingTool,o as rectOf,It as registerBuiltinDrawingTools,p as registerDrawingTool,f as registeredDrawingTools};
2
2
  //# sourceMappingURL=openalgo-charts.draw.mjs.map