@tradecanvas/chart 1.72.0 → 1.72.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/dist/{LayoutSession-r7Rgc5Sw.cjs → LayoutSession-BrXo314m.cjs} +2 -2
  2. package/dist/{LayoutSession-r7Rgc5Sw.cjs.map → LayoutSession-BrXo314m.cjs.map} +1 -1
  3. package/dist/{LayoutSession-DjHF7tmL.js → LayoutSession-BrazGVET.js} +2 -2
  4. package/dist/{LayoutSession-DjHF7tmL.js.map → LayoutSession-BrazGVET.js.map} +1 -1
  5. package/dist/WidgetCommandPalette-CeCLHPy1.js +177 -0
  6. package/dist/WidgetCommandPalette-CeCLHPy1.js.map +1 -0
  7. package/dist/WidgetCommandPalette-ZZNbWwCZ.cjs +2 -0
  8. package/dist/WidgetCommandPalette-ZZNbWwCZ.cjs.map +1 -0
  9. package/dist/{WidgetDrawingSettings-MSpeHFhV.js → WidgetDrawingSettings-BeW8fX7r.js} +5 -5
  10. package/dist/{WidgetDrawingSettings-MSpeHFhV.js.map → WidgetDrawingSettings-BeW8fX7r.js.map} +1 -1
  11. package/dist/{WidgetDrawingSettings-B3KAH9Ag.cjs → WidgetDrawingSettings-Cyl2u_u8.cjs} +2 -2
  12. package/dist/{WidgetDrawingSettings-B3KAH9Ag.cjs.map → WidgetDrawingSettings-Cyl2u_u8.cjs.map} +1 -1
  13. package/dist/WidgetGoToDate-BNdngHlg.cjs +2 -0
  14. package/dist/{WidgetGoToDate-CPzfStIm.cjs.map → WidgetGoToDate-BNdngHlg.cjs.map} +1 -1
  15. package/dist/{WidgetGoToDate-R2teTLpJ.js → WidgetGoToDate-hcDtezRm.js} +6 -5
  16. package/dist/{WidgetGoToDate-R2teTLpJ.js.map → WidgetGoToDate-hcDtezRm.js.map} +1 -1
  17. package/dist/{WidgetHotkeySheet-BE0glkVA.js → WidgetHotkeySheet-1lRFSdvt.js} +3 -3
  18. package/dist/{WidgetHotkeySheet-BE0glkVA.js.map → WidgetHotkeySheet-1lRFSdvt.js.map} +1 -1
  19. package/dist/{WidgetHotkeySheet-pnsXreK6.cjs → WidgetHotkeySheet-y5LWKSG6.cjs} +2 -2
  20. package/dist/{WidgetHotkeySheet-pnsXreK6.cjs.map → WidgetHotkeySheet-y5LWKSG6.cjs.map} +1 -1
  21. package/dist/WidgetIndicatorPicker-CGvZ5kYd.js +245 -0
  22. package/dist/WidgetIndicatorPicker-CGvZ5kYd.js.map +1 -0
  23. package/dist/WidgetIndicatorPicker-DuKJFPRC.cjs +2 -0
  24. package/dist/WidgetIndicatorPicker-DuKJFPRC.cjs.map +1 -0
  25. package/dist/{WidgetIndicatorSettings-BJUjACzj.cjs → WidgetIndicatorSettings-C7vpco6e.cjs} +2 -2
  26. package/dist/{WidgetIndicatorSettings-BJUjACzj.cjs.map → WidgetIndicatorSettings-C7vpco6e.cjs.map} +1 -1
  27. package/dist/{WidgetIndicatorSettings-DgbsZk0h.js → WidgetIndicatorSettings-dDkqzzYo.js} +6 -6
  28. package/dist/{WidgetIndicatorSettings-DgbsZk0h.js.map → WidgetIndicatorSettings-dDkqzzYo.js.map} +1 -1
  29. package/dist/{WidgetSettings-D35fHGXL.js → WidgetSettings--XzDx515.js} +24 -11
  30. package/dist/WidgetSettings--XzDx515.js.map +1 -0
  31. package/dist/WidgetSettings-C0fnWGdY.cjs +2 -0
  32. package/dist/WidgetSettings-C0fnWGdY.cjs.map +1 -0
  33. package/dist/WidgetSymbolSearch-C4OR42nZ.cjs +2 -0
  34. package/dist/WidgetSymbolSearch-C4OR42nZ.cjs.map +1 -0
  35. package/dist/WidgetSymbolSearch-CvPpjIwa.js +580 -0
  36. package/dist/WidgetSymbolSearch-CvPpjIwa.js.map +1 -0
  37. package/dist/{focusTrap-Hm7AUTBw.js → focusTrap-Br9Zfje0.js} +1 -1
  38. package/dist/{focusTrap-Hm7AUTBw.js.map → focusTrap-Br9Zfje0.js.map} +1 -1
  39. package/dist/{focusTrap-B8OoGwHb.cjs → focusTrap-DrhhmG0V.cjs} +1 -1
  40. package/dist/{focusTrap-B8OoGwHb.cjs.map → focusTrap-DrhhmG0V.cjs.map} +1 -1
  41. package/dist/{i18n-DFR1Oukq.cjs → i18n-C2nQBZTY.cjs} +1 -1
  42. package/dist/{i18n-DFR1Oukq.cjs.map → i18n-C2nQBZTY.cjs.map} +1 -1
  43. package/dist/{i18n-CvnQcfor.js → i18n-C5v6Tzp1.js} +1 -1
  44. package/dist/{i18n-CvnQcfor.js.map → i18n-C5v6Tzp1.js.map} +1 -1
  45. package/dist/index.cjs +1 -1
  46. package/dist/index.js +1 -1
  47. package/dist/{indicatorInputWords-D19kY9NO.js → indicatorInputWords-Bd9Pt6qp.js} +2 -2
  48. package/dist/{indicatorInputWords-D19kY9NO.js.map → indicatorInputWords-Bd9Pt6qp.js.map} +1 -1
  49. package/dist/{indicatorInputWords-DzrKBU2I.cjs → indicatorInputWords-CTA4IcJR.cjs} +2 -2
  50. package/dist/{indicatorInputWords-DzrKBU2I.cjs.map → indicatorInputWords-CTA4IcJR.cjs.map} +1 -1
  51. package/dist/{indicatorSettingsTabs-BLEULMJJ.cjs → indicatorSettingsTabs-B0liE3ST.cjs} +2 -2
  52. package/dist/{indicatorSettingsTabs-BLEULMJJ.cjs.map → indicatorSettingsTabs-B0liE3ST.cjs.map} +1 -1
  53. package/dist/{indicatorSettingsTabs-Wxx2v_y4.js → indicatorSettingsTabs-XcgMdbLp.js} +3 -3
  54. package/dist/{indicatorSettingsTabs-Wxx2v_y4.js.map → indicatorSettingsTabs-XcgMdbLp.js.map} +1 -1
  55. package/dist/monthView-B-CieFDJ.cjs +2 -0
  56. package/dist/monthView-B-CieFDJ.cjs.map +1 -0
  57. package/dist/monthView-N8yDaTqZ.js +198 -0
  58. package/dist/monthView-N8yDaTqZ.js.map +1 -0
  59. package/dist/{platformKeys-BAPueZ1I.cjs → platformKeys-B82-j1Fs.cjs} +1 -1
  60. package/dist/{platformKeys-BAPueZ1I.cjs.map → platformKeys-B82-j1Fs.cjs.map} +1 -1
  61. package/dist/{platformKeys-D_x_6ZrV.js → platformKeys-Dd1qOCjF.js} +1 -1
  62. package/dist/{platformKeys-D_x_6ZrV.js.map → platformKeys-Dd1qOCjF.js.map} +1 -1
  63. package/dist/{settingsControls-ef4j_clQ.js → settingsControls-DIjzCFHI.js} +2 -2
  64. package/dist/{settingsControls-ef4j_clQ.js.map → settingsControls-DIjzCFHI.js.map} +1 -1
  65. package/dist/{settingsControls-jNn0If4b.cjs → settingsControls-Tn8_vJJv.cjs} +2 -2
  66. package/dist/{settingsControls-jNn0If4b.cjs.map → settingsControls-Tn8_vJJv.cjs.map} +1 -1
  67. package/dist/symbolCatalog-CA1fpz3s.js +90 -0
  68. package/dist/symbolCatalog-CA1fpz3s.js.map +1 -0
  69. package/dist/symbolCatalog-Dx1YnZgm.cjs +2 -0
  70. package/dist/symbolCatalog-Dx1YnZgm.cjs.map +1 -0
  71. package/dist/widget/ChartWidget.d.ts +102 -580
  72. package/dist/widget/ChartWidget.d.ts.map +1 -1
  73. package/dist/widget/WidgetAlerts.d.ts +35 -0
  74. package/dist/widget/WidgetAlerts.d.ts.map +1 -0
  75. package/dist/widget/WidgetChartSettings.d.ts +211 -0
  76. package/dist/widget/WidgetChartSettings.d.ts.map +1 -0
  77. package/dist/widget/WidgetCommands.d.ts +54 -0
  78. package/dist/widget/WidgetCommands.d.ts.map +1 -0
  79. package/dist/widget/WidgetCompares.d.ts +140 -0
  80. package/dist/widget/WidgetCompares.d.ts.map +1 -0
  81. package/dist/widget/WidgetDockArea.d.ts +90 -0
  82. package/dist/widget/WidgetDockArea.d.ts.map +1 -0
  83. package/dist/widget/WidgetDrawingEdit.d.ts +73 -0
  84. package/dist/widget/WidgetDrawingEdit.d.ts.map +1 -0
  85. package/dist/widget/WidgetIntervals.d.ts +66 -0
  86. package/dist/widget/WidgetIntervals.d.ts.map +1 -0
  87. package/dist/widget/WidgetLayouts.d.ts +85 -0
  88. package/dist/widget/WidgetLayouts.d.ts.map +1 -0
  89. package/dist/widget/WidgetLegendView.d.ts +54 -0
  90. package/dist/widget/WidgetLegendView.d.ts.map +1 -0
  91. package/dist/widget/WidgetMenus.d.ts +79 -0
  92. package/dist/widget/WidgetMenus.d.ts.map +1 -0
  93. package/dist/widget/WidgetReplay.d.ts +199 -0
  94. package/dist/widget/WidgetReplay.d.ts.map +1 -0
  95. package/dist/widget/WidgetSettings.d.ts +2 -0
  96. package/dist/widget/WidgetSettings.d.ts.map +1 -1
  97. package/dist/widget/WidgetTrading.d.ts +48 -0
  98. package/dist/widget/WidgetTrading.d.ts.map +1 -0
  99. package/dist/widget/WidgetWatchlists.d.ts +77 -0
  100. package/dist/widget/WidgetWatchlists.d.ts.map +1 -0
  101. package/dist/widget/index.cjs +43 -29
  102. package/dist/widget/index.cjs.map +1 -1
  103. package/dist/widget/index.js +9628 -9812
  104. package/dist/widget/index.js.map +1 -1
  105. package/dist/widget/keyTarget.d.ts +4 -0
  106. package/dist/widget/keyTarget.d.ts.map +1 -1
  107. package/dist/widget/locales/index.cjs +1 -1
  108. package/dist/widget/locales/index.js +1 -1
  109. package/dist/widget/pageEnv.d.ts +5 -0
  110. package/dist/widget/pageEnv.d.ts.map +1 -0
  111. package/dist/widget/widgetDialogs.d.ts +3 -0
  112. package/dist/widget/widgetDialogs.d.ts.map +1 -1
  113. package/dist/widgetFeatures-BM6u0u74.js +186 -0
  114. package/dist/widgetFeatures-BM6u0u74.js.map +1 -0
  115. package/dist/widgetFeatures-BZ8OVPN2.cjs +3 -0
  116. package/dist/widgetFeatures-BZ8OVPN2.cjs.map +1 -0
  117. package/package.json +3 -3
  118. package/dist/WidgetGoToDate-CPzfStIm.cjs +0 -2
  119. package/dist/WidgetSettings-D35fHGXL.js.map +0 -1
  120. package/dist/WidgetSettings-Pgt3p6vv.cjs +0 -2
  121. package/dist/WidgetSettings-Pgt3p6vv.cjs.map +0 -1
  122. package/dist/widgetFeatures-BvkTbsQn.js +0 -378
  123. package/dist/widgetFeatures-BvkTbsQn.js.map +0 -1
  124. package/dist/widgetFeatures-Cy0fs3Nl.cjs +0 -3
  125. package/dist/widgetFeatures-Cy0fs3Nl.cjs.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./LayoutSession-r7Rgc5Sw.cjs`);let t=require(`@tradecanvas/commons`),n=require(`@tradecanvas/core`);function r(e){let{id:t,params:n={},position:r=null}=typeof e==`string`?{id:e}:e;return JSON.stringify([t,Object.keys(n).sort().map(e=>[e,n[e]]),r])}function i(e,t,n){let i=new Map,a=t.map(e=>{let t=r(e),n=i.get(t)??0;return i.set(t,n+1),{spec:e,key:`${t}#${n}`}}),o=new Set(a.map(e=>e.key));for(let[t,r]of[...n])o.has(t)||(e.removeIndicator(r),n.delete(t));for(let{spec:t,key:r}of a){if(n.has(r))continue;let i=typeof t==`string`?e.addIndicator(t):t.position===void 0?e.addIndicator(t.id,t.params??{}):e.addIndicator(t.id,t.params??{},t.position);i&&n.set(r,i)}}var a=3,o=e=>({time:e.time,open:e.open,high:e.high,low:e.low,close:e.close,volume:e.volume}),s=e=>e.length>0?e[e.length-1]:null;function c(t,n,r){for(let i=0;i<r;i++)if(!e.D(t[i],n[i]))return!1;return!0}function l(e,t){if(e.isReplayActive())return!0;let n=s(e.getData());return t.inReplay?n?.time===t.last?.time:n===t.shownBar?n?.time===t.last?.time||!e.isExtendedHoursVisible():!1}function u(t,n,r){let i=[];for(let a=0;a<n.length;a++){let s=t[r+a];if(!e.D(s,n[a])){if(s.time!==n[a].time||!e.E(s))return null;i.push(o(s))}}return i}function d(e,t){if(t.length===0)return!0;if(!e.updateBar)return!1;for(let n of t)if(!e.updateBar(n))return!1;return!0}function f(e){return e.slice(Math.max(1,e.length-1-3),-1).map(o)}function p(t,n){let r=[];for(let i=n;i<t.length;i++){if(!e.E(t[i])||!(t[i].time>t[i-1].time))return null;r.push(o(t[i]))}return r}function m(t,n,r){let i=r.length;if(i===0||!r.last||!e.E(r.last)||n.length<i||!l(t,r))return!1;let a=r.recent??[],s=i-1-a.length;if(n!==r.source&&(r.source.length!==i||!c(r.source,n,s)))return!1;let f=n[i-1];if(f.time!==r.last.time||!e.E(f))return!1;let m=u(n,a,s),h=p(n,i);return!m||!h||!d(t,m)?!1:(e.D(f,r.last)||t.updateLastBar(o(f)),h.length===1?t.appendBar(h[0]):h.length>1&&t.appendBars(h),!0)}function h(e,t,n){(!n||!m(e,t,n))&&e.setData(t.map(o));let r=t.length>0?o(t[t.length-1]):null,i=e.isReplayActive();return{source:t,length:t.length,last:r,recent:f(t),shownBar:i?null:s(e.getData()),inReplay:i}}function g(e){let{viewport:t,data:r}=e,i=(0,n.priceToYMapper)(t),a=r.length-1,o=Math.max(0,Math.floor(t.visibleRange.from)),s=Math.min(a,Math.ceil(t.visibleRange.to)),c=e=>r.length>0?(0,n.timestampToBarIndex)(e,r):e;return{timeToX:e=>(0,n.barIndexToX)(c(e),t),xToTime:e=>{let i=(0,n.xToBarIndex)(e,t);return r.length>0?(0,n.barIndexToTime)(i,r):i},indexToX:e=>(0,n.barIndexToX)(e,t),xToIndex:e=>(0,n.xToBarIndex)(e,t),priceToY:i,yToPrice:e=>(0,n.yToPrice)(e,t),barWidth:t.barWidth,visible:s<o?{from:0,to:-1}:{from:o,to:s}}}var _={"1x1":{cols:1,rows:1},"1x2":{cols:2,rows:1},"2x1":{cols:1,rows:2},"2x2":{cols:2,rows:2},"1x3":{cols:3,rows:1},"3x1":{cols:1,rows:3},"2x3":{cols:3,rows:2},"3x2":{cols:2,rows:3}},v=class{root;cells=[];layout;options;destroyed=!1;syncing=!1;constructor(e,t={}){this.options=t,this.layout=t.layout??`2x2`,this.root=document.createElement(`div`),this.root.style.cssText=`display:grid;width:100%;height:100%;overflow:hidden;`,e.appendChild(this.root),this.applyLayout(),this.createCells()}applyLayout(){let{cols:e,rows:t}=_[this.layout],n=this.options.gap??1;this.root.style.gridTemplateColumns=`repeat(${e}, 1fr)`,this.root.style.gridTemplateRows=`repeat(${t}, 1fr)`,this.root.style.gap=`${n}px`}createCells(){let{cols:e,rows:t}=_[this.layout],n=e*t;for(let e=0;e<n;e++)this.cells.push(this.createCell(e))}createCell(t){let n=this.options.cells?.[t]??{},r=document.createElement(`div`);r.style.cssText=`position:relative;overflow:hidden;min-width:0;min-height:0;`,this.root.appendChild(r);let i=new e.c(r,{chartType:`candlestick`,autoScale:!0,features:{crosshair:!0,keyboard:!0,volume:!0,legend:!0,priceAxis:!0,timeAxis:!0,grid:!0},...this.options.chartOptions,...n.chartOptions,theme:this.options.theme}),a={container:r,chart:i,symbol:n.symbol??`Chart ${t+1}`,timeframe:n.timeframe??`5m`};return this.options.syncCrosshair!==!1&&(i.on(`crosshairMove`,e=>{let t=e.payload.bar?.time;if(t!==void 0)for(let e of this.cells)e.chart!==i&&e.chart.setCrosshairTime(t)}),i.on(`crosshairLeave`,()=>{for(let e of this.cells)e.chart!==i&&e.chart.setCrosshairTime(null)})),this.options.syncTimeAxis!==!1&&i.on(`visibleRangeChange`,e=>{if(this.syncing)return;this.syncing=!0;let{from:t,to:n}=e.payload,r=i.getData();if(r.length>0&&t>=0&&n<r.length){let e=r[t]?.time,a=r[n]?.time;if(e&&a)for(let t of this.cells)t.chart!==i&&t.chart.setVisibleRange(e,a)}this.syncing=!1}),a}setLayout(e){if(e===this.layout)return;let t=this.cells.length,{cols:n,rows:r}=_[e],i=n*r;if(i<t)for(let e=t-1;e>=i;e--){let t=this.cells[e];t.chart.destroy(),t.container.remove(),this.cells.pop()}this.layout=e,this.applyLayout();for(let e=t;e<i;e++)this.cells.push(this.createCell(e))}getChart(e){return this.cells[e]?.chart??null}getCharts(){return this.cells.map(e=>e.chart)}getCellCount(){return this.cells.length}setData(e,t){this.cells[e]?.chart.setData(t)}setAllData(e){for(let t of this.cells)t.chart.setData(e)}async connectCell(e,t){let n=this.cells[e];n&&(n.symbol=t.symbol,n.timeframe=t.timeframe,await n.chart.connect(t))}async connectAll(e,t,r,i=500){let a=[];for(let o=0;o<this.cells.length&&o<t.length;o++)a.push(this.connectCell(o,{...typeof e==`function`?{adapter:e(t[o],o)}:(0,n.isDataFeed)(e)?{feed:e}:{adapter:e},symbol:t[o],timeframe:r,historyLimit:i}));await Promise.all(a)}setTheme(e){for(let t of this.cells)t.chart.setTheme(e)}destroy(){if(!this.destroyed){this.destroyed=!0;for(let e of this.cells)e.chart.destroy(),e.container.remove();this.cells=[],this.root.remove()}}},y=class extends n.BaseFinanceChart{options;constructor(e,t){super(e,t.theme),this.options=t,this.requestRender()}renderChart(e,t,r,i){(0,n.renderSparkline)(e,t,r,this.options,i)}update(e){this.options={...this.options,data:e},this.requestRender()}setOptions(e){this.options={...this.options,...e},this.requestRender()}},b=class extends n.BaseFinanceChart{options;crosshair=null;constructor(e,t){super(e,t.theme),this.options=t,t.crosshair!==!1&&(this.crosshair=new n.FinanceCrosshair(this.canvas,()=>this.requestRender())),this.requestRender()}renderChart(e,t,r,i){let a=this.crosshair?.getPosition()??null;(0,n.renderDepthChart)(e,t,r,this.options,i,a)}update(e){this.options={...this.options,data:e},this.requestRender()}setOptions(e){this.options={...this.options,...e},this.requestRender()}destroy(){this.crosshair?.destroy(),super.destroy()}},x=class extends n.BaseFinanceChart{options;crosshair=null;constructor(e,t){super(e,t.theme),this.options=t,t.crosshair!==!1&&(this.crosshair=new n.FinanceCrosshair(this.canvas,()=>this.requestRender())),this.requestRender()}renderChart(e,t,r,i){let a=this.crosshair?.getPosition()??null;(0,n.renderEquityCurve)(e,t,r,this.options,i,a)}update(e,t){this.options={...this.options,data:e},t!==void 0&&(this.options={...this.options,benchmark:t}),this.requestRender()}setOptions(e){this.options={...this.options,...e},this.requestRender()}destroy(){this.crosshair?.destroy(),super.destroy()}},S=class extends n.BaseFinanceChart{options;crosshair=null;cachedRects=[];cachedGroups=[];currentData=[];lastLayoutWidth=0;lastLayoutHeight=0;handleClick=null;constructor(e,t){super(e,t.theme),this.options=t,this.currentData=t.data??[],t.crosshair!==!1&&(this.crosshair=new n.FinanceCrosshair(this.canvas,()=>this.requestRender())),t.onCellClick&&(this.handleClick=e=>{let t=this.canvas.getBoundingClientRect(),n=e.clientX-t.left,r=e.clientY-t.top;this.onCanvasClick(n,r)},this.canvas.addEventListener(`click`,this.handleClick)),this.applyLabel(),this.recomputeLayout(),this.requestRender()}applyLabel(){let e=new Set(this.currentData.map(e=>e.group).filter(Boolean)).size,t=this.options.grouped&&e>0?`Market map of ${this.currentData.length} cells in ${e} groups`:`Heatmap of ${this.currentData.length} cells`;this.setLabel(this.options.ariaLabel??t)}recomputeLayout(){let e={x:0,y:0,width:this.width,height:this.height},t=this.options.cellPadding??2;if(this.lastLayoutWidth=this.width,this.lastLayoutHeight=this.height,this.cachedGroups=[],this.options.grouped){let{groups:r,cells:i}=(0,n.layoutGroupedTreemap)(this.currentData.map(e=>({id:e.id,weight:e.weight??(Math.abs(e.value)||1),group:e.group,value:e.value})),e,t,n.GROUP_HEADER);this.cachedRects=i,this.cachedGroups=r}else if(this.options.weighted){let r=this.currentData.map(e=>({id:e.id,weight:e.weight??(Math.abs(e.value)||1)}));this.cachedRects=(0,n.layoutSquarifiedTreemap)(r,e,t)}else this.cachedRects=(0,n.layoutUniformGrid)(this.currentData.map(e=>({id:e.id})),e,t)}onCanvasClick(e,t){if(this.options.onCellClick)for(let n of this.cachedRects){let r=n.rect;if(e>=r.x&&e<=r.x+r.width&&t>=r.y&&t<=r.y+r.height){let e=this.currentData.find(e=>e.id===n.id);e&&this.options.onCellClick(e);return}}}renderChart(e,t,r,i){(t!==this.lastLayoutWidth||r!==this.lastLayoutHeight)&&this.recomputeLayout();let a=this.crosshair?.getPosition()??null;(0,n.renderHeatmap)(e,t,r,this.currentData,this.cachedRects,this.options,i,a,this.cachedGroups)}update(e){this.currentData=e,this.options={...this.options,data:e},this.applyLabel(),this.recomputeLayout(),this.requestRender()}setOptions(e){this.options={...this.options,...e},e.data&&(this.currentData=e.data),this.applyLabel(),this.recomputeLayout(),this.requestRender()}destroy(){this.crosshair?.destroy(),this.handleClick&&this.canvas.removeEventListener(`click`,this.handleClick),super.destroy()}},C=class extends n.BaseFinanceChart{options;crosshair=null;constructor(e,t){super(e,t.theme),this.options=t,t.crosshair!==!1&&(this.crosshair=new n.FinanceCrosshair(this.canvas,()=>this.requestRender())),this.requestRender()}renderChart(e,t,r,i){let a=this.crosshair?.getPosition()??null;(0,n.renderWaterfall)(e,t,r,this.options,i,a)}update(e){this.options={...this.options,data:e},this.requestRender()}setOptions(e){this.options={...this.options,...e},this.requestRender()}destroy(){this.crosshair?.destroy(),super.destroy()}},w=500;function T(e){let t=1-e;return 1-t*t*t}var E=class extends n.BaseFinanceChart{options;currentValue;targetValue;animationStart=null;animationFrom=0;animationFrameId=null;constructor(e,t){super(e,t.theme),this.options=t,this.currentValue=t.value,this.targetValue=t.value,this.requestRender()}renderChart(e,t,r,i){(0,n.renderGauge)(e,t,r,this.options,i,this.currentValue)}setValue(e){if(this.options.animate===!1){this.cancelAnimation(),this.currentValue=e,this.targetValue=e,this.options={...this.options,value:e},this.requestRender();return}this.targetValue=e,this.animationFrom=this.currentValue,this.animationStart=performance.now(),this.options={...this.options,value:e},this.startAnimationLoop()}setOptions(e){let t={...this.options,...e};if(e.value!==void 0&&e.value!==this.targetValue){this.options=t,this.setValue(e.value);return}this.options=t,this.requestRender()}startAnimationLoop(){if(this.animationFrameId!==null)return;let e=()=>{if(this.animationFrameId=null,this.animationStart===null)return;let t=this.options.animationDuration??w,n=performance.now()-this.animationStart,r=Math.min(1,n/Math.max(1,t)),i=T(r);this.currentValue=this.animationFrom+(this.targetValue-this.animationFrom)*i,this.requestRender(),r<1?this.animationFrameId=requestAnimationFrame(e):(this.currentValue=this.targetValue,this.animationStart=null)};this.animationFrameId=requestAnimationFrame(e)}cancelAnimation(){this.animationFrameId!==null&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),this.animationStart=null}destroy(){this.cancelAnimation(),super.destroy()}},D=class extends n.BaseFinanceChart{options;layout=null;layoutFor=null;crosshair;onClick=e=>{let t=this.canvas.getBoundingClientRect();this.layout&&this.clickAt(this.layout,e.clientX-t.left,e.clientY-t.top)};onMove=e=>{if(!this.layout||!this.clickable())return;let t=this.canvas.getBoundingClientRect();this.canvas.style.cursor=this.hits(this.layout,e.clientX-t.left,e.clientY-t.top)?`pointer`:``};constructor(e,t){super(e,t.theme),this.options=t,this.crosshair=new n.FinanceCrosshair(this.canvas,()=>this.requestRender()),this.canvas.addEventListener(`click`,this.onClick),this.canvas.addEventListener(`pointermove`,this.onMove),this.applyLabel(),this.requestRender()}renderChart(e,t,r,i){let a=this.options.crosshair===!1?null:this.crosshair.getPosition(),o=this.layoutFor;(!this.layout||!o||o.options!==this.options||o.width!==t||o.height!==r||o.theme!==i)&&(this.layout=this.compute(t,r,i,(0,n.canvasMeasure)(e,i)),this.layoutFor={options:this.options,width:t,height:r,theme:i}),this.draw(e,t,r,i,a,this.layout)}setOptions(e){this.options={...this.options,...e},`theme`in e&&this.setTheme(e.theme??`dark`),this.applyLabel(),this.requestRender()}applyLabel(){this.setLabel(this.options.ariaLabel??this.describe())}destroy(){this.crosshair.destroy(),this.canvas.removeEventListener(`click`,this.onClick),this.canvas.removeEventListener(`pointermove`,this.onMove),super.destroy()}},O=class extends D{compute(e,t,r,i){return(0,n.computeBarLayout)(this.options,e,t,r,i)}draw(e,t,r,i,a,o){(0,n.renderBarChart)(e,t,r,this.options,i,a,o)}describe(){return`Bar chart of ${this.options.series.map(e=>e.name).join(`, `)}, ${this.options.categories.length} categories`}clickable(){return this.options.onBarClick!==void 0}hits(e,t,r){return(0,n.hitBar)(e,t,r)!==null}clickAt(e,t,r){let i=(0,n.hitBar)(e,t,r);i&&this.options.onBarClick?.({category:i.category,series:i.series,value:i.value,index:i.index})}update(e,t){this.setOptions({categories:e,series:t})}},k=class extends D{compute(e,t,r,i){return(0,n.computeDonutLayout)(this.options,e,t,r,i)}draw(e,t,r,i,a,o){(0,n.renderDonut)(e,t,r,this.options,i,a,o)}describe(){let e=this.options.data.filter(e=>Number.isFinite(e.value)&&e.value>0).map(e=>e.label).join(`, `);return`${(this.options.innerRadius??.6)>0?`Donut`:`Pie`} chart of ${e}`}clickable(){return this.options.onSliceClick!==void 0}hits(e,t,r){return(0,n.hitSlice)(e,t,r)!==null}clickAt(e,t,r){let i=(0,n.hitSlice)(e,t,r);i&&this.options.onSliceClick?.(i.slice)}update(e){this.setOptions({data:e})}},A=class extends D{compute(e,t,r,i){return(0,n.computeScatterLayout)(this.options,e,t,r,i)}draw(e,t,r,i,a,o){(0,n.renderScatter)(e,t,r,this.options,i,a,o)}describe(){let e=this.options.series.reduce((e,t)=>e+t.points.length,0);return`Scatter chart${this.options.xLabel&&this.options.yLabel?` of ${this.options.yLabel} against ${this.options.xLabel}`:``}, ${e} points`}clickable(){return this.options.onPointClick!==void 0}hits(e,t,r){return(0,n.nearestPoint)(e,t,r)!==null}clickAt(e,t,r){let i=(0,n.nearestPoint)(e,t,r);i&&this.options.onPointClick?.(i.point,i.series)}update(e){this.setOptions({series:e})}},j=class extends D{compute(e,t,r,i){return(0,n.computeHistogramLayout)(this.options,e,t,r,i)}draw(e,t,r,i,a,o){(0,n.renderHistogram)(e,t,r,this.options,i,a,o)}describe(){return`Histogram of ${this.options.values.length} values`}clickable(){return!1}hits(){return!1}clickAt(){}update(e){this.setOptions({values:e})}},M=class extends D{compute(e,t,r,i){return(0,n.computeCalendarLayout)(this.options,e,t,r,i)}draw(e,t,r,i,a,o){(0,n.renderCalendar)(e,t,r,this.options,i,a,o)}describe(){let e=this.options.data.map(e=>e.date).filter(e=>/^\d{4}-\d{2}-\d{2}$/.test(e)).sort(),t=this.options.from??e[0],n=this.options.to??e[e.length-1];return t&&n?`Calendar of daily values from ${t} to ${n}`:`Calendar of daily values`}clickable(){return this.options.onDayClick!==void 0}hits(e,t,r){return(0,n.hitDay)(e,t,r)?.day!==void 0}clickAt(e,t,r){let i=(0,n.hitDay)(e,t,r)?.day;i&&this.options.onDayClick?.(i)}update(e){this.setOptions({data:e})}},N=12,P=class extends D{compute(e,t,r,i){return(0,n.computeMatrixLayout)(this.options,e,t,r,i)}draw(e,t,r,i,a,o){(0,n.renderMatrix)(e,t,r,this.options,i,a,o)}describe(){let{rows:e,columns:t}=this.options;return t?e.length+t.length<=N?`Matrix of ${e.join(`, `)} by ${t.join(`, `)}`:`Matrix of ${e.length} rows by ${t.length} columns`:e.length<=N?`Matrix of ${e.join(`, `)}`:`Matrix of ${e.length} rows`}clickable(){return this.options.onCellClick!==void 0}hits(e,t,r){return(0,n.hitMatrixCell)(e,t,r)!==null}clickAt(e,t,r){let i=(0,n.hitMatrixCell)(e,t,r);i&&this.options.onCellClick?.(i.cell)}update(e){this.setOptions({values:e})}},F=class extends D{compute(e,t,r,i){return(0,n.computeCounterClockLayout)(this.options,e,t,r,i)}draw(e,t,r,i,a,o){(0,n.renderCounterClock)(e,t,r,this.options,i,a,o)}describe(){return`Counter-clock chart of price against volume, ${this.options.period??25}-bar averages`}clickable(){return this.options.onPointClick!==void 0}hits(e,t,r){return(0,n.nearestCounterClockPoint)(e,t,r)!==null}clickAt(e,t,r){let i=(0,n.nearestCounterClockPoint)(e,t,r);i&&this.options.onPointClick?.(i.point)}getPhase(){return(0,n.counterClockPhase)((0,n.counterClockPoints)(this.options.data,this.options.period??25,(0,n.shownCount)(this.options)))}update(e){this.setOptions({data:e})}},I=[`Jan`,`Feb`,`Mar`,`Apr`,`May`,`Jun`,`Jul`,`Aug`,`Sep`,`Oct`,`Nov`,`Dec`];function L(e){return e.map(e=>({time:e.time,value:e.equity}))}function R(e){let t=-1/0;return e.map(e=>{e.equity>t&&(t=e.equity);let n=t>0?(e.equity/t-1)*100:0;return{time:e.time,value:n}})}function z(e){if(e.length===0)return[];let n=[];for(let r of e){let e=(0,t.timeframeBucketStart)(r.time,`1M`),i=n[n.length-1];i&&i.key===e?i.close=r.equity:n.push({key:e,close:r.equity})}let r=e[0].equity,i=[];for(let e of n){let t=r===0?1:r,n=(e.close/t-1)*100;r=e.close;let a=new Date(e.key),o=a.getUTCFullYear(),s=a.getUTCMonth();i.push({id:`${o}-${String(s+1).padStart(2,`0`)}`,label:I[s],group:String(o),value:n})}return i}var B=100;function V(e){return`${e>0?`+`:``}${e.toFixed(2)}%`}function H(e){return e>0?`positive`:e<0?`negative`:`neutral`}function U(e){return[{label:`Total Return`,value:V(e.totalReturnPct*B),tone:H(e.totalReturnPct)},{label:`CAGR`,value:V(e.cagr*B),tone:H(e.cagr)},{label:`Sharpe`,value:e.sharpe.toFixed(2),tone:H(e.sharpe)},{label:`Sortino`,value:e.sortino.toFixed(2),tone:H(e.sortino)},{label:`Max Drawdown`,value:V(-Math.abs(e.maxDrawdownPct)*B),tone:`negative`},{label:`Win Rate`,value:`${(e.winRate*B).toFixed(1)}%`,tone:`neutral`},{label:`Profit Factor`,value:Number.isFinite(e.profitFactor)?e.profitFactor.toFixed(2):`∞`,tone:H(e.profitFactor-1)},{label:`Trades`,value:String(e.trades),tone:`neutral`}]}function W(e){return!e||e===`dark`?t.DARK_THEME:e===`light`?t.LIGHT_THEME:e}var G=class{options;theme;root;equityChart=null;drawdownChart=null;heatmap=null;constructor(e,t){this.options=t,this.theme=W(t.theme),this.root=document.createElement(`div`),this.build(),e.appendChild(this.root)}build(){let e=this.theme,{result:t,title:n,subtitle:r}=this.options,i=this.panelBackground(),a=e.grid;if(this.root.style.cssText=[`display:flex`,`flex-direction:column`,`gap:14px`,`width:100%`,`box-sizing:border-box`,`padding:16px`,`background:${e.background}`,`color:${e.text}`,`font-family:${e.font.family}`].join(`;`),n||r){let t=document.createElement(`div`);if(n){let r=document.createElement(`div`);r.textContent=n,r.style.cssText=`font-size:${e.font.sizeLarge}px;font-weight:600;letter-spacing:-0.01em;`,t.appendChild(r)}if(r){let n=document.createElement(`div`);n.textContent=r,n.style.cssText=`font-size:${e.font.sizeSmall}px;color:${e.textSecondary};margin-top:2px;`,t.appendChild(n)}this.root.appendChild(t)}this.root.appendChild(this.buildStatsStrip(U(t.metrics),i,a));let o=document.createElement(`div`);o.style.cssText=[`display:grid`,`grid-template-columns:repeat(auto-fit, minmax(280px, 1fr))`,`grid-auto-rows:220px`,`gap:14px`].join(`;`),this.root.appendChild(o);let s=this.buildPanel(`Equity Curve`,i,a);s.wrap.style.gridColumn=`1 / -1`,o.appendChild(s.wrap),this.equityChart=new x(s.body,{data:L(t.equityCurve),theme:e,lineColor:e.candleUp,fillArea:!0,crosshair:!0});let c=this.buildPanel(`Drawdown`,i,a);o.appendChild(c.wrap),this.drawdownChart=new x(c.body,{data:R(t.equityCurve),theme:e,lineColor:e.candleDown,fillArea:!0,crosshair:!0,valueFormat:e=>`${e.toFixed(1)}%`});let l=z(t.equityCurve),u=this.buildPanel(`Monthly Returns`,i,a);o.appendChild(u.wrap),this.heatmap=new S(u.body,{data:l,theme:e,showValues:!0,valueFormat:e=>`${e>=0?`+`:``}${e.toFixed(1)}`,colorScale:{negative:e.candleDown,zero:i,positive:e.candleUp}})}buildStatsStrip(e,t,n){let r=document.createElement(`div`);r.style.cssText=[`display:grid`,`grid-template-columns:repeat(auto-fit, minmax(120px, 1fr))`,`gap:10px`].join(`;`);let i=this.theme;for(let a of e){let e=document.createElement(`div`);e.style.cssText=[`background:${t}`,`border:1px solid ${n}`,`border-radius:10px`,`padding:10px 12px`,`display:flex`,`flex-direction:column`,`gap:4px`].join(`;`);let o=document.createElement(`div`);o.textContent=a.label,o.style.cssText=`font-size:${i.font.sizeSmall}px;color:${i.textSecondary};text-transform:uppercase;letter-spacing:0.04em;`;let s=document.createElement(`div`);s.textContent=a.value;let c=a.tone===`positive`?i.candleUp:a.tone===`negative`?i.candleDown:i.text;s.style.cssText=`font-size:${i.font.sizeLarge}px;font-weight:600;color:${c};font-variant-numeric:tabular-nums;`,e.appendChild(o),e.appendChild(s),r.appendChild(e)}return r}buildPanel(e,t,n){let r=this.theme,i=document.createElement(`div`);i.style.cssText=[`background:${t}`,`border:1px solid ${n}`,`border-radius:10px`,`overflow:hidden`,`display:flex`,`flex-direction:column`].join(`;`);let a=document.createElement(`div`);a.textContent=e,a.style.cssText=[`font-size:${r.font.sizeSmall}px`,`font-weight:600`,`color:${r.textSecondary}`,`padding:8px 12px`,`border-bottom:1px solid ${n}`,`text-transform:uppercase`,`letter-spacing:0.04em`].join(`;`);let o=document.createElement(`div`);return o.style.cssText=`flex:1;min-height:0;position:relative;`,i.appendChild(a),i.appendChild(o),{wrap:i,body:o}}panelBackground(){return this.theme.name===`light`?`rgba(0,0,0,0.02)`:`rgba(255,255,255,0.03)`}update(e){this.options={...this.options,result:e},this.destroyCharts(),this.root.replaceChildren(),this.build()}setTheme(e){this.theme=W(e),this.options={...this.options,theme:e},this.destroyCharts(),this.root.replaceChildren(),this.build()}destroyCharts(){this.equityChart?.destroy(),this.drawdownChart?.destroy(),this.heatmap?.destroy(),this.equityChart=null,this.drawdownChart=null,this.heatmap=null}destroy(){this.destroyCharts(),this.root.remove()}};Object.defineProperty(exports,`AlertManager`,{enumerable:!0,get:function(){return n.AlertManager}}),Object.defineProperty(exports,`Animator`,{enumerable:!0,get:function(){return n.Animator}}),exports.BarChart=O,Object.defineProperty(exports,`BarCountdown`,{enumerable:!0,get:function(){return n.BarCountdown}}),Object.defineProperty(exports,`BinanceAdapter`,{enumerable:!0,get:function(){return n.BinanceAdapter}}),Object.defineProperty(exports,`BybitAdapter`,{enumerable:!0,get:function(){return n.BybitAdapter}}),Object.defineProperty(exports,`CANDLE_PATTERNS`,{enumerable:!0,get:function(){return n.CANDLE_PATTERNS}}),Object.defineProperty(exports,`CHART_STYLE_KEYS`,{enumerable:!0,get:function(){return t.CHART_STYLE_KEYS}}),exports.CORRECTABLE_BARS=a,exports.CalendarChart=M,exports.Chart=e.c,exports.ChartGrid=v,Object.defineProperty(exports,`ChartLegend`,{enumerable:!0,get:function(){return n.ChartLegend}}),Object.defineProperty(exports,`ChartStateManager`,{enumerable:!0,get:function(){return n.ChartStateManager}}),Object.defineProperty(exports,`CoinbaseAdapter`,{enumerable:!0,get:function(){return n.CoinbaseAdapter}}),Object.defineProperty(exports,`CompareRenderer`,{enumerable:!0,get:function(){return n.CompareRenderer}}),exports.CounterClockChart=F,Object.defineProperty(exports,`CrosshairTooltip`,{enumerable:!0,get:function(){return n.CrosshairTooltip}}),Object.defineProperty(exports,`CurrentPriceLine`,{enumerable:!0,get:function(){return n.CurrentPriceLine}}),Object.defineProperty(exports,`DARK_PRICE_LIMITS`,{enumerable:!0,get:function(){return t.DARK_PRICE_LIMITS}}),Object.defineProperty(exports,`DARK_TERMINAL`,{enumerable:!0,get:function(){return t.DARK_TERMINAL}}),Object.defineProperty(exports,`DARK_THEME`,{enumerable:!0,get:function(){return t.DARK_THEME}}),Object.defineProperty(exports,`DEFAULT_DRAWING_STYLE`,{enumerable:!0,get:function(){return t.DEFAULT_DRAWING_STYLE}}),Object.defineProperty(exports,`DEFAULT_FONT_FAMILY`,{enumerable:!0,get:function(){return t.DEFAULT_FONT_FAMILY}}),exports.DEFAULT_HISTORY_PAGE_SIZE=e.C,Object.defineProperty(exports,`DEFAULT_LEGEND_CONFIG`,{enumerable:!0,get:function(){return n.DEFAULT_LEGEND_CONFIG}}),Object.defineProperty(exports,`DEFAULT_MAX_WEBGL_CHARTS`,{enumerable:!0,get:function(){return n.DEFAULT_MAX_WEBGL_CHARTS}}),Object.defineProperty(exports,`DEFAULT_RECONNECT`,{enumerable:!0,get:function(){return t.DEFAULT_RECONNECT}}),Object.defineProperty(exports,`DEFAULT_SESSION_HOURS`,{enumerable:!0,get:function(){return n.DEFAULT_SESSION_HOURS}}),Object.defineProperty(exports,`DEFAULT_SIGNAL_STYLE`,{enumerable:!0,get:function(){return t.DEFAULT_SIGNAL_STYLE}}),Object.defineProperty(exports,`DEFAULT_STREAM_CONFIG`,{enumerable:!0,get:function(){return t.DEFAULT_STREAM_CONFIG}}),Object.defineProperty(exports,`DEFAULT_TIMEFRAME_FAVORITES`,{enumerable:!0,get:function(){return t.DEFAULT_TIMEFRAME_FAVORITES}}),Object.defineProperty(exports,`DEFAULT_TRADE_ZONE_STYLE`,{enumerable:!0,get:function(){return t.DEFAULT_TRADE_ZONE_STYLE}}),Object.defineProperty(exports,`DEFAULT_TRADING_CONFIG`,{enumerable:!0,get:function(){return t.DEFAULT_TRADING_CONFIG}}),Object.defineProperty(exports,`DataExporter`,{enumerable:!0,get:function(){return n.DataExporter}}),exports.DataManager=e.T,exports.DepthChart=b,exports.DonutChart=k,exports.DragDropImporter=e.o,Object.defineProperty(exports,`DrawingBase`,{enumerable:!0,get:function(){return n.DrawingBase}}),exports.EXCHANGE_TIMEZONE=e.l,exports.EXCHANGE_TIME_ZONE=e.u,Object.defineProperty(exports,`Easing`,{enumerable:!0,get:function(){return n.Easing}}),exports.EquityCurveChart=x,exports.GaugeChart=E,exports.HISTORY_RETRY_MS=e.w,Object.defineProperty(exports,`HNX_SESSIONS`,{enumerable:!0,get:function(){return t.HNX_SESSIONS}}),Object.defineProperty(exports,`HOSE_SESSIONS`,{enumerable:!0,get:function(){return t.HOSE_SESSIONS}}),exports.HeatmapChart=S,exports.HistogramChart=j,Object.defineProperty(exports,`INDICATOR_CATEGORIES`,{enumerable:!0,get:function(){return n.INDICATOR_CATEGORIES}}),Object.defineProperty(exports,`IndicatorBase`,{enumerable:!0,get:function(){return n.IndicatorBase}}),Object.defineProperty(exports,`IndicatorValueMap`,{enumerable:!0,get:function(){return n.IndicatorValueMap}}),Object.defineProperty(exports,`KEPT_BUCKETS`,{enumerable:!0,get:function(){return n.KEPT_BUCKETS}}),Object.defineProperty(exports,`KRX_SESSIONS`,{enumerable:!0,get:function(){return t.KRX_SESSIONS}}),Object.defineProperty(exports,`KR_COLORS`,{enumerable:!0,get:function(){return t.KR_COLORS}}),Object.defineProperty(exports,`KeyboardHandler`,{enumerable:!0,get:function(){return n.KeyboardHandler}}),Object.defineProperty(exports,`KrakenAdapter`,{enumerable:!0,get:function(){return n.KrakenAdapter}}),Object.defineProperty(exports,`LIGHT_PRICE_LIMITS`,{enumerable:!0,get:function(){return t.LIGHT_PRICE_LIMITS}}),Object.defineProperty(exports,`LIGHT_THEME`,{enumerable:!0,get:function(){return t.LIGHT_THEME}}),exports.LayoutManager=e.x,exports.LayoutSession=e.t,Object.defineProperty(exports,`MARKET_CRYPTO`,{enumerable:!0,get:function(){return t.MARKET_CRYPTO}}),Object.defineProperty(exports,`MARKET_HNX`,{enumerable:!0,get:function(){return t.MARKET_HNX}}),Object.defineProperty(exports,`MARKET_HOSE`,{enumerable:!0,get:function(){return t.MARKET_HOSE}}),Object.defineProperty(exports,`MARKET_HOSE_ETF`,{enumerable:!0,get:function(){return t.MARKET_HOSE_ETF}}),Object.defineProperty(exports,`MARKET_KRX`,{enumerable:!0,get:function(){return t.MARKET_KRX}}),Object.defineProperty(exports,`MARKET_NXT`,{enumerable:!0,get:function(){return t.MARKET_NXT}}),Object.defineProperty(exports,`MARKET_NYSE`,{enumerable:!0,get:function(){return t.MARKET_NYSE}}),Object.defineProperty(exports,`MARKET_UPBIT_KRW`,{enumerable:!0,get:function(){return t.MARKET_UPBIT_KRW}}),Object.defineProperty(exports,`MARKET_UPCOM`,{enumerable:!0,get:function(){return t.MARKET_UPCOM}}),Object.defineProperty(exports,`MARKET_VN30F`,{enumerable:!0,get:function(){return t.MARKET_VN30F}}),Object.defineProperty(exports,`MAX_ALERT_BARS`,{enumerable:!0,get:function(){return n.MAX_ALERT_BARS}}),exports.MAX_LAYOUT_NAME=e.n,Object.defineProperty(exports,`MIN_ALERT_BARS`,{enumerable:!0,get:function(){return n.MIN_ALERT_BARS}}),Object.defineProperty(exports,`MS_TIME_THRESHOLD`,{enumerable:!0,get:function(){return t.MS_TIME_THRESHOLD}}),Object.defineProperty(exports,`ManualFeed`,{enumerable:!0,get:function(){return n.ManualFeed}}),exports.MatrixChart=P,Object.defineProperty(exports,`MockAdapter`,{enumerable:!0,get:function(){return n.MockAdapter}}),Object.defineProperty(exports,`NXT_SESSIONS`,{enumerable:!0,get:function(){return t.NXT_SESSIONS}}),exports.PLUGIN_API_VERSION=e.v,Object.defineProperty(exports,`PRICE_SOURCES`,{enumerable:!0,get:function(){return t.PRICE_SOURCES}}),Object.defineProperty(exports,`PaperExecutionAdapter`,{enumerable:!0,get:function(){return n.PaperExecutionAdapter}}),exports.PerformanceDashboard=G,exports.PluginManager=e.p,Object.defineProperty(exports,`PollingAdapter`,{enumerable:!0,get:function(){return n.PollingAdapter}}),Object.defineProperty(exports,`RANGE_PRESETS`,{enumerable:!0,get:function(){return n.RANGE_PRESETS}}),Object.defineProperty(exports,`ReconnectManager`,{enumerable:!0,get:function(){return n.ReconnectManager}}),Object.defineProperty(exports,`ReplayController`,{enumerable:!0,get:function(){return n.ReplayController}}),Object.defineProperty(exports,`ReplayManager`,{enumerable:!0,get:function(){return n.ReplayManager}}),Object.defineProperty(exports,`ResamplingAdapter`,{enumerable:!0,get:function(){return n.ResamplingAdapter}}),Object.defineProperty(exports,`ReshapeMemo`,{enumerable:!0,get:function(){return n.ReshapeMemo}}),Object.defineProperty(exports,`SANS_FONT_FAMILY`,{enumerable:!0,get:function(){return t.SANS_FONT_FAMILY}}),exports.ScatterChart=A,Object.defineProperty(exports,`Screenshot`,{enumerable:!0,get:function(){return n.Screenshot}}),Object.defineProperty(exports,`SessionBreaks`,{enumerable:!0,get:function(){return n.SessionBreaks}}),Object.defineProperty(exports,`SessionShading`,{enumerable:!0,get:function(){return n.SessionShading}}),Object.defineProperty(exports,`SignalMarkerManager`,{enumerable:!0,get:function(){return n.SignalMarkerManager}}),exports.SparklineChart=y,Object.defineProperty(exports,`StreamManager`,{enumerable:!0,get:function(){return n.StreamManager}}),Object.defineProperty(exports,`TC_PALETTE`,{enumerable:!0,get:function(){return t.TC_PALETTE}}),Object.defineProperty(exports,`TC_SERIES_COLORS`,{enumerable:!0,get:function(){return t.TC_SERIES_COLORS}}),Object.defineProperty(exports,`TIMEFRAMES_CRYPTO`,{enumerable:!0,get:function(){return t.TIMEFRAMES_CRYPTO}}),Object.defineProperty(exports,`TIMEFRAMES_FOREX`,{enumerable:!0,get:function(){return t.TIMEFRAMES_FOREX}}),Object.defineProperty(exports,`TIMEFRAMES_STOCK`,{enumerable:!0,get:function(){return t.TIMEFRAMES_STOCK}}),exports.ThemeManager=e.S,Object.defineProperty(exports,`TickAggregator`,{enumerable:!0,get:function(){return n.TickAggregator}}),Object.defineProperty(exports,`TickBarAdapter`,{enumerable:!0,get:function(){return n.TickBarAdapter}}),Object.defineProperty(exports,`TickBarBuilder`,{enumerable:!0,get:function(){return n.TickBarBuilder}}),Object.defineProperty(exports,`TradeZoneManager`,{enumerable:!0,get:function(){return n.TradeZoneManager}}),Object.defineProperty(exports,`UPCOM_SESSIONS`,{enumerable:!0,get:function(){return t.UPCOM_SESSIONS}}),Object.defineProperty(exports,`UndoRedoManager`,{enumerable:!0,get:function(){return n.UndoRedoManager}}),Object.defineProperty(exports,`UpbitAdapter`,{enumerable:!0,get:function(){return n.UpbitAdapter}}),Object.defineProperty(exports,`VN30F_SESSIONS`,{enumerable:!0,get:function(){return t.VN30F_SESSIONS}}),Object.defineProperty(exports,`VN_COLORS`,{enumerable:!0,get:function(){return t.VN_COLORS}}),Object.defineProperty(exports,`VOLUME_ALPHA`,{enumerable:!0,get:function(){return t.VOLUME_ALPHA}}),Object.defineProperty(exports,`VolumeRenderer`,{enumerable:!0,get:function(){return n.VolumeRenderer}}),exports.WaterfallChart=C,Object.defineProperty(exports,`Watermark`,{enumerable:!0,get:function(){return n.Watermark}}),Object.defineProperty(exports,`WebSocketAdapter`,{enumerable:!0,get:function(){return n.WebSocketAdapter}}),Object.defineProperty(exports,`adapterFromFeed`,{enumerable:!0,get:function(){return n.adapterFromFeed}}),Object.defineProperty(exports,`axisTimes`,{enumerable:!0,get:function(){return n.axisTimes}}),Object.defineProperty(exports,`barIndexToX`,{enumerable:!0,get:function(){return n.barIndexToX}}),Object.defineProperty(exports,`barTimeUnit`,{enumerable:!0,get:function(){return t.barTimeUnit}}),Object.defineProperty(exports,`barsAreDaily`,{enumerable:!0,get:function(){return t.barsAreDaily}}),exports.cleanLayoutName=e.r,exports.clearGlobalPlugins=e.m,exports.computeDrawdownCurve=R,exports.computeMonthlyReturns=z,Object.defineProperty(exports,`computePriceLimits`,{enumerable:!0,get:function(){return t.computePriceLimits}}),Object.defineProperty(exports,`contrastRatio`,{enumerable:!0,get:function(){return t.contrastRatio}}),Object.defineProperty(exports,`correlationMatrix`,{enumerable:!0,get:function(){return n.correlationMatrix}}),Object.defineProperty(exports,`counterClockPhase`,{enumerable:!0,get:function(){return n.counterClockPhase}}),Object.defineProperty(exports,`counterClockPoints`,{enumerable:!0,get:function(){return n.counterClockPoints}}),Object.defineProperty(exports,`createMarketTheme`,{enumerable:!0,get:function(){return t.createMarketTheme}}),Object.defineProperty(exports,`createVNTheme`,{enumerable:!0,get:function(){return t.createVNTheme}}),Object.defineProperty(exports,`describeInputs`,{enumerable:!0,get:function(){return n.describeInputs}}),Object.defineProperty(exports,`detectCandlePatterns`,{enumerable:!0,get:function(){return n.detectCandlePatterns}}),exports.feedBars=h,Object.defineProperty(exports,`feedFromAdapter`,{enumerable:!0,get:function(){return n.feedFromAdapter}}),Object.defineProperty(exports,`formatFraction`,{enumerable:!0,get:function(){return t.formatFraction}}),Object.defineProperty(exports,`formatNumber`,{enumerable:!0,get:function(){return t.formatNumber}}),Object.defineProperty(exports,`formatTooltipTime`,{enumerable:!0,get:function(){return n.formatTooltipTime}}),Object.defineProperty(exports,`formatVND`,{enumerable:!0,get:function(){return t.formatVND}}),Object.defineProperty(exports,`formatVolumeLoc`,{enumerable:!0,get:function(){return t.formatVolumeLoc}}),Object.defineProperty(exports,`fractionTick`,{enumerable:!0,get:function(){return t.fractionTick}}),Object.defineProperty(exports,`getCurrentSession`,{enumerable:!0,get:function(){return t.getCurrentSession}}),exports.getGlobalPlugins=e.h,Object.defineProperty(exports,`getLocale`,{enumerable:!0,get:function(){return t.getLocale}}),Object.defineProperty(exports,`histogramBins`,{enumerable:!0,get:function(){return n.histogramBins}}),Object.defineProperty(exports,`indicatorCategory`,{enumerable:!0,get:function(){return n.indicatorCategory}}),Object.defineProperty(exports,`indicatorSource`,{enumerable:!0,get:function(){return t.indicatorSource}}),Object.defineProperty(exports,`inkOn`,{enumerable:!0,get:function(){return t.inkOn}}),Object.defineProperty(exports,`isDataFeed`,{enumerable:!0,get:function(){return n.isDataFeed}}),Object.defineProperty(exports,`isPriceLevelAlert`,{enumerable:!0,get:function(){return n.isPriceLevelAlert}}),Object.defineProperty(exports,`isPriceSource`,{enumerable:!0,get:function(){return t.isPriceSource}}),Object.defineProperty(exports,`isTimeFrame`,{enumerable:!0,get:function(){return t.isTimeFrame}}),Object.defineProperty(exports,`isValidTimeZone`,{enumerable:!0,get:function(){return t.isValidTimeZone}}),exports.localStorageLayouts=e.i,Object.defineProperty(exports,`lttbDownsample`,{enumerable:!0,get:function(){return n.lttbDownsample}}),Object.defineProperty(exports,`lttbVisibleIndices`,{enumerable:!0,get:function(){return n.lttbVisibleIndices}}),Object.defineProperty(exports,`marketStatus`,{enumerable:!0,get:function(){return t.marketStatus}}),exports.memoryLayouts=e.a,Object.defineProperty(exports,`niceScale`,{enumerable:!0,get:function(){return n.niceScale}}),Object.defineProperty(exports,`normalizeBar`,{enumerable:!0,get:function(){return t.normalizeBar}}),Object.defineProperty(exports,`normalizeBarTime`,{enumerable:!0,get:function(){return t.normalizeBarTime}}),Object.defineProperty(exports,`offsetAt`,{enumerable:!0,get:function(){return t.offsetAt}}),exports.overlayScale=g,exports.overlaysForLayer=e.y,Object.defineProperty(exports,`parseIndicatorSource`,{enumerable:!0,get:function(){return t.parseIndicatorSource}}),exports.parseOHLCV=e.s,Object.defineProperty(exports,`parseTimeframe`,{enumerable:!0,get:function(){return t.parseTimeframe}}),Object.defineProperty(exports,`pickBaseTimeframe`,{enumerable:!0,get:function(){return t.pickBaseTimeframe}}),exports.pluginKey=e.b,Object.defineProperty(exports,`priceFormatterFor`,{enumerable:!0,get:function(){return t.priceFormatterFor}}),Object.defineProperty(exports,`priceStepAt`,{enumerable:!0,get:function(){return t.priceStepAt}}),Object.defineProperty(exports,`priceToY`,{enumerable:!0,get:function(){return n.priceToY}}),Object.defineProperty(exports,`priceToYMapper`,{enumerable:!0,get:function(){return n.priceToYMapper}}),Object.defineProperty(exports,`rangePresetStart`,{enumerable:!0,get:function(){return n.rangePresetStart}}),Object.defineProperty(exports,`rankSymbols`,{enumerable:!0,get:function(){return t.rankSymbols}}),Object.defineProperty(exports,`readNews`,{enumerable:!0,get:function(){return t.readNews}}),Object.defineProperty(exports,`readQuote`,{enumerable:!0,get:function(){return t.readQuote}}),Object.defineProperty(exports,`readableOn`,{enumerable:!0,get:function(){return t.readableOn}}),Object.defineProperty(exports,`registerLocale`,{enumerable:!0,get:function(){return t.registerLocale}}),exports.registerPlugin=e.g,Object.defineProperty(exports,`resampleBars`,{enumerable:!0,get:function(){return t.resampleBars}}),Object.defineProperty(exports,`roundToPriceStep`,{enumerable:!0,get:function(){return t.roundToPriceStep}}),Object.defineProperty(exports,`scaleMarketPrices`,{enumerable:!0,get:function(){return t.scaleMarketPrices}}),exports.selectKeyStats=U,Object.defineProperty(exports,`servesTimeframe`,{enumerable:!0,get:function(){return n.servesTimeframe}}),Object.defineProperty(exports,`setLocale`,{enumerable:!0,get:function(){return t.setLocale}}),Object.defineProperty(exports,`setMaxWebGLCharts`,{enumerable:!0,get:function(){return n.setMaxWebGLCharts}}),Object.defineProperty(exports,`sourcePrice`,{enumerable:!0,get:function(){return t.sourcePrice}}),Object.defineProperty(exports,`stepDecimals`,{enumerable:!0,get:function(){return t.stepDecimals}}),Object.defineProperty(exports,`symbolTimeZone`,{enumerable:!0,get:function(){return t.symbolTimeZone}}),exports.syncIndicators=i,Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return t.t}}),Object.defineProperty(exports,`tickBarCount`,{enumerable:!0,get:function(){return t.tickBarCount}}),Object.defineProperty(exports,`timeToX`,{enumerable:!0,get:function(){return n.timeToX}}),Object.defineProperty(exports,`timeframeBucketStart`,{enumerable:!0,get:function(){return t.timeframeBucketStart}}),Object.defineProperty(exports,`timeframeToMs`,{enumerable:!0,get:function(){return t.timeframeToMs}}),Object.defineProperty(exports,`timestampToBarIndex`,{enumerable:!0,get:function(){return n.timestampToBarIndex}}),exports.toEquityPoints=L,Object.defineProperty(exports,`toHeikinAshi`,{enumerable:!0,get:function(){return n.toHeikinAshi}}),Object.defineProperty(exports,`toKagi`,{enumerable:!0,get:function(){return n.toKagi}}),Object.defineProperty(exports,`toLineBreak`,{enumerable:!0,get:function(){return n.toLineBreak}}),Object.defineProperty(exports,`toPointAndFigure`,{enumerable:!0,get:function(){return n.toPointAndFigure}}),Object.defineProperty(exports,`toRangeBars`,{enumerable:!0,get:function(){return n.toRangeBars}}),Object.defineProperty(exports,`toRenko`,{enumerable:!0,get:function(){return n.toRenko}}),exports.unregisterPlugin=e._,Object.defineProperty(exports,`usesKoreanUnits`,{enumerable:!0,get:function(){return t.usesKoreanUnits}}),Object.defineProperty(exports,`vn30fContracts`,{enumerable:!0,get:function(){return t.vn30fContracts}}),Object.defineProperty(exports,`vn30fLastTradingDay`,{enumerable:!0,get:function(){return t.vn30fLastTradingDay}}),Object.defineProperty(exports,`volumeColor`,{enumerable:!0,get:function(){return t.volumeColor}}),Object.defineProperty(exports,`wallToUtc`,{enumerable:!0,get:function(){return t.wallToUtc}}),Object.defineProperty(exports,`withResampling`,{enumerable:!0,get:function(){return n.withResampling}}),Object.defineProperty(exports,`withTickBars`,{enumerable:!0,get:function(){return n.withTickBars}}),Object.defineProperty(exports,`xToBarIndex`,{enumerable:!0,get:function(){return n.xToBarIndex}}),Object.defineProperty(exports,`xToTime`,{enumerable:!0,get:function(){return n.xToTime}}),Object.defineProperty(exports,`yToPrice`,{enumerable:!0,get:function(){return n.yToPrice}}),Object.defineProperty(exports,`zoneOffsetMinutes`,{enumerable:!0,get:function(){return t.zoneOffsetMinutes}});
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./LayoutSession-BrXo314m.cjs`);let t=require(`@tradecanvas/commons`),n=require(`@tradecanvas/core`);function r(e){let{id:t,params:n={},position:r=null}=typeof e==`string`?{id:e}:e;return JSON.stringify([t,Object.keys(n).sort().map(e=>[e,n[e]]),r])}function i(e,t,n){let i=new Map,a=t.map(e=>{let t=r(e),n=i.get(t)??0;return i.set(t,n+1),{spec:e,key:`${t}#${n}`}}),o=new Set(a.map(e=>e.key));for(let[t,r]of[...n])o.has(t)||(e.removeIndicator(r),n.delete(t));for(let{spec:t,key:r}of a){if(n.has(r))continue;let i=typeof t==`string`?e.addIndicator(t):t.position===void 0?e.addIndicator(t.id,t.params??{}):e.addIndicator(t.id,t.params??{},t.position);i&&n.set(r,i)}}var a=3,o=e=>({time:e.time,open:e.open,high:e.high,low:e.low,close:e.close,volume:e.volume}),s=e=>e.length>0?e[e.length-1]:null;function c(t,n,r){for(let i=0;i<r;i++)if(!e.D(t[i],n[i]))return!1;return!0}function l(e,t){if(e.isReplayActive())return!0;let n=s(e.getData());return t.inReplay?n?.time===t.last?.time:n===t.shownBar?n?.time===t.last?.time||!e.isExtendedHoursVisible():!1}function u(t,n,r){let i=[];for(let a=0;a<n.length;a++){let s=t[r+a];if(!e.D(s,n[a])){if(s.time!==n[a].time||!e.E(s))return null;i.push(o(s))}}return i}function d(e,t){if(t.length===0)return!0;if(!e.updateBar)return!1;for(let n of t)if(!e.updateBar(n))return!1;return!0}function f(e){return e.slice(Math.max(1,e.length-1-3),-1).map(o)}function p(t,n){let r=[];for(let i=n;i<t.length;i++){if(!e.E(t[i])||!(t[i].time>t[i-1].time))return null;r.push(o(t[i]))}return r}function m(t,n,r){let i=r.length;if(i===0||!r.last||!e.E(r.last)||n.length<i||!l(t,r))return!1;let a=r.recent??[],s=i-1-a.length;if(n!==r.source&&(r.source.length!==i||!c(r.source,n,s)))return!1;let f=n[i-1];if(f.time!==r.last.time||!e.E(f))return!1;let m=u(n,a,s),h=p(n,i);return!m||!h||!d(t,m)?!1:(e.D(f,r.last)||t.updateLastBar(o(f)),h.length===1?t.appendBar(h[0]):h.length>1&&t.appendBars(h),!0)}function h(e,t,n){(!n||!m(e,t,n))&&e.setData(t.map(o));let r=t.length>0?o(t[t.length-1]):null,i=e.isReplayActive();return{source:t,length:t.length,last:r,recent:f(t),shownBar:i?null:s(e.getData()),inReplay:i}}function g(e){let{viewport:t,data:r}=e,i=(0,n.priceToYMapper)(t),a=r.length-1,o=Math.max(0,Math.floor(t.visibleRange.from)),s=Math.min(a,Math.ceil(t.visibleRange.to)),c=e=>r.length>0?(0,n.timestampToBarIndex)(e,r):e;return{timeToX:e=>(0,n.barIndexToX)(c(e),t),xToTime:e=>{let i=(0,n.xToBarIndex)(e,t);return r.length>0?(0,n.barIndexToTime)(i,r):i},indexToX:e=>(0,n.barIndexToX)(e,t),xToIndex:e=>(0,n.xToBarIndex)(e,t),priceToY:i,yToPrice:e=>(0,n.yToPrice)(e,t),barWidth:t.barWidth,visible:s<o?{from:0,to:-1}:{from:o,to:s}}}var _={"1x1":{cols:1,rows:1},"1x2":{cols:2,rows:1},"2x1":{cols:1,rows:2},"2x2":{cols:2,rows:2},"1x3":{cols:3,rows:1},"3x1":{cols:1,rows:3},"2x3":{cols:3,rows:2},"3x2":{cols:2,rows:3}},v=class{root;cells=[];layout;options;destroyed=!1;syncing=!1;constructor(e,t={}){this.options=t,this.layout=t.layout??`2x2`,this.root=document.createElement(`div`),this.root.style.cssText=`display:grid;width:100%;height:100%;overflow:hidden;`,e.appendChild(this.root),this.applyLayout(),this.createCells()}applyLayout(){let{cols:e,rows:t}=_[this.layout],n=this.options.gap??1;this.root.style.gridTemplateColumns=`repeat(${e}, 1fr)`,this.root.style.gridTemplateRows=`repeat(${t}, 1fr)`,this.root.style.gap=`${n}px`}createCells(){let{cols:e,rows:t}=_[this.layout],n=e*t;for(let e=0;e<n;e++)this.cells.push(this.createCell(e))}createCell(t){let n=this.options.cells?.[t]??{},r=document.createElement(`div`);r.style.cssText=`position:relative;overflow:hidden;min-width:0;min-height:0;`,this.root.appendChild(r);let i=new e.c(r,{chartType:`candlestick`,autoScale:!0,features:{crosshair:!0,keyboard:!0,volume:!0,legend:!0,priceAxis:!0,timeAxis:!0,grid:!0},...this.options.chartOptions,...n.chartOptions,theme:this.options.theme}),a={container:r,chart:i,symbol:n.symbol??`Chart ${t+1}`,timeframe:n.timeframe??`5m`};return this.options.syncCrosshair!==!1&&(i.on(`crosshairMove`,e=>{let t=e.payload.bar?.time;if(t!==void 0)for(let e of this.cells)e.chart!==i&&e.chart.setCrosshairTime(t)}),i.on(`crosshairLeave`,()=>{for(let e of this.cells)e.chart!==i&&e.chart.setCrosshairTime(null)})),this.options.syncTimeAxis!==!1&&i.on(`visibleRangeChange`,e=>{if(this.syncing)return;this.syncing=!0;let{from:t,to:n}=e.payload,r=i.getData();if(r.length>0&&t>=0&&n<r.length){let e=r[t]?.time,a=r[n]?.time;if(e&&a)for(let t of this.cells)t.chart!==i&&t.chart.setVisibleRange(e,a)}this.syncing=!1}),a}setLayout(e){if(e===this.layout)return;let t=this.cells.length,{cols:n,rows:r}=_[e],i=n*r;if(i<t)for(let e=t-1;e>=i;e--){let t=this.cells[e];t.chart.destroy(),t.container.remove(),this.cells.pop()}this.layout=e,this.applyLayout();for(let e=t;e<i;e++)this.cells.push(this.createCell(e))}getChart(e){return this.cells[e]?.chart??null}getCharts(){return this.cells.map(e=>e.chart)}getCellCount(){return this.cells.length}setData(e,t){this.cells[e]?.chart.setData(t)}setAllData(e){for(let t of this.cells)t.chart.setData(e)}async connectCell(e,t){let n=this.cells[e];n&&(n.symbol=t.symbol,n.timeframe=t.timeframe,await n.chart.connect(t))}async connectAll(e,t,r,i=500){let a=[];for(let o=0;o<this.cells.length&&o<t.length;o++)a.push(this.connectCell(o,{...typeof e==`function`?{adapter:e(t[o],o)}:(0,n.isDataFeed)(e)?{feed:e}:{adapter:e},symbol:t[o],timeframe:r,historyLimit:i}));await Promise.all(a)}setTheme(e){for(let t of this.cells)t.chart.setTheme(e)}destroy(){if(!this.destroyed){this.destroyed=!0;for(let e of this.cells)e.chart.destroy(),e.container.remove();this.cells=[],this.root.remove()}}},y=class extends n.BaseFinanceChart{options;constructor(e,t){super(e,t.theme),this.options=t,this.requestRender()}renderChart(e,t,r,i){(0,n.renderSparkline)(e,t,r,this.options,i)}update(e){this.options={...this.options,data:e},this.requestRender()}setOptions(e){this.options={...this.options,...e},this.requestRender()}},b=class extends n.BaseFinanceChart{options;crosshair=null;constructor(e,t){super(e,t.theme),this.options=t,t.crosshair!==!1&&(this.crosshair=new n.FinanceCrosshair(this.canvas,()=>this.requestRender())),this.requestRender()}renderChart(e,t,r,i){let a=this.crosshair?.getPosition()??null;(0,n.renderDepthChart)(e,t,r,this.options,i,a)}update(e){this.options={...this.options,data:e},this.requestRender()}setOptions(e){this.options={...this.options,...e},this.requestRender()}destroy(){this.crosshair?.destroy(),super.destroy()}},x=class extends n.BaseFinanceChart{options;crosshair=null;constructor(e,t){super(e,t.theme),this.options=t,t.crosshair!==!1&&(this.crosshair=new n.FinanceCrosshair(this.canvas,()=>this.requestRender())),this.requestRender()}renderChart(e,t,r,i){let a=this.crosshair?.getPosition()??null;(0,n.renderEquityCurve)(e,t,r,this.options,i,a)}update(e,t){this.options={...this.options,data:e},t!==void 0&&(this.options={...this.options,benchmark:t}),this.requestRender()}setOptions(e){this.options={...this.options,...e},this.requestRender()}destroy(){this.crosshair?.destroy(),super.destroy()}},S=class extends n.BaseFinanceChart{options;crosshair=null;cachedRects=[];cachedGroups=[];currentData=[];lastLayoutWidth=0;lastLayoutHeight=0;handleClick=null;constructor(e,t){super(e,t.theme),this.options=t,this.currentData=t.data??[],t.crosshair!==!1&&(this.crosshair=new n.FinanceCrosshair(this.canvas,()=>this.requestRender())),t.onCellClick&&(this.handleClick=e=>{let t=this.canvas.getBoundingClientRect(),n=e.clientX-t.left,r=e.clientY-t.top;this.onCanvasClick(n,r)},this.canvas.addEventListener(`click`,this.handleClick)),this.applyLabel(),this.recomputeLayout(),this.requestRender()}applyLabel(){let e=new Set(this.currentData.map(e=>e.group).filter(Boolean)).size,t=this.options.grouped&&e>0?`Market map of ${this.currentData.length} cells in ${e} groups`:`Heatmap of ${this.currentData.length} cells`;this.setLabel(this.options.ariaLabel??t)}recomputeLayout(){let e={x:0,y:0,width:this.width,height:this.height},t=this.options.cellPadding??2;if(this.lastLayoutWidth=this.width,this.lastLayoutHeight=this.height,this.cachedGroups=[],this.options.grouped){let{groups:r,cells:i}=(0,n.layoutGroupedTreemap)(this.currentData.map(e=>({id:e.id,weight:e.weight??(Math.abs(e.value)||1),group:e.group,value:e.value})),e,t,n.GROUP_HEADER);this.cachedRects=i,this.cachedGroups=r}else if(this.options.weighted){let r=this.currentData.map(e=>({id:e.id,weight:e.weight??(Math.abs(e.value)||1)}));this.cachedRects=(0,n.layoutSquarifiedTreemap)(r,e,t)}else this.cachedRects=(0,n.layoutUniformGrid)(this.currentData.map(e=>({id:e.id})),e,t)}onCanvasClick(e,t){if(this.options.onCellClick)for(let n of this.cachedRects){let r=n.rect;if(e>=r.x&&e<=r.x+r.width&&t>=r.y&&t<=r.y+r.height){let e=this.currentData.find(e=>e.id===n.id);e&&this.options.onCellClick(e);return}}}renderChart(e,t,r,i){(t!==this.lastLayoutWidth||r!==this.lastLayoutHeight)&&this.recomputeLayout();let a=this.crosshair?.getPosition()??null;(0,n.renderHeatmap)(e,t,r,this.currentData,this.cachedRects,this.options,i,a,this.cachedGroups)}update(e){this.currentData=e,this.options={...this.options,data:e},this.applyLabel(),this.recomputeLayout(),this.requestRender()}setOptions(e){this.options={...this.options,...e},e.data&&(this.currentData=e.data),this.applyLabel(),this.recomputeLayout(),this.requestRender()}destroy(){this.crosshair?.destroy(),this.handleClick&&this.canvas.removeEventListener(`click`,this.handleClick),super.destroy()}},C=class extends n.BaseFinanceChart{options;crosshair=null;constructor(e,t){super(e,t.theme),this.options=t,t.crosshair!==!1&&(this.crosshair=new n.FinanceCrosshair(this.canvas,()=>this.requestRender())),this.requestRender()}renderChart(e,t,r,i){let a=this.crosshair?.getPosition()??null;(0,n.renderWaterfall)(e,t,r,this.options,i,a)}update(e){this.options={...this.options,data:e},this.requestRender()}setOptions(e){this.options={...this.options,...e},this.requestRender()}destroy(){this.crosshair?.destroy(),super.destroy()}},w=500;function T(e){let t=1-e;return 1-t*t*t}var E=class extends n.BaseFinanceChart{options;currentValue;targetValue;animationStart=null;animationFrom=0;animationFrameId=null;constructor(e,t){super(e,t.theme),this.options=t,this.currentValue=t.value,this.targetValue=t.value,this.requestRender()}renderChart(e,t,r,i){(0,n.renderGauge)(e,t,r,this.options,i,this.currentValue)}setValue(e){if(this.options.animate===!1){this.cancelAnimation(),this.currentValue=e,this.targetValue=e,this.options={...this.options,value:e},this.requestRender();return}this.targetValue=e,this.animationFrom=this.currentValue,this.animationStart=performance.now(),this.options={...this.options,value:e},this.startAnimationLoop()}setOptions(e){let t={...this.options,...e};if(e.value!==void 0&&e.value!==this.targetValue){this.options=t,this.setValue(e.value);return}this.options=t,this.requestRender()}startAnimationLoop(){if(this.animationFrameId!==null)return;let e=()=>{if(this.animationFrameId=null,this.animationStart===null)return;let t=this.options.animationDuration??w,n=performance.now()-this.animationStart,r=Math.min(1,n/Math.max(1,t)),i=T(r);this.currentValue=this.animationFrom+(this.targetValue-this.animationFrom)*i,this.requestRender(),r<1?this.animationFrameId=requestAnimationFrame(e):(this.currentValue=this.targetValue,this.animationStart=null)};this.animationFrameId=requestAnimationFrame(e)}cancelAnimation(){this.animationFrameId!==null&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null),this.animationStart=null}destroy(){this.cancelAnimation(),super.destroy()}},D=class extends n.BaseFinanceChart{options;layout=null;layoutFor=null;crosshair;onClick=e=>{let t=this.canvas.getBoundingClientRect();this.layout&&this.clickAt(this.layout,e.clientX-t.left,e.clientY-t.top)};onMove=e=>{if(!this.layout||!this.clickable())return;let t=this.canvas.getBoundingClientRect();this.canvas.style.cursor=this.hits(this.layout,e.clientX-t.left,e.clientY-t.top)?`pointer`:``};constructor(e,t){super(e,t.theme),this.options=t,this.crosshair=new n.FinanceCrosshair(this.canvas,()=>this.requestRender()),this.canvas.addEventListener(`click`,this.onClick),this.canvas.addEventListener(`pointermove`,this.onMove),this.applyLabel(),this.requestRender()}renderChart(e,t,r,i){let a=this.options.crosshair===!1?null:this.crosshair.getPosition(),o=this.layoutFor;(!this.layout||!o||o.options!==this.options||o.width!==t||o.height!==r||o.theme!==i)&&(this.layout=this.compute(t,r,i,(0,n.canvasMeasure)(e,i)),this.layoutFor={options:this.options,width:t,height:r,theme:i}),this.draw(e,t,r,i,a,this.layout)}setOptions(e){this.options={...this.options,...e},`theme`in e&&this.setTheme(e.theme??`dark`),this.applyLabel(),this.requestRender()}applyLabel(){this.setLabel(this.options.ariaLabel??this.describe())}destroy(){this.crosshair.destroy(),this.canvas.removeEventListener(`click`,this.onClick),this.canvas.removeEventListener(`pointermove`,this.onMove),super.destroy()}},O=class extends D{compute(e,t,r,i){return(0,n.computeBarLayout)(this.options,e,t,r,i)}draw(e,t,r,i,a,o){(0,n.renderBarChart)(e,t,r,this.options,i,a,o)}describe(){return`Bar chart of ${this.options.series.map(e=>e.name).join(`, `)}, ${this.options.categories.length} categories`}clickable(){return this.options.onBarClick!==void 0}hits(e,t,r){return(0,n.hitBar)(e,t,r)!==null}clickAt(e,t,r){let i=(0,n.hitBar)(e,t,r);i&&this.options.onBarClick?.({category:i.category,series:i.series,value:i.value,index:i.index})}update(e,t){this.setOptions({categories:e,series:t})}},k=class extends D{compute(e,t,r,i){return(0,n.computeDonutLayout)(this.options,e,t,r,i)}draw(e,t,r,i,a,o){(0,n.renderDonut)(e,t,r,this.options,i,a,o)}describe(){let e=this.options.data.filter(e=>Number.isFinite(e.value)&&e.value>0).map(e=>e.label).join(`, `);return`${(this.options.innerRadius??.6)>0?`Donut`:`Pie`} chart of ${e}`}clickable(){return this.options.onSliceClick!==void 0}hits(e,t,r){return(0,n.hitSlice)(e,t,r)!==null}clickAt(e,t,r){let i=(0,n.hitSlice)(e,t,r);i&&this.options.onSliceClick?.(i.slice)}update(e){this.setOptions({data:e})}},A=class extends D{compute(e,t,r,i){return(0,n.computeScatterLayout)(this.options,e,t,r,i)}draw(e,t,r,i,a,o){(0,n.renderScatter)(e,t,r,this.options,i,a,o)}describe(){let e=this.options.series.reduce((e,t)=>e+t.points.length,0);return`Scatter chart${this.options.xLabel&&this.options.yLabel?` of ${this.options.yLabel} against ${this.options.xLabel}`:``}, ${e} points`}clickable(){return this.options.onPointClick!==void 0}hits(e,t,r){return(0,n.nearestPoint)(e,t,r)!==null}clickAt(e,t,r){let i=(0,n.nearestPoint)(e,t,r);i&&this.options.onPointClick?.(i.point,i.series)}update(e){this.setOptions({series:e})}},j=class extends D{compute(e,t,r,i){return(0,n.computeHistogramLayout)(this.options,e,t,r,i)}draw(e,t,r,i,a,o){(0,n.renderHistogram)(e,t,r,this.options,i,a,o)}describe(){return`Histogram of ${this.options.values.length} values`}clickable(){return!1}hits(){return!1}clickAt(){}update(e){this.setOptions({values:e})}},M=class extends D{compute(e,t,r,i){return(0,n.computeCalendarLayout)(this.options,e,t,r,i)}draw(e,t,r,i,a,o){(0,n.renderCalendar)(e,t,r,this.options,i,a,o)}describe(){let e=this.options.data.map(e=>e.date).filter(e=>/^\d{4}-\d{2}-\d{2}$/.test(e)).sort(),t=this.options.from??e[0],n=this.options.to??e[e.length-1];return t&&n?`Calendar of daily values from ${t} to ${n}`:`Calendar of daily values`}clickable(){return this.options.onDayClick!==void 0}hits(e,t,r){return(0,n.hitDay)(e,t,r)?.day!==void 0}clickAt(e,t,r){let i=(0,n.hitDay)(e,t,r)?.day;i&&this.options.onDayClick?.(i)}update(e){this.setOptions({data:e})}},N=12,P=class extends D{compute(e,t,r,i){return(0,n.computeMatrixLayout)(this.options,e,t,r,i)}draw(e,t,r,i,a,o){(0,n.renderMatrix)(e,t,r,this.options,i,a,o)}describe(){let{rows:e,columns:t}=this.options;return t?e.length+t.length<=N?`Matrix of ${e.join(`, `)} by ${t.join(`, `)}`:`Matrix of ${e.length} rows by ${t.length} columns`:e.length<=N?`Matrix of ${e.join(`, `)}`:`Matrix of ${e.length} rows`}clickable(){return this.options.onCellClick!==void 0}hits(e,t,r){return(0,n.hitMatrixCell)(e,t,r)!==null}clickAt(e,t,r){let i=(0,n.hitMatrixCell)(e,t,r);i&&this.options.onCellClick?.(i.cell)}update(e){this.setOptions({values:e})}},F=class extends D{compute(e,t,r,i){return(0,n.computeCounterClockLayout)(this.options,e,t,r,i)}draw(e,t,r,i,a,o){(0,n.renderCounterClock)(e,t,r,this.options,i,a,o)}describe(){return`Counter-clock chart of price against volume, ${this.options.period??25}-bar averages`}clickable(){return this.options.onPointClick!==void 0}hits(e,t,r){return(0,n.nearestCounterClockPoint)(e,t,r)!==null}clickAt(e,t,r){let i=(0,n.nearestCounterClockPoint)(e,t,r);i&&this.options.onPointClick?.(i.point)}getPhase(){return(0,n.counterClockPhase)((0,n.counterClockPoints)(this.options.data,this.options.period??25,(0,n.shownCount)(this.options)))}update(e){this.setOptions({data:e})}},I=[`Jan`,`Feb`,`Mar`,`Apr`,`May`,`Jun`,`Jul`,`Aug`,`Sep`,`Oct`,`Nov`,`Dec`];function L(e){return e.map(e=>({time:e.time,value:e.equity}))}function R(e){let t=-1/0;return e.map(e=>{e.equity>t&&(t=e.equity);let n=t>0?(e.equity/t-1)*100:0;return{time:e.time,value:n}})}function z(e){if(e.length===0)return[];let n=[];for(let r of e){let e=(0,t.timeframeBucketStart)(r.time,`1M`),i=n[n.length-1];i&&i.key===e?i.close=r.equity:n.push({key:e,close:r.equity})}let r=e[0].equity,i=[];for(let e of n){let t=r===0?1:r,n=(e.close/t-1)*100;r=e.close;let a=new Date(e.key),o=a.getUTCFullYear(),s=a.getUTCMonth();i.push({id:`${o}-${String(s+1).padStart(2,`0`)}`,label:I[s],group:String(o),value:n})}return i}var B=100;function V(e){return`${e>0?`+`:``}${e.toFixed(2)}%`}function H(e){return e>0?`positive`:e<0?`negative`:`neutral`}function U(e){return[{label:`Total Return`,value:V(e.totalReturnPct*B),tone:H(e.totalReturnPct)},{label:`CAGR`,value:V(e.cagr*B),tone:H(e.cagr)},{label:`Sharpe`,value:e.sharpe.toFixed(2),tone:H(e.sharpe)},{label:`Sortino`,value:e.sortino.toFixed(2),tone:H(e.sortino)},{label:`Max Drawdown`,value:V(-Math.abs(e.maxDrawdownPct)*B),tone:`negative`},{label:`Win Rate`,value:`${(e.winRate*B).toFixed(1)}%`,tone:`neutral`},{label:`Profit Factor`,value:Number.isFinite(e.profitFactor)?e.profitFactor.toFixed(2):`∞`,tone:H(e.profitFactor-1)},{label:`Trades`,value:String(e.trades),tone:`neutral`}]}function W(e){return!e||e===`dark`?t.DARK_THEME:e===`light`?t.LIGHT_THEME:e}var G=class{options;theme;root;equityChart=null;drawdownChart=null;heatmap=null;constructor(e,t){this.options=t,this.theme=W(t.theme),this.root=document.createElement(`div`),this.build(),e.appendChild(this.root)}build(){let e=this.theme,{result:t,title:n,subtitle:r}=this.options,i=this.panelBackground(),a=e.grid;if(this.root.style.cssText=[`display:flex`,`flex-direction:column`,`gap:14px`,`width:100%`,`box-sizing:border-box`,`padding:16px`,`background:${e.background}`,`color:${e.text}`,`font-family:${e.font.family}`].join(`;`),n||r){let t=document.createElement(`div`);if(n){let r=document.createElement(`div`);r.textContent=n,r.style.cssText=`font-size:${e.font.sizeLarge}px;font-weight:600;letter-spacing:-0.01em;`,t.appendChild(r)}if(r){let n=document.createElement(`div`);n.textContent=r,n.style.cssText=`font-size:${e.font.sizeSmall}px;color:${e.textSecondary};margin-top:2px;`,t.appendChild(n)}this.root.appendChild(t)}this.root.appendChild(this.buildStatsStrip(U(t.metrics),i,a));let o=document.createElement(`div`);o.style.cssText=[`display:grid`,`grid-template-columns:repeat(auto-fit, minmax(280px, 1fr))`,`grid-auto-rows:220px`,`gap:14px`].join(`;`),this.root.appendChild(o);let s=this.buildPanel(`Equity Curve`,i,a);s.wrap.style.gridColumn=`1 / -1`,o.appendChild(s.wrap),this.equityChart=new x(s.body,{data:L(t.equityCurve),theme:e,lineColor:e.candleUp,fillArea:!0,crosshair:!0});let c=this.buildPanel(`Drawdown`,i,a);o.appendChild(c.wrap),this.drawdownChart=new x(c.body,{data:R(t.equityCurve),theme:e,lineColor:e.candleDown,fillArea:!0,crosshair:!0,valueFormat:e=>`${e.toFixed(1)}%`});let l=z(t.equityCurve),u=this.buildPanel(`Monthly Returns`,i,a);o.appendChild(u.wrap),this.heatmap=new S(u.body,{data:l,theme:e,showValues:!0,valueFormat:e=>`${e>=0?`+`:``}${e.toFixed(1)}`,colorScale:{negative:e.candleDown,zero:i,positive:e.candleUp}})}buildStatsStrip(e,t,n){let r=document.createElement(`div`);r.style.cssText=[`display:grid`,`grid-template-columns:repeat(auto-fit, minmax(120px, 1fr))`,`gap:10px`].join(`;`);let i=this.theme;for(let a of e){let e=document.createElement(`div`);e.style.cssText=[`background:${t}`,`border:1px solid ${n}`,`border-radius:10px`,`padding:10px 12px`,`display:flex`,`flex-direction:column`,`gap:4px`].join(`;`);let o=document.createElement(`div`);o.textContent=a.label,o.style.cssText=`font-size:${i.font.sizeSmall}px;color:${i.textSecondary};text-transform:uppercase;letter-spacing:0.04em;`;let s=document.createElement(`div`);s.textContent=a.value;let c=a.tone===`positive`?i.candleUp:a.tone===`negative`?i.candleDown:i.text;s.style.cssText=`font-size:${i.font.sizeLarge}px;font-weight:600;color:${c};font-variant-numeric:tabular-nums;`,e.appendChild(o),e.appendChild(s),r.appendChild(e)}return r}buildPanel(e,t,n){let r=this.theme,i=document.createElement(`div`);i.style.cssText=[`background:${t}`,`border:1px solid ${n}`,`border-radius:10px`,`overflow:hidden`,`display:flex`,`flex-direction:column`].join(`;`);let a=document.createElement(`div`);a.textContent=e,a.style.cssText=[`font-size:${r.font.sizeSmall}px`,`font-weight:600`,`color:${r.textSecondary}`,`padding:8px 12px`,`border-bottom:1px solid ${n}`,`text-transform:uppercase`,`letter-spacing:0.04em`].join(`;`);let o=document.createElement(`div`);return o.style.cssText=`flex:1;min-height:0;position:relative;`,i.appendChild(a),i.appendChild(o),{wrap:i,body:o}}panelBackground(){return this.theme.name===`light`?`rgba(0,0,0,0.02)`:`rgba(255,255,255,0.03)`}update(e){this.options={...this.options,result:e},this.destroyCharts(),this.root.replaceChildren(),this.build()}setTheme(e){this.theme=W(e),this.options={...this.options,theme:e},this.destroyCharts(),this.root.replaceChildren(),this.build()}destroyCharts(){this.equityChart?.destroy(),this.drawdownChart?.destroy(),this.heatmap?.destroy(),this.equityChart=null,this.drawdownChart=null,this.heatmap=null}destroy(){this.destroyCharts(),this.root.remove()}};Object.defineProperty(exports,`AlertManager`,{enumerable:!0,get:function(){return n.AlertManager}}),Object.defineProperty(exports,`Animator`,{enumerable:!0,get:function(){return n.Animator}}),exports.BarChart=O,Object.defineProperty(exports,`BarCountdown`,{enumerable:!0,get:function(){return n.BarCountdown}}),Object.defineProperty(exports,`BinanceAdapter`,{enumerable:!0,get:function(){return n.BinanceAdapter}}),Object.defineProperty(exports,`BybitAdapter`,{enumerable:!0,get:function(){return n.BybitAdapter}}),Object.defineProperty(exports,`CANDLE_PATTERNS`,{enumerable:!0,get:function(){return n.CANDLE_PATTERNS}}),Object.defineProperty(exports,`CHART_STYLE_KEYS`,{enumerable:!0,get:function(){return t.CHART_STYLE_KEYS}}),exports.CORRECTABLE_BARS=a,exports.CalendarChart=M,exports.Chart=e.c,exports.ChartGrid=v,Object.defineProperty(exports,`ChartLegend`,{enumerable:!0,get:function(){return n.ChartLegend}}),Object.defineProperty(exports,`ChartStateManager`,{enumerable:!0,get:function(){return n.ChartStateManager}}),Object.defineProperty(exports,`CoinbaseAdapter`,{enumerable:!0,get:function(){return n.CoinbaseAdapter}}),Object.defineProperty(exports,`CompareRenderer`,{enumerable:!0,get:function(){return n.CompareRenderer}}),exports.CounterClockChart=F,Object.defineProperty(exports,`CrosshairTooltip`,{enumerable:!0,get:function(){return n.CrosshairTooltip}}),Object.defineProperty(exports,`CurrentPriceLine`,{enumerable:!0,get:function(){return n.CurrentPriceLine}}),Object.defineProperty(exports,`DARK_PRICE_LIMITS`,{enumerable:!0,get:function(){return t.DARK_PRICE_LIMITS}}),Object.defineProperty(exports,`DARK_TERMINAL`,{enumerable:!0,get:function(){return t.DARK_TERMINAL}}),Object.defineProperty(exports,`DARK_THEME`,{enumerable:!0,get:function(){return t.DARK_THEME}}),Object.defineProperty(exports,`DEFAULT_DRAWING_STYLE`,{enumerable:!0,get:function(){return t.DEFAULT_DRAWING_STYLE}}),Object.defineProperty(exports,`DEFAULT_FONT_FAMILY`,{enumerable:!0,get:function(){return t.DEFAULT_FONT_FAMILY}}),exports.DEFAULT_HISTORY_PAGE_SIZE=e.C,Object.defineProperty(exports,`DEFAULT_LEGEND_CONFIG`,{enumerable:!0,get:function(){return n.DEFAULT_LEGEND_CONFIG}}),Object.defineProperty(exports,`DEFAULT_MAX_WEBGL_CHARTS`,{enumerable:!0,get:function(){return n.DEFAULT_MAX_WEBGL_CHARTS}}),Object.defineProperty(exports,`DEFAULT_RECONNECT`,{enumerable:!0,get:function(){return t.DEFAULT_RECONNECT}}),Object.defineProperty(exports,`DEFAULT_SESSION_HOURS`,{enumerable:!0,get:function(){return n.DEFAULT_SESSION_HOURS}}),Object.defineProperty(exports,`DEFAULT_SIGNAL_STYLE`,{enumerable:!0,get:function(){return t.DEFAULT_SIGNAL_STYLE}}),Object.defineProperty(exports,`DEFAULT_STREAM_CONFIG`,{enumerable:!0,get:function(){return t.DEFAULT_STREAM_CONFIG}}),Object.defineProperty(exports,`DEFAULT_TIMEFRAME_FAVORITES`,{enumerable:!0,get:function(){return t.DEFAULT_TIMEFRAME_FAVORITES}}),Object.defineProperty(exports,`DEFAULT_TRADE_ZONE_STYLE`,{enumerable:!0,get:function(){return t.DEFAULT_TRADE_ZONE_STYLE}}),Object.defineProperty(exports,`DEFAULT_TRADING_CONFIG`,{enumerable:!0,get:function(){return t.DEFAULT_TRADING_CONFIG}}),Object.defineProperty(exports,`DataExporter`,{enumerable:!0,get:function(){return n.DataExporter}}),exports.DataManager=e.T,exports.DepthChart=b,exports.DonutChart=k,exports.DragDropImporter=e.o,Object.defineProperty(exports,`DrawingBase`,{enumerable:!0,get:function(){return n.DrawingBase}}),exports.EXCHANGE_TIMEZONE=e.l,exports.EXCHANGE_TIME_ZONE=e.u,Object.defineProperty(exports,`Easing`,{enumerable:!0,get:function(){return n.Easing}}),exports.EquityCurveChart=x,exports.GaugeChart=E,exports.HISTORY_RETRY_MS=e.w,Object.defineProperty(exports,`HNX_SESSIONS`,{enumerable:!0,get:function(){return t.HNX_SESSIONS}}),Object.defineProperty(exports,`HOSE_SESSIONS`,{enumerable:!0,get:function(){return t.HOSE_SESSIONS}}),exports.HeatmapChart=S,exports.HistogramChart=j,Object.defineProperty(exports,`INDICATOR_CATEGORIES`,{enumerable:!0,get:function(){return n.INDICATOR_CATEGORIES}}),Object.defineProperty(exports,`IndicatorBase`,{enumerable:!0,get:function(){return n.IndicatorBase}}),Object.defineProperty(exports,`IndicatorValueMap`,{enumerable:!0,get:function(){return n.IndicatorValueMap}}),Object.defineProperty(exports,`KEPT_BUCKETS`,{enumerable:!0,get:function(){return n.KEPT_BUCKETS}}),Object.defineProperty(exports,`KRX_SESSIONS`,{enumerable:!0,get:function(){return t.KRX_SESSIONS}}),Object.defineProperty(exports,`KR_COLORS`,{enumerable:!0,get:function(){return t.KR_COLORS}}),Object.defineProperty(exports,`KeyboardHandler`,{enumerable:!0,get:function(){return n.KeyboardHandler}}),Object.defineProperty(exports,`KrakenAdapter`,{enumerable:!0,get:function(){return n.KrakenAdapter}}),Object.defineProperty(exports,`LIGHT_PRICE_LIMITS`,{enumerable:!0,get:function(){return t.LIGHT_PRICE_LIMITS}}),Object.defineProperty(exports,`LIGHT_THEME`,{enumerable:!0,get:function(){return t.LIGHT_THEME}}),exports.LayoutManager=e.x,exports.LayoutSession=e.t,Object.defineProperty(exports,`MARKET_CRYPTO`,{enumerable:!0,get:function(){return t.MARKET_CRYPTO}}),Object.defineProperty(exports,`MARKET_HNX`,{enumerable:!0,get:function(){return t.MARKET_HNX}}),Object.defineProperty(exports,`MARKET_HOSE`,{enumerable:!0,get:function(){return t.MARKET_HOSE}}),Object.defineProperty(exports,`MARKET_HOSE_ETF`,{enumerable:!0,get:function(){return t.MARKET_HOSE_ETF}}),Object.defineProperty(exports,`MARKET_KRX`,{enumerable:!0,get:function(){return t.MARKET_KRX}}),Object.defineProperty(exports,`MARKET_NXT`,{enumerable:!0,get:function(){return t.MARKET_NXT}}),Object.defineProperty(exports,`MARKET_NYSE`,{enumerable:!0,get:function(){return t.MARKET_NYSE}}),Object.defineProperty(exports,`MARKET_UPBIT_KRW`,{enumerable:!0,get:function(){return t.MARKET_UPBIT_KRW}}),Object.defineProperty(exports,`MARKET_UPCOM`,{enumerable:!0,get:function(){return t.MARKET_UPCOM}}),Object.defineProperty(exports,`MARKET_VN30F`,{enumerable:!0,get:function(){return t.MARKET_VN30F}}),Object.defineProperty(exports,`MAX_ALERT_BARS`,{enumerable:!0,get:function(){return n.MAX_ALERT_BARS}}),exports.MAX_LAYOUT_NAME=e.n,Object.defineProperty(exports,`MIN_ALERT_BARS`,{enumerable:!0,get:function(){return n.MIN_ALERT_BARS}}),Object.defineProperty(exports,`MS_TIME_THRESHOLD`,{enumerable:!0,get:function(){return t.MS_TIME_THRESHOLD}}),Object.defineProperty(exports,`ManualFeed`,{enumerable:!0,get:function(){return n.ManualFeed}}),exports.MatrixChart=P,Object.defineProperty(exports,`MockAdapter`,{enumerable:!0,get:function(){return n.MockAdapter}}),Object.defineProperty(exports,`NXT_SESSIONS`,{enumerable:!0,get:function(){return t.NXT_SESSIONS}}),exports.PLUGIN_API_VERSION=e.v,Object.defineProperty(exports,`PRICE_SOURCES`,{enumerable:!0,get:function(){return t.PRICE_SOURCES}}),Object.defineProperty(exports,`PaperExecutionAdapter`,{enumerable:!0,get:function(){return n.PaperExecutionAdapter}}),exports.PerformanceDashboard=G,exports.PluginManager=e.p,Object.defineProperty(exports,`PollingAdapter`,{enumerable:!0,get:function(){return n.PollingAdapter}}),Object.defineProperty(exports,`RANGE_PRESETS`,{enumerable:!0,get:function(){return n.RANGE_PRESETS}}),Object.defineProperty(exports,`ReconnectManager`,{enumerable:!0,get:function(){return n.ReconnectManager}}),Object.defineProperty(exports,`ReplayController`,{enumerable:!0,get:function(){return n.ReplayController}}),Object.defineProperty(exports,`ReplayManager`,{enumerable:!0,get:function(){return n.ReplayManager}}),Object.defineProperty(exports,`ResamplingAdapter`,{enumerable:!0,get:function(){return n.ResamplingAdapter}}),Object.defineProperty(exports,`ReshapeMemo`,{enumerable:!0,get:function(){return n.ReshapeMemo}}),Object.defineProperty(exports,`SANS_FONT_FAMILY`,{enumerable:!0,get:function(){return t.SANS_FONT_FAMILY}}),exports.ScatterChart=A,Object.defineProperty(exports,`Screenshot`,{enumerable:!0,get:function(){return n.Screenshot}}),Object.defineProperty(exports,`SessionBreaks`,{enumerable:!0,get:function(){return n.SessionBreaks}}),Object.defineProperty(exports,`SessionShading`,{enumerable:!0,get:function(){return n.SessionShading}}),Object.defineProperty(exports,`SignalMarkerManager`,{enumerable:!0,get:function(){return n.SignalMarkerManager}}),exports.SparklineChart=y,Object.defineProperty(exports,`StreamManager`,{enumerable:!0,get:function(){return n.StreamManager}}),Object.defineProperty(exports,`TC_PALETTE`,{enumerable:!0,get:function(){return t.TC_PALETTE}}),Object.defineProperty(exports,`TC_SERIES_COLORS`,{enumerable:!0,get:function(){return t.TC_SERIES_COLORS}}),Object.defineProperty(exports,`TIMEFRAMES_CRYPTO`,{enumerable:!0,get:function(){return t.TIMEFRAMES_CRYPTO}}),Object.defineProperty(exports,`TIMEFRAMES_FOREX`,{enumerable:!0,get:function(){return t.TIMEFRAMES_FOREX}}),Object.defineProperty(exports,`TIMEFRAMES_STOCK`,{enumerable:!0,get:function(){return t.TIMEFRAMES_STOCK}}),exports.ThemeManager=e.S,Object.defineProperty(exports,`TickAggregator`,{enumerable:!0,get:function(){return n.TickAggregator}}),Object.defineProperty(exports,`TickBarAdapter`,{enumerable:!0,get:function(){return n.TickBarAdapter}}),Object.defineProperty(exports,`TickBarBuilder`,{enumerable:!0,get:function(){return n.TickBarBuilder}}),Object.defineProperty(exports,`TradeZoneManager`,{enumerable:!0,get:function(){return n.TradeZoneManager}}),Object.defineProperty(exports,`UPCOM_SESSIONS`,{enumerable:!0,get:function(){return t.UPCOM_SESSIONS}}),Object.defineProperty(exports,`UndoRedoManager`,{enumerable:!0,get:function(){return n.UndoRedoManager}}),Object.defineProperty(exports,`UpbitAdapter`,{enumerable:!0,get:function(){return n.UpbitAdapter}}),Object.defineProperty(exports,`VN30F_SESSIONS`,{enumerable:!0,get:function(){return t.VN30F_SESSIONS}}),Object.defineProperty(exports,`VN_COLORS`,{enumerable:!0,get:function(){return t.VN_COLORS}}),Object.defineProperty(exports,`VOLUME_ALPHA`,{enumerable:!0,get:function(){return t.VOLUME_ALPHA}}),Object.defineProperty(exports,`VolumeRenderer`,{enumerable:!0,get:function(){return n.VolumeRenderer}}),exports.WaterfallChart=C,Object.defineProperty(exports,`Watermark`,{enumerable:!0,get:function(){return n.Watermark}}),Object.defineProperty(exports,`WebSocketAdapter`,{enumerable:!0,get:function(){return n.WebSocketAdapter}}),Object.defineProperty(exports,`adapterFromFeed`,{enumerable:!0,get:function(){return n.adapterFromFeed}}),Object.defineProperty(exports,`axisTimes`,{enumerable:!0,get:function(){return n.axisTimes}}),Object.defineProperty(exports,`barIndexToX`,{enumerable:!0,get:function(){return n.barIndexToX}}),Object.defineProperty(exports,`barTimeUnit`,{enumerable:!0,get:function(){return t.barTimeUnit}}),Object.defineProperty(exports,`barsAreDaily`,{enumerable:!0,get:function(){return t.barsAreDaily}}),exports.cleanLayoutName=e.r,exports.clearGlobalPlugins=e.m,exports.computeDrawdownCurve=R,exports.computeMonthlyReturns=z,Object.defineProperty(exports,`computePriceLimits`,{enumerable:!0,get:function(){return t.computePriceLimits}}),Object.defineProperty(exports,`contrastRatio`,{enumerable:!0,get:function(){return t.contrastRatio}}),Object.defineProperty(exports,`correlationMatrix`,{enumerable:!0,get:function(){return n.correlationMatrix}}),Object.defineProperty(exports,`counterClockPhase`,{enumerable:!0,get:function(){return n.counterClockPhase}}),Object.defineProperty(exports,`counterClockPoints`,{enumerable:!0,get:function(){return n.counterClockPoints}}),Object.defineProperty(exports,`createMarketTheme`,{enumerable:!0,get:function(){return t.createMarketTheme}}),Object.defineProperty(exports,`createVNTheme`,{enumerable:!0,get:function(){return t.createVNTheme}}),Object.defineProperty(exports,`describeInputs`,{enumerable:!0,get:function(){return n.describeInputs}}),Object.defineProperty(exports,`detectCandlePatterns`,{enumerable:!0,get:function(){return n.detectCandlePatterns}}),exports.feedBars=h,Object.defineProperty(exports,`feedFromAdapter`,{enumerable:!0,get:function(){return n.feedFromAdapter}}),Object.defineProperty(exports,`formatFraction`,{enumerable:!0,get:function(){return t.formatFraction}}),Object.defineProperty(exports,`formatNumber`,{enumerable:!0,get:function(){return t.formatNumber}}),Object.defineProperty(exports,`formatTooltipTime`,{enumerable:!0,get:function(){return n.formatTooltipTime}}),Object.defineProperty(exports,`formatVND`,{enumerable:!0,get:function(){return t.formatVND}}),Object.defineProperty(exports,`formatVolumeLoc`,{enumerable:!0,get:function(){return t.formatVolumeLoc}}),Object.defineProperty(exports,`fractionTick`,{enumerable:!0,get:function(){return t.fractionTick}}),Object.defineProperty(exports,`getCurrentSession`,{enumerable:!0,get:function(){return t.getCurrentSession}}),exports.getGlobalPlugins=e.h,Object.defineProperty(exports,`getLocale`,{enumerable:!0,get:function(){return t.getLocale}}),Object.defineProperty(exports,`histogramBins`,{enumerable:!0,get:function(){return n.histogramBins}}),Object.defineProperty(exports,`indicatorCategory`,{enumerable:!0,get:function(){return n.indicatorCategory}}),Object.defineProperty(exports,`indicatorSource`,{enumerable:!0,get:function(){return t.indicatorSource}}),Object.defineProperty(exports,`inkOn`,{enumerable:!0,get:function(){return t.inkOn}}),Object.defineProperty(exports,`isDataFeed`,{enumerable:!0,get:function(){return n.isDataFeed}}),Object.defineProperty(exports,`isPriceLevelAlert`,{enumerable:!0,get:function(){return n.isPriceLevelAlert}}),Object.defineProperty(exports,`isPriceSource`,{enumerable:!0,get:function(){return t.isPriceSource}}),Object.defineProperty(exports,`isTimeFrame`,{enumerable:!0,get:function(){return t.isTimeFrame}}),Object.defineProperty(exports,`isValidTimeZone`,{enumerable:!0,get:function(){return t.isValidTimeZone}}),exports.localStorageLayouts=e.i,Object.defineProperty(exports,`lttbDownsample`,{enumerable:!0,get:function(){return n.lttbDownsample}}),Object.defineProperty(exports,`lttbVisibleIndices`,{enumerable:!0,get:function(){return n.lttbVisibleIndices}}),Object.defineProperty(exports,`marketStatus`,{enumerable:!0,get:function(){return t.marketStatus}}),exports.memoryLayouts=e.a,Object.defineProperty(exports,`niceScale`,{enumerable:!0,get:function(){return n.niceScale}}),Object.defineProperty(exports,`normalizeBar`,{enumerable:!0,get:function(){return t.normalizeBar}}),Object.defineProperty(exports,`normalizeBarTime`,{enumerable:!0,get:function(){return t.normalizeBarTime}}),Object.defineProperty(exports,`offsetAt`,{enumerable:!0,get:function(){return t.offsetAt}}),exports.overlayScale=g,exports.overlaysForLayer=e.y,Object.defineProperty(exports,`parseIndicatorSource`,{enumerable:!0,get:function(){return t.parseIndicatorSource}}),exports.parseOHLCV=e.s,Object.defineProperty(exports,`parseTimeframe`,{enumerable:!0,get:function(){return t.parseTimeframe}}),Object.defineProperty(exports,`pickBaseTimeframe`,{enumerable:!0,get:function(){return t.pickBaseTimeframe}}),exports.pluginKey=e.b,Object.defineProperty(exports,`priceFormatterFor`,{enumerable:!0,get:function(){return t.priceFormatterFor}}),Object.defineProperty(exports,`priceStepAt`,{enumerable:!0,get:function(){return t.priceStepAt}}),Object.defineProperty(exports,`priceToY`,{enumerable:!0,get:function(){return n.priceToY}}),Object.defineProperty(exports,`priceToYMapper`,{enumerable:!0,get:function(){return n.priceToYMapper}}),Object.defineProperty(exports,`rangePresetStart`,{enumerable:!0,get:function(){return n.rangePresetStart}}),Object.defineProperty(exports,`rankSymbols`,{enumerable:!0,get:function(){return t.rankSymbols}}),Object.defineProperty(exports,`readNews`,{enumerable:!0,get:function(){return t.readNews}}),Object.defineProperty(exports,`readQuote`,{enumerable:!0,get:function(){return t.readQuote}}),Object.defineProperty(exports,`readableOn`,{enumerable:!0,get:function(){return t.readableOn}}),Object.defineProperty(exports,`registerLocale`,{enumerable:!0,get:function(){return t.registerLocale}}),exports.registerPlugin=e.g,Object.defineProperty(exports,`resampleBars`,{enumerable:!0,get:function(){return t.resampleBars}}),Object.defineProperty(exports,`roundToPriceStep`,{enumerable:!0,get:function(){return t.roundToPriceStep}}),Object.defineProperty(exports,`scaleMarketPrices`,{enumerable:!0,get:function(){return t.scaleMarketPrices}}),exports.selectKeyStats=U,Object.defineProperty(exports,`servesTimeframe`,{enumerable:!0,get:function(){return n.servesTimeframe}}),Object.defineProperty(exports,`setLocale`,{enumerable:!0,get:function(){return t.setLocale}}),Object.defineProperty(exports,`setMaxWebGLCharts`,{enumerable:!0,get:function(){return n.setMaxWebGLCharts}}),Object.defineProperty(exports,`sourcePrice`,{enumerable:!0,get:function(){return t.sourcePrice}}),Object.defineProperty(exports,`stepDecimals`,{enumerable:!0,get:function(){return t.stepDecimals}}),Object.defineProperty(exports,`symbolTimeZone`,{enumerable:!0,get:function(){return t.symbolTimeZone}}),exports.syncIndicators=i,Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return t.t}}),Object.defineProperty(exports,`tickBarCount`,{enumerable:!0,get:function(){return t.tickBarCount}}),Object.defineProperty(exports,`timeToX`,{enumerable:!0,get:function(){return n.timeToX}}),Object.defineProperty(exports,`timeframeBucketStart`,{enumerable:!0,get:function(){return t.timeframeBucketStart}}),Object.defineProperty(exports,`timeframeToMs`,{enumerable:!0,get:function(){return t.timeframeToMs}}),Object.defineProperty(exports,`timestampToBarIndex`,{enumerable:!0,get:function(){return n.timestampToBarIndex}}),exports.toEquityPoints=L,Object.defineProperty(exports,`toHeikinAshi`,{enumerable:!0,get:function(){return n.toHeikinAshi}}),Object.defineProperty(exports,`toKagi`,{enumerable:!0,get:function(){return n.toKagi}}),Object.defineProperty(exports,`toLineBreak`,{enumerable:!0,get:function(){return n.toLineBreak}}),Object.defineProperty(exports,`toPointAndFigure`,{enumerable:!0,get:function(){return n.toPointAndFigure}}),Object.defineProperty(exports,`toRangeBars`,{enumerable:!0,get:function(){return n.toRangeBars}}),Object.defineProperty(exports,`toRenko`,{enumerable:!0,get:function(){return n.toRenko}}),exports.unregisterPlugin=e._,Object.defineProperty(exports,`usesKoreanUnits`,{enumerable:!0,get:function(){return t.usesKoreanUnits}}),Object.defineProperty(exports,`vn30fContracts`,{enumerable:!0,get:function(){return t.vn30fContracts}}),Object.defineProperty(exports,`vn30fLastTradingDay`,{enumerable:!0,get:function(){return t.vn30fLastTradingDay}}),Object.defineProperty(exports,`volumeColor`,{enumerable:!0,get:function(){return t.volumeColor}}),Object.defineProperty(exports,`wallToUtc`,{enumerable:!0,get:function(){return t.wallToUtc}}),Object.defineProperty(exports,`withResampling`,{enumerable:!0,get:function(){return n.withResampling}}),Object.defineProperty(exports,`withTickBars`,{enumerable:!0,get:function(){return n.withTickBars}}),Object.defineProperty(exports,`xToBarIndex`,{enumerable:!0,get:function(){return n.xToBarIndex}}),Object.defineProperty(exports,`xToTime`,{enumerable:!0,get:function(){return n.xToTime}}),Object.defineProperty(exports,`yToPrice`,{enumerable:!0,get:function(){return n.yToPrice}}),Object.defineProperty(exports,`zoneOffsetMinutes`,{enumerable:!0,get:function(){return t.zoneOffsetMinutes}});
2
2
  //# sourceMappingURL=index.cjs.map
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { C as e, D as t, E as n, S as r, T as i, _ as a, a as o, b as s, c, g as l, h as u, i as ee, l as te, m as ne, n as re, o as ie, p as ae, r as oe, s as se, t as ce, u as le, v as ue, w as de, x as fe, y as pe } from "./LayoutSession-DjHF7tmL.js";
1
+ import { C as e, D as t, E as n, S as r, T as i, _ as a, a as o, b as s, c, g as l, h as u, i as ee, l as te, m as ne, n as re, o as ie, p as ae, r as oe, s as se, t as ce, u as le, v as ue, w as de, x as fe, y as pe } from "./LayoutSession-BrazGVET.js";
2
2
  import { CHART_STYLE_KEYS as me, DARK_PRICE_LIMITS as he, DARK_TERMINAL as ge, DARK_THEME as _e, DARK_THEME as ve, DEFAULT_DRAWING_STYLE as ye, DEFAULT_FONT_FAMILY as be, DEFAULT_RECONNECT as xe, DEFAULT_SIGNAL_STYLE as Se, DEFAULT_STREAM_CONFIG as Ce, DEFAULT_TIMEFRAME_FAVORITES as we, DEFAULT_TRADE_ZONE_STYLE as Te, DEFAULT_TRADING_CONFIG as Ee, HNX_SESSIONS as d, HOSE_SESSIONS as f, KRX_SESSIONS as p, KR_COLORS as m, LIGHT_PRICE_LIMITS as h, LIGHT_THEME as g, LIGHT_THEME as _, MARKET_CRYPTO as v, MARKET_HNX as y, MARKET_HOSE as b, MARKET_HOSE_ETF as x, MARKET_KRX as S, MARKET_NXT as C, MARKET_NYSE as w, MARKET_UPBIT_KRW as T, MARKET_UPCOM as E, MARKET_VN30F as D, MS_TIME_THRESHOLD as De, NXT_SESSIONS as Oe, PRICE_SOURCES as ke, SANS_FONT_FAMILY as Ae, TC_PALETTE as je, TC_SERIES_COLORS as Me, TIMEFRAMES_CRYPTO as Ne, TIMEFRAMES_FOREX as Pe, TIMEFRAMES_STOCK as Fe, UPCOM_SESSIONS as Ie, VN30F_SESSIONS as Le, VN_COLORS as Re, VOLUME_ALPHA as ze, barTimeUnit as Be, barsAreDaily as Ve, computePriceLimits as He, contrastRatio as Ue, createMarketTheme as We, createVNTheme as Ge, formatFraction as Ke, formatNumber as qe, formatVND as Je, formatVolumeLoc as Ye, fractionTick as Xe, getCurrentSession as Ze, getLocale as Qe, indicatorSource as $e, inkOn as et, isPriceSource as tt, isTimeFrame as nt, isValidTimeZone as rt, marketStatus as it, normalizeBar as at, normalizeBarTime as ot, offsetAt as st, parseIndicatorSource as ct, parseTimeframe as lt, pickBaseTimeframe as ut, priceFormatterFor as dt, priceStepAt as ft, rankSymbols as pt, readNews as mt, readQuote as ht, readableOn as gt, registerLocale as _t, resampleBars as vt, roundToPriceStep as yt, scaleMarketPrices as bt, setLocale as xt, sourcePrice as St, stepDecimals as Ct, symbolTimeZone as wt, t as Tt, tickBarCount as Et, timeframeBucketStart as Dt, timeframeBucketStart as Ot, timeframeToMs as kt, usesKoreanUnits as At, vn30fContracts as jt, vn30fLastTradingDay as Mt, volumeColor as Nt, wallToUtc as Pt, zoneOffsetMinutes as Ft } from "@tradecanvas/commons";
