@tradecanvas/core 2.0.0-beta.1 → 2.0.0-beta.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.
package/dist/index.cjs CHANGED
@@ -21,6 +21,6 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=requi
21
21
  cursor: pointer;
22
22
  color: ${n?`#1fa874`:`#e8505b`};
23
23
  transition: background 0.1s;
24
- `,t.addEventListener(`mouseenter`,()=>{t.style.background=`#1f2630`}),t.addEventListener(`mouseleave`,()=>{t.style.background=`transparent`}),t.addEventListener(`click`,()=>{this.onItemSelect?.(e.intent),this.hide()}),s.appendChild(t)}n.appendChild(s),this.menuElement=s;let l=e=>{(e instanceof KeyboardEvent&&e.key===`Escape`||e instanceof MouseEvent&&!s.contains(e.target))&&this.hide()};document.addEventListener(`mousedown`,l),document.addEventListener(`keydown`,l),this.removeHandler=()=>{document.removeEventListener(`mousedown`,l),document.removeEventListener(`keydown`,l)}}hide(){this.menuElement?.remove(),this.menuElement=null,this.removeHandler?.(),this.removeHandler=null}destroy(){this.hide(),this.onItemSelect=null}};function vx(e,t,n={}){let r=Math.max(Math.abs(t)*(n.riskFraction??.01),1e-8),i=r*(n.riskReward??2);return e===`buy`?{side:e,entry:t,stopLoss:t-r,takeProfit:t+i}:{side:e,entry:t,stopLoss:t+r,takeProfit:t-i}}function yx(e){let t=Math.abs(e.entry-e.stopLoss);return t===0?0:Math.abs(e.takeProfit-e.entry)/t}var bx=6,xx=.12,Sx=[6,3],Cx=class{draft=null;dragStart=null;dragging=null;defaults;constructor(e={}){this.defaults=e}start(e,t){this.draft=vx(e,t,this.defaults),this.dragging=null}cancel(){this.draft=null,this.dragging=null}isActive(){return this.draft!==null}getDraft(){return this.draft?{...this.draft}:null}hitTest(t,n,r=bx){if(!this.draft)return null;let i=[`entry`,`sl`,`tp`],a=null,o=r;for(let r of i){let i=e.O(this.priceOf(r),n),s=Math.abs(i-t.y);s<=o&&(o=s,a=r)}return a}beginDrag(e,t,n){let r=this.hitTest(e,t,n);return r!==null&&this.beginDragOn(r)}beginDragOn(e){return this.draft?(this.dragging=e,this.dragStart=this.draft,!0):!1}cancelDrag(){this.dragging&&this.dragStart&&(this.draft=this.dragStart),this.dragging=null,this.dragStart=null}drag(t,n){if(!this.draft||!this.dragging)return!1;let r=e.F(t.y,n);return this.draft=Tx(this.draft,this.dragging,r),!0}endDrag(){this.dragging=null,this.dragStart=null}isDragging(){return this.dragging!==null}priceOf(e){let t=this.draft;return e===`entry`?t.entry:e===`sl`?t.stopLoss:t.takeProfit}render(e,t,n,r){this.renderLines(e,t,n),Ub(e,this.tags(t,n),t,n,[])}renderLines(t,n,r){let i=this.draft;if(!i)return;let{chartRect:a}=n,o=e.O(i.entry,n),s=e.O(i.stopLoss,n),c=e.O(i.takeProfit,n),{profit:l,loss:u}=wx(r);t.save(),t.globalAlpha=xx,t.fillStyle=l,t.fillRect(a.x,Math.min(o,c),a.width,Math.abs(c-o)),t.fillStyle=u,t.fillRect(a.x,Math.min(o,s),a.width,Math.abs(s-o)),t.globalAlpha=1,xb(t,n,o,r.text,Sx),xb(t,n,c,l,[]),xb(t,n,s,u,[]),t.restore()}tags(t,n){let r=this.draft;if(!r)return[];let{profit:i,loss:a}=wx(n),o=r.side===`buy`?1:-1,s=e=>{let t=r.entry===0?0:(e-r.entry)/r.entry*100*o;return`${t>=0?`+`:``}${t.toFixed(2)}%`};return[{y:e.O(r.entry,t),color:n.text,grab:{kind:`bracket`,handle:`entry`},cells:[{kind:`stamp`,text:r.side===`buy`?`Long`:`Short`},{kind:`text`,text:`${yx(r).toFixed(2)}R`}]},{y:e.O(r.takeProfit,t),color:i,grab:{kind:`bracket`,handle:`tp`},cells:[{kind:`stamp`,text:`TP`},{kind:`text`,text:s(r.takeProfit),color:i}]},{y:e.O(r.stopLoss,t),color:a,grab:{kind:`bracket`,handle:`sl`},cells:[{kind:`stamp`,text:`SL`},{kind:`text`,text:s(r.stopLoss),color:a}]}].filter(e=>X(e.y,t))}renderAxisBadges(e,t,n,r){for(let i of this.axisBadges(t,n,r))Kb(e,i.y,i.text,i.color,t,n)}axisBadges(n,r,i){let a=this.draft;if(!a)return[];let{profit:o,loss:s}=wx(r),c=[];for(let[l,u]of[[a.takeProfit,o],[a.stopLoss,s],[a.entry,r.text]]){let r=e.O(l,n);X(r,n)&&c.push({y:r,text:(0,t.priceTagText)(l,n,i),color:u})}return c}};function wx(e){return{profit:e.style?.trading.profit??e.candleUp,loss:e.style?.trading.loss??e.candleDown}}function Tx(e,t,n){let r=e.side===`buy`;if(t===`entry`){let t=n-e.entry;return{side:e.side,entry:n,stopLoss:e.stopLoss+t,takeProfit:e.takeProfit+t}}if(t===`sl`){let t=r?Math.min(n,e.entry):Math.max(n,e.entry);return{...e,stopLoss:t}}let i=r?Math.max(n,e.entry):Math.min(n,e.entry);return{...e,takeProfit:i}}function Ex(e,t,n){return n==null?`limit`:e===`buy`?t<=n?`limit`:`stop`:t>=n?`limit`:`stop`}var Dx=6,Ox=[6,3],kx=class{draft=null;dragStart=null;dragging=!1;start(e,t,n=1){this.draft={side:e,price:t,quantity:n},this.dragging=!1}cancel(){this.draft=null,this.dragging=!1}isActive(){return this.draft!==null}isDragging(){return this.dragging}getDraft(){return this.draft?{...this.draft}:null}setPrice(e){return this.draft?(this.draft={...this.draft,price:e},!0):!1}toIntent(e){return this.draft?{side:this.draft.side,type:Ex(this.draft.side,this.draft.price,e),price:this.draft.price,quantity:this.draft.quantity}:null}hitTest(t,n,r=Dx){return this.draft?Math.abs(e.O(this.draft.price,n)-t.y)<=r:!1}beginDrag(e,t,n){return this.hitTest(e,t,n)&&this.beginDragOn()}beginDragOn(){return this.draft?(this.dragging=!0,this.dragStart=this.draft,!0):!1}cancelDrag(){this.dragging&&this.dragStart&&(this.draft=this.dragStart),this.dragging=!1,this.dragStart=null}drag(t,n){return!this.draft||!this.dragging?!1:this.setPrice(e.F(t.y,n))}endDrag(){this.dragging=!1,this.dragStart=null}render(e,t,n,r,i){this.renderLines(e,t,n),Ub(e,this.tags(t,n,r),t,n,[])}renderLines(t,n,r){let i=this.draft;i&&(t.save(),xb(t,n,e.O(i.price,n),Ax(i.side,r),Ox),t.restore())}tags(t,n,r){let i=this.draft;if(!i)return[];let a=e.O(i.price,t);if(!X(a,t))return[];let o=Ex(i.side,i.price,r);return[{y:a,color:Ax(i.side,n),grab:{kind:`draft`},cells:[{kind:`stamp`,text:String(i.quantity)},{kind:`text`,text:Zb({side:i.side,type:o})}]}]}renderAxisBadges(e,t,n,r){for(let i of this.axisBadges(t,n,r))Kb(e,i.y,i.text,i.color,t,n)}axisBadges(n,r,i){let a=this.draft;if(!a)return[];let o=e.O(a.price,n);return X(o,n)?[{y:o,text:(0,t.priceTagText)(a.price,n,i),color:Ax(a.side,r)}]:[]}};function Ax(e,t){return e===`buy`?t.style?.trading.buy??t.candleUp:t.style?.trading.sell??t.candleDown}var jx=2;function Mx(e,t){return e.type===t.type?e.type===`cancelOrder`?e.orderId===t.orderId:e.type===`removeStop`?e.positionId===t.positionId&&e.which===t.which:e.positionId===t.positionId:!1}function Nx(e,t,n=jx){let r=(e,n)=>t.x>=e.x-n&&t.x<=e.x+e.size+n&&t.y>=e.y-n&&t.y<=e.y+e.size+n;for(let t=e.length-1;t>=0;t--)if(r(e[t],0))return e[t];let i=null,a=1/0;for(let o of e){if(!r(o,n))continue;let e=Math.hypot(t.x-(o.x+o.size/2),t.y-(o.y+o.size/2));e<a&&(a=e,i=o)}return i}var Px=5,Fx=7,Ix=2;function Lx(e,n){let r=n.data;return r&&r.length>0?e/(0,t.barTimeUnit)(r):e}function Rx(t,n,r,i){if(n.length===0)return;let{chartRect:a}=r,o=i.orderColors?.buy??`#1fa874`,s=i.orderColors?.sell??`#e8505b`;t.lineWidth=1.5;for(let i of n){let n=e.j(Lx(i.time,r),r),c=e.O(i.price,r);if(n<a.x||n>a.x+a.width||c<a.y||c>a.y+a.height)continue;let l=i.side===`buy`,u=l?c+Ix:c-Ix,d=l?u+Fx:u-Fx;t.beginPath(),t.moveTo(n,u),t.lineTo(n-Px,d),t.lineTo(n+Px,d),t.closePath();let f=l?o:s;!i.reason||i.reason===`order`?(t.fillStyle=f,t.fill()):(t.strokeStyle=f,t.stroke())}}function zx(e){for(let t in e)if(e[t]!==null)return!0;return!1}function Bx(e,t){let n={};for(let r of Object.keys(e)){let i=e[r];i!==null&&(n[t[r]]=i)}return n}function Vx(e,t){let n=t.style?.trading;return!n||!zx(n)?e:{...e,orderColors:{...e.orderColors,...Bx({buy:n.buy,sell:n.sell},{buy:`buy`,sell:`sell`})},positionColors:{...e.positionColors,...Bx({profit:n.profit,loss:n.loss,entry:n.entry},{profit:`profit`,loss:`loss`,entry:`entry`})}}}function Hx(e,t){let n=t.style?.markers;return!n||!zx(n)?e:{...e,...Bx(n,{long:`longColor`,short:`shortColor`,neutral:`neutralColor`})}}function Ux(e,t){let n=t.style?.tradeZones;return!n||!zx(n)?e:{...e,...Bx(n,{profit:`profitColor`,loss:`lossColor`,active:`activeColor`})}}var Wx=1e3,Gx=class{orders=[];positions=[];depthData=null;currentPrice=null;config;orderRenderer=new tx;positionRenderer=new px;depthOverlay=new mx;dragHandler;contextMenu=new _x;bracket=new Cx;orderDraft=new kx;buttons=[];tagBoxes=[];tagInset=0;drawnTags=[];grabOffset=0;fills=[];realisedPnl=0;requestRender=null;eventCallback=null;container=null;constructor(e){this.config={...t.DEFAULT_TRADING_CONFIG,...e},this.dragHandler=new gx(this.config.dragThreshold),this.contextMenu.onItemSelect=e=>{this.eventCallback?.(`orderPlace`,e)}}setContainer(e){this.container=e}setRequestRender(e){this.requestRender=e}setEventCallback(e){this.eventCallback=e}setOrders(e){this.orders=e,this.requestRender?.()}setPositions(e){this.positions=e,this.requestRender?.()}getOrders(){return[...this.orders]}getPositions(){return[...this.positions]}getCurrentPrice(){return this.currentPrice}setDepthData(e){this.depthData=e,this.requestRender?.()}setCurrentPrice(e){this.currentPrice=e,this.requestRender?.()}setConfig(e){Object.assign(this.config,e),this.requestRender?.()}addFill(e){this.fills=[...this.fills.slice(-(Wx-1)),e],this.realisedPnl+=e.pnl??0,this.requestRender?.()}setFills(e){this.fills=e.slice(-Wx),this.realisedPnl=e.reduce((e,t)=>e+(t.pnl??0),0),this.requestRender?.()}getRealisedPnl(){return this.realisedPnl}getFills(){return[...this.fills]}armed=null;isOverButton(e){return this.config.enabled&&Nx(this.buttons,e)!==null}runButton(e){switch(e.type){case`cancelOrder`:this.eventCallback?.(`orderCancel`,{orderId:e.orderId});break;case`closePosition`:this.eventCallback?.(`positionClose`,{positionId:e.positionId});break;case`reversePosition`:this.eventCallback?.(`positionReverse`,{positionId:e.positionId});break;case`removeStop`:this.eventCallback?.(`positionModify`,{positionId:e.positionId,[e.which]:null});break}}startBracket(e,t){this.bracket.start(e,t),this.requestRender?.()}cancelBracket(){this.bracket.isActive()&&(this.bracket.cancel(),this.requestRender?.())}confirmBracket(){let e=this.bracket.getDraft();return e?(this.eventCallback?.(`bracketPlace`,{side:e.side,entry:e.entry,stopLoss:e.stopLoss,takeProfit:e.takeProfit,riskReward:yx(e)}),this.bracket.cancel(),this.requestRender?.(),!0):!1}isBracketActive(){return this.bracket.isActive()}startOrderDraft(e,t){this.orderDraft.start(e,t),this.requestRender?.()}cancelOrderDraft(){this.orderDraft.isActive()&&(this.orderDraft.cancel(),this.requestRender?.())}confirmOrderDraft(){let e=this.orderDraft.toIntent(this.currentPrice);return e?(this.eventCallback?.(`orderPlace`,e),this.orderDraft.cancel(),this.requestRender?.(),!0):!1}isOrderDraftActive(){return this.orderDraft.isActive()}isOverDraggableLine(t,n,r=8){if(!this.config.enabled)return!1;if(Rb(this.tagBoxes,t.x,t.y)&&!Nx(this.buttons,t))return!0;let i=i=>{if(i===void 0)return!1;let a=e.O(i,n);return X(a,n)&&Math.abs(t.y-a)<=r};for(let e of this.orders)if(e.draggable!==!1&&i(e.price))return!0;for(let e of this.positions)if(i(e.stopLoss)||i(e.takeProfit))return!0;return!1}onPointerDown(e,t,n){if(!this.config.enabled)return!1;let r=Nx(this.buttons,e,n?.button),i=r?null:Rb(this.tagBoxes,e.x,e.y);return i&&this.grabTag(i,e)||(this.grabOffset=0,this.bracket.isActive()&&this.bracket.beginDrag(e,t,n?.handle))||this.orderDraft.isActive()&&this.orderDraft.beginDrag(e,t,n?.handle)?(this.requestRender?.(),!0):r?(this.armed=r.action,!0):this.dragHandler.onPointerDown(e,this.orders,this.positions,t,n?.order??8)}grabTag(e,t){this.grabOffset=e.lineY-t.y;let n=e.grab;switch(n.kind){case`bracket`:return this.bracket.beginDragOn(n.handle);case`draft`:return this.orderDraft.beginDragOn();case`order`:{let t=this.orders.find(e=>e.id===n.orderId);return t!==void 0&&this.dragHandler.beginOrder(t,e.lineY)}case`stop`:{let t=this.positions.find(e=>e.id===n.positionId);return t!==void 0&&this.dragHandler.beginStop(t,n.which,e.lineY)}}}onPointerMove(e,t){if(this.armed)return!0;let n=this.grabOffset===0?e:{x:e.x,y:bb(e.y+this.grabOffset,t)};if(this.bracket.isDragging()){let e=this.bracket.drag(n,t);return e&&this.requestRender?.(),e}if(this.orderDraft.isDragging()){let e=this.orderDraft.drag(n,t);return e&&this.requestRender?.(),e}if(!this.dragHandler.isActive())return!1;let r=this.dragHandler.onPointerMove(n,t);return r&&this.requestRender?.(),r}onPointerUp(e){if(this.grabOffset=0,this.armed){let t=this.armed;this.armed=null;let n=e?Nx(this.buttons,e):null;return n&&Mx(n.action,t)&&this.runButton(t),!0}if(this.bracket.isDragging())return this.bracket.endDrag(),this.requestRender?.(),!0;if(this.orderDraft.isDragging())return this.orderDraft.endDrag(),this.requestRender?.(),!0;let t=this.dragHandler.onPointerUp();return t?(t.sourceType===`order`?this.eventCallback?.(`orderModify`,{orderId:t.id,newPrice:t.newPrice,previousPrice:t.previousPrice}):this.eventCallback?.(`positionModify`,{positionId:t.id,[t.sourceType]:t.newPrice}),this.requestRender?.(),!0):!1}cancelPointer(){this.grabOffset=0;let e=!1;return this.armed&&(this.armed=null,e=!0),this.bracket.isDragging()&&(this.bracket.cancelDrag(),e=!0),this.orderDraft.isDragging()&&(this.orderDraft.cancelDrag(),e=!0),this.dragHandler.cancel()&&(e=!0),e&&this.requestRender?.(),e}onContextMenu(n,r){if(!this.config.enabled||!this.config.contextMenu?.enabled||!this.container)return!1;let i=e.F(n.y,r);return this.contextMenu.show(n,i,this.container,this.config,e=>(0,t.priceTagText)(e,r,this.config.pricePrecision)),!0}tagRects(){return this.drawnTags}setTagInset(e){this.tagInset=Math.max(0,e)}render(e,t,n){if(this.buttons=[],this.tagBoxes=[],this.drawnTags=[],!this.config.enabled)return;let{chartRect:r}=t;e.save();try{e.beginPath(),e.rect(r.x,r.y,r.width,r.height),e.clip(),this.renderInPlot(e,t,n)}finally{e.restore()}}renderInPlot(e,t,n){let r=Vx(this.config,n);this.depthData&&this.depthOverlay.render(e,this.depthData,t,r),r.fillMarks!==!1&&Rx(e,this.fills,t,r);let i=this.dragHandler.getDragState();this.positionRenderer.renderLines(e,this.positions,this.currentPrice,t,r,i),this.orderRenderer.renderLines(e,this.orders,t,r,i),this.bracket.renderLines(e,t,n),this.orderDraft.renderLines(e,t,n),Ub(e,[...this.bracket.tags(t,n),...this.orderDraft.tags(t,n,this.currentPrice),...this.positionRenderer.tags(this.positions,this.currentPrice,t,r,i),...this.orderRenderer.tags(this.orders,t,r,i)],t,n,this.buttons,this.tagBoxes,this.tagInset,this.drawnTags)}renderAxisBadges(e,t,n,r){if(this.config.enabled){if(r){let{chartRect:i}=t;this.sortedAxisBadges(t,n).forEach((a,o)=>{let s=r[o]??a.y;!Number.isFinite(s)||s-16/2<i.y-.5||s+16/2>i.y+i.height+.5||Kb(e,s,a.text,a.color,t,n)});return}for(let r of Gb(this.axisBadges(t,n),t))Kb(e,r.at,r.text,r.color,t,n)}}axisBadgeLines(e,n=t.DARK_THEME){return this.config.enabled?this.sortedAxisBadges(e,n).map(e=>e.y):[]}sortedAxisBadges(e,t){return this.axisBadges(e,t).sort((e,t)=>e.y-t.y)}axisBadges(e,t){let n=Vx(this.config,t);return[...this.positionRenderer.axisBadges(this.positions,e,n,this.dragHandler.getDragState()),...this.orderRenderer.axisBadges(this.orders,e,n,this.dragHandler.getDragState()),...this.bracket.axisBadges(e,t,this.config.pricePrecision),...this.orderDraft.axisBadges(e,t,this.config.pricePrecision)]}axisTagYs(e,n=t.DARK_THEME){return this.config.enabled?Gb(this.axisBadges(e,n),e).map(e=>e.at):[]}destroy(){this.contextMenu.destroy()}},Kx=class{constructor(e){this.manager=e}render(e,t,n){this.manager.render(e,t,n)}renderAxisBadges(e,t,n,r){this.manager.renderAxisBadges(e,t,n,r)}axisBadgeLines(e,t){return this.manager.axisBadgeLines(e,t)}tagRects(){return this.manager.tagRects()}axisTagYs(e,t){return this.manager.axisTagYs(e,t)}},qx=class{name=`paper`;state=`disconnected`;listeners=new Map;orders=[];positions=[];markPrice;markTime;seq=0;constructor(e={}){this.markPrice=e.markPrice??0}connect(e){this.state=`connected`,this.emit(`connectionChange`,this.state),this.emit(`orders`,this.orders),this.emit(`positions`,this.positions)}disconnect(){this.state=`disconnected`,this.emit(`connectionChange`,this.state)}getConnectionState(){return this.state}setMarkPrice(e,t){this.markPrice=e,this.markTime=t!==void 0&&Number.isFinite(t)?t:void 0,this.checkPendingOrders(),this.checkStops()}fillTime(){return this.markTime??Date.now()}getOrders(){return[...this.orders]}getPositions(){return[...this.positions]}async placeOrder(e){let t={id:this.nextId(`ord`),side:e.side,type:e.type,price:e.price,stopPrice:e.stopPrice,quantity:e.quantity??1,label:e.type===`market`?void 0:Yx(e.type),draggable:!0,stopLoss:e.stopLoss,takeProfit:e.takeProfit,timeInForce:e.timeInForce};return e.type===`market`?this.fill(t,this.markPrice||e.price):(this.orders=[...this.orders,t],this.emit(`orders`,this.orders)),t}async modifyOrder(e){this.orders=this.orders.map(t=>t.id===e.orderId?{...t,price:e.newPrice}:t),this.emit(`orders`,this.orders)}async cancelOrder(e){this.orders=this.orders.filter(t=>t.id!==e.orderId),this.emit(`orders`,this.orders)}async modifyPosition(e){let t=(e,t)=>e===void 0?t:e??void 0;this.positions=this.positions.map(n=>n.id===e.positionId?{...n,stopLoss:t(e.stopLoss,n.stopLoss),takeProfit:t(e.takeProfit,n.takeProfit)}:n),this.emit(`positions`,this.positions)}async closePosition(e){let t=this.positions.find(t=>t.id===e.positionId);t&&(this.close(t,this.markPrice||t.entryPrice,`close`),this.emit(`positions`,this.positions))}async reversePosition(e){let t=this.positions.find(t=>t.id===e.positionId);if(!t)return;let n=this.markPrice||t.entryPrice;this.close(t,n,`reverse`);let r=t.quantity-(t.closedQuantity??0),i={id:this.nextId(`ord`),side:Jx(t.side),type:`market`,price:n,quantity:r};this.fill(i,n)}on(e,t){let n=this.listeners.get(e);n||(n=new Set,this.listeners.set(e,n)),n.add(t)}off(e,t){this.listeners.get(e)?.delete(t)}dispose(){this.disconnect(),this.listeners.clear(),this.orders=[],this.positions=[]}fill(e,t){this.orders=this.orders.filter(t=>t.id!==e.id);let n={id:this.nextId(`pos`),side:e.side,entryPrice:t,quantity:e.quantity,stopLoss:e.stopLoss,takeProfit:e.takeProfit};this.positions=[...this.positions,n];let r={orderId:e.id,side:e.side,price:t,quantity:e.quantity,time:this.fillTime(),positionId:n.id,reason:`order`};this.emit(`fill`,r),this.emit(`orders`,this.orders),this.emit(`positions`,this.positions)}close(e,t,n){this.positions=this.positions.filter(t=>t.id!==e.id);let r=e.quantity-(e.closedQuantity??0),i=e.side===`buy`?1:-1;this.emit(`fill`,{orderId:this.nextId(`ord`),side:Jx(e.side),price:t,quantity:r,time:this.fillTime(),positionId:e.id,reason:n,pnl:(t-e.entryPrice)*r*i})}checkPendingOrders(){let e=this.orders.filter(e=>this.isTriggered(e));for(let t of e)this.fill(t,t.type===`limit`?t.price:t.stopPrice??t.price)}isTriggered(e){if(e.type===`limit`)return e.side===`buy`?this.markPrice<=e.price:this.markPrice>=e.price;if(e.type===`stop`||e.type===`stopLimit`){let t=e.stopPrice??e.price;return e.side===`buy`?this.markPrice>=t:this.markPrice<=t}return!1}checkStops(){let e=!1;for(let t of[...this.positions]){let n=t.stopLoss!==void 0&&(t.side===`buy`?this.markPrice<=t.stopLoss:this.markPrice>=t.stopLoss),r=t.takeProfit!==void 0&&(t.side===`buy`?this.markPrice>=t.takeProfit:this.markPrice<=t.takeProfit);!n&&!r||(this.close(t,n?t.stopLoss:t.takeProfit,n?`stopLoss`:`takeProfit`),e=!0)}e&&this.emit(`positions`,this.positions)}nextId(e){return`${e}-${++this.seq}`}emit(e,t){let n=this.listeners.get(e);if(n){let r={type:e,data:t,timestamp:Date.now()};for(let e of n)e(r)}}};function Jx(e){return e===`buy`?`sell`:`buy`}function Yx(e){switch(e){case`stop`:return`STOP`;case`stopLimit`:return`STOP LIMIT`;default:return`LIMIT`}}var Xx=class{listeners=new Map;on(e,t){let n=this.listeners.get(e);return n||(n=new Set,this.listeners.set(e,n)),n.add(t),()=>n.delete(t)}once(e,t){let n=this.on(e,e=>{n(),t(e)});return n}off(e,t){this.listeners.get(e)?.delete(t)}emit(e,t){let n=this.listeners.get(e);if(n)for(let e of n)e(t)}removeAllListeners(){this.listeners.clear()}},Zx=6e4,Qx=e=>[e.open,e.high,e.low,e.close].every(Number.isFinite),$x=class extends Xx{currentBar=null;newest=-1/0;builtFromTrades=!1;lastTradeAt=null;timeframe;timeframeMs;dateFrame;bucket={};dateStamps=!1;tickRing;ringHead=0;ringCount=0;ringCapacity;constructor(e,n=1e3){super(),this.timeframe=e,this.timeframeMs=(0,t.timeframeToMs)(e),this.dateFrame=(0,t.timeframeSpansDays)(e),this.ringCapacity=n,this.tickRing=Array(n)}setTimeframe(e){this.timeframe=e,this.timeframeMs=(0,t.timeframeToMs)(e),this.dateFrame=(0,t.timeframeSpansDays)(e),this.reset()}seed(e){this.builtOffTheBuckets()&&(this.currentBar=null,this.newest=-1/0,this.lastTradeAt=null),Number.isFinite(e)&&(this.newest=Math.max(this.newest,(0,t.normalizeBarTime)(e)))}resume(e){if(!Qx(e))return;let n=(0,t.normalizeBarTime)(e.time);n<this.newest||(this.newest=n,this.currentBar={time:n,open:e.open,high:e.high,low:e.low,close:e.close,volume:e.volume??0,closed:!1,tickCount:0},this.builtFromTrades=!0,this.lastTradeAt=null)}setTimeZone(e,t=!1){this.bucket={timeZone:e??void 0},this.dateStamps=t}processTick(e){let n=(this.ringHead+this.ringCount)%this.ringCapacity;this.tickRing[n]=e,this.ringCount<this.ringCapacity?this.ringCount++:this.ringHead=(this.ringHead+1)%this.ringCapacity;let r=this.barFor(e.time);r!==null&&(this.newest=(0,t.normalizeBarTime)(r),this.lastTradeAt=e.time,!this.currentBar||this.currentBar.time!==r?(this.currentBar&&(this.currentBar.closed=!0,this.emit(`barClose`,this.currentBar)),this.currentBar={time:r,open:e.price,high:e.price,low:e.price,close:e.price,volume:e.volume,closed:!1,tickCount:1},this.builtFromTrades=!0):(this.currentBar.high=Math.max(this.currentBar.high,e.price),this.currentBar.low=Math.min(this.currentBar.low,e.price),this.currentBar.close=e.price,this.currentBar.volume+=e.volume,this.currentBar.tickCount++),this.emit(`bar`,this.currentBar))}processBar(e,n){let r=(0,t.normalizeBarTime)(e.time);if(r<this.newest){n&&this.emit(`correction`,{...e});return}if(this.newest=r,this.builtFromTrades=!1,n&&this.currentBar&&(0,t.normalizeBarTime)(this.currentBar.time)===r)this.currentBar={...e,closed:!0,tickCount:this.currentBar.tickCount+1},this.emit(`barClose`,this.currentBar),this.currentBar=null;else if(!n)this.currentBar={...e,closed:!1,tickCount:(this.currentBar?.tickCount??0)+1},this.emit(`bar`,this.currentBar);else{let t={...e,closed:!0,tickCount:1};this.emit(`barClose`,t),this.currentBar=null}}getCurrentBar(){return this.currentBar?{...this.currentBar}:null}getTickBuffer(){let e=Array(this.ringCount);for(let t=0;t<this.ringCount;t++)e[t]=this.tickRing[(this.ringHead+t)%this.ringCapacity];return e}reset(){this.currentBar=null,this.newest=-1/0,this.builtFromTrades=!1,this.lastTradeAt=null,this.ringHead=0,this.ringCount=0}barFor(e){let n=this.alignToTimeframe(e);if((0,t.normalizeBarTime)(n)>=this.newest)return n;if((0,t.normalizeBarTime)(e)<this.instantOf(this.newest))return null;let r=this.currentBar;return r!==null&&(0,t.normalizeBarTime)(r.time)===this.newest?r.time:this.newest}instantOf(e){return!this.dateStamps||!this.dateFrame?e:e-(0,t.offsetAt)(this.bucket.timeZone??0,e)*Zx}builtOffTheBuckets(){let e=this.currentBar;return e===null||!this.builtFromTrades?!1:this.lastTradeAt===null?!this.startsABucket((0,t.normalizeBarTime)(e.time)):this.alignToTimeframe(this.lastTradeAt)!==e.time}startsABucket(e){return this.timeframeMs>0?this.dateStamps&&this.dateFrame?(0,t.timeframeBucketStart)(e,this.timeframe)===e:this.alignToTimeframe(e)===e:!0}alignToTimeframe(e){if(!(this.timeframeMs>0))return e;let n=(0,t.timeframeBucketStart)(e,this.timeframe,this.bucket);return!this.dateStamps||!this.dateFrame?n:n+(0,t.offsetAt)(this.bucket.timeZone??0,n)*Zx}},eS=class extends Xx{config;attempt=0;timer=null;active=!1;constructor(e){super(),this.config={...t.DEFAULT_RECONNECT,...e}}schedule(e){if(!this.config.enabled||!this.active)return;if(this.cancel(),this.attempt++,this.attempt>this.config.maxRetries){this.emit(`giveUp`,{attempts:this.attempt-1}),this.active=!1;return}let t=this.computeDelay();this.emit(`attempt`,{attempt:this.attempt,delay:t}),this.timer=setTimeout(()=>{this.timer=null,this.active&&e()},t)}onConnected(){this.attempt=0,this.cancel(),this.emit(`success`,void 0)}start(){this.active=!0}stop(){this.active=!1,this.cancel(),this.attempt=0}cancel(){this.timer&&=(clearTimeout(this.timer),null)}getAttempt(){return this.attempt}isActive(){return this.active}computeDelay(){let e=this.config.baseDelay,t=this.config.backoffMultiplier**(this.attempt-1),n=Math.min(e*t,this.config.maxDelay),r=n*.25*(Math.random()*2-1);return Math.max(0,Math.round(n+r))}},tS=20,nS=class{price=null;previousClose=null;visible=!0;flashUntil=0;pricePrecision=null;locale=`en-US`;tag=null;setLocale(e){this.locale=e}setPrice(e,t){this.price!==null&&e!==this.price&&(this.flashUntil=Date.now()+300),t===void 0?e!==this.price&&(this.previousClose=this.price??e):this.previousClose=t,this.price=e}setVisible(e){this.visible=e}isVisible(){return this.visible}setPricePrecision(e){this.pricePrecision=e}getPrice(){return this.price}getTag(){return this.tag}render(e,t,n){this.renderLine(e,t,n),this.renderTag(e,t,n)}placed(t,n){let r=n.style?.lastPrice;if(!this.visible||this.price===null||r?.visible===!1)return null;let i=e.O(this.price,t),{chartRect:a}=t;return i<a.y||i>a.y+a.height?null:{y:i,color:this.previousClose===null||this.price>=this.previousClose?r?.up??n.candleUp??`#1fa874`:r?.down??n.candleDown??`#e8505b`}}renderLine(n,r,i){let a=this.placed(r,i);if(!a)return;let{y:o,color:s}=a,{chartRect:c}=r,l=i.style?.lastPrice,u=Date.now()<this.flashUntil,d=l?.width??1;n.setLineDash((0,t.lineDash)(l?.style??`solid`,[4,3],d)),n.strokeStyle=s,n.lineWidth=d,n.globalAlpha=u?1:.7,n.beginPath(),e.y(n,c.x,c.x+c.width,Math.round(o)+.5,d),n.stroke(),n.setLineDash([]),n.globalAlpha=1}renderTag(e,n,r){this.tag=null;let i=this.placed(n,r);if(!i||this.price===null)return;let{y:a,color:o}=i,{chartRect:s}=n,c=s.x+s.width+1,l=this.pricePrecision??(0,t.autoPricePrecision)(n.priceRange.min,n.priceRange.max),u=n.formatPrice?n.formatPrice(this.price):(0,t.formatPrice)(this.price,l,this.locale);e.font=`bold 11px ${r.font.family}`;let d=e.measureText(u).width,f=n.priceAxisWidth??t.PRICE_AXIS_WIDTH,p=Math.min(d+12,f-2);e.fillStyle=o,A(e,c,a-tS/2,p,tS,r),this.tag={x:c,y:a-tS/2,width:p,height:tS,color:o};let m=c-5;e.beginPath(),e.moveTo(m,a),e.lineTo(m+5,a-5),e.lineTo(m+5,a+5),e.closePath(),e.fill(),e.fillStyle=ne(o),e.textBaseline=`middle`,e.textAlign=`left`,e.fillText(u,c+5,a)}},rS=1e3,iS=10,aS=1440,oS=5e3,sS=2,cS=864e5,lS=6e4,uS=[`tick`,`barClose`,`snapshot`,`connectionChange`,`error`,`symbolInfo`],dS=new WeakMap;function fS(e){if(e instanceof vS||!e.supportedTimeframes?.length)return e;let t=dS.get(e);return t||(t=new vS(e,e.supportedTimeframes),dS.set(e,t)),t}function pS(e,n,r){if(n.includes(e))return e;let i=(0,t.pickBaseTimeframe)(e,n,{timeZone:r});return i&&Math.ceil((0,t.timeframeToMs)(e)/(0,t.timeframeToMs)(i))<=1440?i:null}function mS(e,n){if((0,t.tickBarCount)(n)!==null)return typeof e.fetchTrades==`function`&&typeof e.subscribeTrades==`function`;let r=e.supportedTimeframes;return!r?.length||pS(n,r)!==null}function hS(e,n,r){let i=(0,t.parseTimeframe)(n),a=r!==void 0&&(0,t.timeframeSpansDays)(n)&&e%cS!==0,o=a?e+(0,t.offsetAt)(r,e)*lS:e,s;if(i?.unit===`M`){let e=new Date(o);s=Date.UTC(e.getUTCFullYear(),e.getUTCMonth()+i.count,1)}else s=o+(0,t.timeframeToMs)(n);return a?(0,t.wallToUtc)(s,r):s}function gS(e,t){let n=t[0],r={time:e,open:n.open,high:n.high,low:n.low,close:n.close,volume:n.volume};for(let e=1;e<t.length;e++){let n=t[e];n.high>r.high&&(r.high=n.high),n.low<r.low&&(r.low=n.low),r.close=n.close,r.volume+=n.volume}return r}function _S(e,t){return gS(e,[...t.values()].sort((e,t)=>e.time-t.time))}var vS=class{name;fetchHistoryBefore;searchSymbols;resolveSymbol;subscribeQuotes;fetchNews;fetchTrades;subscribeTrades;listeners=new Map;unsubscribe=[];live=null;bucket=null;parts=new Map;closedBuckets=new Map;tail=null;generation=0;zones=new Map;resolving=new Map;unanswered=new Map;constructor(e,t){this.inner=e,this.baseTimeframes=t,this.name=e.name,e.fetchHistoryBefore&&(this.fetchHistoryBefore=(e,t,n,r)=>this.historyBefore(e,t,n,r)),e.searchSymbols&&(this.searchSymbols=e.searchSymbols.bind(e)),e.resolveSymbol&&(this.resolveSymbol=e=>this.resolveShared(e)),e.subscribeQuotes&&(this.subscribeQuotes=e.subscribeQuotes.bind(e)),e.fetchNews&&(this.fetchNews=e.fetchNews.bind(e)),e.fetchTrades&&(this.fetchTrades=e.fetchTrades.bind(e)),e.subscribeTrades&&(this.subscribeTrades=e.subscribeTrades.bind(e)),this.listen(`bar`,e=>this.onBar(e));for(let e of uS)this.listen(e,t=>this.emit(e,t.data))}baseFor(e){let t=pS(e,this.baseTimeframes);if(!t)throw RangeError(`${this.name} cannot serve the ${e} timeframe`);return t}connect(e){let t=this.baseFor(e.timeframe);this.generation++,this.resetBucket(),this.closedBuckets.clear(),this.live=t===e.timeframe?null:{symbol:e.symbol,target:e.timeframe,...this.planFor(e.timeframe,this.keptZone(e.symbol))},this.live&&this.resumeFromHistory(this.live),this.inner.connect({...e,timeframe:this.live?.base??t})}disconnect(){this.generation++,this.inner.disconnect(),this.resetBucket(),this.closedBuckets.clear(),this.live=null}getConnectionState(){return this.inner.getConnectionState()}async fetchHistory(e,t,n=500){if(this.baseFor(t)===t)return this.inner.fetchHistory(e,t,n);let r=this.generation,{plan:i,bars:a}=await this.baseBarsWithZone(e,t,async i=>{let a=this.baseBarsFor(t,i,n),o=await this.inner.fetchHistory(e,i,Math.min(a,rS));return this.extendBack(e,i,o,a,r)});return this.rememberTail(e,t,a,i),this.toTarget(a,t,n,i)}on(e,t){let n=this.listeners.get(e);n||(n=new Set,this.listeners.set(e,n)),n.add(t)}off(e,t){this.listeners.get(e)?.delete(t)}dispose(){this.generation++;for(let e of this.unsubscribe)e();this.unsubscribe.length=0,this.listeners.clear(),this.inner.dispose()}bucketFor(e,t){let n=pS(t,this.baseTimeframes);return n===null||n===t?null:{...this.planFor(t,this.keptZone(e)).bucket}}waitsForZone(e){return typeof this.inner.resolveSymbol==`function`&&(0,t.timeframeFollowsDays)(e)}keptZone(e){return this.zones.get(e)??void 0}renewZone(e){let t=this.unanswered.get(e);if(!t)return;let n=t.zone,r=t.asked!==void 0&&this.resolving.get(e)===t.asked;n===void 0&&r||(this.unanswered.delete(e),n===void 0?this.zones.delete(e):this.zones.set(e,n))}async zoneFor(e){if(this.zones.has(e))return this.keptZone(e);let t,n=new Promise(e=>{t=setTimeout(()=>e(),oS)});try{await Promise.race([this.resolveShared(e),n])}catch{}finally{clearTimeout(t)}return this.zones.has(e)||(this.zones.set(e,null),this.unanswered.set(e,{asked:this.resolving.get(e)})),this.keptZone(e)}resolveShared(e){let t=this.resolving.get(e);if(t)return t;let n=this.inner.resolveSymbol.bind(this.inner),r=Promise.resolve().then(()=>n(e));this.resolving.set(e,r);let i=()=>{this.resolving.get(e)===r&&this.resolving.delete(e)};return r.then(t=>{this.keepZone(e,t),i()},i),r}keepZone(e,n){let r=(0,t.symbolTimeZone)(n),i=r&&(0,t.isValidTimeZone)(r)&&!(0,t.isUtcTimeZone)(r)?r:null,a=this.unanswered.get(e);a?this.unanswered.set(e,{...a,zone:i}):this.zones.has(e)||this.zones.set(e,i)}planFor(e,n){let r=this.baseFor(e),i=n!==void 0&&r!==e&&(0,t.timeframeFollowsDays)(e)?pS(e,this.baseTimeframes,n):null,a=i??r,o=i?n:void 0;return{base:a,zone:o,bucket:{timeZone:o,dates:(0,t.timeframeSpansDays)(a)}}}async historyBefore(e,t,n,r){let i=this.inner.fetchHistoryBefore.bind(this.inner);if(this.baseFor(t)===t)return i(e,t,n,r);let a=this.generation,{plan:o,bars:s}=await this.baseBarsWithZone(e,t,async o=>{let s=this.baseBarsFor(t,o,r),c=await i(e,o,n,Math.min(s,rS));return this.extendBack(e,o,c.filter(e=>e.time<n),s,a,1)});return this.toTarget(s,t,r,o)}async baseBarsWithZone(e,t,n){if(!this.waitsForZone(t)||this.zones.has(e)){let r=this.planFor(t,this.keptZone(e));return{plan:r,bars:await n(r.base)}}let r=this.planFor(t,void 0).base,i=n(r);i.catch(()=>{});let a=this.planFor(t,await this.zoneFor(e));return{plan:a,bars:await(a.base===r?i:n(a.base))}}baseBarsFor(e,n,r){return(r+1)*Math.ceil((0,t.timeframeToMs)(e)/(0,t.timeframeToMs)(n))}async extendBack(e,t,n,r,i,a=1){let o=this.inner.fetchHistoryBefore?.bind(this.inner),s=n,c=a;for(;o&&s.length>0&&s.length<r&&c<10&&i===this.generation;){let n=s[0].time,i=await o(e,t,n,Math.min(r-s.length,rS));c++;let a=i.filter(e=>e.time<n);if(a.length===0)break;s=a.concat(s)}return s}toTarget(e,n,r,i){if(e.length===0)return[];let a=(0,t.resampleBars)(e,n,i.bucket);return a.length>1&&a[0].time!==e[0].time&&a.shift(),a.length>r?a.slice(a.length-r):a}rememberTail(e,n,r,i){if(r.length===0)return;let a=(0,t.timeframeBucketStart)(r[r.length-1].time,n,i.bucket),o=r.length;for(;o>0&&(0,t.timeframeBucketStart)(r[o-1].time,n,i.bucket)===a;)o--;this.tail={symbol:e,target:n,zone:i.zone,bucket:a,bars:r.slice(o)}}resumeFromHistory(e){let t=this.tail;if(!(!t||t.symbol!==e.symbol||t.target!==e.target||t.zone!==e.zone)){this.bucket=t.bucket;for(let e of t.bars)this.parts.set(e.time,e)}}onBar(e){let n=this.live;if(!n){this.emit(`bar`,e.data);return}let{bar:r,closed:i}=e.data,a=(0,t.timeframeBucketStart)(r.time,n.target,n.bucket);if(this.bucket!==null&&a<this.bucket){i&&this.correctClosed(a,r);return}if(this.bucket!==null&&a>this.bucket){let e=this.composed();e&&this.emit(`bar`,{bar:e,closed:!0}),this.keepClosed(),this.resetBucket()}this.bucket=a,this.parts.set(r.time,r);let o=this.composed();if(!o)return;let s=(0,t.timeframeBucketStart)(hS(r.time,n.base,n.zone),n.target,n.bucket),c=i&&s!==a;this.emit(`bar`,{bar:o,closed:c}),c&&(this.keepClosed(),this.resetBucket(),this.bucket=s)}composed(){return this.bucket===null||this.parts.size===0?null:_S(this.bucket,this.parts)}correctClosed(e,t){let n=this.closedBuckets.get(e);n&&(n.set(t.time,t),this.emit(`bar`,{bar:_S(e,n),closed:!0}))}keepClosed(){if(!(this.bucket===null||this.parts.size===0)){this.closedBuckets.set(this.bucket,this.parts);for(let e of this.closedBuckets.keys()){if(this.closedBuckets.size<=2)break;this.closedBuckets.delete(e)}}}resetBucket(){this.bucket=null,this.parts=new Map}listen(e,t){let n=e=>t(e);this.inner.on(e,n),this.unsubscribe.push(()=>this.inner.off(e,n))}emit(e,t){let n=this.listeners.get(e);if(!n)return;let r={type:e,data:t,timestamp:Date.now()};for(let e of n)e(r)}},yS=1e3,bS=15e3,xS=[`tick`,`bar`,`barClose`,`snapshot`,`connectionChange`,`error`,`symbolInfo`],SS=class{bar=null;count=0;lastTime=-1/0;constructor(e){this.tradesPerBar=e}push(e){let t=[],n=!1;for(let r of e){if(this.bar)this.bar={...this.bar,high:Math.max(this.bar.high,r.price),low:Math.min(this.bar.low,r.price),close:r.price,volume:this.bar.volume+r.volume};else{let e=Math.max(r.time,this.lastTime+1);this.lastTime=e,this.bar={time:e,open:r.price,high:r.price,low:r.price,close:r.price,volume:r.volume},this.count=0}this.count++,n=!0,this.count>=this.tradesPerBar&&(t.push({bar:this.bar,closed:!0}),this.bar=null,n=!1)}return n&&this.bar&&t.push({bar:this.bar,closed:!1}),t}build(e){return this.bar=null,this.count=0,this.lastTime=-1/0,this.push(e).map(e=>e.bar)}},CS=class{name;supportedTimeframes;searchSymbols;resolveSymbol;subscribeQuotes;fetchNews;fetchTrades;subscribeTrades;listeners=new Map;tick=null;stopTrades=null;keepAlive=null;tickMode=!1;state=`disconnected`;constructor(e){this.inner=e,this.name=e.name,this.supportedTimeframes=e.supportedTimeframes,e.searchSymbols&&(this.searchSymbols=e.searchSymbols.bind(e)),e.resolveSymbol&&(this.resolveSymbol=e.resolveSymbol.bind(e)),e.subscribeQuotes&&(this.subscribeQuotes=e.subscribeQuotes.bind(e)),e.fetchNews&&(this.fetchNews=e.fetchNews.bind(e)),this.fetchTrades=e.fetchTrades.bind(e),this.subscribeTrades=e.subscribeTrades.bind(e);for(let t of xS)e.on(t,e=>{this.tickMode||this.emit(t,e.data)})}async fetchHistory(e,n,r){let i=(0,t.tickBarCount)(n);if(i===null)return this.inner.fetchHistory(e,n,r);let a=(await this.inner.fetchTrades(e,yS)).filter(DS).sort((e,t)=>e.time-t.time),o=new SS(i),s=o.build(a);return this.tick={symbol:e,builder:o,after:a.length?a[a.length-1].time:-1/0},r!==void 0&&r>0?s.slice(-r):s}fetchHistoryBefore(e,n,r,i){return(0,t.tickBarCount)(n)!==null||!this.inner.fetchHistoryBefore?Promise.resolve([]):this.inner.fetchHistoryBefore(e,n,r,i)}connect(e){this.disconnect();let n=(0,t.tickBarCount)(e.timeframe);if(n===null){this.tickMode=!1,this.inner.connect(e);return}this.tickMode=!0;let r=this.tick?.symbol===e.symbol?this.tick:{symbol:e.symbol,builder:new SS(n),after:-1/0};this.tick=r,this.stopTrades=this.inner.subscribeTrades(e.symbol,e=>{let t=e.filter(e=>DS(e)&&e.time>=r.after);for(let{bar:e,closed:n}of r.builder.push(t))this.emit(`bar`,{bar:e,closed:n}),this.emit(`tick`,{time:e.time,price:e.close,volume:e.volume})}),this.state=`connected`,this.emit(`connectionChange`,`connected`),this.keepAlive=setInterval(()=>this.emit(`connectionChange`,`connected`),bS)}disconnect(){this.tickMode?(this.stopTrades?.(),this.stopTrades=null,this.keepAlive&&clearInterval(this.keepAlive),this.keepAlive=null,this.state=`disconnected`):this.inner.disconnect()}getConnectionState(){return this.tickMode?this.state:this.inner.getConnectionState()}dispose(){this.stopTrades?.(),this.stopTrades=null,this.keepAlive&&clearInterval(this.keepAlive),this.keepAlive=null,this.listeners.clear(),this.inner.dispose()}on(e,t){let n=this.listeners.get(e);n||(n=new Set,this.listeners.set(e,n)),n.add(t)}off(e,t){this.listeners.get(e)?.delete(t)}emit(e,t){let n=this.listeners.get(e);if(!n)return;let r={type:e,data:t,timestamp:Date.now()};for(let e of n)e(r)}},wS=new WeakMap;function TS(e){if(e instanceof CS||!ES(e))return e;let t=wS.get(e);return t||(t=new CS(e),wS.set(e,t)),t}function ES(e){return typeof e.fetchTrades==`function`&&typeof e.subscribeTrades==`function`}function DS(e){return Number.isFinite(e?.time)&&Number.isFinite(e?.price)&&Number.isFinite(e?.volume)}var OS=Symbol(`tradecanvas.sourceAdapter`),kS=new WeakSet;function AS(e){return kS.has(e)}var jS=(e,t)=>`${e}\u0000${t}`;function MS(e){return typeof e.getBars==`function`&&typeof e.subscribeBars==`function`}function NS(e){if(e.adapter&&e.feed)throw TypeError(`A stream takes an adapter or a feed, not both`);if(e.adapter)return e.adapter;if(e.feed)return IS(e.feed);throw TypeError(`A stream needs an adapter or a feed`)}function PS(e,t,n){for(let r of n){let n=t[r];typeof n==`function`&&(e[r]=n.bind(t))}}var FS=[`resolveSymbol`,`searchSymbols`,`subscribeQuotes`,`fetchNews`,`fetchTrades`,`subscribeTrades`];function IS(e){let t=e[OS];if(t)return t;let n=new LS(e);return kS.add(n),n}var LS=class{name;supportedTimeframes;fetchHistoryBefore;state=`disconnected`;listeners=new Map;unsubscribe=null;requests=new Map;streamed=null;constructor(e){this.feed=e,this.name=e.name,e.supportedTimeframes&&(this.supportedTimeframes=e.supportedTimeframes),e.pagesBack!==!1&&(this.fetchHistoryBefore=(e,t,n,r)=>this.feed.getBars({symbol:e,timeframe:t,countBack:r,before:n,signal:this.signalFor(e,t)})),PS(this,e,FS)}fetchHistory(e,t,n=500){return this.feed.getBars({symbol:e,timeframe:t,countBack:n,signal:this.signalFor(e,t)})}connect(e){this.subscribe({symbol:e.symbol,timeframe:e.timeframe})}subscribe(e,t){this.stopSubscription(),this.streamed=jS(e.symbol,e.timeframe);let n=!0,r=!1,i=null;this.unsubscribe=()=>{n=!1,i?.()};let a=e=>{this.setState(e),t?.connection(e)},o=this.feed.subscribeBars(e,{bar:(e,r)=>{n&&(this.emit(`bar`,{bar:e,closed:r}),t?.bar(e,r))},tick:e=>{n&&(this.emit(`tick`,e),t?.tick(e))},connection:e=>{n&&(r=!0,a(e))},symbolInfo:e=>{n&&(this.emit(`symbolInfo`,e),t?.symbolInfo(e))},error:e=>{n&&(this.emit(`error`,{message:e}),t?.error(e))}});if(!n){o();return}i=o,r||a(`connected`)}disconnect(){this.stopSubscription(),this.streamed!==null&&(this.requests.get(this.streamed)?.abort(),this.requests.delete(this.streamed),this.streamed=null),this.state=`disconnected`}getConnectionState(){return this.state}on(e,t){let n=this.listeners.get(e);n||(n=new Set,this.listeners.set(e,n)),n.add(t)}off(e,t){this.listeners.get(e)?.delete(t)}dispose(){this.disconnect(),this.listeners.clear()}signalFor(e,t){let n=jS(e,t),r=this.requests.get(n);return r||(r=new AbortController,this.requests.set(n,r)),r.signal}stopSubscription(){let e=this.unsubscribe;this.unsubscribe=null,e?.()}setState(e){this.state=e,this.emit(`connectionChange`,e)}emit(e,t){let n={type:e,data:t,timestamp:Date.now()};for(let t of[...this.listeners.get(e)??[]])t(n)}};function RS(e){let t={name:e.name,...e.supportedTimeframes?{supportedTimeframes:e.supportedTimeframes}:{},pagesBack:typeof e.fetchHistoryBefore==`function`,getBars:async({symbol:t,timeframe:n,countBack:r,before:i})=>i===void 0?e.fetchHistory(t,n,r):e.fetchHistoryBefore?e.fetchHistoryBefore(t,n,i,r):[],subscribeBars:(t,n)=>zS(e,t,n),[OS]:e};return PS(t,e,FS),t}function zS(e,t,n){let r=[[`bar`,e=>{let{bar:t,closed:r}=e.data;n.bar(t,r)}],[`tick`,e=>n.tick(e.data)],[`connectionChange`,e=>n.connection(e.data)],[`symbolInfo`,e=>n.symbolInfo(e.data)],[`error`,e=>n.error(e.data?.message??`Adapter error`)]];for(let[t,n]of r)e.on(t,n);return e.connect({symbol:t.symbol,timeframe:t.timeframe}),()=>{for(let[t,n]of r)e.off(t,n);e.disconnect()}}function BS(e){let t=NS(e),n=!AS(t),r=fS(t),i=r instanceof vS?r:null,a=TS(r);return a instanceof LS?new VS(a,i,n):new HS(a,i,n)}var VS=class{subscriber=null;constructor(e,t,n){this.adapter=e,this.resampler=t,this.watchSilence=n}listen(e){this.subscriber=e}getBars(e,t){return this.adapter.fetchHistory(e.symbol,e.timeframe,t)}subscribeBars(e){this.adapter.subscribe(e,this.subscriber??void 0)}unsubscribe(){this.adapter.disconnect()}release(){this.subscriber=null}},HS=class{unlisten=[];constructor(e,t,n){this.adapter=e,this.resampler=t,this.watchSilence=n}listen(e){this.hear(`connectionChange`,t=>e.connection(t.data)),this.hear(`tick`,t=>e.tick(t.data)),this.hear(`bar`,t=>{let{bar:n,closed:r}=t.data;e.bar(n,r)}),this.hear(`error`,t=>e.error(t.data?.message??`Adapter error`));try{this.hear(`symbolInfo`,t=>e.symbolInfo(t?.data))}catch{}}getBars(e,t){return this.adapter.fetchHistory(e.symbol,e.timeframe,t)}subscribeBars(e){this.adapter.connect({symbol:e.symbol,timeframe:e.timeframe})}unsubscribe(){this.adapter.disconnect()}release(){for(let e of this.unlisten)e();this.unlisten=[]}hear(e,t){this.adapter.on(e,t),this.unlisten.push(()=>this.adapter.off(e,t))}},US=2e4,WS=6e4,GS=3e4,KS=500,qS=864e5;function JS(e,n){if(!n)return e;let{time:r,open:i,high:a,low:o,close:s,volume:c}=n;return[...e,{time:(0,t.normalizeBarTime)(r)/(0,t.barTimeUnit)(e),open:i,high:a,low:o,close:s,volume:c}]}function YS(e,n,r){return(0,t.timeframeBucketStart)(e,n,{timeZone:r})===e&&(0,t.timeframeBucketStart)(e,n)!==e}var XS=class extends Xx{config=null;source=null;aggregator=null;reconnector;priceLine=new nS;state=`disconnected`;lastPrice=null;previousClose=null;sentPreviousClose=null;previousCloseTime=null;heartbeatTimer=null;lastMessageTime=0;connectSeq=0;timeZone=null;historyEnd=null;constructor(){super(),this.reconnector=new eS,this.wireReconnector()}async connect(e){this.disconnect();let n=BS(e);n.resampler?.renewZone(e.symbol),this.config={...t.DEFAULT_STREAM_CONFIG,...e},this.source=n,this.aggregator=new $x(e.timeframe),this.historyEnd=null,this.applyTickZone(),this.reconnector.removeAllListeners(),this.reconnector.stop(),this.reconnector=new eS(e.reconnect??t.DEFAULT_RECONNECT),this.wireReconnector(),this.aggregator.on(`bar`,e=>{this.emit(`barUpdate`,e),this.updatePrice(e.close)}),this.aggregator.on(`barClose`,e=>{this.setPreviousClose(e),this.emit(`barClose`,e)}),this.aggregator.on(`correction`,e=>{(0,t.normalizeBarTime)(e.time)===this.previousCloseTime&&(this.previousClose=e.close),this.emit(`barCorrection`,e)}),n.listen(this.subscriber()),this.reconnector.start(),await this.doConnect()}disconnect(){this.connectSeq++,this.reconnector.stop(),this.stopHeartbeat(),this.source&&=(this.source.release(),this.source.unsubscribe(),null),this.aggregator?.reset(),this.aggregator?.removeAllListeners(),this.aggregator=null,this.config=null,this.historyEnd=null,this.lastPrice=null,this.previousClose=null,this.previousCloseTime=null,this.sentPreviousClose=null,this.setState(`disconnected`)}async switchTo(e,t){!this.config||!this.source||(this.reconnector.stop(),this.source.unsubscribe(),this.reconnector.start(),this.aggregator?.reset(),this.aggregator?.setTimeframe(t),this.lastPrice=null,this.previousClose=null,this.previousCloseTime=null,this.sentPreviousClose=null,(e!==this.config.symbol||t!==this.config.timeframe)&&this.source.resampler?.renewZone(e),this.config.symbol=e,this.config.timeframe=t,await this.doConnect())}getConnectionState(){return this.state}setTimeZone(e){if(e!==null&&!(0,t.isValidTimeZone)(e))throw RangeError(`Unknown time zone: ${e}`);this.timeZone=e,this.applyTickZone()}getConnectionInfo(){return{state:this.state,reconnectAttempt:this.reconnector.getAttempt(),lastMessageTime:this.lastMessageTime}}getLastPrice(){return this.lastPrice}applyTickZone(){let e=this.config;if(!this.aggregator||!e)return;let t=this.historyEnd,n=t!==null&&t%qS===0,r=this.source?.resampler?.bucketFor(e.symbol,e.timeframe);if(r){let e=r.dates===!0&&n;this.aggregator.setTimeZone(r.timeZone??(e?this.timeZone:null),e);return}this.aggregator.setTimeZone(this.tickZone(e.timeframe,t),n)}tickZone(e,n){let r=this.timeZone;return r===null||(0,t.timeframeSpansDays)(e)||n!==null&&YS(n,e,r)?r:null}async doConnect(){if(!this.config||!this.source)return;let e=++this.connectSeq,n={symbol:this.config.symbol,timeframe:this.config.timeframe};this.setState(`connecting`);try{let r=await this.source.getBars(n,this.config.historyLimit??KS);if(e!==this.connectSeq||!this.source)return;let i=r.length>0?r[r.length-1]:null;this.historyEnd=i?(0,t.normalizeBarTime)(i.time):null,this.applyTickZone(),this.seedAggregator(i);let a=this.formingAfter(i);i&&!a&&(this.setPreviousClose(i),this.updatePrice(i.close)),this.emit(`snapshot`,JS(r,a)),this.source.subscribeBars(n),this.startHeartbeat()}catch(t){if(e!==this.connectSeq)return;let n=t instanceof Error?t.message:String(t);this.emit(`error`,{message:n,code:`CONNECT_FAILED`}),this.setState(`error`),this.reconnector.schedule(()=>this.doConnect())}}wireReconnector(){this.reconnector.on(`attempt`,({attempt:e,delay:t})=>{this.setState(`reconnecting`),this.emit(`connectionChange`,{state:`reconnecting`,reconnectAttempt:e,lastMessageTime:this.lastMessageTime})}),this.reconnector.on(`giveUp`,({attempts:e})=>{this.setState(`error`),this.emit(`error`,{message:`Reconnection failed after ${e} attempts`,code:`RECONNECT_EXHAUSTED`})})}subscriber(){return{connection:e=>this.onConnection(e),tick:e=>this.onTick(e),bar:(e,t)=>this.onBar(e,t),error:e=>this.emit(`error`,{message:e??`Adapter error`}),symbolInfo:e=>{e&&typeof e==`object`&&this.emit(`symbolInfo`,e)}}}onConnection(e){this.lastMessageTime=Date.now(),e===`connected`?(this.reconnector.onConnected(),this.setState(`connected`)):(e===`disconnected`||e===`error`)&&this.reconnector.schedule(()=>this.doConnect())}onTick(e){this.lastMessageTime=Date.now(),this.emit(`tick`,e),(e.bid!==void 0||e.ask!==void 0)&&this.emit(`quote`,{bid:e.bid,ask:e.ask}),this.config?.aggregateTicks&&this.aggregator?this.aggregator.processTick(e):this.updatePrice(e.price)}onBar(e,t){this.lastMessageTime=Date.now(),this.aggregator?.processBar(e,t)}setPreviousClose(e){this.previousClose=e.close,this.previousCloseTime=(0,t.normalizeBarTime)(e.time)}seedAggregator(e){this.aggregator&&(this.aggregator.seed(e?e.time:-1/0),e&&this.config?.aggregateTicks&&this.aggregator.resume(e))}formingAfter(e){let n=this.aggregator?.getCurrentBar()??null;return!n||e&&(0,t.normalizeBarTime)(n.time)<=(0,t.normalizeBarTime)(e.time)?null:n}updatePrice(e){e===this.lastPrice&&this.previousClose===this.sentPreviousClose||(this.lastPrice=e,this.sentPreviousClose=this.previousClose,this.priceLine.setPrice(e,this.previousClose??void 0),this.emit(`priceChange`,{price:e,previousClose:this.previousClose}))}setState(e){this.state!==e&&(this.state=e,this.emit(`connectionChange`,{state:e,reconnectAttempt:this.reconnector.getAttempt(),lastMessageTime:this.lastMessageTime}))}wake(e){!this.source||!this.config||this.state===`connecting`||this.state===`disconnected`||this.state===`connected`&&e===`visible`&&(!this.source.watchSilence||Date.now()-this.lastMessageTime<=US)||(this.reconnector.stop(),this.source.unsubscribe(),this.reconnector.start(),this.doConnect())}startHeartbeat(){this.stopHeartbeat(),this.heartbeatTimer=setInterval(()=>{this.source?.watchSilence===!0&&Date.now()-this.lastMessageTime>WS&&this.state===`connected`&&(this.emit(`error`,{message:`Heartbeat timeout`,code:`HEARTBEAT_TIMEOUT`}),this.source?.unsubscribe(),this.reconnector.schedule(()=>this.doConnect()))},GS)}stopHeartbeat(){this.heartbeatTimer&&=(clearInterval(this.heartbeatTimer),null)}dispose(){this.disconnect(),this.removeAllListeners()}},ZS=class extends Xx{data;speed;index;status=`idle`;timer=null;constructor(e){if(super(),e.data.length===0)throw Error(`ReplayController requires non-empty data`);this.data=e.data,this.speed=Math.max(.01,e.speed??1),this.index=Math.max(0,Math.min(e.startIndex??0,e.data.length)),e.autoStart&&this.start()}getStatus(){return this.status}getIndex(){return this.index}getTotal(){return this.data.length}getPrefix(){return this.data.slice(0,this.index)}start(){if(this.status!==`playing`){if(this.index>=this.data.length){this.transition(`finished`);return}this.transition(`playing`),this.scheduleNext()}}pause(){this.status===`playing`&&(this.clearTimer(),this.transition(`paused`))}resume(){this.status===`paused`&&this.start()}stop(){this.clearTimer(),this.index=0,this.transition(`idle`)}step(e=1){if(!(e<=0)){this.clearTimer();for(let t=0;t<e;t++)if(!this.emitNext())return;this.status!==`finished`&&this.transition(`paused`)}}seek(e){let t=Math.max(0,Math.min(e,this.data.length));this.clearTimer(),this.index=t;let n=t>=this.data.length?`finished`:`paused`;this.transition(n)}setSpeed(e){this.speed=Math.max(.01,e),this.status===`playing`&&(this.clearTimer(),this.scheduleNext())}destroy(){this.clearTimer(),this.removeAllListeners()}scheduleNext(){let e=1e3/this.speed;this.timer=setTimeout(()=>{this.timer=null,this.status===`playing`&&this.emitNext()&&this.scheduleNext()},e)}emitNext(){if(this.index>=this.data.length)return this.transition(`finished`),this.emit(`finished`,{total:this.data.length}),!1;let e=this.data[this.index],t=this.index;return this.index++,this.emit(`bar`,{bar:e,index:t,total:this.data.length}),this.index>=this.data.length?(this.transition(`finished`),this.emit(`finished`,{total:this.data.length}),!1):!0}clearTimer(){this.timer!==null&&(clearTimeout(this.timer),this.timer=null)}transition(e){this.status!==e&&(this.status=e,this.emit(`stateChange`,{status:e,index:this.index,total:this.data.length}))}};function QS(e){if(!Array.isArray(e)||e.length<6)return null;let t=e[0];if(typeof t!=`number`||!Number.isFinite(t))return null;let n=eC(e[1]),r=eC(e[2]),i=eC(e[3]),a=eC(e[4]),o=eC(e[5]);return n===null||r===null||i===null||a===null||o===null?null:{time:t,open:n,high:r,low:i,close:a,volume:o}}function $S(e){if(!tC(e))return null;let t=e.t;if(typeof t!=`number`||!Number.isFinite(t))return null;let n=eC(e.o),r=eC(e.h),i=eC(e.l),a=eC(e.c),o=eC(e.v);if(n===null||r===null||i===null||a===null||o===null)return null;let s=typeof e.x==`boolean`?e.x:!1;return{bar:{time:t,open:n,high:r,low:i,close:a,volume:o},closed:s}}function eC(e){if(typeof e==`number`)return Number.isFinite(e)?e:null;if(typeof e==`string`){let t=parseFloat(e);return Number.isFinite(t)?t:null}return null}function tC(e){return typeof e==`object`&&!!e}function Z(e){let t=typeof e==`string`?Number(e):e;return typeof t==`number`&&Number.isFinite(t)?t:void 0}function nC(e){let n=e&&typeof e==`object`&&`data`in e?e.data:e;if(!n||typeof n!=`object`)return null;let r=n;return r.e===`24hrMiniTicker`?(0,t.readQuote)({symbol:r.s,last:Z(r.c),open:Z(r.o),high:Z(r.h),low:Z(r.l),volume:Z(r.v),time:Z(r.E)}):null}function rC(e){if(!e||typeof e!=`object`)return null;let n=e;return(0,t.readQuote)({symbol:n.symbol,last:Z(n.lastPrice),change:Z(n.priceChange),changePercent:Z(n.priceChangePercent),open:Z(n.openPrice),high:Z(n.highPrice),low:Z(n.lowPrice),prevClose:Z(n.prevClosePrice),volume:Z(n.volume),bid:Z(n.bidPrice),ask:Z(n.askPrice),time:Z(n.closeTime)})}function iC(e){if(!e||typeof e!=`object`)return null;let t=e,n=Z(t.T),r=Z(t.p),i=Z(t.q);return n!==void 0&&r!==void 0&&i!==void 0?{time:n,price:r,volume:i}:null}var aC=64,oC=(e,t)=>`${e}|${t}`,sC=class{last=new Map;serve(e,t,n){if(!Array.isArray(n)||n.length===0)return;let r=n[n.length-1],i=Number(r?.time);if(!Number.isFinite(i))return;let a=oC(e,t);this.last.delete(a),this.last.set(a,{time:i,close:Number(r?.close??NaN)}),this.last.size>aC&&this.last.delete(this.last.keys().next().value)}lastBar(e,t){return this.last.get(oC(e,t))}},cC=class{newest=-1/0;servedClose=null;served=new sC;serve(e,t,n){this.served.serve(e,t,n)}reset(e,n){let r=this.served.lastBar(e,n);this.newest=r===void 0?-1/0:(0,t.normalizeBarTime)(r.time),this.servedClose=r?.close??null}admit(e,n=!1){let r=(0,t.normalizeBarTime)(e.time);return Number.isFinite(r)?r<this.newest||r===this.newest&&n&&e.close===this.servedClose?!1:(this.servedClose=null,this.newest=r,!0):!0}},lC={"1s":`1s`,"1m":`1m`,"3m":`3m`,"5m":`5m`,"15m":`15m`,"30m":`30m`,"1h":`1h`,"2h":`2h`,"4h":`4h`,"6h":`6h`,"8h":`8h`,"12h":`12h`,"1d":`1d`,"3d":`3d`,"1w":`1w`,"1M":`1M`},uC=1e3,dC=200,fC=[`USDT`,`USDC`,`FDUSD`,`BTC`,`ETH`,`BNB`,`EUR`,`TRY`,`BRL`,`JPY`];function pC(e){let t=e.currency?fC.indexOf(e.currency):-1;return t<0?0:40-t*3}function mC(e){if(typeof e.symbol!=`string`||e.status!==`TRADING`)return null;let n=typeof e.baseAsset==`string`?e.baseAsset:``,r=typeof e.quoteAsset==`string`?e.quoteAsset:``,i=Array.isArray(e.filters)?e.filters.find(e=>typeof e==`object`&&!!e&&e.filterType===`PRICE_FILTER`&&typeof e.tickSize==`string`):void 0,a={symbol:e.symbol,description:n&&r?`${n} / ${r}`:e.symbol,exchange:`Binance`,type:`crypto`};return i&&(a.pricePrecision=(0,t.stepDecimals)(i.tickSize),a.minTick=Number(i.tickSize)),a.timeZone=`UTC`,r&&(a.currency=r),a}function hC(e){let t=e?.symbols;if(!Array.isArray(t))return[];let n=[];for(let e of t){let t=mC(e);t&&n.push(t)}return n}var gC=class{name=`binance`;supportedTimeframes=Object.keys(lC);ws=null;state=`disconnected`;listeners=new Map;config=null;restBase;wsBase;symbolList=null;newestBar=new cC;constructor(e){this.restBase=e?.restBase??`https://api.binance.com/api/v3`,this.wsBase=e?.wsBase??`wss://stream.binance.com:9443/ws`}connect(e){this.config=e,this.newestBar.reset(e.symbol,e.timeframe),this.connectWs()}disconnect(){if(this.ws){let e=this.ws;e.onopen=null,e.onmessage=null,e.onerror=null,e.onclose=null,e.close(),this.ws=null}this.setState(`disconnected`)}getConnectionState(){return this.state}async fetchHistory(e,t,n=500){let r=await this.fetchKlines(e,t,n,``);return this.newestBar.serve(e,t,r),r}async searchSymbols(e,n){return(0,t.rankSymbols)(await this.loadSymbols(),e,n?.limit??50,pC)}async resolveSymbol(e){if(this.symbolList){let t=(await this.symbolList.catch(()=>null))?.find(t=>t.symbol===e);if(t)return t}let t=await fetch(`${this.restBase}/exchangeInfo?symbol=${encodeURIComponent(e)}`);return t.ok?hC(await t.json())[0]??null:null}loadSymbols(){return this.symbolList||(this.symbolList=(async()=>{let e=await fetch(`${this.restBase}/exchangeInfo`);if(!e.ok)throw Error(`Binance REST error: ${e.status}`);return hC(await e.json())})(),this.symbolList.catch(()=>{this.symbolList=null})),this.symbolList}subscribeQuotes(e,t){let n=[...new Set(e.map(e=>e.trim().toUpperCase()))].filter(e=>/^[A-Z0-9]{2,30}$/.test(e)).slice(0,dC);if(n.length===0)return()=>{};let r=!1,i=null,a=null,o=0,s=new Set,c=new AbortController;(async()=>{let e=await fetch(`${this.restBase}/ticker/24hr?symbols=${encodeURIComponent(JSON.stringify(n))}`,{signal:c.signal});if(e.ok)return e.json();let t=await fetch(`${this.restBase}/ticker/24hr`,{signal:c.signal});if(!t.ok)return[];let r=await t.json(),i=new Set(n);return Array.isArray(r)?r.filter(e=>i.has(e?.symbol)):[]})().then(e=>{if(r||!Array.isArray(e))return;let n=e.map(rC).filter(e=>e!==null&&!s.has(e.symbol));n.length>0&&t(n)}).catch(()=>{});let l=this.wsBase.replace(/\/ws\/?$/,``),u=()=>{if(!r){try{i=new WebSocket(`${l}/stream?streams=${n.map(e=>`${e.toLowerCase()}@miniTicker`).join(`/`)}`)}catch{d();return}i.onopen=()=>{o=0},i.onmessage=e=>{let n;try{n=JSON.parse(typeof e.data==`string`?e.data:``)}catch{return}let i=nC(n);!i||r||(s.add(i.symbol),t([i]))},i.onclose=()=>{i=null,d()}}},d=()=>{r||(a=setTimeout(u,Math.min(3e4,1e3*2**o++)))};return u(),()=>{r=!0,c.abort(),a&&clearTimeout(a),i&&=(i.onopen=null,i.onmessage=null,i.onclose=null,i.close(),null)}}async fetchTrades(e,t=1e3){let n=Math.max(1,Math.min(1e3,Math.floor(t))),r=await fetch(`${this.restBase}/aggTrades?symbol=${encodeURIComponent(e.toUpperCase())}&limit=${n}`);if(!r.ok)throw Error(`Binance aggTrades ${r.status}`);let i=await r.json();return Array.isArray(i)?i.map(iC).filter(e=>e!==null):[]}subscribeTrades(e,t){let n=`${e.trim().toLowerCase()}@aggTrade`;if(!/^[a-z0-9]{2,30}@aggTrade$/.test(n))return()=>{};let r=!1,i=null,a=null,o=0,s=()=>{if(!r){try{i=new WebSocket(`${this.wsBase}/${n}`)}catch{c();return}i.onopen=()=>{o=0},i.onmessage=e=>{let n;try{n=JSON.parse(typeof e.data==`string`?e.data:``)}catch{return}let i=iC(n);i&&!r&&t([i])},i.onclose=()=>{i=null,c()}}},c=()=>{r||(a=setTimeout(s,Math.min(3e4,1e3*2**o++)))};return s(),()=>{r=!0,a&&clearTimeout(a),i&&=(i.onopen=null,i.onmessage=null,i.onclose=null,i.close(),null)}}fetchHistoryBefore(e,t,n,r=500){return this.fetchKlines(e,t,Math.min(r,uC),`&endTime=${Math.floor(n)-1}`)}async fetchKlines(e,t,n,r){let i=lC[t]??`15m`,a=`${this.restBase}/klines?symbol=${e}&interval=${i}&limit=${n}${r}`,o=await fetch(a);if(!o.ok)throw Error(`Binance REST error: ${o.status}`);let s=await o.json();if(!Array.isArray(s))return[];let c=[];for(let e of s){let t=QS(e);t&&c.push(t)}return c}on(e,t){let n=this.listeners.get(e);n||(n=new Set,this.listeners.set(e,n)),n.add(t)}off(e,t){this.listeners.get(e)?.delete(t)}dispose(){this.disconnect(),this.listeners.clear()}connectWs(){if(!this.config)return;let e=`${this.config.symbol.toLowerCase()}@kline_${lC[this.config.timeframe]??`15m`}`,t=`${this.wsBase}/${e}`;this.setState(`connecting`);try{this.ws=new WebSocket(t)}catch{this.setState(`error`),this.emitEvent(`error`,{message:`WebSocket creation failed`}),this.emitEvent(`connectionChange`,`error`);return}this.ws.onopen=()=>{this.setState(`connected`),this.emitEvent(`connectionChange`,`connected`)},this.ws.onmessage=e=>{let t;try{t=JSON.parse(typeof e.data==`string`?e.data:``)}catch{return}typeof t==`object`&&t&&t.e===`kline`&&this.handleKline(t.k)},this.ws.onerror=()=>{this.setState(`error`),this.emitEvent(`error`,{message:`WebSocket error`})},this.ws.onclose=()=>{this.setState(`disconnected`),this.emitEvent(`connectionChange`,`disconnected`)}}handleKline(e){let t=$S(e);if(!t)return;let{bar:n,closed:r}=t,i=this.newestBar.admit(n,r);this.emitEvent(`bar`,{bar:n,closed:r}),i&&this.emitEvent(`tick`,{time:Date.now(),price:n.close,volume:n.volume})}setState(e){this.state=e}emitEvent(e,t){let n=this.listeners.get(e);if(n){let r={type:e,data:t,timestamp:Date.now()};for(let e of n)e(r)}}},_C=class{name=`mock`;state=`disconnected`;listeners=new Map;config=null;options;tickTimer=null;currentPrice;oldestOpen=new Map;forming=null;formingTimeframe=null;constructor(e){this.options={basePrice:100,volatility:1.5,tickInterval:2e3,historySize:500,...e},this.currentPrice=this.options.basePrice}connect(e){this.config=e,this.state=`connected`,this.emitEvent(`connectionChange`,`connected`),this.startTicking()}disconnect(){this.stopTicking(),this.state=`disconnected`,this.emitEvent(`connectionChange`,`disconnected`)}getConnectionState(){return this.state}subscribeQuotes(e,t){let n=[...new Set(e)].map(e=>{let t=this.options.basePrice*(.5+vC(e)%1e3/1e3);return{symbol:e,open:t,last:t,high:t,low:t,volume:0}});if(n.length===0)return()=>{};let r=this.options.volatility/100,i=()=>t(n.map(e=>({symbol:e.symbol,last:e.last,open:e.open,high:e.high,low:e.low,volume:e.volume,change:e.last-e.open,changePercent:(e.last-e.open)/e.open*100,time:Date.now()})));i();let a=setInterval(()=>{for(let e of n)e.last=Math.max(e.open*.01,e.last*(1+(Math.random()-.5)*r)),e.high=Math.max(e.high,e.last),e.low=Math.min(e.low,e.last),e.volume+=Math.random()*100;i()},this.options.tickInterval);return()=>clearInterval(a)}async fetchTrades(e,t=1e3){let n=Math.max(1,Math.min(1e3,Math.floor(t))),r=Date.now(),i=this.options.volatility/1e3,a=this.options.basePrice*(.5+vC(e)%1e3/1e3),o=[];for(let e=n-1;e>=0;e--)a=Math.max(a*.5,a*(1+(Math.random()-.5)*i)),o.push({time:r-e*1e3,price:a,volume:Math.random()*5});return o}subscribeTrades(e,t){let n=this.options.volatility/1e3,r=this.options.basePrice*(.5+vC(e)%1e3/1e3),i=setInterval(()=>{let e=[];for(let t=0;t<3;t++)r=Math.max(r*.5,r*(1+(Math.random()-.5)*n)),e.push({time:Date.now(),price:r,volume:Math.random()*5});t(e)},this.options.tickInterval);return()=>clearInterval(i)}async fetchHistory(e,t,n){let r=this.options.historyGenerator?this.options.historyGenerator(e,t,n??this.options.historySize):this.generateHistory(t,n??this.options.historySize);return r.length>0&&this.oldestOpen.set(e,r[0].open),this.forming=r.length>0?{...r[r.length-1]}:null,this.formingTimeframe=t,r}async fetchHistoryBefore(e,n,r,i){let a=(0,t.timeframeToMs)(n),o=this.options.volatility/100,s=Array(Math.max(0,i)),c=this.oldestOpen.get(e)??this.options.basePrice;for(let e=0;e<i;e++){let t=c/(1+(Math.random()-.52)*o),n=Math.max(t,c)+Math.random()*c*o*.3,l=Math.max(0,Math.min(t,c)-Math.random()*c*o*.3),u=Math.floor(1e4+Math.random()*1e5);s[i-1-e]={time:r-(e+1)*a,open:t,high:n,low:l,close:c,volume:u},c=t}return this.oldestOpen.set(e,c),s}async searchSymbols(e,n){return(0,t.rankSymbols)(this.options.symbols??[],e,n?.limit??50)}async resolveSymbol(e){return this.options.symbols?.find(t=>t.symbol===e)??null}on(e,t){let n=this.listeners.get(e);n||(n=new Set,this.listeners.set(e,n)),n.add(t)}off(e,t){this.listeners.get(e)?.delete(t)}dispose(){this.disconnect(),this.listeners.clear()}generateHistory(e,n){let r=[],i=(0,t.timeframeToMs)(e),a=Math.floor(Date.now()/i)*i,o=this.options.basePrice,s=this.options.volatility/100;for(let e=n-1;e>=0;e--){let t=a-e*i,n=(Math.random()-.48)*o*s,c=o;o+=n;let l=Math.max(c,o)+Math.random()*o*s*.3,u=Math.min(c,o)-Math.random()*o*s*.3,d=Math.floor(1e4+Math.random()*1e5);r.push({time:t,open:c,high:l,low:u,close:o,volume:d})}return this.currentPrice=o,r}startTicking(){this.stopTicking();let e=this.options.tickInterval??2e3;this.tickTimer=setInterval(()=>{if(this.state!==`connected`||!this.config)return;let e=this.options.volatility/100,t=(Math.random()-.48)*this.currentPrice*e*.3;this.currentPrice+=t;let n=Date.now(),r=this.tickBar(n,t,Math.floor(100+Math.random()*5e3));this.emitEvent(`bar`,{bar:r,closed:!1}),this.emitEvent(`tick`,{time:n,price:this.currentPrice,volume:r.volume})},e)}tickBar(e,n,r){let i=this.config.timeframe,a=(0,t.timeframeToMs)(i),o=Math.floor(e/a)*a,s=this.currentPrice,c=this.formingTimeframe===i?this.forming:null,l=Math.abs(n)*.2,u;if(c&&c.time===o)u={time:o,open:c.open,high:Math.max(c.high,s+l),low:Math.min(c.low,s-l),close:s,volume:c.volume+r};else{let e=c?.close??s-n;u={time:o,open:e,high:Math.max(e,s)+l,low:Math.min(e,s)-l,close:s,volume:r}}return this.forming=u,this.formingTimeframe=i,{...u}}stopTicking(){this.tickTimer&&=(clearInterval(this.tickTimer),null)}emitEvent(e,t){let n=this.listeners.get(e);if(n){let r={type:e,data:t,timestamp:Date.now()};for(let e of n)e(r)}}};function vC(e){let t=0;for(let n=0;n<e.length;n++)t=t*31+e.charCodeAt(n)>>>0;return t}var yC=class{name;supportedTimeframes;ws=null;state=`disconnected`;config=null;listeners=new Map;opts;newestBar=new cC;fetchHistoryBefore;searchSymbols;resolveSymbol;constructor(e){this.opts=e,this.name=e.name,this.supportedTimeframes=e.supportedTimeframes;let t=e.fetchHistoryBefore;t&&(this.fetchHistoryBefore=(e,n,r,i)=>t(e,n,r,i)),e.searchSymbols&&(this.searchSymbols=e.searchSymbols),e.resolveSymbol&&(this.resolveSymbol=e.resolveSymbol)}connect(e){this.config=e,this.newestBar.reset(e.symbol,e.timeframe),this.openSocket()}disconnect(){let e=this.config;if(this.ws){if(this.opts.unsubscribeMessage&&e)try{this.sendMessage(this.opts.unsubscribeMessage(e))}catch{}let t=this.ws;t.onopen=null,t.onmessage=null,t.onerror=null,t.onclose=null,t.close(),this.ws=null}this.setState(`disconnected`)}getConnectionState(){return this.state}fetchHistory(e,t,n){let r=this.opts.fetchHistory(e,t,n??this.opts.defaultHistoryLimit??500);return Promise.resolve(r).then(n=>(this.newestBar.serve(e,t,n),n))}on(e,t){let n=this.listeners.get(e);n||(n=new Set,this.listeners.set(e,n)),n.add(t)}off(e,t){this.listeners.get(e)?.delete(t)}dispose(){this.disconnect(),this.listeners.clear()}openSocket(){let e=this.config;if(!e)return;let t=this.opts.wsUrl(e);this.setState(`connecting`);let n;try{n=this.createSocket(t)}catch{this.setState(`error`),this.emitEvent(`error`,{message:`WebSocket creation failed`}),this.emitEvent(`connectionChange`,`error`);return}this.ws=n,n.onopen=()=>{if(this.setState(`connected`),this.emitEvent(`connectionChange`,`connected`),this.opts.subscribeMessage)try{this.sendMessage(this.opts.subscribeMessage(e))}catch{}},n.onmessage=t=>{let n=this.decode(t.data);if(n===void 0)return;let r;try{r=this.opts.parseMessage(n,e)}catch{return}if(!r)return;let i=r.bar?this.newestBar.admit(r.bar,r.closed??!1):!1;r.bar&&this.emitEvent(`bar`,{bar:r.bar,closed:r.closed??!1}),r.tick?this.emitEvent(`tick`,r.tick):r.bar&&i&&this.emitEvent(`tick`,{time:Date.now(),price:r.bar.close,volume:r.bar.volume})},n.onerror=()=>{this.setState(`error`),this.emitEvent(`error`,{message:`WebSocket error`})},n.onclose=()=>{this.setState(`disconnected`),this.emitEvent(`connectionChange`,`disconnected`)}}sendMessage(e){e===void 0||!this.ws||this.ws.send(typeof e==`string`?e:JSON.stringify(e))}decode(e){if(this.opts.decode)try{return this.opts.decode(e)}catch{return}if(typeof e==`string`)try{return JSON.parse(e)}catch{return}return e}createSocket(e){if(this.opts.socketFactory)return this.opts.socketFactory(e);let t=globalThis.WebSocket;if(!t)throw Error(`No WebSocket implementation available`);return new t(e)}setState(e){this.state=e}emitEvent(e,t){let n=this.listeners.get(e);if(n){let r={type:e,data:t,timestamp:Date.now()};for(let e of n)e(r)}}},bC=class{name;supportedTimeframes;state=`disconnected`;listeners=new Map;config=null;timer=null;lastBarTime=0;served=new sC;opts;fetchHistoryBefore;searchSymbols;resolveSymbol;constructor(e){this.opts=e,this.name=e.name,this.supportedTimeframes=e.supportedTimeframes;let t=e.fetchHistoryBefore;t&&(this.fetchHistoryBefore=(e,n,r,i)=>t(e,n,r,i)),e.searchSymbols&&(this.searchSymbols=e.searchSymbols),e.resolveSymbol&&(this.resolveSymbol=e.resolveSymbol)}connect(e){this.config=e,this.lastBarTime=this.served.lastBar(e.symbol,e.timeframe)?.time??0,this.state=`connected`,this.emitEvent(`connectionChange`,`connected`),this.startPolling()}disconnect(){this.stopPolling(),this.state=`disconnected`,this.emitEvent(`connectionChange`,`disconnected`)}getConnectionState(){return this.state}async fetchHistory(e,t,n){let r=await this.opts.fetchBars(e,t,n??this.opts.defaultHistoryLimit??500);return this.served.serve(e,t,r),r}on(e,t){let n=this.listeners.get(e);n||(n=new Set,this.listeners.set(e,n)),n.add(t)}off(e,t){this.listeners.get(e)?.delete(t)}dispose(){this.disconnect(),this.listeners.clear()}async poll(){let e=this.config;if(!e||this.state!==`connected`)return;let t;try{t=await this.opts.fetchBars(e.symbol,e.timeframe,this.opts.pollLimit??2)}catch(e){this.emitEvent(`error`,{message:`Poll failed`,cause:e});return}if(t.length===0)return;let n=t[t.length-1];if(!(n.time<this.lastBarTime)){if(this.lastBarTime>0&&n.time>this.lastBarTime){let e=t.find(e=>e.time===this.lastBarTime);e&&this.emitEvent(`bar`,{bar:e,closed:!0})}this.emitEvent(`bar`,{bar:n,closed:!1}),this.emitEvent(`tick`,{time:Date.now(),price:n.close,volume:n.volume}),this.lastBarTime=n.time}}startPolling(){this.stopPolling(),this.poll();let e=this.opts.setInterval??((e,t)=>setInterval(e,t));this.timer=e(()=>{this.poll()},this.opts.intervalMs??5e3)}stopPolling(){this.timer!==null&&((this.opts.clearInterval??(e=>clearInterval(e)))(this.timer),this.timer=null)}emitEvent(e,t){let n=this.listeners.get(e);if(n){let r={type:e,data:t,timestamp:Date.now()};for(let e of n)e(r)}}};function Q(e){if(typeof e==`number`)return Number.isFinite(e)?e:null;if(typeof e==`string`){let t=parseFloat(e);return Number.isFinite(t)?t:null}return null}function xC(e){return typeof e==`object`&&!!e}var SC={"1m":60,"5m":300,"15m":900,"1h":3600,"6h":21600,"1d":86400};function CC(e){return SC[e]??3600}var wC=class extends bC{constructor(e={}){let t=e.restBase??`https://api.exchange.coinbase.com`;super({name:`coinbase`,supportedTimeframes:Object.keys(SC),intervalMs:e.intervalMs??5e3,pollLimit:2,fetchBars:(e,n)=>TC(t,e,n)})}};async function TC(e,t,n){let r=`${e}/products/${t}/candles?granularity=${CC(n)}`,i=await fetch(r);if(!i.ok)throw Error(`Coinbase REST error: ${i.status}`);return EC(await i.json())}function EC(e){if(!Array.isArray(e))return[];let t=[];for(let n of e){let e=DC(n);e&&t.push(e)}return t.sort((e,t)=>e.time-t.time),t}function DC(e){if(!Array.isArray(e)||e.length<6)return null;let t=Q(e[0]),n=Q(e[1]),r=Q(e[2]),i=Q(e[3]),a=Q(e[4]),o=Q(e[5]);return t===null||n===null||r===null||i===null||a===null||o===null?null:{time:t*1e3,open:i,high:r,low:n,close:a,volume:o}}var OC={"1m":`1`,"3m":`3`,"5m":`5`,"15m":`15`,"30m":`30`,"1h":`60`,"2h":`120`,"4h":`240`,"6h":`360`,"12h":`720`,"1d":`D`,"1w":`W`,"1M":`M`};function kC(e){return OC[e]??`1`}var AC=class extends yC{constructor(e={}){let t=e.restBase??`https://api.bybit.com`,n=e.wsBase??`wss://stream.bybit.com/v5/public/spot`,r=e.category??`spot`;super({name:`bybit`,wsUrl:()=>n,subscribeMessage:e=>({op:`subscribe`,args:[`kline.${kC(e.timeframe)}.${e.symbol}`]}),unsubscribeMessage:e=>({op:`unsubscribe`,args:[`kline.${kC(e.timeframe)}.${e.symbol}`]}),supportedTimeframes:Object.keys(OC),parseMessage:jC,fetchHistory:(e,n,i)=>MC(t,r,e,n,i),fetchHistoryBefore:(e,n,i,a)=>MC(t,r,e,n,a,Math.floor(i)-1)})}};function jC(e){if(!xC(e)||typeof e.topic!=`string`||!e.topic.startsWith(`kline.`))return null;let t=e.data;if(!Array.isArray(t)||t.length===0)return null;let n=t[t.length-1];if(!xC(n))return null;let r=Q(n.start),i=Q(n.open),a=Q(n.high),o=Q(n.low),s=Q(n.close),c=Q(n.volume);if(r===null||i===null||a===null||o===null||s===null||c===null)return null;let l=typeof n.confirm==`boolean`?n.confirm:!1;return{bar:{time:r,open:i,high:a,low:o,close:s,volume:c},closed:l}}async function MC(e,t,n,r,i,a){let o=`${e}/v5/market/kline?category=${t}&symbol=${n}&interval=${kC(r)}&limit=${Math.min(Math.max(i,1),1e3)}${a===void 0?``:`&end=${a}`}`,s=await fetch(o);if(!s.ok)throw Error(`Bybit REST error: ${s.status}`);return NC(await s.json())}function NC(e){if(!xC(e)||!xC(e.result))return[];let t=e.result.list;if(!Array.isArray(t))return[];let n=[];for(let e of t){let t=PC(e);t&&n.push(t)}return n.sort((e,t)=>e.time-t.time),n}function PC(e){if(!Array.isArray(e)||e.length<6)return null;let t=Q(e[0]),n=Q(e[1]),r=Q(e[2]),i=Q(e[3]),a=Q(e[4]),o=Q(e[5]);return t===null||n===null||r===null||i===null||a===null||o===null?null:{time:t,open:n,high:r,low:i,close:a,volume:o}}var FC={"1m":1,"5m":5,"15m":15,"30m":30,"1h":60,"4h":240,"1d":1440,"1w":10080};function IC(e){return FC[e]??1}var LC=class extends yC{constructor(e={}){let t=e.restBase??`https://api.kraken.com`,n=e.wsBase??`wss://ws.kraken.com/v2`;super({name:`kraken`,wsUrl:()=>n,subscribeMessage:e=>({method:`subscribe`,params:{channel:`ohlc`,symbol:[e.symbol],interval:IC(e.timeframe)}}),unsubscribeMessage:e=>({method:`unsubscribe`,params:{channel:`ohlc`,symbol:[e.symbol],interval:IC(e.timeframe)}}),supportedTimeframes:Object.keys(FC),parseMessage:RC,fetchHistory:(e,n)=>zC(t,e,n)})}};function RC(e){if(!xC(e)||e.channel!==`ohlc`)return null;let t=e.data;if(!Array.isArray(t)||t.length===0)return null;let n=t[t.length-1];if(!xC(n))return null;let r=Q(n.open),i=Q(n.high),a=Q(n.low),o=Q(n.close),s=Q(n.volume),c=typeof n.interval_begin==`string`?Date.parse(n.interval_begin):NaN;return r===null||i===null||a===null||o===null||s===null||!Number.isFinite(c)?null:{bar:{time:c,open:r,high:i,low:a,close:o,volume:s},closed:!1}}async function zC(e,t,n){let r=IC(n),i=t.replace(`/`,``),a=`${e}/0/public/OHLC?pair=${encodeURIComponent(i)}&interval=${r}`,o=await fetch(a);if(!o.ok)throw Error(`Kraken REST error: ${o.status}`);return BC(await o.json())}function BC(e){if(!xC(e)||!xC(e.result))return[];let t=null;for(let[n,r]of Object.entries(e.result))if(n!==`last`&&Array.isArray(r)){t=r;break}if(!Array.isArray(t))return[];let n=[];for(let e of t){let t=VC(e);t&&n.push(t)}return n.sort((e,t)=>e.time-t.time),n}function VC(e){if(!Array.isArray(e)||e.length<7)return null;let t=Q(e[0]),n=Q(e[1]),r=Q(e[2]),i=Q(e[3]),a=Q(e[4]),o=Q(e[6]);return t===null||n===null||r===null||i===null||a===null||o===null?null:{time:t*1e3,open:n,high:r,low:i,close:a,volume:o}}var HC=200,UC={"1m":`minutes/1`,"3m":`minutes/3`,"5m":`minutes/5`,"15m":`minutes/15`,"30m":`minutes/30`,"1h":`minutes/60`,"4h":`minutes/240`,"1d":`days`,"1w":`weeks`,"1M":`months`},WC={"1m":`candle.1m`,"3m":`candle.3m`,"5m":`candle.5m`,"15m":`candle.15m`,"30m":`candle.30m`,"1h":`candle.60m`,"4h":`candle.240m`,"1d":`ticker`};function GC(e){return UC[e]??null}function KC(e){return WC[e]??null}var qC=class extends yC{constructor(e={}){let t=e.restBase??`https://api.upbit.com`,n=e.wsUrl??`wss://api.upbit.com/websocket/v1`;super({name:`upbit`,wsUrl:()=>n,socketFactory:e.socketFactory??JC,decode:XC,subscribeMessage:e=>[{ticket:`tradecanvas`},{type:KC(e.timeframe)??`candle.1m`,codes:[e.symbol]},{format:`DEFAULT`}],supportedTimeframes:Object.keys(WC),parseMessage:ZC,fetchHistory:(e,n,r)=>ew(t,e,n,r),fetchHistoryBefore:(e,n,r,i)=>ew(t,e,n,i,r)})}};function JC(e){let t=globalThis.WebSocket;if(!t)throw Error(`No WebSocket implementation available`);let n=new t(e);return n.binaryType=`arraybuffer`,n}var YC=null;function XC(e){if(typeof e==`string`)return JSON.parse(e);if(e instanceof ArrayBuffer||ArrayBuffer.isView(e))return JSON.parse((YC??=new TextDecoder).decode(e))}function ZC(e){if(!xC(e)||typeof e.type!=`string`)return null;if(e.type.startsWith(`candle.`)){let t=$C(e,e.candle_date_time_utc,e.candle_acc_trade_volume);return t?{bar:t,closed:!1}:null}if(e.type===`ticker`&&typeof e.trade_date==`string`&&/^\d{8}$/.test(e.trade_date)){let t=e.trade_date,n=$C(e,`${t.slice(0,4)}-${t.slice(4,6)}-${t.slice(6,8)}T00:00:00`,e.acc_trade_volume);return n?{bar:n,closed:!1}:null}return null}function QC(e){if(!Array.isArray(e))return[];let t=[];for(let n of e){let e=xC(n)?$C(n,n.candle_date_time_utc,n.candle_acc_trade_volume):null;e&&t.push(e)}return t.sort((e,t)=>e.time-t.time),t}function $C(e,t,n){let r=typeof t==`string`?Date.parse(`${t}Z`):NaN,i=Q(e.opening_price),a=Q(e.high_price),o=Q(e.low_price),s=Q(e.trade_price),c=Q(n);return!Number.isFinite(r)||i===null||a===null||o===null||s===null||c===null?null:{time:r,open:i,high:a,low:o,close:s,volume:c}}async function ew(e,t,n,r,i){let a=GC(n);if(!a)throw Error(`Upbit has no ${n} candles`);let o=new URLSearchParams({market:t,count:String(Math.min(Math.max(Math.floor(r),1),200))});i!==void 0&&o.set(`to`,new Date(i).toISOString().replace(/\.\d{3}Z$/,`Z`));let s=await fetch(`${e}/v1/candles/${a}?${o}`);if(!s.ok)throw Error(`Upbit REST error: ${s.status}`);return QC(await s.json())}var tw=(e,t)=>`${e}\u0000${t}`,nw=class{name;series=new Map;subscribers=new Map;constructor(e={}){this.name=e.name??`manual`}setBars(e,t,n){let r=n.map(e=>({...e})).sort((e,t)=>e.time-t.time);this.series.set(tw(e,t),r)}pushBar(e,t,n,r=!1){let i=tw(e,t),a=this.series.get(i)??[],o=a[a.length-1],s={...n},c=r;if(!o||s.time>o.time)this.series.set(i,[...a,s]);else{let n=a.findIndex(e=>e.time===s.time);if(n<0)throw RangeError(`ManualFeed: no ${e} ${t} bar at ${s.time} to replace`);n<a.length-1&&(c=!0),this.series.set(i,a.map((e,t)=>t===n?s:e))}for(let e of[...this.subscribers.get(i)??[]])e.bar({...s},c)}async getBars(e){let t=this.series.get(tw(e.symbol,e.timeframe))??[],{before:n}=e,r=n===void 0?t.length:rw(t,n);return t.slice(Math.max(0,r-e.countBack),r).map(e=>({...e}))}subscribeBars(e,t){let n=tw(e.symbol,e.timeframe),r=this.subscribers.get(n);return r||(r=new Set,this.subscribers.set(n,r)),r.add(t),()=>{r.delete(t),r.size===0&&this.subscribers.delete(n)}}};function rw(e,t){let n=0,r=e.length;for(;n<r;){let i=n+r>>1;e[i].time<t?n=i+1:r=i}return n}var iw={visible:!0,showSymbol:!0,showOHLC:!0,showChange:!0,showVolume:!0,position:`top-left`,fontSize:12,fontFamily:null,ground:!0},aw=class{config={...iw};symbol=``;timeframe=``;hoverBar=null;hoverPrev=null;indicators=[];statusText=null;exchange=``;drawnHeight=null;drawnWidth=0;locale=`en-US`;inset=sw;top=ow;lineGap=cw;pricePrecision=null;reportedHeight=null;resizeListener=null;setResizeListener(e){this.resizeListener=e}forgetHeight(){this.drawnHeight=null,this.reportedHeight=null}reportResize(){let e=this.getHeight();e!==this.reportedHeight&&(this.reportedHeight=e,this.resizeListener?.())}setConfig(e){Object.assign(this.config,e),this.forgetHeight()}getConfig(){return{...this.config}}setPricePrecision(e){this.pricePrecision=e}setLocale(e){this.locale=e}setSymbol(e){e!==this.symbol&&(this.symbol=e,this.forgetHeight())}setTimeframe(e){e!==this.timeframe&&(this.timeframe=e,this.forgetHeight())}setChartType(e){}setHoverBar(e,t=null){this.hoverBar=e,this.hoverPrev=e?t:null}setIndicatorValues(e){this.indicators=e}setStatusText(e){e!==this.statusText&&(this.statusText=e,this.forgetHeight())}setExchange(e){e!==this.exchange&&(this.exchange=e,this.forgetHeight())}title(){return this.config.showSymbol?[(0,t.tickerOf)(this.symbol),this.timeframe,this.exchange].filter(Boolean).join(` · `):``}titleCells(e,t,n,r,i){let a=[],o=this.title();if(o){let i=`600 ${t}px ${n}`;e.font=i,a.push({label:``,labelWidth:0,value:o,width:e.measureText(o).width,color:r,font:i})}if(this.statusText){let r=`${t}px ${n}`;e.font=r,a.push({label:``,labelWidth:0,value:this.statusText,width:e.measureText(this.statusText).width,color:i,font:r})}return a}priceCells(e,n,r,i,a,o,s,c){let l=`${o}px ${s}`;e.font=l;let u=i.close>=i.open,d=this.pricePrecision??(0,t.autoPricePrecision)(n.priceRange.min,n.priceRange.max),f=e=>n.formatPrice?.(e)??(0,t.formatPrice)(e,d,this.locale),p=[{label:`O`,value:f(i.open),color:c},{label:`H`,value:f(i.high),color:c},{label:`L`,value:f(i.low),color:c},{label:`C`,value:f(i.close),color:u?r.candleUp:r.candleDown}];if(this.config.showChange){let e=i.close-a.close,n=a.close===0?0:e/a.close*100,o=e>=0?`+`:``,s=(0,t.formatPrice)(n,2,this.locale);p.push({label:``,value:`${o}${f(e)} (${o}${s}%)`,color:e>=0?r.candleUp:r.candleDown})}return p.map(t=>({...t,labelWidth:t.label?e.measureText(t.label+` `).width:0,width:pw(e,t.value),font:l}))}setSpacing(e){e.inset===this.inset&&e.top===this.top&&e.lineGap===this.lineGap||(this.inset=e.inset,this.top=e.top,this.lineGap=e.lineGap,this.drawnHeight=null)}getInset(){return this.inset}getHeight(){if(!this.config.visible||this.config.position!==`top-left`)return 0;if(this.drawnHeight!==null)return this.drawnHeight;let e=this.config.fontSize,t=this.top;return(this.config.showOHLC||this.title()||this.statusText)&&(t+=e+this.lineGap),this.config.showVolume&&(t+=e+2),t}getWidth(){return!this.config.visible||this.config.position!==`top-left`?0:this.drawnWidth}render(e,n,r,i){if(!this.config.visible)return this.reportResize();if(i.length===0)return;let a=this.hoverBar??i[i.length-1],o=this.hoverBar?this.hoverPrev??a:i.length>1?i[i.length-2]:a,{chartRect:s}=n,c=this.config.fontSize,l=this.config.fontFamily??r.font.family,u=r.style?.legend.text??r.text,d=r.style?.legend.label??r.textSecondary,f=this.config.position===`top-left`,p=f?s.x+this.inset:s.x+s.width-this.inset,m=s.y+this.top;e.textAlign=f?`left`:`right`,e.textBaseline=`top`;let h=0,g=this.titleCells(e,c,l,u,d);if(this.config.showOHLC&&g.push(...this.priceCells(e,n,r,a,o,c,l,u)),g.length>0){e.font=`${c}px ${l}`;let t=e.measureText(` `).width;for(let n of fw(g,t,s.width-2*this.inset)){let i=n.reduce((e,n)=>e+n.labelWidth+n.width+t,-t);h=Math.max(h,i);let a=f?p:p-i;this.drawGround(e,r,a,m,i,c),e.textAlign=`left`;for(let r of n)e.font=r.font,r.label&&(e.fillStyle=d,e.fillText(r.label,a,m),a+=r.labelWidth),e.fillStyle=r.color,e.fillText(r.value,a,m),a+=r.width+t;m+=c+this.lineGap}e.textAlign=f?`left`:`right`}if(this.config.showVolume){e.font=`${c}px ${l}`,e.fillStyle=d;let n=(0,t.formatVolumeLoc)(a.volume,this.locale),i=e.measureText(`Vol ${n}`).width;this.drawGround(e,r,f?p:p-i,m,i,c),e.fillStyle=d,e.fillText(`Vol ${n}`,p,m),h=Math.max(h,i),m+=c+2}if(this.drawnHeight=f?m-s.y:null,this.drawnWidth=f?this.inset+h:0,this.reportResize(),this.indicators.length>0){e.font=`${c}px ${l}`;let t=e.measureText(` `).width,n=this.indicators.map(t=>{let n=`${t.name} ${t.value}`;return{entry:n,color:t.color,width:pw(e,n)}}),i=n.reduce((e,n)=>e+n.width+t,-t),a=f?p:p-i;this.drawGround(e,r,a,m,i,c),e.textAlign=`left`;for(let{entry:r,color:i,width:o}of n)e.fillStyle=i,e.fillText(r,a,m),a+=o+t}}drawGround(e,t,n,r,i,a){!this.config.ground||i<=0||(e.save(),e.globalAlpha=lw,e.fillStyle=t.background,e.fillRect(n-uw,r-dw,i+2*uw,a+this.lineGap),e.restore())}},{legendTop:ow,legendInset:sw,legendLineGap:cw}=t.CHART_SPACING[t.DEFAULT_CHART_DENSITY],lw=.72,uw=3,dw=1;function fw(e,t,n){let r=[],i=[],a=0;for(let o of e){let e=o.labelWidth+o.width;i.length>0&&a+t+e>n&&(r.push(i),i=[],a=0),a+=(i.length>0?t:0)+e,i.push(o)}return i.length>0&&r.push(i),r}function pw(e,t){let n=t.replace(/\d/g,`0`);return Math.max(e.measureText(t).width,e.measureText(n.replace(/[-−]/g,`+`)).width,e.measureText(n.replace(/\+/g,`-`)).width)}var mw=class{static toDataURL(e,t){return this.compose(e,t)?.toDataURL(`image/png`)??``}static async toBlob(e,t){let n=this.compose(e,t);return n?new Promise(e=>n.toBlob(e,`image/png`)):null}static download(e,t=`chart.png`,n){let r=this.toDataURL(e,n);if(!r)return;let i=document.createElement(`a`);i.href=r,i.download=t,document.body.appendChild(i),i.click(),document.body.removeChild(i)}static compose(e,t){let n=e.querySelectorAll(`canvas`);if(n.length===0)return null;let r=n[0],i=r.width,a=r.height,o=document.createElement(`canvas`);o.width=i,o.height=a;let s=o.getContext(`2d`);t&&(s.fillStyle=t,s.fillRect(0,0,i,a));let c=Array.from(n).sort((e,t)=>(parseInt(e.style.zIndex)||0)-(parseInt(t.style.zIndex)||0));for(let e of c)s.drawImage(e,0,0);return o}},hw=class{config=null;setConfig(e){this.config=e}isVisible(){return!!this.config?.text}render(e,t,n){if(!this.config?.text)return;let{chartRect:r}=t,i=this.config.fontSize??48,a=n.style?.watermark.color??this.config.color??n.textSecondary;e.save(),e.globalAlpha=.07,e.font=`bold ${i}px ${n.font.family}`,e.fillStyle=a,e.textAlign=`center`,e.textBaseline=`middle`,e.fillText(this.config.text,r.x+r.width/2,r.y+r.height/2),e.restore()}},gw={solid:null,dashed:[6,4],dotted:[2,3]},_w=6;function vw(e,t){let n=[...e].sort((e,t)=>t.rank-e.rank||e.px-t.px),r=[],i=[];for(let e of n){let n=0,a=r.length;for(;n<a;){let t=n+a>>1;r[t]<e.px?n=t+1:a=t}n>0&&e.px-r[n-1]<t||n<r.length&&r[n]-e.px<t||(r.splice(n,0,e.px),i.push(e))}return i.sort((e,t)=>e.px-t.px)}var yw=class{config={visible:!1};cachedBreaksTyped=[];cachedMedianStep=0;cacheValid=!1;lastDataLength=0;firstTime=NaN;lastTime=NaN;tz=null;setConfig(e){Object.assign(this.config,e)}setTimezone(e){e!==this.tz&&(this.tz=e,this.invalidateCache())}isVisible(){return this.config.visible}setVisible(e){this.config.visible=e}computeBreaksTyped(e){if(e.length<2)return[];let n=this.lastDataLength,r=this.cacheValid&&e.length>=n&&e[0].time===this.firstTime&&e[n-1].time===this.lastTime;if(r&&e.length===n)return this.cachedBreaksTyped;let i=r?this.cachedBreaksTyped.slice():[],a=(0,t.barTimeUnit)(e),o=r?n:1,s=(0,t.timeParts)(e[o-1].time*a,this.tz);for(let n=o;n<e.length;n++){let r=(0,t.timeParts)(e[n].time*a,this.tz);if(r.year!==s.year)i.push({idx:n,kind:`year`});else if(r.month!==s.month)i.push({idx:n,kind:`month`});else if(r.day!==s.day){let e=new Date(Date.UTC(r.year,r.month-1,r.day)).getUTCDay()===1;i.push({idx:n,kind:e?`week`:`day`})}s=r}return this.lastDataLength=e.length,this.firstTime=e[0].time,this.lastTime=e[e.length-1].time,this.cachedBreaksTyped=i,r||(this.cachedMedianStep=bw(e)),this.cacheValid=!0,i}render(e,t,n,r){this.renderLines(e,t,n,r)}renderLines(e,t,n,r){let i=this.lineMarks(t,r,n);if(i.length===0)return;let{chartRect:a}=t,o=this.look(n),s=gw[o.style];e.save(),s&&e.setLineDash(s),e.strokeStyle=o.color;for(let t of i)e.globalAlpha=t.alpha,e.lineWidth=t.width,e.beginPath(),e.moveTo(t.px,a.y),e.lineTo(t.px,a.y+a.height),e.stroke();e.restore()}lineRects(e,t,n){let r=this.lineMarks(e,n,t);if(r.length===0)return[];let{color:i,style:a}=this.look(t),o=gw[a]??void 0,{y:s,height:c}=e.chartRect;return r.map(e=>({x:e.px-e.width/2,y:s,width:e.width,height:c,color:i,alpha:e.alpha,...o?{dash:o}:{}}))}look(e){let t=e.style?.sessionBreaks;return{color:t?.color??this.config.color??e.axisLine,style:t?.style??this.config.lineStyle??`dashed`,width:t?.width??this.config.lineWidth??1}}lineMarks(e,t,n){return vw(this.marks(e,t,n),_w)}marks(t,n,r){if(!this.config.visible||n.length<2)return[];let i=this.computeBreaksTyped(n);if(i.length===0||this.cachedMedianStep>=1380*60*1e3)return[];let{chartRect:a}=t,o=this.look(r).width,s=[];for(let n of i){let r=e.C(n.idx,t)-(t.barWidth+t.barSpacing)/2;if(r<a.x-1||r>a.x+a.width+1)continue;let i=Math.round(r)+.5,c=.25,l=o,u=3;n.kind===`day`?(c=.22,u=0):n.kind===`week`?(c=.34,u=1):n.kind===`month`?(c=.5,u=2,l=o+.5):(c=.7,l=o+1),s.push({px:i,width:l,alpha:c,rank:u})}return s}invalidateCache(){this.lastDataLength=0,this.cachedBreaksTyped=[],this.cachedMedianStep=0,this.cacheValid=!1}};function bw(e){if(e.length<2)return 0;let n=Math.min(50,e.length-1),r=(0,t.barTimeUnit)(e),i=[];for(let t=1;t<=n;t++)i.push((e[t].time-e[t-1].time)*r);return i.sort((e,t)=>e-t),i[Math.floor(i.length/2)]}var xw=864e5;function Sw(e,t){let n={...e,...t};return t.tzOffsetMinutes!==void 0&&t.timeZone===void 0&&delete n.timeZone,n.windows?n.windows=n.windows.map(e=>({...e})):delete n.windows,n}function Cw(e,t){let n=((e+t*6e4)%xw+xw)%xw;return Math.floor(n/6e4)}function ww(e,t,n){return t===n?!0:t<n?e>=t&&e<n:e>=t||e<n}function Tw(e,n){let r=Cw(e,n.timeZone?(0,t.zoneOffsetMinutes)(n.timeZone,e):n.tzOffsetMinutes??0);return n.windows&&n.windows.length>0?n.windows.some(e=>ww(r,e.startMinute,e.endMinute)):ww(r,n.startMinute,n.endMinute)}var Ew={startMinute:570,endMinute:960,tzOffsetMinutes:-300,timeZone:`America/New_York`},Dw=class{visible=!1;config={...Ew};setVisible(e){this.visible=e}isVisible(){return this.visible}setConfig(e){this.config=Sw(this.config,e)}replaceConfig(e){this.config=Sw(e,{})}getConfig(){return{...this.config,windows:this.config.windows?.map(e=>({...e}))}}render(e,t,n,r){let i=this.rects(t,n,r);if(i.length!==0){e.save(),e.fillStyle=i[0].color;for(let t of i)e.fillRect(t.x,t.y,t.width,t.height);e.restore()}}rects(t,n,r){if(!this.visible||t.length===0)return[];let{chartRect:i}=n,{from:a,to:o}=n.visibleRange,s=Math.max(0,a),c=Math.min(o,t.length-1);if(c<s)return[];let l=n.barWidth+n.barSpacing,u=r.name===`light`?`rgba(0,0,0,0.045)`:`rgba(0,0,0,0.28)`,d=[],f=-1,p=(t,r)=>{let a=e.C(t,n)-l/2,o=e.C(r,n)+l/2;d.push({x:a,y:i.y,width:o-a,height:i.height,color:u,alpha:1})};for(let e=s;e<=c;e++){let n=!Tw(t[e].time,this.config);n&&f===-1?f=e:!n&&f!==-1&&(p(f,e-1),f=-1)}return f!==-1&&p(f,c),d}},Ow=[2,3],kw=16,Aw=class{highLow=!1;quote=null;quoteShown=!0;priceText=null;setPriceText(e){this.priceText=e}setQuoteShown(e){this.quoteShown=e}setHighLow(e){this.highLow=e}isHighLowVisible(){return this.highLow}setBidAsk(e){this.quote=e?{...e}:null}getBidAsk(){return this.quote?{...this.quote}:null}levels(e,t){let n=[];if(this.highLow){let r=Math.max(0,t.visibleRange.from),i=Math.min(e.length-1,t.visibleRange.to),a=-1/0,o=1/0;for(let t=r;t<=i;t++)e[t].high>a&&(a=e[t].high),e[t].low<o&&(o=e[t].low);Number.isFinite(a)&&n.push({kind:`high`,price:a}),Number.isFinite(o)&&n.push({kind:`low`,price:o})}let{bid:r,ask:i}=(this.quoteShown?this.quote:null)??{};return r!==void 0&&Number.isFinite(r)&&n.push({kind:`bid`,price:r}),i!==void 0&&Number.isFinite(i)&&n.push({kind:`ask`,price:i}),n}render(t,n,r,i){let{chartRect:a}=n;t.save(),t.setLineDash(Ow),t.lineWidth=1;for(let o of this.levels(i,n)){let i=Math.round(e.O(o.price,n))+.5;i<a.y||i>a.y+a.height||(t.strokeStyle=jw(o.kind,r),t.beginPath(),e.y(t,a.x,a.x+a.width,i),t.stroke())}t.restore()}renderAxisTags(n,r,i,a,o){let{chartRect:s}=r,c=s.x+s.width+1,l=(r.priceAxisWidth??t.PRICE_AXIS_WIDTH)-2,u=(0,t.autoPricePrecision)(r.priceRange.min,r.priceRange.max);n.save(),n.font=`${i.font.sizeSmall}px ${i.font.family}`,n.textBaseline=`middle`,n.textAlign=`left`;for(let d of this.levels(a,r)){let a=e.O(d.price,r);if(a<s.y||a>s.y+s.height)continue;let f=o?.get(d.kind)??a;if(Number.isNaN(f))continue;n.fillStyle=jw(d.kind,i),A(n,c,f-kw/2,l,kw,i),n.fillStyle=i.background;let p=r.formatPrice?.(d.price)??this.priceText?.(d.price)??(0,t.formatPrice)(d.price,u);n.fillText(p,c+5,f)}n.restore()}};function jw(e,t){switch(e){case`bid`:return t.candleUp;case`ask`:return t.candleDown;default:return t.style?.highLow.color??t.textSecondary}}var Mw=12,Nw=3,Pw=500,Fw=2,Iw=[`movesUp`,`movesDown`];function Lw(e){return e.channel===`price`&&!e.drawingId&&!e.target&&!Iw.includes(e.condition)}function Rw(e,t,n,r){switch(r){case`crossingUp`:return e!==void 0&&e<n&&t>=n;case`crossingDown`:return e!==void 0&&e>n&&t<=n;case`crossing`:return e!==void 0&&(e<n&&t>=n||e>n&&t<=n);case`greaterThan`:return t>n;case`lessThan`:return t<n;default:return!1}}var zw=[`crossing`,`crossingUp`,`crossingDown`];function Bw(e,t,n){let r=e<0&&t>=0,i=e>0&&t<=0;return n===`crossingUp`?r:n===`crossingDown`?i:r||i}var Vw=1,Hw=2**31-1,Uw=class extends Xx{alerts=[];lastValues=new Map;drawingSides=new Map;drawingLevels=null;requestRender=null;pricePrecision=null;barTime=null;expiryTimer=null;history=new Map;lastDiffs=new Map;setBarTime(e){this.barTime=e}setRequestRender(e){this.requestRender=e}setPricePrecision(e){this.pricePrecision=e}addAlert(e,t=`crossing`,n,r=!1,i=`price`,a,o={}){let s=Ww(t,i,o),c=`tc_alert_${Vw++}`,l={id:c,price:e,condition:t,message:n,triggered:!1,repeating:r,channel:i,label:a,...s};return this.alerts.push(l),s.expiresAt!==void 0&&this.scheduleExpiry(),this.emit(`added`,l),this.requestRender?.(),c}setDrawingLevels(e){this.drawingLevels=e}addDrawingAlert(e,t=`crossing`,n,r=!1,i){if(!zw.includes(t))throw RangeError(`An alert on a drawing takes a crossing condition, not "${t}"`);let a=`tc_alert_${Vw++}`,o={id:a,price:this.drawingLevels?.(e)?.[0]??NaN,condition:t,message:n,triggered:!1,repeating:r,channel:`price`,label:i,drawingId:e};return this.alerts.push(o),this.emit(`added`,o),a}removeDrawingAlerts(e){for(let t of this.alerts.filter(t=>t.drawingId===e))this.removeAlert(t.id)}takeDrawingAlerts(e){let t=this.alerts.filter(t=>t.drawingId===e);for(let e of t)this.removeAlert(e.id);return t.map(e=>({...e}))}restoreAlerts(e){for(let t of e){if(this.alerts.some(e=>e.id===t.id))continue;let e={...t};this.alerts.push(e),this.emit(`added`,e)}this.scheduleExpiry(),this.requestRender?.()}pruneDrawingAlerts(e){let t=this.alerts.filter(t=>t.drawingId!==void 0&&!e.has(t.drawingId));for(let e of t)this.removeAlert(e.id);return t.length}removeAlert(e){this.drawingSides.delete(e),this.lastDiffs.delete(e);let t=this.alerts.some(t=>t.id===e&&t.expiresAt!==void 0);this.alerts=this.alerts.filter(t=>t.id!==e),t&&this.scheduleExpiry(),this.emit(`removed`,e),this.requestRender?.()}getAlerts(){return[...this.alerts]}getAlertAtPoint(t,n,r=6){let{chartRect:i}=n;if(t.y<i.y||t.y>i.y+i.height)return null;let a=null,o=r;for(let r of this.alerts){if(!Lw(r))continue;let i=Math.abs(e.O(r.price,n)-t.y);i<=o&&(o=i,a=r)}return a}updateAlertPrice(e,t){let n=this.alerts.find(t=>t.id===e);!n||!Number.isFinite(t)||(n.price=t,n.triggered=!1,n.expiresAt!==void 0&&this.scheduleExpiry(),this.emit(`updated`,{...n}),this.requestRender?.())}clearAlerts(){this.alerts=[],this.lastDiffs.clear(),this.drawingSides.clear(),this.scheduleExpiry(),this.requestRender?.()}checkPrice(e){this.checkChannel(`price`,e),this.checkDrawingAlerts(e)}checkDrawings(e){this.checkDrawingAlerts(e)}expire(){let e=Date.now(),t=this.alerts.filter(t=>!t.expired&&t.expiresAt!==void 0&&e>=t.expiresAt&&!(t.triggered&&!t.repeating));if(t.length!==0){for(let e of t)e.expired=!0;try{for(let e of t)this.emit(`expired`,{...e}),this.emit(`updated`,{...e})}finally{this.requestRender?.(),this.scheduleExpiry()}}}scheduleExpiry(){this.expiryTimer&&clearTimeout(this.expiryTimer),this.expiryTimer=null;let e=Math.min(...this.alerts.filter(e=>!e.expired&&e.expiresAt!==void 0&&!(e.triggered&&!e.repeating)).map(e=>e.expiresAt));if(!Number.isFinite(e))return;let t=Math.min(Math.max(0,e-Date.now()),Hw);this.expiryTimer=setTimeout(()=>{this.expiryTimer=null,this.expire(),this.expiryTimer||this.scheduleExpiry()},t)}dispose(){this.expiryTimer&&clearTimeout(this.expiryTimer),this.expiryTimer=null}checkDrawingAlerts(e){if(!(!this.drawingLevels||!Number.isFinite(e)))for(let t of this.alerts){if(!t.drawingId||t.expired)continue;let n=this.drawingLevels(t.drawingId);if(!n||n.length===0){this.drawingSides.delete(t.id);continue}t.price=n[0];let r=n.map(t=>Math.sign(e-t)),i=this.drawingSides.get(t.id);this.drawingSides.set(t.id,r),!(!i||i.length!==r.length)&&(r.some((e,n)=>Bw(i[n],e,t.condition))?t.triggered||(t.triggered=!0,this.emit(`triggered`,{...t})):t.repeating&&(t.triggered=!1))}}checkChannel(e,t){this.checkChannels(new Map([[e,t]]))}checkChannels(e,t={}){let n=(e instanceof Map?[...e.entries()]:Object.entries(e)).filter(([,e])=>Number.isFinite(e));if(n.length===0)return;this.expire();let r=new Map,i=new Map;for(let[e,t]of n){r.set(e,this.lastValues.get(e));let n=this.recordBar(e,t);n&&i.set(e,n),this.lastValues.set(e,t)}for(let e of this.alerts){if(e.drawingId||e.expired)continue;let n=r.has(e.channel),a=e.target!==void 0&&r.has(e.target);if(!n&&!a||e.target!==void 0&&t.together&&!(n&&a))continue;let o;if(e.onBarClose){let t=i.get(e.channel)??(e.target?i.get(e.target):void 0);if(!t)continue;o=this.closedBarMet(e,t)}else if(e.target)o=this.targetMet(e);else if(Iw.includes(e.condition)){if(!n)continue;o=this.moveMet(e,this.history.get(e.channel)??[])}else{let t=r.get(e.channel);if(!n||t===void 0)continue;o=Rw(t,this.lastValues.get(e.channel),e.price,e.condition)}this.settle(e,o)}}settle(e,t){t?e.triggered||(e.triggered=!0,this.emit(`triggered`,{...e})):e.repeating&&(e.triggered=!1)}targetMet(e){let t=this.lastValues.get(e.channel),n=e.target?this.lastValues.get(e.target):void 0;if(t===void 0||n===void 0)return!1;let r=t-n,i=this.lastDiffs.get(e.id);return this.lastDiffs.set(e.id,r),e.price=n,Rw(i,r,0,e.condition)}moveMet(e,t,n=t.length){let r=e.bars??1,i=t.slice(Math.max(0,n-r),n);if(i.length<2||e.percent===void 0)return!1;let a=i[i.length-1].value,o=i.map(e=>e.value);if(e.condition===`movesUp`){let t=Math.min(...o);return t!==0&&(a-t)/Math.abs(t)*100>=e.percent}let s=Math.max(...o);return s!==0&&(s-a)/Math.abs(s)*100>=e.percent}closedBarMet(e,t){let n=this.history.get(e.channel)??[],r=n.findIndex(e=>e.time===t.time);if(r<0)return!1;if(Iw.includes(e.condition))return this.moveMet(e,n,r+1);let i=(e,t)=>{let r=this.history.get(e)??[],i=n[t]?.time;return i===void 0?void 0:r.find(e=>e.time===i)?.value},a=n[r].value,o=r>0?n[r-1].value:void 0,s=e.price;if(e.target){let t=i(e.target,r),n=r>0?i(e.target,r-1):void 0;if(t===void 0)return!1;a-=t,o=o!==void 0&&n!==void 0?o-n:void 0,s=0,e.price=t}return Rw(o,a,s,e.condition)}recordBar(e,t){let n=this.barTime;if(n===null)return null;let r=this.history.get(e)??[],i=r[r.length-1];if(i&&n<i.time)return r=r.filter(e=>e.time<n),r.push({time:n,value:t}),this.history.set(e,r),null;if(i&&i.time===n)return r[r.length-1]={time:n,value:t},null;i=r[r.length-1],r.push({time:n,value:t});let a=Math.min(502,Math.max(3,...this.alerts.map(e=>(e.bars??1)+2)));return r.length>a&&r.splice(0,r.length-a),this.history.set(e,r),i?{channel:e,time:i.time}:null}seedLastValue(e,t){Number.isFinite(t)&&this.lastValues.set(e,t)}clearLastValues(){this.lastValues.clear(),this.drawingSides.clear(),this.history.clear(),this.lastDiffs.clear()}saveToStorage(e){try{let t=this.alerts.map(e=>({id:e.id,price:e.price,condition:e.condition,message:e.message,triggered:e.triggered,repeating:e.repeating,channel:e.channel,label:e.label,drawingId:e.drawingId,target:e.target,percent:e.percent,bars:e.bars,onBarClose:e.onBarClose,expiresAt:e.expiresAt,expired:e.expired}));localStorage.setItem(e,JSON.stringify(t))}catch{}}loadFromStorage(e){try{let t=localStorage.getItem(e);if(!t)return;let n=JSON.parse(t);if(!Array.isArray(n))return;for(let e of n){if(typeof e.drawingId==`string`&&e.condition&&!e.triggered){zw.includes(e.condition)&&this.addDrawingAlert(e.drawingId,e.condition,e.message,e.repeating??!1,e.label);continue}if(!e.condition||e.triggered||e.expired)continue;let t=Gw(e),n=!t.target&&!Iw.includes(e.condition),r=typeof e.price==`number`&&Number.isFinite(e.price)?e.price:NaN;if(!(n&&Number.isNaN(r)))try{this.addAlert(r,e.condition,e.message,e.repeating??!1,e.channel??`price`,e.label,t)}catch{}}}catch{}}render(n,r,i){let{chartRect:a}=r;for(let o of this.alerts){if(!Lw(o))continue;let s=e.O(o.price,r);if(s<a.y||s>a.y+a.height)continue;let c=o.expired?`#8a93a3`:o.triggered?`#f2a93b`:`#4c8dff`;n.setLineDash([2,6]),n.strokeStyle=c,n.lineWidth=1,n.beginPath(),e.y(n,a.x,a.x+a.width,Math.round(s)+.5),n.stroke(),n.setLineDash([]),n.font=`10px ${i.font.family}`,n.fillStyle=c,n.textBaseline=`bottom`,n.textAlign=`right`;let l=`${(0,t.priceTagText)(o.price,r,this.pricePrecision??void 0)}${o.message?` - ${o.message}`:``}`,u=a.x+a.width-4;n.fillText(l,u,s-2);let d=u-n.measureText(l).width-Nw-Mw;d>=a.x&&Pb(n,t.UI_ICONS.bell,d,s-2-Mw,Mw,c)}}};function Ww(e,t,n){let r={},i=Iw.includes(e);if(n.target!==void 0){if(i)throw RangeError(`An alert on a move takes no other line`);if(n.target===t)throw RangeError(`An alert can’t compare a line with itself`);r.target=n.target}if(i){let{percent:e,bars:t}=n;if(e===void 0||!Number.isFinite(e)||e<=0)throw RangeError(`An alert on a move needs a percent above 0`);if(t===void 0||!Number.isInteger(t)||t<2||t>500)throw RangeError(`An alert on a move needs 2 to 500 bars`);r.percent=e,r.bars=t}return n.onBarClose&&(r.onBarClose=!0),n.expiresAt!==void 0&&Number.isFinite(n.expiresAt)&&(r.expiresAt=n.expiresAt),r}function Gw(e){let t={};return typeof e.target==`string`&&e.target&&(t.target=e.target),typeof e.percent==`number`&&Number.isFinite(e.percent)&&(t.percent=e.percent),typeof e.bars==`number`&&Number.isInteger(e.bars)&&(t.bars=e.bars),e.onBarClose===!0&&(t.onBarClose=!0),typeof e.expiresAt==`number`&&Number.isFinite(e.expiresAt)&&(t.expiresAt=e.expiresAt),t}var Kw=16,qw=3*Kw,Jw=1e3/30,Yw=1e-9,Xw=()=>typeof requestAnimationFrame==`function`&&!(typeof document<`u`&&document.hidden),Zw={now:()=>typeof performance<`u`?performance.now():Date.now(),frame:e=>Xw()?{raf:requestAnimationFrame(e)}:{timeout:setTimeout(e,Kw)},cancel:e=>{let t=e;t.raf!==void 0&&cancelAnimationFrame(t.raf),t.timeout!==void 0&&clearTimeout(t.timeout)}},Qw=class extends Xx{data=[];cursor=-1;timer=null;frameHandle=null;run=0;state=`stopped`;config={speed:1,interval:500};paceMs=null;owedMs=0;constructor(e=Zw){super(),this.clock=e}load(e){this.stop(),this.data=e,this.cursor=-1,this.owedMs=0}play(e){if(this.data.length===0)return;if(e){let{startIndex:t,paused:n,duration:r,...i}=e;this.config={...this.config,...i};let a=t===void 0?null:this.clamp(t);if(n){this.clearTimer(),this.seekTo(a??Math.max(0,this.cursor)),this.setPace(r),this.setState(`paused`);return}a!==null&&(this.cursor=a-1,this.owedMs=0),this.setPace(r)}if(this.isAtEnd()){this.clearTimer(),this.setState(`paused`);return}this.clearTimer();let t=this.stepMs();if(!(t>0)||!Number.isFinite(t)){this.setState(`paused`);return}this.setState(`playing`),this.config.animate?this.runForming(t):t<Kw||this.paceMs!==null?this.runFrames(t):this.timer=setInterval(()=>this.advance(1),t)}pause(){this.clearTimer(),this.setState(`paused`)}resume(){this.state===`paused`&&this.play()}stop(){this.clearTimer(),this.cursor=-1,this.owedMs=0,this.setState(`stopped`)}seekTo(e){this.data.length!==0&&(this.cursor=this.clamp(e),this.owedMs=0,this.emit(`bar`,{bar:this.data[this.cursor],index:this.cursor,total:this.data.length}))}setSpeed(e){let t=this.getFraction();this.config={...this.config,speed:e},this.paceMs=null;let n=this.stepMs();this.owedMs=n>0&&Number.isFinite(n)?t*n:0,this.state===`playing`&&this.play()}getState(){return this.state}isAtEnd(){return this.data.length>0&&this.cursor>=this.data.length-1}getProgress(){let e=this.data.length;return{current:Math.max(0,this.cursor),total:e,percent:e>0?(this.cursor+1)/e*100:0}}remainingMs(){return this.paceMs===null?null:this.paceMs*Math.max(0,this.data.length-1-this.cursor)}getStepMs(){return this.stepMs()}getFraction(){let e=this.stepMs();return e>0&&Number.isFinite(e)?Math.min(1,this.owedMs/e):0}dispose(){this.stop(),this.removeAllListeners(),this.data=[]}setPace(e){this.paceMs=e!==void 0&&e>0&&Number.isFinite(e)?e/Math.max(1,this.data.length-1-this.cursor):null}runFrames(e){let t=this.run,n=this.clock.now(),r=0,i=()=>{if(t!==this.run||this.state!==`playing`)return;this.frameHandle=null;let a=this.clock.now();r+=Math.min(50,Math.max(0,a-n)),n=a;let o=Math.floor(r/e);try{o>0&&(r-=o*e,this.advance(o))}finally{t===this.run&&this.state===`playing`&&this.frameHandle===null&&(this.frameHandle=this.clock.frame(i))}};this.frameHandle=this.clock.frame(i)}stepMs(){return this.paceMs??this.config.interval/this.config.speed}runForming(e){let t=this.run,n=e>=qw,r=this.clock.now(),i=-1/0,a=r=>{!n||this.isAtEnd()||t!==this.run||this.state!==`playing`||(i=r,this.emit(`phase`,{index:this.cursor+1,fraction:Math.min(1,this.owedMs/e)}))},o=()=>{if(t!==this.run||this.state!==`playing`)return;this.frameHandle=null;let n=this.clock.now();this.owedMs+=Math.min(50,Math.max(0,n-r)),r=n;let s=Math.floor((this.owedMs+Yw)/e);try{s>0?(this.owedMs=Math.max(0,this.owedMs-s*e),this.advance(s),a(n)):n-i+Kw/2>=Jw&&a(n)}finally{t===this.run&&this.state===`playing`&&this.frameHandle===null&&(this.frameHandle=this.clock.frame(o))}};a(r),this.frameHandle=this.clock.frame(o)}advance(e){if(this.isAtEnd()){this.finish();return}this.cursor=Math.min(this.data.length-1,this.cursor+e),this.emit(`bar`,{bar:this.data[this.cursor],index:this.cursor,total:this.data.length}),this.isAtEnd()&&this.finish()}finish(){this.clearTimer(),this.setState(`paused`),this.emit(`complete`,void 0)}clamp(e){return Number.isFinite(e)?Math.max(0,Math.min(Math.floor(e),this.data.length-1)):0}clearTimer(){this.run++,this.timer&&=(clearInterval(this.timer),null),this.frameHandle!==null&&(this.clock.cancel(this.frameHandle),this.frameHandle=null)}setState(e){this.state!==e&&(this.state=e,this.emit(`stateChange`,e))}},$w=64,eT=3,tT=3;function $(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function nT(e){return Array.isArray(e)?e:[]}function rT(e,t){return typeof e==`string`?e:t}function iT(e,t){return typeof e==`number`&&Number.isFinite(e)?e:t}function aT(e){if(!$(e)||typeof e.id!=`string`||typeof e.type!=`string`||!Array.isArray(e.anchors)||e.anchors.length===0||e.anchors.length>oT||!$(e.style))return null;let n=[];for(let t of e.anchors){if(!$(t)||typeof t.time!=`number`||typeof t.price!=`number`||!Number.isFinite(t.time)||!Number.isFinite(t.price))return null;n.push({time:t.time,price:t.price})}let r=(0,t.sanitizeDrawingStyle)(e.style);return r.color===void 0||r.lineWidth===void 0?null:{id:e.id,type:e.type,anchors:n,style:{lineStyle:`solid`,...r,color:r.color,lineWidth:r.lineWidth},visible:typeof e.visible==`boolean`?e.visible:!0,locked:typeof e.locked==`boolean`?e.locked:!1,options:$(e.options)?e.options:void 0,intervals:ja(e.intervals)??void 0,group:uT(e.group),...Lp(e.name)===void 0?{}:{name:Lp(e.name)},...typeof e.paneId==`string`&&e.paneId.length>0&&e.paneId.length<=sT?{paneId:e.paneId}:{},meta:$(e.meta)?e.meta:void 0}}var oT=5e3,sT=200,cT=64,lT=80;function uT(e){if(!(!$(e)||typeof e.id!=`string`||typeof e.name!=`string`)&&!(e.id===``||e.id.length>cT))return{id:e.id,name:e.name.slice(0,lT)}}function dT(e){return!$(e)||typeof e.id!=`string`||typeof e.side!=`string`||typeof e.type!=`string`||typeof e.price!=`number`||typeof e.quantity!=`number`?null:e}function fT(e){if(!$(e))return;let n={},r=nT(e.colors).filter(e=>typeof e==`string`);r.length>0&&(n.colors=r);let i=nT(e.lineWidths).filter(e=>typeof e==`number`&&Number.isFinite(e)&&e>0);i.length>0&&(n.lineWidths=i),typeof e.opacity==`number`&&Number.isFinite(e.opacity)&&(n.opacity=Math.min(1,Math.max(0,e.opacity)));let a=(0,t.readIndicatorPlotStyles)(e.plots);return a&&(n.plots=a),Object.keys(n).length>0?n:void 0}var pT=[`crossingUp`,`crossingDown`,`crossing`,`greaterThan`,`lessThan`,`movesUp`,`movesDown`];function mT(e){if(!$(e)||typeof e.id!=`string`)return null;let t=typeof e.drawingId==`string`?e.drawingId:void 0,n=typeof e.price==`number`&&Number.isFinite(e.price)?e.price:null,r=pT.find(t=>t===e.condition)??`crossing`,i=Gw(e),a=i.target!==void 0||r===`movesUp`||r===`movesDown`;return n===null&&!t&&!a?null:{id:e.id,price:n??NaN,drawingId:t,condition:r,message:typeof e.message==`string`?e.message:void 0,triggered:e.triggered===!0,repeating:e.repeating===!0,channel:rT(e.channel,`price`),label:typeof e.label==`string`?e.label:void 0,...i,...e.expired===!0?{expired:!0}:{}}}function hT(e){return!$(e)||typeof e.id!=`string`||typeof e.side!=`string`||typeof e.entryPrice!=`number`||typeof e.quantity!=`number`?null:e}var gT=4e3;function _T(e){if(!$(e))return;let n={},r=[];for(let[i,a]of Object.entries(e)){let e=(0,t.readChartStyleOverrides)(a);r.push(...e.rejected);let o=Object.fromEntries(Object.entries(e.overrides).filter(([,e])=>e!==null));Object.keys(o).length>0&&(n[i.slice(0,$w)]=o)}return r.length>0&&console.warn(`Saved style overrides left out: ${[...new Set(r)].join(`, `)}`),n}function vT(e){if(!$(e))return yT();typeof e.version==`number`&&e.version>tT&&console.warn(`Chart state from a newer version (${e.version}); loading what this version understands.`);let n=$(e.viewport)?e.viewport:{},r=[];for(let n of nT(e.indicators))$(n)&&(typeof n.id!=`string`||typeof n.instanceId!=`string`||$(n.params)&&r.push({id:n.id,instanceId:n.instanceId,params:n.params,position:typeof n.position==`string`?n.position:void 0,style:fT(n.style),visible:typeof n.visible==`boolean`?n.visible:void 0,levels:Array.isArray(n.levels)?n.levels.filter(e=>typeof e==`number`&&Number.isFinite(e)):void 0,pane:typeof n.pane==`string`?n.pane:void 0,scale:n.scale===`left`?`left`:void 0,intervals:ja(n.intervals)??void 0,paneStyle:(0,t.readPaneStyle)(n.paneStyle)??void 0,paneSize:typeof n.paneSize==`number`&&Number.isFinite(n.paneSize)&&n.paneSize>0?Math.min(n.paneSize,gT):void 0,paneOrder:typeof n.paneOrder==`number`&&Number.isInteger(n.paneOrder)&&n.paneOrder>=0?n.paneOrder:void 0,paneCollapsed:n.paneCollapsed===!0?!0:void 0,paneMaximized:n.paneMaximized===!0?!0:void 0,paneLog:n.paneLog===!0?!0:void 0,paneInvert:n.paneInvert===!0?!0:void 0,panePercent:n.panePercent===!0?!0:void 0}));let i=[];for(let t of nT(e.drawings)){let e=aT(t);e&&i.push(e)}let a=[];for(let t of nT(e.orders)){let e=dT(t);e&&a.push(e)}let o=[];for(let t of nT(e.positions)){let e=hT(t);e&&o.push(e)}let s=[];for(let t of nT(e.alerts)){let e=mT(t);e&&s.push(e)}let c=_T(e.overrides);return{version:typeof e.version==`number`&&Array.isArray(e.indicators)?e.version:1,timestamp:iT(e.timestamp,Date.now()),symbol:typeof e.symbol==`string`?e.symbol:void 0,timeframe:typeof e.timeframe==`string`?e.timeframe:void 0,chartType:rT(e.chartType,`candlestick`),...e.chartTypeOptions===void 0?{}:{chartTypeOptions:(0,t.readChartTypeOptions)(e.chartTypeOptions)},viewport:{barWidth:iT(n.barWidth,8),barSpacing:iT(n.barSpacing,2),offset:iT(n.offset,0)},theme:typeof e.theme==`string`?e.theme:void 0,...c?{overrides:c}:{},locale:typeof e.locale==`string`?e.locale:void 0,indicators:r,drawings:i,orders:a,positions:o,alerts:s}}function yT(){return{version:1,timestamp:Date.now(),chartType:`candlestick`,viewport:{barWidth:8,barSpacing:2,offset:0},indicators:[],drawings:[],orders:[],positions:[],alerts:[]}}var bT=class{static capture(e,t){return{version:e.getIndicators?tT:1,timestamp:Date.now(),chartType:t?.chartType??`candlestick`,...t?.chartTypeOptions&&Object.keys(t.chartTypeOptions).length>0?{chartTypeOptions:t.chartTypeOptions}:{},symbol:t?.symbol,timeframe:t?.timeframe,viewport:{barWidth:8,barSpacing:2,offset:0},theme:e.getTheme().name,...e.getOverrides&&Object.keys(e.getOverrides()).length>0?{overrides:e.getOverrides()}:{},indicators:e.getIndicators?.()??[],drawings:e.getDrawings(),orders:e.getOrders?.()??[],positions:e.getPositions?.()??[],alerts:e.getAlerts?.()??[]}}static serialize(e){return JSON.stringify(e)}static deserialize(e){return vT(JSON.parse(e))}static saveToStorage(e,t){localStorage.setItem(e,this.serialize(t))}static loadFromStorage(e){let t=localStorage.getItem(e);return t?this.deserialize(t):null}static downloadFile(e,t=`tc-chart-state.json`){let n=new Blob([this.serialize(e)],{type:`application/json`}),r=URL.createObjectURL(n),i=document.createElement(`a`);i.href=r,i.download=t,document.body.appendChild(i),i.click(),document.body.removeChild(i),URL.revokeObjectURL(r)}static loadFromFile(){return new Promise((e,t)=>{let n=document.createElement(`input`);n.type=`file`,n.accept=`.json`,n.onchange=async()=>{let r=n.files?.[0];if(!r){t(Error(`No file selected`));return}let i=await r.text();e(this.deserialize(i))},n.click()})}},xT=class{undoStack=[];redoStack=[];maxHistory=50;onChange=null;grouped=null;setOnChange(e){this.onChange=e}push(e){if(this.grouped){this.grouped.push(e);return}this.undoStack.push(e),this.undoStack.length>this.maxHistory&&this.undoStack.shift(),this.redoStack.length=0,this.onChange?.()}canUndo(){return this.undoStack.length>0}canRedo(){return this.redoStack.length>0}undo(){let e=this.undoStack.pop();return e?(this.redoStack.push(e),this.onChange?.(),e):null}redo(){let e=this.redoStack.pop();return e?(this.undoStack.push(e),this.onChange?.(),e):null}clear(){this.undoStack.length=0,this.redoStack.length=0,this.onChange?.()}group(e){if(this.grouped)return e();let t=[];this.grouped=t;try{return e()}finally{this.grouped=null,t.length===1?this.push(t[0]):t.length>1&&this.push({type:`drawingBatch`,before:null,after:null,actions:t})}}last(){return this.grouped?this.grouped[this.grouped.length-1]??null:this.undoStack[this.undoStack.length-1]??null}dropLast(){if(this.grouped){this.grouped.pop();return}this.undoStack.pop()&&(this.redoStack.length=0,this.onChange?.())}replaceLast(e){if(this.grouped){this.grouped.length>0?this.grouped[this.grouped.length-1]=e:this.grouped.push(e);return}if(this.undoStack.length===0){this.push(e);return}this.undoStack[this.undoStack.length-1]=e,this.redoStack.length=0,this.onChange?.()}getState(){return{canUndo:this.undoStack.length>0,canRedo:this.redoStack.length>0,undoCount:this.undoStack.length,redoCount:this.redoStack.length}}},ST=[`Time`,`Open`,`High`,`Low`,`Close`,`Volume`];function CT(e,n){return new Date((0,t.normalizeBarTime)(e,n)).toISOString()}function wT(e){let t=/^[=+\-@\t\r]/.test(e)&&!/^-?\d/.test(e)?`'${e}`:e;return/[",\r\n]/.test(t)?`"${t.replace(/"/g,`""`)}"`:t}var TT=15,ET=0x38d7ea4c68000;function DT(e){return e==null||!Number.isFinite(e)?null:Number.isInteger(e)||Math.abs(e)>=ET?e:Number(e.toPrecision(TT))}var OT=e=>{let t=DT(e);return t===null?``:String(t)},kT=class{static toCSV(e,n=[]){let r=[...ST,...n.map(e=>wT(e.name))].join(`,`),i=(0,t.barTimeUnit)(e);return[r,...e.map((e,t)=>[CT(e.time,i),...[e.open,e.high,e.low,e.close,e.volume].map(OT),...n.map(e=>OT(e.values[t]))].join(`,`))].join(`
24
+ `,t.addEventListener(`mouseenter`,()=>{t.style.background=`#1f2630`}),t.addEventListener(`mouseleave`,()=>{t.style.background=`transparent`}),t.addEventListener(`click`,()=>{this.onItemSelect?.(e.intent),this.hide()}),s.appendChild(t)}n.appendChild(s),this.menuElement=s;let l=e=>{(e instanceof KeyboardEvent&&e.key===`Escape`||e instanceof MouseEvent&&!s.contains(e.target))&&this.hide()};document.addEventListener(`mousedown`,l),document.addEventListener(`keydown`,l),this.removeHandler=()=>{document.removeEventListener(`mousedown`,l),document.removeEventListener(`keydown`,l)}}hide(){this.menuElement?.remove(),this.menuElement=null,this.removeHandler?.(),this.removeHandler=null}destroy(){this.hide(),this.onItemSelect=null}};function vx(e,t,n={}){let r=Math.max(Math.abs(t)*(n.riskFraction??.01),1e-8),i=r*(n.riskReward??2);return e===`buy`?{side:e,entry:t,stopLoss:t-r,takeProfit:t+i}:{side:e,entry:t,stopLoss:t+r,takeProfit:t-i}}function yx(e){let t=Math.abs(e.entry-e.stopLoss);return t===0?0:Math.abs(e.takeProfit-e.entry)/t}var bx=6,xx=.12,Sx=[6,3],Cx=class{draft=null;dragStart=null;dragging=null;defaults;constructor(e={}){this.defaults=e}start(e,t){this.draft=vx(e,t,this.defaults),this.dragging=null}cancel(){this.draft=null,this.dragging=null}isActive(){return this.draft!==null}getDraft(){return this.draft?{...this.draft}:null}hitTest(t,n,r=bx){if(!this.draft)return null;let i=[`entry`,`sl`,`tp`],a=null,o=r;for(let r of i){let i=e.O(this.priceOf(r),n),s=Math.abs(i-t.y);s<=o&&(o=s,a=r)}return a}beginDrag(e,t,n){let r=this.hitTest(e,t,n);return r!==null&&this.beginDragOn(r)}beginDragOn(e){return this.draft?(this.dragging=e,this.dragStart=this.draft,!0):!1}cancelDrag(){this.dragging&&this.dragStart&&(this.draft=this.dragStart),this.dragging=null,this.dragStart=null}drag(t,n){if(!this.draft||!this.dragging)return!1;let r=e.F(t.y,n);return this.draft=Tx(this.draft,this.dragging,r),!0}endDrag(){this.dragging=null,this.dragStart=null}isDragging(){return this.dragging!==null}priceOf(e){let t=this.draft;return e===`entry`?t.entry:e===`sl`?t.stopLoss:t.takeProfit}render(e,t,n,r){this.renderLines(e,t,n),Ub(e,this.tags(t,n),t,n,[])}renderLines(t,n,r){let i=this.draft;if(!i)return;let{chartRect:a}=n,o=e.O(i.entry,n),s=e.O(i.stopLoss,n),c=e.O(i.takeProfit,n),{profit:l,loss:u}=wx(r);t.save(),t.globalAlpha=xx,t.fillStyle=l,t.fillRect(a.x,Math.min(o,c),a.width,Math.abs(c-o)),t.fillStyle=u,t.fillRect(a.x,Math.min(o,s),a.width,Math.abs(s-o)),t.globalAlpha=1,xb(t,n,o,r.text,Sx),xb(t,n,c,l,[]),xb(t,n,s,u,[]),t.restore()}tags(t,n){let r=this.draft;if(!r)return[];let{profit:i,loss:a}=wx(n),o=r.side===`buy`?1:-1,s=e=>{let t=r.entry===0?0:(e-r.entry)/r.entry*100*o;return`${t>=0?`+`:``}${t.toFixed(2)}%`};return[{y:e.O(r.entry,t),color:n.text,grab:{kind:`bracket`,handle:`entry`},cells:[{kind:`stamp`,text:r.side===`buy`?`Long`:`Short`},{kind:`text`,text:`${yx(r).toFixed(2)}R`}]},{y:e.O(r.takeProfit,t),color:i,grab:{kind:`bracket`,handle:`tp`},cells:[{kind:`stamp`,text:`TP`},{kind:`text`,text:s(r.takeProfit),color:i}]},{y:e.O(r.stopLoss,t),color:a,grab:{kind:`bracket`,handle:`sl`},cells:[{kind:`stamp`,text:`SL`},{kind:`text`,text:s(r.stopLoss),color:a}]}].filter(e=>X(e.y,t))}renderAxisBadges(e,t,n,r){for(let i of this.axisBadges(t,n,r))Kb(e,i.y,i.text,i.color,t,n)}axisBadges(n,r,i){let a=this.draft;if(!a)return[];let{profit:o,loss:s}=wx(r),c=[];for(let[l,u]of[[a.takeProfit,o],[a.stopLoss,s],[a.entry,r.text]]){let r=e.O(l,n);X(r,n)&&c.push({y:r,text:(0,t.priceTagText)(l,n,i),color:u})}return c}};function wx(e){return{profit:e.style?.trading.profit??e.candleUp,loss:e.style?.trading.loss??e.candleDown}}function Tx(e,t,n){let r=e.side===`buy`;if(t===`entry`){let t=n-e.entry;return{side:e.side,entry:n,stopLoss:e.stopLoss+t,takeProfit:e.takeProfit+t}}if(t===`sl`){let t=r?Math.min(n,e.entry):Math.max(n,e.entry);return{...e,stopLoss:t}}let i=r?Math.max(n,e.entry):Math.min(n,e.entry);return{...e,takeProfit:i}}function Ex(e,t,n){return n==null?`limit`:e===`buy`?t<=n?`limit`:`stop`:t>=n?`limit`:`stop`}var Dx=6,Ox=[6,3],kx=class{draft=null;dragStart=null;dragging=!1;start(e,t,n=1){this.draft={side:e,price:t,quantity:n},this.dragging=!1}cancel(){this.draft=null,this.dragging=!1}isActive(){return this.draft!==null}isDragging(){return this.dragging}getDraft(){return this.draft?{...this.draft}:null}setPrice(e){return this.draft?(this.draft={...this.draft,price:e},!0):!1}toIntent(e){return this.draft?{side:this.draft.side,type:Ex(this.draft.side,this.draft.price,e),price:this.draft.price,quantity:this.draft.quantity}:null}hitTest(t,n,r=Dx){return this.draft?Math.abs(e.O(this.draft.price,n)-t.y)<=r:!1}beginDrag(e,t,n){return this.hitTest(e,t,n)&&this.beginDragOn()}beginDragOn(){return this.draft?(this.dragging=!0,this.dragStart=this.draft,!0):!1}cancelDrag(){this.dragging&&this.dragStart&&(this.draft=this.dragStart),this.dragging=!1,this.dragStart=null}drag(t,n){return!this.draft||!this.dragging?!1:this.setPrice(e.F(t.y,n))}endDrag(){this.dragging=!1,this.dragStart=null}render(e,t,n,r,i){this.renderLines(e,t,n),Ub(e,this.tags(t,n,r),t,n,[])}renderLines(t,n,r){let i=this.draft;i&&(t.save(),xb(t,n,e.O(i.price,n),Ax(i.side,r),Ox),t.restore())}tags(t,n,r){let i=this.draft;if(!i)return[];let a=e.O(i.price,t);if(!X(a,t))return[];let o=Ex(i.side,i.price,r);return[{y:a,color:Ax(i.side,n),grab:{kind:`draft`},cells:[{kind:`stamp`,text:String(i.quantity)},{kind:`text`,text:Zb({side:i.side,type:o})}]}]}renderAxisBadges(e,t,n,r){for(let i of this.axisBadges(t,n,r))Kb(e,i.y,i.text,i.color,t,n)}axisBadges(n,r,i){let a=this.draft;if(!a)return[];let o=e.O(a.price,n);return X(o,n)?[{y:o,text:(0,t.priceTagText)(a.price,n,i),color:Ax(a.side,r)}]:[]}};function Ax(e,t){return e===`buy`?t.style?.trading.buy??t.candleUp:t.style?.trading.sell??t.candleDown}var jx=2;function Mx(e,t){return e.type===t.type?e.type===`cancelOrder`?e.orderId===t.orderId:e.type===`removeStop`?e.positionId===t.positionId&&e.which===t.which:e.positionId===t.positionId:!1}function Nx(e,t,n=jx){let r=(e,n)=>t.x>=e.x-n&&t.x<=e.x+e.size+n&&t.y>=e.y-n&&t.y<=e.y+e.size+n;for(let t=e.length-1;t>=0;t--)if(r(e[t],0))return e[t];let i=null,a=1/0;for(let o of e){if(!r(o,n))continue;let e=Math.hypot(t.x-(o.x+o.size/2),t.y-(o.y+o.size/2));e<a&&(a=e,i=o)}return i}var Px=5,Fx=7,Ix=2;function Lx(e,n){let r=n.data;return r&&r.length>0?e/(0,t.barTimeUnit)(r):e}function Rx(t,n,r,i){if(n.length===0)return;let{chartRect:a}=r,o=i.orderColors?.buy??`#1fa874`,s=i.orderColors?.sell??`#e8505b`;t.lineWidth=1.5;for(let i of n){let n=e.j(Lx(i.time,r),r),c=e.O(i.price,r);if(n<a.x||n>a.x+a.width||c<a.y||c>a.y+a.height)continue;let l=i.side===`buy`,u=l?c+Ix:c-Ix,d=l?u+Fx:u-Fx;t.beginPath(),t.moveTo(n,u),t.lineTo(n-Px,d),t.lineTo(n+Px,d),t.closePath();let f=l?o:s;!i.reason||i.reason===`order`?(t.fillStyle=f,t.fill()):(t.strokeStyle=f,t.stroke())}}function zx(e){for(let t in e)if(e[t]!==null)return!0;return!1}function Bx(e,t){let n={};for(let r of Object.keys(e)){let i=e[r];i!==null&&(n[t[r]]=i)}return n}function Vx(e,t){let n=t.style?.trading;return!n||!zx(n)?e:{...e,orderColors:{...e.orderColors,...Bx({buy:n.buy,sell:n.sell},{buy:`buy`,sell:`sell`})},positionColors:{...e.positionColors,...Bx({profit:n.profit,loss:n.loss,entry:n.entry},{profit:`profit`,loss:`loss`,entry:`entry`})}}}function Hx(e,t){let n=t.style?.markers;return!n||!zx(n)?e:{...e,...Bx(n,{long:`longColor`,short:`shortColor`,neutral:`neutralColor`})}}function Ux(e,t){let n=t.style?.tradeZones;return!n||!zx(n)?e:{...e,...Bx(n,{profit:`profitColor`,loss:`lossColor`,active:`activeColor`})}}var Wx=1e3,Gx=class{orders=[];positions=[];depthData=null;currentPrice=null;config;orderRenderer=new tx;positionRenderer=new px;depthOverlay=new mx;dragHandler;contextMenu=new _x;bracket=new Cx;orderDraft=new kx;buttons=[];tagBoxes=[];tagInset=0;drawnTags=[];grabOffset=0;fills=[];realisedPnl=0;requestRender=null;eventCallback=null;container=null;constructor(e){this.config={...t.DEFAULT_TRADING_CONFIG,...e},this.dragHandler=new gx(this.config.dragThreshold),this.contextMenu.onItemSelect=e=>{this.eventCallback?.(`orderPlace`,e)}}setContainer(e){this.container=e}setRequestRender(e){this.requestRender=e}setEventCallback(e){this.eventCallback=e}setOrders(e){this.orders=e,this.requestRender?.()}setPositions(e){this.positions=e,this.requestRender?.()}getOrders(){return[...this.orders]}getPositions(){return[...this.positions]}getCurrentPrice(){return this.currentPrice}setDepthData(e){this.depthData=e,this.requestRender?.()}setCurrentPrice(e){this.currentPrice=e,this.requestRender?.()}setConfig(e){Object.assign(this.config,e),this.requestRender?.()}addFill(e){this.fills=[...this.fills.slice(-(Wx-1)),e],this.realisedPnl+=e.pnl??0,this.requestRender?.()}setFills(e){this.fills=e.slice(-Wx),this.realisedPnl=e.reduce((e,t)=>e+(t.pnl??0),0),this.requestRender?.()}getRealisedPnl(){return this.realisedPnl}getFills(){return[...this.fills]}armed=null;isOverButton(e){return this.config.enabled&&Nx(this.buttons,e)!==null}runButton(e){switch(e.type){case`cancelOrder`:this.eventCallback?.(`orderCancel`,{orderId:e.orderId});break;case`closePosition`:this.eventCallback?.(`positionClose`,{positionId:e.positionId});break;case`reversePosition`:this.eventCallback?.(`positionReverse`,{positionId:e.positionId});break;case`removeStop`:this.eventCallback?.(`positionModify`,{positionId:e.positionId,[e.which]:null});break}}startBracket(e,t){this.bracket.start(e,t),this.requestRender?.()}cancelBracket(){this.bracket.isActive()&&(this.bracket.cancel(),this.requestRender?.())}confirmBracket(){let e=this.bracket.getDraft();return e?(this.eventCallback?.(`bracketPlace`,{side:e.side,entry:e.entry,stopLoss:e.stopLoss,takeProfit:e.takeProfit,riskReward:yx(e)}),this.bracket.cancel(),this.requestRender?.(),!0):!1}isBracketActive(){return this.bracket.isActive()}startOrderDraft(e,t){this.orderDraft.start(e,t),this.requestRender?.()}cancelOrderDraft(){this.orderDraft.isActive()&&(this.orderDraft.cancel(),this.requestRender?.())}confirmOrderDraft(){let e=this.orderDraft.toIntent(this.currentPrice);return e?(this.eventCallback?.(`orderPlace`,e),this.orderDraft.cancel(),this.requestRender?.(),!0):!1}isOrderDraftActive(){return this.orderDraft.isActive()}isOverDraggableLine(t,n,r=8){if(!this.config.enabled)return!1;if(Rb(this.tagBoxes,t.x,t.y)&&!Nx(this.buttons,t))return!0;let i=i=>{if(i===void 0)return!1;let a=e.O(i,n);return X(a,n)&&Math.abs(t.y-a)<=r};for(let e of this.orders)if(e.draggable!==!1&&i(e.price))return!0;for(let e of this.positions)if(i(e.stopLoss)||i(e.takeProfit))return!0;return!1}onPointerDown(e,t,n){if(!this.config.enabled)return!1;let r=Nx(this.buttons,e,n?.button),i=r?null:Rb(this.tagBoxes,e.x,e.y);return i&&this.grabTag(i,e)||(this.grabOffset=0,this.bracket.isActive()&&this.bracket.beginDrag(e,t,n?.handle))||this.orderDraft.isActive()&&this.orderDraft.beginDrag(e,t,n?.handle)?(this.requestRender?.(),!0):r?(this.armed=r.action,!0):this.dragHandler.onPointerDown(e,this.orders,this.positions,t,n?.order??8)}grabTag(e,t){this.grabOffset=e.lineY-t.y;let n=e.grab;switch(n.kind){case`bracket`:return this.bracket.beginDragOn(n.handle);case`draft`:return this.orderDraft.beginDragOn();case`order`:{let t=this.orders.find(e=>e.id===n.orderId);return t!==void 0&&this.dragHandler.beginOrder(t,e.lineY)}case`stop`:{let t=this.positions.find(e=>e.id===n.positionId);return t!==void 0&&this.dragHandler.beginStop(t,n.which,e.lineY)}}}onPointerMove(e,t){if(this.armed)return!0;let n=this.grabOffset===0?e:{x:e.x,y:bb(e.y+this.grabOffset,t)};if(this.bracket.isDragging()){let e=this.bracket.drag(n,t);return e&&this.requestRender?.(),e}if(this.orderDraft.isDragging()){let e=this.orderDraft.drag(n,t);return e&&this.requestRender?.(),e}if(!this.dragHandler.isActive())return!1;let r=this.dragHandler.onPointerMove(n,t);return r&&this.requestRender?.(),r}onPointerUp(e){if(this.grabOffset=0,this.armed){let t=this.armed;this.armed=null;let n=e?Nx(this.buttons,e):null;return n&&Mx(n.action,t)&&this.runButton(t),!0}if(this.bracket.isDragging())return this.bracket.endDrag(),this.requestRender?.(),!0;if(this.orderDraft.isDragging())return this.orderDraft.endDrag(),this.requestRender?.(),!0;let t=this.dragHandler.onPointerUp();return t?(t.sourceType===`order`?this.eventCallback?.(`orderModify`,{orderId:t.id,newPrice:t.newPrice,previousPrice:t.previousPrice}):this.eventCallback?.(`positionModify`,{positionId:t.id,[t.sourceType]:t.newPrice}),this.requestRender?.(),!0):!1}cancelPointer(){this.grabOffset=0;let e=!1;return this.armed&&(this.armed=null,e=!0),this.bracket.isDragging()&&(this.bracket.cancelDrag(),e=!0),this.orderDraft.isDragging()&&(this.orderDraft.cancelDrag(),e=!0),this.dragHandler.cancel()&&(e=!0),e&&this.requestRender?.(),e}onContextMenu(n,r){if(!this.config.enabled||!this.config.contextMenu?.enabled||!this.container)return!1;let i=e.F(n.y,r);return this.contextMenu.show(n,i,this.container,this.config,e=>(0,t.priceTagText)(e,r,this.config.pricePrecision)),!0}tagRects(){return this.drawnTags}setTagInset(e){this.tagInset=Math.max(0,e)}render(e,t,n){if(this.buttons=[],this.tagBoxes=[],this.drawnTags=[],!this.config.enabled)return;let{chartRect:r}=t;e.save();try{e.beginPath(),e.rect(r.x,r.y,r.width,r.height),e.clip(),this.renderInPlot(e,t,n)}finally{e.restore()}}renderInPlot(e,t,n){let r=Vx(this.config,n);this.depthData&&this.depthOverlay.render(e,this.depthData,t,r),r.fillMarks!==!1&&Rx(e,this.fills,t,r);let i=this.dragHandler.getDragState();this.positionRenderer.renderLines(e,this.positions,this.currentPrice,t,r,i),this.orderRenderer.renderLines(e,this.orders,t,r,i),this.bracket.renderLines(e,t,n),this.orderDraft.renderLines(e,t,n),Ub(e,[...this.bracket.tags(t,n),...this.orderDraft.tags(t,n,this.currentPrice),...this.positionRenderer.tags(this.positions,this.currentPrice,t,r,i),...this.orderRenderer.tags(this.orders,t,r,i)],t,n,this.buttons,this.tagBoxes,this.tagInset,this.drawnTags)}renderAxisBadges(e,t,n,r){if(this.config.enabled){if(r){let{chartRect:i}=t;this.sortedAxisBadges(t,n).forEach((a,o)=>{let s=r[o]??a.y;!Number.isFinite(s)||s-16/2<i.y-.5||s+16/2>i.y+i.height+.5||Kb(e,s,a.text,a.color,t,n)});return}for(let r of Gb(this.axisBadges(t,n),t))Kb(e,r.at,r.text,r.color,t,n)}}axisBadgeLines(e,n=t.DARK_THEME){return this.config.enabled?this.sortedAxisBadges(e,n).map(e=>e.y):[]}sortedAxisBadges(e,t){return this.axisBadges(e,t).sort((e,t)=>e.y-t.y)}axisBadges(e,t){let n=Vx(this.config,t);return[...this.positionRenderer.axisBadges(this.positions,e,n,this.dragHandler.getDragState()),...this.orderRenderer.axisBadges(this.orders,e,n,this.dragHandler.getDragState()),...this.bracket.axisBadges(e,t,this.config.pricePrecision),...this.orderDraft.axisBadges(e,t,this.config.pricePrecision)]}axisTagYs(e,n=t.DARK_THEME){return this.config.enabled?Gb(this.axisBadges(e,n),e).map(e=>e.at):[]}destroy(){this.contextMenu.destroy()}},Kx=class{constructor(e){this.manager=e}render(e,t,n){this.manager.render(e,t,n)}renderAxisBadges(e,t,n,r){this.manager.renderAxisBadges(e,t,n,r)}axisBadgeLines(e,t){return this.manager.axisBadgeLines(e,t)}tagRects(){return this.manager.tagRects()}axisTagYs(e,t){return this.manager.axisTagYs(e,t)}},qx=class{name=`paper`;state=`disconnected`;listeners=new Map;orders=[];positions=[];markPrice;markTime;seq=0;constructor(e={}){this.markPrice=e.markPrice??0}connect(e){this.state=`connected`,this.emit(`connectionChange`,this.state),this.emit(`orders`,this.orders),this.emit(`positions`,this.positions)}disconnect(){this.state=`disconnected`,this.emit(`connectionChange`,this.state)}getConnectionState(){return this.state}setMarkPrice(e,t){this.markPrice=e,this.markTime=t!==void 0&&Number.isFinite(t)?t:void 0,this.checkPendingOrders(),this.checkStops()}fillTime(){return this.markTime??Date.now()}getOrders(){return[...this.orders]}getPositions(){return[...this.positions]}async placeOrder(e){let t={id:this.nextId(`ord`),side:e.side,type:e.type,price:e.price,stopPrice:e.stopPrice,quantity:e.quantity??1,label:e.type===`market`?void 0:Yx(e.type),draggable:!0,stopLoss:e.stopLoss,takeProfit:e.takeProfit,timeInForce:e.timeInForce};return e.type===`market`?this.fill(t,this.markPrice||e.price):(this.orders=[...this.orders,t],this.emit(`orders`,this.orders)),t}async modifyOrder(e){this.orders=this.orders.map(t=>t.id===e.orderId?{...t,price:e.newPrice}:t),this.emit(`orders`,this.orders)}async cancelOrder(e){this.orders=this.orders.filter(t=>t.id!==e.orderId),this.emit(`orders`,this.orders)}async modifyPosition(e){let t=(e,t)=>e===void 0?t:e??void 0;this.positions=this.positions.map(n=>n.id===e.positionId?{...n,stopLoss:t(e.stopLoss,n.stopLoss),takeProfit:t(e.takeProfit,n.takeProfit)}:n),this.emit(`positions`,this.positions)}async closePosition(e){let t=this.positions.find(t=>t.id===e.positionId);t&&(this.close(t,this.markPrice||t.entryPrice,`close`),this.emit(`positions`,this.positions))}async reversePosition(e){let t=this.positions.find(t=>t.id===e.positionId);if(!t)return;let n=this.markPrice||t.entryPrice;this.close(t,n,`reverse`);let r=t.quantity-(t.closedQuantity??0),i={id:this.nextId(`ord`),side:Jx(t.side),type:`market`,price:n,quantity:r};this.fill(i,n)}on(e,t){let n=this.listeners.get(e);n||(n=new Set,this.listeners.set(e,n)),n.add(t)}off(e,t){this.listeners.get(e)?.delete(t)}dispose(){this.disconnect(),this.listeners.clear(),this.orders=[],this.positions=[]}fill(e,t){this.orders=this.orders.filter(t=>t.id!==e.id);let n={id:this.nextId(`pos`),side:e.side,entryPrice:t,quantity:e.quantity,stopLoss:e.stopLoss,takeProfit:e.takeProfit};this.positions=[...this.positions,n];let r={orderId:e.id,side:e.side,price:t,quantity:e.quantity,time:this.fillTime(),positionId:n.id,reason:`order`};this.emit(`fill`,r),this.emit(`orders`,this.orders),this.emit(`positions`,this.positions)}close(e,t,n){this.positions=this.positions.filter(t=>t.id!==e.id);let r=e.quantity-(e.closedQuantity??0),i=e.side===`buy`?1:-1;this.emit(`fill`,{orderId:this.nextId(`ord`),side:Jx(e.side),price:t,quantity:r,time:this.fillTime(),positionId:e.id,reason:n,pnl:(t-e.entryPrice)*r*i})}checkPendingOrders(){let e=this.orders.filter(e=>this.isTriggered(e));for(let t of e)this.fill(t,t.type===`limit`?t.price:t.stopPrice??t.price)}isTriggered(e){if(e.type===`limit`)return e.side===`buy`?this.markPrice<=e.price:this.markPrice>=e.price;if(e.type===`stop`||e.type===`stopLimit`){let t=e.stopPrice??e.price;return e.side===`buy`?this.markPrice>=t:this.markPrice<=t}return!1}checkStops(){let e=!1;for(let t of[...this.positions]){let n=t.stopLoss!==void 0&&(t.side===`buy`?this.markPrice<=t.stopLoss:this.markPrice>=t.stopLoss),r=t.takeProfit!==void 0&&(t.side===`buy`?this.markPrice>=t.takeProfit:this.markPrice<=t.takeProfit);!n&&!r||(this.close(t,n?t.stopLoss:t.takeProfit,n?`stopLoss`:`takeProfit`),e=!0)}e&&this.emit(`positions`,this.positions)}nextId(e){return`${e}-${++this.seq}`}emit(e,t){let n=this.listeners.get(e);if(n){let r={type:e,data:t,timestamp:Date.now()};for(let e of n)e(r)}}};function Jx(e){return e===`buy`?`sell`:`buy`}function Yx(e){switch(e){case`stop`:return`STOP`;case`stopLimit`:return`STOP LIMIT`;default:return`LIMIT`}}var Xx=class{listeners=new Map;on(e,t){let n=this.listeners.get(e);return n||(n=new Set,this.listeners.set(e,n)),n.add(t),()=>n.delete(t)}once(e,t){let n=this.on(e,e=>{n(),t(e)});return n}off(e,t){this.listeners.get(e)?.delete(t)}emit(e,t){let n=this.listeners.get(e);if(n)for(let e of n)e(t)}removeAllListeners(){this.listeners.clear()}},Zx=6e4,Qx=e=>[e.open,e.high,e.low,e.close].every(Number.isFinite),$x=class extends Xx{currentBar=null;newest=-1/0;builtFromTrades=!1;lastTradeAt=null;timeframe;timeframeMs;dateFrame;bucket={};dateStamps=!1;tickRing;ringHead=0;ringCount=0;ringCapacity;constructor(e,n=1e3){super(),this.timeframe=e,this.timeframeMs=(0,t.timeframeToMs)(e),this.dateFrame=(0,t.timeframeSpansDays)(e),this.ringCapacity=n,this.tickRing=Array(n)}setTimeframe(e){this.timeframe=e,this.timeframeMs=(0,t.timeframeToMs)(e),this.dateFrame=(0,t.timeframeSpansDays)(e),this.reset()}seed(e){this.builtOffTheBuckets()&&(this.currentBar=null,this.newest=-1/0,this.lastTradeAt=null),Number.isFinite(e)&&(this.newest=Math.max(this.newest,(0,t.normalizeBarTime)(e)))}resume(e){if(!Qx(e))return;let n=(0,t.normalizeBarTime)(e.time);n<this.newest||(this.newest=n,this.currentBar={time:n,open:e.open,high:e.high,low:e.low,close:e.close,volume:e.volume??0,closed:!1,tickCount:0},this.builtFromTrades=!0,this.lastTradeAt=null)}setTimeZone(e,t=!1){this.bucket={timeZone:e??void 0},this.dateStamps=t}processTick(e){let n=(this.ringHead+this.ringCount)%this.ringCapacity;this.tickRing[n]=e,this.ringCount<this.ringCapacity?this.ringCount++:this.ringHead=(this.ringHead+1)%this.ringCapacity;let r=this.barFor(e.time);r!==null&&(this.newest=(0,t.normalizeBarTime)(r),this.lastTradeAt=e.time,!this.currentBar||this.currentBar.time!==r?(this.currentBar&&(this.currentBar.closed=!0,this.emit(`barClose`,this.currentBar)),this.currentBar={time:r,open:e.price,high:e.price,low:e.price,close:e.price,volume:e.volume,closed:!1,tickCount:1},this.builtFromTrades=!0):(this.currentBar.high=Math.max(this.currentBar.high,e.price),this.currentBar.low=Math.min(this.currentBar.low,e.price),this.currentBar.close=e.price,this.currentBar.volume+=e.volume,this.currentBar.tickCount++),this.emit(`bar`,this.currentBar))}processBar(e,n){let r=(0,t.normalizeBarTime)(e.time);if(r<this.newest){n&&this.emit(`correction`,{...e});return}if(this.newest=r,this.builtFromTrades=!1,n&&this.currentBar&&(0,t.normalizeBarTime)(this.currentBar.time)===r)this.currentBar={...e,closed:!0,tickCount:this.currentBar.tickCount+1},this.emit(`barClose`,this.currentBar),this.currentBar=null;else if(!n)this.currentBar={...e,closed:!1,tickCount:(this.currentBar?.tickCount??0)+1},this.emit(`bar`,this.currentBar);else{let t={...e,closed:!0,tickCount:1};this.emit(`barClose`,t),this.currentBar=null}}getCurrentBar(){return this.currentBar?{...this.currentBar}:null}getTickBuffer(){let e=Array(this.ringCount);for(let t=0;t<this.ringCount;t++)e[t]=this.tickRing[(this.ringHead+t)%this.ringCapacity];return e}reset(){this.currentBar=null,this.newest=-1/0,this.builtFromTrades=!1,this.lastTradeAt=null,this.ringHead=0,this.ringCount=0}barFor(e){let n=this.alignToTimeframe(e);if((0,t.normalizeBarTime)(n)>=this.newest)return n;if((0,t.normalizeBarTime)(e)<this.instantOf(this.newest))return null;let r=this.currentBar;return r!==null&&(0,t.normalizeBarTime)(r.time)===this.newest?r.time:this.newest}instantOf(e){return!this.dateStamps||!this.dateFrame?e:e-(0,t.offsetAt)(this.bucket.timeZone??0,e)*Zx}builtOffTheBuckets(){let e=this.currentBar;return e===null||!this.builtFromTrades?!1:this.lastTradeAt===null?!this.startsABucket((0,t.normalizeBarTime)(e.time)):this.alignToTimeframe(this.lastTradeAt)!==e.time}startsABucket(e){return this.timeframeMs>0?this.dateStamps&&this.dateFrame?(0,t.timeframeBucketStart)(e,this.timeframe)===e:this.alignToTimeframe(e)===e:!0}alignToTimeframe(e){if(!(this.timeframeMs>0))return e;let n=(0,t.timeframeBucketStart)(e,this.timeframe,this.bucket);return!this.dateStamps||!this.dateFrame?n:n+(0,t.offsetAt)(this.bucket.timeZone??0,n)*Zx}},eS=class extends Xx{config;attempt=0;timer=null;active=!1;constructor(e){super(),this.config={...t.DEFAULT_RECONNECT,...e}}schedule(e){if(!this.config.enabled||!this.active)return;if(this.cancel(),this.attempt++,this.attempt>this.config.maxRetries){this.emit(`giveUp`,{attempts:this.attempt-1}),this.active=!1;return}let t=this.computeDelay();this.emit(`attempt`,{attempt:this.attempt,delay:t}),this.timer=setTimeout(()=>{this.timer=null,this.active&&e()},t)}onConnected(){this.attempt=0,this.cancel(),this.emit(`success`,void 0)}start(){this.active=!0}stop(){this.active=!1,this.cancel(),this.attempt=0}cancel(){this.timer&&=(clearTimeout(this.timer),null)}getAttempt(){return this.attempt}isActive(){return this.active}computeDelay(){let e=this.config.baseDelay,t=this.config.backoffMultiplier**(this.attempt-1),n=Math.min(e*t,this.config.maxDelay),r=n*.25*(Math.random()*2-1);return Math.max(0,Math.round(n+r))}},tS=20,nS=class{price=null;previousClose=null;visible=!0;flashUntil=0;pricePrecision=null;locale=`en-US`;tag=null;setLocale(e){this.locale=e}setPrice(e,t){this.price!==null&&e!==this.price&&(this.flashUntil=Date.now()+300),t===void 0?e!==this.price&&(this.previousClose=this.price??e):this.previousClose=t,this.price=e}setVisible(e){this.visible=e}isVisible(){return this.visible}setPricePrecision(e){this.pricePrecision=e}getPrice(){return this.price}getTag(){return this.tag}render(e,t,n){this.renderLine(e,t,n),this.renderTag(e,t,n)}placed(t,n){let r=n.style?.lastPrice;if(!this.visible||this.price===null||r?.visible===!1)return null;let i=e.O(this.price,t),{chartRect:a}=t;return i<a.y||i>a.y+a.height?null:{y:i,color:this.previousClose===null||this.price>=this.previousClose?r?.up??n.candleUp??`#1fa874`:r?.down??n.candleDown??`#e8505b`}}renderLine(n,r,i){let a=this.placed(r,i);if(!a)return;let{y:o,color:s}=a,{chartRect:c}=r,l=i.style?.lastPrice,u=Date.now()<this.flashUntil,d=l?.width??1;n.setLineDash((0,t.lineDash)(l?.style??`solid`,[4,3],d)),n.strokeStyle=s,n.lineWidth=d,n.globalAlpha=u?1:.7,n.beginPath(),e.y(n,c.x,c.x+c.width,Math.round(o)+.5,d),n.stroke(),n.setLineDash([]),n.globalAlpha=1}renderTag(e,n,r){this.tag=null;let i=this.placed(n,r);if(!i||this.price===null)return;let{y:a,color:o}=i,{chartRect:s}=n,c=s.x+s.width+1,l=this.pricePrecision??(0,t.autoPricePrecision)(n.priceRange.min,n.priceRange.max),u=n.formatPrice?n.formatPrice(this.price):(0,t.formatPrice)(this.price,l,this.locale);e.font=`bold 11px ${r.font.family}`;let d=e.measureText(u).width,f=n.priceAxisWidth??t.PRICE_AXIS_WIDTH,p=Math.min(d+12,f-2);e.fillStyle=o,A(e,c,a-tS/2,p,tS,r),this.tag={x:c,y:a-tS/2,width:p,height:tS,color:o};let m=c-5;e.beginPath(),e.moveTo(m,a),e.lineTo(m+5,a-5),e.lineTo(m+5,a+5),e.closePath(),e.fill(),e.fillStyle=ne(o),e.textBaseline=`middle`,e.textAlign=`left`,e.fillText(u,c+5,a)}},rS=1e3,iS=10,aS=1440,oS=5e3,sS=2,cS=864e5,lS=6e4,uS=[`tick`,`barClose`,`snapshot`,`connectionChange`,`error`,`symbolInfo`],dS=new WeakMap;function fS(e){if(e instanceof vS||!e.supportedTimeframes?.length)return e;let t=dS.get(e);return t||(t=new vS(e,e.supportedTimeframes),dS.set(e,t)),t}function pS(e,n,r){if(n.includes(e))return e;let i=(0,t.pickBaseTimeframe)(e,n,{timeZone:r});return i&&Math.ceil((0,t.timeframeToMs)(e)/(0,t.timeframeToMs)(i))<=1440?i:null}function mS(e,n){if((0,t.tickBarCount)(n)!==null)return typeof e.fetchTrades==`function`&&typeof e.subscribeTrades==`function`;let r=e.supportedTimeframes;return!r?.length||pS(n,r)!==null}function hS(e,n,r){let i=(0,t.parseTimeframe)(n),a=r!==void 0&&(0,t.timeframeSpansDays)(n)&&e%cS!==0,o=a?e+(0,t.offsetAt)(r,e)*lS:e,s;if(i?.unit===`M`){let e=new Date(o);s=Date.UTC(e.getUTCFullYear(),e.getUTCMonth()+i.count,1)}else s=o+(0,t.timeframeToMs)(n);return a?(0,t.wallToUtc)(s,r):s}function gS(e,t){let n=t[0],r={time:e,open:n.open,high:n.high,low:n.low,close:n.close,volume:n.volume};for(let e=1;e<t.length;e++){let n=t[e];n.high>r.high&&(r.high=n.high),n.low<r.low&&(r.low=n.low),r.close=n.close,r.volume+=n.volume}return r}function _S(e,t){return gS(e,[...t.values()].sort((e,t)=>e.time-t.time))}var vS=class{name;fetchHistoryBefore;searchSymbols;resolveSymbol;subscribeQuotes;fetchNews;fetchTrades;subscribeTrades;listeners=new Map;unsubscribe=[];live=null;bucket=null;parts=new Map;closedBuckets=new Map;tail=null;generation=0;zones=new Map;resolving=new Map;unanswered=new Map;constructor(e,t){this.inner=e,this.baseTimeframes=t,this.name=e.name,e.fetchHistoryBefore&&(this.fetchHistoryBefore=(e,t,n,r)=>this.historyBefore(e,t,n,r)),e.searchSymbols&&(this.searchSymbols=e.searchSymbols.bind(e)),e.resolveSymbol&&(this.resolveSymbol=e=>this.resolveShared(e)),e.subscribeQuotes&&(this.subscribeQuotes=e.subscribeQuotes.bind(e)),e.fetchNews&&(this.fetchNews=e.fetchNews.bind(e)),e.fetchTrades&&(this.fetchTrades=e.fetchTrades.bind(e)),e.subscribeTrades&&(this.subscribeTrades=e.subscribeTrades.bind(e)),this.listen(`bar`,e=>this.onBar(e));for(let e of uS)this.listen(e,t=>this.emit(e,t.data))}baseFor(e){let t=pS(e,this.baseTimeframes);if(!t)throw RangeError(`${this.name} cannot serve the ${e} timeframe`);return t}connect(e){let t=this.baseFor(e.timeframe);this.generation++,this.resetBucket(),this.closedBuckets.clear(),this.live=t===e.timeframe?null:{symbol:e.symbol,target:e.timeframe,...this.planFor(e.timeframe,this.keptZone(e.symbol))},this.live&&this.resumeFromHistory(this.live),this.inner.connect({...e,timeframe:this.live?.base??t})}disconnect(){this.generation++,this.inner.disconnect(),this.resetBucket(),this.closedBuckets.clear(),this.live=null}getConnectionState(){return this.inner.getConnectionState()}async fetchHistory(e,t,n=500){if(this.baseFor(t)===t)return this.inner.fetchHistory(e,t,n);let r=this.generation,{plan:i,bars:a}=await this.baseBarsWithZone(e,t,async i=>{let a=this.baseBarsFor(t,i,n),o=await this.inner.fetchHistory(e,i,Math.min(a,rS));return this.extendBack(e,i,o,a,r)});return this.rememberTail(e,t,a,i),this.toTarget(a,t,n,i)}on(e,t){let n=this.listeners.get(e);n||(n=new Set,this.listeners.set(e,n)),n.add(t)}off(e,t){this.listeners.get(e)?.delete(t)}dispose(){this.generation++;for(let e of this.unsubscribe)e();this.unsubscribe.length=0,this.listeners.clear(),this.inner.dispose()}bucketFor(e,t){let n=pS(t,this.baseTimeframes);return n===null||n===t?null:{...this.planFor(t,this.keptZone(e)).bucket}}waitsForZone(e){return typeof this.inner.resolveSymbol==`function`&&(0,t.timeframeFollowsDays)(e)}keptZone(e){return this.zones.get(e)??void 0}renewZone(e){let t=this.unanswered.get(e);if(!t)return;let n=t.zone,r=t.asked!==void 0&&this.resolving.get(e)===t.asked;n===void 0&&r||(this.unanswered.delete(e),n===void 0?this.zones.delete(e):this.zones.set(e,n))}async zoneFor(e){if(this.zones.has(e))return this.keptZone(e);let t,n=new Promise(e=>{t=setTimeout(()=>e(),oS)});try{await Promise.race([this.resolveShared(e),n])}catch{}finally{clearTimeout(t)}return this.zones.has(e)||(this.zones.set(e,null),this.unanswered.set(e,{asked:this.resolving.get(e)})),this.keptZone(e)}resolveShared(e){let t=this.resolving.get(e);if(t)return t;let n=this.inner.resolveSymbol.bind(this.inner),r=Promise.resolve().then(()=>n(e));this.resolving.set(e,r);let i=()=>{this.resolving.get(e)===r&&this.resolving.delete(e)};return r.then(t=>{this.keepZone(e,t),i()},i),r}keepZone(e,n){let r=(0,t.symbolTimeZone)(n),i=r&&(0,t.isValidTimeZone)(r)&&!(0,t.isUtcTimeZone)(r)?r:null,a=this.unanswered.get(e);a?this.unanswered.set(e,{...a,zone:i}):this.zones.has(e)||this.zones.set(e,i)}planFor(e,n){let r=this.baseFor(e),i=n!==void 0&&r!==e&&(0,t.timeframeFollowsDays)(e)?pS(e,this.baseTimeframes,n):null,a=i??r,o=i?n:void 0;return{base:a,zone:o,bucket:{timeZone:o,dates:(0,t.timeframeSpansDays)(a)}}}async historyBefore(e,t,n,r){let i=this.inner.fetchHistoryBefore.bind(this.inner);if(this.baseFor(t)===t)return i(e,t,n,r);let a=this.generation,{plan:o,bars:s}=await this.baseBarsWithZone(e,t,async o=>{let s=this.baseBarsFor(t,o,r),c=await i(e,o,n,Math.min(s,rS));return this.extendBack(e,o,c.filter(e=>e.time<n),s,a,1)});return this.toTarget(s,t,r,o)}async baseBarsWithZone(e,t,n){if(!this.waitsForZone(t)||this.zones.has(e)){let r=this.planFor(t,this.keptZone(e));return{plan:r,bars:await n(r.base)}}let r=this.planFor(t,void 0).base,i=n(r);i.catch(()=>{});let a=this.planFor(t,await this.zoneFor(e));return{plan:a,bars:await(a.base===r?i:n(a.base))}}baseBarsFor(e,n,r){return(r+1)*Math.ceil((0,t.timeframeToMs)(e)/(0,t.timeframeToMs)(n))}async extendBack(e,t,n,r,i,a=1){let o=this.inner.fetchHistoryBefore?.bind(this.inner),s=n,c=a;for(;o&&s.length>0&&s.length<r&&c<10&&i===this.generation;){let n=s[0].time,i=await o(e,t,n,Math.min(r-s.length,rS));c++;let a=i.filter(e=>e.time<n);if(a.length===0)break;s=a.concat(s)}return s}toTarget(e,n,r,i){if(e.length===0)return[];let a=(0,t.resampleBars)(e,n,i.bucket);return a.length>1&&a[0].time!==e[0].time&&a.shift(),a.length>r?a.slice(a.length-r):a}rememberTail(e,n,r,i){if(r.length===0)return;let a=(0,t.timeframeBucketStart)(r[r.length-1].time,n,i.bucket),o=r.length;for(;o>0&&(0,t.timeframeBucketStart)(r[o-1].time,n,i.bucket)===a;)o--;this.tail={symbol:e,target:n,zone:i.zone,bucket:a,bars:r.slice(o)}}resumeFromHistory(e){let t=this.tail;if(!(!t||t.symbol!==e.symbol||t.target!==e.target||t.zone!==e.zone)){this.bucket=t.bucket;for(let e of t.bars)this.parts.set(e.time,e)}}onBar(e){let n=this.live;if(!n){this.emit(`bar`,e.data);return}let{bar:r,closed:i}=e.data,a=(0,t.timeframeBucketStart)(r.time,n.target,n.bucket);if(this.bucket!==null&&a<this.bucket){i&&this.correctClosed(a,r);return}if(this.bucket!==null&&a>this.bucket){let e=this.composed();e&&this.emit(`bar`,{bar:e,closed:!0}),this.keepClosed(),this.resetBucket()}this.bucket=a,this.parts.set(r.time,r);let o=this.composed();if(!o)return;let s=(0,t.timeframeBucketStart)(hS(r.time,n.base,n.zone),n.target,n.bucket),c=i&&s!==a;this.emit(`bar`,{bar:o,closed:c}),c&&(this.keepClosed(),this.resetBucket(),this.bucket=s)}composed(){return this.bucket===null||this.parts.size===0?null:_S(this.bucket,this.parts)}correctClosed(e,t){let n=this.closedBuckets.get(e);n&&(n.set(t.time,t),this.emit(`bar`,{bar:_S(e,n),closed:!0}))}keepClosed(){if(!(this.bucket===null||this.parts.size===0)){this.closedBuckets.set(this.bucket,this.parts);for(let e of this.closedBuckets.keys()){if(this.closedBuckets.size<=2)break;this.closedBuckets.delete(e)}}}resetBucket(){this.bucket=null,this.parts=new Map}listen(e,t){let n=e=>t(e);this.inner.on(e,n),this.unsubscribe.push(()=>this.inner.off(e,n))}emit(e,t){let n=this.listeners.get(e);if(!n)return;let r={type:e,data:t,timestamp:Date.now()};for(let e of n)e(r)}},yS=1e3,bS=15e3,xS=[`tick`,`bar`,`barClose`,`snapshot`,`connectionChange`,`error`,`symbolInfo`],SS=class{bar=null;count=0;lastTime=-1/0;constructor(e){this.tradesPerBar=e}push(e){let t=[],n=!1;for(let r of e){if(this.bar)this.bar={...this.bar,high:Math.max(this.bar.high,r.price),low:Math.min(this.bar.low,r.price),close:r.price,volume:this.bar.volume+r.volume};else{let e=Math.max(r.time,this.lastTime+1);this.lastTime=e,this.bar={time:e,open:r.price,high:r.price,low:r.price,close:r.price,volume:r.volume},this.count=0}this.count++,n=!0,this.count>=this.tradesPerBar&&(t.push({bar:this.bar,closed:!0}),this.bar=null,n=!1)}return n&&this.bar&&t.push({bar:this.bar,closed:!1}),t}build(e){return this.bar=null,this.count=0,this.lastTime=-1/0,this.push(e).map(e=>e.bar)}},CS=class{name;supportedTimeframes;searchSymbols;resolveSymbol;subscribeQuotes;fetchNews;fetchTrades;subscribeTrades;listeners=new Map;tick=null;stopTrades=null;keepAlive=null;tickMode=!1;state=`disconnected`;constructor(e){this.inner=e,this.name=e.name,this.supportedTimeframes=e.supportedTimeframes,e.searchSymbols&&(this.searchSymbols=e.searchSymbols.bind(e)),e.resolveSymbol&&(this.resolveSymbol=e.resolveSymbol.bind(e)),e.subscribeQuotes&&(this.subscribeQuotes=e.subscribeQuotes.bind(e)),e.fetchNews&&(this.fetchNews=e.fetchNews.bind(e)),this.fetchTrades=e.fetchTrades.bind(e),this.subscribeTrades=e.subscribeTrades.bind(e);for(let t of xS)e.on(t,e=>{this.tickMode||this.emit(t,e.data)})}async fetchHistory(e,n,r){let i=(0,t.tickBarCount)(n);if(i===null)return this.inner.fetchHistory(e,n,r);let a=(await this.inner.fetchTrades(e,yS)).filter(DS).sort((e,t)=>e.time-t.time),o=new SS(i),s=o.build(a);return this.tick={symbol:e,builder:o,after:a.length?a[a.length-1].time:-1/0},r!==void 0&&r>0?s.slice(-r):s}fetchHistoryBefore(e,n,r,i){return(0,t.tickBarCount)(n)!==null||!this.inner.fetchHistoryBefore?Promise.resolve([]):this.inner.fetchHistoryBefore(e,n,r,i)}connect(e){this.disconnect();let n=(0,t.tickBarCount)(e.timeframe);if(n===null){this.tickMode=!1,this.inner.connect(e);return}this.tickMode=!0;let r=this.tick?.symbol===e.symbol?this.tick:{symbol:e.symbol,builder:new SS(n),after:-1/0};this.tick=r,this.stopTrades=this.inner.subscribeTrades(e.symbol,e=>{let t=e.filter(e=>DS(e)&&e.time>=r.after);for(let{bar:e,closed:n}of r.builder.push(t))this.emit(`bar`,{bar:e,closed:n}),this.emit(`tick`,{time:e.time,price:e.close,volume:e.volume})}),this.state=`connected`,this.emit(`connectionChange`,`connected`),this.keepAlive=setInterval(()=>this.emit(`connectionChange`,`connected`),bS)}disconnect(){this.tickMode?(this.stopTrades?.(),this.stopTrades=null,this.keepAlive&&clearInterval(this.keepAlive),this.keepAlive=null,this.state=`disconnected`):this.inner.disconnect()}getConnectionState(){return this.tickMode?this.state:this.inner.getConnectionState()}dispose(){this.stopTrades?.(),this.stopTrades=null,this.keepAlive&&clearInterval(this.keepAlive),this.keepAlive=null,this.listeners.clear(),this.inner.dispose()}on(e,t){let n=this.listeners.get(e);n||(n=new Set,this.listeners.set(e,n)),n.add(t)}off(e,t){this.listeners.get(e)?.delete(t)}emit(e,t){let n=this.listeners.get(e);if(!n)return;let r={type:e,data:t,timestamp:Date.now()};for(let e of n)e(r)}},wS=new WeakMap;function TS(e){if(e instanceof CS||!ES(e))return e;let t=wS.get(e);return t||(t=new CS(e),wS.set(e,t)),t}function ES(e){return typeof e.fetchTrades==`function`&&typeof e.subscribeTrades==`function`}function DS(e){return Number.isFinite(e?.time)&&Number.isFinite(e?.price)&&Number.isFinite(e?.volume)}var OS=Symbol(`tradecanvas.sourceAdapter`),kS=new WeakSet;function AS(e){return kS.has(e)}var jS=(e,t)=>`${e}\u0000${t}`;function MS(e){return typeof e.getBars==`function`&&typeof e.subscribeBars==`function`}function NS(e){if(e.adapter&&e.feed)throw TypeError(`A stream takes an adapter or a feed, not both`);if(e.adapter)return e.adapter;if(e.feed)return IS(e.feed);throw TypeError(`A stream needs an adapter or a feed`)}function PS(e,t,n){for(let r of n){let n=t[r];typeof n==`function`&&(e[r]=n.bind(t))}}var FS=[`resolveSymbol`,`searchSymbols`,`subscribeQuotes`,`fetchNews`,`fetchTrades`,`subscribeTrades`];function IS(e){let t=e[OS];if(t)return t;let n=new LS(e);return kS.add(n),n}var LS=class{name;supportedTimeframes;fetchHistoryBefore;state=`disconnected`;listeners=new Map;unsubscribe=null;requests=new Map;streamed=null;constructor(e){this.feed=e,this.name=e.name,e.supportedTimeframes&&(this.supportedTimeframes=e.supportedTimeframes),e.pagesBack!==!1&&(this.fetchHistoryBefore=(e,t,n,r)=>this.feed.getBars({symbol:e,timeframe:t,countBack:r,before:n,signal:this.signalFor(e,t)})),PS(this,e,FS)}fetchHistory(e,t,n=500){return this.feed.getBars({symbol:e,timeframe:t,countBack:n,signal:this.signalFor(e,t)})}fetchStreamHistory(e,t){return this.streamed=jS(e.symbol,e.timeframe),this.fetchHistory(e.symbol,e.timeframe,t)}connect(e){this.subscribe({symbol:e.symbol,timeframe:e.timeframe})}subscribe(e,t){this.stopSubscription(),this.streamed=jS(e.symbol,e.timeframe);let n=!0,r=!1,i=null;this.unsubscribe=()=>{n=!1,i?.()};let a=e=>{this.setState(e),t?.connection(e)},o=this.feed.subscribeBars(e,{bar:(e,r)=>{n&&(this.emit(`bar`,{bar:e,closed:r}),t?.bar(e,r))},tick:e=>{n&&(this.emit(`tick`,e),t?.tick(e))},connection:e=>{n&&(r=!0,a(e))},symbolInfo:e=>{n&&(this.emit(`symbolInfo`,e),t?.symbolInfo(e))},error:e=>{n&&(this.emit(`error`,{message:e}),t?.error(e))}});if(!n){o();return}i=o,r||a(`connected`)}disconnect(){this.stopSubscription(),this.streamed!==null&&(this.requests.get(this.streamed)?.abort(),this.requests.delete(this.streamed),this.streamed=null),this.state=`disconnected`}getConnectionState(){return this.state}on(e,t){let n=this.listeners.get(e);n||(n=new Set,this.listeners.set(e,n)),n.add(t)}off(e,t){this.listeners.get(e)?.delete(t)}dispose(){this.disconnect(),this.listeners.clear()}signalFor(e,t){let n=jS(e,t),r=this.requests.get(n);return r||(r=new AbortController,this.requests.set(n,r)),r.signal}stopSubscription(){let e=this.unsubscribe;this.unsubscribe=null,e?.()}setState(e){this.state=e,this.emit(`connectionChange`,e)}emit(e,t){let n={type:e,data:t,timestamp:Date.now()};for(let t of[...this.listeners.get(e)??[]])t(n)}};function RS(e){let t={name:e.name,...e.supportedTimeframes?{supportedTimeframes:e.supportedTimeframes}:{},pagesBack:typeof e.fetchHistoryBefore==`function`,getBars:async({symbol:t,timeframe:n,countBack:r,before:i})=>i===void 0?e.fetchHistory(t,n,r):e.fetchHistoryBefore?e.fetchHistoryBefore(t,n,i,r):[],subscribeBars:(t,n)=>zS(e,t,n),[OS]:e};return PS(t,e,FS),t}function zS(e,t,n){let r=[[`bar`,e=>{let{bar:t,closed:r}=e.data;n.bar(t,r)}],[`tick`,e=>n.tick(e.data)],[`connectionChange`,e=>n.connection(e.data)],[`symbolInfo`,e=>n.symbolInfo(e.data)],[`error`,e=>n.error(e.data?.message??`Adapter error`)]];for(let[t,n]of r)e.on(t,n);return e.connect({symbol:t.symbol,timeframe:t.timeframe}),()=>{for(let[t,n]of r)e.off(t,n);e.disconnect()}}function BS(e){let t=NS(e),n=!AS(t),r=fS(t),i=r instanceof vS?r:null,a=TS(r);return a instanceof LS?new VS(a,i,n):new HS(a,i,n)}var VS=class{subscriber=null;constructor(e,t,n){this.adapter=e,this.resampler=t,this.watchSilence=n}listen(e){this.subscriber=e}getBars(e,t){return this.adapter.fetchStreamHistory(e,t)}subscribeBars(e){this.adapter.subscribe(e,this.subscriber??void 0)}unsubscribe(){this.adapter.disconnect()}release(){this.subscriber=null}},HS=class{unlisten=[];constructor(e,t,n){this.adapter=e,this.resampler=t,this.watchSilence=n}listen(e){this.hear(`connectionChange`,t=>e.connection(t.data)),this.hear(`tick`,t=>e.tick(t.data)),this.hear(`bar`,t=>{let{bar:n,closed:r}=t.data;e.bar(n,r)}),this.hear(`error`,t=>e.error(t.data?.message??`Adapter error`));try{this.hear(`symbolInfo`,t=>e.symbolInfo(t?.data))}catch{}}getBars(e,t){return this.adapter.fetchHistory(e.symbol,e.timeframe,t)}subscribeBars(e){this.adapter.connect({symbol:e.symbol,timeframe:e.timeframe})}unsubscribe(){this.adapter.disconnect()}release(){for(let e of this.unlisten)e();this.unlisten=[]}hear(e,t){this.adapter.on(e,t),this.unlisten.push(()=>this.adapter.off(e,t))}},US=2e4,WS=6e4,GS=3e4,KS=500,qS=864e5;function JS(e,n){if(!n)return e;let{time:r,open:i,high:a,low:o,close:s,volume:c}=n;return[...e,{time:(0,t.normalizeBarTime)(r)/(0,t.barTimeUnit)(e),open:i,high:a,low:o,close:s,volume:c}]}function YS(e,n,r){return(0,t.timeframeBucketStart)(e,n,{timeZone:r})===e&&(0,t.timeframeBucketStart)(e,n)!==e}var XS=class extends Xx{config=null;source=null;aggregator=null;reconnector;priceLine=new nS;state=`disconnected`;lastPrice=null;previousClose=null;sentPreviousClose=null;previousCloseTime=null;heartbeatTimer=null;lastMessageTime=0;connectSeq=0;timeZone=null;historyEnd=null;constructor(){super(),this.reconnector=new eS,this.wireReconnector()}async connect(e){this.disconnect();let n=BS(e);n.resampler?.renewZone(e.symbol),this.config={...t.DEFAULT_STREAM_CONFIG,...e},this.source=n,this.aggregator=new $x(e.timeframe),this.historyEnd=null,this.applyTickZone(),this.reconnector.removeAllListeners(),this.reconnector.stop(),this.reconnector=new eS(e.reconnect??t.DEFAULT_RECONNECT),this.wireReconnector(),this.aggregator.on(`bar`,e=>{this.emit(`barUpdate`,e),this.updatePrice(e.close)}),this.aggregator.on(`barClose`,e=>{this.setPreviousClose(e),this.emit(`barClose`,e)}),this.aggregator.on(`correction`,e=>{(0,t.normalizeBarTime)(e.time)===this.previousCloseTime&&(this.previousClose=e.close),this.emit(`barCorrection`,e)}),n.listen(this.subscriber()),this.reconnector.start(),await this.doConnect()}disconnect(){this.connectSeq++,this.reconnector.stop(),this.stopHeartbeat(),this.source&&=(this.source.release(),this.source.unsubscribe(),null),this.aggregator?.reset(),this.aggregator?.removeAllListeners(),this.aggregator=null,this.config=null,this.historyEnd=null,this.lastPrice=null,this.previousClose=null,this.previousCloseTime=null,this.sentPreviousClose=null,this.setState(`disconnected`)}async switchTo(e,t){!this.config||!this.source||(this.reconnector.stop(),this.source.unsubscribe(),this.reconnector.start(),this.aggregator?.reset(),this.aggregator?.setTimeframe(t),this.lastPrice=null,this.previousClose=null,this.previousCloseTime=null,this.sentPreviousClose=null,(e!==this.config.symbol||t!==this.config.timeframe)&&this.source.resampler?.renewZone(e),this.config.symbol=e,this.config.timeframe=t,await this.doConnect())}getConnectionState(){return this.state}setTimeZone(e){if(e!==null&&!(0,t.isValidTimeZone)(e))throw RangeError(`Unknown time zone: ${e}`);this.timeZone=e,this.applyTickZone()}getConnectionInfo(){return{state:this.state,reconnectAttempt:this.reconnector.getAttempt(),lastMessageTime:this.lastMessageTime}}getLastPrice(){return this.lastPrice}applyTickZone(){let e=this.config;if(!this.aggregator||!e)return;let t=this.historyEnd,n=t!==null&&t%qS===0,r=this.source?.resampler?.bucketFor(e.symbol,e.timeframe);if(r){let e=r.dates===!0&&n;this.aggregator.setTimeZone(r.timeZone??(e?this.timeZone:null),e);return}this.aggregator.setTimeZone(this.tickZone(e.timeframe,t),n)}tickZone(e,n){let r=this.timeZone;return r===null||(0,t.timeframeSpansDays)(e)||n!==null&&YS(n,e,r)?r:null}async doConnect(){if(!this.config||!this.source)return;let e=++this.connectSeq,n={symbol:this.config.symbol,timeframe:this.config.timeframe};this.setState(`connecting`);try{let r=await this.source.getBars(n,this.config.historyLimit??KS);if(e!==this.connectSeq||!this.source)return;let i=r.length>0?r[r.length-1]:null;this.historyEnd=i?(0,t.normalizeBarTime)(i.time):null,this.applyTickZone(),this.seedAggregator(i);let a=this.formingAfter(i);i&&!a&&(this.setPreviousClose(i),this.updatePrice(i.close)),this.emit(`snapshot`,JS(r,a)),this.source.subscribeBars(n),this.startHeartbeat()}catch(t){if(e!==this.connectSeq)return;let n=t instanceof Error?t.message:String(t);this.emit(`error`,{message:n,code:`CONNECT_FAILED`}),this.setState(`error`),this.reconnector.schedule(()=>this.doConnect())}}wireReconnector(){this.reconnector.on(`attempt`,({attempt:e,delay:t})=>{this.state=`reconnecting`,this.emit(`connectionChange`,{state:`reconnecting`,reconnectAttempt:e,lastMessageTime:this.lastMessageTime})}),this.reconnector.on(`giveUp`,({attempts:e})=>{this.setState(`error`),this.emit(`error`,{message:`Reconnection failed after ${e} attempts`,code:`RECONNECT_EXHAUSTED`})})}subscriber(){return{connection:e=>this.onConnection(e),tick:e=>this.onTick(e),bar:(e,t)=>this.onBar(e,t),error:e=>this.emit(`error`,{message:e??`Adapter error`}),symbolInfo:e=>{e&&typeof e==`object`&&this.emit(`symbolInfo`,e)}}}onConnection(e){this.lastMessageTime=Date.now(),e===`connected`?(this.reconnector.onConnected(),this.setState(`connected`)):(e===`disconnected`||e===`error`)&&this.reconnector.schedule(()=>this.doConnect())}onTick(e){this.lastMessageTime=Date.now(),this.emit(`tick`,e),(e.bid!==void 0||e.ask!==void 0)&&this.emit(`quote`,{bid:e.bid,ask:e.ask}),this.config?.aggregateTicks&&this.aggregator?this.aggregator.processTick(e):this.updatePrice(e.price)}onBar(e,t){this.lastMessageTime=Date.now(),this.aggregator?.processBar(e,t)}setPreviousClose(e){this.previousClose=e.close,this.previousCloseTime=(0,t.normalizeBarTime)(e.time)}seedAggregator(e){this.aggregator&&(this.aggregator.seed(e?e.time:-1/0),e&&this.config?.aggregateTicks&&this.aggregator.resume(e))}formingAfter(e){let n=this.aggregator?.getCurrentBar()??null;return!n||e&&(0,t.normalizeBarTime)(n.time)<=(0,t.normalizeBarTime)(e.time)?null:n}updatePrice(e){e===this.lastPrice&&this.previousClose===this.sentPreviousClose||(this.lastPrice=e,this.sentPreviousClose=this.previousClose,this.priceLine.setPrice(e,this.previousClose??void 0),this.emit(`priceChange`,{price:e,previousClose:this.previousClose}))}setState(e){this.state!==e&&(this.state=e,this.emit(`connectionChange`,{state:e,reconnectAttempt:this.reconnector.getAttempt(),lastMessageTime:this.lastMessageTime}))}wake(e){!this.source||!this.config||this.state===`connecting`||this.state===`disconnected`||this.state===`connected`&&e===`visible`&&(!this.source.watchSilence||Date.now()-this.lastMessageTime<=US)||(this.reconnector.stop(),this.source.unsubscribe(),this.reconnector.start(),this.doConnect())}startHeartbeat(){this.stopHeartbeat(),this.heartbeatTimer=setInterval(()=>{this.source?.watchSilence===!0&&Date.now()-this.lastMessageTime>WS&&this.state===`connected`&&(this.emit(`error`,{message:`Heartbeat timeout`,code:`HEARTBEAT_TIMEOUT`}),this.source?.unsubscribe(),this.reconnector.schedule(()=>this.doConnect()))},GS)}stopHeartbeat(){this.heartbeatTimer&&=(clearInterval(this.heartbeatTimer),null)}dispose(){this.disconnect(),this.removeAllListeners()}},ZS=class extends Xx{data;speed;index;status=`idle`;timer=null;constructor(e){if(super(),e.data.length===0)throw Error(`ReplayController requires non-empty data`);this.data=e.data,this.speed=Math.max(.01,e.speed??1),this.index=Math.max(0,Math.min(e.startIndex??0,e.data.length)),e.autoStart&&this.start()}getStatus(){return this.status}getIndex(){return this.index}getTotal(){return this.data.length}getPrefix(){return this.data.slice(0,this.index)}start(){if(this.status!==`playing`){if(this.index>=this.data.length){this.transition(`finished`);return}this.transition(`playing`),this.scheduleNext()}}pause(){this.status===`playing`&&(this.clearTimer(),this.transition(`paused`))}resume(){this.status===`paused`&&this.start()}stop(){this.clearTimer(),this.index=0,this.transition(`idle`)}step(e=1){if(!(e<=0)){this.clearTimer();for(let t=0;t<e;t++)if(!this.emitNext())return;this.status!==`finished`&&this.transition(`paused`)}}seek(e){let t=Math.max(0,Math.min(e,this.data.length));this.clearTimer(),this.index=t;let n=t>=this.data.length?`finished`:`paused`;this.transition(n)}setSpeed(e){this.speed=Math.max(.01,e),this.status===`playing`&&(this.clearTimer(),this.scheduleNext())}destroy(){this.clearTimer(),this.removeAllListeners()}scheduleNext(){let e=1e3/this.speed;this.timer=setTimeout(()=>{this.timer=null,this.status===`playing`&&this.emitNext()&&this.scheduleNext()},e)}emitNext(){if(this.index>=this.data.length)return this.transition(`finished`),this.emit(`finished`,{total:this.data.length}),!1;let e=this.data[this.index],t=this.index;return this.index++,this.emit(`bar`,{bar:e,index:t,total:this.data.length}),this.index>=this.data.length?(this.transition(`finished`),this.emit(`finished`,{total:this.data.length}),!1):!0}clearTimer(){this.timer!==null&&(clearTimeout(this.timer),this.timer=null)}transition(e){this.status!==e&&(this.status=e,this.emit(`stateChange`,{status:e,index:this.index,total:this.data.length}))}};function QS(e){if(!Array.isArray(e)||e.length<6)return null;let t=e[0];if(typeof t!=`number`||!Number.isFinite(t))return null;let n=eC(e[1]),r=eC(e[2]),i=eC(e[3]),a=eC(e[4]),o=eC(e[5]);return n===null||r===null||i===null||a===null||o===null?null:{time:t,open:n,high:r,low:i,close:a,volume:o}}function $S(e){if(!tC(e))return null;let t=e.t;if(typeof t!=`number`||!Number.isFinite(t))return null;let n=eC(e.o),r=eC(e.h),i=eC(e.l),a=eC(e.c),o=eC(e.v);if(n===null||r===null||i===null||a===null||o===null)return null;let s=typeof e.x==`boolean`?e.x:!1;return{bar:{time:t,open:n,high:r,low:i,close:a,volume:o},closed:s}}function eC(e){if(typeof e==`number`)return Number.isFinite(e)?e:null;if(typeof e==`string`){let t=parseFloat(e);return Number.isFinite(t)?t:null}return null}function tC(e){return typeof e==`object`&&!!e}function Z(e){let t=typeof e==`string`?Number(e):e;return typeof t==`number`&&Number.isFinite(t)?t:void 0}function nC(e){let n=e&&typeof e==`object`&&`data`in e?e.data:e;if(!n||typeof n!=`object`)return null;let r=n;return r.e===`24hrMiniTicker`?(0,t.readQuote)({symbol:r.s,last:Z(r.c),open:Z(r.o),high:Z(r.h),low:Z(r.l),volume:Z(r.v),time:Z(r.E)}):null}function rC(e){if(!e||typeof e!=`object`)return null;let n=e;return(0,t.readQuote)({symbol:n.symbol,last:Z(n.lastPrice),change:Z(n.priceChange),changePercent:Z(n.priceChangePercent),open:Z(n.openPrice),high:Z(n.highPrice),low:Z(n.lowPrice),prevClose:Z(n.prevClosePrice),volume:Z(n.volume),bid:Z(n.bidPrice),ask:Z(n.askPrice),time:Z(n.closeTime)})}function iC(e){if(!e||typeof e!=`object`)return null;let t=e,n=Z(t.T),r=Z(t.p),i=Z(t.q);return n!==void 0&&r!==void 0&&i!==void 0?{time:n,price:r,volume:i}:null}var aC=64,oC=(e,t)=>`${e}|${t}`,sC=class{last=new Map;serve(e,t,n){if(!Array.isArray(n)||n.length===0)return;let r=n[n.length-1],i=Number(r?.time);if(!Number.isFinite(i))return;let a=oC(e,t);this.last.delete(a),this.last.set(a,{time:i,close:Number(r?.close??NaN)}),this.last.size>aC&&this.last.delete(this.last.keys().next().value)}lastBar(e,t){return this.last.get(oC(e,t))}},cC=class{newest=-1/0;servedClose=null;served=new sC;serve(e,t,n){this.served.serve(e,t,n)}reset(e,n){let r=this.served.lastBar(e,n);this.newest=r===void 0?-1/0:(0,t.normalizeBarTime)(r.time),this.servedClose=r?.close??null}admit(e,n=!1){let r=(0,t.normalizeBarTime)(e.time);return Number.isFinite(r)?r<this.newest||r===this.newest&&n&&e.close===this.servedClose?!1:(this.servedClose=null,this.newest=r,!0):!0}},lC={"1s":`1s`,"1m":`1m`,"3m":`3m`,"5m":`5m`,"15m":`15m`,"30m":`30m`,"1h":`1h`,"2h":`2h`,"4h":`4h`,"6h":`6h`,"8h":`8h`,"12h":`12h`,"1d":`1d`,"3d":`3d`,"1w":`1w`,"1M":`1M`},uC=1e3,dC=200,fC=[`USDT`,`USDC`,`FDUSD`,`BTC`,`ETH`,`BNB`,`EUR`,`TRY`,`BRL`,`JPY`];function pC(e){let t=e.currency?fC.indexOf(e.currency):-1;return t<0?0:40-t*3}function mC(e){if(typeof e.symbol!=`string`||e.status!==`TRADING`)return null;let n=typeof e.baseAsset==`string`?e.baseAsset:``,r=typeof e.quoteAsset==`string`?e.quoteAsset:``,i=Array.isArray(e.filters)?e.filters.find(e=>typeof e==`object`&&!!e&&e.filterType===`PRICE_FILTER`&&typeof e.tickSize==`string`):void 0,a={symbol:e.symbol,description:n&&r?`${n} / ${r}`:e.symbol,exchange:`Binance`,type:`crypto`};return i&&(a.pricePrecision=(0,t.stepDecimals)(i.tickSize),a.minTick=Number(i.tickSize)),a.timeZone=`UTC`,r&&(a.currency=r),a}function hC(e){let t=e?.symbols;if(!Array.isArray(t))return[];let n=[];for(let e of t){let t=mC(e);t&&n.push(t)}return n}var gC=class{name=`binance`;supportedTimeframes=Object.keys(lC);ws=null;state=`disconnected`;listeners=new Map;config=null;restBase;wsBase;symbolList=null;newestBar=new cC;constructor(e){this.restBase=e?.restBase??`https://api.binance.com/api/v3`,this.wsBase=e?.wsBase??`wss://stream.binance.com:9443/ws`}connect(e){this.config=e,this.newestBar.reset(e.symbol,e.timeframe),this.connectWs()}disconnect(){if(this.ws){let e=this.ws;e.onopen=null,e.onmessage=null,e.onerror=null,e.onclose=null,e.close(),this.ws=null}this.setState(`disconnected`)}getConnectionState(){return this.state}async fetchHistory(e,t,n=500){let r=await this.fetchKlines(e,t,n,``);return this.newestBar.serve(e,t,r),r}async searchSymbols(e,n){return(0,t.rankSymbols)(await this.loadSymbols(),e,n?.limit??50,pC)}async resolveSymbol(e){if(this.symbolList){let t=(await this.symbolList.catch(()=>null))?.find(t=>t.symbol===e);if(t)return t}let t=await fetch(`${this.restBase}/exchangeInfo?symbol=${encodeURIComponent(e)}`);return t.ok?hC(await t.json())[0]??null:null}loadSymbols(){return this.symbolList||(this.symbolList=(async()=>{let e=await fetch(`${this.restBase}/exchangeInfo`);if(!e.ok)throw Error(`Binance REST error: ${e.status}`);return hC(await e.json())})(),this.symbolList.catch(()=>{this.symbolList=null})),this.symbolList}subscribeQuotes(e,t){let n=[...new Set(e.map(e=>e.trim().toUpperCase()))].filter(e=>/^[A-Z0-9]{2,30}$/.test(e)).slice(0,dC);if(n.length===0)return()=>{};let r=!1,i=null,a=null,o=0,s=new Set,c=new AbortController;(async()=>{let e=await fetch(`${this.restBase}/ticker/24hr?symbols=${encodeURIComponent(JSON.stringify(n))}`,{signal:c.signal});if(e.ok)return e.json();let t=await fetch(`${this.restBase}/ticker/24hr`,{signal:c.signal});if(!t.ok)return[];let r=await t.json(),i=new Set(n);return Array.isArray(r)?r.filter(e=>i.has(e?.symbol)):[]})().then(e=>{if(r||!Array.isArray(e))return;let n=e.map(rC).filter(e=>e!==null&&!s.has(e.symbol));n.length>0&&t(n)}).catch(()=>{});let l=this.wsBase.replace(/\/ws\/?$/,``),u=()=>{if(!r){try{i=new WebSocket(`${l}/stream?streams=${n.map(e=>`${e.toLowerCase()}@miniTicker`).join(`/`)}`)}catch{d();return}i.onopen=()=>{o=0},i.onmessage=e=>{let n;try{n=JSON.parse(typeof e.data==`string`?e.data:``)}catch{return}let i=nC(n);!i||r||(s.add(i.symbol),t([i]))},i.onclose=()=>{i=null,d()}}},d=()=>{r||(a=setTimeout(u,Math.min(3e4,1e3*2**o++)))};return u(),()=>{r=!0,c.abort(),a&&clearTimeout(a),i&&=(i.onopen=null,i.onmessage=null,i.onclose=null,i.close(),null)}}async fetchTrades(e,t=1e3){let n=Math.max(1,Math.min(1e3,Math.floor(t))),r=await fetch(`${this.restBase}/aggTrades?symbol=${encodeURIComponent(e.toUpperCase())}&limit=${n}`);if(!r.ok)throw Error(`Binance aggTrades ${r.status}`);let i=await r.json();return Array.isArray(i)?i.map(iC).filter(e=>e!==null):[]}subscribeTrades(e,t){let n=`${e.trim().toLowerCase()}@aggTrade`;if(!/^[a-z0-9]{2,30}@aggTrade$/.test(n))return()=>{};let r=!1,i=null,a=null,o=0,s=()=>{if(!r){try{i=new WebSocket(`${this.wsBase}/${n}`)}catch{c();return}i.onopen=()=>{o=0},i.onmessage=e=>{let n;try{n=JSON.parse(typeof e.data==`string`?e.data:``)}catch{return}let i=iC(n);i&&!r&&t([i])},i.onclose=()=>{i=null,c()}}},c=()=>{r||(a=setTimeout(s,Math.min(3e4,1e3*2**o++)))};return s(),()=>{r=!0,a&&clearTimeout(a),i&&=(i.onopen=null,i.onmessage=null,i.onclose=null,i.close(),null)}}fetchHistoryBefore(e,t,n,r=500){return this.fetchKlines(e,t,Math.min(r,uC),`&endTime=${Math.floor(n)-1}`)}async fetchKlines(e,t,n,r){let i=lC[t]??`15m`,a=`${this.restBase}/klines?symbol=${e}&interval=${i}&limit=${n}${r}`,o=await fetch(a);if(!o.ok)throw Error(`Binance REST error: ${o.status}`);let s=await o.json();if(!Array.isArray(s))return[];let c=[];for(let e of s){let t=QS(e);t&&c.push(t)}return c}on(e,t){let n=this.listeners.get(e);n||(n=new Set,this.listeners.set(e,n)),n.add(t)}off(e,t){this.listeners.get(e)?.delete(t)}dispose(){this.disconnect(),this.listeners.clear()}connectWs(){if(!this.config)return;let e=`${this.config.symbol.toLowerCase()}@kline_${lC[this.config.timeframe]??`15m`}`,t=`${this.wsBase}/${e}`;this.setState(`connecting`);try{this.ws=new WebSocket(t)}catch{this.setState(`error`),this.emitEvent(`error`,{message:`WebSocket creation failed`}),this.emitEvent(`connectionChange`,`error`);return}this.ws.onopen=()=>{this.setState(`connected`),this.emitEvent(`connectionChange`,`connected`)},this.ws.onmessage=e=>{let t;try{t=JSON.parse(typeof e.data==`string`?e.data:``)}catch{return}typeof t==`object`&&t&&t.e===`kline`&&this.handleKline(t.k)},this.ws.onerror=()=>{this.setState(`error`),this.emitEvent(`error`,{message:`WebSocket error`})},this.ws.onclose=()=>{this.setState(`disconnected`),this.emitEvent(`connectionChange`,`disconnected`)}}handleKline(e){let t=$S(e);if(!t)return;let{bar:n,closed:r}=t,i=this.newestBar.admit(n,r);this.emitEvent(`bar`,{bar:n,closed:r}),i&&this.emitEvent(`tick`,{time:Date.now(),price:n.close,volume:n.volume})}setState(e){this.state=e}emitEvent(e,t){let n=this.listeners.get(e);if(n){let r={type:e,data:t,timestamp:Date.now()};for(let e of n)e(r)}}},_C=class{name=`mock`;state=`disconnected`;listeners=new Map;config=null;options;tickTimer=null;currentPrice;oldestOpen=new Map;forming=null;formingTimeframe=null;constructor(e){this.options={basePrice:100,volatility:1.5,tickInterval:2e3,historySize:500,...e},this.currentPrice=this.options.basePrice}connect(e){this.config=e,this.state=`connected`,this.emitEvent(`connectionChange`,`connected`),this.startTicking()}disconnect(){this.stopTicking(),this.state=`disconnected`,this.emitEvent(`connectionChange`,`disconnected`)}getConnectionState(){return this.state}subscribeQuotes(e,t){let n=[...new Set(e)].map(e=>{let t=this.options.basePrice*(.5+vC(e)%1e3/1e3);return{symbol:e,open:t,last:t,high:t,low:t,volume:0}});if(n.length===0)return()=>{};let r=this.options.volatility/100,i=()=>t(n.map(e=>({symbol:e.symbol,last:e.last,open:e.open,high:e.high,low:e.low,volume:e.volume,change:e.last-e.open,changePercent:(e.last-e.open)/e.open*100,time:Date.now()})));i();let a=setInterval(()=>{for(let e of n)e.last=Math.max(e.open*.01,e.last*(1+(Math.random()-.5)*r)),e.high=Math.max(e.high,e.last),e.low=Math.min(e.low,e.last),e.volume+=Math.random()*100;i()},this.options.tickInterval);return()=>clearInterval(a)}async fetchTrades(e,t=1e3){let n=Math.max(1,Math.min(1e3,Math.floor(t))),r=Date.now(),i=this.options.volatility/1e3,a=this.options.basePrice*(.5+vC(e)%1e3/1e3),o=[];for(let e=n-1;e>=0;e--)a=Math.max(a*.5,a*(1+(Math.random()-.5)*i)),o.push({time:r-e*1e3,price:a,volume:Math.random()*5});return o}subscribeTrades(e,t){let n=this.options.volatility/1e3,r=this.options.basePrice*(.5+vC(e)%1e3/1e3),i=setInterval(()=>{let e=[];for(let t=0;t<3;t++)r=Math.max(r*.5,r*(1+(Math.random()-.5)*n)),e.push({time:Date.now(),price:r,volume:Math.random()*5});t(e)},this.options.tickInterval);return()=>clearInterval(i)}async fetchHistory(e,t,n){let r=this.options.historyGenerator?this.options.historyGenerator(e,t,n??this.options.historySize):this.generateHistory(t,n??this.options.historySize);return r.length>0&&this.oldestOpen.set(e,r[0].open),this.forming=r.length>0?{...r[r.length-1]}:null,this.formingTimeframe=t,r}async fetchHistoryBefore(e,n,r,i){let a=(0,t.timeframeToMs)(n),o=this.options.volatility/100,s=Array(Math.max(0,i)),c=this.oldestOpen.get(e)??this.options.basePrice;for(let e=0;e<i;e++){let t=c/(1+(Math.random()-.52)*o),n=Math.max(t,c)+Math.random()*c*o*.3,l=Math.max(0,Math.min(t,c)-Math.random()*c*o*.3),u=Math.floor(1e4+Math.random()*1e5);s[i-1-e]={time:r-(e+1)*a,open:t,high:n,low:l,close:c,volume:u},c=t}return this.oldestOpen.set(e,c),s}async searchSymbols(e,n){return(0,t.rankSymbols)(this.options.symbols??[],e,n?.limit??50)}async resolveSymbol(e){return this.options.symbols?.find(t=>t.symbol===e)??null}on(e,t){let n=this.listeners.get(e);n||(n=new Set,this.listeners.set(e,n)),n.add(t)}off(e,t){this.listeners.get(e)?.delete(t)}dispose(){this.disconnect(),this.listeners.clear()}generateHistory(e,n){let r=[],i=(0,t.timeframeToMs)(e),a=Math.floor(Date.now()/i)*i,o=this.options.basePrice,s=this.options.volatility/100;for(let e=n-1;e>=0;e--){let t=a-e*i,n=(Math.random()-.48)*o*s,c=o;o+=n;let l=Math.max(c,o)+Math.random()*o*s*.3,u=Math.min(c,o)-Math.random()*o*s*.3,d=Math.floor(1e4+Math.random()*1e5);r.push({time:t,open:c,high:l,low:u,close:o,volume:d})}return this.currentPrice=o,r}startTicking(){this.stopTicking();let e=this.options.tickInterval??2e3;this.tickTimer=setInterval(()=>{if(this.state!==`connected`||!this.config)return;let e=this.options.volatility/100,t=(Math.random()-.48)*this.currentPrice*e*.3;this.currentPrice+=t;let n=Date.now(),r=this.tickBar(n,t,Math.floor(100+Math.random()*5e3));this.emitEvent(`bar`,{bar:r,closed:!1}),this.emitEvent(`tick`,{time:n,price:this.currentPrice,volume:r.volume})},e)}tickBar(e,n,r){let i=this.config.timeframe,a=(0,t.timeframeToMs)(i),o=Math.floor(e/a)*a,s=this.currentPrice,c=this.formingTimeframe===i?this.forming:null,l=Math.abs(n)*.2,u;if(c&&c.time===o)u={time:o,open:c.open,high:Math.max(c.high,s+l),low:Math.min(c.low,s-l),close:s,volume:c.volume+r};else{let e=c?.close??s-n;u={time:o,open:e,high:Math.max(e,s)+l,low:Math.min(e,s)-l,close:s,volume:r}}return this.forming=u,this.formingTimeframe=i,{...u}}stopTicking(){this.tickTimer&&=(clearInterval(this.tickTimer),null)}emitEvent(e,t){let n=this.listeners.get(e);if(n){let r={type:e,data:t,timestamp:Date.now()};for(let e of n)e(r)}}};function vC(e){let t=0;for(let n=0;n<e.length;n++)t=t*31+e.charCodeAt(n)>>>0;return t}var yC=class{name;supportedTimeframes;ws=null;state=`disconnected`;config=null;listeners=new Map;opts;newestBar=new cC;fetchHistoryBefore;searchSymbols;resolveSymbol;constructor(e){this.opts=e,this.name=e.name,this.supportedTimeframes=e.supportedTimeframes;let t=e.fetchHistoryBefore;t&&(this.fetchHistoryBefore=(e,n,r,i)=>t(e,n,r,i)),e.searchSymbols&&(this.searchSymbols=e.searchSymbols),e.resolveSymbol&&(this.resolveSymbol=e.resolveSymbol)}connect(e){this.config=e,this.newestBar.reset(e.symbol,e.timeframe),this.openSocket()}disconnect(){let e=this.config;if(this.ws){if(this.opts.unsubscribeMessage&&e)try{this.sendMessage(this.opts.unsubscribeMessage(e))}catch{}let t=this.ws;t.onopen=null,t.onmessage=null,t.onerror=null,t.onclose=null,t.close(),this.ws=null}this.setState(`disconnected`)}getConnectionState(){return this.state}fetchHistory(e,t,n){let r=this.opts.fetchHistory(e,t,n??this.opts.defaultHistoryLimit??500);return Promise.resolve(r).then(n=>(this.newestBar.serve(e,t,n),n))}on(e,t){let n=this.listeners.get(e);n||(n=new Set,this.listeners.set(e,n)),n.add(t)}off(e,t){this.listeners.get(e)?.delete(t)}dispose(){this.disconnect(),this.listeners.clear()}openSocket(){let e=this.config;if(!e)return;let t=this.opts.wsUrl(e);this.setState(`connecting`);let n;try{n=this.createSocket(t)}catch{this.setState(`error`),this.emitEvent(`error`,{message:`WebSocket creation failed`}),this.emitEvent(`connectionChange`,`error`);return}this.ws=n,n.onopen=()=>{if(this.setState(`connected`),this.emitEvent(`connectionChange`,`connected`),this.opts.subscribeMessage)try{this.sendMessage(this.opts.subscribeMessage(e))}catch{}},n.onmessage=t=>{let n=this.decode(t.data);if(n===void 0)return;let r;try{r=this.opts.parseMessage(n,e)}catch{return}if(!r)return;let i=r.bar?this.newestBar.admit(r.bar,r.closed??!1):!1;r.bar&&this.emitEvent(`bar`,{bar:r.bar,closed:r.closed??!1}),r.tick?this.emitEvent(`tick`,r.tick):r.bar&&i&&this.emitEvent(`tick`,{time:Date.now(),price:r.bar.close,volume:r.bar.volume})},n.onerror=()=>{this.setState(`error`),this.emitEvent(`error`,{message:`WebSocket error`})},n.onclose=()=>{this.setState(`disconnected`),this.emitEvent(`connectionChange`,`disconnected`)}}sendMessage(e){e===void 0||!this.ws||this.ws.send(typeof e==`string`?e:JSON.stringify(e))}decode(e){if(this.opts.decode)try{return this.opts.decode(e)}catch{return}if(typeof e==`string`)try{return JSON.parse(e)}catch{return}return e}createSocket(e){if(this.opts.socketFactory)return this.opts.socketFactory(e);let t=globalThis.WebSocket;if(!t)throw Error(`No WebSocket implementation available`);return new t(e)}setState(e){this.state=e}emitEvent(e,t){let n=this.listeners.get(e);if(n){let r={type:e,data:t,timestamp:Date.now()};for(let e of n)e(r)}}},bC=class{name;supportedTimeframes;state=`disconnected`;listeners=new Map;config=null;timer=null;lastBarTime=0;served=new sC;opts;fetchHistoryBefore;searchSymbols;resolveSymbol;constructor(e){this.opts=e,this.name=e.name,this.supportedTimeframes=e.supportedTimeframes;let t=e.fetchHistoryBefore;t&&(this.fetchHistoryBefore=(e,n,r,i)=>t(e,n,r,i)),e.searchSymbols&&(this.searchSymbols=e.searchSymbols),e.resolveSymbol&&(this.resolveSymbol=e.resolveSymbol)}connect(e){this.config=e,this.lastBarTime=this.served.lastBar(e.symbol,e.timeframe)?.time??0,this.state=`connected`,this.emitEvent(`connectionChange`,`connected`),this.startPolling()}disconnect(){this.stopPolling(),this.state=`disconnected`,this.emitEvent(`connectionChange`,`disconnected`)}getConnectionState(){return this.state}async fetchHistory(e,t,n){let r=await this.opts.fetchBars(e,t,n??this.opts.defaultHistoryLimit??500);return this.served.serve(e,t,r),r}on(e,t){let n=this.listeners.get(e);n||(n=new Set,this.listeners.set(e,n)),n.add(t)}off(e,t){this.listeners.get(e)?.delete(t)}dispose(){this.disconnect(),this.listeners.clear()}async poll(){let e=this.config;if(!e||this.state!==`connected`)return;let t;try{t=await this.opts.fetchBars(e.symbol,e.timeframe,this.opts.pollLimit??2)}catch(e){this.emitEvent(`error`,{message:`Poll failed`,cause:e});return}if(t.length===0)return;let n=t[t.length-1];if(!(n.time<this.lastBarTime)){if(this.lastBarTime>0&&n.time>this.lastBarTime){let e=t.find(e=>e.time===this.lastBarTime);e&&this.emitEvent(`bar`,{bar:e,closed:!0})}this.emitEvent(`bar`,{bar:n,closed:!1}),this.emitEvent(`tick`,{time:Date.now(),price:n.close,volume:n.volume}),this.lastBarTime=n.time}}startPolling(){this.stopPolling(),this.poll();let e=this.opts.setInterval??((e,t)=>setInterval(e,t));this.timer=e(()=>{this.poll()},this.opts.intervalMs??5e3)}stopPolling(){this.timer!==null&&((this.opts.clearInterval??(e=>clearInterval(e)))(this.timer),this.timer=null)}emitEvent(e,t){let n=this.listeners.get(e);if(n){let r={type:e,data:t,timestamp:Date.now()};for(let e of n)e(r)}}};function Q(e){if(typeof e==`number`)return Number.isFinite(e)?e:null;if(typeof e==`string`){let t=parseFloat(e);return Number.isFinite(t)?t:null}return null}function xC(e){return typeof e==`object`&&!!e}var SC={"1m":60,"5m":300,"15m":900,"1h":3600,"6h":21600,"1d":86400};function CC(e){return SC[e]??3600}var wC=class extends bC{constructor(e={}){let t=e.restBase??`https://api.exchange.coinbase.com`;super({name:`coinbase`,supportedTimeframes:Object.keys(SC),intervalMs:e.intervalMs??5e3,pollLimit:2,fetchBars:(e,n)=>TC(t,e,n)})}};async function TC(e,t,n){let r=`${e}/products/${t}/candles?granularity=${CC(n)}`,i=await fetch(r);if(!i.ok)throw Error(`Coinbase REST error: ${i.status}`);return EC(await i.json())}function EC(e){if(!Array.isArray(e))return[];let t=[];for(let n of e){let e=DC(n);e&&t.push(e)}return t.sort((e,t)=>e.time-t.time),t}function DC(e){if(!Array.isArray(e)||e.length<6)return null;let t=Q(e[0]),n=Q(e[1]),r=Q(e[2]),i=Q(e[3]),a=Q(e[4]),o=Q(e[5]);return t===null||n===null||r===null||i===null||a===null||o===null?null:{time:t*1e3,open:i,high:r,low:n,close:a,volume:o}}var OC={"1m":`1`,"3m":`3`,"5m":`5`,"15m":`15`,"30m":`30`,"1h":`60`,"2h":`120`,"4h":`240`,"6h":`360`,"12h":`720`,"1d":`D`,"1w":`W`,"1M":`M`};function kC(e){return OC[e]??`1`}var AC=class extends yC{constructor(e={}){let t=e.restBase??`https://api.bybit.com`,n=e.wsBase??`wss://stream.bybit.com/v5/public/spot`,r=e.category??`spot`;super({name:`bybit`,wsUrl:()=>n,subscribeMessage:e=>({op:`subscribe`,args:[`kline.${kC(e.timeframe)}.${e.symbol}`]}),unsubscribeMessage:e=>({op:`unsubscribe`,args:[`kline.${kC(e.timeframe)}.${e.symbol}`]}),supportedTimeframes:Object.keys(OC),parseMessage:jC,fetchHistory:(e,n,i)=>MC(t,r,e,n,i),fetchHistoryBefore:(e,n,i,a)=>MC(t,r,e,n,a,Math.floor(i)-1)})}};function jC(e){if(!xC(e)||typeof e.topic!=`string`||!e.topic.startsWith(`kline.`))return null;let t=e.data;if(!Array.isArray(t)||t.length===0)return null;let n=t[t.length-1];if(!xC(n))return null;let r=Q(n.start),i=Q(n.open),a=Q(n.high),o=Q(n.low),s=Q(n.close),c=Q(n.volume);if(r===null||i===null||a===null||o===null||s===null||c===null)return null;let l=typeof n.confirm==`boolean`?n.confirm:!1;return{bar:{time:r,open:i,high:a,low:o,close:s,volume:c},closed:l}}async function MC(e,t,n,r,i,a){let o=`${e}/v5/market/kline?category=${t}&symbol=${n}&interval=${kC(r)}&limit=${Math.min(Math.max(i,1),1e3)}${a===void 0?``:`&end=${a}`}`,s=await fetch(o);if(!s.ok)throw Error(`Bybit REST error: ${s.status}`);return NC(await s.json())}function NC(e){if(!xC(e)||!xC(e.result))return[];let t=e.result.list;if(!Array.isArray(t))return[];let n=[];for(let e of t){let t=PC(e);t&&n.push(t)}return n.sort((e,t)=>e.time-t.time),n}function PC(e){if(!Array.isArray(e)||e.length<6)return null;let t=Q(e[0]),n=Q(e[1]),r=Q(e[2]),i=Q(e[3]),a=Q(e[4]),o=Q(e[5]);return t===null||n===null||r===null||i===null||a===null||o===null?null:{time:t,open:n,high:r,low:i,close:a,volume:o}}var FC={"1m":1,"5m":5,"15m":15,"30m":30,"1h":60,"4h":240,"1d":1440,"1w":10080};function IC(e){return FC[e]??1}var LC=class extends yC{constructor(e={}){let t=e.restBase??`https://api.kraken.com`,n=e.wsBase??`wss://ws.kraken.com/v2`;super({name:`kraken`,wsUrl:()=>n,subscribeMessage:e=>({method:`subscribe`,params:{channel:`ohlc`,symbol:[e.symbol],interval:IC(e.timeframe)}}),unsubscribeMessage:e=>({method:`unsubscribe`,params:{channel:`ohlc`,symbol:[e.symbol],interval:IC(e.timeframe)}}),supportedTimeframes:Object.keys(FC),parseMessage:RC,fetchHistory:(e,n)=>zC(t,e,n)})}};function RC(e){if(!xC(e)||e.channel!==`ohlc`)return null;let t=e.data;if(!Array.isArray(t)||t.length===0)return null;let n=t[t.length-1];if(!xC(n))return null;let r=Q(n.open),i=Q(n.high),a=Q(n.low),o=Q(n.close),s=Q(n.volume),c=typeof n.interval_begin==`string`?Date.parse(n.interval_begin):NaN;return r===null||i===null||a===null||o===null||s===null||!Number.isFinite(c)?null:{bar:{time:c,open:r,high:i,low:a,close:o,volume:s},closed:!1}}async function zC(e,t,n){let r=IC(n),i=t.replace(`/`,``),a=`${e}/0/public/OHLC?pair=${encodeURIComponent(i)}&interval=${r}`,o=await fetch(a);if(!o.ok)throw Error(`Kraken REST error: ${o.status}`);return BC(await o.json())}function BC(e){if(!xC(e)||!xC(e.result))return[];let t=null;for(let[n,r]of Object.entries(e.result))if(n!==`last`&&Array.isArray(r)){t=r;break}if(!Array.isArray(t))return[];let n=[];for(let e of t){let t=VC(e);t&&n.push(t)}return n.sort((e,t)=>e.time-t.time),n}function VC(e){if(!Array.isArray(e)||e.length<7)return null;let t=Q(e[0]),n=Q(e[1]),r=Q(e[2]),i=Q(e[3]),a=Q(e[4]),o=Q(e[6]);return t===null||n===null||r===null||i===null||a===null||o===null?null:{time:t*1e3,open:n,high:r,low:i,close:a,volume:o}}var HC=200,UC={"1m":`minutes/1`,"3m":`minutes/3`,"5m":`minutes/5`,"15m":`minutes/15`,"30m":`minutes/30`,"1h":`minutes/60`,"4h":`minutes/240`,"1d":`days`,"1w":`weeks`,"1M":`months`},WC={"1m":`candle.1m`,"3m":`candle.3m`,"5m":`candle.5m`,"15m":`candle.15m`,"30m":`candle.30m`,"1h":`candle.60m`,"4h":`candle.240m`,"1d":`ticker`};function GC(e){return UC[e]??null}function KC(e){return WC[e]??null}var qC=class extends yC{constructor(e={}){let t=e.restBase??`https://api.upbit.com`,n=e.wsUrl??`wss://api.upbit.com/websocket/v1`;super({name:`upbit`,wsUrl:()=>n,socketFactory:e.socketFactory??JC,decode:XC,subscribeMessage:e=>[{ticket:`tradecanvas`},{type:KC(e.timeframe)??`candle.1m`,codes:[e.symbol]},{format:`DEFAULT`}],supportedTimeframes:Object.keys(WC),parseMessage:ZC,fetchHistory:(e,n,r)=>ew(t,e,n,r),fetchHistoryBefore:(e,n,r,i)=>ew(t,e,n,i,r)})}};function JC(e){let t=globalThis.WebSocket;if(!t)throw Error(`No WebSocket implementation available`);let n=new t(e);return n.binaryType=`arraybuffer`,n}var YC=null;function XC(e){if(typeof e==`string`)return JSON.parse(e);if(e instanceof ArrayBuffer||ArrayBuffer.isView(e))return JSON.parse((YC??=new TextDecoder).decode(e))}function ZC(e){if(!xC(e)||typeof e.type!=`string`)return null;if(e.type.startsWith(`candle.`)){let t=$C(e,e.candle_date_time_utc,e.candle_acc_trade_volume);return t?{bar:t,closed:!1}:null}if(e.type===`ticker`&&typeof e.trade_date==`string`&&/^\d{8}$/.test(e.trade_date)){let t=e.trade_date,n=$C(e,`${t.slice(0,4)}-${t.slice(4,6)}-${t.slice(6,8)}T00:00:00`,e.acc_trade_volume);return n?{bar:n,closed:!1}:null}return null}function QC(e){if(!Array.isArray(e))return[];let t=[];for(let n of e){let e=xC(n)?$C(n,n.candle_date_time_utc,n.candle_acc_trade_volume):null;e&&t.push(e)}return t.sort((e,t)=>e.time-t.time),t}function $C(e,t,n){let r=typeof t==`string`?Date.parse(`${t}Z`):NaN,i=Q(e.opening_price),a=Q(e.high_price),o=Q(e.low_price),s=Q(e.trade_price),c=Q(n);return!Number.isFinite(r)||i===null||a===null||o===null||s===null||c===null?null:{time:r,open:i,high:a,low:o,close:s,volume:c}}async function ew(e,t,n,r,i){let a=GC(n);if(!a)throw Error(`Upbit has no ${n} candles`);let o=new URLSearchParams({market:t,count:String(Math.min(Math.max(Math.floor(r),1),200))});i!==void 0&&o.set(`to`,new Date(i).toISOString().replace(/\.\d{3}Z$/,`Z`));let s=await fetch(`${e}/v1/candles/${a}?${o}`);if(!s.ok)throw Error(`Upbit REST error: ${s.status}`);return QC(await s.json())}var tw=(e,t)=>`${e}\u0000${t}`,nw=class{name;series=new Map;subscribers=new Map;constructor(e={}){this.name=e.name??`manual`}setBars(e,t,n){let r=n.map(e=>({...e})).sort((e,t)=>e.time-t.time);this.series.set(tw(e,t),r)}pushBar(e,t,n,r=!1){let i=tw(e,t),a=this.series.get(i)??[],o=a[a.length-1],s={...n},c=r;if(!o||s.time>o.time)this.series.set(i,[...a,s]);else{let n=a.findIndex(e=>e.time===s.time);if(n<0)throw RangeError(`ManualFeed: no ${e} ${t} bar at ${s.time} to replace`);n<a.length-1&&(c=!0),this.series.set(i,a.map((e,t)=>t===n?s:e))}for(let e of[...this.subscribers.get(i)??[]])e.bar({...s},c)}async getBars(e){let t=this.series.get(tw(e.symbol,e.timeframe))??[],{before:n}=e,r=n===void 0?t.length:rw(t,n);return t.slice(Math.max(0,r-e.countBack),r).map(e=>({...e}))}subscribeBars(e,t){let n=tw(e.symbol,e.timeframe),r=this.subscribers.get(n);return r||(r=new Set,this.subscribers.set(n,r)),r.add(t),()=>{r.delete(t),r.size===0&&this.subscribers.delete(n)}}};function rw(e,t){let n=0,r=e.length;for(;n<r;){let i=n+r>>1;e[i].time<t?n=i+1:r=i}return n}var iw={visible:!0,showSymbol:!0,showOHLC:!0,showChange:!0,showVolume:!0,position:`top-left`,fontSize:12,fontFamily:null,ground:!0},aw=class{config={...iw};symbol=``;timeframe=``;hoverBar=null;hoverPrev=null;indicators=[];statusText=null;exchange=``;drawnHeight=null;drawnWidth=0;locale=`en-US`;inset=sw;top=ow;lineGap=cw;pricePrecision=null;reportedHeight=null;resizeListener=null;setResizeListener(e){this.resizeListener=e}forgetHeight(){this.drawnHeight=null,this.reportedHeight=null}reportResize(){let e=this.getHeight();e!==this.reportedHeight&&(this.reportedHeight=e,this.resizeListener?.())}setConfig(e){Object.assign(this.config,e),this.forgetHeight()}getConfig(){return{...this.config}}setPricePrecision(e){this.pricePrecision=e}setLocale(e){this.locale=e}setSymbol(e){e!==this.symbol&&(this.symbol=e,this.forgetHeight())}setTimeframe(e){e!==this.timeframe&&(this.timeframe=e,this.forgetHeight())}setChartType(e){}setHoverBar(e,t=null){this.hoverBar=e,this.hoverPrev=e?t:null}setIndicatorValues(e){this.indicators=e}setStatusText(e){e!==this.statusText&&(this.statusText=e,this.forgetHeight())}setExchange(e){e!==this.exchange&&(this.exchange=e,this.forgetHeight())}title(){return this.config.showSymbol?[(0,t.tickerOf)(this.symbol),this.timeframe,this.exchange].filter(Boolean).join(` · `):``}titleCells(e,t,n,r,i){let a=[],o=this.title();if(o){let i=`600 ${t}px ${n}`;e.font=i,a.push({label:``,labelWidth:0,value:o,width:e.measureText(o).width,color:r,font:i})}if(this.statusText){let r=`${t}px ${n}`;e.font=r,a.push({label:``,labelWidth:0,value:this.statusText,width:e.measureText(this.statusText).width,color:i,font:r})}return a}priceCells(e,n,r,i,a,o,s,c){let l=`${o}px ${s}`;e.font=l;let u=i.close>=i.open,d=this.pricePrecision??(0,t.autoPricePrecision)(n.priceRange.min,n.priceRange.max),f=e=>n.formatPrice?.(e)??(0,t.formatPrice)(e,d,this.locale),p=[{label:`O`,value:f(i.open),color:c},{label:`H`,value:f(i.high),color:c},{label:`L`,value:f(i.low),color:c},{label:`C`,value:f(i.close),color:u?r.candleUp:r.candleDown}];if(this.config.showChange){let e=i.close-a.close,n=a.close===0?0:e/a.close*100,o=e>=0?`+`:``,s=(0,t.formatPrice)(n,2,this.locale);p.push({label:``,value:`${o}${f(e)} (${o}${s}%)`,color:e>=0?r.candleUp:r.candleDown})}return p.map(t=>({...t,labelWidth:t.label?e.measureText(t.label+` `).width:0,width:pw(e,t.value),font:l}))}setSpacing(e){e.inset===this.inset&&e.top===this.top&&e.lineGap===this.lineGap||(this.inset=e.inset,this.top=e.top,this.lineGap=e.lineGap,this.drawnHeight=null)}getInset(){return this.inset}getHeight(){if(!this.config.visible||this.config.position!==`top-left`)return 0;if(this.drawnHeight!==null)return this.drawnHeight;let e=this.config.fontSize,t=this.top;return(this.config.showOHLC||this.title()||this.statusText)&&(t+=e+this.lineGap),this.config.showVolume&&(t+=e+2),t}getWidth(){return!this.config.visible||this.config.position!==`top-left`?0:this.drawnWidth}render(e,n,r,i){if(!this.config.visible)return this.reportResize();if(i.length===0)return;let a=this.hoverBar??i[i.length-1],o=this.hoverBar?this.hoverPrev??a:i.length>1?i[i.length-2]:a,{chartRect:s}=n,c=this.config.fontSize,l=this.config.fontFamily??r.font.family,u=r.style?.legend.text??r.text,d=r.style?.legend.label??r.textSecondary,f=this.config.position===`top-left`,p=f?s.x+this.inset:s.x+s.width-this.inset,m=s.y+this.top;e.textAlign=f?`left`:`right`,e.textBaseline=`top`;let h=0,g=this.titleCells(e,c,l,u,d);if(this.config.showOHLC&&g.push(...this.priceCells(e,n,r,a,o,c,l,u)),g.length>0){e.font=`${c}px ${l}`;let t=e.measureText(` `).width;for(let n of fw(g,t,s.width-2*this.inset)){let i=n.reduce((e,n)=>e+n.labelWidth+n.width+t,-t);h=Math.max(h,i);let a=f?p:p-i;this.drawGround(e,r,a,m,i,c),e.textAlign=`left`;for(let r of n)e.font=r.font,r.label&&(e.fillStyle=d,e.fillText(r.label,a,m),a+=r.labelWidth),e.fillStyle=r.color,e.fillText(r.value,a,m),a+=r.width+t;m+=c+this.lineGap}e.textAlign=f?`left`:`right`}if(this.config.showVolume){e.font=`${c}px ${l}`,e.fillStyle=d;let n=(0,t.formatVolumeLoc)(a.volume,this.locale),i=e.measureText(`Vol ${n}`).width;this.drawGround(e,r,f?p:p-i,m,i,c),e.fillStyle=d,e.fillText(`Vol ${n}`,p,m),h=Math.max(h,i),m+=c+2}if(this.drawnHeight=f?m-s.y:null,this.drawnWidth=f?this.inset+h:0,this.reportResize(),this.indicators.length>0){e.font=`${c}px ${l}`;let t=e.measureText(` `).width,n=this.indicators.map(t=>{let n=`${t.name} ${t.value}`;return{entry:n,color:t.color,width:pw(e,n)}}),i=n.reduce((e,n)=>e+n.width+t,-t),a=f?p:p-i;this.drawGround(e,r,a,m,i,c),e.textAlign=`left`;for(let{entry:r,color:i,width:o}of n)e.fillStyle=i,e.fillText(r,a,m),a+=o+t}}drawGround(e,t,n,r,i,a){!this.config.ground||i<=0||(e.save(),e.globalAlpha=lw,e.fillStyle=t.background,e.fillRect(n-uw,r-dw,i+2*uw,a+this.lineGap),e.restore())}},{legendTop:ow,legendInset:sw,legendLineGap:cw}=t.CHART_SPACING[t.DEFAULT_CHART_DENSITY],lw=.72,uw=3,dw=1;function fw(e,t,n){let r=[],i=[],a=0;for(let o of e){let e=o.labelWidth+o.width;i.length>0&&a+t+e>n&&(r.push(i),i=[],a=0),a+=(i.length>0?t:0)+e,i.push(o)}return i.length>0&&r.push(i),r}function pw(e,t){let n=t.replace(/\d/g,`0`);return Math.max(e.measureText(t).width,e.measureText(n.replace(/[-−]/g,`+`)).width,e.measureText(n.replace(/\+/g,`-`)).width)}var mw=class{static toDataURL(e,t){return this.compose(e,t)?.toDataURL(`image/png`)??``}static async toBlob(e,t){let n=this.compose(e,t);return n?new Promise(e=>n.toBlob(e,`image/png`)):null}static download(e,t=`chart.png`,n){let r=this.toDataURL(e,n);if(!r)return;let i=document.createElement(`a`);i.href=r,i.download=t,document.body.appendChild(i),i.click(),document.body.removeChild(i)}static compose(e,t){let n=e.querySelectorAll(`canvas`);if(n.length===0)return null;let r=n[0],i=r.width,a=r.height,o=document.createElement(`canvas`);o.width=i,o.height=a;let s=o.getContext(`2d`);t&&(s.fillStyle=t,s.fillRect(0,0,i,a));let c=Array.from(n).sort((e,t)=>(parseInt(e.style.zIndex)||0)-(parseInt(t.style.zIndex)||0));for(let e of c)s.drawImage(e,0,0);return o}},hw=class{config=null;setConfig(e){this.config=e}isVisible(){return!!this.config?.text}render(e,t,n){if(!this.config?.text)return;let{chartRect:r}=t,i=this.config.fontSize??48,a=n.style?.watermark.color??this.config.color??n.textSecondary;e.save(),e.globalAlpha=.07,e.font=`bold ${i}px ${n.font.family}`,e.fillStyle=a,e.textAlign=`center`,e.textBaseline=`middle`,e.fillText(this.config.text,r.x+r.width/2,r.y+r.height/2),e.restore()}},gw={solid:null,dashed:[6,4],dotted:[2,3]},_w=6;function vw(e,t){let n=[...e].sort((e,t)=>t.rank-e.rank||e.px-t.px),r=[],i=[];for(let e of n){let n=0,a=r.length;for(;n<a;){let t=n+a>>1;r[t]<e.px?n=t+1:a=t}n>0&&e.px-r[n-1]<t||n<r.length&&r[n]-e.px<t||(r.splice(n,0,e.px),i.push(e))}return i.sort((e,t)=>e.px-t.px)}var yw=class{config={visible:!1};cachedBreaksTyped=[];cachedMedianStep=0;cacheValid=!1;lastDataLength=0;firstTime=NaN;lastTime=NaN;tz=null;setConfig(e){Object.assign(this.config,e)}setTimezone(e){e!==this.tz&&(this.tz=e,this.invalidateCache())}isVisible(){return this.config.visible}setVisible(e){this.config.visible=e}computeBreaksTyped(e){if(e.length<2)return[];let n=this.lastDataLength,r=this.cacheValid&&e.length>=n&&e[0].time===this.firstTime&&e[n-1].time===this.lastTime;if(r&&e.length===n)return this.cachedBreaksTyped;let i=r?this.cachedBreaksTyped.slice():[],a=(0,t.barTimeUnit)(e),o=r?n:1,s=(0,t.timeParts)(e[o-1].time*a,this.tz);for(let n=o;n<e.length;n++){let r=(0,t.timeParts)(e[n].time*a,this.tz);if(r.year!==s.year)i.push({idx:n,kind:`year`});else if(r.month!==s.month)i.push({idx:n,kind:`month`});else if(r.day!==s.day){let e=new Date(Date.UTC(r.year,r.month-1,r.day)).getUTCDay()===1;i.push({idx:n,kind:e?`week`:`day`})}s=r}return this.lastDataLength=e.length,this.firstTime=e[0].time,this.lastTime=e[e.length-1].time,this.cachedBreaksTyped=i,r||(this.cachedMedianStep=bw(e)),this.cacheValid=!0,i}render(e,t,n,r){this.renderLines(e,t,n,r)}renderLines(e,t,n,r){let i=this.lineMarks(t,r,n);if(i.length===0)return;let{chartRect:a}=t,o=this.look(n),s=gw[o.style];e.save(),s&&e.setLineDash(s),e.strokeStyle=o.color;for(let t of i)e.globalAlpha=t.alpha,e.lineWidth=t.width,e.beginPath(),e.moveTo(t.px,a.y),e.lineTo(t.px,a.y+a.height),e.stroke();e.restore()}lineRects(e,t,n){let r=this.lineMarks(e,n,t);if(r.length===0)return[];let{color:i,style:a}=this.look(t),o=gw[a]??void 0,{y:s,height:c}=e.chartRect;return r.map(e=>({x:e.px-e.width/2,y:s,width:e.width,height:c,color:i,alpha:e.alpha,...o?{dash:o}:{}}))}look(e){let t=e.style?.sessionBreaks;return{color:t?.color??this.config.color??e.axisLine,style:t?.style??this.config.lineStyle??`dashed`,width:t?.width??this.config.lineWidth??1}}lineMarks(e,t,n){return vw(this.marks(e,t,n),_w)}marks(t,n,r){if(!this.config.visible||n.length<2)return[];let i=this.computeBreaksTyped(n);if(i.length===0||this.cachedMedianStep>=1380*60*1e3)return[];let{chartRect:a}=t,o=this.look(r).width,s=[];for(let n of i){let r=e.C(n.idx,t)-(t.barWidth+t.barSpacing)/2;if(r<a.x-1||r>a.x+a.width+1)continue;let i=Math.round(r)+.5,c=.25,l=o,u=3;n.kind===`day`?(c=.22,u=0):n.kind===`week`?(c=.34,u=1):n.kind===`month`?(c=.5,u=2,l=o+.5):(c=.7,l=o+1),s.push({px:i,width:l,alpha:c,rank:u})}return s}invalidateCache(){this.lastDataLength=0,this.cachedBreaksTyped=[],this.cachedMedianStep=0,this.cacheValid=!1}};function bw(e){if(e.length<2)return 0;let n=Math.min(50,e.length-1),r=(0,t.barTimeUnit)(e),i=[];for(let t=1;t<=n;t++)i.push((e[t].time-e[t-1].time)*r);return i.sort((e,t)=>e-t),i[Math.floor(i.length/2)]}var xw=864e5;function Sw(e,t){let n={...e,...t};return t.tzOffsetMinutes!==void 0&&t.timeZone===void 0&&delete n.timeZone,n.windows?n.windows=n.windows.map(e=>({...e})):delete n.windows,n}function Cw(e,t){let n=((e+t*6e4)%xw+xw)%xw;return Math.floor(n/6e4)}function ww(e,t,n){return t===n?!0:t<n?e>=t&&e<n:e>=t||e<n}function Tw(e,n){let r=Cw(e,n.timeZone?(0,t.zoneOffsetMinutes)(n.timeZone,e):n.tzOffsetMinutes??0);return n.windows&&n.windows.length>0?n.windows.some(e=>ww(r,e.startMinute,e.endMinute)):ww(r,n.startMinute,n.endMinute)}var Ew={startMinute:570,endMinute:960,tzOffsetMinutes:-300,timeZone:`America/New_York`},Dw=class{visible=!1;config={...Ew};setVisible(e){this.visible=e}isVisible(){return this.visible}setConfig(e){this.config=Sw(this.config,e)}replaceConfig(e){this.config=Sw(e,{})}getConfig(){return{...this.config,windows:this.config.windows?.map(e=>({...e}))}}render(e,t,n,r){let i=this.rects(t,n,r);if(i.length!==0){e.save(),e.fillStyle=i[0].color;for(let t of i)e.fillRect(t.x,t.y,t.width,t.height);e.restore()}}rects(t,n,r){if(!this.visible||t.length===0)return[];let{chartRect:i}=n,{from:a,to:o}=n.visibleRange,s=Math.max(0,a),c=Math.min(o,t.length-1);if(c<s)return[];let l=n.barWidth+n.barSpacing,u=r.name===`light`?`rgba(0,0,0,0.045)`:`rgba(0,0,0,0.28)`,d=[],f=-1,p=(t,r)=>{let a=e.C(t,n)-l/2,o=e.C(r,n)+l/2;d.push({x:a,y:i.y,width:o-a,height:i.height,color:u,alpha:1})};for(let e=s;e<=c;e++){let n=!Tw(t[e].time,this.config);n&&f===-1?f=e:!n&&f!==-1&&(p(f,e-1),f=-1)}return f!==-1&&p(f,c),d}},Ow=[2,3],kw=16,Aw=class{highLow=!1;quote=null;quoteShown=!0;priceText=null;setPriceText(e){this.priceText=e}setQuoteShown(e){this.quoteShown=e}setHighLow(e){this.highLow=e}isHighLowVisible(){return this.highLow}setBidAsk(e){this.quote=e?{...e}:null}getBidAsk(){return this.quote?{...this.quote}:null}levels(e,t){let n=[];if(this.highLow){let r=Math.max(0,t.visibleRange.from),i=Math.min(e.length-1,t.visibleRange.to),a=-1/0,o=1/0;for(let t=r;t<=i;t++)e[t].high>a&&(a=e[t].high),e[t].low<o&&(o=e[t].low);Number.isFinite(a)&&n.push({kind:`high`,price:a}),Number.isFinite(o)&&n.push({kind:`low`,price:o})}let{bid:r,ask:i}=(this.quoteShown?this.quote:null)??{};return r!==void 0&&Number.isFinite(r)&&n.push({kind:`bid`,price:r}),i!==void 0&&Number.isFinite(i)&&n.push({kind:`ask`,price:i}),n}render(t,n,r,i){let{chartRect:a}=n;t.save(),t.setLineDash(Ow),t.lineWidth=1;for(let o of this.levels(i,n)){let i=Math.round(e.O(o.price,n))+.5;i<a.y||i>a.y+a.height||(t.strokeStyle=jw(o.kind,r),t.beginPath(),e.y(t,a.x,a.x+a.width,i),t.stroke())}t.restore()}renderAxisTags(n,r,i,a,o){let{chartRect:s}=r,c=s.x+s.width+1,l=(r.priceAxisWidth??t.PRICE_AXIS_WIDTH)-2,u=(0,t.autoPricePrecision)(r.priceRange.min,r.priceRange.max);n.save(),n.font=`${i.font.sizeSmall}px ${i.font.family}`,n.textBaseline=`middle`,n.textAlign=`left`;for(let d of this.levels(a,r)){let a=e.O(d.price,r);if(a<s.y||a>s.y+s.height)continue;let f=o?.get(d.kind)??a;if(Number.isNaN(f))continue;n.fillStyle=jw(d.kind,i),A(n,c,f-kw/2,l,kw,i),n.fillStyle=i.background;let p=r.formatPrice?.(d.price)??this.priceText?.(d.price)??(0,t.formatPrice)(d.price,u);n.fillText(p,c+5,f)}n.restore()}};function jw(e,t){switch(e){case`bid`:return t.candleUp;case`ask`:return t.candleDown;default:return t.style?.highLow.color??t.textSecondary}}var Mw=12,Nw=3,Pw=500,Fw=2,Iw=[`movesUp`,`movesDown`];function Lw(e){return e.channel===`price`&&!e.drawingId&&!e.target&&!Iw.includes(e.condition)}function Rw(e,t,n,r){switch(r){case`crossingUp`:return e!==void 0&&e<n&&t>=n;case`crossingDown`:return e!==void 0&&e>n&&t<=n;case`crossing`:return e!==void 0&&(e<n&&t>=n||e>n&&t<=n);case`greaterThan`:return t>n;case`lessThan`:return t<n;default:return!1}}var zw=[`crossing`,`crossingUp`,`crossingDown`];function Bw(e,t,n){let r=e<0&&t>=0,i=e>0&&t<=0;return n===`crossingUp`?r:n===`crossingDown`?i:r||i}var Vw=1,Hw=2**31-1,Uw=class extends Xx{alerts=[];lastValues=new Map;drawingSides=new Map;drawingLevels=null;requestRender=null;pricePrecision=null;barTime=null;expiryTimer=null;history=new Map;lastDiffs=new Map;setBarTime(e){this.barTime=e}setRequestRender(e){this.requestRender=e}setPricePrecision(e){this.pricePrecision=e}addAlert(e,t=`crossing`,n,r=!1,i=`price`,a,o={}){let s=Ww(t,i,o),c=`tc_alert_${Vw++}`,l={id:c,price:e,condition:t,message:n,triggered:!1,repeating:r,channel:i,label:a,...s};return this.alerts.push(l),s.expiresAt!==void 0&&this.scheduleExpiry(),this.emit(`added`,l),this.requestRender?.(),c}setDrawingLevels(e){this.drawingLevels=e}addDrawingAlert(e,t=`crossing`,n,r=!1,i){if(!zw.includes(t))throw RangeError(`An alert on a drawing takes a crossing condition, not "${t}"`);let a=`tc_alert_${Vw++}`,o={id:a,price:this.drawingLevels?.(e)?.[0]??NaN,condition:t,message:n,triggered:!1,repeating:r,channel:`price`,label:i,drawingId:e};return this.alerts.push(o),this.emit(`added`,o),a}removeDrawingAlerts(e){for(let t of this.alerts.filter(t=>t.drawingId===e))this.removeAlert(t.id)}takeDrawingAlerts(e){let t=this.alerts.filter(t=>t.drawingId===e);for(let e of t)this.removeAlert(e.id);return t.map(e=>({...e}))}restoreAlerts(e){for(let t of e){if(this.alerts.some(e=>e.id===t.id))continue;let e={...t};this.alerts.push(e),this.emit(`added`,e)}this.scheduleExpiry(),this.requestRender?.()}pruneDrawingAlerts(e){let t=this.alerts.filter(t=>t.drawingId!==void 0&&!e.has(t.drawingId));for(let e of t)this.removeAlert(e.id);return t.length}removeAlert(e){this.drawingSides.delete(e),this.lastDiffs.delete(e);let t=this.alerts.some(t=>t.id===e&&t.expiresAt!==void 0);this.alerts=this.alerts.filter(t=>t.id!==e),t&&this.scheduleExpiry(),this.emit(`removed`,e),this.requestRender?.()}getAlerts(){return[...this.alerts]}getAlertAtPoint(t,n,r=6){let{chartRect:i}=n;if(t.y<i.y||t.y>i.y+i.height)return null;let a=null,o=r;for(let r of this.alerts){if(!Lw(r))continue;let i=Math.abs(e.O(r.price,n)-t.y);i<=o&&(o=i,a=r)}return a}updateAlertPrice(e,t){let n=this.alerts.find(t=>t.id===e);!n||!Number.isFinite(t)||(n.price=t,n.triggered=!1,n.expiresAt!==void 0&&this.scheduleExpiry(),this.emit(`updated`,{...n}),this.requestRender?.())}clearAlerts(){this.alerts=[],this.lastDiffs.clear(),this.drawingSides.clear(),this.scheduleExpiry(),this.requestRender?.()}checkPrice(e){this.checkChannel(`price`,e),this.checkDrawingAlerts(e)}checkDrawings(e){this.checkDrawingAlerts(e)}expire(){let e=Date.now(),t=this.alerts.filter(t=>!t.expired&&t.expiresAt!==void 0&&e>=t.expiresAt&&!(t.triggered&&!t.repeating));if(t.length!==0){for(let e of t)e.expired=!0;try{for(let e of t)this.emit(`expired`,{...e}),this.emit(`updated`,{...e})}finally{this.requestRender?.(),this.scheduleExpiry()}}}scheduleExpiry(){this.expiryTimer&&clearTimeout(this.expiryTimer),this.expiryTimer=null;let e=Math.min(...this.alerts.filter(e=>!e.expired&&e.expiresAt!==void 0&&!(e.triggered&&!e.repeating)).map(e=>e.expiresAt));if(!Number.isFinite(e))return;let t=Math.min(Math.max(0,e-Date.now()),Hw);this.expiryTimer=setTimeout(()=>{this.expiryTimer=null,this.expire(),this.expiryTimer||this.scheduleExpiry()},t)}dispose(){this.expiryTimer&&clearTimeout(this.expiryTimer),this.expiryTimer=null}checkDrawingAlerts(e){if(!(!this.drawingLevels||!Number.isFinite(e)))for(let t of this.alerts){if(!t.drawingId||t.expired)continue;let n=this.drawingLevels(t.drawingId);if(!n||n.length===0){this.drawingSides.delete(t.id);continue}t.price=n[0];let r=n.map(t=>Math.sign(e-t)),i=this.drawingSides.get(t.id);this.drawingSides.set(t.id,r),!(!i||i.length!==r.length)&&(r.some((e,n)=>Bw(i[n],e,t.condition))?t.triggered||(t.triggered=!0,this.emit(`triggered`,{...t})):t.repeating&&(t.triggered=!1))}}checkChannel(e,t){this.checkChannels(new Map([[e,t]]))}checkChannels(e,t={}){let n=(e instanceof Map?[...e.entries()]:Object.entries(e)).filter(([,e])=>Number.isFinite(e));if(n.length===0)return;this.expire();let r=new Map,i=new Map;for(let[e,t]of n){r.set(e,this.lastValues.get(e));let n=this.recordBar(e,t);n&&i.set(e,n),this.lastValues.set(e,t)}for(let e of this.alerts){if(e.drawingId||e.expired)continue;let n=r.has(e.channel),a=e.target!==void 0&&r.has(e.target);if(!n&&!a||e.target!==void 0&&t.together&&!(n&&a))continue;let o;if(e.onBarClose){let t=i.get(e.channel)??(e.target?i.get(e.target):void 0);if(!t)continue;o=this.closedBarMet(e,t)}else if(e.target)o=this.targetMet(e);else if(Iw.includes(e.condition)){if(!n)continue;o=this.moveMet(e,this.history.get(e.channel)??[])}else{let t=r.get(e.channel);if(!n||t===void 0)continue;o=Rw(t,this.lastValues.get(e.channel),e.price,e.condition)}this.settle(e,o)}}settle(e,t){t?e.triggered||(e.triggered=!0,this.emit(`triggered`,{...e})):e.repeating&&(e.triggered=!1)}targetMet(e){let t=this.lastValues.get(e.channel),n=e.target?this.lastValues.get(e.target):void 0;if(t===void 0||n===void 0)return!1;let r=t-n,i=this.lastDiffs.get(e.id);return this.lastDiffs.set(e.id,r),e.price=n,Rw(i,r,0,e.condition)}moveMet(e,t,n=t.length){let r=e.bars??1,i=t.slice(Math.max(0,n-r),n);if(i.length<2||e.percent===void 0)return!1;let a=i[i.length-1].value,o=i.map(e=>e.value);if(e.condition===`movesUp`){let t=Math.min(...o);return t!==0&&(a-t)/Math.abs(t)*100>=e.percent}let s=Math.max(...o);return s!==0&&(s-a)/Math.abs(s)*100>=e.percent}closedBarMet(e,t){let n=this.history.get(e.channel)??[],r=n.findIndex(e=>e.time===t.time);if(r<0)return!1;if(Iw.includes(e.condition))return this.moveMet(e,n,r+1);let i=(e,t)=>{let r=this.history.get(e)??[],i=n[t]?.time;return i===void 0?void 0:r.find(e=>e.time===i)?.value},a=n[r].value,o=r>0?n[r-1].value:void 0,s=e.price;if(e.target){let t=i(e.target,r),n=r>0?i(e.target,r-1):void 0;if(t===void 0)return!1;a-=t,o=o!==void 0&&n!==void 0?o-n:void 0,s=0,e.price=t}return Rw(o,a,s,e.condition)}recordBar(e,t){let n=this.barTime;if(n===null)return null;let r=this.history.get(e)??[],i=r[r.length-1];if(i&&n<i.time)return r=r.filter(e=>e.time<n),r.push({time:n,value:t}),this.history.set(e,r),null;if(i&&i.time===n)return r[r.length-1]={time:n,value:t},null;i=r[r.length-1],r.push({time:n,value:t});let a=Math.min(502,Math.max(3,...this.alerts.map(e=>(e.bars??1)+2)));return r.length>a&&r.splice(0,r.length-a),this.history.set(e,r),i?{channel:e,time:i.time}:null}seedLastValue(e,t){Number.isFinite(t)&&this.lastValues.set(e,t)}clearLastValues(){this.lastValues.clear(),this.drawingSides.clear(),this.history.clear(),this.lastDiffs.clear()}saveToStorage(e){try{let t=this.alerts.map(e=>({id:e.id,price:e.price,condition:e.condition,message:e.message,triggered:e.triggered,repeating:e.repeating,channel:e.channel,label:e.label,drawingId:e.drawingId,target:e.target,percent:e.percent,bars:e.bars,onBarClose:e.onBarClose,expiresAt:e.expiresAt,expired:e.expired}));localStorage.setItem(e,JSON.stringify(t))}catch{}}loadFromStorage(e){try{let t=localStorage.getItem(e);if(!t)return;let n=JSON.parse(t);if(!Array.isArray(n))return;for(let e of n){if(typeof e.drawingId==`string`&&e.condition&&!e.triggered){zw.includes(e.condition)&&this.addDrawingAlert(e.drawingId,e.condition,e.message,e.repeating??!1,e.label);continue}if(!e.condition||e.triggered||e.expired)continue;let t=Gw(e),n=!t.target&&!Iw.includes(e.condition),r=typeof e.price==`number`&&Number.isFinite(e.price)?e.price:NaN;if(!(n&&Number.isNaN(r)))try{this.addAlert(r,e.condition,e.message,e.repeating??!1,e.channel??`price`,e.label,t)}catch{}}}catch{}}render(n,r,i){let{chartRect:a}=r;for(let o of this.alerts){if(!Lw(o))continue;let s=e.O(o.price,r);if(s<a.y||s>a.y+a.height)continue;let c=o.expired?`#8a93a3`:o.triggered?`#f2a93b`:`#4c8dff`;n.setLineDash([2,6]),n.strokeStyle=c,n.lineWidth=1,n.beginPath(),e.y(n,a.x,a.x+a.width,Math.round(s)+.5),n.stroke(),n.setLineDash([]),n.font=`10px ${i.font.family}`,n.fillStyle=c,n.textBaseline=`bottom`,n.textAlign=`right`;let l=`${(0,t.priceTagText)(o.price,r,this.pricePrecision??void 0)}${o.message?` - ${o.message}`:``}`,u=a.x+a.width-4;n.fillText(l,u,s-2);let d=u-n.measureText(l).width-Nw-Mw;d>=a.x&&Pb(n,t.UI_ICONS.bell,d,s-2-Mw,Mw,c)}}};function Ww(e,t,n){let r={},i=Iw.includes(e);if(n.target!==void 0){if(i)throw RangeError(`An alert on a move takes no other line`);if(n.target===t)throw RangeError(`An alert can’t compare a line with itself`);r.target=n.target}if(i){let{percent:e,bars:t}=n;if(e===void 0||!Number.isFinite(e)||e<=0)throw RangeError(`An alert on a move needs a percent above 0`);if(t===void 0||!Number.isInteger(t)||t<2||t>500)throw RangeError(`An alert on a move needs 2 to 500 bars`);r.percent=e,r.bars=t}return n.onBarClose&&(r.onBarClose=!0),n.expiresAt!==void 0&&Number.isFinite(n.expiresAt)&&(r.expiresAt=n.expiresAt),r}function Gw(e){let t={};return typeof e.target==`string`&&e.target&&(t.target=e.target),typeof e.percent==`number`&&Number.isFinite(e.percent)&&(t.percent=e.percent),typeof e.bars==`number`&&Number.isInteger(e.bars)&&(t.bars=e.bars),e.onBarClose===!0&&(t.onBarClose=!0),typeof e.expiresAt==`number`&&Number.isFinite(e.expiresAt)&&(t.expiresAt=e.expiresAt),t}var Kw=16,qw=3*Kw,Jw=1e3/30,Yw=1e-9,Xw=()=>typeof requestAnimationFrame==`function`&&!(typeof document<`u`&&document.hidden),Zw={now:()=>typeof performance<`u`?performance.now():Date.now(),frame:e=>Xw()?{raf:requestAnimationFrame(e)}:{timeout:setTimeout(e,Kw)},cancel:e=>{let t=e;t.raf!==void 0&&cancelAnimationFrame(t.raf),t.timeout!==void 0&&clearTimeout(t.timeout)}},Qw=class extends Xx{data=[];cursor=-1;timer=null;frameHandle=null;run=0;state=`stopped`;config={speed:1,interval:500};paceMs=null;owedMs=0;constructor(e=Zw){super(),this.clock=e}load(e){this.stop(),this.data=e,this.cursor=-1,this.owedMs=0}play(e){if(this.data.length===0)return;if(e){let{startIndex:t,paused:n,duration:r,...i}=e;this.config={...this.config,...i};let a=t===void 0?null:this.clamp(t);if(n){this.clearTimer(),this.seekTo(a??Math.max(0,this.cursor)),this.setPace(r),this.setState(`paused`);return}a!==null&&(this.cursor=a-1,this.owedMs=0),this.setPace(r)}if(this.isAtEnd()){this.clearTimer(),this.setState(`paused`);return}this.clearTimer();let t=this.stepMs();if(!(t>0)||!Number.isFinite(t)){this.setState(`paused`);return}this.setState(`playing`),this.config.animate?this.runForming(t):t<Kw||this.paceMs!==null?this.runFrames(t):this.timer=setInterval(()=>this.advance(1),t)}pause(){this.clearTimer(),this.setState(`paused`)}resume(){this.state===`paused`&&this.play()}stop(){this.clearTimer(),this.cursor=-1,this.owedMs=0,this.setState(`stopped`)}seekTo(e){this.data.length!==0&&(this.cursor=this.clamp(e),this.owedMs=0,this.emit(`bar`,{bar:this.data[this.cursor],index:this.cursor,total:this.data.length}))}setSpeed(e){let t=this.getFraction();this.config={...this.config,speed:e},this.paceMs=null;let n=this.stepMs();this.owedMs=n>0&&Number.isFinite(n)?t*n:0,this.state===`playing`&&this.play()}getState(){return this.state}isAtEnd(){return this.data.length>0&&this.cursor>=this.data.length-1}getProgress(){let e=this.data.length;return{current:Math.max(0,this.cursor),total:e,percent:e>0?(this.cursor+1)/e*100:0}}remainingMs(){return this.paceMs===null?null:this.paceMs*Math.max(0,this.data.length-1-this.cursor)}getStepMs(){return this.stepMs()}getFraction(){let e=this.stepMs();return e>0&&Number.isFinite(e)?Math.min(1,this.owedMs/e):0}dispose(){this.stop(),this.removeAllListeners(),this.data=[]}setPace(e){this.paceMs=e!==void 0&&e>0&&Number.isFinite(e)?e/Math.max(1,this.data.length-1-this.cursor):null}runFrames(e){let t=this.run,n=this.clock.now(),r=0,i=()=>{if(t!==this.run||this.state!==`playing`)return;this.frameHandle=null;let a=this.clock.now();r+=Math.min(50,Math.max(0,a-n)),n=a;let o=Math.floor(r/e);try{o>0&&(r-=o*e,this.advance(o))}finally{t===this.run&&this.state===`playing`&&this.frameHandle===null&&(this.frameHandle=this.clock.frame(i))}};this.frameHandle=this.clock.frame(i)}stepMs(){return this.paceMs??this.config.interval/this.config.speed}runForming(e){let t=this.run,n=e>=qw,r=this.clock.now(),i=-1/0,a=r=>{!n||this.isAtEnd()||t!==this.run||this.state!==`playing`||(i=r,this.emit(`phase`,{index:this.cursor+1,fraction:Math.min(1,this.owedMs/e)}))},o=()=>{if(t!==this.run||this.state!==`playing`)return;this.frameHandle=null;let n=this.clock.now();this.owedMs+=Math.min(50,Math.max(0,n-r)),r=n;let s=Math.floor((this.owedMs+Yw)/e);try{s>0?(this.owedMs=Math.max(0,this.owedMs-s*e),this.advance(s),a(n)):n-i+Kw/2>=Jw&&a(n)}finally{t===this.run&&this.state===`playing`&&this.frameHandle===null&&(this.frameHandle=this.clock.frame(o))}};a(r),this.frameHandle=this.clock.frame(o)}advance(e){if(this.isAtEnd()){this.finish();return}this.cursor=Math.min(this.data.length-1,this.cursor+e),this.emit(`bar`,{bar:this.data[this.cursor],index:this.cursor,total:this.data.length}),this.isAtEnd()&&this.finish()}finish(){this.clearTimer(),this.setState(`paused`),this.emit(`complete`,void 0)}clamp(e){return Number.isFinite(e)?Math.max(0,Math.min(Math.floor(e),this.data.length-1)):0}clearTimer(){this.run++,this.timer&&=(clearInterval(this.timer),null),this.frameHandle!==null&&(this.clock.cancel(this.frameHandle),this.frameHandle=null)}setState(e){this.state!==e&&(this.state=e,this.emit(`stateChange`,e))}},$w=64,eT=3,tT=3;function $(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function nT(e){return Array.isArray(e)?e:[]}function rT(e,t){return typeof e==`string`?e:t}function iT(e,t){return typeof e==`number`&&Number.isFinite(e)?e:t}function aT(e){if(!$(e)||typeof e.id!=`string`||typeof e.type!=`string`||!Array.isArray(e.anchors)||e.anchors.length===0||e.anchors.length>oT||!$(e.style))return null;let n=[];for(let t of e.anchors){if(!$(t)||typeof t.time!=`number`||typeof t.price!=`number`||!Number.isFinite(t.time)||!Number.isFinite(t.price))return null;n.push({time:t.time,price:t.price})}let r=(0,t.sanitizeDrawingStyle)(e.style);return r.color===void 0||r.lineWidth===void 0?null:{id:e.id,type:e.type,anchors:n,style:{lineStyle:`solid`,...r,color:r.color,lineWidth:r.lineWidth},visible:typeof e.visible==`boolean`?e.visible:!0,locked:typeof e.locked==`boolean`?e.locked:!1,options:$(e.options)?e.options:void 0,intervals:ja(e.intervals)??void 0,group:uT(e.group),...Lp(e.name)===void 0?{}:{name:Lp(e.name)},...typeof e.paneId==`string`&&e.paneId.length>0&&e.paneId.length<=sT?{paneId:e.paneId}:{},meta:$(e.meta)?e.meta:void 0}}var oT=5e3,sT=200,cT=64,lT=80;function uT(e){if(!(!$(e)||typeof e.id!=`string`||typeof e.name!=`string`)&&!(e.id===``||e.id.length>cT))return{id:e.id,name:e.name.slice(0,lT)}}function dT(e){return!$(e)||typeof e.id!=`string`||typeof e.side!=`string`||typeof e.type!=`string`||typeof e.price!=`number`||typeof e.quantity!=`number`?null:e}function fT(e){if(!$(e))return;let n={},r=nT(e.colors).filter(e=>typeof e==`string`);r.length>0&&(n.colors=r);let i=nT(e.lineWidths).filter(e=>typeof e==`number`&&Number.isFinite(e)&&e>0);i.length>0&&(n.lineWidths=i),typeof e.opacity==`number`&&Number.isFinite(e.opacity)&&(n.opacity=Math.min(1,Math.max(0,e.opacity)));let a=(0,t.readIndicatorPlotStyles)(e.plots);return a&&(n.plots=a),Object.keys(n).length>0?n:void 0}var pT=[`crossingUp`,`crossingDown`,`crossing`,`greaterThan`,`lessThan`,`movesUp`,`movesDown`];function mT(e){if(!$(e)||typeof e.id!=`string`)return null;let t=typeof e.drawingId==`string`?e.drawingId:void 0,n=typeof e.price==`number`&&Number.isFinite(e.price)?e.price:null,r=pT.find(t=>t===e.condition)??`crossing`,i=Gw(e),a=i.target!==void 0||r===`movesUp`||r===`movesDown`;return n===null&&!t&&!a?null:{id:e.id,price:n??NaN,drawingId:t,condition:r,message:typeof e.message==`string`?e.message:void 0,triggered:e.triggered===!0,repeating:e.repeating===!0,channel:rT(e.channel,`price`),label:typeof e.label==`string`?e.label:void 0,...i,...e.expired===!0?{expired:!0}:{}}}function hT(e){return!$(e)||typeof e.id!=`string`||typeof e.side!=`string`||typeof e.entryPrice!=`number`||typeof e.quantity!=`number`?null:e}var gT=4e3;function _T(e){if(!$(e))return;let n={},r=[];for(let[i,a]of Object.entries(e)){let e=(0,t.readChartStyleOverrides)(a);r.push(...e.rejected);let o=Object.fromEntries(Object.entries(e.overrides).filter(([,e])=>e!==null));Object.keys(o).length>0&&(n[i.slice(0,$w)]=o)}return r.length>0&&console.warn(`Saved style overrides left out: ${[...new Set(r)].join(`, `)}`),n}function vT(e){if(!$(e))return yT();typeof e.version==`number`&&e.version>tT&&console.warn(`Chart state from a newer version (${e.version}); loading what this version understands.`);let n=$(e.viewport)?e.viewport:{},r=[];for(let n of nT(e.indicators))$(n)&&(typeof n.id!=`string`||typeof n.instanceId!=`string`||$(n.params)&&r.push({id:n.id,instanceId:n.instanceId,params:n.params,position:typeof n.position==`string`?n.position:void 0,style:fT(n.style),visible:typeof n.visible==`boolean`?n.visible:void 0,levels:Array.isArray(n.levels)?n.levels.filter(e=>typeof e==`number`&&Number.isFinite(e)):void 0,pane:typeof n.pane==`string`?n.pane:void 0,scale:n.scale===`left`?`left`:void 0,intervals:ja(n.intervals)??void 0,paneStyle:(0,t.readPaneStyle)(n.paneStyle)??void 0,paneSize:typeof n.paneSize==`number`&&Number.isFinite(n.paneSize)&&n.paneSize>0?Math.min(n.paneSize,gT):void 0,paneOrder:typeof n.paneOrder==`number`&&Number.isInteger(n.paneOrder)&&n.paneOrder>=0?n.paneOrder:void 0,paneCollapsed:n.paneCollapsed===!0?!0:void 0,paneMaximized:n.paneMaximized===!0?!0:void 0,paneLog:n.paneLog===!0?!0:void 0,paneInvert:n.paneInvert===!0?!0:void 0,panePercent:n.panePercent===!0?!0:void 0}));let i=[];for(let t of nT(e.drawings)){let e=aT(t);e&&i.push(e)}let a=[];for(let t of nT(e.orders)){let e=dT(t);e&&a.push(e)}let o=[];for(let t of nT(e.positions)){let e=hT(t);e&&o.push(e)}let s=[];for(let t of nT(e.alerts)){let e=mT(t);e&&s.push(e)}let c=_T(e.overrides);return{version:typeof e.version==`number`&&Array.isArray(e.indicators)?e.version:1,timestamp:iT(e.timestamp,Date.now()),symbol:typeof e.symbol==`string`?e.symbol:void 0,timeframe:typeof e.timeframe==`string`?e.timeframe:void 0,chartType:rT(e.chartType,`candlestick`),...e.chartTypeOptions===void 0?{}:{chartTypeOptions:(0,t.readChartTypeOptions)(e.chartTypeOptions)},viewport:{barWidth:iT(n.barWidth,8),barSpacing:iT(n.barSpacing,2),offset:iT(n.offset,0)},theme:typeof e.theme==`string`?e.theme:void 0,...c?{overrides:c}:{},locale:typeof e.locale==`string`?e.locale:void 0,indicators:r,drawings:i,orders:a,positions:o,alerts:s}}function yT(){return{version:1,timestamp:Date.now(),chartType:`candlestick`,viewport:{barWidth:8,barSpacing:2,offset:0},indicators:[],drawings:[],orders:[],positions:[],alerts:[]}}var bT=class{static capture(e,t){return{version:e.getIndicators?tT:1,timestamp:Date.now(),chartType:t?.chartType??`candlestick`,...t?.chartTypeOptions&&Object.keys(t.chartTypeOptions).length>0?{chartTypeOptions:t.chartTypeOptions}:{},symbol:t?.symbol,timeframe:t?.timeframe,viewport:{barWidth:8,barSpacing:2,offset:0},theme:e.getTheme().name,...e.getOverrides&&Object.keys(e.getOverrides()).length>0?{overrides:e.getOverrides()}:{},indicators:e.getIndicators?.()??[],drawings:e.getDrawings(),orders:e.getOrders?.()??[],positions:e.getPositions?.()??[],alerts:e.getAlerts?.()??[]}}static serialize(e){return JSON.stringify(e)}static deserialize(e){return vT(JSON.parse(e))}static saveToStorage(e,t){localStorage.setItem(e,this.serialize(t))}static loadFromStorage(e){let t=localStorage.getItem(e);return t?this.deserialize(t):null}static downloadFile(e,t=`tc-chart-state.json`){let n=new Blob([this.serialize(e)],{type:`application/json`}),r=URL.createObjectURL(n),i=document.createElement(`a`);i.href=r,i.download=t,document.body.appendChild(i),i.click(),document.body.removeChild(i),URL.revokeObjectURL(r)}static loadFromFile(){return new Promise((e,t)=>{let n=document.createElement(`input`);n.type=`file`,n.accept=`.json`,n.onchange=async()=>{let r=n.files?.[0];if(!r){t(Error(`No file selected`));return}let i=await r.text();e(this.deserialize(i))},n.click()})}},xT=class{undoStack=[];redoStack=[];maxHistory=50;onChange=null;grouped=null;setOnChange(e){this.onChange=e}push(e){if(this.grouped){this.grouped.push(e);return}this.undoStack.push(e),this.undoStack.length>this.maxHistory&&this.undoStack.shift(),this.redoStack.length=0,this.onChange?.()}canUndo(){return this.undoStack.length>0}canRedo(){return this.redoStack.length>0}undo(){let e=this.undoStack.pop();return e?(this.redoStack.push(e),this.onChange?.(),e):null}redo(){let e=this.redoStack.pop();return e?(this.undoStack.push(e),this.onChange?.(),e):null}clear(){this.undoStack.length=0,this.redoStack.length=0,this.onChange?.()}group(e){if(this.grouped)return e();let t=[];this.grouped=t;try{return e()}finally{this.grouped=null,t.length===1?this.push(t[0]):t.length>1&&this.push({type:`drawingBatch`,before:null,after:null,actions:t})}}last(){return this.grouped?this.grouped[this.grouped.length-1]??null:this.undoStack[this.undoStack.length-1]??null}dropLast(){if(this.grouped){this.grouped.pop();return}this.undoStack.pop()&&(this.redoStack.length=0,this.onChange?.())}replaceLast(e){if(this.grouped){this.grouped.length>0?this.grouped[this.grouped.length-1]=e:this.grouped.push(e);return}if(this.undoStack.length===0){this.push(e);return}this.undoStack[this.undoStack.length-1]=e,this.redoStack.length=0,this.onChange?.()}getState(){return{canUndo:this.undoStack.length>0,canRedo:this.redoStack.length>0,undoCount:this.undoStack.length,redoCount:this.redoStack.length}}},ST=[`Time`,`Open`,`High`,`Low`,`Close`,`Volume`];function CT(e,n){return new Date((0,t.normalizeBarTime)(e,n)).toISOString()}function wT(e){let t=/^[=+\-@\t\r]/.test(e)&&!/^-?\d/.test(e)?`'${e}`:e;return/[",\r\n]/.test(t)?`"${t.replace(/"/g,`""`)}"`:t}var TT=15,ET=0x38d7ea4c68000;function DT(e){return e==null||!Number.isFinite(e)?null:Number.isInteger(e)||Math.abs(e)>=ET?e:Number(e.toPrecision(TT))}var OT=e=>{let t=DT(e);return t===null?``:String(t)},kT=class{static toCSV(e,n=[]){let r=[...ST,...n.map(e=>wT(e.name))].join(`,`),i=(0,t.barTimeUnit)(e);return[r,...e.map((e,t)=>[CT(e.time,i),...[e.open,e.high,e.low,e.close,e.volume].map(OT),...n.map(e=>OT(e.values[t]))].join(`,`))].join(`
25
25
  `)}static toJSON(e,n=[]){let r=(0,t.barTimeUnit)(e);return JSON.stringify(e.map((e,t)=>{let i={time:CT(e.time,r),open:DT(e.open),high:DT(e.high),low:DT(e.low),close:DT(e.close),volume:DT(e.volume)};for(let e of n)i[e.name]=DT(e.values[t]);return i}),null,2)}static download(e,t,n){let r=new Blob([e],{type:n}),i=URL.createObjectURL(r),a=document.createElement(`a`);a.href=i,a.download=t,document.body.appendChild(a),a.click(),document.body.removeChild(a),URL.revokeObjectURL(i)}};function AT(e,t,n=-1/0){return t===null?e:e.filter(e=>e.time>=n&&e.time<t)}function jT(e,t,n=-1/0){return t===null?e:e.filter(e=>e.entryTime>=n&&e.entryTime<t).map(e=>{if(e.exitTime===void 0||e.exitTime<t)return e;let{exitTime:n,exitPrice:r,pnl:i,pnlPercent:a,...o}=e;return o})}var MT=1,NT=3,PT=class extends Xx{markers=[];style={...t.DEFAULT_SIGNAL_STYLE};requestRender=null;dataGetter=null;revealUntil=null;revealFrom=-1/0;setRequestRender(e){this.requestRender=e}setDataGetter(e){this.dataGetter=e}setStyle(e){this.style={...this.style,...e},this.requestRender?.()}getStyle(){return{...this.style}}addMarker(e){let t=e.id??`tc_signal_${MT++}`,n={...e,id:t};return this.markers.push(n),this.emit(`added`,n),this.requestRender?.(),t}removeMarker(e){this.markers=this.markers.filter(t=>t.id!==e),this.emit(`removed`,e),this.requestRender?.()}getMarkers(){return[...this.markers]}clearMarkers(){this.markers=[],this.emit(`cleared`,void 0),this.requestRender?.()}setMarkers(e){this.markers=[...e],this.requestRender?.()}setRevealUntil(e,t=-1/0){e===this.revealUntil&&t===this.revealFrom||(this.revealUntil=e,this.revealFrom=t,this.requestRender?.())}shownMarkers(){return[...AT(this.markers,this.revealUntil,this.revealFrom)]}markerAt(t,n){let r=this.dataGetter?.();if(!r||r.length===0)return null;let{chartRect:i}=n;if(t.x<i.x||t.x>i.x+i.width||t.y<i.y||t.y>i.y+i.height)return null;let a=this.style.arrowSize??12,o=AT(this.markers,this.revealUntil,this.revealFrom);for(let i=o.length-1;i>=0;i--){let s=o[i],c=e.C(e.M(s.time,r),n),l=e.O(s.price,n),u=a*Math.max(.6,Math.min(1,s.confidence)),d=s.direction===`long`?l-u:(s.direction,l-u*.4),f=s.direction===`long`?l+u*.4:s.direction===`short`?l+u:l+u*.4;if(Math.abs(t.x-c)<=u*.6+NT&&t.y>=d-NT&&t.y<=f+NT)return s}return null}render(t,n,r){let i=this.dataGetter?.(),a=AT(this.markers,this.revealUntil,this.revealFrom);if(!i||i.length===0||a.length===0)return;let{chartRect:o}=n,s=Hx(this.style,r),c=s.arrowSize??12;t.save(),t.beginPath(),t.rect(o.x,o.y,o.width,o.height),t.clip();for(let l of a){let a=e.C(e.M(l.time,i),n),u=e.O(l.price,n);if(a<o.x-c||a>o.x+o.width+c||u<o.y-c||u>o.y+o.height+c)continue;let d=this.resolveColor(l,s),f=c*Math.max(.6,Math.min(1,l.confidence));if(this.renderArrow(t,a,u,l.direction,f,d),s.showLabel&&l.label){t.font=`10px ${r.font.family}`,t.fillStyle=d,t.textAlign=`center`,t.textBaseline=l.direction===`long`?`top`:`bottom`;let e=l.direction===`long`?u+f+3:u-f-3;t.fillText(l.label,a,e)}if(s.showConfidence&&l.confidence<1){t.font=`9px ${r.font.family}`,t.fillStyle=d,t.globalAlpha=.7,t.textAlign=`center`,t.textBaseline=l.direction===`long`?`top`:`bottom`;let e=l.direction===`long`?u+f+(l.label?14:3):u-f-(l.label?14:3);t.fillText(`${Math.round(l.confidence*100)}%`,a,e),t.globalAlpha=1}}t.restore()}resolveColor(e,t){if(e.color)return e.color;if(t.sourceColors?.[e.source])return t.sourceColors[e.source];switch(e.direction){case`long`:return t.longColor??`#1fa874`;case`short`:return t.shortColor??`#e8505b`;default:return t.neutralColor??`#9E9E9E`}}renderArrow(e,t,n,r,i,a){e.fillStyle=a,e.beginPath(),r===`long`?(e.moveTo(t,n-i),e.lineTo(t-i*.6,n),e.lineTo(t-i*.2,n),e.lineTo(t-i*.2,n+i*.4),e.lineTo(t+i*.2,n+i*.4),e.lineTo(t+i*.2,n),e.lineTo(t+i*.6,n)):r===`short`?(e.moveTo(t,n+i),e.lineTo(t-i*.6,n),e.lineTo(t-i*.2,n),e.lineTo(t-i*.2,n-i*.4),e.lineTo(t+i*.2,n-i*.4),e.lineTo(t+i*.2,n),e.lineTo(t+i*.6,n)):e.arc(t,n,i*.4,0,Math.PI*2),e.closePath(),e.fill()}},FT=12,IT=2,LT=1,RT=class extends Xx{zones=[];style={...t.DEFAULT_TRADE_ZONE_STYLE};requestRender=null;dataGetter=null;revealUntil=null;revealFrom=-1/0;pricePrecision=null;setRequestRender(e){this.requestRender=e}setDataGetter(e){this.dataGetter=e}setPricePrecision(e){this.pricePrecision=e}setStyle(e){this.style={...this.style,...e},this.requestRender?.()}getStyle(){return{...this.style}}addZone(e){let t=e.id??`tc_zone_${LT++}`,n={...e,id:t};return this.zones.push(n),this.emit(`added`,n),this.requestRender?.(),t}updateZone(e,t){let n=this.zones.findIndex(t=>t.id===e);n!==-1&&(this.zones[n]={...this.zones[n],...t},this.requestRender?.())}removeZone(e){this.zones=this.zones.filter(t=>t.id!==e),this.emit(`removed`,e),this.requestRender?.()}getZones(){return[...this.zones]}clearZones(){this.zones=[],this.emit(`cleared`,void 0),this.requestRender?.()}setZones(e){this.zones=[...e],this.requestRender?.()}setRevealUntil(e,t=-1/0){e===this.revealUntil&&t===this.revealFrom||(this.revealUntil=e,this.revealFrom=t,this.requestRender?.())}shownZones(){return[...jT(this.zones,this.revealUntil,this.revealFrom)]}render(e,t,n){let r=this.dataGetter?.(),i=jT(this.zones,this.revealUntil,this.revealFrom);if(!r||r.length===0||i.length===0)return;let{chartRect:a}=t,o=Ux(this.style,n);e.save(),e.beginPath(),e.rect(a.x,a.y,a.width,a.height),e.clip();for(let a of i)this.renderZone(e,a,r,t,n,o);e.restore()}renderZone(n,r,i,a,o,s){let{chartRect:c}=a,l=e.M(r.entryTime,i),u=r.exitTime==null?i.length-1:e.M(r.exitTime,i),d=e.C(l,a),f=e.C(u,a),p=Math.max(c.x,Math.min(d,f)),m=Math.min(c.x+c.width,Math.max(d,f));if(m-p<1)return;let h=e.O(r.entryPrice,a),g=r.exitPrice==null?e.O(r.entryPrice,a):e.O(r.exitPrice,a),_=Math.min(h,g),v=Math.max(Math.max(h,g)-_,2),y=r.exitTime==null,b=r.pnl==null?r.direction===`long`?(r.exitPrice??r.entryPrice)>=r.entryPrice:(r.exitPrice??r.entryPrice)<=r.entryPrice:r.pnl>=0,x=y?s.activeColor??`#4c8dff`:b?s.profitColor??`#1fa874`:s.lossColor??`#e8505b`;n.fillStyle=x,n.globalAlpha=s.fillOpacity??.12,n.fillRect(p,_,m-p,v),n.globalAlpha=1;let S=s.borderWidth??1;if(n.strokeStyle=x,n.lineWidth=S,n.setLineDash([]),n.beginPath(),n.moveTo(p,Math.round(h)+.5),n.lineTo(m,Math.round(h)+.5),n.stroke(),!y&&r.exitPrice!=null&&(n.setLineDash([3,3]),n.beginPath(),n.moveTo(p,Math.round(g)+.5),n.lineTo(m,Math.round(g)+.5),n.stroke(),n.setLineDash([])),Pb(n,r.direction===`long`?t.UI_ICONS.trendingUp:t.UI_ICONS.trendingDown,p+4,h-3-FT,FT,x),n.font=`bold 10px ${o.font.family}`,n.fillStyle=x,n.textBaseline=`bottom`,n.textAlign=`left`,n.fillText((0,t.priceTagText)(r.entryPrice,a,this.pricePrecision??void 0),p+4+FT+3,h-3),s.showPnl&&!y&&r.pnl!=null){let e=r.pnl>=0?`+`:``,i=e=>(0,t.formatPrice)(e,IT,a.numberLocale??`en-US`),s=r.pnlPercent==null?`${e}${i(r.pnl)}`:`${e}${i(r.pnl)} (${e}${i(r.pnlPercent)}%)`;n.font=`bold 10px ${o.font.family}`,n.fillStyle=x,n.textBaseline=`top`,n.textAlign=`right`;let c=n.measureText(s).width+8,l=m-c-2,u=_+2;n.globalAlpha=.85,n.fillStyle=o.background,A(n,l,u,c,14,o),n.globalAlpha=1,n.fillStyle=x,n.fillText(s,m-4,u+1)}s.showLabel&&r.label&&(n.font=`9px ${o.font.family}`,n.fillStyle=x,n.globalAlpha=.8,n.textBaseline=`top`,n.textAlign=`left`,n.fillText(r.label,p+4,h+3),n.globalAlpha=1)}},zT=2,BT=4,VT=10,HT=class{active=!1;startBar=0;startPrice=0;endBar=0;endPrice=0;startTime=null;endTime=null;isActive(){return this.active}begin(t,n,r){let i=Math.round(e.N(t.x,n)),a=e.F(t.y,n);this.startBar=i,this.startPrice=a,this.endBar=i,this.endPrice=a,this.startTime=UT(i,r),this.endTime=this.startTime,this.active=!0}update(t,n,r){if(!this.active)return;let i=Math.round(e.N(t.x,n));this.endBar=i,this.endPrice=e.F(t.y,n),this.endTime=UT(i,r)}end(){this.active=!1}render(n,r,i){if(!this.active)return;let a=e.C(this.startBar,r),o=e.C(this.endBar,r),s=e.O(this.startPrice,r),c=e.O(this.endPrice,r),l=Math.min(a,o),u=Math.max(a,o),d=Math.min(s,c),f=Math.max(s,c),p=u-l,m=f-d,h=this.endPrice>=this.startPrice?i.candleUp:i.candleDown,g=XT(h,.14);n.save();let{chartRect:_}=r;n.beginPath(),n.rect(_.x,_.y,_.width,_.height),n.clip(),n.fillStyle=g,n.fillRect(l,d,p,m),n.strokeStyle=h,n.lineWidth=1,n.setLineDash([4,3]),n.strokeRect(l+.5,d+.5,p,m),n.setLineDash([]),n.strokeStyle=h,n.lineWidth=1.5,n.beginPath(),n.moveTo(a,s),n.lineTo(o,c),n.stroke(),qT(n,a,s,h),qT(n,o,c,h),n.restore();let v=Math.abs(this.endBar-this.startBar),y=this.endPrice-this.startPrice,b=this.startPrice===0?0:y/this.startPrice*100,x=this.startTime!==null&&this.endTime!==null?KT(Math.abs(this.endTime-this.startTime)):null,S=[],C=y>0?`+`:y<0?`−`:``,w=Math.abs(y),T=(0,t.formatPrice)(Math.abs(b),zT,r.numberLocale??`en-US`);S.push(`${C}${WT(w,r)} (${C}${T}%)`),S.push(`${v} bars${x?` · `+x:``}`),n.save(),JT(n,o,c,S,h,i),n.restore()}};function UT(e,n){return e<0||e>=n.length?null:n[e].time*(0,t.barTimeUnit)(n)}function WT(e,n){return(0,t.priceTagText)(e,n,n.pricePrecision??GT(e))}function GT(e){return e>=1e3?2:e>=1?4:e<=0?BT-1:Math.min(VT,BT-1-Math.floor(Math.log10(e)))}function KT(e){let t=e/1e3;if(t<60)return`${t.toFixed(0)}s`;let n=t/60;if(n<60)return`${n.toFixed(1)}m`;let r=n/60;if(r<24)return`${r.toFixed(1)}h`;let i=r/24;if(i<30)return`${i.toFixed(1)}d`;let a=i/30;return a<12?`${a.toFixed(1)}mo`:`${(i/365).toFixed(1)}y`}function qT(e,t,n,r){e.fillStyle=r,e.beginPath(),e.arc(t,n,3.5,0,Math.PI*2),e.fill(),e.fillStyle=`#fff`,e.beginPath(),e.arc(t,n,1.5,0,Math.PI*2),e.fill()}function JT(e,t,n,r,i,a){e.font=`600 11px ${a.font.family}`;let o=0;for(let t of r){let n=e.measureText(t).width;n>o&&(o=n)}let s=Math.ceil(o)+16,c=r.length*14+12,l=t+8,u=n+8,d=e.canvas.clientWidth||e.canvas.width;l+s>d-4&&(l=t-s-8),l<4&&(l=4),e.fillStyle=a.background,e.globalAlpha=.96,YT(e,l,u,s,c,6),e.fill(),e.globalAlpha=1,e.strokeStyle=i,e.lineWidth=1,YT(e,l+.5,u+.5,s-1,c-1,6),e.stroke(),e.fillStyle=a.text,e.textBaseline=`top`,e.textAlign=`left`;for(let t=0;t<r.length;t++)e.fillStyle=t===0?i:a.textSecondary,e.fillText(r[t],l+8,u+6+t*14)}function YT(e,t,n,r,i,a){e.beginPath(),e.moveTo(t+a,n),e.arcTo(t+r,n,t+r,n+i,a),e.arcTo(t+r,n+i,t,n+i,a),e.arcTo(t,n+i,t,n,a),e.arcTo(t,n,t+r,n,a),e.closePath()}function XT(e,t){if(e.startsWith(`#`)){let n=0,r=0,i=0;return e.length===4?(n=parseInt(e[1]+e[1],16),r=parseInt(e[2]+e[2],16),i=parseInt(e[3]+e[3],16)):e.length>=7&&(n=parseInt(e.slice(1,3),16),r=parseInt(e.slice(3,5),16),i=parseInt(e.slice(5,7),16)),`rgba(${n},${r},${i},${t})`}if(e.startsWith(`rgb`)){let n=e.match(/[\d.]+/g);if(n&&n.length>=3)return`rgba(${n[0]},${n[1]},${n[2]},${t})`}return e}var ZT=6,QT=class{start=null;current=null;isActive(){return this.start!==null}begin(e){this.start=e,this.current=e}update(e){this.start&&(this.current=e)}end(){let e=this.start,t=this.current;if(this.cancel(),!e||!t)return null;let n=Math.min(e.x,t.x),r=Math.max(e.x,t.x),i=Math.min(e.y,t.y),a=Math.max(e.y,t.y);return{x0:n,y0:i,x1:r,y1:a,isClick:r-n<6&&a-i<6}}cancel(){this.start=null,this.current=null}render(e,t,n){if(!this.start||!this.current)return;let{chartRect:r}=t,i=e=>Math.max(r.x,Math.min(r.x+r.width,e)),a=e=>Math.max(r.y,Math.min(r.y+r.height,e)),o=i(Math.min(this.start.x,this.current.x)),s=i(Math.max(this.start.x,this.current.x)),c=a(Math.min(this.start.y,this.current.y)),l=a(Math.max(this.start.y,this.current.y));e.save(),e.fillStyle=n.crosshair,e.globalAlpha=.1,e.fillRect(o,c,s-o,l-c),e.globalAlpha=.8,e.strokeStyle=n.crosshair,e.lineWidth=1,e.setLineDash([4,3]),e.strokeRect(Math.round(o)+.5,Math.round(c)+.5,Math.round(s-o),Math.round(l-c)),e.restore()}},$T={linear:e=>e,easeOutCubic:e=>1-(1-e)**3,easeOutQuart:e=>1-(1-e)**4,easeInOutCubic:e=>e<.5?4*e*e*e:1-(-2*e+2)**3/2,easeOutExpo:e=>e===1?1:1-2**(-10*e),easeOutElastic:e=>e===0||e===1?e:2**(-10*e)*Math.sin((e*10-.75)*(2*Math.PI/3))+1,spring:e=>1-Math.E**(-6*e)*Math.cos(8*e)},eE=class{animations=new Map;frameId=0;running=!1;animate(e,t){this.animations.set(e,{startTime:-1,duration:t.duration,easing:t.easing??$T.easeOutCubic,onUpdate:t.onUpdate,onComplete:t.onComplete}),this.running||(this.running=!0,this.tick())}cancel(e){this.animations.delete(e),this.animations.size===0&&this.stop()}cancelAll(){this.animations.clear(),this.stop()}isAnimating(e){return e?this.animations.has(e):this.animations.size>0}tick(){this.frameId=requestAnimationFrame(e=>{let t=[];for(let[n,r]of this.animations){r.startTime<0&&(r.startTime=e);let i=e-r.startTime,a=Math.min(1,i/r.duration),o=r.easing(a);r.onUpdate(o),a>=1&&(r.onComplete?.(),t.push(n))}for(let e of t)this.animations.delete(e);this.animations.size>0?this.tick():this.running=!1})}stop(){this.frameId&&=(cancelAnimationFrame(this.frameId),0),this.running=!1}dispose(){this.cancelAll()}};function tE(e){return!e||e===`dark`?t.DARK_THEME:e===`light`?t.LIGHT_THEME:e}var nE=class{canvas;ctx;container;theme;width=0;height=0;dpr=1;frameId=null;resizeObserver;constructor(e,t){this.container=e,this.theme=tE(t),this.canvas=document.createElement(`canvas`),this.canvas.style.width=`100%`,this.canvas.style.height=`100%`,this.canvas.style.display=`block`,s(this.canvas),this.canvas.setAttribute(`role`,`img`),e.appendChild(this.canvas),this.ctx=this.canvas.getContext(`2d`),this.dpr=r(),this.updateSize(),this.resizeObserver=new ResizeObserver(()=>{this.updateSize(),this.requestRender()}),this.resizeObserver.observe(e)}updateSize(){this.dpr=r();let e=this.container.getBoundingClientRect();this.width=e.width||this.container.clientWidth,this.height=e.height||this.container.clientHeight,this.canvas.width=Math.max(1,Math.floor(this.width*this.dpr)),this.canvas.height=Math.max(1,Math.floor(this.height*this.dpr))}requestRender(){this.frameId===null&&(this.frameId=requestAnimationFrame(()=>{this.frameId=null,(this.width===0||this.height===0)&&this.updateSize(),!(this.width===0||this.height===0)&&(this.ctx.save(),this.ctx.scale(this.dpr,this.dpr),this.ctx.clearRect(0,0,this.width,this.height),this.renderChart(this.ctx,this.width,this.height,this.theme),this.ctx.restore())}))}setLabel(e){this.canvas.setAttribute(`aria-label`,e)}setTheme(e){this.theme=tE(e),this.requestRender()}destroy(){this.frameId!==null&&cancelAnimationFrame(this.frameId),this.resizeObserver.disconnect(),this.canvas.width=0,this.canvas.height=0,this.canvas.remove()}},rE=class{pos=null;canvas;onUpdate;handleMove;handleLeave;constructor(e,t){this.canvas=e,this.onUpdate=t,this.handleMove=t=>{let n=e.getBoundingClientRect();this.pos={x:t.clientX-n.left,y:t.clientY-n.top},this.onUpdate()},this.handleLeave=()=>{this.pos=null,this.onUpdate()},e.addEventListener(`pointermove`,this.handleMove),e.addEventListener(`pointerleave`,this.handleLeave)}getPosition(){return this.pos}isActive(){return this.pos!==null}drawCrosshair(e,t,n,r){this.pos&&(e.save(),e.strokeStyle=r,e.lineWidth=.5,e.setLineDash([4,4]),e.beginPath(),e.moveTo(this.pos.x,0),e.lineTo(this.pos.x,n),e.stroke(),e.beginPath(),e.moveTo(0,this.pos.y),e.lineTo(t,this.pos.y),e.stroke(),e.restore())}destroy(){this.canvas.removeEventListener(`pointermove`,this.handleMove),this.canvas.removeEventListener(`pointerleave`,this.handleLeave)}};function iE(e,t,n,r,i){let{data:a,mode:o=`area`,lineWidth:s=1.5,showLastPoint:c=!1,showMinMax:l=!1}=r;if(a.length<2||t<=0||n<=0)return;let u=r.color??i.lineColor,d=r.fillColor??u,f=t-4,p=n-4,m=1/0,h=-1/0,g=0,_=0;for(let e=0;e<a.length;e++)a[e]<m&&(m=a[e],g=e),a[e]>h&&(h=a[e],_=e);let v=h-m||1,y=e=>2+e/(a.length-1)*f,b=e=>2+p-(e-m)/v*p;if(o===`area`){let t=e.createLinearGradient(0,2,0,n-2);t.addColorStop(0,d+(d.startsWith(`#`)?`40`:``)),t.addColorStop(1,`transparent`),e.beginPath(),e.moveTo(y(0),b(a[0]));for(let t=1;t<a.length;t++)e.lineTo(y(t),b(a[t]));e.lineTo(y(a.length-1),n-2),e.lineTo(y(0),n-2),e.closePath(),e.fillStyle=t,e.fill()}e.beginPath(),e.moveTo(y(0),b(a[0]));for(let t=1;t<a.length;t++)e.lineTo(y(t),b(a[t]));if(e.strokeStyle=u,e.lineWidth=s,e.lineJoin=`round`,e.stroke(),c){let t=r.lastPointColor??u,n=y(a.length-1),i=b(a[a.length-1]);e.beginPath(),e.arc(n,i,3,0,Math.PI*2),e.fillStyle=t,e.fill()}if(l){let t=r.minPointColor??i.candleDown,n=r.maxPointColor??i.candleUp;e.beginPath(),e.arc(y(g),b(m),2.5,0,Math.PI*2),e.fillStyle=t,e.fill(),e.beginPath(),e.arc(y(_),b(h),2.5,0,Math.PI*2),e.fillStyle=n,e.fill()}}var aE=50,oE=60,sE=20,cE=.2;function lE(e){let t=[...e].sort((e,t)=>t.price-e.price),n=[],r=0;for(let e of t)r+=e.volume,n.push({price:e.price,cumulativeVolume:r});return n}function uE(e){let t=[...e].sort((e,t)=>e.price-t.price),n=[],r=0;for(let e of t)r+=e.volume,n.push({price:e.price,cumulativeVolume:r});return n}function dE(e,t){return{left:aE,right:e-oE,top:sE,bottom:t-sE,plotWidth:e-aE-oE,plotHeight:t-sE*2}}function fE(e,t,n,r){e.fillStyle=r,e.fillRect(0,0,t,n)}function pE(e,n,r,i,a,o,s,c){let{left:l,right:u,top:d,bottom:f,plotWidth:p,plotHeight:m}=n;e.save(),e.strokeStyle=o.grid,e.lineWidth=.5,e.fillStyle=o.axisLabel,e.font=`${o.font.sizeSmall}px ${o.font.family}`;let h=(0,t.computeTickStep)(0,a,5);for(let t=0;t<=a;t+=h){let n=f-t/a*m;e.beginPath(),e.moveTo(l,n),e.lineTo(u,n),e.stroke(),e.textAlign=`right`,e.textBaseline=`middle`,e.fillText(c(t),l-4,n)}let g=i-r,_=(0,t.computeTickStep)(r,i,6),v=Math.ceil(r/_)*_;for(let t=v;t<=i;t+=_){let n=l+(t-r)/g*p;e.beginPath(),e.moveTo(n,d),e.lineTo(n,f),e.stroke(),e.textAlign=`center`,e.textBaseline=`top`,e.fillText(s(t),n,f+4)}e.restore()}function mE(e,t,n,r,i,a,o,s,c){if(t.length===0)return;let{left:l,bottom:u,plotWidth:d,plotHeight:f}=n,p=e=>l+(e-r)/i*d,m=e=>u-e/a*f;if(e.beginPath(),c===`bid`){e.moveTo(p(t[0].price),u);for(let n=0;n<t.length;n++){let r=p(t[n].price),i=m(t[n].cumulativeVolume);e.lineTo(r,i),n<t.length-1&&e.lineTo(p(t[n+1].price),i)}e.lineTo(p(t[t.length-1].price),u)}else{e.moveTo(p(t[0].price),u);for(let n=0;n<t.length;n++){let r=p(t[n].price),i=m(t[n].cumulativeVolume);e.lineTo(r,i),n<t.length-1&&e.lineTo(p(t[n+1].price),i)}e.lineTo(p(t[t.length-1].price),u)}if(e.closePath(),e.fillStyle=o,e.fill(),e.beginPath(),c===`bid`){e.moveTo(p(t[0].price),m(t[0].cumulativeVolume));for(let n=0;n<t.length;n++){let r=p(t[n].price),i=m(t[n].cumulativeVolume);n>0&&e.lineTo(r,m(t[n-1].cumulativeVolume)),e.lineTo(r,i)}}else{e.moveTo(p(t[0].price),m(t[0].cumulativeVolume));for(let n=1;n<t.length;n++){let r=m(t[n-1].cumulativeVolume),i=p(t[n].price),a=m(t[n].cumulativeVolume);e.lineTo(i,r),e.lineTo(i,a)}}e.strokeStyle=s,e.lineWidth=1.5,e.stroke()}function hE(e,t,n,r,i,a,o,s,c){let{left:l,top:u,bottom:d,plotWidth:f}=r,p=l+(t-i)/a*f;if(e.save(),e.strokeStyle=o.textSecondary,e.lineWidth=1,e.setLineDash([4,4]),e.beginPath(),e.moveTo(p,u),e.lineTo(p,d),e.stroke(),e.restore(),s){let t=`Spread: ${c(n)}`;e.save(),e.font=`${o.font.sizeSmall}px ${o.font.family}`,e.fillStyle=o.textSecondary,e.textAlign=`center`,e.textBaseline=`bottom`,e.fillText(t,p,u-2),e.restore()}}function gE(e,t,n,r,i,a,o,s,c,l,u){let{left:d,top:f,bottom:p,plotWidth:m,plotHeight:h}=i,g=t.x;if(g<d||g>i.right)return;let _=a+(g-d)/m*o,v=0,y=``;if(n.length>0&&_<=n[0].price){y=`Bid`;for(let e of n)if(_<=e.price)v=e.cumulativeVolume;else break}if(r.length>0&&_>=r[0].price){y=`Ask`;for(let e of r)if(_>=e.price)v=e.cumulativeVolume;else break}if(e.save(),e.strokeStyle=c.crosshair,e.lineWidth=.5,e.setLineDash([4,4]),e.beginPath(),e.moveTo(g,f),e.lineTo(g,p),e.stroke(),v>0){let t=p-v/s*h;e.beginPath(),e.moveTo(d,t),e.lineTo(i.right,t),e.stroke()}e.restore();let b=[`Price: ${l(_)}`,y?`${y} Vol: ${u(v)}`:``].filter(Boolean);e.save(),e.font=`${c.font.sizeSmall}px ${c.font.family}`;let x=Math.max(...b.map(t=>e.measureText(t).width))+16,S=b.length*(c.font.sizeSmall+4)+12,C=g+10,w=t.y-S/2;C+x>i.right&&(C=g-x-10),w<f&&(w=f),w+S>p&&(w=p-S),e.fillStyle=c.axisLabelBackground,e.globalAlpha=.9,e.fillRect(C,w,x,S),e.globalAlpha=1,e.fillStyle=c.text,e.textBaseline=`top`,e.textAlign=`left`;for(let t=0;t<b.length;t++)e.fillText(b[t],C+8,w+6+t*(c.font.sizeSmall+4));e.restore()}function _E(e){return e.toFixed(2)}function vE(e){return e>=1e6?(e/1e6).toFixed(2)+`M`:e>=1e3?(e/1e3).toFixed(1)+`K`:e.toFixed(0)}function yE(e,t,n,r,i,a){let{data:o}=r;if(o.bids.length===0&&o.asks.length===0||t<=0||n<=0)return;let s=r.bidColor??i.candleUp,c=r.askColor??i.candleDown,l=r.bidFillColor??s+`40`,u=r.askFillColor??c+`40`,d=r.midPriceLine!==!1,f=r.spreadLabel!==!1,p=r.priceFormat??_E,m=r.volumeFormat??vE,h=lE(o.bids),g=uE(o.asks),_=h.length>0?h[0].price:0,v=g.length>0?g[0].price:0,y=h.length>0&&g.length>0?(_+v)/2:_||v,b=g.length>0&&h.length>0?v-_:0,x=h.length>0?h[h.length-1].price:y,S=g.length>0?g[g.length-1].price:y,C=Math.max(y-x,S-y)*(1+cE),w=y-C,T=y+C,E=T-w,D=h.length>0?h[h.length-1].cumulativeVolume:0,O=g.length>0?g[g.length-1].cumulativeVolume:0,k=Math.max(D,O)||1,A=dE(t,n);fE(e,t,n,i.background),pE(e,A,w,T,k,i,p,m),mE(e,h,A,w,E,k,l,s,`bid`),mE(e,g,A,w,E,k,u,c,`ask`),d&&hE(e,y,b,A,w,E,i,f,p),a&&gE(e,a,h,g,A,w,E,k,i,p,m)}var bE=70,xE=30,SE=20,CE=20,wE=.05;function TE(e,t){return{left:bE,right:e-SE,top:CE,bottom:t-xE,plotWidth:e-bE-SE,plotHeight:t-CE-xE}}function EE(e,t){let n=1/0,r=-1/0;for(let t of e)t.value<n&&(n=t.value),t.value>r&&(r=t.value);if(t)for(let e of t)e.value<n&&(n=e.value),e.value>r&&(r=e.value);let i=(r-n)*wE;return{valMin:n-i,valMax:r+i}}function DE(e){let t=[],n=-1/0;for(let r of e)r.value>n&&(n=r.value),t.push(n);return t}function OE(e){let t=864e5;if(365.25*t,e<7*t){let e=new Intl.DateTimeFormat(void 0,{hour:`2-digit`,minute:`2-digit`});return t=>e.format(new Date(t))}if(e<315576e5){let e=new Intl.DateTimeFormat(void 0,{month:`short`,day:`numeric`});return t=>e.format(new Date(t))}let n=new Intl.DateTimeFormat(void 0,{month:`short`,year:`numeric`});return e=>n.format(new Date(e))}function kE(e){return Math.abs(e)>=1e6?(e/1e6).toFixed(2)+`M`:Math.abs(e)>=1e3?(e/1e3).toFixed(1)+`K`:e.toFixed(2)}function AE(e,t,n,r){e.fillStyle=r,e.fillRect(0,0,t,n)}function jE(e,n,r,i,a,o,s,c,l){let{left:u,right:d,top:f,bottom:p,plotWidth:m,plotHeight:h}=n;e.save(),e.strokeStyle=s.grid,e.lineWidth=.5,e.fillStyle=s.axisLabel,e.font=`${s.font.sizeSmall}px ${s.font.family}`;let g=(0,t.computeTickStep)(r,i,6),_=Math.ceil(r/g)*g;for(let t=_;t<=i;t+=g){let n=p-(t-r)/(i-r)*h;e.beginPath(),e.moveTo(u,n),e.lineTo(d,n),e.stroke(),e.textAlign=`right`,e.textBaseline=`middle`,e.fillText(c(t),u-6,n)}let v=o-a,y=(0,t.computeTickStep)(a,o,6),b=Math.ceil(a/y)*y;for(let t=b;t<=o;t+=y){let n=u+(t-a)/v*m;e.beginPath(),e.moveTo(n,f),e.lineTo(n,p),e.stroke(),e.textAlign=`center`,e.textBaseline=`top`,e.fillText(l(t),n,p+4)}e.restore()}function ME(e,t,n,r,i,a,o,s,c){if(t.length<2)return;let{left:l,bottom:u,plotWidth:d,plotHeight:f}=n,p=e=>l+(e-r)/i*d,m=e=>u-(e-a)/o*f;e.save(),e.beginPath(),e.moveTo(p(t[0].time),m(t[0].value));for(let n=1;n<t.length;n++)e.lineTo(p(t[n].time),m(t[n].value));e.strokeStyle=s,e.lineWidth=c,e.lineJoin=`round`,e.stroke(),e.restore()}function NE(e,t,n,r,i,a,o,s){if(t.length<2)return;let{left:c,bottom:l,plotWidth:u,plotHeight:d}=n,f=e=>c+(e-r)/i*u,p=e=>l-(e-a)/o*d,m=e.createLinearGradient(0,n.top,0,l);m.addColorStop(0,s+`40`),m.addColorStop(1,`transparent`),e.save(),e.beginPath(),e.moveTo(f(t[0].time),p(t[0].value));for(let n=1;n<t.length;n++)e.lineTo(f(t[n].time),p(t[n].value));e.lineTo(f(t[t.length-1].time),l),e.lineTo(f(t[0].time),l),e.closePath(),e.fillStyle=m,e.fill(),e.restore()}function PE(e,t,n,r,i,a,o,s,c){if(t.length<2)return;let{left:l,bottom:u,plotWidth:d,plotHeight:f}=r,p=e=>l+(e-i)/a*d,m=e=>u-(e-o)/s*f;e.save(),e.fillStyle=c,e.beginPath(),e.moveTo(p(t[0].time),m(n[0]));for(let r=1;r<t.length;r++)e.lineTo(p(t[r].time),m(n[r]));for(let n=t.length-1;n>=0;n--)e.lineTo(p(t[n].time),m(t[n].value));e.closePath(),e.fill(),e.restore()}function FE(e,t,n,r,i,a,o,s,c,l){if(t.length===0)return;let{left:u,bottom:d,plotWidth:f,plotHeight:p}=n,m=t[t.length-1],h=u+(m.time-r)/i*f,g=d-(m.value-a)/o*p;e.save(),e.font=`${l.font.sizeSmall}px ${l.font.family}`,e.fillStyle=c,e.textAlign=`left`,e.textBaseline=`middle`,e.fillText(s,h+4,g),e.restore()}function IE(e,t,n,r,i,a,o,s,c,l,u,d){let{left:f,top:p,bottom:m,plotWidth:h,plotHeight:g}=i,_=t.x;if(_<f||_>i.right)return;e.save(),e.strokeStyle=l.crosshair,e.lineWidth=.5,e.setLineDash([4,4]),e.beginPath(),e.moveTo(_,p),e.lineTo(_,m),e.stroke(),e.restore();let v=a+(_-f)/h*o,y=0,b=1/0;for(let e=0;e<n.length;e++){let t=Math.abs(n[e].time-v);t<b&&(b=t,y=e)}let x=n[y],S=[u(x.time),`Value: ${d(x.value)}`];r&&r.length>y&&S.push(`Benchmark: ${d(r[y].value)}`);let C=f+(x.time-a)/o*h,w=m-(x.value-s)/c*g;e.beginPath(),e.arc(C,w,3,0,Math.PI*2),e.fillStyle=l.lineColor,e.fill(),e.save(),e.font=`${l.font.sizeSmall}px ${l.font.family}`;let T=Math.max(...S.map(t=>e.measureText(t).width))+16,E=S.length*(l.font.sizeSmall+4)+12,D=_+10,O=t.y-E/2;D+T>i.right&&(D=_-T-10),O<p&&(O=p),O+E>m&&(O=m-E),e.fillStyle=l.axisLabelBackground,e.globalAlpha=.9,e.fillRect(D,O,T,E),e.globalAlpha=1,e.fillStyle=l.text,e.textBaseline=`top`,e.textAlign=`left`;for(let t=0;t<S.length;t++)e.fillText(S[t],D+8,O+6+t*(l.font.sizeSmall+4));e.restore()}function LE(e,t,n,r,i,a){let{data:o}=r;if(o.length<2||t<=0||n<=0)return;let s=r.lineColor??i.lineColor,c=r.lineWidth??1.5,l=r.drawdown===!0,u=r.drawdownColor??i.candleDown+`30`,d=r.fillArea===!0,f=r.benchmark,p=r.benchmarkColor??i.textSecondary,m=r.benchmarkLabel??`Benchmark`,h=r.valueFormat??kE,{valMin:g,valMax:_}=EE(o,f),v=_-g||1,y=o[0].time,b=o[o.length-1].time,x=b-y||1,S=r.timeFormat??OE(x),C=TE(t,n);AE(e,t,n,i.background),jE(e,C,g,_,y,b,i,h,S),l&&PE(e,o,DE(o),C,y,x,g,v,u),d&&NE(e,o,C,y,x,g,v,s),ME(e,o,C,y,x,g,v,s,c),f&&f.length>=2&&(ME(e,f,C,y,x,g,v,p,1),FE(e,f,C,y,x,g,v,m,p,i)),a&&IE(e,a,o,f,C,y,x,g,v,i,S,h)}function RE(e,t,n){if(e.length===0)return[];let r=e.length,i=Math.ceil(Math.sqrt(r)),a=Math.ceil(r/i),o=t.width/i,s=t.height/a,c=[];for(let a=0;a<r;a++){let r=a%i,l=Math.floor(a/i);c.push({id:e[a].id,rect:{x:t.x+r*o+n,y:t.y+l*s+n,width:Math.max(0,o-n*2),height:Math.max(0,s-n*2)}})}return c}function zE(e,t){let n=e.reduce((e,t)=>e+t,0);if(n===0||t===0)return 1/0;let r=0;for(let i of e){let e=n/t,a=i/e,o=e>a?e/a:a/e;o>r&&(r=o)}return r}function BE(e,t,n,r,i,a){let o=r?n.height:n.width,s=e.reduce((e,t)=>e+t,0),c=o>0?s/o:0,l=0;for(let o=0;o<e.length;o++){let s=c>0?e[o]/c:0,u;u=r?{x:n.x+i,y:n.y+l+i,width:Math.max(0,c-i*2),height:Math.max(0,s-i*2)}:{x:n.x+l+i,y:n.y+i,width:Math.max(0,s-i*2),height:Math.max(0,c-i*2)},a.push({id:t[o],rect:u}),l+=s}}function VE(e,t,n,r,i){if(e.length===0)return;let a=n.width>=n.height,o=a?n.height:n.width;if(e.length===1){BE(e,t,n,a,r,i);return}let s=[],c=[],l=0;for(;l<e.length;){let u=[...s,e[l]];if(s.length===0||zE(u,o)<=zE(s,o))s.push(e[l]),c.push(t[l]),l++;else{BE(s,c,n,a,r,i);let u=s.reduce((e,t)=>e+t,0),d=o>0?u/o:0;n=a?{x:n.x+d,y:n.y,width:n.width-d,height:n.height}:{x:n.x,y:n.y+d,width:n.width,height:n.height-d},VE(e.slice(l),t.slice(l),n,r,i);return}}s.length>0&&BE(s,c,n,a,r,i)}function HE(e,t,n){if(e.length===0)return[];let r=[...e].sort((e,t)=>t.weight-e.weight),i=r.reduce((e,t)=>e+Math.max(0,t.weight),0);if(i===0)return[];let a=t.width*t.height,o=r.map(e=>Math.max(0,e.weight)/i*a),s=r.map(e=>e.id),c=[];return VE(o,s,{...t},n,c),c}var UE=2,WE=18;function GE(e,t,n,r=18){let i=new Map;for(let t of e){if(!(t.weight>0))continue;let e=t.group??``,n=i.get(e);n?n.push(t):i.set(e,[t])}let a=[...i.keys()],o=HE(a.map((e,t)=>({id:String(t),weight:i.get(e).reduce((e,t)=>e+t.weight,0)})),t,0),s=[],c=[];for(let e of o){let t=a[Number(e.id)],o=i.get(t),l=o.reduce((e,t)=>e+t.weight,0),u=o.reduce((e,t)=>e+(Number.isFinite(t.value)?t.value*t.weight:0),0),d=e.rect,f=t!==``&&d.height>=r*2.5&&d.width>=40?r:0,p={x:d.x+UE/2,y:d.y+UE/2+f,width:Math.max(0,d.width-UE),height:Math.max(0,d.height-UE-f)};s.push({name:t,rect:{...d},header:f,value:l>0?u/l:0,count:o.length}),c.push(...HE(o,p,n))}return{groups:s,cells:c}}function KE(e){return(e>=0?`+`:``)+e.toFixed(2)+`%`}function qE(e){return e.label}function JE(e,n){let r=n.min??-5,i=n.max??5;if(e<=r)return n.negative;if(e>=i)return n.positive;if(e<0){let i=1-e/r;return(0,t.lerpColor)(n.negative,n.zero,i)}let a=e/i;return(0,t.lerpColor)(n.zero,n.positive,a)}var YE=`#FFFFFF`,XE=`#11151b`;function ZE(e,n){let r=/^rgba\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)\s*\)$/i.exec(e.trim());return xf(r?(0,t.lerpColor)(n,`rgb(${r[1]},${r[2]},${r[3]})`,Number(r[4])):(0,t.lerpColor)(e,e,0))===XE?XE:YE}function QE(e,t,n,r,i,a){let o=Math.min(a,r/2,i/2);e.beginPath(),e.moveTo(t+o,n),e.lineTo(t+r-o,n),e.arcTo(t+r,n,t+r,n+o,o),e.lineTo(t+r,n+i-o),e.arcTo(t+r,n+i,t+r-o,n+i,o),e.lineTo(t+o,n+i),e.arcTo(t,n+i,t,n+i-o,o),e.lineTo(t,n+o),e.arcTo(t,n,t+o,n,o),e.closePath()}function $E(e,t,n,r,i,a,o,s,c,l,u,d){if(i<40||a<30)return;let f=n+i/2,p=r+a/2;e.save();let m=d===YE;if(e.shadowColor=m?`rgba(0,0,0,0.6)`:`transparent`,e.shadowBlur=m?2:0,e.fillStyle=d,e.textAlign=`center`,s){let n=l(t),r=Math.min(o.font.sizeMedium,i/n.length*1.5,a/4);e.font=`bold `+Math.max(8,r)+`px `+o.font.family,e.textBaseline=c?`bottom`:`middle`,e.fillText(n,f,c?p-1:p,i-8)}if(c){let n=u(t.value),r=Math.min(o.font.sizeSmall,i/n.length*1.5,a/4);e.font=Math.max(7,r)+`px `+o.font.family,e.textBaseline=s?`top`:`middle`,e.fillText(n,f,s?p+1:p,i-8)}e.restore()}function eD(e,t,n,r,i,a,o,s){let c=[o(t),s(t.value)];if(t.meta)for(let[e,n]of Object.entries(t.meta))c.push(e+`: `+String(n));e.save(),e.font=a.font.sizeSmall+`px `+a.font.family;let l=Math.max(...c.map(t=>e.measureText(t).width))+16,u=a.font.sizeSmall+4,d=c.length*u+12,f=n.x+14,p=n.y-d/2;f+l>r&&(f=n.x-l-14),p<0&&(p=0),p+d>i&&(p=i-d),e.fillStyle=a.axisLabelBackground,e.globalAlpha=.92,QE(e,f,p,l,d,4),e.fill(),e.globalAlpha=1,e.fillStyle=a.text,e.textBaseline=`top`,e.textAlign=`left`;for(let t=0;t<c.length;t++)e.fillText(c[t],f+8,p+6+t*u);e.restore()}function tD(e,t,n,r,i,a,o,s,c=[]){if(r.length===0||i.length===0||t<=0||n<=0)return null;let l=a.colorScale,u={negative:l?.negative??`#e8505b`,zero:l?.zero??`#424242`,positive:l?.positive??`#1fa874`,min:l?.min,max:l?.max},d=a.cellRadius??4,f=a.showLabels!==!1,p=a.showValues!==!1,m=a.valueFormat??KE,h=a.labelFormat??qE,g=new Map;for(let e of r)g.set(e.id,e);let _=null,v=null;if(s)for(let e of i){let{x:t,y:n,width:r,height:i}=e.rect;if(s.x>=t&&s.x<=t+r&&s.y>=n&&s.y<=n+i){_=e.id;let t=g.get(e.id);t&&(v={cell:t,rect:e});break}}e.fillStyle=o.background,e.fillRect(0,0,t,n);for(let t of i){let n=g.get(t.id);if(!n)continue;let{x:r,y:i,width:a,height:s}=t.rect;if(a<=0||s<=0)continue;let c=JE(n.value,u);QE(e,r,i,a,s,d),e.fillStyle=c,e.fill(),$E(e,n,r,i,a,s,o,f,p,h,m,ZE(c,o.background)),t.id===_&&(QE(e,r,i,a,s,d),e.strokeStyle=`#FFFFFF`,e.lineWidth=1.5,e.stroke())}let y=s&&!v?c.find(e=>e.header>0&&nD(e,s)):void 0;return rD(e,c,o,m,y),v&&s?eD(e,v.cell,s,t,n,o,h,m):y&&s&&eD(e,{id:``,label:y.name,value:y.value},s,t,n,o,e=>e.label,m),v}function nD(e,t){let n=e.rect;return t.x>=n.x&&t.x<=n.x+n.width&&t.y>=n.y&&t.y<=n.y+e.header}function rD(e,t,n,r,i){if(t.length===0)return;e.save(),e.textBaseline=`middle`;let a=n.font.sizeSmall,o=t=>e.measureText(t).width;for(let s of t){if(s.header<=0)continue;let{x:t,y:c,width:l}=s.rect,u=c+s.header/2+1;e.font=a+`px `+n.font.family;let d=r(s.value),f=o(d),p=l>=f*2+24;p&&(e.textAlign=`right`,e.fillStyle=s.value<0?n.candleDown:s.value>0?n.candleUp:n.textSecondary,e.fillText(d,t+l-5,u)),e.font=`600 `+a+`px `+n.font.family,e.textAlign=`left`,e.fillStyle=s===i?n.text:n.textSecondary;let m=l-10-(p?f+8:0),h=uf(s.name,m,e=>o(e),a);h&&e.fillText(h,t+5,u)}e.restore()}var iD=60,aD=12,oD=24,sD=40,cD=.7,lD=1;function uD(e){return e.type?e.type:e.value>0?`positive`:e.value<0?`negative`:`subtotal`}function dD(e){let t=Math.abs(e);return t>=1e6?(e/1e6).toFixed(2)+`M`:t>=1e3?(e/1e3).toFixed(1)+`K`:e.toFixed(2)}function fD(e,t){return{left:iD,right:e-aD,top:oD,bottom:t-sD,plotWidth:e-iD-aD,plotHeight:t-oD-sD}}function pD(e,t,n,r,i){let a=Array(e.length),o=Array(e.length),s=t.plotWidth/e.length,c=s*n,l=(s-c)/2,{left:u,bottom:d,plotHeight:f}=t,p=0;for(let t=0;t<e.length;t++){let n=e[t],m=uD(n),h,g;m===`total`||m===`subtotal`?(h=0,g=n.value,p=n.value):(h=p,g=p+n.value,p=g);let _=Math.min(h,g),v=Math.max(h,g),y=d-(_-r)/i*f,b=d-(v-r)/i*f,x=Math.min(y,b),S=Math.max(Math.abs(b-y),lD),C=u+t*s,w=C+l;a[t]={label:n.label,value:n.value,start:h,end:g,type:m,rectX:w,rectY:x,rectW:c,rectH:S,slotX:C,slotW:s},o[t]=p}return{bars:a,cumulatives:o}}function mD(e){if(e.length===0)return{valMin:0,valMax:1};let t=0,n=0,r=0;for(let i=0;i<e.length;i++){let a=e[i],o=uD(a),s,c;o===`total`||o===`subtotal`?(s=0,c=a.value,r=a.value):(s=r,c=r+a.value,r=c),s<t&&(t=s),c<t&&(t=c),s>n&&(n=s),c>n&&(n=c)}let i=(n-t||1)*.1;return{valMin:t-i,valMax:n+i}}function hD(e,t,n,r){e.fillStyle=r,e.fillRect(0,0,t,n)}function gD(e,n,r,i,a,o){let{left:s,right:c,top:l,bottom:u,plotHeight:d}=n,f=i-r||1;e.strokeStyle=a.grid,e.lineWidth=.5,e.fillStyle=a.axisLabel,e.font=`${a.font.sizeSmall}px ${a.font.family}`,e.textAlign=`right`,e.textBaseline=`middle`;let p=(0,t.computeTickStep)(r,i,5),m=Math.ceil(r/p)*p;e.beginPath();for(let t=m;t<=i;t+=p){let n=Math.round(u-(t-r)/f*d)+.5;n<l||n>u||(e.moveTo(s,n),e.lineTo(c,n))}e.stroke();for(let t=m;t<=i;t+=p){let n=u-(t-r)/f*d;n<l-1||n>u+1||e.fillText(o(t),s-6,n)}if(r<0&&i>0){let t=Math.round(u-(0-r)/f*d)+.5;e.strokeStyle=a.axisLine,e.lineWidth=1,e.beginPath(),e.moveTo(s,t),e.lineTo(c,t),e.stroke()}}function _D(e,t,n){let r=[`positive`,`negative`,`total`,`subtotal`];for(let i=0;i<r.length;i++){let a=r[i],o=n[a],s=!1;e.beginPath();for(let n=0;n<t.length;n++){let r=t[n];if(r.type!==a)continue;let i=Math.round(r.rectX),o=Math.round(r.rectY),c=Math.round(r.rectW),l=Math.round(r.rectH);e.rect(i,o,c,l),s=!0}s&&(e.fillStyle=o,e.fill())}}function vD(e,t,n,r,i,a,o){if(o===`none`||t.length<2)return;let{bottom:s,plotHeight:c}=n;e.strokeStyle=a,e.lineWidth=1,o===`dashed`?e.setLineDash([4,4]):e.setLineDash([]),e.beginPath();for(let n=0;n<t.length-1;n++){let a=t[n],o=t[n+1],l=a.end,u=Math.round(s-(l-r)/i*c)+.5,d=Math.round(a.rectX+a.rectW),f=Math.round(o.rectX);f<=d||(e.moveTo(d,u),e.lineTo(f,u))}e.stroke(),e.setLineDash([])}function yD(e,t,n,r,i,a){e.fillStyle=r.text,e.font=`${r.font.sizeSmall}px ${r.font.family}`,e.textAlign=`center`;for(let r=0;r<t.length;r++){let o=t[r],s;s=o.type===`total`||o.type===`subtotal`?i(o.value):a?`${o.value>=0?`+`:``}${i(o.value)}`:i(n[r]);let c=o.rectX+o.rectW/2;o.end<o.start?(e.textBaseline=`top`,e.fillText(s,c,o.rectY+o.rectH+4)):(e.textBaseline=`bottom`,e.fillText(s,c,o.rectY-4))}}function bD(e,t,n,r,i){e.fillStyle=r.axisLabel,e.font=`${r.font.sizeSmall}px ${r.font.family}`,e.textAlign=`center`,e.textBaseline=`top`;let a=n.bottom+6,o=t.length>0?t[0].slotW-4:0,s=!1;for(let n=0;n<t.length;n++)if(e.measureText(i(t[n].label)).width>o){s=!0;break}if(!s){for(let n=0;n<t.length;n++){let r=t[n],o=r.slotX+r.slotW/2;e.fillText(i(r.label),o,a)}return}e.save(),e.textAlign=`right`,e.textBaseline=`middle`;for(let n=0;n<t.length;n++){let r=t[n],o=r.slotX+r.slotW/2;e.setTransform(1,0,0,1,o,a+4),e.rotate(-Math.PI/4),e.fillText(i(r.label),0,0)}e.setTransform(1,0,0,1,0,0),e.restore()}function xD(e,t,n){if(t<n.left||t>n.right)return null;for(let n=0;n<e.length;n++){let r=e[n];if(t>=r.slotX&&t<=r.slotX+r.slotW)return n}return null}function SD(e,t,n,r,i,a,o,s){let c=t[r],l=n[r],u=Math.round(c.slotX+c.slotW/2)+.5;e.strokeStyle=o.crosshair,e.lineWidth=.5,e.setLineDash([4,4]),e.beginPath(),e.moveTo(u,a.top),e.lineTo(u,a.bottom),e.stroke(),e.setLineDash([]);let d=[c.label,`Value: ${c.value>=0&&(c.type===`positive`||c.type===`negative`)?`+`:``}${s(c.value)}`,`Total: ${s(l)}`];e.font=`${o.font.sizeSmall}px ${o.font.family}`;let f=0;for(let t=0;t<d.length;t++){let n=e.measureText(d[t]).width;n>f&&(f=n)}let p=f+16,m=d.length*(o.font.sizeSmall+4)+12,h=i.x+10,g=i.y-m/2;h+p>a.right&&(h=i.x-p-10),g<a.top&&(g=a.top),g+m>a.bottom&&(g=a.bottom-m),e.fillStyle=o.axisLabelBackground,e.globalAlpha=.9,e.fillRect(h,g,p,m),e.globalAlpha=1,e.fillStyle=o.text,e.textAlign=`left`,e.textBaseline=`top`;let _=o.font.sizeSmall+4;for(let t=0;t<d.length;t++)e.fillText(d[t],h+8,g+6+t*_)}function CD(e,t,n,r,i,a){let{data:o}=r;if(!o||o.length===0||t<=0||n<=0)return{hitBar:null};let s=r.positiveColor??i.candleUp,c=r.negativeColor??i.candleDown,l=r.totalColor??i.lineColor,u=r.subtotalColor??i.textSecondary,d=r.connectorColor??i.textSecondary,f=r.connectorStyle??`dashed`,p=r.barWidth??cD,m=r.showValues!==!1,h=r.showDelta!==!1,g=r.valueFormat??dD,_=r.labelFormat??(e=>e),{valMin:v,valMax:y}=mD(o),b=y-v||1,x=fD(t,n),{bars:S,cumulatives:C}=pD(o,x,p,v,b);hD(e,t,n,i.background),gD(e,x,v,y,i,g),vD(e,S,x,v,b,d,f),_D(e,S,{positive:s,negative:c,total:l,subtotal:u}),m&&yD(e,S,C,i,g,h),bD(e,S,x,i,_);let w=a?xD(S,a.x,x):null;return a&&w!==null&&SD(e,S,C,w,a,x,i,g),{hitBar:w}}var wD=Math.PI/180,TD=150,ED=240,DD=90,OD=.14,kD=1.6*wD,AD=.22,jD=8,MD=18,ND=16,PD=6.5,FD=20,ID=5,LD=28;function RD(e,t,n){return e<t?t:e>n?n:e}function zD(e){let t=Math.abs(e);return t>=1e6?(e/1e6).toFixed(2)+`M`:t>=1e3?(e/1e3).toFixed(1)+`K`:Number.isInteger(e)?e.toFixed(0):e.toFixed(1)}function BD(e){let t=Number.isFinite(e.startAngle)?e.startAngle:TD,n=(Number.isFinite(e.endAngle)?e.endAngle:t+ED)-t;return n<=0&&(n=(n%360+360)%360||360),n=RD(n,DD,360),{start:(t%360+360)%360*wD,sweep:n*wD}}function VD(e,t){let n=Math.min(Math.cos(e),Math.cos(t)),r=Math.max(Math.cos(e),Math.cos(t)),i=Math.min(Math.sin(e),Math.sin(t)),a=Math.max(Math.sin(e),Math.sin(t));for(let o=Math.ceil(e/(Math.PI/2));Math.PI/2*o<=t;o++){let e=Math.PI/2*o;n=Math.min(n,Math.cos(e)),r=Math.max(r,Math.cos(e)),i=Math.min(i,Math.sin(e)),a=Math.max(a,Math.sin(e))}return{minX:n,maxX:r,minY:i,maxY:a}}function HD(e){if(e.showZoneLabels!==!0||!e.zones)return 0;let t=e.zones.reduce((e,t)=>Math.max(e,t.label?.length??0),0);return t>0?t*PD+12:0}function UD(e,t,n){let r=Number.isFinite(n.min)?n.min:0,i=Number.isFinite(n.max)?n.max:100;i-r>Math.abs(r)*1e-9||(i=r+Math.max(1,Math.abs(r)*1e-6));let{start:a,sweep:o}=BD(n),s=a,c=a+o,l=RD(n.thickness??OD,.04,.5),u=VD(s,c),d=Math.max(u.maxY,.18),f=HD(n),p=f>0?ND:0,m=Math.max(1,e-2*jD-2*f),h=Math.max(1,t-2*jD-MD-p),g=1+l/2,_=Math.max(8,Math.min(m/((u.maxX-u.minX)*g),h/((d-u.minY)*g))),v=_*l,y=(d-u.minY)*_*g+MD+p,b=e/2-(u.maxX+u.minX)/2*_,x=(t-y)/2+p-u.minY*_*g,S=_-v/2,C=Math.max(11,Math.round(S*.46)),w=u.maxY>.3?x-C*.12:x-C*.55,T=Math.max(Math.sin(s),Math.sin(c)),E=T>.2?x+T*_+v/2+2:1/0,D=Math.min(t-jD,E);return{cx:b,cy:x,radius:_,thickness:v,startAngle:s,endAngle:c,min:r,max:i,valueY:w,valueSize:C,textBottom:D}}function WD(e,t){let n=Number.isFinite(e)?RD((e-t.min)/(t.max-t.min),0,1):0;return t.startAngle+(t.endAngle-t.startAngle)*n}function GD(e,t){if(!t||!Number.isFinite(e))return;let n;for(let r of t)e>=r.from&&e<=r.to&&(n=r);return n}function KD(e,t,n){let r=(t??[]).map(t=>({a0:WD(t.from,e),a1:WD(t.to,e),color:t.color,track:!1})).filter(e=>e.a1>e.a0).sort((e,t)=>e.a0-t.a0),i=[],a=e.startAngle;for(let e of r)e.a1<=a||(e.a0>a+1e-9&&i.push({a0:a,a1:e.a0,color:n,track:!0}),i.push({...e,a0:Math.max(e.a0,a)}),a=e.a1);return a<e.endAngle-1e-9&&i.push({a0:a,a1:e.endAngle,color:n,track:!0}),i}function qD(e,t,n,r,i){r<=n||(e.beginPath(),e.arc(t.cx,t.cy,t.radius,n,r,!1),e.lineWidth=t.thickness,e.lineCap=`butt`,e.strokeStyle=i,e.stroke())}function JD(e,t,n,r,i,a){let o=t.cx+Math.cos(n)*t.radius,s=t.cy+Math.sin(n)*t.radius,c=a===`start`?n-Math.PI:n;e.globalAlpha=i,e.beginPath(),e.arc(o,s,t.thickness/2,c,c+(i>=1?Math.PI*2:Math.PI),!1),e.closePath(),e.fillStyle=r,e.fill(),e.globalAlpha=1}function YD(e,t,n,r,i,a){let o=KD(t,n,i),s=o.some(e=>!e.track);o.forEach((n,i)=>{let a=i>0&&!n.track&&!o[i-1].track?kD/2:0,s=i<o.length-1&&!n.track&&!o[i+1].track?kD/2:0,c=n.a0+a,l=n.a1-s;if(n.track){qD(e,t,c,l,n.color);return}e.globalAlpha=AD,qD(e,t,c,l,n.color),e.globalAlpha=1,qD(e,t,c,Math.min(l,r),n.color)}),s||qD(e,t,t.startAngle,r,a);let c=r>t.startAngle+1e-9,l=r>=t.endAngle-1e-9,u=(e,t)=>e.track?[!s&&t?a:i,1]:[e.color,t?1:AD],[d,f]=u(o[0],c),[p,m]=u(o[o.length-1],l);JD(e,t,t.startAngle,d,f,`start`),JD(e,t,t.endAngle,p,m,`end`)}function XD(e,t,n){let r=t.radius-t.thickness/2;if(r<LD)return;let i=Math.max(4,t.thickness*.45);e.strokeStyle=n,e.lineCap=`butt`;for(let n=0;n<=FD;n++){let a=n%ID===0,o=t.startAngle+(t.endAngle-t.startAngle)*n/FD,s=r-i,c=s-(a?Math.max(6,t.thickness*.55):Math.max(3,t.thickness*.3));e.globalAlpha=a?.55:.3,e.lineWidth=a?1.5:1,e.beginPath(),e.moveTo(t.cx+Math.cos(o)*s,t.cy+Math.sin(o)*s),e.lineTo(t.cx+Math.cos(o)*c,t.cy+Math.sin(o)*c),e.stroke()}e.globalAlpha=1}function ZD(e,t,n,r,i){let a=t.cx+Math.cos(n)*t.radius,o=t.cy+Math.sin(n)*t.radius;e.beginPath(),e.arc(a,o,t.thickness*.78,0,Math.PI*2),e.fillStyle=r,e.fill(),e.lineWidth=Math.max(2,t.thickness*.32),e.strokeStyle=i,e.stroke()}function QD(e,t,n,r,i){let a=Math.cos(n),o=Math.sin(n),s=t.radius-t.thickness*.9,c=Math.max(6,t.thickness*.6),l=Math.max(1.5,t.thickness*.14);e.beginPath(),e.moveTo(t.cx+a*s,t.cy+o*s),e.lineTo(t.cx-o*l-a*c,t.cy+a*l-o*c),e.lineTo(t.cx+o*l-a*c,t.cy-a*l-o*c),e.closePath(),e.fillStyle=r,e.fill(),e.beginPath(),e.arc(t.cx,t.cy,Math.max(4,t.thickness*.42),0,Math.PI*2),e.fill(),e.lineWidth=2,e.strokeStyle=i,e.stroke()}function $D(e,t,n,r,i,a,o){e.font=`${n} ${r}px ${i}`;let s=e.measureText(t).width;if(s<=a)return r;let c=Math.floor(r*a/s);return c<o?0:(e.font=`${n} ${c}px ${i}`,c)}function eO(e,t,n,r,i,a,o){let s=a.font.family,c=(t.radius-t.thickness/2)*1.3,l=a.font.sizeSmall;e.textAlign=`center`,e.textBaseline=`middle`;let u=$D(e,n,`600`,t.valueSize,s,c,l);if(u===0)return;let d=o?Math.min(t.cy+u*.8,t.textBottom-u/2):t.valueY;e.fillStyle=a.text,e.fillText(n,t.cx,d);let f=Math.max(l,Math.round(u*.26));if(i?.label&&!o){let n=i.label.toUpperCase();$D(e,n,`600`,f,s,c*.9,l)>0&&(e.fillStyle=i.color,e.fillText(n,t.cx,d-u*.78))}if(r){let n=d+u*.72;n+f/2<=t.textBottom&&$D(e,r,`400`,f,s,c,l)>0&&(e.fillStyle=a.textSecondary,e.fillText(r,t.cx,n))}}function tO(e,t,n,r){e.fillStyle=r.textSecondary,e.font=`${r.font.sizeSmall+1}px ${r.font.family}`;let i=t.thickness/2+6;for(let[r,a]of[[t.startAngle,t.min],[t.endAngle,t.max]]){let o=Math.cos(r),s=Math.sin(r),c=t.cx+o*t.radius,l=t.cy+s*t.radius;s>.2?(e.textAlign=`center`,e.textBaseline=`top`,e.fillText(n(a),c,l+i)):(e.textAlign=o<-.2?`right`:o>.2?`left`:`center`,e.textBaseline=s<-.2?`bottom`:`middle`,e.fillText(n(a),c+o*i,l+s*i))}}function nO(e,t,n,r){e.fillStyle=r.textSecondary,e.font=`${r.font.sizeSmall}px ${r.font.family}`,e.textBaseline=`middle`;let i=t.radius+t.thickness/2+8;for(let r of n){if(!r.label)continue;let n=WD((RD(r.from,t.min,t.max)+RD(r.to,t.min,t.max))/2,t),a=Math.cos(n);e.textAlign=a<-.2?`right`:a>.2?`left`:`center`,e.fillText(r.label,t.cx+a*i,t.cy+Math.sin(n)*i)}}function rO(e,t,n,r,i,a){if(t<=0||n<=0)return;let o=UD(t,n,r),s=Number.isFinite(a),c=s?RD(a,o.min,o.max):o.min,l=WD(c,o),u=s?GD(c,r.zones):void 0,d=r.pointer===`needle`,f=r.valueFormat??zD,p=u?.color??r.needleColor??i.lineColor;e.save(),e.fillStyle=i.background,e.fillRect(0,0,t,n),YD(e,o,r.zones,l,r.trackColor??i.grid,p),XD(e,o,i.textSecondary),s&&(d?QD(e,o,l,r.needleColor??i.text,i.background):ZD(e,o,l,p,i.background)),r.showValue!==!1&&eO(e,o,s?f(c):`—`,r.label,u,i,d),tO(e,o,f,i),r.showZoneLabels===!0&&r.zones?.length&&nO(e,o,r.zones,i),e.restore()}var iO=12,aO=.72,oO=20,sO=.35;function cO(e){let t=0,n=0,r=e.mode===`stacked`;return e.categories.forEach((i,a)=>{let o=0,s=0;for(let i of e.series){let e=i.values[a];Number.isFinite(e)&&(r?e>=0?o+=e:s+=e:(n=Math.max(n,e),t=Math.min(t,e)))}n=Math.max(n,o),t=Math.min(t,s)}),[t,n]}function lO(e,t){let n=e.colorBySign;return n?n===!0?{positive:t.candleUp,negative:t.candleDown}:n:null}function uO(e,t,n,r,i){let a=e.orientation===`horizontal`,o=e.legend??e.series.length>1?of(e.series.map((e,t)=>({label:e.name,color:rf(t,e.color)})),t-iO*2,i):null,s=iO+(o?o.height+6:0),[c,l]=cO(e),u=Qd(c,l,a?Math.max(2,Math.floor(t/110)):5),d=e.valueFormat??K(u),f=Math.max(0,...u.ticks.map(e=>i(d(e),11))),p;if(a){let r=iO+Math.min(t*sO,Math.max(0,...e.categories.map(e=>i(e,11))))+8;p={x:r,y:s,width:Math.max(1,t-r-iO-f/2),height:Math.max(1,n-s-iO-oO)}}else{let e=iO+f+8;p={x:e,y:s,width:Math.max(1,t-e-iO),height:Math.max(1,n-s-iO-oO)}}let m=Math.max(1,e.categories.length),h=a?p.y:p.x,g=(a?p.height:p.width)/m,_=g*aO,v=e.mode===`stacked`,y=v?_:_/Math.max(1,e.series.length),b=e=>a?$d(u,e,p.x,p.width):$d(u,e,p.y,p.height,!0),x=b(0),S=lO(e,r),C=Array(m).fill(0),w=Array(m).fill(0),T=[];return e.series.forEach((t,n)=>{e.categories.forEach((e,r)=>{let i=t.values[r];if(!Number.isFinite(i))return;let o=0;v&&(o=i>=0?C[r]:w[r],i>=0?C[r]+=i:w[r]+=i);let s=b(o),c=b(o+i),l=h+r*g+(g-_)/2+(v?0:n*y),u=S?i>=0?S.positive:S.negative:rf(n,t.color),d=Math.min(s,c),f=Math.abs(c-s);T.push(a?{x:d,y:l,width:f,height:y,category:e,series:t.name,value:i,index:r,color:u}:{x:l,y:d,width:y,height:f,category:e,series:t.name,value:i,index:r,color:u})})}),{plot:p,scale:u,orientation:a?`horizontal`:`vertical`,zero:x,bars:T,bandStart:h,band:g,legend:o,legendY:iO}}function dO(e,t,n){for(let r of e.bars)if(t>=r.x-2&&t<=r.x+r.width+2&&n>=r.y-2&&n<=r.y+r.height+2)return r;return null}function fO(e,t,n,r){let{plot:i}=e;if(t<i.x||t>i.x+i.width||n<i.y||n>i.y+i.height)return-1;let a=e.orientation===`horizontal`?n:t,o=Math.floor((a-e.bandStart)/e.band);return o>=0&&o<r?o:-1}function pO(e,n,r,i,a,o,s=uO(i,n,r,a,af(e,a))){let c=af(e,a),l=i.valueFormat??nf,{plot:u,orientation:d}=s,f=d===`horizontal`;e.fillStyle=a.background,e.fillRect(0,0,n,r),s.legend&&sf(e,s.legend,iO,s.legendY,a),lf(e,u,s.scale,f?`horizontal`:`vertical`,a,i.valueFormat??K(s.scale));let p=o&&i.crosshair!==!1?fO(s,o.x,o.y,i.categories.length):-1;if(p>=0){e.fillStyle=(0,t.withAlpha)(a.crosshair,.08);let n=s.bandStart+p*s.band;f?e.fillRect(u.x,n,u.width,s.band):e.fillRect(n,u.y,s.band,u.height)}for(let t of s.bars)e.fillStyle=t.color,e.fillRect(t.x,t.y,Math.max(t.width,+!!f),Math.max(t.height,+!f));e.strokeStyle=a.axisLine,e.lineWidth=1,e.beginPath();let m=Math.round(s.zero)+.5;if(f?(e.moveTo(m,u.y),e.lineTo(m,u.y+u.height)):(e.moveTo(u.x,m),e.lineTo(u.x+u.width,m)),e.stroke(),mO(e,i.categories,s,a,c),i.showValues&&hO(e,s,a,l,i.mode===`stacked`),p>=0&&o){let t=[{text:i.categories[p],bold:!0}];for(let e of s.bars)e.index===p&&t.push({text:`${e.series}: ${l(e.value)}`,color:e.color});cf(e,t,o,{x:0,y:0,width:n,height:r},a)}return s}function mO(e,t,n,r,i){let{plot:a}=n;e.save(),e.font=q(r,11),e.fillStyle=r.axisLabel;let o=Math.max(0,...t.map(e=>i(e,11))),s=n.orientation===`vertical`?Math.max(1,Math.ceil((o+8)/Math.max(1,n.band))):1;t.forEach((t,r)=>{if(r%s!==0)return;let o=n.bandStart+(r+.5)*n.band;n.orientation===`horizontal`?(e.textAlign=`right`,e.textBaseline=`middle`,e.fillText(uf(t,a.x-iO-8,i),a.x-8,o)):(e.textAlign=`center`,e.textBaseline=`top`,e.fillText(uf(t,n.band*s-4,i),o,a.y+a.height+6))}),e.restore()}function hO(e,t,n,r,i){e.save(),e.font=q(n,10),e.fillStyle=n.textSecondary;for(let n of t.bars){let a=r(n.value);if(t.orientation===`horizontal`){e.textBaseline=`middle`;let t=n.y+n.height/2;i?(e.textAlign=`center`,e.measureText(a).width<n.width-4&&e.fillText(a,n.x+n.width/2,t)):n.value>=0?(e.textAlign=`left`,e.fillText(a,n.x+n.width+4,t)):(e.textAlign=`right`,e.fillText(a,n.x-4,t))}else{e.textAlign=`center`;let t=n.x+n.width/2;i?(e.textBaseline=`middle`,n.height>13&&e.measureText(a).width<n.width&&e.fillText(a,t,n.y+n.height/2)):n.value>=0?(e.textBaseline=`bottom`,e.fillText(a,t,n.y-3)):(e.textBaseline=`top`,e.fillText(a,t,n.y+n.height+3))}}e.restore()}var gO=12,_O=-Math.PI/2,vO=Math.PI*2,yO=5,bO=1.4,xO=18,SO=new Intl.NumberFormat(void 0,{style:`percent`,maximumFractionDigits:1});function CO(e,t,n,r,i){let a=e.data.filter(e=>Number.isFinite(e.value)&&e.value>0),o=a.reduce((e,t)=>e+t.value,0),s=a.map((e,t)=>({label:`${e.label} ${SO.format(e.value/o)}`,color:rf(t,e.color)})),c=e.legend!==!1&&a.length>0,l=c&&t>=n*bO&&a.length*xO<=n-gO*2,u=l?Math.min(t*.4,Math.max(...s.map(e=>i(e.label,11)))+16):t-gO*2,d=c?of(s,u,i,l):null,f=l?t-u-gO*3:t-gO*2,p=l?n-gO*2:n-gO*3-(d?.height??0),m=Math.max(0,Math.min(f,p)/2-yO),h=gO+f/2,g=gO+p/2,_=e.innerRadius,v=Math.min(.95,Math.max(0,_!==void 0&&Number.isFinite(_)?_:.6)),y=_O,b=a.map((e,t)=>{let n=e.value/o,r=y;return y+=n*vO,{label:e.label,value:e.value,share:n,start:r,end:y,color:rf(t,e.color),slice:e}});return{cx:h,cy:g,radius:m,inner:m*v,total:o,slices:b,legend:d,legendX:l?t-u-gO:gO,legendY:l?Math.max(gO,g-(d?.height??0)/2):gO*2+p}}function wO(e,t,n){let r=t-e.cx,i=n-e.cy,a=Math.hypot(r,i);if(a<e.inner||a>e.radius+yO)return null;let o=Math.atan2(i,r);for(;o<_O;)o+=vO;return e.slices.find(e=>o>=e.start&&o<e.end)??null}function TO(e,t,n,r,i,a,o=CO(r,t,n,i,af(e,i))){let s=af(e,i),c=r.valueFormat??nf;e.fillStyle=i.background,e.fillRect(0,0,t,n);let l=a&&r.crosshair!==!1?wO(o,a.x,a.y):null,{cx:u,cy:d,radius:f,inner:p}=o;for(let t of o.slices){let n=(t.start+t.end)/2,r=t===l?yO:0,a=u+Math.cos(n)*r,s=d+Math.sin(n)*r;e.beginPath(),e.arc(a,s,f,t.start,t.end),p>0?e.arc(a,s,p,t.end,t.start,!0):e.lineTo(a,s),e.closePath(),e.fillStyle=t.color,e.fill(),o.slices.length>1&&(e.strokeStyle=i.background,e.lineWidth=1.5,e.stroke())}return r.showLabels!==!1&&EO(e,o,i),DO(e,o,r,i,s),o.legend&&sf(e,o.legend,o.legendX,o.legendY,i),l&&a&&cf(e,[{text:l.label,bold:!0,color:l.color},{text:`${c(l.value)} · ${SO.format(l.share)}`}],a,{x:0,y:0,width:t,height:n},i),o}function EO(e,t,n){let{cx:r,cy:i,radius:a,inner:o}=t,s=o>0?(a+o)/2:a*.62;e.save(),e.font=q(n,11,`600`),e.textAlign=`center`,e.textBaseline=`middle`,e.fillStyle=`#fff`;for(let n of t.slices){let t=SO.format(n.share);if((n.end-n.start)*s<e.measureText(t).width+8||o>0&&a-o<15)continue;let c=(n.start+n.end)/2;e.fillText(t,r+Math.cos(c)*s,i+Math.sin(c)*s)}e.restore()}function DO(e,t,n,r,i){if(t.inner<=0||!n.centerLabel&&!n.centerValue)return;let a=t.inner*1.6;if(e.save(),e.textAlign=`center`,e.textBaseline=`middle`,n.centerValue){let o=Math.max(12,Math.min(28,t.inner*.42));e.font=q(r,o,`600`),e.fillStyle=r.text,e.fillText(uf(n.centerValue,a,i,o),t.cx,t.cy+(n.centerLabel?o*.35:0))}n.centerLabel&&(e.font=q(r,11),e.fillStyle=r.textSecondary,e.fillText(uf(n.centerLabel,a,i),t.cx,t.cy-(n.centerValue?11*1.1:0))),e.restore()}var OO=12,kO=5,AO=3,jO=18,MO=20,NO=6;function PO(e,n,r,i,a){let o=1/0,s=-1/0,c=1/0,l=-1/0,u=0;for(let t of e.series)for(let e of t.points)!Number.isFinite(e.x)||!Number.isFinite(e.y)||(e.x<o&&(o=e.x),e.x>s&&(s=e.x),e.y<c&&(c=e.y),e.y>l&&(l=e.y),e.size!==void 0&&Number.isFinite(e.size)&&e.size>u&&(u=e.size));let d=e.maxRadius??24,f=d+NO,p=(e,t,n)=>{if(e>t)return[0,1];let r=(t-e)*f/Math.max(1,n-f*2);return[e>=0?Math.max(0,e-r):e-r,t<=0?Math.min(0,t+r):t+r]},m=Qd(...p(o,s,n*.8),Math.max(2,Math.floor(n/110))),h=Qd(...p(c,l,r*.7),5),g=e.xFormat??K(m),_=e.yFormat??K(h),v=e.legend??e.series.length>1?of(e.series.map((e,t)=>({label:e.name,color:rf(t,e.color)})),n-OO*2,a):null,y=OO+(v?v.height+6:0),b=Math.max(0,...h.ticks.map(e=>a(_(e),11))),x=OO+(e.yLabel?jO:0)+b+8,S=OO+MO+(e.xLabel?jO:0),C=a(g(m.max),11)/2,w={x,y,width:Math.max(1,n-x-OO-C),height:Math.max(1,r-y-S)},T=[];return e.series.forEach((e,n)=>{let r=rf(n,e.color),i=(0,t.withAlpha)(r,.55),a=(0,t.withAlpha)(r,.85);for(let t of e.points){if(!Number.isFinite(t.x)||!Number.isFinite(t.y))continue;let n=t.size!==void 0&&Number.isFinite(t.size)&&t.size>0&&u>0?Math.max(AO,d*Math.sqrt(t.size/u)):kO;T.push({px:$d(m,t.x,w.x,w.width),py:$d(h,t.y,w.y,w.height,!0),r:n,color:r,fill:i,hoverFill:a,series:e.name,label:t.label,point:t})}}),{plot:w,xScale:m,yScale:h,points:T,drawOrder:T.map((e,t)=>t).sort((e,t)=>T[t].r-T[e].r),legend:v}}function FO(e,t,n){let r=null,i=1/0;for(let a of e.points){let e=Math.hypot(a.px-t,a.py-n);e<=a.r+NO&&e<i&&(r=a,i=e)}return r}function IO(e,t,n,r,i,a,o=PO(r,t,n,i,af(e,i))){let{plot:s,xScale:c,yScale:l}=o,u=r.xFormat??K(c),d=r.yFormat??K(l);e.fillStyle=i.background,e.fillRect(0,0,t,n),o.legend&&sf(e,o.legend,OO,OO,i),lf(e,s,l,`vertical`,i,d),lf(e,s,c,`horizontal`,i,u),r.zeroLines!==!1&&LO(e,o,i),RO(e,o,r,i);let f=a&&r.crosshair!==!1?FO(o,a.x,a.y):null;e.save(),e.beginPath(),e.rect(s.x,s.y,s.width,s.height),e.clip();for(let t of o.drawOrder){let n=o.points[t];e.beginPath(),e.arc(n.px,n.py,n===f?n.r+2:n.r,0,Math.PI*2),e.fillStyle=n===f?n.hoverFill:n.fill,e.fill(),e.strokeStyle=n.color,e.lineWidth=1,e.stroke()}if(e.restore(),r.showLabels){e.save(),e.font=q(i,10),e.fillStyle=i.textSecondary,e.textAlign=`left`,e.textBaseline=`middle`;for(let t of o.points)t.label&&e.fillText(t.label,t.px+t.r+4,t.py);e.restore()}if(f&&a){let o=[{text:f.label??f.series,bold:!0,color:f.color}];f.label&&r.series.length>1&&o.push({text:f.series}),o.push({text:`${r.xLabel??`x`}: ${(r.xFormat??nf)(f.point.x)}`}),o.push({text:`${r.yLabel??`y`}: ${(r.yFormat??nf)(f.point.y)}`}),f.point.size!==void 0&&o.push({text:nf(f.point.size)}),cf(e,o,a,{x:0,y:0,width:t,height:n},i)}return o}function LO(e,t,n){let{plot:r,xScale:i,yScale:a}=t;if(e.save(),e.strokeStyle=n.axisLine,e.lineWidth=1,e.beginPath(),i.min<0&&i.max>0){let t=Math.round($d(i,0,r.x,r.width))+.5;e.moveTo(t,r.y),e.lineTo(t,r.y+r.height)}if(a.min<0&&a.max>0){let t=Math.round($d(a,0,r.y,r.height,!0))+.5;e.moveTo(r.x,t),e.lineTo(r.x+r.width,t)}e.stroke(),e.restore()}function RO(e,t,n,r){let{plot:i}=t;e.save(),e.font=q(r,11,`600`),e.fillStyle=r.textSecondary,e.textAlign=`center`,n.xLabel&&(e.textBaseline=`bottom`,e.fillText(n.xLabel,i.x+i.width/2,i.y+i.height+MO+jO)),n.yLabel&&(e.translate(OO+11/2,i.y+i.height/2),e.rotate(-Math.PI/2),e.textBaseline=`middle`,e.fillText(n.yLabel,0,0)),e.restore()}var zO=1e-9,BO=1e3,VO=e=>{let t=Number(e.toPrecision(12));return t===0?0:t};function HO(e,t={}){let n=e.filter(e=>Number.isFinite(e));if(n.length===0)return[];let r=1/0,i=-1/0;for(let e of n)e<r&&(r=e),e>i&&(i=e);if(r===i)return[{from:r,to:i,count:n.length}];let a=t.binWidth;if(a!==void 0&&a>0&&Number.isFinite(a)){let e=Math.floor(r/a+zO),t=Math.max(e,Math.ceil(i/a-zO)-1)-e+1;if(t<=1e3){let r=Array.from({length:t},(t,n)=>({from:VO((e+n)*a),to:VO((e+n+1)*a),count:0}));for(let i of n)r[Math.min(t-1,Math.floor(i/a+zO)-e)].count++;return r}}let o=t.bins,s=typeof o==`number`&&Number.isFinite(o)&&o>=1?Math.min(BO,Math.floor(o)):Math.min(BO,Math.ceil(Math.log2(n.length))+1),c=(i-r)/s,l=Array.from({length:s},(e,t)=>({from:VO(r+t*c),to:VO(t===s-1?i:r+(t+1)*c),count:0}));for(let e of n)l[Math.min(s-1,Math.floor((e-r)/c+zO))].count++;return l}var UO=12,WO=20,GO=16;function KO(e,n,r){return n.colorBySign?(e.from+e.to)/2<0?r.candleDown:r.candleUp:n.color??t.TC_SERIES_COLORS[0]}function qO(e,t,n,r,i){let a=HO(e.values,{bins:e.bins,binWidth:e.binWidth}),o=a.length>0?a[0].from:0,s=a.length>0?a[a.length-1].to:1,c=(e.markers??[]).map(e=>e.value).filter(e=>Number.isFinite(e)),l=Qd(Math.min(o,...c),Math.max(s,...c),Math.max(2,Math.floor(t/110))),u=0;for(let e of a)e.count>u&&(u=e.count);let d=Qd(0,Math.max(4,u),4),f=e.valueFormat??K(l),p=Math.max(0,...d.ticks.map(e=>i(K(d)(e),11))),m=UO+(c.length>0?GO:0),h=UO+p+8,g=UO+i(f(l.max),11)/2,_={x:h,y:m,width:Math.max(1,t-h-g),height:Math.max(1,n-m-UO-WO)};return{plot:_,xScale:l,yScale:d,bars:a.map(t=>{let n=$d(l,t.from,_.x,_.width),i=t.to>t.from?$d(l,t.to,_.x,_.width):n+_.width/10,a=$d(d,t.count,_.y,_.height,!0);return{x:n,y:a,width:Math.max(1,i-n),height:_.y+_.height-a,bin:t,color:KO(t,e,r)}}),total:a.reduce((e,t)=>e+t.count,0)}}function JO(e,t,n){let{plot:r}=e;return n<r.y||n>r.y+r.height?null:e.bars.find(e=>t>=e.x&&t<e.x+e.width)??null}var YO=new Intl.NumberFormat(void 0,{style:`percent`,maximumFractionDigits:1});function XO(e,n,r,i,a,o,s=qO(i,n,r,a,af(e,a))){let c=i.valueFormat??nf,{plot:l}=s;e.fillStyle=a.background,e.fillRect(0,0,n,r),lf(e,l,s.yScale,`vertical`,a,K(s.yScale)),lf(e,l,s.xScale,`horizontal`,a,i.valueFormat??K(s.xScale));let u=o&&i.crosshair!==!1?JO(s,o.x,o.y):null;for(let n of s.bars)e.fillStyle=n===u?n.color:(0,t.withAlpha)(n.color,.75),e.fillRect(n.x+(n.width>3?.5:0),n.y,Math.max(1,n.width-+(n.width>3)),n.height);if(ZO(e,s,i,a,c),u&&o){let{bin:t}=u;cf(e,[{text:t.to>t.from?`${c(t.from)} – ${c(t.to)}`:c(t.from),bold:!0,color:u.color},{text:`${nf(t.count)} · ${YO.format(s.total>0?t.count/s.total:0)}`}],o,{x:0,y:0,width:n,height:r},a)}return s}function ZO(e,t,n,r,i){let{plot:a}=t;e.save(),e.font=q(r,10),e.textAlign=`center`,e.textBaseline=`bottom`;let o=[];for(let s of n.markers??[]){if(!Number.isFinite(s.value))continue;let n=Math.round($d(t.xScale,s.value,a.x,a.width))+.5,c=s.color??r.text;e.strokeStyle=c,e.setLineDash([4,3]),e.lineWidth=1,e.beginPath(),e.moveTo(n,a.y),e.lineTo(n,a.y+a.height),e.stroke(),e.setLineDash([]),e.fillStyle=c;let l=s.label?`${s.label} ${i(s.value)}`:i(s.value),u=e.measureText(l).width/2+4,d=0;for(;o.some(e=>e.row===d&&n-u<e.to&&n+u>e.from);)d++;o.push({from:n-u,to:n+u,row:d}),e.fillText(l,n,a.y-3+d*14)}e.restore()}var QO=864e5,$O=3,ek=12,tk=16,nk=10,rk=28,ik=6;function ak(e){let t=/^(\d{4})-(\d{2})-(\d{2})$/.exec(e);if(!t)return null;let[n,r,i]=[Number(t[1]),Number(t[2]),Number(t[3])],a=Date.UTC(n,r-1,i),o=new Date(a);return o.getUTCFullYear()!==n||o.getUTCMonth()!==r-1||o.getUTCDate()!==i?null:Math.round(a/QO)}function ok(e){return new Date(e*QO).toISOString().slice(0,10)}var sk=e=>((e+4)%7+7)%7;function ck(e,t){let n=e.from===void 0?null:ak(e.from),r=e.to===void 0?null:ak(e.to);if(n===null||r===null){let e=1/0,i=-1/0;for(let n of t.keys())n<e&&(e=n),n>i&&(i=n);n??=Number.isFinite(e)?e:null,r??=Number.isFinite(i)?i:null}if(n===null||r===null||n>r)return null;let i=new Date(r*QO).getUTCFullYear()-10+1;return[Math.max(n,Math.round(Date.UTC(i,0,1)/QO)),r]}function lk(e,t,n){let r=[],i=e;for(;i<=t;){let e=new Date(i*QO).getUTCFullYear(),a=Math.min(t,Math.round(Date.UTC(e,11,31)/QO)),o=i-n(i);r.push({year:e,first:i,last:a,origin:o,weeks:Math.floor((a-o)/7)+1}),i=a+1}return r}var uk=new Map;function dk(e){let t=e??``,n=uk.get(t);if(!n){try{n={month:new Intl.DateTimeFormat(e,{month:`short`,timeZone:`UTC`}),weekday:new Intl.DateTimeFormat(e,{weekday:`short`,timeZone:`UTC`}),long:new Intl.DateTimeFormat(e,{dateStyle:`full`,timeZone:`UTC`})}}catch{n=dk(void 0)}uk.set(t,n)}return n}function fk(e,t,n,r,i){let a=new Map;for(let t of e.data){let e=ak(t.date);e!==null&&Number.isFinite(t.value)&&a.set(e,t)}let o=dk(e.locale),s=e.dateFormat??(e=>o.long.format(new Date(`${e}T00:00:00Z`))),c=e.weekdays===5,l=e=>!c||sk(e)>=1&&sk(e)<=5,u=ck(e,a),d=t-ek*2,f=e.legend===!1?0:28,p=c?5:7,m=c?1:e.weekStart??1,h=e=>(sk(e)-m+7)%7,g=u?lk(u[0],u[1],h):[],_=e=>n-ek*2-f-e*tk-(e-1)*nk;for(;g.length>1&&_(g.length)/(g.length*p)<$O;)g=g.slice(1);let v=[];for(let[e,t]of a)g.length>0&&e>=g[0].first&&e<=g[g.length-1].last&&l(e)&&v.push(t.value);let y=_f(v,r,e.colorScale),b={cells:[],months:[],weekdays:[],years:[],scale:y,bar:null,pitch:0,formatDate:s};if(g.length===0||d<=0||_(g.length)<=0)return b;let x=g.length>1,S=g.map(e=>String(e.year)),C=Array.from({length:p},(e,t)=>o.weekday.format(new Date((3+m+t)*QO))),w=ek+Math.max(...C.map(e=>i(e,10)),...x?S.map(e=>i(e,11)):[0])+ik,T=Math.max(...g.map(e=>e.weeks)),E=Math.min(rk,(t-w-ek)/T,_(g.length)/(g.length*p));if(!(E>0))return b;let D=E-(E>=6?Math.max(1,Math.round(E*.12)):0),O=T*E,k=w+Math.max(0,(t-w-ek-O)/2),A={...b,pitch:E},j=ek;for(let[e,n]of g.entries()){let r=j+tk;x&&A.years.push({label:S[e],x:k-ik,y:j});let s=-1,c=-1/0;for(let e=n.first;e<=n.last;e++){if(!l(e))continue;let u=k+Math.floor((e-n.origin)/7)*E,d=r+h(e)*E,f=a.get(e);A.cells.push({x:u,y:d,size:D,date:ok(e),day:f,color:f&&Number.isFinite(f.value)?vf(f.value,y):null});let p=new Date(e*QO).getUTCMonth();if(p!==s){s=p;let n=o.month.format(new Date(e*QO)),r=u+i(n,10);u>=c&&r<=t&&(A.months.push({label:n,x:u,y:j}),c=r+4)}}if(E>=8){let e=E>=13?1:2;for(let t=0;t<p;t+=e)A.weekdays.push({label:C[t],x:k-ik,y:r+t*E+D/2})}j=r+p*E+nk}return f>0&&(A.bar={x:k,y:j-nk+8,width:Math.min(O,t-k-ek),height:f-8}),A}function pk(e,t,n){for(let r of e.cells)if(t>=r.x&&t<r.x+e.pitch&&n>=r.y&&n<r.y+e.pitch)return r;return null}function mk(e,n,r,i,a,o,s=fk(i,n,r,a,af(e,a))){let c=i.valueFormat??nf;e.fillStyle=a.background,e.fillRect(0,0,n,r);let l=o&&i.crosshair!==!1?pk(s,o.x,o.y):null,u=(0,t.withAlpha)(a.textSecondary,.12),d=s.pitch>=10?2:0;e.save();for(let t of s.cells)e.fillStyle=t.color??u,e.beginPath(),d>0&&typeof e.roundRect==`function`?e.roundRect(t.x,t.y,t.size,t.size,d):e.rect(t.x,t.y,t.size,t.size),e.fill();l&&(e.strokeStyle=a.text,e.lineWidth=1.5,e.strokeRect(l.x-.75,l.y-.75,l.size+1.5,l.size+1.5)),e.fillStyle=a.textSecondary,e.font=q(a,10),e.textAlign=`left`,e.textBaseline=`top`;for(let t of s.months)e.fillText(t.label,t.x,t.y);e.textAlign=`right`,e.textBaseline=`middle`;for(let t of s.weekdays)e.fillText(t.label,t.x,t.y);e.font=q(a,11,`600`),e.fillStyle=a.text,e.textBaseline=`top`;for(let t of s.years)e.fillText(t.label,t.x,t.y);if(e.restore(),s.bar&&Sf(e,s.bar,s.scale,c,a),l&&o){let t=[{text:s.formatDate(l.date),bold:!0,color:l.color??void 0}];if(l.day){t.push({text:c(l.day.value)});for(let[e,n]of Object.entries(l.day.meta??{}))t.push({text:`${e}: ${String(n)}`})}else t.push({text:`–`});cf(e,t,o,{x:0,y:0,width:n,height:r},a)}return s}var hk=12,gk=6,_k=72,vk=Math.PI/4,yk=Math.sin(vk);function bk(e){let t=e.length,n=Array.from({length:t},()=>Array(t).fill(NaN));for(let r=0;r<t;r++)for(let i=r;i<t;i++){let t=xk(e[r],e[i],r===i);n[r][i]=t,n[i][r]=t}return n}function xk(e,t,n){let r=Math.min(e.length,t.length),i=0,a=0,o=0;for(let n=0;n<r;n++)Number.isFinite(e[n])&&Number.isFinite(t[n])&&(i++,a+=e[n],o+=t[n]);if(i<3)return NaN;let s=a/i,c=o/i,l=0,u=0,d=0;for(let n=0;n<r;n++){if(!Number.isFinite(e[n])||!Number.isFinite(t[n]))continue;let r=e[n]-s,i=t[n]-c;l+=r*i,u+=r*r,d+=i*i}return u===0||d===0?NaN:n?1:Math.max(-1,Math.min(1,l/Math.sqrt(u*d)))}var Sk=e=>e.toFixed(2);function Ck(e,t,n,r){return!t||!e?!0:e===`lower`?r<=n:r>=n}function wk(e,t,n,r,i){let a=e.rows.slice(0,200),o=(e.columns??e.rows).slice(0,200),s=e.columns===void 0||e.columns.length===e.rows.length&&e.columns.every((t,n)=>t===e.rows[n]),c=[];for(let t=0;t<a.length;t++)for(let n=0;n<o.length;n++){let r=e.values[t]?.[n];Number.isFinite(r)&&Ck(e.triangle,s,t,n)&&c.push(r)}let l=_f(c,r,e.colorScale),u={cells:[],rowLabels:[],columnLabels:[],grid:{x:0,y:0,width:0,height:0},pitch:0,scale:l,bar:null,at:[]};if(a.length===0||o.length===0||t<=0||n<=0)return u;let d=Math.min(t*.3,Math.max(...a.map(e=>i(e,11)))),f=Math.max(...o.map(e=>i(e,11))),p=e.legend===!1?0:28,m=hk+d+gk,h=t-m-hk,g=e=>Math.min(_k,h/o.length,(n-e-hk-p)/a.length),_=hk+11+gk,v=g(_),y=f>v-4,b=f;if(y&&(b=Math.min(f,n*.33/yk),_=hk+b*yk+11,v=g(_)),!(v>0))return u;let x=v-+(v>=8),S=m+Math.max(0,(h-o.length*v)/2);y&&(b=Math.max(0,Math.min(b,(S+x/2-2-11*yk/2)/yk))),u.grid={x:S,y:_,width:o.length*v,height:a.length*v},u.pitch=v;let C=e.valueFormat??Sk,w=e.showValues!==!1,T=Math.max(8,Math.min(11,v/3));for(let t=0;t<a.length;t++){u.at.push([]);for(let n=0;n<o.length;n++){let r=e.values[t]?.[n];if(!Number.isFinite(r)||!Ck(e.triangle,s,t,n))continue;let c=vf(r,l),d=w?C(r):``,f=w&&v>=18&&i(d,T)<=v-4,p={x:S+n*v,y:_+t*v,size:x,cell:{row:a[t],column:o[n],value:r,rowIndex:t,columnIndex:n},color:c,text:f?d:null,textColor:xf(c)};u.cells.push(p),u.at[t][n]=p}}let E=Math.max(1,Math.ceil(11/v)),D=Math.max(1,Math.ceil(11/(y?v*yk:v)));for(let e=0;e<a.length;e+=E)u.rowLabels.push({text:uf(a[e],d,i),index:e,x:S-gk,y:_+e*v+x/2});for(let e=0;e<o.length;e+=D)u.columnLabels.push({text:uf(o[e],b,i),index:e,x:S+e*v+x/2,y:_-gk,rotated:y});return p>0&&(u.bar={x:S,y:_+a.length*v+8,width:Math.min(u.grid.width,t-S-hk),height:p-8}),u}function Tk(e,t,n){let{grid:r,pitch:i}=e;return i<=0||t<r.x||n<r.y||t>=r.x+r.width||n>=r.y+r.height?null:e.at[Math.floor((n-r.y)/i)]?.[Math.floor((t-r.x)/i)]??null}function Ek(e,t,n,r,i,a,o=wk(r,t,n,i,af(e,i))){let s=r.valueFormat??Sk;e.fillStyle=i.background,e.fillRect(0,0,t,n);let c=a&&r.crosshair!==!1?Tk(o,a.x,a.y):null;e.save();let l=Math.max(8,Math.min(11,o.pitch/3));e.textAlign=`center`,e.textBaseline=`middle`,e.font=q(i,l);for(let t of o.cells)e.fillStyle=t.color,e.fillRect(t.x,t.y,t.size,t.size),t.text&&(e.fillStyle=t.textColor,e.fillText(t.text,t.x+t.size/2,t.y+t.size/2));c&&(e.strokeStyle=i.text,e.lineWidth=1.5,e.strokeRect(c.x+.75,c.y+.75,c.size-1.5,c.size-1.5)),e.font=q(i,11),e.fillStyle=i.textSecondary,e.textAlign=`right`;for(let t of o.rowLabels)e.fillStyle=c&&c.cell.rowIndex===t.index?i.text:i.textSecondary,e.fillText(t.text,t.x,t.y);for(let t of o.columnLabels)e.fillStyle=c&&c.cell.columnIndex===t.index?i.text:i.textSecondary,t.rotated?(e.save(),e.translate(t.x,t.y),e.rotate(vk),e.textAlign=`right`,e.fillText(t.text,0,0),e.restore()):(e.textAlign=`center`,e.textBaseline=`bottom`,e.fillText(t.text,t.x,t.y),e.textBaseline=`middle`);if(e.restore(),o.bar&&Sf(e,o.bar,o.scale,s,i),c&&a){let{cell:r}=c;cf(e,[{text:`${r.row} × ${r.column}`,bold:!0,color:c.color},{text:s(r.value)}],a,{x:0,y:0,width:t,height:n},i)}return o}var Dk=12,Ok=18,kk=20,Ak=10,jk=.2,Mk=2e3,Nk=1e-9;function Pk(e,t,n=1/0){let r=Number.isFinite(t)?Math.max(1,Math.floor(t)):25,i=[],a=Math.max(r-1,e.length-(Number.isFinite(n)?Math.max(1,Math.floor(n)):e.length));for(let t=a;t<e.length;t++){let n=0,a=0;for(let i=t-r+1;i<=t;i++)n+=e[i].volume,a+=e[i].close;i.push({time:e[t].time,volume:n/r,price:a/r})}return i}var Fk=(e,t)=>t-e>Nk*Math.max(Math.abs(e),Math.abs(t));function Ik(e){if(e.length<2)return null;let t=1/0,n=-1/0,r=1/0,i=-1/0;for(let a of e)t=Math.min(t,a.volume),n=Math.max(n,a.volume),r=Math.min(r,a.price),i=Math.max(i,a.price);let a=e[e.length-2],o=e[e.length-1],s=Fk(t,n)?(o.volume-a.volume)/(n-t):0,c=Fk(r,i)?(o.price-a.price)/(i-r):0;if(Math.abs(s)<1e-6&&Math.abs(c)<1e-6)return null;let l=(Math.atan2(c,s)+2*Math.PI)%(2*Math.PI);return Math.round(l/(Math.PI/4))%8+1}function Lk(e,n,r,i,a){let o=Pk(e.data,e.period??25,Rk(e)),s=1/0,c=-1/0,l=1/0,u=-1/0;for(let e of o)s=Math.min(s,e.volume),c=Math.max(c,e.volume),l=Math.min(l,e.price),u=Math.max(u,e.price);o.length>0&&!Fk(s,c)&&(c=s),o.length>0&&!Fk(l,u)&&(u=l);let d=Qd(o.length>0?s:0,o.length>0?c:1,Math.max(2,Math.floor(n/110))),f=Qd(o.length>0?l:0,o.length>0?u:1,Math.max(2,Math.floor(r/60))),p=e.priceFormat??K(f),m=e.volumeFormat??K(d),h=Dk+Math.max(0,...f.ticks.map(e=>a(p(e),11)))+8+(e.yLabel?Ok:0),g=Dk+a(m(d.max),11)/2,_=Dk,v=Dk+kk+(e.xLabel?Ok:0),y={x:h,y:_,width:Math.max(1,n-h-g),height:Math.max(1,r-_-v)},b=Math.max(1,o.length-1);return{plot:y,xScale:d,yScale:f,points:o.map((e,t)=>({px:$d(d,e.volume,y.x,y.width),py:$d(f,e.price,y.y,y.height,!0),alpha:jk+(1-jk)*t/b,point:e})),phase:Ik(o),color:e.color??t.TC_SERIES_COLORS[0]}}function Rk(e){let t=e.points??60;return Number.isFinite(t)?Math.min(Mk,Math.max(2,Math.floor(t))):60}function zk(e,t,n){let r=null,i=Ak*Ak;for(let a=e.points.length-1;a>=0;a--){let o=e.points[a],s=(o.px-t)**2+(o.py-n)**2;s<i&&(r=o,i=s)}return r}var Bk=new Intl.DateTimeFormat(void 0,{year:`numeric`,month:`short`,day:`numeric`});function Vk(e,n,r,i,a,o,s=Lk(i,n,r,a,af(e,a))){let{plot:c,points:l,color:u}=s,d=i.timeFormat??(e=>Bk.format(new Date(e))),f=i.priceFormat??nf,p=i.volumeFormat??nf;e.fillStyle=a.background,e.fillRect(0,0,n,r),lf(e,c,s.yScale,`vertical`,a,i.priceFormat??K(s.yScale)),lf(e,c,s.xScale,`horizontal`,a,i.volumeFormat??K(s.xScale)),Hk(e,c,i,a),e.save(),e.lineWidth=1.5,e.lineJoin=`round`;for(let n=1;n<l.length;n++)e.strokeStyle=(0,t.withAlpha)(u,l[n].alpha),e.beginPath(),e.moveTo(l[n-1].px,l[n-1].py),e.lineTo(l[n].px,l[n].py),e.stroke();for(let n of l)e.fillStyle=(0,t.withAlpha)(u,n.alpha),e.beginPath(),e.arc(n.px,n.py,2,0,Math.PI*2),e.fill();let m=l[l.length-1];m&&(e.fillStyle=u,e.strokeStyle=a.background,e.lineWidth=2,e.beginPath(),e.arc(m.px,m.py,5,0,Math.PI*2),e.fill(),e.stroke()),e.restore();let h=o&&i.crosshair!==!1?zk(s,o.x,o.y):null;return h&&o&&(e.save(),e.strokeStyle=a.text,e.lineWidth=1.5,e.beginPath(),e.arc(h.px,h.py,5,0,Math.PI*2),e.stroke(),e.restore(),cf(e,[{text:d(h.point.time),bold:!0,color:u},{text:`${i.yLabel??`Price`}: ${f(h.point.price)}`},{text:`${i.xLabel??`Volume`}: ${p(h.point.volume)}`}],o,{x:0,y:0,width:n,height:r},a)),s}function Hk(e,t,n,r){e.save(),e.font=q(r,11),e.fillStyle=r.textSecondary,e.textAlign=`center`,n.xLabel&&(e.textBaseline=`bottom`,e.fillText(n.xLabel,t.x+t.width/2,t.y+t.height+kk+Ok)),n.yLabel&&(e.translate(Dk+4,t.y+t.height/2),e.rotate(-Math.PI/2),e.textBaseline=`middle`,e.fillText(n.yLabel,0,0)),e.restore()}exports.ABCDPatternTool=xv,exports.ADXIndicator=Es,exports.ALMAIndicator=Oc,exports.ATRIndicator=Ts,exports.AXIS_LABEL_HEIGHT=ee,exports.AcceleratorOscillatorIndicator=mc,exports.AccumulationDistributionIndicator=wc,exports.AccumulativeSwingIndexIndicator=yu,exports.AdvanceDeclineIndicator=xu,exports.AlertDragHandler=zd,exports.AlertManager=Uw,exports.AlligatorIndicator=ds,exports.AnchoredNoteTool=py,exports.AnchoredTextTool=fy,exports.AnchoredVWAPIndicator=ns,exports.AnchoredVWAPTool=j_,exports.Animator=eE,exports.ArcTool=Ly,exports.AreaRenderer=et,exports.AroonIndicator=js,exports.ArrowMarkTool=Xv,exports.ArrowTool=x_,exports.AverageDayRangeIndicator=el,exports.AveragePriceIndicator=cl,exports.AwesomeOscillatorIndicator=bs,exports.AxisDragHandler=Rd,exports.BalanceOfPowerIndicator=$s,exports.BalloonTool=dy,exports.BarCountdown=fe,exports.BarRenderer=tt,exports.BarsPatternTool=vb,exports.BaseFinanceChart=nE,exports.BaselineRenderer=it,exports.BinanceAdapter=gC,exports.BollingerBandWidthIndicator=Vc,exports.BollingerBandsIndicator=zo,exports.BollingerPercentBIndicator=Bc,exports.BracketTool=Cx,exports.BrushTool=Ay,exports.BybitAdapter=AC,exports.CANDLE_PATTERNS=Yl,exports.CCIIndicator=ks,exports.CMFIndicator=Ps,exports.COUNTDOWN_HEIGHT=de,exports.CROSSHAIR_CURSORS=Pf,exports.CalloutTool=Vv,exports.CandlestickRenderer=le,exports.CanvasLayer=c,exports.ChaikinOscillatorIndicator=xs,exports.ChaikinVolatilityIndicator=sc,exports.ChandeKrollStopIndicator=Lc,exports.ChandeMomentumIndicator=tc,exports.ChandelierExitIndicator=us,exports.ChartLegend=aw,exports.ChartStateManager=bT,exports.ChopZoneIndicator=Tu,exports.ChoppinessIndexIndicator=Ls,exports.CircleTool=Tv,exports.CoinbaseAdapter=wC,exports.CompareRenderer=Wr,exports.CompareSymbolIndicator=no,exports.CompareSymbolPaneIndicator=ro,exports.ConnorsRSIIndicator=Vs,exports.CoppockIndicator=Us,exports.CorrelationCoefficientIndicator=co,exports.CorrelationLogIndicator=lo,exports.CrossLineTool=rv,exports.CrosshairHandler=wf,exports.CrosshairTooltip=Qf,exports.CurrentPriceLine=nS,exports.CurveTool=Iy,exports.CyclicLinesTool=Nv,exports.CypherPatternTool=wv,exports.DEFAULT_LEGEND_CONFIG=iw,exports.DEFAULT_MAX_PIXEL_RATIO=n,exports.DEFAULT_MAX_WEBGL_CHARTS=e.t,exports.DEFAULT_SESSION_HOURS=Ew,exports.DEMAIndicator=Ec,exports.DENSE_BAR_WIDTH=e.u,exports.DOUBLE_TAP_MS=md,exports.DOUBLE_TAP_PX=hd,exports.DPRManager=o,exports.DataExporter=kT,exports.DateAndPriceRangeTool=kv,exports.DateRangeTool=u_,exports.DepthHeatmapBuffer=$t,exports.DepthHeatmapRenderer=en,exports.DepthOverlay=mx,exports.DetrendedPriceOscillatorIndicator=Qs,exports.DisparityIndexIndicator=_c,exports.DonchianChannelIndicator=Qo,exports.DrawingBase=J,exports.DrawingManager=jm,exports.DrawingRenderer=zm,exports.EMAIndicator=Ro,exports.EaseOfMovementIndicator=ic,exports.Easing=$T,exports.ElderRayIndicator=qs,exports.ElliottCorrectionTool=t_,exports.ElliottDoubleComboTool=r_,exports.ElliottImpulseTool=e_,exports.ElliottTriangleTool=n_,exports.ElliottTripleComboTool=i_,exports.ElliottWaveTool=$g,exports.EllipseTool=bg,exports.Emitter=Xx,exports.EnvelopeIndicator=hs,exports.EquivolumeRenderer=dt,exports.EventBus=up,exports.ExtendedLineTool=Jh,exports.FibArcsTool=tb,exports.FibChannelTool=dv,exports.FibCirclesTool=eb,exports.FibExtensionTool=_g,exports.FibRetracementTool=hg,exports.FibSpeedResistanceFanTool=vv,exports.FibSpiralTool=ib,exports.FibTimeZonesTool=W_,exports.FibWedgeTool=nb,exports.FinanceCrosshair=rE,exports.FisherTransformIndicator=Zs,exports.FlagTool=qv,exports.ForceIndexIndicator=Bs,exports.ForecastTool=gb,exports.GROUP_HEADER=WE,exports.GannBoxTool=k_,exports.GannFanTool=w_,exports.GannSquareTool=ab,exports.GridRenderer=e.o,exports.GuppyMMAIndicator=al,exports.HLCAreaRenderer=pt,exports.HammingMAIndicator=fu,exports.HeadAndShouldersTool=Sv,exports.HiLoRenderer=vt,exports.HighlighterTool=jy,exports.HistoricalVolatilityIndicator=Uc,exports.HollowCandleRenderer=nt,exports.HorizontalLineTool=Uh,exports.HorizontalRayTool=Wh,exports.HullMAIndicator=as,exports.ICON_GLYPHS=Zv,exports.INDICATOR_CATEGORIES=Fu,exports.INDICATOR_WORKER_MIN_BARS=Do,exports.INTERVAL_LIMITS=Da,exports.INTERVAL_UNITS=Ea,exports.IchimokuIndicator=Jo,exports.IconTool=$v,exports.IndicatorBase=L,exports.IndicatorEngine=Io,exports.IndicatorValueMap=R,exports.IndicatorWorkerClient=qu,exports.IndicatorWorkerHost=Wu,exports.IndicatorWorkerPool=Yu,exports.InfoLineTool=av,exports.InteractionManager=Td,exports.KAMAIndicator=kc,exports.KEPT_BUCKETS=sS,exports.KSTIndicator=Ws,exports.KagiRenderer=ot,exports.KeltnerChannelIndicator=Zo,exports.KeyboardHandler=Vf,exports.KlingerIndicator=Xs,exports.KrakenAdapter=LC,exports.LSMAIndicator=Ac,exports.LayerManager=l,exports.LineRenderer=$e,exports.LineWithMarkersRenderer=ht,exports.LinearRegressionChannelIndicator=is,exports.LinearRegressionSlopeIndicator=Qc,exports.MACDIndicator=Cs,exports.MAChannelIndicator=cu,exports.MACrossIndicator=Pc,exports.MADoubleIndicator=gu,exports.MARibbonIndicator=ol,exports.MATripleIndicator=_u,exports.MAX_ALERT_BARS=Pw,exports.MAX_BASE_RATIO=aS,exports.MAX_BASE_REQUESTS=iS,exports.MFIIndicator=As,exports.MIN_ALERT_BARS=Fw,exports.MIN_BAR_UNIT=Ie,exports.MIN_BAR_UNIT_LIMIT=Le,exports.MTFMovingAverageIndicator=cs,exports.MajorityRuleIndicator=Su,exports.ManualFeed=nw,exports.MarketProfileRenderer=Rt,exports.MassIndexIndicator=ec,exports.McGinleyDynamicIndicator=jc,exports.MeasureOverlay=HT,exports.MeasureTool=d_,exports.MedianPriceIndicator=ll,exports.MockAdapter=_C,exports.ModifiedSchiffPitchforkTool=Dg,exports.MomentumIndicator=Hc,exports.NetVolumeIndicator=tl,exports.NoteTool=Bv,exports.OBVIndicator=Ds,exports.OrderDraftTool=kx,exports.OrderRenderer=tx,exports.PRICE_AXIS_ADD_STRIP=Od,exports.PRICE_SCALE_MARGIN=Be,exports.PanHandler=Id,exports.PaneResizeHandler=Bd,exports.PaperExecutionAdapter=qx,exports.ParabolicSARIndicator=Yo,exports.ParallelChannelTool=Zh,exports.PathTool=My,exports.PercentagePriceOscillatorIndicator=fc,exports.PeriodLevelsRenderer=Ut,exports.PinnedTooltip=op,exports.PitchfanTool=rb,exports.PitchforkTool=Tg,exports.PivotMarkersRenderer=Yt,exports.PivotPointsIndicator=es,exports.PointAndFigureRenderer=lt,exports.PollingAdapter=bC,exports.PolylineTool=Ny,exports.PositionRenderer=px,exports.PrettyGoodOscillatorIndicator=yc,exports.PriceAxis=D,exports.PriceAxisAddButton=kd,exports.PriceLabelTool=Sy,exports.PriceLines=Aw,exports.PriceOscillatorIndicator=Ou,exports.PriceRangeTool=s_,exports.PriceVolumeTrendIndicator=ac,exports.ProjectionTool=_b,exports.QstickIndicator=vc,exports.RANGE_PRESETS=We,exports.ROCIndicator=Ms,exports.RSIIndicator=Ss,exports.RayTool=qh,exports.ReconnectManager=eS,exports.RectangleTool=yg,exports.RegressionChannelTool=ng,exports.RelativeMomentumIndexIndicator=gc,exports.RelativeVigorIndicator=cc,exports.RelativeVolatilityIndexIndicator=Xc,exports.RenderEngine=Me,exports.RenderLoop=u,exports.RenkoRenderer=at,exports.ReplayController=ZS,exports.ReplayManager=Qw,exports.ResamplingAdapter=vS,exports.ReshapeMemo=Zr,exports.RiskRewardTool=nv,exports.SELECTION_BOX_MIN_SIZE=ZT,exports.SMAIndicator=Lo,exports.SMIErgodicIndicator=Du,exports.SMMAIndicator=Dc,exports.SNAPSHOT_VERSION=eT,exports.SYMBOL_INDICATOR_IDS=eo,exports.SYMBOL_ZONE_WAIT_MS=oS,exports.SchaffTrendCycleIndicator=Js,exports.SchiffPitchforkTool=Eg,exports.Screenshot=mw,exports.SelectionBoxOverlay=QT,exports.SessionBreaks=yw,exports.SessionShading=Dw,exports.SessionVWAPIndicator=ls,exports.SignalMarkerManager=PT,exports.SignpostTool=uy,exports.SineLineTool=ub,exports.SpreadIndicator=io,exports.StandardErrorBandsIndicator=nl,exports.StandardErrorIndicator=$c,exports.StdDevIndicator=bc,exports.StepLineRenderer=mt,exports.StochasticIndicator=ws,exports.StochasticMomentumIndexIndicator=Yc,exports.StochasticRSIIndicator=lc,exports.StreamManager=XS,exports.SupertrendIndicator=Xo,exports.SymbolSeriesStore=nn,exports.TEMAIndicator=ys,exports.TOUCH_REACH=pd,exports.TRIXIndicator=nc,exports.TSIIndicator=Ns,exports.TapTracker=gd,exports.TextAnnotationTool=y_,exports.ThreeDrivesTool=Cv,exports.TickAggregator=$x,exports.TickBarAdapter=CS,exports.TickBarBuilder=SS,exports.TimeAxis=ld,exports.TimeCyclesTool=lb,exports.TradeZoneManager=RT,exports.TradingContextMenu=_x,exports.TradingDragHandler=gx,exports.TradingManager=Gx,exports.TradingRenderer=Kx,exports.TrendAngleTool=kh,exports.TrendLineTool=Hh,exports.TrendStrengthIndexIndicator=Zc,exports.TriangleTool=xg,exports.TypicalPriceIndicator=ul,exports.UPBIT_MAX_CANDLES=HC,exports.UlcerIndexIndicator=Kc,exports.UltimateOscillatorIndicator=Rs,exports.UndoRedoManager=xT,exports.UpbitAdapter=qC,exports.VOLUME_HEIGHT_RATIO=yt,exports.VROCIndicator=Tc,exports.VWAPIndicator=Go,exports.VWMAIndicator=ps,exports.VerticalLineTool=Kh,exports.Viewport=He,exports.VolatilityIndexIndicator=vu,exports.VolatilityOHLCIndicator=ju,exports.VolatilityZeroTrendIndicator=Mu,exports.VolumeCandleRenderer=ut,exports.VolumeDeltaIndicator=Fs,exports.VolumeOscillatorIndicator=Wc,exports.VolumeProfileIndicator=Cc,exports.VolumeProfileRangeTool=B_,exports.VolumeProfileRenderer=Ct,exports.VolumeRenderer=bt,exports.VortexIndicator=Is,exports.WMAIndicator=ms,exports.Watermark=hw,exports.WebSocketAdapter=yC,exports.WilliamsADIndicator=oc,exports.WilliamsFractalsIndicator=Ic,exports.WilliamsRIndicator=Os,exports.XABCDPatternTool=bv,exports.ZigZagIndicator=rs,exports.ZoomHandler=Ld,exports.adapterFromFeed=IS,exports.alignAxisTags=pe,exports.alignOutput=wa,exports.arcPoints=Fy,exports.assignSessionLetters=It,exports.axisFormat=K,exports.axisTimes=si,exports.barIndexToTime=e.S,exports.barIndexToX=e.C,exports.barTimeStep=e.w,exports.barTimeStepMs=e.T,exports.barsToColumns=uo,exports.bracketRiskReward=yx,exports.canvasMeasure=af,exports.cappedPixelRatio=r,exports.claimGpuContext=e.n,exports.classifyPivots=Gt,exports.cleanIntervals=ja,exports.columnsToBars=fo,exports.columnsToOutput=So,exports.computeBarLayout=uO,exports.computeBracketDefaults=vx,exports.computeCalendarLayout=fk,exports.computeCounterClockLayout=Lk,exports.computeDonutLayout=CO,exports.computeHistogramLayout=qO,exports.computeMarketProfile=Pt,exports.computeMatrixLayout=wk,exports.computePeriodLevels=Ht,exports.computeScatterLayout=PO,exports.computeSessionProfiles=Lt,exports.correlationMatrix=bk,exports.counterClockPhase=Ik,exports.counterClockPoints=Pk,exports.createIndicatorWorker=Gu,exports.curvePoints=Py,exports.dayToIso=ok,exports.defaultFormat=nf,exports.describeInputs=Hu,exports.detectCandlePatterns=$l,exports.drawAxisValueLabels=ae,exports.drawIcon=Pb,exports.drawingAxisSpan=xm,exports.drawnKeys=Wi,exports.feedFromAdapter=RS,exports.fillTag=A,exports.findDominantSwing=Bm,exports.findPivots=Kt,exports.forEachPixelColumn=e.d,exports.forecastOutcome=hb,exports.formatTooltipTime=Yf,exports.getIntParam=U,exports.getNumberParam=H,exports.getVisibleData=Ue,exports.gpuContextsLeft=e.r,exports.hasHistogram=$i,exports.hasTrades=ES,exports.histogramBins=HO,exports.hitBar=dO,exports.hitCategory=fO,exports.hitDay=pk,exports.hitHistogramBar=JO,exports.hitMatrixCell=Tk,exports.hitSlice=wO,exports.idleCssCursor=Bf,exports.indicatorCategory=Lu,exports.indicatorValuePrecision=j,exports.indicatorWorkerPool=Xu,exports.inferOrderType=Ex,exports.inputSource=xa,exports.isCrosshairCursor=Ff,exports.isDataFeed=MS,exports.isDense=e.f,exports.isInWindow=ww,exports.isPriceLevelAlert=Lw,exports.isRegularSession=Tw,exports.isSeriesPalette=Na,exports.isUpTone=Gi,exports.isWorkerResponse=Uu,exports.labelTextColor=ne,exports.layoutAxisValueLabels=ie,exports.layoutGroupedTreemap=GE,exports.layoutLegend=of,exports.layoutSquarifiedTreemap=HE,exports.layoutUniformGrid=RE,exports.lineSourceBars=Ca,exports.lineSpace=Mp,exports.loadWebGL=Pe,exports.loadWebGLRenderer=Fe,exports.lttbDownsample=Xe,exports.lttbVisibleIndices=Qe,exports.mergeSessionHours=Sw,exports.minuteOfDay=Cw,exports.nearestCounterClockPoint=zk,exports.nearestPoint=FO,exports.niceScale=Qd,exports.outputToColumns=_o,exports.paneLogRange=Zi,exports.paneValueRange=Xi,exports.parseDay=ak,exports.pastTimeStep=e.E,exports.plotColor=Yi,exports.plotLook=Ji,exports.plotShown=Ki,exports.pointAndFigureColumns=vi,exports.priceBucketRow=e.D,exports.priceScaleText=d,exports.priceSourceBars=Sa,exports.priceToY=e.O,exports.priceToYMapper=e.k,exports.rangePresetStart=Ye,exports.readAlertOptions=Gw,exports.readableText=xf,exports.registerBuiltInDrawingTools=yb,exports.registerBuiltInIndicators=Pu,exports.renderAxisValueLabels=oe,exports.renderBarChart=pO,exports.renderCalendar=mk,exports.renderCounterClock=Vk,exports.renderDenseBars=e.p,exports.renderDepthChart=yE,exports.renderDonut=TO,exports.renderEquityCurve=LE,exports.renderGauge=rO,exports.renderHeatmap=tD,exports.renderHistogram=XO,exports.renderMatrix=Ek,exports.renderPlots=ea,exports.renderScatter=IO,exports.renderSparkline=iE,exports.renderWaterfall=CD,exports.resolveBarIndex=e.A,exports.resolveColorScale=_f,exports.scaleColor=vf,exports.servesTimeframe=mS,exports.setMaxWebGLCharts=e.i,exports.shownCount=Rk,exports.shownOnInterval=Aa,exports.sourceParam=ba,exports.spreadLabels=te,exports.streamAdapterOf=NS,exports.timeToX=e.j,exports.timestampToBarIndex=e.M,exports.toHeikinAshi=Gr,exports.toKagi=mi,exports.toLineBreak=pi,exports.toPointAndFigure=_i,exports.toRangeBars=Li,exports.toRenko=ci,exports.tpoLetter=Ft,exports.waveLabel=Yg,exports.whenGpuContextFree=e.a,exports.withResampling=fS,exports.withTickBars=TS,exports.xToBarIndex=e.N,exports.xToTime=e.P,exports.yToPrice=e.F;
26
26
  //# sourceMappingURL=index.cjs.map