3
3
  import { AlertManager as It, Animator as Lt, BarCountdown as Rt, BaseFinanceChart as O, BinanceAdapter as zt, BybitAdapter as Bt, CANDLE_PATTERNS as Vt, ChartLegend as Ht, ChartStateManager as Ut, CoinbaseAdapter as Wt, CompareRenderer as Gt, CrosshairTooltip as Kt, CurrentPriceLine as qt, DEFAULT_LEGEND_CONFIG as Jt, DEFAULT_MAX_WEBGL_CHARTS as Yt, DEFAULT_SESSION_HOURS as Xt, DataExporter as Zt, DrawingBase as Qt, Easing as $t, FinanceCrosshair as k, GROUP_HEADER as en, INDICATOR_CATEGORIES as tn, IndicatorBase as nn, IndicatorValueMap as rn, KEPT_BUCKETS as an, KeyboardHandler as on, KrakenAdapter as sn, MAX_ALERT_BARS as cn, MIN_ALERT_BARS as ln, ManualFeed as un, MockAdapter as dn, PaperExecutionAdapter as fn, PollingAdapter as pn, RANGE_PRESETS as mn, ReconnectManager as hn, ReplayController as gn, ReplayManager as _n, ResamplingAdapter as vn, ReshapeMemo as yn, Screenshot as bn, SessionBreaks as xn, SessionShading as Sn, SignalMarkerManager as A, StreamManager as Cn, TickAggregator as wn, TickBarAdapter as Tn, TickBarBuilder as En, TradeZoneManager as Dn, UndoRedoManager as On, UpbitAdapter as kn, VolumeRenderer as An, Watermark as jn, WebSocketAdapter as Mn, adapterFromFeed as Nn, axisTimes as Pn, barIndexToTime as Fn, barIndexToX as In, barIndexToX as j, canvasMeasure as Ln, computeBarLayout as Rn, computeCalendarLayout as zn, computeCounterClockLayout as Bn, computeDonutLayout as Vn, computeHistogramLayout as Hn, computeMatrixLayout as Un, computeScatterLayout as Wn, correlationMatrix as Gn, counterClockPhase as Kn, counterClockPhase as qn, counterClockPoints as Jn, counterClockPoints as Yn, describeInputs as Xn, detectCandlePatterns as Zn, feedFromAdapter as Qn, formatTooltipTime as $n, histogramBins as er, hitBar as M, hitDay as N, hitMatrixCell as P, hitSlice as F, indicatorCategory as tr, isDataFeed as nr, isDataFeed as rr, isPriceLevelAlert as ir, layoutGroupedTreemap as ar, layoutSquarifiedTreemap as or, layoutUniformGrid as sr, lttbDownsample as cr, lttbVisibleIndices as lr, nearestCounterClockPoint as I, nearestPoint as L, niceScale as ur, priceToY as dr, priceToYMapper as fr, priceToYMapper as pr, rangePresetStart as mr, renderBarChart as hr, renderCalendar as gr, renderCounterClock as _r, renderDepthChart as vr, renderDonut as yr, renderEquityCurve as br, renderGauge as xr, renderHeatmap as Sr, renderHistogram as Cr, renderMatrix as wr, renderScatter as Tr, renderSparkline as Er, renderWaterfall as Dr, servesTimeframe as Or, setMaxWebGLCharts as kr, shownCount as Ar, timeToX as jr, timestampToBarIndex as Mr, timestampToBarIndex as Nr, toHeikinAshi as Pr, toKagi as Fr, toLineBreak as Ir, toPointAndFigure as Lr, toRangeBars as Rr, toRenko as zr, withResampling as Br, withTickBars as Vr, xToBarIndex as Hr, xToBarIndex as R, xToTime as Ur, yToPrice as Wr, yToPrice as Gr } from "@tradecanvas/core";
4
4
  //#region src/frameworks/syncIndicators.ts
@@ -1,5 +1,5 @@
1
1
  import { t as e } from "./indicatorLabel-Sbegyhp2.js";
2
- import { c as t } from "./i18n-CvnQcfor.js";
2
+ import { c as t } from "./i18n-C5v6Tzp1.js";
3
3
  //#region src/widget/indicatorInputWords.ts
4
4
  function n(e) {
5
5
  return Object.prototype.hasOwnProperty.call(t, e);
@@ -22,4 +22,4 @@ function a(t, n) {
22
22
  //#endregion
23
23
  export { r as n, a as r, i as t };
24
24
 
25
- //# sourceMappingURL=indicatorInputWords-D19kY9NO.js.map
25
+ //# sourceMappingURL=indicatorInputWords-Bd9Pt6qp.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"indicatorInputWords-D19kY9NO.js","names":[],"sources":["../src/widget/indicatorInputWords.ts"],"sourcesContent":["import type { IndicatorDescriptor } from '@tradecanvas/commons';\nimport { indicatorChipLabel } from '../indicatorLabel.js';\nimport { EN_MESSAGES, type MessageKey, type Translator } from './i18n.js';\n\n/**\n * Words for an indicator's inputs in the widget's language: an input named\n * `anchor` is `indicatorInput.anchor`, its choice `'week'` is\n * `indicatorInput.anchor.week`. Only inputs the widget has words for; any\n * other keeps its own label and its values as they are.\n */\n\n/** Whether the widget has a message under `key`, one built from an input's name. */\nfunction isMessageKey(key: string): key is MessageKey {\n return Object.prototype.hasOwnProperty.call(EN_MESSAGES, key);\n}\n\n/** An input's label in the widget's language, or null for one it has no word for. */\nexport function inputLabel(name: string, t: Translator): string | null {\n const key = `indicatorInput.${name}`;\n return isMessageKey(key) ? t(key) : null;\n}\n\n/** A choice of an input in the widget's language, or null for one it has no word for. */\nexport function choiceLabel(name: string, choice: string | number, t: Translator): string | null {\n const key = `indicatorInput.${name}.${choice}`;\n return isMessageKey(key) ? t(key) : null;\n}\n\n/** An indicator on the chart, as the widget names it. */\nexport interface NamedIndicator {\n id: string;\n params: Record<string, unknown>;\n descriptor: Pick<IndicatorDescriptor, 'defaultConfig' | 'shortName' | 'inputs'>;\n}\n\n/**\n * The indicator's name in the legend, the chips and the Objects panel: its\n * chip label ('EMA 21'), then the word for each choice off its default, so\n * two read apart ('VWAP', 'VWAP Week'). The CSV column keeps the chip label.\n */\nexport function widgetIndicatorLabel(ind: NamedIndicator, t: Translator): string {\n const { defaultConfig, shortName, inputs } = ind.descriptor;\n const words = Object.entries(inputs ?? {}).flatMap(([name, spec]) => {\n const value = ind.params[name];\n if (!spec.options || (typeof value !== 'string' && typeof value !== 'number') || value === defaultConfig[name]) return [];\n return choiceLabel(name, value, t) ?? [];\n });\n return [indicatorChipLabel(ind.id, ind.params, defaultConfig, shortName), ...words].join(' ');\n}\n"],"mappings":";;;AAYA,SAAS,EAAa,GAAgC;AACpD,QAAO,OAAO,UAAU,eAAe,KAAK,GAAa,EAAI;;AAI/D,SAAgB,EAAW,GAAc,GAA8B;CACrE,IAAM,IAAM,kBAAkB;AAC9B,QAAO,EAAa,EAAI,GAAG,EAAE,EAAI,GAAG;;AAItC,SAAgB,EAAY,GAAc,GAAyB,GAA8B;CAC/F,IAAM,IAAM,kBAAkB,EAAK,GAAG;AACtC,QAAO,EAAa,EAAI,GAAG,EAAE,EAAI,GAAG;;AAetC,SAAgB,EAAqB,GAAqB,GAAuB;CAC/E,IAAM,EAAE,kBAAe,cAAW,cAAW,EAAI,YAC3C,IAAQ,OAAO,QAAQ,KAAU,EAAE,CAAC,CAAC,SAAS,CAAC,GAAM,OAAU;EACnE,IAAM,IAAQ,EAAI,OAAO;AAEzB,SADI,CAAC,EAAK,WAAY,OAAO,KAAU,YAAY,OAAO,KAAU,YAAa,MAAU,EAAc,KAAc,EAAE,GAClH,EAAY,GAAM,GAAO,EAAE,IAAI,EAAE;GACxC;AACF,QAAO,CAAC,EAAmB,EAAI,IAAI,EAAI,QAAQ,GAAe,EAAU,EAAE,GAAG,EAAM,CAAC,KAAK,IAAI"}
1
+ {"version":3,"file":"indicatorInputWords-Bd9Pt6qp.js","names":[],"sources":["../src/widget/indicatorInputWords.ts"],"sourcesContent":["import type { IndicatorDescriptor } from '@tradecanvas/commons';\nimport { indicatorChipLabel } from '../indicatorLabel.js';\nimport { EN_MESSAGES, type MessageKey, type Translator } from './i18n.js';\n\n/**\n * Words for an indicator's inputs in the widget's language: an input named\n * `anchor` is `indicatorInput.anchor`, its choice `'week'` is\n * `indicatorInput.anchor.week`. Only inputs the widget has words for; any\n * other keeps its own label and its values as they are.\n */\n\n/** Whether the widget has a message under `key`, one built from an input's name. */\nfunction isMessageKey(key: string): key is MessageKey {\n return Object.prototype.hasOwnProperty.call(EN_MESSAGES, key);\n}\n\n/** An input's label in the widget's language, or null for one it has no word for. */\nexport function inputLabel(name: string, t: Translator): string | null {\n const key = `indicatorInput.${name}`;\n return isMessageKey(key) ? t(key) : null;\n}\n\n/** A choice of an input in the widget's language, or null for one it has no word for. */\nexport function choiceLabel(name: string, choice: string | number, t: Translator): string | null {\n const key = `indicatorInput.${name}.${choice}`;\n return isMessageKey(key) ? t(key) : null;\n}\n\n/** An indicator on the chart, as the widget names it. */\nexport interface NamedIndicator {\n id: string;\n params: Record<string, unknown>;\n descriptor: Pick<IndicatorDescriptor, 'defaultConfig' | 'shortName' | 'inputs'>;\n}\n\n/**\n * The indicator's name in the legend, the chips and the Objects panel: its\n * chip label ('EMA 21'), then the word for each choice off its default, so\n * two read apart ('VWAP', 'VWAP Week'). The CSV column keeps the chip label.\n */\nexport function widgetIndicatorLabel(ind: NamedIndicator, t: Translator): string {\n const { defaultConfig, shortName, inputs } = ind.descriptor;\n const words = Object.entries(inputs ?? {}).flatMap(([name, spec]) => {\n const value = ind.params[name];\n if (!spec.options || (typeof value !== 'string' && typeof value !== 'number') || value === defaultConfig[name]) return [];\n return choiceLabel(name, value, t) ?? [];\n });\n return [indicatorChipLabel(ind.id, ind.params, defaultConfig, shortName), ...words].join(' ');\n}\n"],"mappings":";;;AAYA,SAAS,EAAa,GAAgC;AACpD,QAAO,OAAO,UAAU,eAAe,KAAK,GAAa,EAAI;;AAI/D,SAAgB,EAAW,GAAc,GAA8B;CACrE,IAAM,IAAM,kBAAkB;AAC9B,QAAO,EAAa,EAAI,GAAG,EAAE,EAAI,GAAG;;AAItC,SAAgB,EAAY,GAAc,GAAyB,GAA8B;CAC/F,IAAM,IAAM,kBAAkB,EAAK,GAAG;AACtC,QAAO,EAAa,EAAI,GAAG,EAAE,EAAI,GAAG;;AAetC,SAAgB,EAAqB,GAAqB,GAAuB;CAC/E,IAAM,EAAE,kBAAe,cAAW,cAAW,EAAI,YAC3C,IAAQ,OAAO,QAAQ,KAAU,EAAE,CAAC,CAAC,SAAS,CAAC,GAAM,OAAU;EACnE,IAAM,IAAQ,EAAI,OAAO;AAEzB,SADI,CAAC,EAAK,WAAY,OAAO,KAAU,YAAY,OAAO,KAAU,YAAa,MAAU,EAAc,KAAc,EAAE,GAClH,EAAY,GAAM,GAAO,EAAE,IAAI,EAAE;GACxC;AACF,QAAO,CAAC,EAAmB,EAAI,IAAI,EAAI,QAAQ,GAAe,EAAU,EAAE,GAAG,EAAM,CAAC,KAAK,IAAI"}
@@ -1,2 +1,2 @@
1
- const e=require(`./indicatorLabel-BNZvaOcl.cjs`),t=require(`./i18n-DFR1Oukq.cjs`);function n(e){return Object.prototype.hasOwnProperty.call(t.c,e)}function r(e,t){let r=`indicatorInput.${e}`;return n(r)?t(r):null}function i(e,t,r){let i=`indicatorInput.${e}.${t}`;return n(i)?r(i):null}function a(t,n){let{defaultConfig:r,shortName:a,inputs:o}=t.descriptor,s=Object.entries(o??{}).flatMap(([e,a])=>{let o=t.params[e];return!a.options||typeof o!=`string`&&typeof o!=`number`||o===r[e]?[]:i(e,o,n)??[]});return[e.t(t.id,t.params,r,a),...s].join(` `)}Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return i}});
2
- //# sourceMappingURL=indicatorInputWords-DzrKBU2I.cjs.map
1
+ const e=require(`./indicatorLabel-BNZvaOcl.cjs`),t=require(`./i18n-C2nQBZTY.cjs`);function n(e){return Object.prototype.hasOwnProperty.call(t.c,e)}function r(e,t){let r=`indicatorInput.${e}`;return n(r)?t(r):null}function i(e,t,r){let i=`indicatorInput.${e}.${t}`;return n(i)?r(i):null}function a(t,n){let{defaultConfig:r,shortName:a,inputs:o}=t.descriptor,s=Object.entries(o??{}).flatMap(([e,a])=>{let o=t.params[e];return!a.options||typeof o!=`string`&&typeof o!=`number`||o===r[e]?[]:i(e,o,n)??[]});return[e.t(t.id,t.params,r,a),...s].join(` `)}Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return i}});
2
+ //# sourceMappingURL=indicatorInputWords-CTA4IcJR.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"indicatorInputWords-DzrKBU2I.cjs","names":[],"sources":["../src/widget/indicatorInputWords.ts"],"sourcesContent":["import type { IndicatorDescriptor } from '@tradecanvas/commons';\nimport { indicatorChipLabel } from '../indicatorLabel.js';\nimport { EN_MESSAGES, type MessageKey, type Translator } from './i18n.js';\n\n/**\n * Words for an indicator's inputs in the widget's language: an input named\n * `anchor` is `indicatorInput.anchor`, its choice `'week'` is\n * `indicatorInput.anchor.week`. Only inputs the widget has words for; any\n * other keeps its own label and its values as they are.\n */\n\n/** Whether the widget has a message under `key`, one built from an input's name. */\nfunction isMessageKey(key: string): key is MessageKey {\n return Object.prototype.hasOwnProperty.call(EN_MESSAGES, key);\n}\n\n/** An input's label in the widget's language, or null for one it has no word for. */\nexport function inputLabel(name: string, t: Translator): string | null {\n const key = `indicatorInput.${name}`;\n return isMessageKey(key) ? t(key) : null;\n}\n\n/** A choice of an input in the widget's language, or null for one it has no word for. */\nexport function choiceLabel(name: string, choice: string | number, t: Translator): string | null {\n const key = `indicatorInput.${name}.${choice}`;\n return isMessageKey(key) ? t(key) : null;\n}\n\n/** An indicator on the chart, as the widget names it. */\nexport interface NamedIndicator {\n id: string;\n params: Record<string, unknown>;\n descriptor: Pick<IndicatorDescriptor, 'defaultConfig' | 'shortName' | 'inputs'>;\n}\n\n/**\n * The indicator's name in the legend, the chips and the Objects panel: its\n * chip label ('EMA 21'), then the word for each choice off its default, so\n * two read apart ('VWAP', 'VWAP Week'). The CSV column keeps the chip label.\n */\nexport function widgetIndicatorLabel(ind: NamedIndicator, t: Translator): string {\n const { defaultConfig, shortName, inputs } = ind.descriptor;\n const words = Object.entries(inputs ?? {}).flatMap(([name, spec]) => {\n const value = ind.params[name];\n if (!spec.options || (typeof value !== 'string' && typeof value !== 'number') || value === defaultConfig[name]) return [];\n return choiceLabel(name, value, t) ?? [];\n });\n return [indicatorChipLabel(ind.id, ind.params, defaultConfig, shortName), ...words].join(' ');\n}\n"],"mappings":"kFAYA,SAAS,EAAa,EAAgC,CACpD,OAAO,OAAO,UAAU,eAAe,KAAK,EAAA,EAAa,EAAI,CAI/D,SAAgB,EAAW,EAAc,EAA8B,CACrE,IAAM,EAAM,kBAAkB,IAC9B,OAAO,EAAa,EAAI,CAAG,EAAE,EAAI,CAAG,KAItC,SAAgB,EAAY,EAAc,EAAyB,EAA8B,CAC/F,IAAM,EAAM,kBAAkB,EAAK,GAAG,IACtC,OAAO,EAAa,EAAI,CAAG,EAAE,EAAI,CAAG,KAetC,SAAgB,EAAqB,EAAqB,EAAuB,CAC/E,GAAM,CAAE,gBAAe,YAAW,UAAW,EAAI,WAC3C,EAAQ,OAAO,QAAQ,GAAU,EAAE,CAAC,CAAC,SAAS,CAAC,EAAM,KAAU,CACnE,IAAM,EAAQ,EAAI,OAAO,GAEzB,MADI,CAAC,EAAK,SAAY,OAAO,GAAU,UAAY,OAAO,GAAU,UAAa,IAAU,EAAc,GAAc,EAAE,CAClH,EAAY,EAAM,EAAO,EAAE,EAAI,EAAE,EACxC,CACF,MAAO,CAAC,EAAA,EAAmB,EAAI,GAAI,EAAI,OAAQ,EAAe,EAAU,CAAE,GAAG,EAAM,CAAC,KAAK,IAAI"}
1
+ {"version":3,"file":"indicatorInputWords-CTA4IcJR.cjs","names":[],"sources":["../src/widget/indicatorInputWords.ts"],"sourcesContent":["import type { IndicatorDescriptor } from '@tradecanvas/commons';\nimport { indicatorChipLabel } from '../indicatorLabel.js';\nimport { EN_MESSAGES, type MessageKey, type Translator } from './i18n.js';\n\n/**\n * Words for an indicator's inputs in the widget's language: an input named\n * `anchor` is `indicatorInput.anchor`, its choice `'week'` is\n * `indicatorInput.anchor.week`. Only inputs the widget has words for; any\n * other keeps its own label and its values as they are.\n */\n\n/** Whether the widget has a message under `key`, one built from an input's name. */\nfunction isMessageKey(key: string): key is MessageKey {\n return Object.prototype.hasOwnProperty.call(EN_MESSAGES, key);\n}\n\n/** An input's label in the widget's language, or null for one it has no word for. */\nexport function inputLabel(name: string, t: Translator): string | null {\n const key = `indicatorInput.${name}`;\n return isMessageKey(key) ? t(key) : null;\n}\n\n/** A choice of an input in the widget's language, or null for one it has no word for. */\nexport function choiceLabel(name: string, choice: string | number, t: Translator): string | null {\n const key = `indicatorInput.${name}.${choice}`;\n return isMessageKey(key) ? t(key) : null;\n}\n\n/** An indicator on the chart, as the widget names it. */\nexport interface NamedIndicator {\n id: string;\n params: Record<string, unknown>;\n descriptor: Pick<IndicatorDescriptor, 'defaultConfig' | 'shortName' | 'inputs'>;\n}\n\n/**\n * The indicator's name in the legend, the chips and the Objects panel: its\n * chip label ('EMA 21'), then the word for each choice off its default, so\n * two read apart ('VWAP', 'VWAP Week'). The CSV column keeps the chip label.\n */\nexport function widgetIndicatorLabel(ind: NamedIndicator, t: Translator): string {\n const { defaultConfig, shortName, inputs } = ind.descriptor;\n const words = Object.entries(inputs ?? {}).flatMap(([name, spec]) => {\n const value = ind.params[name];\n if (!spec.options || (typeof value !== 'string' && typeof value !== 'number') || value === defaultConfig[name]) return [];\n return choiceLabel(name, value, t) ?? [];\n });\n return [indicatorChipLabel(ind.id, ind.params, defaultConfig, shortName), ...words].join(' ');\n}\n"],"mappings":"kFAYA,SAAS,EAAa,EAAgC,CACpD,OAAO,OAAO,UAAU,eAAe,KAAK,EAAA,EAAa,EAAI,CAI/D,SAAgB,EAAW,EAAc,EAA8B,CACrE,IAAM,EAAM,kBAAkB,IAC9B,OAAO,EAAa,EAAI,CAAG,EAAE,EAAI,CAAG,KAItC,SAAgB,EAAY,EAAc,EAAyB,EAA8B,CAC/F,IAAM,EAAM,kBAAkB,EAAK,GAAG,IACtC,OAAO,EAAa,EAAI,CAAG,EAAE,EAAI,CAAG,KAetC,SAAgB,EAAqB,EAAqB,EAAuB,CAC/E,GAAM,CAAE,gBAAe,YAAW,UAAW,EAAI,WAC3C,EAAQ,OAAO,QAAQ,GAAU,EAAE,CAAC,CAAC,SAAS,CAAC,EAAM,KAAU,CACnE,IAAM,EAAQ,EAAI,OAAO,GAEzB,MADI,CAAC,EAAK,SAAY,OAAO,GAAU,UAAY,OAAO,GAAU,UAAa,IAAU,EAAc,GAAc,EAAE,CAClH,EAAY,EAAM,EAAO,EAAE,EAAI,EAAE,EACxC,CACF,MAAO,CAAC,EAAA,EAAmB,EAAI,GAAI,EAAI,OAAQ,EAAe,EAAU,CAAE,GAAG,EAAM,CAAC,KAAK,IAAI"}
@@ -1,2 +1,2 @@
1
- const e=require(`./focusTrap-B8OoGwHb.cjs`),t=require(`./settingsControls-jNn0If4b.cjs`);let n=require(`@tradecanvas/core`);var r=[1,1.5,2,3,4],i=[`solid`,`dashed`,`dotted`],a=`#4c8dff`,o=10,s={ticks:`toolbar.timeframes.ticks`,seconds:`toolbar.timeframes.seconds`,minutes:`toolbar.timeframes.minutes`,hours:`toolbar.timeframes.hours`,days:`toolbar.timeframes.days`,weeks:`toolbar.timeframes.weeks`,months:`toolbar.timeframes.months`};function c(e,n,i,a,o){let s=p();for(let e of[...n.plots].sort((e,t)=>e.color-t.color))s.appendChild(l(e,n,i,a));let c=t.o(r.map(e=>({value:String(e),label:`${e} px`})),String(n.lineWidth),e=>i.lineWidth(Number(e)));if(c.dataset.role=`line-width`,s.appendChild(t.s(a(`indicatorSettings.lineWidth`),c)),n.scale&&i.scale){let e=t.o([{value:`right`,label:a(`indicatorSettings.scale.right`)},{value:`left`,label:a(`indicatorSettings.scale.left`)}],n.scale,e=>i.scale?.(e===`left`?`left`:`right`));e.dataset.role=`scale`,s.appendChild(t.s(a(`indicatorSettings.scale`),e))}e.appendChild(s),n.levels&&i.levels&&e.appendChild(u([...n.levels],i.levels,a,o))}function l(e,n,r,o){let s=n.plotStyles[e.key]??{},c=document.createElement(`div`);c.className=`tcw-settings-row tcw-indi-plot`,c.dataset.plot=e.key;let l=document.createElement(`label`);l.className=`tcw-indi-plot-name`;let u=document.createElement(`input`);u.type=`checkbox`,u.checked=s.visible!==!1,u.addEventListener(`change`,()=>r.plot(e.key,{visible:u.checked}));let d=document.createElement(`span`);d.className=`tcw-settings-label`,d.textContent=e.title,l.append(u,d);let f=document.createElement(`span`);f.className=`tcw-indi-plot-controls`;let p=(e,i)=>{let o=t.r(n.colors[e]??n.colors[0]??a,t=>r.color(e,t));return o.setAttribute(`aria-label`,i),o};if(e.tone!==void 0&&e.downColor!==void 0?f.append(p(e.color,`${e.title} ${o(`indicatorSettings.up`)}`),p(e.downColor,`${e.title} ${o(`indicatorSettings.down`)}`)):f.appendChild(p(e.color,e.title)),(e.kind??`line`)===`line`||e.kind===`step`){let n=t.o(i.map(e=>({value:e,label:o(`drawingSettings.lineStyle.${e}`)})),s.lineStyle??e.lineStyle??`solid`,t=>r.plot(e.key,{lineStyle:t}));n.setAttribute(`aria-label`,`${e.title}: ${o(`drawingSettings.lineStyle`)}`),f.appendChild(n)}return c.append(l,f),c}function u(n,r,i,a){let s=p(),c=n,l=()=>{let e=document.createElement(`div`);e.className=`tcw-settings-section-title`,e.textContent=i(`indicatorSettings.tab.levels`);let t=c.map((e,t)=>d(e,t)),n=document.createElement(`button`);n.type=`button`,n.className=`tcw-reset-link tcw-indi-add`,n.textContent=`+ ${i(`indicatorSettings.addLevel`)}`,n.addEventListener(`click`,()=>{let e=c[c.length-1];u([...c,e===void 0?0:e+o]);let t=s.querySelectorAll(`.tcw-indi-level input`);t[t.length-1]?.focus()}),s.replaceChildren(e,...c.length===0?[m(i(`indicatorSettings.noLevels`))]:t,n)},u=e=>{c=e,r([...e]),l()},d=(n,o)=>{let l=t.i(n,{step:`any`},e=>{c=c.map((t,n)=>n===o?e:t),r([...c])});l.id=`tcw-indi-level-${a}-${o}`;let d=document.createElement(`button`);d.type=`button`,d.className=`tcw-indi-remove`,d.innerHTML=e.i(`x`,12);let f=i(`indicatorSettings.removeLevel`);d.title=f,d.setAttribute(`aria-label`,`${f} ${o+1}`),d.addEventListener(`click`,()=>{u(c.filter((e,t)=>t!==o)),(s.querySelectorAll(`.tcw-indi-remove`)[o]??s.querySelector(`.tcw-indi-add`))?.focus()});let p=document.createElement(`span`);p.className=`tcw-indi-level`,p.append(l,d);let m=document.createElement(`div`);m.className=`tcw-settings-row`;let h=document.createElement(`label`);return h.className=`tcw-settings-label`,h.htmlFor=l.id,h.textContent=`${i(`indicatorSettings.level`)} ${o+1}`,m.append(h,p),m};return l(),s}function d(e,t,r,i){let a=new Map(n.INTERVAL_UNITS.map(e=>{let r=t?.[e],i=Array.isArray(r)?r:[1,n.INTERVAL_LIMITS[e]];return[e,{on:r!==!1,from:i[0],to:i[1]}]})),o=()=>{let e={};for(let[t,{on:r,from:i,to:o}]of a){let[a,s]=[Math.min(i,o),Math.max(i,o)];r?(a>1||s<n.INTERVAL_LIMITS[t])&&(e[t]=[a,s]):e[t]=!1}r(Object.keys(e).length>0?e:null)},s=p();for(let e of n.INTERVAL_UNITS)s.appendChild(f(e,a.get(e),o,i));e.appendChild(s)}function f(e,r,i,a){let o=document.createElement(`div`);o.className=`tcw-settings-row tcw-indi-unit`,o.dataset.unit=e;let c=document.createElement(`label`);c.className=`tcw-indi-plot-name`;let l=document.createElement(`input`);l.type=`checkbox`,l.checked=r.on;let u=document.createElement(`span`);u.className=`tcw-settings-label`,u.textContent=a(s[e]),c.append(l,u),o.appendChild(c);let d=[];if(e!==`ticks`){let c=(o,c)=>{let l=t.i(r[o],{min:1,max:n.INTERVAL_LIMITS[e],step:1},e=>{r[o]=Math.round(e),l.value=String(r[o]),i()});return l.setAttribute(`aria-label`,`${a(s[e])}: ${a(c)}`),l.disabled=!r.on,d.push(l),l},l=document.createElement(`span`);l.className=`tcw-indi-range`;let u=document.createElement(`span`);u.setAttribute(`aria-hidden`,`true`),u.textContent=`–`,l.append(c(`from`,`indicatorSettings.rangeFrom`),u,c(`to`,`indicatorSettings.rangeTo`)),o.appendChild(l)}return l.addEventListener(`change`,()=>{r.on=l.checked;for(let e of d)e.disabled=!l.checked;i()}),o}function p(){let e=document.createElement(`div`);return e.className=`tcw-settings-section`,e}function m(e){let t=document.createElement(`div`);return t.className=`tcw-settings-label`,t.textContent=e,t}Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return c}});
2
- //# sourceMappingURL=indicatorSettingsTabs-BLEULMJJ.cjs.map
1
+ const e=require(`./focusTrap-DrhhmG0V.cjs`),t=require(`./settingsControls-Tn8_vJJv.cjs`);let n=require(`@tradecanvas/core`);var r=[1,1.5,2,3,4],i=[`solid`,`dashed`,`dotted`],a=`#4c8dff`,o=10,s={ticks:`toolbar.timeframes.ticks`,seconds:`toolbar.timeframes.seconds`,minutes:`toolbar.timeframes.minutes`,hours:`toolbar.timeframes.hours`,days:`toolbar.timeframes.days`,weeks:`toolbar.timeframes.weeks`,months:`toolbar.timeframes.months`};function c(e,n,i,a,o){let s=p();for(let e of[...n.plots].sort((e,t)=>e.color-t.color))s.appendChild(l(e,n,i,a));let c=t.o(r.map(e=>({value:String(e),label:`${e} px`})),String(n.lineWidth),e=>i.lineWidth(Number(e)));if(c.dataset.role=`line-width`,s.appendChild(t.s(a(`indicatorSettings.lineWidth`),c)),n.scale&&i.scale){let e=t.o([{value:`right`,label:a(`indicatorSettings.scale.right`)},{value:`left`,label:a(`indicatorSettings.scale.left`)}],n.scale,e=>i.scale?.(e===`left`?`left`:`right`));e.dataset.role=`scale`,s.appendChild(t.s(a(`indicatorSettings.scale`),e))}e.appendChild(s),n.levels&&i.levels&&e.appendChild(u([...n.levels],i.levels,a,o))}function l(e,n,r,o){let s=n.plotStyles[e.key]??{},c=document.createElement(`div`);c.className=`tcw-settings-row tcw-indi-plot`,c.dataset.plot=e.key;let l=document.createElement(`label`);l.className=`tcw-indi-plot-name`;let u=document.createElement(`input`);u.type=`checkbox`,u.checked=s.visible!==!1,u.addEventListener(`change`,()=>r.plot(e.key,{visible:u.checked}));let d=document.createElement(`span`);d.className=`tcw-settings-label`,d.textContent=e.title,l.append(u,d);let f=document.createElement(`span`);f.className=`tcw-indi-plot-controls`;let p=(e,i)=>{let o=t.r(n.colors[e]??n.colors[0]??a,t=>r.color(e,t));return o.setAttribute(`aria-label`,i),o};if(e.tone!==void 0&&e.downColor!==void 0?f.append(p(e.color,`${e.title} ${o(`indicatorSettings.up`)}`),p(e.downColor,`${e.title} ${o(`indicatorSettings.down`)}`)):f.appendChild(p(e.color,e.title)),(e.kind??`line`)===`line`||e.kind===`step`){let n=t.o(i.map(e=>({value:e,label:o(`drawingSettings.lineStyle.${e}`)})),s.lineStyle??e.lineStyle??`solid`,t=>r.plot(e.key,{lineStyle:t}));n.setAttribute(`aria-label`,`${e.title}: ${o(`drawingSettings.lineStyle`)}`),f.appendChild(n)}return c.append(l,f),c}function u(n,r,i,a){let s=p(),c=n,l=()=>{let e=document.createElement(`div`);e.className=`tcw-settings-section-title`,e.textContent=i(`indicatorSettings.tab.levels`);let t=c.map((e,t)=>d(e,t)),n=document.createElement(`button`);n.type=`button`,n.className=`tcw-reset-link tcw-indi-add`,n.textContent=`+ ${i(`indicatorSettings.addLevel`)}`,n.addEventListener(`click`,()=>{let e=c[c.length-1];u([...c,e===void 0?0:e+o]);let t=s.querySelectorAll(`.tcw-indi-level input`);t[t.length-1]?.focus()}),s.replaceChildren(e,...c.length===0?[m(i(`indicatorSettings.noLevels`))]:t,n)},u=e=>{c=e,r([...e]),l()},d=(n,o)=>{let l=t.i(n,{step:`any`},e=>{c=c.map((t,n)=>n===o?e:t),r([...c])});l.id=`tcw-indi-level-${a}-${o}`;let d=document.createElement(`button`);d.type=`button`,d.className=`tcw-indi-remove`,d.innerHTML=e.i(`x`,12);let f=i(`indicatorSettings.removeLevel`);d.title=f,d.setAttribute(`aria-label`,`${f} ${o+1}`),d.addEventListener(`click`,()=>{u(c.filter((e,t)=>t!==o)),(s.querySelectorAll(`.tcw-indi-remove`)[o]??s.querySelector(`.tcw-indi-add`))?.focus()});let p=document.createElement(`span`);p.className=`tcw-indi-level`,p.append(l,d);let m=document.createElement(`div`);m.className=`tcw-settings-row`;let h=document.createElement(`label`);return h.className=`tcw-settings-label`,h.htmlFor=l.id,h.textContent=`${i(`indicatorSettings.level`)} ${o+1}`,m.append(h,p),m};return l(),s}function d(e,t,r,i){let a=new Map(n.INTERVAL_UNITS.map(e=>{let r=t?.[e],i=Array.isArray(r)?r:[1,n.INTERVAL_LIMITS[e]];return[e,{on:r!==!1,from:i[0],to:i[1]}]})),o=()=>{let e={};for(let[t,{on:r,from:i,to:o}]of a){let[a,s]=[Math.min(i,o),Math.max(i,o)];r?(a>1||s<n.INTERVAL_LIMITS[t])&&(e[t]=[a,s]):e[t]=!1}r(Object.keys(e).length>0?e:null)},s=p();for(let e of n.INTERVAL_UNITS)s.appendChild(f(e,a.get(e),o,i));e.appendChild(s)}function f(e,r,i,a){let o=document.createElement(`div`);o.className=`tcw-settings-row tcw-indi-unit`,o.dataset.unit=e;let c=document.createElement(`label`);c.className=`tcw-indi-plot-name`;let l=document.createElement(`input`);l.type=`checkbox`,l.checked=r.on;let u=document.createElement(`span`);u.className=`tcw-settings-label`,u.textContent=a(s[e]),c.append(l,u),o.appendChild(c);let d=[];if(e!==`ticks`){let c=(o,c)=>{let l=t.i(r[o],{min:1,max:n.INTERVAL_LIMITS[e],step:1},e=>{r[o]=Math.round(e),l.value=String(r[o]),i()});return l.setAttribute(`aria-label`,`${a(s[e])}: ${a(c)}`),l.disabled=!r.on,d.push(l),l},l=document.createElement(`span`);l.className=`tcw-indi-range`;let u=document.createElement(`span`);u.setAttribute(`aria-hidden`,`true`),u.textContent=`–`,l.append(c(`from`,`indicatorSettings.rangeFrom`),u,c(`to`,`indicatorSettings.rangeTo`)),o.appendChild(l)}return l.addEventListener(`change`,()=>{r.on=l.checked;for(let e of d)e.disabled=!l.checked;i()}),o}function p(){let e=document.createElement(`div`);return e.className=`tcw-settings-section`,e}function m(e){let t=document.createElement(`div`);return t.className=`tcw-settings-label`,t.textContent=e,t}Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return c}});
2
+ //# sourceMappingURL=indicatorSettingsTabs-B0liE3ST.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"indicatorSettingsTabs-BLEULMJJ.cjs","names":[],"sources":["../src/widget/indicatorSettingsTabs.ts"],"sourcesContent":["import type { IndicatorIntervals, IndicatorPlot, IndicatorPlotStyle, IntervalUnit, LineStyle } from '@tradecanvas/commons';\nimport { INTERVAL_LIMITS, INTERVAL_UNITS } from '@tradecanvas/core';\nimport { createIcon } from './icons.js';\nimport { colorInput, numberInput, selectInput, settingsRow } from './settingsControls.js';\nimport type { MessageKey, Translator } from './i18n.js';\n\nconst LINE_WIDTHS = [1, 1.5, 2, 3, 4];\nconst LINE_STYLES: readonly LineStyle[] = ['solid', 'dashed', 'dotted'];\n/** A line's colour where the indicator gives none (a colour field needs one; not a token, which it can't read). */\nconst FALLBACK_COLOR = '#4c8dff';\n/** A new level sits this far above the last one. */\nconst LEVEL_STEP = 10;\n\nconst UNIT_LABELS: Record<IntervalUnit, MessageKey> = {\n ticks: 'toolbar.timeframes.ticks',\n seconds: 'toolbar.timeframes.seconds',\n minutes: 'toolbar.timeframes.minutes',\n hours: 'toolbar.timeframes.hours',\n days: 'toolbar.timeframes.days',\n weeks: 'toolbar.timeframes.weeks',\n months: 'toolbar.timeframes.months',\n};\n\n/** What the Style tab shows. */\nexport interface StyleTabState {\n plots: readonly IndicatorPlot[];\n colors: readonly string[];\n plotStyles: Readonly<Record<string, IndicatorPlotStyle>>;\n lineWidth: number;\n /** The price scale of a price-pane overlay; unset for the rest. */\n scale?: 'right' | 'left';\n /** Its levels; unset: it has none to edit. */\n levels?: readonly number[];\n}\n\n/** What the Style tab changes. */\nexport interface StyleTabActions {\n color(index: number, value: string): void;\n plot(key: string, patch: IndicatorPlotStyle): void;\n lineWidth(width: number): void;\n scale?(scale: 'right' | 'left'): void;\n levels?(levels: number[]): void;\n}\n\n/**\n * The Style tab: a row per line (shown or not, its colours, its dash), the\n * line width, the price scale of an overlay, and the levels under them.\n */\nexport function renderStyleTab(body: HTMLElement, state: StyleTabState, actions: StyleTabActions, t: Translator, uid: number): void {\n const lines = section();\n // In the order of their colours: a two-tone plot's up and down sit together.\n for (const plot of [...state.plots].sort((a, b) => a.color - b.color)) lines.appendChild(plotRow(plot, state, actions, t));\n const width = selectInput(LINE_WIDTHS.map((w) => ({ value: String(w), label: `${w} px` })), String(state.lineWidth), (v) => actions.lineWidth(Number(v)));\n width.dataset.role = 'line-width';\n lines.appendChild(settingsRow(t('indicatorSettings.lineWidth'), width));\n if (state.scale && actions.scale) {\n const scale = selectInput([\n { value: 'right', label: t('indicatorSettings.scale.right') },\n { value: 'left', label: t('indicatorSettings.scale.left') },\n ], state.scale, (v) => actions.scale?.(v === 'left' ? 'left' : 'right'));\n scale.dataset.role = 'scale';\n lines.appendChild(settingsRow(t('indicatorSettings.scale'), scale));\n }\n body.appendChild(lines);\n if (state.levels && actions.levels) body.appendChild(levelsSection([...state.levels], actions.levels, t, uid));\n}\n\nfunction plotRow(plot: IndicatorPlot, state: StyleTabState, actions: StyleTabActions, t: Translator): HTMLDivElement {\n const own = state.plotStyles[plot.key] ?? {};\n const row = document.createElement('div');\n row.className = 'tcw-settings-row tcw-indi-plot';\n row.dataset.plot = plot.key;\n const name = document.createElement('label');\n name.className = 'tcw-indi-plot-name';\n const shown = document.createElement('input');\n shown.type = 'checkbox';\n shown.checked = own.visible !== false;\n shown.addEventListener('change', () => actions.plot(plot.key, { visible: shown.checked }));\n const text = document.createElement('span');\n text.className = 'tcw-settings-label';\n text.textContent = plot.title;\n name.append(shown, text);\n\n const controls = document.createElement('span');\n controls.className = 'tcw-indi-plot-controls';\n const swatch = (index: number, label: string) => {\n const input = colorInput(state.colors[index] ?? state.colors[0] ?? FALLBACK_COLOR, (v) => actions.color(index, v));\n input.setAttribute('aria-label', label);\n return input;\n };\n const twoTone = plot.tone !== undefined && plot.downColor !== undefined;\n if (twoTone) {\n controls.append(\n swatch(plot.color, `${plot.title} ${t('indicatorSettings.up')}`),\n swatch(plot.downColor!, `${plot.title} ${t('indicatorSettings.down')}`),\n );\n } else {\n controls.appendChild(swatch(plot.color, plot.title));\n }\n // Bars and dots have no dash.\n if ((plot.kind ?? 'line') === 'line' || plot.kind === 'step') {\n const dash = selectInput(\n LINE_STYLES.map((s) => ({ value: s, label: t(`drawingSettings.lineStyle.${s}`) })),\n own.lineStyle ?? plot.lineStyle ?? 'solid',\n (v) => actions.plot(plot.key, { lineStyle: v as LineStyle }),\n );\n dash.setAttribute('aria-label', `${plot.title}: ${t('drawingSettings.lineStyle')}`);\n controls.appendChild(dash);\n }\n row.append(name, controls);\n return row;\n}\n\n/** The levels, each with its remove button, and Add; it redraws itself and keeps the keyboard nearby. */\nfunction levelsSection(start: number[], onChange: (levels: number[]) => void, t: Translator, uid: number): HTMLElement {\n const block = section();\n let levels = start;\n const draw = () => {\n const title = document.createElement('div');\n title.className = 'tcw-settings-section-title';\n title.textContent = t('indicatorSettings.tab.levels');\n const rows = levels.map((level, i) => levelRow(level, i));\n const add = document.createElement('button');\n add.type = 'button';\n add.className = 'tcw-reset-link tcw-indi-add';\n add.textContent = `+ ${t('indicatorSettings.addLevel')}`;\n add.addEventListener('click', () => {\n const last = levels[levels.length - 1];\n set([...levels, last === undefined ? 0 : last + LEVEL_STEP]);\n const inputs = block.querySelectorAll<HTMLInputElement>('.tcw-indi-level input');\n inputs[inputs.length - 1]?.focus();\n });\n block.replaceChildren(title, ...(levels.length === 0 ? [note(t('indicatorSettings.noLevels'))] : rows), add);\n };\n const set = (next: number[]) => {\n levels = next;\n onChange([...next]);\n draw();\n };\n const levelRow = (level: number, i: number): HTMLElement => {\n const input = numberInput(level, { step: 'any' }, (n) => {\n levels = levels.map((v, j) => (j === i ? n : v));\n onChange([...levels]);\n });\n input.id = `tcw-indi-level-${uid}-${i}`;\n const remove = document.createElement('button');\n remove.type = 'button';\n remove.className = 'tcw-indi-remove';\n remove.innerHTML = createIcon('x', 12);\n const label = t('indicatorSettings.removeLevel');\n remove.title = label;\n remove.setAttribute('aria-label', `${label} ${i + 1}`);\n remove.addEventListener('click', () => {\n set(levels.filter((_, j) => j !== i));\n (block.querySelectorAll<HTMLElement>('.tcw-indi-remove')[i] ?? block.querySelector<HTMLElement>('.tcw-indi-add'))?.focus();\n });\n const controls = document.createElement('span');\n controls.className = 'tcw-indi-level';\n controls.append(input, remove);\n const row = document.createElement('div');\n row.className = 'tcw-settings-row';\n const text = document.createElement('label');\n text.className = 'tcw-settings-label';\n text.htmlFor = input.id;\n text.textContent = `${t('indicatorSettings.level')} ${i + 1}`;\n row.append(text, controls);\n return row;\n };\n draw();\n return block;\n}\n\n/** One kind of interval as the Visibility tab edits it: shown at all, and from which count to which. */\ninterface UnitState {\n on: boolean;\n from: number;\n to: number;\n}\n\n/**\n * The Visibility tab: a row per kind of interval, ticked where the indicator\n * shows, with the range of counts it shows on (ticks: on or off).\n */\nexport function renderVisibilityTab(body: HTMLElement, start: IndicatorIntervals | null, onChange: (intervals: IndicatorIntervals | null) => void, t: Translator): void {\n const state = new Map<IntervalUnit, UnitState>(INTERVAL_UNITS.map((unit) => {\n const rule = start?.[unit];\n const range = Array.isArray(rule) ? rule : [1, INTERVAL_LIMITS[unit]];\n return [unit, { on: rule !== false, from: range[0], to: range[1] }];\n }));\n const commit = () => {\n const rules: { -readonly [U in IntervalUnit]?: false | readonly [number, number] } = {};\n for (const [unit, { on, from, to }] of state) {\n const [lo, hi] = [Math.min(from, to), Math.max(from, to)];\n if (!on) rules[unit] = false;\n else if (lo > 1 || hi < INTERVAL_LIMITS[unit]) rules[unit] = [lo, hi];\n }\n onChange(Object.keys(rules).length > 0 ? rules : null);\n };\n const block = section();\n for (const unit of INTERVAL_UNITS) block.appendChild(unitRow(unit, state.get(unit)!, commit, t));\n body.appendChild(block);\n}\n\nfunction unitRow(unit: IntervalUnit, unitState: UnitState, commit: () => void, t: Translator): HTMLDivElement {\n const row = document.createElement('div');\n row.className = 'tcw-settings-row tcw-indi-unit';\n row.dataset.unit = unit;\n const name = document.createElement('label');\n name.className = 'tcw-indi-plot-name';\n const box = document.createElement('input');\n box.type = 'checkbox';\n box.checked = unitState.on;\n const text = document.createElement('span');\n text.className = 'tcw-settings-label';\n text.textContent = t(UNIT_LABELS[unit]);\n name.append(box, text);\n row.appendChild(name);\n const fields: HTMLInputElement[] = [];\n if (unit !== 'ticks') {\n const field = (key: 'from' | 'to', label: MessageKey) => {\n const input: HTMLInputElement = numberInput(unitState[key], { min: 1, max: INTERVAL_LIMITS[unit], step: 1 }, (n) => {\n // A count of intervals is whole: 2.5 hours reads 3.\n unitState[key] = Math.round(n);\n input.value = String(unitState[key]);\n commit();\n });\n input.setAttribute('aria-label', `${t(UNIT_LABELS[unit])}: ${t(label)}`);\n input.disabled = !unitState.on;\n fields.push(input);\n return input;\n };\n const range = document.createElement('span');\n range.className = 'tcw-indi-range';\n const dash = document.createElement('span');\n dash.setAttribute('aria-hidden', 'true');\n dash.textContent = '–';\n range.append(field('from', 'indicatorSettings.rangeFrom'), dash, field('to', 'indicatorSettings.rangeTo'));\n row.appendChild(range);\n }\n box.addEventListener('change', () => {\n unitState.on = box.checked;\n for (const input of fields) input.disabled = !box.checked;\n commit();\n });\n return row;\n}\n\nfunction section(): HTMLDivElement {\n const el = document.createElement('div');\n el.className = 'tcw-settings-section';\n return el;\n}\n\nfunction note(text: string): HTMLDivElement {\n const el = document.createElement('div');\n el.className = 'tcw-settings-label';\n el.textContent = text;\n return el;\n}\n"],"mappings":"4HAMA,IAAM,EAAc,CAAC,EAAG,IAAK,EAAG,EAAG,EAAE,CAC/B,EAAoC,CAAC,QAAS,SAAU,SAAS,CAEjE,EAAiB,UAEjB,EAAa,GAEb,EAAgD,CACpD,MAAO,2BACP,QAAS,6BACT,QAAS,6BACT,MAAO,2BACP,KAAM,0BACN,MAAO,2BACP,OAAQ,4BACT,CA2BD,SAAgB,EAAe,EAAmB,EAAsB,EAA0B,EAAe,EAAmB,CAClI,IAAM,EAAQ,GAAS,CAEvB,IAAK,IAAM,IAAQ,CAAC,GAAG,EAAM,MAAM,CAAC,MAAM,EAAG,IAAM,EAAE,MAAQ,EAAE,MAAM,CAAE,EAAM,YAAY,EAAQ,EAAM,EAAO,EAAS,EAAE,CAAC,CAC1H,IAAM,EAAQ,EAAA,EAAY,EAAY,IAAK,IAAO,CAAE,MAAO,OAAO,EAAE,CAAE,MAAO,GAAG,EAAE,KAAM,EAAE,CAAE,OAAO,EAAM,UAAU,CAAG,GAAM,EAAQ,UAAU,OAAO,EAAE,CAAC,CAAC,CAGzJ,GAFA,EAAM,QAAQ,KAAO,aACrB,EAAM,YAAY,EAAA,EAAY,EAAE,8BAA8B,CAAE,EAAM,CAAC,CACnE,EAAM,OAAS,EAAQ,MAAO,CAChC,IAAM,EAAQ,EAAA,EAAY,CACxB,CAAE,MAAO,QAAS,MAAO,EAAE,gCAAgC,CAAE,CAC7D,CAAE,MAAO,OAAQ,MAAO,EAAE,+BAA+B,CAAE,CAC5D,CAAE,EAAM,MAAQ,GAAM,EAAQ,QAAQ,IAAM,OAAS,OAAS,QAAQ,CAAC,CACxE,EAAM,QAAQ,KAAO,QACrB,EAAM,YAAY,EAAA,EAAY,EAAE,0BAA0B,CAAE,EAAM,CAAC,CAErE,EAAK,YAAY,EAAM,CACnB,EAAM,QAAU,EAAQ,QAAQ,EAAK,YAAY,EAAc,CAAC,GAAG,EAAM,OAAO,CAAE,EAAQ,OAAQ,EAAG,EAAI,CAAC,CAGhH,SAAS,EAAQ,EAAqB,EAAsB,EAA0B,EAA+B,CACnH,IAAM,EAAM,EAAM,WAAW,EAAK,MAAQ,EAAE,CACtC,EAAM,SAAS,cAAc,MAAM,CACzC,EAAI,UAAY,iCAChB,EAAI,QAAQ,KAAO,EAAK,IACxB,IAAM,EAAO,SAAS,cAAc,QAAQ,CAC5C,EAAK,UAAY,qBACjB,IAAM,EAAQ,SAAS,cAAc,QAAQ,CAC7C,EAAM,KAAO,WACb,EAAM,QAAU,EAAI,UAAY,GAChC,EAAM,iBAAiB,aAAgB,EAAQ,KAAK,EAAK,IAAK,CAAE,QAAS,EAAM,QAAS,CAAC,CAAC,CAC1F,IAAM,EAAO,SAAS,cAAc,OAAO,CAC3C,EAAK,UAAY,qBACjB,EAAK,YAAc,EAAK,MACxB,EAAK,OAAO,EAAO,EAAK,CAExB,IAAM,EAAW,SAAS,cAAc,OAAO,CAC/C,EAAS,UAAY,yBACrB,IAAM,GAAU,EAAe,IAAkB,CAC/C,IAAM,EAAQ,EAAA,EAAW,EAAM,OAAO,IAAU,EAAM,OAAO,IAAM,EAAiB,GAAM,EAAQ,MAAM,EAAO,EAAE,CAAC,CAElH,OADA,EAAM,aAAa,aAAc,EAAM,CAChC,GAYT,GAVgB,EAAK,OAAS,IAAA,IAAa,EAAK,YAAc,IAAA,GAE5D,EAAS,OACP,EAAO,EAAK,MAAO,GAAG,EAAK,MAAM,GAAG,EAAE,uBAAuB,GAAG,CAChE,EAAO,EAAK,UAAY,GAAG,EAAK,MAAM,GAAG,EAAE,yBAAyB,GAAG,CACxE,CAED,EAAS,YAAY,EAAO,EAAK,MAAO,EAAK,MAAM,CAAC,EAGjD,EAAK,MAAQ,UAAY,QAAU,EAAK,OAAS,OAAQ,CAC5D,IAAM,EAAO,EAAA,EACX,EAAY,IAAK,IAAO,CAAE,MAAO,EAAG,MAAO,EAAE,6BAA6B,IAAI,CAAE,EAAE,CAClF,EAAI,WAAa,EAAK,WAAa,QAClC,GAAM,EAAQ,KAAK,EAAK,IAAK,CAAE,UAAW,EAAgB,CAAC,CAC7D,CACD,EAAK,aAAa,aAAc,GAAG,EAAK,MAAM,IAAI,EAAE,4BAA4B,GAAG,CACnF,EAAS,YAAY,EAAK,CAG5B,OADA,EAAI,OAAO,EAAM,EAAS,CACnB,EAIT,SAAS,EAAc,EAAiB,EAAsC,EAAe,EAA0B,CACrH,IAAM,EAAQ,GAAS,CACnB,EAAS,EACP,MAAa,CACjB,IAAM,EAAQ,SAAS,cAAc,MAAM,CAC3C,EAAM,UAAY,6BAClB,EAAM,YAAc,EAAE,+BAA+B,CACrD,IAAM,EAAO,EAAO,KAAK,EAAO,IAAM,EAAS,EAAO,EAAE,CAAC,CACnD,EAAM,SAAS,cAAc,SAAS,CAC5C,EAAI,KAAO,SACX,EAAI,UAAY,8BAChB,EAAI,YAAc,KAAK,EAAE,6BAA6B,GACtD,EAAI,iBAAiB,YAAe,CAClC,IAAM,EAAO,EAAO,EAAO,OAAS,GACpC,EAAI,CAAC,GAAG,EAAQ,IAAS,IAAA,GAAY,EAAI,EAAO,EAAW,CAAC,CAC5D,IAAM,EAAS,EAAM,iBAAmC,wBAAwB,CAChF,EAAO,EAAO,OAAS,IAAI,OAAO,EAClC,CACF,EAAM,gBAAgB,EAAO,GAAI,EAAO,SAAW,EAAI,CAAC,EAAK,EAAE,6BAA6B,CAAC,CAAC,CAAG,EAAO,EAAI,EAExG,EAAO,GAAmB,CAC9B,EAAS,EACT,EAAS,CAAC,GAAG,EAAK,CAAC,CACnB,GAAM,EAEF,GAAY,EAAe,IAA2B,CAC1D,IAAM,EAAQ,EAAA,EAAY,EAAO,CAAE,KAAM,MAAO,CAAG,GAAM,CACvD,EAAS,EAAO,KAAK,EAAG,IAAO,IAAM,EAAI,EAAI,EAAG,CAChD,EAAS,CAAC,GAAG,EAAO,CAAC,EACrB,CACF,EAAM,GAAK,kBAAkB,EAAI,GAAG,IACpC,IAAM,EAAS,SAAS,cAAc,SAAS,CAC/C,EAAO,KAAO,SACd,EAAO,UAAY,kBACnB,EAAO,UAAY,EAAA,EAAW,IAAK,GAAG,CACtC,IAAM,EAAQ,EAAE,gCAAgC,CAChD,EAAO,MAAQ,EACf,EAAO,aAAa,aAAc,GAAG,EAAM,GAAG,EAAI,IAAI,CACtD,EAAO,iBAAiB,YAAe,CACrC,EAAI,EAAO,QAAQ,EAAG,IAAM,IAAM,EAAE,CAAC,EACpC,EAAM,iBAA8B,mBAAmB,CAAC,IAAM,EAAM,cAA2B,gBAAgB,GAAG,OAAO,EAC1H,CACF,IAAM,EAAW,SAAS,cAAc,OAAO,CAC/C,EAAS,UAAY,iBACrB,EAAS,OAAO,EAAO,EAAO,CAC9B,IAAM,EAAM,SAAS,cAAc,MAAM,CACzC,EAAI,UAAY,mBAChB,IAAM,EAAO,SAAS,cAAc,QAAQ,CAK5C,MAJA,GAAK,UAAY,qBACjB,EAAK,QAAU,EAAM,GACrB,EAAK,YAAc,GAAG,EAAE,0BAA0B,CAAC,GAAG,EAAI,IAC1D,EAAI,OAAO,EAAM,EAAS,CACnB,GAGT,OADA,GAAM,CACC,EAcT,SAAgB,EAAoB,EAAmB,EAAkC,EAA0D,EAAqB,CACtK,IAAM,EAAQ,IAAI,IAA6B,EAAA,eAAe,IAAK,GAAS,CAC1E,IAAM,EAAO,IAAQ,GACf,EAAQ,MAAM,QAAQ,EAAK,CAAG,EAAO,CAAC,EAAG,EAAA,gBAAgB,GAAM,CACrE,MAAO,CAAC,EAAM,CAAE,GAAI,IAAS,GAAO,KAAM,EAAM,GAAI,GAAI,EAAM,GAAI,CAAC,EACnE,CAAC,CACG,MAAe,CACnB,IAAM,EAA+E,EAAE,CACvF,IAAK,GAAM,CAAC,EAAM,CAAE,KAAI,OAAM,SAAS,EAAO,CAC5C,GAAM,CAAC,EAAI,GAAM,CAAC,KAAK,IAAI,EAAM,EAAG,CAAE,KAAK,IAAI,EAAM,EAAG,CAAC,CACpD,GACI,EAAK,GAAK,EAAK,EAAA,gBAAgB,MAAO,EAAM,GAAQ,CAAC,EAAI,EAAG,EAD5D,EAAM,GAAQ,GAGzB,EAAS,OAAO,KAAK,EAAM,CAAC,OAAS,EAAI,EAAQ,KAAK,EAElD,EAAQ,GAAS,CACvB,IAAK,IAAM,KAAQ,EAAA,eAAgB,EAAM,YAAY,EAAQ,EAAM,EAAM,IAAI,EAAK,CAAG,EAAQ,EAAE,CAAC,CAChG,EAAK,YAAY,EAAM,CAGzB,SAAS,EAAQ,EAAoB,EAAsB,EAAoB,EAA+B,CAC5G,IAAM,EAAM,SAAS,cAAc,MAAM,CACzC,EAAI,UAAY,iCAChB,EAAI,QAAQ,KAAO,EACnB,IAAM,EAAO,SAAS,cAAc,QAAQ,CAC5C,EAAK,UAAY,qBACjB,IAAM,EAAM,SAAS,cAAc,QAAQ,CAC3C,EAAI,KAAO,WACX,EAAI,QAAU,EAAU,GACxB,IAAM,EAAO,SAAS,cAAc,OAAO,CAC3C,EAAK,UAAY,qBACjB,EAAK,YAAc,EAAE,EAAY,GAAM,CACvC,EAAK,OAAO,EAAK,EAAK,CACtB,EAAI,YAAY,EAAK,CACrB,IAAM,EAA6B,EAAE,CACrC,GAAI,IAAS,QAAS,CACpB,IAAM,GAAS,EAAoB,IAAsB,CACvD,IAAM,EAA0B,EAAA,EAAY,EAAU,GAAM,CAAE,IAAK,EAAG,IAAK,EAAA,gBAAgB,GAAO,KAAM,EAAG,CAAG,GAAM,CAElH,EAAU,GAAO,KAAK,MAAM,EAAE,CAC9B,EAAM,MAAQ,OAAO,EAAU,GAAK,CACpC,GAAQ,EACR,CAIF,OAHA,EAAM,aAAa,aAAc,GAAG,EAAE,EAAY,GAAM,CAAC,IAAI,EAAE,EAAM,GAAG,CACxE,EAAM,SAAW,CAAC,EAAU,GAC5B,EAAO,KAAK,EAAM,CACX,GAEH,EAAQ,SAAS,cAAc,OAAO,CAC5C,EAAM,UAAY,iBAClB,IAAM,EAAO,SAAS,cAAc,OAAO,CAC3C,EAAK,aAAa,cAAe,OAAO,CACxC,EAAK,YAAc,IACnB,EAAM,OAAO,EAAM,OAAQ,8BAA8B,CAAE,EAAM,EAAM,KAAM,4BAA4B,CAAC,CAC1G,EAAI,YAAY,EAAM,CAOxB,OALA,EAAI,iBAAiB,aAAgB,CACnC,EAAU,GAAK,EAAI,QACnB,IAAK,IAAM,KAAS,EAAQ,EAAM,SAAW,CAAC,EAAI,QAClD,GAAQ,EACR,CACK,EAGT,SAAS,GAA0B,CACjC,IAAM,EAAK,SAAS,cAAc,MAAM,CAExC,MADA,GAAG,UAAY,uBACR,EAGT,SAAS,EAAK,EAA8B,CAC1C,IAAM,EAAK,SAAS,cAAc,MAAM,CAGxC,MAFA,GAAG,UAAY,qBACf,EAAG,YAAc,EACV"}
1
+ {"version":3,"file":"indicatorSettingsTabs-B0liE3ST.cjs","names":[],"sources":["../src/widget/indicatorSettingsTabs.ts"],"sourcesContent":["import type { IndicatorIntervals, IndicatorPlot, IndicatorPlotStyle, IntervalUnit, LineStyle } from '@tradecanvas/commons';\nimport { INTERVAL_LIMITS, INTERVAL_UNITS } from '@tradecanvas/core';\nimport { createIcon } from './icons.js';\nimport { colorInput, numberInput, selectInput, settingsRow } from './settingsControls.js';\nimport type { MessageKey, Translator } from './i18n.js';\n\nconst LINE_WIDTHS = [1, 1.5, 2, 3, 4];\nconst LINE_STYLES: readonly LineStyle[] = ['solid', 'dashed', 'dotted'];\n/** A line's colour where the indicator gives none (a colour field needs one; not a token, which it can't read). */\nconst FALLBACK_COLOR = '#4c8dff';\n/** A new level sits this far above the last one. */\nconst LEVEL_STEP = 10;\n\nconst UNIT_LABELS: Record<IntervalUnit, MessageKey> = {\n ticks: 'toolbar.timeframes.ticks',\n seconds: 'toolbar.timeframes.seconds',\n minutes: 'toolbar.timeframes.minutes',\n hours: 'toolbar.timeframes.hours',\n days: 'toolbar.timeframes.days',\n weeks: 'toolbar.timeframes.weeks',\n months: 'toolbar.timeframes.months',\n};\n\n/** What the Style tab shows. */\nexport interface StyleTabState {\n plots: readonly IndicatorPlot[];\n colors: readonly string[];\n plotStyles: Readonly<Record<string, IndicatorPlotStyle>>;\n lineWidth: number;\n /** The price scale of a price-pane overlay; unset for the rest. */\n scale?: 'right' | 'left';\n /** Its levels; unset: it has none to edit. */\n levels?: readonly number[];\n}\n\n/** What the Style tab changes. */\nexport interface StyleTabActions {\n color(index: number, value: string): void;\n plot(key: string, patch: IndicatorPlotStyle): void;\n lineWidth(width: number): void;\n scale?(scale: 'right' | 'left'): void;\n levels?(levels: number[]): void;\n}\n\n/**\n * The Style tab: a row per line (shown or not, its colours, its dash), the\n * line width, the price scale of an overlay, and the levels under them.\n */\nexport function renderStyleTab(body: HTMLElement, state: StyleTabState, actions: StyleTabActions, t: Translator, uid: number): void {\n const lines = section();\n // In the order of their colours: a two-tone plot's up and down sit together.\n for (const plot of [...state.plots].sort((a, b) => a.color - b.color)) lines.appendChild(plotRow(plot, state, actions, t));\n const width = selectInput(LINE_WIDTHS.map((w) => ({ value: String(w), label: `${w} px` })), String(state.lineWidth), (v) => actions.lineWidth(Number(v)));\n width.dataset.role = 'line-width';\n lines.appendChild(settingsRow(t('indicatorSettings.lineWidth'), width));\n if (state.scale && actions.scale) {\n const scale = selectInput([\n { value: 'right', label: t('indicatorSettings.scale.right') },\n { value: 'left', label: t('indicatorSettings.scale.left') },\n ], state.scale, (v) => actions.scale?.(v === 'left' ? 'left' : 'right'));\n scale.dataset.role = 'scale';\n lines.appendChild(settingsRow(t('indicatorSettings.scale'), scale));\n }\n body.appendChild(lines);\n if (state.levels && actions.levels) body.appendChild(levelsSection([...state.levels], actions.levels, t, uid));\n}\n\nfunction plotRow(plot: IndicatorPlot, state: StyleTabState, actions: StyleTabActions, t: Translator): HTMLDivElement {\n const own = state.plotStyles[plot.key] ?? {};\n const row = document.createElement('div');\n row.className = 'tcw-settings-row tcw-indi-plot';\n row.dataset.plot = plot.key;\n const name = document.createElement('label');\n name.className = 'tcw-indi-plot-name';\n const shown = document.createElement('input');\n shown.type = 'checkbox';\n shown.checked = own.visible !== false;\n shown.addEventListener('change', () => actions.plot(plot.key, { visible: shown.checked }));\n const text = document.createElement('span');\n text.className = 'tcw-settings-label';\n text.textContent = plot.title;\n name.append(shown, text);\n\n const controls = document.createElement('span');\n controls.className = 'tcw-indi-plot-controls';\n const swatch = (index: number, label: string) => {\n const input = colorInput(state.colors[index] ?? state.colors[0] ?? FALLBACK_COLOR, (v) => actions.color(index, v));\n input.setAttribute('aria-label', label);\n return input;\n };\n const twoTone = plot.tone !== undefined && plot.downColor !== undefined;\n if (twoTone) {\n controls.append(\n swatch(plot.color, `${plot.title} ${t('indicatorSettings.up')}`),\n swatch(plot.downColor!, `${plot.title} ${t('indicatorSettings.down')}`),\n );\n } else {\n controls.appendChild(swatch(plot.color, plot.title));\n }\n // Bars and dots have no dash.\n if ((plot.kind ?? 'line') === 'line' || plot.kind === 'step') {\n const dash = selectInput(\n LINE_STYLES.map((s) => ({ value: s, label: t(`drawingSettings.lineStyle.${s}`) })),\n own.lineStyle ?? plot.lineStyle ?? 'solid',\n (v) => actions.plot(plot.key, { lineStyle: v as LineStyle }),\n );\n dash.setAttribute('aria-label', `${plot.title}: ${t('drawingSettings.lineStyle')}`);\n controls.appendChild(dash);\n }\n row.append(name, controls);\n return row;\n}\n\n/** The levels, each with its remove button, and Add; it redraws itself and keeps the keyboard nearby. */\nfunction levelsSection(start: number[], onChange: (levels: number[]) => void, t: Translator, uid: number): HTMLElement {\n const block = section();\n let levels = start;\n const draw = () => {\n const title = document.createElement('div');\n title.className = 'tcw-settings-section-title';\n title.textContent = t('indicatorSettings.tab.levels');\n const rows = levels.map((level, i) => levelRow(level, i));\n const add = document.createElement('button');\n add.type = 'button';\n add.className = 'tcw-reset-link tcw-indi-add';\n add.textContent = `+ ${t('indicatorSettings.addLevel')}`;\n add.addEventListener('click', () => {\n const last = levels[levels.length - 1];\n set([...levels, last === undefined ? 0 : last + LEVEL_STEP]);\n const inputs = block.querySelectorAll<HTMLInputElement>('.tcw-indi-level input');\n inputs[inputs.length - 1]?.focus();\n });\n block.replaceChildren(title, ...(levels.length === 0 ? [note(t('indicatorSettings.noLevels'))] : rows), add);\n };\n const set = (next: number[]) => {\n levels = next;\n onChange([...next]);\n draw();\n };\n const levelRow = (level: number, i: number): HTMLElement => {\n const input = numberInput(level, { step: 'any' }, (n) => {\n levels = levels.map((v, j) => (j === i ? n : v));\n onChange([...levels]);\n });\n input.id = `tcw-indi-level-${uid}-${i}`;\n const remove = document.createElement('button');\n remove.type = 'button';\n remove.className = 'tcw-indi-remove';\n remove.innerHTML = createIcon('x', 12);\n const label = t('indicatorSettings.removeLevel');\n remove.title = label;\n remove.setAttribute('aria-label', `${label} ${i + 1}`);\n remove.addEventListener('click', () => {\n set(levels.filter((_, j) => j !== i));\n (block.querySelectorAll<HTMLElement>('.tcw-indi-remove')[i] ?? block.querySelector<HTMLElement>('.tcw-indi-add'))?.focus();\n });\n const controls = document.createElement('span');\n controls.className = 'tcw-indi-level';\n controls.append(input, remove);\n const row = document.createElement('div');\n row.className = 'tcw-settings-row';\n const text = document.createElement('label');\n text.className = 'tcw-settings-label';\n text.htmlFor = input.id;\n text.textContent = `${t('indicatorSettings.level')} ${i + 1}`;\n row.append(text, controls);\n return row;\n };\n draw();\n return block;\n}\n\n/** One kind of interval as the Visibility tab edits it: shown at all, and from which count to which. */\ninterface UnitState {\n on: boolean;\n from: number;\n to: number;\n}\n\n/**\n * The Visibility tab: a row per kind of interval, ticked where the indicator\n * shows, with the range of counts it shows on (ticks: on or off).\n */\nexport function renderVisibilityTab(body: HTMLElement, start: IndicatorIntervals | null, onChange: (intervals: IndicatorIntervals | null) => void, t: Translator): void {\n const state = new Map<IntervalUnit, UnitState>(INTERVAL_UNITS.map((unit) => {\n const rule = start?.[unit];\n const range = Array.isArray(rule) ? rule : [1, INTERVAL_LIMITS[unit]];\n return [unit, { on: rule !== false, from: range[0], to: range[1] }];\n }));\n const commit = () => {\n const rules: { -readonly [U in IntervalUnit]?: false | readonly [number, number] } = {};\n for (const [unit, { on, from, to }] of state) {\n const [lo, hi] = [Math.min(from, to), Math.max(from, to)];\n if (!on) rules[unit] = false;\n else if (lo > 1 || hi < INTERVAL_LIMITS[unit]) rules[unit] = [lo, hi];\n }\n onChange(Object.keys(rules).length > 0 ? rules : null);\n };\n const block = section();\n for (const unit of INTERVAL_UNITS) block.appendChild(unitRow(unit, state.get(unit)!, commit, t));\n body.appendChild(block);\n}\n\nfunction unitRow(unit: IntervalUnit, unitState: UnitState, commit: () => void, t: Translator): HTMLDivElement {\n const row = document.createElement('div');\n row.className = 'tcw-settings-row tcw-indi-unit';\n row.dataset.unit = unit;\n const name = document.createElement('label');\n name.className = 'tcw-indi-plot-name';\n const box = document.createElement('input');\n box.type = 'checkbox';\n box.checked = unitState.on;\n const text = document.createElement('span');\n text.className = 'tcw-settings-label';\n text.textContent = t(UNIT_LABELS[unit]);\n name.append(box, text);\n row.appendChild(name);\n const fields: HTMLInputElement[] = [];\n if (unit !== 'ticks') {\n const field = (key: 'from' | 'to', label: MessageKey) => {\n const input: HTMLInputElement = numberInput(unitState[key], { min: 1, max: INTERVAL_LIMITS[unit], step: 1 }, (n) => {\n // A count of intervals is whole: 2.5 hours reads 3.\n unitState[key] = Math.round(n);\n input.value = String(unitState[key]);\n commit();\n });\n input.setAttribute('aria-label', `${t(UNIT_LABELS[unit])}: ${t(label)}`);\n input.disabled = !unitState.on;\n fields.push(input);\n return input;\n };\n const range = document.createElement('span');\n range.className = 'tcw-indi-range';\n const dash = document.createElement('span');\n dash.setAttribute('aria-hidden', 'true');\n dash.textContent = '–';\n range.append(field('from', 'indicatorSettings.rangeFrom'), dash, field('to', 'indicatorSettings.rangeTo'));\n row.appendChild(range);\n }\n box.addEventListener('change', () => {\n unitState.on = box.checked;\n for (const input of fields) input.disabled = !box.checked;\n commit();\n });\n return row;\n}\n\nfunction section(): HTMLDivElement {\n const el = document.createElement('div');\n el.className = 'tcw-settings-section';\n return el;\n}\n\nfunction note(text: string): HTMLDivElement {\n const el = document.createElement('div');\n el.className = 'tcw-settings-label';\n el.textContent = text;\n return el;\n}\n"],"mappings":"4HAMA,IAAM,EAAc,CAAC,EAAG,IAAK,EAAG,EAAG,EAAE,CAC/B,EAAoC,CAAC,QAAS,SAAU,SAAS,CAEjE,EAAiB,UAEjB,EAAa,GAEb,EAAgD,CACpD,MAAO,2BACP,QAAS,6BACT,QAAS,6BACT,MAAO,2BACP,KAAM,0BACN,MAAO,2BACP,OAAQ,4BACT,CA2BD,SAAgB,EAAe,EAAmB,EAAsB,EAA0B,EAAe,EAAmB,CAClI,IAAM,EAAQ,GAAS,CAEvB,IAAK,IAAM,IAAQ,CAAC,GAAG,EAAM,MAAM,CAAC,MAAM,EAAG,IAAM,EAAE,MAAQ,EAAE,MAAM,CAAE,EAAM,YAAY,EAAQ,EAAM,EAAO,EAAS,EAAE,CAAC,CAC1H,IAAM,EAAQ,EAAA,EAAY,EAAY,IAAK,IAAO,CAAE,MAAO,OAAO,EAAE,CAAE,MAAO,GAAG,EAAE,KAAM,EAAE,CAAE,OAAO,EAAM,UAAU,CAAG,GAAM,EAAQ,UAAU,OAAO,EAAE,CAAC,CAAC,CAGzJ,GAFA,EAAM,QAAQ,KAAO,aACrB,EAAM,YAAY,EAAA,EAAY,EAAE,8BAA8B,CAAE,EAAM,CAAC,CACnE,EAAM,OAAS,EAAQ,MAAO,CAChC,IAAM,EAAQ,EAAA,EAAY,CACxB,CAAE,MAAO,QAAS,MAAO,EAAE,gCAAgC,CAAE,CAC7D,CAAE,MAAO,OAAQ,MAAO,EAAE,+BAA+B,CAAE,CAC5D,CAAE,EAAM,MAAQ,GAAM,EAAQ,QAAQ,IAAM,OAAS,OAAS,QAAQ,CAAC,CACxE,EAAM,QAAQ,KAAO,QACrB,EAAM,YAAY,EAAA,EAAY,EAAE,0BAA0B,CAAE,EAAM,CAAC,CAErE,EAAK,YAAY,EAAM,CACnB,EAAM,QAAU,EAAQ,QAAQ,EAAK,YAAY,EAAc,CAAC,GAAG,EAAM,OAAO,CAAE,EAAQ,OAAQ,EAAG,EAAI,CAAC,CAGhH,SAAS,EAAQ,EAAqB,EAAsB,EAA0B,EAA+B,CACnH,IAAM,EAAM,EAAM,WAAW,EAAK,MAAQ,EAAE,CACtC,EAAM,SAAS,cAAc,MAAM,CACzC,EAAI,UAAY,iCAChB,EAAI,QAAQ,KAAO,EAAK,IACxB,IAAM,EAAO,SAAS,cAAc,QAAQ,CAC5C,EAAK,UAAY,qBACjB,IAAM,EAAQ,SAAS,cAAc,QAAQ,CAC7C,EAAM,KAAO,WACb,EAAM,QAAU,EAAI,UAAY,GAChC,EAAM,iBAAiB,aAAgB,EAAQ,KAAK,EAAK,IAAK,CAAE,QAAS,EAAM,QAAS,CAAC,CAAC,CAC1F,IAAM,EAAO,SAAS,cAAc,OAAO,CAC3C,EAAK,UAAY,qBACjB,EAAK,YAAc,EAAK,MACxB,EAAK,OAAO,EAAO,EAAK,CAExB,IAAM,EAAW,SAAS,cAAc,OAAO,CAC/C,EAAS,UAAY,yBACrB,IAAM,GAAU,EAAe,IAAkB,CAC/C,IAAM,EAAQ,EAAA,EAAW,EAAM,OAAO,IAAU,EAAM,OAAO,IAAM,EAAiB,GAAM,EAAQ,MAAM,EAAO,EAAE,CAAC,CAElH,OADA,EAAM,aAAa,aAAc,EAAM,CAChC,GAYT,GAVgB,EAAK,OAAS,IAAA,IAAa,EAAK,YAAc,IAAA,GAE5D,EAAS,OACP,EAAO,EAAK,MAAO,GAAG,EAAK,MAAM,GAAG,EAAE,uBAAuB,GAAG,CAChE,EAAO,EAAK,UAAY,GAAG,EAAK,MAAM,GAAG,EAAE,yBAAyB,GAAG,CACxE,CAED,EAAS,YAAY,EAAO,EAAK,MAAO,EAAK,MAAM,CAAC,EAGjD,EAAK,MAAQ,UAAY,QAAU,EAAK,OAAS,OAAQ,CAC5D,IAAM,EAAO,EAAA,EACX,EAAY,IAAK,IAAO,CAAE,MAAO,EAAG,MAAO,EAAE,6BAA6B,IAAI,CAAE,EAAE,CAClF,EAAI,WAAa,EAAK,WAAa,QAClC,GAAM,EAAQ,KAAK,EAAK,IAAK,CAAE,UAAW,EAAgB,CAAC,CAC7D,CACD,EAAK,aAAa,aAAc,GAAG,EAAK,MAAM,IAAI,EAAE,4BAA4B,GAAG,CACnF,EAAS,YAAY,EAAK,CAG5B,OADA,EAAI,OAAO,EAAM,EAAS,CACnB,EAIT,SAAS,EAAc,EAAiB,EAAsC,EAAe,EAA0B,CACrH,IAAM,EAAQ,GAAS,CACnB,EAAS,EACP,MAAa,CACjB,IAAM,EAAQ,SAAS,cAAc,MAAM,CAC3C,EAAM,UAAY,6BAClB,EAAM,YAAc,EAAE,+BAA+B,CACrD,IAAM,EAAO,EAAO,KAAK,EAAO,IAAM,EAAS,EAAO,EAAE,CAAC,CACnD,EAAM,SAAS,cAAc,SAAS,CAC5C,EAAI,KAAO,SACX,EAAI,UAAY,8BAChB,EAAI,YAAc,KAAK,EAAE,6BAA6B,GACtD,EAAI,iBAAiB,YAAe,CAClC,IAAM,EAAO,EAAO,EAAO,OAAS,GACpC,EAAI,CAAC,GAAG,EAAQ,IAAS,IAAA,GAAY,EAAI,EAAO,EAAW,CAAC,CAC5D,IAAM,EAAS,EAAM,iBAAmC,wBAAwB,CAChF,EAAO,EAAO,OAAS,IAAI,OAAO,EAClC,CACF,EAAM,gBAAgB,EAAO,GAAI,EAAO,SAAW,EAAI,CAAC,EAAK,EAAE,6BAA6B,CAAC,CAAC,CAAG,EAAO,EAAI,EAExG,EAAO,GAAmB,CAC9B,EAAS,EACT,EAAS,CAAC,GAAG,EAAK,CAAC,CACnB,GAAM,EAEF,GAAY,EAAe,IAA2B,CAC1D,IAAM,EAAQ,EAAA,EAAY,EAAO,CAAE,KAAM,MAAO,CAAG,GAAM,CACvD,EAAS,EAAO,KAAK,EAAG,IAAO,IAAM,EAAI,EAAI,EAAG,CAChD,EAAS,CAAC,GAAG,EAAO,CAAC,EACrB,CACF,EAAM,GAAK,kBAAkB,EAAI,GAAG,IACpC,IAAM,EAAS,SAAS,cAAc,SAAS,CAC/C,EAAO,KAAO,SACd,EAAO,UAAY,kBACnB,EAAO,UAAY,EAAA,EAAW,IAAK,GAAG,CACtC,IAAM,EAAQ,EAAE,gCAAgC,CAChD,EAAO,MAAQ,EACf,EAAO,aAAa,aAAc,GAAG,EAAM,GAAG,EAAI,IAAI,CACtD,EAAO,iBAAiB,YAAe,CACrC,EAAI,EAAO,QAAQ,EAAG,IAAM,IAAM,EAAE,CAAC,EACpC,EAAM,iBAA8B,mBAAmB,CAAC,IAAM,EAAM,cAA2B,gBAAgB,GAAG,OAAO,EAC1H,CACF,IAAM,EAAW,SAAS,cAAc,OAAO,CAC/C,EAAS,UAAY,iBACrB,EAAS,OAAO,EAAO,EAAO,CAC9B,IAAM,EAAM,SAAS,cAAc,MAAM,CACzC,EAAI,UAAY,mBAChB,IAAM,EAAO,SAAS,cAAc,QAAQ,CAK5C,MAJA,GAAK,UAAY,qBACjB,EAAK,QAAU,EAAM,GACrB,EAAK,YAAc,GAAG,EAAE,0BAA0B,CAAC,GAAG,EAAI,IAC1D,EAAI,OAAO,EAAM,EAAS,CACnB,GAGT,OADA,GAAM,CACC,EAcT,SAAgB,EAAoB,EAAmB,EAAkC,EAA0D,EAAqB,CACtK,IAAM,EAAQ,IAAI,IAA6B,EAAA,eAAe,IAAK,GAAS,CAC1E,IAAM,EAAO,IAAQ,GACf,EAAQ,MAAM,QAAQ,EAAK,CAAG,EAAO,CAAC,EAAG,EAAA,gBAAgB,GAAM,CACrE,MAAO,CAAC,EAAM,CAAE,GAAI,IAAS,GAAO,KAAM,EAAM,GAAI,GAAI,EAAM,GAAI,CAAC,EACnE,CAAC,CACG,MAAe,CACnB,IAAM,EAA+E,EAAE,CACvF,IAAK,GAAM,CAAC,EAAM,CAAE,KAAI,OAAM,SAAS,EAAO,CAC5C,GAAM,CAAC,EAAI,GAAM,CAAC,KAAK,IAAI,EAAM,EAAG,CAAE,KAAK,IAAI,EAAM,EAAG,CAAC,CACpD,GACI,EAAK,GAAK,EAAK,EAAA,gBAAgB,MAAO,EAAM,GAAQ,CAAC,EAAI,EAAG,EAD5D,EAAM,GAAQ,GAGzB,EAAS,OAAO,KAAK,EAAM,CAAC,OAAS,EAAI,EAAQ,KAAK,EAElD,EAAQ,GAAS,CACvB,IAAK,IAAM,KAAQ,EAAA,eAAgB,EAAM,YAAY,EAAQ,EAAM,EAAM,IAAI,EAAK,CAAG,EAAQ,EAAE,CAAC,CAChG,EAAK,YAAY,EAAM,CAGzB,SAAS,EAAQ,EAAoB,EAAsB,EAAoB,EAA+B,CAC5G,IAAM,EAAM,SAAS,cAAc,MAAM,CACzC,EAAI,UAAY,iCAChB,EAAI,QAAQ,KAAO,EACnB,IAAM,EAAO,SAAS,cAAc,QAAQ,CAC5C,EAAK,UAAY,qBACjB,IAAM,EAAM,SAAS,cAAc,QAAQ,CAC3C,EAAI,KAAO,WACX,EAAI,QAAU,EAAU,GACxB,IAAM,EAAO,SAAS,cAAc,OAAO,CAC3C,EAAK,UAAY,qBACjB,EAAK,YAAc,EAAE,EAAY,GAAM,CACvC,EAAK,OAAO,EAAK,EAAK,CACtB,EAAI,YAAY,EAAK,CACrB,IAAM,EAA6B,EAAE,CACrC,GAAI,IAAS,QAAS,CACpB,IAAM,GAAS,EAAoB,IAAsB,CACvD,IAAM,EAA0B,EAAA,EAAY,EAAU,GAAM,CAAE,IAAK,EAAG,IAAK,EAAA,gBAAgB,GAAO,KAAM,EAAG,CAAG,GAAM,CAElH,EAAU,GAAO,KAAK,MAAM,EAAE,CAC9B,EAAM,MAAQ,OAAO,EAAU,GAAK,CACpC,GAAQ,EACR,CAIF,OAHA,EAAM,aAAa,aAAc,GAAG,EAAE,EAAY,GAAM,CAAC,IAAI,EAAE,EAAM,GAAG,CACxE,EAAM,SAAW,CAAC,EAAU,GAC5B,EAAO,KAAK,EAAM,CACX,GAEH,EAAQ,SAAS,cAAc,OAAO,CAC5C,EAAM,UAAY,iBAClB,IAAM,EAAO,SAAS,cAAc,OAAO,CAC3C,EAAK,aAAa,cAAe,OAAO,CACxC,EAAK,YAAc,IACnB,EAAM,OAAO,EAAM,OAAQ,8BAA8B,CAAE,EAAM,EAAM,KAAM,4BAA4B,CAAC,CAC1G,EAAI,YAAY,EAAM,CAOxB,OALA,EAAI,iBAAiB,aAAgB,CACnC,EAAU,GAAK,EAAI,QACnB,IAAK,IAAM,KAAS,EAAQ,EAAM,SAAW,CAAC,EAAI,QAClD,GAAQ,EACR,CACK,EAGT,SAAS,GAA0B,CACjC,IAAM,EAAK,SAAS,cAAc,MAAM,CAExC,MADA,GAAG,UAAY,uBACR,EAGT,SAAS,EAAK,EAA8B,CAC1C,IAAM,EAAK,SAAS,cAAc,MAAM,CAGxC,MAFA,GAAG,UAAY,qBACf,EAAG,YAAc,EACV"}
@@ -1,5 +1,5 @@
1
- import { i as e } from "./focusTrap-Hm7AUTBw.js";
2
- import { i as t, o as n, r, s as i } from "./settingsControls-ef4j_clQ.js";
1
+ import { i as e } from "./focusTrap-Br9Zfje0.js";
2
+ import { i as t, o as n, r, s as i } from "./settingsControls-DIjzCFHI.js";
3
3
  import { INTERVAL_LIMITS as a, INTERVAL_UNITS as o } from "@tradecanvas/core";
4
4
  //#region src/widget/indicatorSettingsTabs.ts
5
5
  var s = [
@@ -158,4 +158,4 @@ function v(e) {
158
158
  //#endregion
159
159
  export { h as n, f as t };
160
160
 
161
- //# sourceMappingURL=indicatorSettingsTabs-Wxx2v_y4.js.map
161
+ //# sourceMappingURL=indicatorSettingsTabs-XcgMdbLp.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"indicatorSettingsTabs-Wxx2v_y4.js","names":[],"sources":["../src/widget/indicatorSettingsTabs.ts"],"sourcesContent":["import type { IndicatorIntervals, IndicatorPlot, IndicatorPlotStyle, IntervalUnit, LineStyle } from '@tradecanvas/commons';\nimport { INTERVAL_LIMITS, INTERVAL_UNITS } from '@tradecanvas/core';\nimport { createIcon } from './icons.js';\nimport { colorInput, numberInput, selectInput, settingsRow } from './settingsControls.js';\nimport type { MessageKey, Translator } from './i18n.js';\n\nconst LINE_WIDTHS = [1, 1.5, 2, 3, 4];\nconst LINE_STYLES: readonly LineStyle[] = ['solid', 'dashed', 'dotted'];\n/** A line's colour where the indicator gives none (a colour field needs one; not a token, which it can't read). */\nconst FALLBACK_COLOR = '#4c8dff';\n/** A new level sits this far above the last one. */\nconst LEVEL_STEP = 10;\n\nconst UNIT_LABELS: Record<IntervalUnit, MessageKey> = {\n ticks: 'toolbar.timeframes.ticks',\n seconds: 'toolbar.timeframes.seconds',\n minutes: 'toolbar.timeframes.minutes',\n hours: 'toolbar.timeframes.hours',\n days: 'toolbar.timeframes.days',\n weeks: 'toolbar.timeframes.weeks',\n months: 'toolbar.timeframes.months',\n};\n\n/** What the Style tab shows. */\nexport interface StyleTabState {\n plots: readonly IndicatorPlot[];\n colors: readonly string[];\n plotStyles: Readonly<Record<string, IndicatorPlotStyle>>;\n lineWidth: number;\n /** The price scale of a price-pane overlay; unset for the rest. */\n scale?: 'right' | 'left';\n /** Its levels; unset: it has none to edit. */\n levels?: readonly number[];\n}\n\n/** What the Style tab changes. */\nexport interface StyleTabActions {\n color(index: number, value: string): void;\n plot(key: string, patch: IndicatorPlotStyle): void;\n lineWidth(width: number): void;\n scale?(scale: 'right' | 'left'): void;\n levels?(levels: number[]): void;\n}\n\n/**\n * The Style tab: a row per line (shown or not, its colours, its dash), the\n * line width, the price scale of an overlay, and the levels under them.\n */\nexport function renderStyleTab(body: HTMLElement, state: StyleTabState, actions: StyleTabActions, t: Translator, uid: number): void {\n const lines = section();\n // In the order of their colours: a two-tone plot's up and down sit together.\n for (const plot of [...state.plots].sort((a, b) => a.color - b.color)) lines.appendChild(plotRow(plot, state, actions, t));\n const width = selectInput(LINE_WIDTHS.map((w) => ({ value: String(w), label: `${w} px` })), String(state.lineWidth), (v) => actions.lineWidth(Number(v)));\n width.dataset.role = 'line-width';\n lines.appendChild(settingsRow(t('indicatorSettings.lineWidth'), width));\n if (state.scale && actions.scale) {\n const scale = selectInput([\n { value: 'right', label: t('indicatorSettings.scale.right') },\n { value: 'left', label: t('indicatorSettings.scale.left') },\n ], state.scale, (v) => actions.scale?.(v === 'left' ? 'left' : 'right'));\n scale.dataset.role = 'scale';\n lines.appendChild(settingsRow(t('indicatorSettings.scale'), scale));\n }\n body.appendChild(lines);\n if (state.levels && actions.levels) body.appendChild(levelsSection([...state.levels], actions.levels, t, uid));\n}\n\nfunction plotRow(plot: IndicatorPlot, state: StyleTabState, actions: StyleTabActions, t: Translator): HTMLDivElement {\n const own = state.plotStyles[plot.key] ?? {};\n const row = document.createElement('div');\n row.className = 'tcw-settings-row tcw-indi-plot';\n row.dataset.plot = plot.key;\n const name = document.createElement('label');\n name.className = 'tcw-indi-plot-name';\n const shown = document.createElement('input');\n shown.type = 'checkbox';\n shown.checked = own.visible !== false;\n shown.addEventListener('change', () => actions.plot(plot.key, { visible: shown.checked }));\n const text = document.createElement('span');\n text.className = 'tcw-settings-label';\n text.textContent = plot.title;\n name.append(shown, text);\n\n const controls = document.createElement('span');\n controls.className = 'tcw-indi-plot-controls';\n const swatch = (index: number, label: string) => {\n const input = colorInput(state.colors[index] ?? state.colors[0] ?? FALLBACK_COLOR, (v) => actions.color(index, v));\n input.setAttribute('aria-label', label);\n return input;\n };\n const twoTone = plot.tone !== undefined && plot.downColor !== undefined;\n if (twoTone) {\n controls.append(\n swatch(plot.color, `${plot.title} ${t('indicatorSettings.up')}`),\n swatch(plot.downColor!, `${plot.title} ${t('indicatorSettings.down')}`),\n );\n } else {\n controls.appendChild(swatch(plot.color, plot.title));\n }\n // Bars and dots have no dash.\n if ((plot.kind ?? 'line') === 'line' || plot.kind === 'step') {\n const dash = selectInput(\n LINE_STYLES.map((s) => ({ value: s, label: t(`drawingSettings.lineStyle.${s}`) })),\n own.lineStyle ?? plot.lineStyle ?? 'solid',\n (v) => actions.plot(plot.key, { lineStyle: v as LineStyle }),\n );\n dash.setAttribute('aria-label', `${plot.title}: ${t('drawingSettings.lineStyle')}`);\n controls.appendChild(dash);\n }\n row.append(name, controls);\n return row;\n}\n\n/** The levels, each with its remove button, and Add; it redraws itself and keeps the keyboard nearby. */\nfunction levelsSection(start: number[], onChange: (levels: number[]) => void, t: Translator, uid: number): HTMLElement {\n const block = section();\n let levels = start;\n const draw = () => {\n const title = document.createElement('div');\n title.className = 'tcw-settings-section-title';\n title.textContent = t('indicatorSettings.tab.levels');\n const rows = levels.map((level, i) => levelRow(level, i));\n const add = document.createElement('button');\n add.type = 'button';\n add.className = 'tcw-reset-link tcw-indi-add';\n add.textContent = `+ ${t('indicatorSettings.addLevel')}`;\n add.addEventListener('click', () => {\n const last = levels[levels.length - 1];\n set([...levels, last === undefined ? 0 : last + LEVEL_STEP]);\n const inputs = block.querySelectorAll<HTMLInputElement>('.tcw-indi-level input');\n inputs[inputs.length - 1]?.focus();\n });\n block.replaceChildren(title, ...(levels.length === 0 ? [note(t('indicatorSettings.noLevels'))] : rows), add);\n };\n const set = (next: number[]) => {\n levels = next;\n onChange([...next]);\n draw();\n };\n const levelRow = (level: number, i: number): HTMLElement => {\n const input = numberInput(level, { step: 'any' }, (n) => {\n levels = levels.map((v, j) => (j === i ? n : v));\n onChange([...levels]);\n });\n input.id = `tcw-indi-level-${uid}-${i}`;\n const remove = document.createElement('button');\n remove.type = 'button';\n remove.className = 'tcw-indi-remove';\n remove.innerHTML = createIcon('x', 12);\n const label = t('indicatorSettings.removeLevel');\n remove.title = label;\n remove.setAttribute('aria-label', `${label} ${i + 1}`);\n remove.addEventListener('click', () => {\n set(levels.filter((_, j) => j !== i));\n (block.querySelectorAll<HTMLElement>('.tcw-indi-remove')[i] ?? block.querySelector<HTMLElement>('.tcw-indi-add'))?.focus();\n });\n const controls = document.createElement('span');\n controls.className = 'tcw-indi-level';\n controls.append(input, remove);\n const row = document.createElement('div');\n row.className = 'tcw-settings-row';\n const text = document.createElement('label');\n text.className = 'tcw-settings-label';\n text.htmlFor = input.id;\n text.textContent = `${t('indicatorSettings.level')} ${i + 1}`;\n row.append(text, controls);\n return row;\n };\n draw();\n return block;\n}\n\n/** One kind of interval as the Visibility tab edits it: shown at all, and from which count to which. */\ninterface UnitState {\n on: boolean;\n from: number;\n to: number;\n}\n\n/**\n * The Visibility tab: a row per kind of interval, ticked where the indicator\n * shows, with the range of counts it shows on (ticks: on or off).\n */\nexport function renderVisibilityTab(body: HTMLElement, start: IndicatorIntervals | null, onChange: (intervals: IndicatorIntervals | null) => void, t: Translator): void {\n const state = new Map<IntervalUnit, UnitState>(INTERVAL_UNITS.map((unit) => {\n const rule = start?.[unit];\n const range = Array.isArray(rule) ? rule : [1, INTERVAL_LIMITS[unit]];\n return [unit, { on: rule !== false, from: range[0], to: range[1] }];\n }));\n const commit = () => {\n const rules: { -readonly [U in IntervalUnit]?: false | readonly [number, number] } = {};\n for (const [unit, { on, from, to }] of state) {\n const [lo, hi] = [Math.min(from, to), Math.max(from, to)];\n if (!on) rules[unit] = false;\n else if (lo > 1 || hi < INTERVAL_LIMITS[unit]) rules[unit] = [lo, hi];\n }\n onChange(Object.keys(rules).length > 0 ? rules : null);\n };\n const block = section();\n for (const unit of INTERVAL_UNITS) block.appendChild(unitRow(unit, state.get(unit)!, commit, t));\n body.appendChild(block);\n}\n\nfunction unitRow(unit: IntervalUnit, unitState: UnitState, commit: () => void, t: Translator): HTMLDivElement {\n const row = document.createElement('div');\n row.className = 'tcw-settings-row tcw-indi-unit';\n row.dataset.unit = unit;\n const name = document.createElement('label');\n name.className = 'tcw-indi-plot-name';\n const box = document.createElement('input');\n box.type = 'checkbox';\n box.checked = unitState.on;\n const text = document.createElement('span');\n text.className = 'tcw-settings-label';\n text.textContent = t(UNIT_LABELS[unit]);\n name.append(box, text);\n row.appendChild(name);\n const fields: HTMLInputElement[] = [];\n if (unit !== 'ticks') {\n const field = (key: 'from' | 'to', label: MessageKey) => {\n const input: HTMLInputElement = numberInput(unitState[key], { min: 1, max: INTERVAL_LIMITS[unit], step: 1 }, (n) => {\n // A count of intervals is whole: 2.5 hours reads 3.\n unitState[key] = Math.round(n);\n input.value = String(unitState[key]);\n commit();\n });\n input.setAttribute('aria-label', `${t(UNIT_LABELS[unit])}: ${t(label)}`);\n input.disabled = !unitState.on;\n fields.push(input);\n return input;\n };\n const range = document.createElement('span');\n range.className = 'tcw-indi-range';\n const dash = document.createElement('span');\n dash.setAttribute('aria-hidden', 'true');\n dash.textContent = '–';\n range.append(field('from', 'indicatorSettings.rangeFrom'), dash, field('to', 'indicatorSettings.rangeTo'));\n row.appendChild(range);\n }\n box.addEventListener('change', () => {\n unitState.on = box.checked;\n for (const input of fields) input.disabled = !box.checked;\n commit();\n });\n return row;\n}\n\nfunction section(): HTMLDivElement {\n const el = document.createElement('div');\n el.className = 'tcw-settings-section';\n return el;\n}\n\nfunction note(text: string): HTMLDivElement {\n const el = document.createElement('div');\n el.className = 'tcw-settings-label';\n el.textContent = text;\n return el;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"indicatorSettingsTabs-XcgMdbLp.js","names":[],"sources":["../src/widget/indicatorSettingsTabs.ts"],"sourcesContent":["import type { IndicatorIntervals, IndicatorPlot, IndicatorPlotStyle, IntervalUnit, LineStyle } from '@tradecanvas/commons';\nimport { INTERVAL_LIMITS, INTERVAL_UNITS } from '@tradecanvas/core';\nimport { createIcon } from './icons.js';\nimport { colorInput, numberInput, selectInput, settingsRow } from './settingsControls.js';\nimport type { MessageKey, Translator } from './i18n.js';\n\nconst LINE_WIDTHS = [1, 1.5, 2, 3, 4];\nconst LINE_STYLES: readonly LineStyle[] = ['solid', 'dashed', 'dotted'];\n/** A line's colour where the indicator gives none (a colour field needs one; not a token, which it can't read). */\nconst FALLBACK_COLOR = '#4c8dff';\n/** A new level sits this far above the last one. */\nconst LEVEL_STEP = 10;\n\nconst UNIT_LABELS: Record<IntervalUnit, MessageKey> = {\n ticks: 'toolbar.timeframes.ticks',\n seconds: 'toolbar.timeframes.seconds',\n minutes: 'toolbar.timeframes.minutes',\n hours: 'toolbar.timeframes.hours',\n days: 'toolbar.timeframes.days',\n weeks: 'toolbar.timeframes.weeks',\n months: 'toolbar.timeframes.months',\n};\n\n/** What the Style tab shows. */\nexport interface StyleTabState {\n plots: readonly IndicatorPlot[];\n colors: readonly string[];\n plotStyles: Readonly<Record<string, IndicatorPlotStyle>>;\n lineWidth: number;\n /** The price scale of a price-pane overlay; unset for the rest. */\n scale?: 'right' | 'left';\n /** Its levels; unset: it has none to edit. */\n levels?: readonly number[];\n}\n\n/** What the Style tab changes. */\nexport interface StyleTabActions {\n color(index: number, value: string): void;\n plot(key: string, patch: IndicatorPlotStyle): void;\n lineWidth(width: number): void;\n scale?(scale: 'right' | 'left'): void;\n levels?(levels: number[]): void;\n}\n\n/**\n * The Style tab: a row per line (shown or not, its colours, its dash), the\n * line width, the price scale of an overlay, and the levels under them.\n */\nexport function renderStyleTab(body: HTMLElement, state: StyleTabState, actions: StyleTabActions, t: Translator, uid: number): void {\n const lines = section();\n // In the order of their colours: a two-tone plot's up and down sit together.\n for (const plot of [...state.plots].sort((a, b) => a.color - b.color)) lines.appendChild(plotRow(plot, state, actions, t));\n const width = selectInput(LINE_WIDTHS.map((w) => ({ value: String(w), label: `${w} px` })), String(state.lineWidth), (v) => actions.lineWidth(Number(v)));\n width.dataset.role = 'line-width';\n lines.appendChild(settingsRow(t('indicatorSettings.lineWidth'), width));\n if (state.scale && actions.scale) {\n const scale = selectInput([\n { value: 'right', label: t('indicatorSettings.scale.right') },\n { value: 'left', label: t('indicatorSettings.scale.left') },\n ], state.scale, (v) => actions.scale?.(v === 'left' ? 'left' : 'right'));\n scale.dataset.role = 'scale';\n lines.appendChild(settingsRow(t('indicatorSettings.scale'), scale));\n }\n body.appendChild(lines);\n if (state.levels && actions.levels) body.appendChild(levelsSection([...state.levels], actions.levels, t, uid));\n}\n\nfunction plotRow(plot: IndicatorPlot, state: StyleTabState, actions: StyleTabActions, t: Translator): HTMLDivElement {\n const own = state.plotStyles[plot.key] ?? {};\n const row = document.createElement('div');\n row.className = 'tcw-settings-row tcw-indi-plot';\n row.dataset.plot = plot.key;\n const name = document.createElement('label');\n name.className = 'tcw-indi-plot-name';\n const shown = document.createElement('input');\n shown.type = 'checkbox';\n shown.checked = own.visible !== false;\n shown.addEventListener('change', () => actions.plot(plot.key, { visible: shown.checked }));\n const text = document.createElement('span');\n text.className = 'tcw-settings-label';\n text.textContent = plot.title;\n name.append(shown, text);\n\n const controls = document.createElement('span');\n controls.className = 'tcw-indi-plot-controls';\n const swatch = (index: number, label: string) => {\n const input = colorInput(state.colors[index] ?? state.colors[0] ?? FALLBACK_COLOR, (v) => actions.color(index, v));\n input.setAttribute('aria-label', label);\n return input;\n };\n const twoTone = plot.tone !== undefined && plot.downColor !== undefined;\n if (twoTone) {\n controls.append(\n swatch(plot.color, `${plot.title} ${t('indicatorSettings.up')}`),\n swatch(plot.downColor!, `${plot.title} ${t('indicatorSettings.down')}`),\n );\n } else {\n controls.appendChild(swatch(plot.color, plot.title));\n }\n // Bars and dots have no dash.\n if ((plot.kind ?? 'line') === 'line' || plot.kind === 'step') {\n const dash = selectInput(\n LINE_STYLES.map((s) => ({ value: s, label: t(`drawingSettings.lineStyle.${s}`) })),\n own.lineStyle ?? plot.lineStyle ?? 'solid',\n (v) => actions.plot(plot.key, { lineStyle: v as LineStyle }),\n );\n dash.setAttribute('aria-label', `${plot.title}: ${t('drawingSettings.lineStyle')}`);\n controls.appendChild(dash);\n }\n row.append(name, controls);\n return row;\n}\n\n/** The levels, each with its remove button, and Add; it redraws itself and keeps the keyboard nearby. */\nfunction levelsSection(start: number[], onChange: (levels: number[]) => void, t: Translator, uid: number): HTMLElement {\n const block = section();\n let levels = start;\n const draw = () => {\n const title = document.createElement('div');\n title.className = 'tcw-settings-section-title';\n title.textContent = t('indicatorSettings.tab.levels');\n const rows = levels.map((level, i) => levelRow(level, i));\n const add = document.createElement('button');\n add.type = 'button';\n add.className = 'tcw-reset-link tcw-indi-add';\n add.textContent = `+ ${t('indicatorSettings.addLevel')}`;\n add.addEventListener('click', () => {\n const last = levels[levels.length - 1];\n set([...levels, last === undefined ? 0 : last + LEVEL_STEP]);\n const inputs = block.querySelectorAll<HTMLInputElement>('.tcw-indi-level input');\n inputs[inputs.length - 1]?.focus();\n });\n block.replaceChildren(title, ...(levels.length === 0 ? [note(t('indicatorSettings.noLevels'))] : rows), add);\n };\n const set = (next: number[]) => {\n levels = next;\n onChange([...next]);\n draw();\n };\n const levelRow = (level: number, i: number): HTMLElement => {\n const input = numberInput(level, { step: 'any' }, (n) => {\n levels = levels.map((v, j) => (j === i ? n : v));\n onChange([...levels]);\n });\n input.id = `tcw-indi-level-${uid}-${i}`;\n const remove = document.createElement('button');\n remove.type = 'button';\n remove.className = 'tcw-indi-remove';\n remove.innerHTML = createIcon('x', 12);\n const label = t('indicatorSettings.removeLevel');\n remove.title = label;\n remove.setAttribute('aria-label', `${label} ${i + 1}`);\n remove.addEventListener('click', () => {\n set(levels.filter((_, j) => j !== i));\n (block.querySelectorAll<HTMLElement>('.tcw-indi-remove')[i] ?? block.querySelector<HTMLElement>('.tcw-indi-add'))?.focus();\n });\n const controls = document.createElement('span');\n controls.className = 'tcw-indi-level';\n controls.append(input, remove);\n const row = document.createElement('div');\n row.className = 'tcw-settings-row';\n const text = document.createElement('label');\n text.className = 'tcw-settings-label';\n text.htmlFor = input.id;\n text.textContent = `${t('indicatorSettings.level')} ${i + 1}`;\n row.append(text, controls);\n return row;\n };\n draw();\n return block;\n}\n\n/** One kind of interval as the Visibility tab edits it: shown at all, and from which count to which. */\ninterface UnitState {\n on: boolean;\n from: number;\n to: number;\n}\n\n/**\n * The Visibility tab: a row per kind of interval, ticked where the indicator\n * shows, with the range of counts it shows on (ticks: on or off).\n */\nexport function renderVisibilityTab(body: HTMLElement, start: IndicatorIntervals | null, onChange: (intervals: IndicatorIntervals | null) => void, t: Translator): void {\n const state = new Map<IntervalUnit, UnitState>(INTERVAL_UNITS.map((unit) => {\n const rule = start?.[unit];\n const range = Array.isArray(rule) ? rule : [1, INTERVAL_LIMITS[unit]];\n return [unit, { on: rule !== false, from: range[0], to: range[1] }];\n }));\n const commit = () => {\n const rules: { -readonly [U in IntervalUnit]?: false | readonly [number, number] } = {};\n for (const [unit, { on, from, to }] of state) {\n const [lo, hi] = [Math.min(from, to), Math.max(from, to)];\n if (!on) rules[unit] = false;\n else if (lo > 1 || hi < INTERVAL_LIMITS[unit]) rules[unit] = [lo, hi];\n }\n onChange(Object.keys(rules).length > 0 ? rules : null);\n };\n const block = section();\n for (const unit of INTERVAL_UNITS) block.appendChild(unitRow(unit, state.get(unit)!, commit, t));\n body.appendChild(block);\n}\n\nfunction unitRow(unit: IntervalUnit, unitState: UnitState, commit: () => void, t: Translator): HTMLDivElement {\n const row = document.createElement('div');\n row.className = 'tcw-settings-row tcw-indi-unit';\n row.dataset.unit = unit;\n const name = document.createElement('label');\n name.className = 'tcw-indi-plot-name';\n const box = document.createElement('input');\n box.type = 'checkbox';\n box.checked = unitState.on;\n const text = document.createElement('span');\n text.className = 'tcw-settings-label';\n text.textContent = t(UNIT_LABELS[unit]);\n name.append(box, text);\n row.appendChild(name);\n const fields: HTMLInputElement[] = [];\n if (unit !== 'ticks') {\n const field = (key: 'from' | 'to', label: MessageKey) => {\n const input: HTMLInputElement = numberInput(unitState[key], { min: 1, max: INTERVAL_LIMITS[unit], step: 1 }, (n) => {\n // A count of intervals is whole: 2.5 hours reads 3.\n unitState[key] = Math.round(n);\n input.value = String(unitState[key]);\n commit();\n });\n input.setAttribute('aria-label', `${t(UNIT_LABELS[unit])}: ${t(label)}`);\n input.disabled = !unitState.on;\n fields.push(input);\n return input;\n };\n const range = document.createElement('span');\n range.className = 'tcw-indi-range';\n const dash = document.createElement('span');\n dash.setAttribute('aria-hidden', 'true');\n dash.textContent = '–';\n range.append(field('from', 'indicatorSettings.rangeFrom'), dash, field('to', 'indicatorSettings.rangeTo'));\n row.appendChild(range);\n }\n box.addEventListener('change', () => {\n unitState.on = box.checked;\n for (const input of fields) input.disabled = !box.checked;\n commit();\n });\n return row;\n}\n\nfunction section(): HTMLDivElement {\n const el = document.createElement('div');\n el.className = 'tcw-settings-section';\n return el;\n}\n\nfunction note(text: string): HTMLDivElement {\n const el = document.createElement('div');\n el.className = 'tcw-settings-label';\n el.textContent = text;\n return el;\n}\n"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ var e=42,t=7,n=new Set([`US`,`CA`,`MX`,`BR`,`JP`,`KR`,`TW`,`HK`,`IL`,`PH`,`IN`,`ZA`,`AU`,`TH`,`SA`,`PE`,`CO`]);function r(e){try{let t=new Intl.Locale(e),r=t.getWeekInfo?.()??t.weekInfo;return r?r.firstDay===7?0:1:+!n.has(t.maximize().region??``)}catch{return 1}}function i(n,r,i){let a=(new Date(Date.UTC(n,r,1)).getUTCDay()-i+t)%t,o=[];for(let t=0;t<e;t++){let e=new Date(Date.UTC(n,r,1-a+t));o.push({year:e.getUTCFullYear(),month:e.getUTCMonth(),day:e.getUTCDate()})}return o}var a=e=>String(e).padStart(2,`0`),o=e=>`${String(e.year).padStart(4,`0`)}-${a(e.month+1)}-${a(e.day)}`;function s(e){let t=/^(\d{4})-(\d{2})-(\d{2})$/.exec(e??``);return t?{year:Number(t[1]),month:Number(t[2])-1,day:Number(t[3])}:null}function c(){let e=new Date;return{year:e.getFullYear(),month:e.getMonth(),day:e.getDate()}}function l(e,t){let n=new Date(Date.UTC(e.year,e.month,e.day+t));return{year:n.getUTCFullYear(),month:n.getUTCMonth(),day:n.getUTCDate()}}var u=class{element;grid;titleEl;chosen=``;limits={};today=o(c());view={year:0,month:0};focusDay=c();constructor(e,n,i){this.locale=n,this.onPick=i;let a=document.createElement(`div`);a.className=`tcw-calendar`;let o=document.createElement(`div`);o.className=`tcw-calendar-head`;let s=document.createElement(`div`);s.className=`tcw-calendar-title`,s.setAttribute(`aria-live`,`polite`),o.append(this.navButton(e.prevMonth,-1),s,this.navButton(e.nextMonth,1));let c=document.createElement(`div`);c.className=`tcw-calendar-weekdays`,c.setAttribute(`aria-hidden`,`true`);let l=r(n),u=new Intl.DateTimeFormat(n,{weekday:`narrow`,timeZone:`UTC`});for(let e=0;e<t;e++){let n=document.createElement(`span`);n.className=`tcw-calendar-weekday`,n.textContent=u.format(new Date(Date.UTC(2023,0,1+(l+e)%t))),c.appendChild(n)}let d=document.createElement(`div`);d.className=`tcw-calendar-grid`,d.setAttribute(`role`,`grid`),d.addEventListener(`keydown`,e=>this.onKey(e)),d.addEventListener(`click`,e=>{let t=e.target.closest(`.tcw-calendar-day`);t&&!t.disabled&&t.dataset.date&&this.pick(t.dataset.date)});let f=document.createElement(`div`);f.className=`tcw-calendar-foot`;let p=document.createElement(`button`);p.type=`button`,p.className=`tcw-calendar-today`,p.textContent=e.today,p.addEventListener(`click`,()=>this.pick(this.today)),f.appendChild(p),a.append(o,c,d,f),this.element=a,this.grid=d,this.titleEl=s}show(e,t={}){this.chosen=e,this.limits=t,this.today=s(t.today)?t.today:o(c());let n=this.clamp(s(e)??s(this.today));this.focusDay=n,this.view={year:n.year,month:n.month},this.render()}focusGrid(){this.grid.querySelector(`[tabindex="0"]`)?.focus()}navButton(e,t){let n=document.createElement(`button`);return n.type=`button`,n.className=`tcw-calendar-nav`,n.setAttribute(`aria-label`,e),n.innerHTML=t<0?`<svg viewBox="0 0 16 16" aria-hidden="true"><path d="M10 3.5L5.5 8l4.5 4.5"/></svg>`:`<svg viewBox="0 0 16 16" aria-hidden="true"><path d="M6 3.5L10.5 8 6 12.5"/></svg>`,n.addEventListener(`click`,()=>this.turn(t)),n}turn(e){let t=new Date(Date.UTC(this.view.year,this.view.month+e,1));this.view={year:t.getUTCFullYear(),month:t.getUTCMonth()};let n=new Date(Date.UTC(this.view.year,this.view.month+1,0)).getUTCDate();this.focusDay=this.clamp({...this.view,day:Math.min(this.focusDay.day,n)}),this.view={year:this.focusDay.year,month:this.focusDay.month},this.render()}clamp(e){let t=o(e),n=s(this.limits.min),r=s(this.limits.max);return n&&t<o(n)?n:r&&t>o(r)?r:e}allowed(e){let{min:t,max:n}=this.limits;return!(t&&e<t)&&!(n&&e>n)}render(){let e=this.locale;this.titleEl.textContent=new Intl.DateTimeFormat(e,{month:`long`,year:`numeric`,timeZone:`UTC`}).format(new Date(Date.UTC(this.view.year,this.view.month,1)));let n=this.today,a=o(this.focusDay),s=new Intl.DateTimeFormat(e,{dateStyle:`full`,timeZone:`UTC`});this.grid.textContent=``;let c=null;for(let[l,u]of i(this.view.year,this.view.month,r(e)).entries()){l%t===0&&(c=document.createElement(`div`),c.className=`tcw-calendar-week`,c.setAttribute(`role`,`row`),this.grid.appendChild(c));let e=o(u),r=document.createElement(`button`);r.type=`button`,r.className=`tcw-calendar-day`,r.dataset.date=e,r.setAttribute(`role`,`gridcell`),r.textContent=String(u.day),r.setAttribute(`aria-label`,s.format(new Date(Date.UTC(u.year,u.month,u.day)))),r.setAttribute(`aria-selected`,String(e===this.chosen)),r.tabIndex=e===a?0:-1,u.month!==this.view.month&&r.classList.add(`tcw-outside`),e===n&&r.classList.add(`tcw-today`),this.allowed(e)||(r.disabled=!0),c?.appendChild(r)}}onKey(e){let n={ArrowLeft:-1,ArrowRight:1,ArrowUp:-t,ArrowDown:t},r=this.element.isConnected&&getComputedStyle(this.element).direction===`rtl`;if(e.key in n){let t=r&&(e.key===`ArrowLeft`||e.key===`ArrowRight`)?-n[e.key]:n[e.key];this.moveFocus(l(this.focusDay,t))}else if(e.key===`PageUp`||e.key===`PageDown`)this.turn(e.key===`PageUp`?-1:1),this.focusGrid();else if(e.key===`Home`||e.key===`End`){let t=new Date(Date.UTC(this.view.year,this.view.month+1,0)).getUTCDate();this.moveFocus({...this.view,day:e.key===`Home`?1:t})}else if(e.key===`Enter`||e.key===` `)this.pick(o(this.focusDay));else return;e.preventDefault()}moveFocus(e){let t=this.clamp(e);this.focusDay=t,(t.year!==this.view.year||t.month!==this.view.month)&&(this.view={year:t.year,month:t.month}),this.render(),this.focusGrid()}pick(e){this.allowed(e)&&this.onPick(e)}};Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return u}});
2
+ //# sourceMappingURL=monthView-B-CieFDJ.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"monthView-B-CieFDJ.cjs","names":[],"sources":["../src/widget/monthView.ts"],"sourcesContent":["export interface CalendarLabels {\n prevMonth: string;\n nextMonth: string;\n today: string;\n}\n\nexport interface CalendarDay {\n year: number;\n /** 0–11. */\n month: number;\n day: number;\n}\n\n/** The first and last day that can be picked, and today, YYYY-MM-DD; each may be left out. */\nexport interface DayLimits {\n min?: string;\n max?: string;\n /** Today where the dates are read (the chart's time zone); the browser's when left out. */\n today?: string;\n}\n\nconst DAYS_SHOWN = 42;\nconst DAYS_IN_WEEK = 7;\n\n/** Regions whose weeks start on Sunday, for engines without week data. */\nconst SUNDAY_REGIONS = new Set(['US', 'CA', 'MX', 'BR', 'JP', 'KR', 'TW', 'HK', 'IL', 'PH', 'IN', 'ZA', 'AU', 'TH', 'SA', 'PE', 'CO']);\n\n/** The first day of the week where `locale` is spoken: 0 Sunday, 1 Monday. */\nexport function weekStart(locale: string): 0 | 1 {\n try {\n const loc = new Intl.Locale(locale) as Intl.Locale & {\n getWeekInfo?: () => { firstDay: number };\n weekInfo?: { firstDay: number };\n };\n const info = loc.getWeekInfo?.() ?? loc.weekInfo;\n if (info) return info.firstDay === 7 ? 0 : 1;\n return SUNDAY_REGIONS.has(loc.maximize().region ?? '') ? 0 : 1;\n } catch {\n return 1;\n }\n}\n\n/** Six whole weeks around month `month` of `year`, from `firstDay` (0 Sunday, 1 Monday). */\nexport function monthGrid(year: number, month: number, firstDay: 0 | 1): CalendarDay[] {\n const first = new Date(Date.UTC(year, month, 1));\n const lead = (first.getUTCDay() - firstDay + DAYS_IN_WEEK) % DAYS_IN_WEEK;\n const days: CalendarDay[] = [];\n for (let i = 0; i < DAYS_SHOWN; i++) {\n const d = new Date(Date.UTC(year, month, 1 - lead + i));\n days.push({ year: d.getUTCFullYear(), month: d.getUTCMonth(), day: d.getUTCDate() });\n }\n return days;\n}\n\nconst pad = (n: number) => String(n).padStart(2, '0');\nconst iso = (d: CalendarDay) => `${String(d.year).padStart(4, '0')}-${pad(d.month + 1)}-${pad(d.day)}`;\n\nfunction parseIso(value: string | undefined): CalendarDay | null {\n const m = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(value ?? '');\n if (!m) return null;\n return { year: Number(m[1]), month: Number(m[2]) - 1, day: Number(m[3]) };\n}\n\nfunction todayDay(): CalendarDay {\n const now = new Date();\n return { year: now.getFullYear(), month: now.getMonth(), day: now.getDate() };\n}\n\n/** `d` moved by `days` (any sign), across months and years. */\nfunction addDays(d: CalendarDay, days: number): CalendarDay {\n const t = new Date(Date.UTC(d.year, d.month, d.day + days));\n return { year: t.getUTCFullYear(), month: t.getUTCMonth(), day: t.getUTCDate() };\n}\n\n/**\n * A month of days drawn by the widget: arrows to turn it, today marked, the\n * chosen day marked, a button for today, and the keys a date grid takes. It\n * only tells which day was picked; what that day goes into is its owner's\n * business (a date field's calendar, the Go to dialog).\n */\nexport class MonthView {\n readonly element: HTMLDivElement;\n private readonly grid: HTMLDivElement;\n private readonly titleEl: HTMLDivElement;\n private chosen = '';\n private limits: DayLimits = {};\n private today = iso(todayDay());\n /** The month shown and the day the keys are on. */\n private view = { year: 0, month: 0 };\n private focusDay: CalendarDay = todayDay();\n\n constructor(\n labels: CalendarLabels,\n private readonly locale: string,\n private readonly onPick: (value: string) => void,\n ) {\n const element = document.createElement('div');\n element.className = 'tcw-calendar';\n\n const head = document.createElement('div');\n head.className = 'tcw-calendar-head';\n const title = document.createElement('div');\n title.className = 'tcw-calendar-title';\n title.setAttribute('aria-live', 'polite');\n head.append(this.navButton(labels.prevMonth, -1), title, this.navButton(labels.nextMonth, 1));\n\n const weekdays = document.createElement('div');\n weekdays.className = 'tcw-calendar-weekdays';\n weekdays.setAttribute('aria-hidden', 'true');\n const firstDay = weekStart(locale);\n const dayName = new Intl.DateTimeFormat(locale, { weekday: 'narrow', timeZone: 'UTC' });\n for (let i = 0; i < DAYS_IN_WEEK; i++) {\n // 2023-01-01 was a Sunday.\n const cell = document.createElement('span');\n cell.className = 'tcw-calendar-weekday';\n cell.textContent = dayName.format(new Date(Date.UTC(2023, 0, 1 + ((firstDay + i) % DAYS_IN_WEEK))));\n weekdays.appendChild(cell);\n }\n\n const grid = document.createElement('div');\n grid.className = 'tcw-calendar-grid';\n grid.setAttribute('role', 'grid');\n grid.addEventListener('keydown', (e) => this.onKey(e));\n grid.addEventListener('click', (e) => {\n const day = (e.target as Element).closest<HTMLButtonElement>('.tcw-calendar-day');\n if (day && !day.disabled && day.dataset.date) this.pick(day.dataset.date);\n });\n\n const foot = document.createElement('div');\n foot.className = 'tcw-calendar-foot';\n const today = document.createElement('button');\n today.type = 'button';\n today.className = 'tcw-calendar-today';\n today.textContent = labels.today;\n today.addEventListener('click', () => this.pick(this.today));\n foot.appendChild(today);\n\n element.append(head, weekdays, grid, foot);\n this.element = element;\n this.grid = grid;\n this.titleEl = title;\n }\n\n /** Show the month of `value` (today's when it is no date), that day marked, days outside `limits` greyed. */\n show(value: string, limits: DayLimits = {}): void {\n this.chosen = value;\n this.limits = limits;\n this.today = parseIso(limits.today) ? limits.today! : iso(todayDay());\n const start = this.clamp(parseIso(value) ?? parseIso(this.today)!);\n this.focusDay = start;\n this.view = { year: start.year, month: start.month };\n this.render();\n }\n\n /** Moves keyboard focus onto the days. */\n focusGrid(): void {\n this.grid.querySelector<HTMLButtonElement>('[tabindex=\"0\"]')?.focus();\n }\n\n private navButton(label: string, by: -1 | 1): HTMLButtonElement {\n const b = document.createElement('button');\n b.type = 'button';\n b.className = 'tcw-calendar-nav';\n b.setAttribute('aria-label', label);\n b.innerHTML = by < 0\n ? '<svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M10 3.5L5.5 8l4.5 4.5\"/></svg>'\n : '<svg viewBox=\"0 0 16 16\" aria-hidden=\"true\"><path d=\"M6 3.5L10.5 8 6 12.5\"/></svg>';\n b.addEventListener('click', () => this.turn(by));\n return b;\n }\n\n private turn(by: number): void {\n const t = new Date(Date.UTC(this.view.year, this.view.month + by, 1));\n this.view = { year: t.getUTCFullYear(), month: t.getUTCMonth() };\n // The keys' day follows into the new month, on the same date where it has one.\n const last = new Date(Date.UTC(this.view.year, this.view.month + 1, 0)).getUTCDate();\n this.focusDay = this.clamp({ ...this.view, day: Math.min(this.focusDay.day, last) });\n this.view = { year: this.focusDay.year, month: this.focusDay.month };\n this.render();\n }\n\n /** `day` moved inside the limits, so the keys never rest on a greyed day. */\n private clamp(day: CalendarDay): CalendarDay {\n const value = iso(day);\n const min = parseIso(this.limits.min);\n const max = parseIso(this.limits.max);\n if (min && value < iso(min)) return min;\n if (max && value > iso(max)) return max;\n return day;\n }\n\n private allowed(value: string): boolean {\n const { min, max } = this.limits;\n return !(min && value < min) && !(max && value > max);\n }\n\n private render(): void {\n const locale = this.locale;\n this.titleEl.textContent = new Intl.DateTimeFormat(locale, { month: 'long', year: 'numeric', timeZone: 'UTC' })\n .format(new Date(Date.UTC(this.view.year, this.view.month, 1)));\n const today = this.today;\n const focus = iso(this.focusDay);\n const fullDate = new Intl.DateTimeFormat(locale, { dateStyle: 'full', timeZone: 'UTC' });\n this.grid.textContent = '';\n let row: HTMLElement | null = null;\n for (const [i, day] of monthGrid(this.view.year, this.view.month, weekStart(locale)).entries()) {\n if (i % DAYS_IN_WEEK === 0) {\n row = document.createElement('div');\n row.className = 'tcw-calendar-week';\n row.setAttribute('role', 'row');\n this.grid.appendChild(row);\n }\n const value = iso(day);\n const b = document.createElement('button');\n b.type = 'button';\n b.className = 'tcw-calendar-day';\n b.dataset.date = value;\n b.setAttribute('role', 'gridcell');\n b.textContent = String(day.day);\n b.setAttribute('aria-label', fullDate.format(new Date(Date.UTC(day.year, day.month, day.day))));\n b.setAttribute('aria-selected', String(value === this.chosen));\n b.tabIndex = value === focus ? 0 : -1;\n if (day.month !== this.view.month) b.classList.add('tcw-outside');\n if (value === today) b.classList.add('tcw-today');\n if (!this.allowed(value)) b.disabled = true;\n row?.appendChild(b);\n }\n }\n\n private onKey(e: KeyboardEvent): void {\n const moves: Record<string, number> = { ArrowLeft: -1, ArrowRight: 1, ArrowUp: -DAYS_IN_WEEK, ArrowDown: DAYS_IN_WEEK };\n const rtl = this.element.isConnected && getComputedStyle(this.element).direction === 'rtl';\n if (e.key in moves) {\n const by = rtl && (e.key === 'ArrowLeft' || e.key === 'ArrowRight') ? -moves[e.key] : moves[e.key];\n this.moveFocus(addDays(this.focusDay, by));\n } else if (e.key === 'PageUp' || e.key === 'PageDown') {\n this.turn(e.key === 'PageUp' ? -1 : 1);\n this.focusGrid();\n } else if (e.key === 'Home' || e.key === 'End') {\n const last = new Date(Date.UTC(this.view.year, this.view.month + 1, 0)).getUTCDate();\n this.moveFocus({ ...this.view, day: e.key === 'Home' ? 1 : last });\n } else if (e.key === 'Enter' || e.key === ' ') {\n this.pick(iso(this.focusDay));\n } else {\n return;\n }\n e.preventDefault();\n }\n\n private moveFocus(target: CalendarDay): void {\n const day = this.clamp(target);\n this.focusDay = day;\n if (day.year !== this.view.year || day.month !== this.view.month) {\n this.view = { year: day.year, month: day.month };\n }\n this.render();\n this.focusGrid();\n }\n\n private pick(value: string): void {\n if (this.allowed(value)) this.onPick(value);\n }\n}\n"],"mappings":"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"}