emberwick 0.1.1 → 0.2.0

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.
@@ -1,2 +1,2 @@
1
- (function(_,x){typeof exports=="object"&&typeof module!="undefined"?x(exports):typeof define=="function"&&define.amd?define(["exports"],x):(_=typeof globalThis!="undefined"?globalThis:_||self,x(_.Emberwick={}))})(this,function(_){"use strict";class x{constructor(t,i){this.container=t,this.names=i,this.canvas={},this.ctx={},this.width=0,this.height=0,this.dpr=0,this.onResize=null,getComputedStyle(t).position==="static"&&(t.style.position="relative"),i.forEach((e,n)=>{const h=document.createElement("canvas");Object.assign(h.style,{position:"absolute",left:"0",top:"0",width:"100%",height:"100%",pointerEvents:"none",zIndex:String(n+1)}),t.appendChild(h),this.canvas[e]=h,this.ctx[e]=h.getContext("2d")}),this._ro=new ResizeObserver(()=>this.measure()),this._ro.observe(t),this.measure()}measure(){const t=this.container.getBoundingClientRect(),i=Math.max(1,Math.floor(t.width)),e=Math.max(1,Math.floor(t.height)),n=Math.min(window.devicePixelRatio||1,2);if(!(i===this.width&&e===this.height&&n===this.dpr)){this.width=i,this.height=e,this.dpr=n;for(const h of this.names){const o=this.canvas[h];o.width=Math.floor(i*n),o.height=Math.floor(e*n),this.ctx[h].setTransform(n,0,0,n,0,0)}this.onResize&&this.onResize(i,e)}}composite(){const t=document.createElement("canvas");t.width=Math.floor(this.width*this.dpr),t.height=Math.floor(this.height*this.dpr);const i=t.getContext("2d");for(const e of this.names)i.drawImage(this.canvas[e],0,0);return t}destroy(){this._ro.disconnect();for(const t of this.names)this.canvas[t].remove();this.canvas={},this.ctx={}}}class q{constructor(t){this.onFrame=t,this.fps=0,this._raf=0,this._dirty=new Set,this._last=0,this._running=!1,this._frames=0,this._fpsAt=0,this._tick=this._tick.bind(this)}invalidate(...t){if(!t.length)this._dirty.add("all");else for(const i of t)this._dirty.add(i);this._schedule()}start(){this._running||(this._running=!0,this._last=performance.now(),this._fpsAt=this._last,this.invalidate("all"))}stop(){this._running=!1,this._raf&&cancelAnimationFrame(this._raf),this._raf=0}_schedule(){this._raf||!this._running||(this._raf=requestAnimationFrame(this._tick))}_tick(t){if(this._raf=0,!this._running)return;const i=Math.min(Math.max(t-this._last,1),64);this._last=t,this._frames++,t-this._fpsAt>=500&&(this.fps=Math.round(this._frames*1e3/(t-this._fpsAt)),this._frames=0,this._fpsAt=t);const e=this._dirty;this._dirty=new Set;let n=!1;try{n=this.onFrame(e,i,t)===!0}catch(h){console.error("[Emberwick] frame error",h)}(n||this._dirty.size)&&this._schedule()}}const F=s=>1-Math.pow(1-s,3),G=s=>s<.5?4*s*s*s:1-Math.pow(-2*s+2,3)/2;class k{constructor(t=0,i=90){this.value=t,this.target=t,this.tau=i}set(t){this.target=t}jump(t){this.value=t,this.target=t}get settled(){const t=1e-9+Math.abs(this.target)*1e-6;return Math.abs(this.target-this.value)<=t}tick(t){return this.settled?(this.value=this.target,!1):(this.value+=(this.target-this.value)*(1-Math.exp(-t/this.tau)),!0)}}class z{constructor(t=200,i=F){this.duration=t,this.ease=i,this.t=t}restart(){this.t=0}get done(){return this.t>=this.duration}get progress(){return this.ease(Math.min(1,this.t/this.duration))}tick(t){return this.done?!1:(this.t+=t,!0)}}const L=(s,t,i)=>s<t?t:s>i?i:s;class I{constructor({spacing:t=9,minSpacing:i=.8,maxSpacing:e=160,rightOffset:n=12}={}){this.minSpacing=i,this.maxSpacing=e,this.rightOffset=n,this.width=0,this.barCount=0,this.follow=!0,this.timeframeMs=6e4,this._spacing=new k(t,65),this._right=new k(n,65),this._initial=t}get spacing(){return this._spacing.value}get right(){return this._right.value}resize(t){this.width=Math.max(1,t)}setBarCount(t){const i=t>this.barCount;if(this.barCount=t,this.follow){const e=t-1+this.rightOffset;i?this._right.set(e):this._right.jump(e)}}x(t){return this.width-(this._right.value-t)*this._spacing.value}index(t){return this._right.value-(this.width-t)/this._spacing.value}barWidth(){const t=this._spacing.value;return Math.max(1,Math.floor(t*.72))}visibleRange(){const t=Math.floor(this.index(0))-1,i=Math.ceil(this.index(this.width))+1;return{from:L(t,0,Math.max(0,this.barCount-1)),to:L(i,0,Math.max(0,this.barCount-1))}}_clampRight(t){const i=this.barCount-1+this.rightOffset+this.width/this._spacing.target,e=Math.min(4,this.barCount-1+this.rightOffset);return L(t,e,i)}panBy(t){if(!t)return!1;const i=this._clampRight(this._right.value-t/this._spacing.value);return this._right.jump(i),this.follow=!1,!0}zoomAt(t,i){const e=this._spacing.target,n=L(e*i,this.minSpacing,this.maxSpacing);if(Math.abs(n-e)<1e-9)return!1;const h=this.follow?this.width:t,u=this._right.target-(this.width-h)/e+(this.width-h)/n;return this._spacing.set(n),this._right.set(this._clampRight(u)),!0}snapToRealtime(){this.follow=!0,this._right.set(this.barCount-1+this.rightOffset)}reset(){this._spacing.set(this._initial),this.snapToRealtime()}tick(t){const i=this._spacing.tick(t),e=this._right.tick(t);return i||e}get settled(){return this._spacing.settled&&this._right.settled}}const V=(s,t,i)=>s<t?t:s>i?i:s;class P{constructor({mode:t="linear",tau:i=120,marginTop:e=.12,marginBottom:n=.12}={}){this.mode=t,this.marginTop=e,this.marginBottom=n,this.auto=!0,this.top=0,this.height=1,this._lo=new k(0,i),this._hi=new k(1,i),this._primed=!1}_fwd(t){return this.mode==="log"?Math.log(Math.max(t,1e-9)):t}_inv(t){return this.mode==="log"?Math.exp(t):t}setMode(t){if(t===this.mode)return;const i=this._inv(this._lo.value),e=this._inv(this._hi.value);this.mode=t,this._lo.jump(this._fwd(i)),this._hi.jump(this._fwd(e))}layout(t,i){this.top=t,this.height=Math.max(1,i)}get lo(){return this._inv(this._lo.value)}get hi(){return this._inv(this._hi.value)}y(t){const i=this._lo.value,e=this._hi.value,n=(this._fwd(t)-i)/(e-i||1);return this.top+this.height*(1-n)}price(t){const i=this._lo.value,e=this._hi.value,n=1-(t-this.top)/this.height;return this._inv(i+n*(e-i))}fit(t,i,e,n){if(!this.auto||!t.length)return;let h=1/0,o=-1/0;for(let v=i;v<=e;v++){const a=t[v];a&&(a.low<h&&(h=a.low),a.high>o&&(o=a.high))}if(n&&(n.low<h&&(h=n.low),n.high>o&&(o=n.high)),!isFinite(h)||!isFinite(o))return;let p=this._fwd(h),u=this._fwd(o),l=(u-p)*this.marginTop;l>0||(l=Math.abs(u)*.01||1),p-=l,u+=(u-p)*0+l,this._lo.set(p),this._hi.set(u),this._primed||(this._lo.jump(p),this._hi.jump(u),this._primed=!0)}scaleBy(t){this.auto=!1;const i=this._lo.target,e=this._hi.target,n=(i+e)/2,h=(e-i)/2*V(t,.2,5);this._lo.set(n-h),this._hi.set(n+h)}resetAuto(){this.auto=!0}tick(t){const i=this._lo.tick(t),e=this._hi.tick(t);return i||e}}const A={background:"#0b0e14",grid:"rgba(255,255,255,0.045)",axisLine:"rgba(255,255,255,0.10)",text:"#8b93a7",textStrong:"#e6e9ef",up:"#26a69a",down:"#ef5350",upFill:"#26a69a",downFill:"#ef5350",wickUp:"#26a69a",wickDown:"#ef5350",volumeUp:"rgba(38,166,154,0.30)",volumeDown:"rgba(239,83,80,0.30)",crosshair:"rgba(255,255,255,0.32)",labelBg:"#2a3040",labelText:"#e6e9ef",tagText:"#06080d",font:'11px ui-sans-serif, -apple-system, "Segoe UI", Roboto, sans-serif',priceAxisWidth:68,timeAxisHeight:26},J={...A,background:"#ffffff",grid:"rgba(0,0,0,0.06)",axisLine:"rgba(0,0,0,0.14)",text:"#6b7280",textStrong:"#111827",labelBg:"#374151",volumeUp:"rgba(38,166,154,0.25)",volumeDown:"rgba(239,83,80,0.25)",crosshair:"rgba(0,0,0,0.35)",tagText:"#ffffff"};class H{constructor(t=55){this.enabled=!0,this.o=new k(0,t),this.h=new k(0,t),this.l=new k(0,t),this.c=new k(0,t),this.vol=new k(0,t*2),this.spawn=new z(240),this._has=!1,this._time=null}setTarget(t){if(!t){this._has=!1;return}(!this._has||t.time!==this._time)&&(this.o.jump(t.open),this.h.jump(t.open),this.l.jump(t.open),this.c.jump(t.open),this.vol.jump(0),this.spawn.restart(),this._time=t.time,this._has=!0),this.o.set(t.open),this.h.set(t.high),this.l.set(t.low),this.c.set(t.close),this.vol.set(t.volume||0)}reset(){this._has=!1,this._time=null}tick(t){if(!this._has)return!1;let i=!1;return this.o.tick(t)&&(i=!0),this.h.tick(t)&&(i=!0),this.l.tick(t)&&(i=!0),this.c.tick(t)&&(i=!0),this.vol.tick(t)&&(i=!0),this.spawn.tick(t)&&(i=!0),i}read(t){if(!this._has||!this.enabled||t.time!==this._time)return t;const i=this.o.value,e=this.c.value;return{time:t.time,open:i,close:e,high:Math.max(this.h.value,i,e),low:Math.min(this.l.value,i,e),volume:this.vol.value,_spawn:this.spawn.progress}}}class j{constructor({friction:t=.92,min:i=.015}={}){this.friction=t,this.min=i,this.v=0,this.active=!1}sample(t,i){if(i<=0)return;const e=t/i;this.v=this.v*.6+e*.4,this.active=!1}release(){Math.abs(this.v)>this.min&&(this.active=!0)}stop(){this.v=0,this.active=!1}tick(t){if(!this.active)return 0;const i=this.v*t;return this.v*=Math.pow(this.friction,t/16.6667),Math.abs(this.v)<this.min&&this.stop(),i}}function N(s,t){const i=s/Math.max(1,t);if(!(i>0)||!isFinite(i))return 1;const e=Math.pow(10,Math.floor(Math.log10(i))),n=i/e;return(n<1.5?1:n<3?2:n<7?5:10)*e}function B(s,t,i){const e=N(t-s,i),n=[],h=Math.ceil(s/e)*e;for(let o=h;o<=t+e*1e-9;o+=e)n.push(o);return{ticks:n,step:e}}function D(s){return!isFinite(s)||s<=0?2:s>=100?0:s>=1?2:Math.min(8,Math.ceil(-Math.log10(s))+1)}function Q(s){const t=[1,2,5,10,15,20,30,60,120,240,480,960,1920,3840,7680];for(const i of t)if(i>=s)return i;return Math.ceil(s/1e3)*1e3}const R=s=>String(s).padStart(2,"0");function Z(s,t){const i=new Date(s);return t>=864e5?`${i.getDate()} ${i.toLocaleString("en",{month:"short"})}`:i.getHours()===0&&i.getMinutes()===0?`${i.getDate()} ${i.toLocaleString("en",{month:"short"})}`:`${R(i.getHours())}:${R(i.getMinutes())}`}function tt(s){const t=new Date(s);return`${t.getFullYear()}-${R(t.getMonth()+1)}-${R(t.getDate())} ${R(t.getHours())}:${R(t.getMinutes())}`}function it(s,t){const{theme:i,ts:e,ps:n,plot:h,bars:o,width:p,height:u}=t;s.clearRect(0,0,p,u),s.fillStyle=i.background,s.fillRect(0,0,p,u),s.font=i.font,s.textBaseline="middle";const l=Math.max(2,Math.floor(h.h/58)),{ticks:v,step:a}=B(n.lo,n.hi,l),c=D(a);s.strokeStyle=i.grid,s.lineWidth=1,s.beginPath();for(const f of v){const d=Math.round(n.y(f))+.5;d<h.y||d>h.y+h.h||(s.moveTo(0,d),s.lineTo(h.w,d))}s.stroke(),s.fillStyle=i.text,s.textAlign="left";for(const f of v){const d=Math.round(n.y(f));d<h.y+6||d>h.y+h.h-6||s.fillText(f.toFixed(c),h.w+8,d)}if(o.length){const f=Math.ceil(74/Math.max(1e-4,e.spacing)),d=Q(f),{from:T,to:b}=e.visibleRange(),S=Math.ceil(T/d)*d;s.strokeStyle=i.grid,s.beginPath();for(let g=S;g<=b;g+=d){const r=Math.round(e.x(g))+.5;r<0||r>h.w||(s.moveTo(r,0),s.lineTo(r,h.h))}s.stroke(),s.fillStyle=i.text,s.textAlign="center";const w=h.h+i.timeAxisHeight/2;for(let g=S;g<=b;g+=d){const r=o[g];if(!r)continue;const m=Math.round(e.x(g));m<28||m>h.w-28||s.fillText(Z(r.time,e.timeframeMs),m,w)}}s.strokeStyle=i.axisLine,s.beginPath(),s.moveTo(h.w+.5,0),s.lineTo(h.w+.5,h.h),s.moveTo(0,h.h+.5),s.lineTo(p,h.h+.5),s.stroke()}function st(s,t){const{theme:i,ts:e,ps:n,plot:h,bars:o,width:p,height:u,live:l,volumeRatio:v}=t;if(s.clearRect(0,0,p,u),!o.length)return;const{from:a,to:c}=e.visibleRange(),f=e.barWidth(),d=f/2,T=f<=2,b=h.h*v,S=h.y+h.h-b;let w=0;for(let r=a;r<=c;r++){const m=o[r];m&&m.volume>w&&(w=m.volume)}if(w>0)for(let r=a;r<=c;r++){let m=o[r];if(!m)continue;l&&r===o.length-1&&(m=l);const M=e.x(r);if(M<-f||M>h.w+f)continue;const y=m.volume/w*b*.9;s.fillStyle=m.close>=m.open?i.volumeUp:i.volumeDown,s.fillRect(Math.round(M-d),S+(b-y),Math.max(1,f),y)}for(let r=a;r<=c;r++){let m=o[r];if(!m)continue;const M=r===o.length-1;l&&M&&(m=l);const y=e.x(r);if(y<-f||y>h.w+f)continue;const C=m.close>=m.open,at=C?i.up:i.down,U=n.y(m.open),W=n.y(m.close),rt=n.y(m.high),lt=n.y(m.low);let K=1;l&&M&&typeof m._spawn=="number"&&(K=.35+.65*m._spawn);const X=Math.round(y)+(f%2?.5:0);if(s.strokeStyle=C?i.wickUp:i.wickDown,s.lineWidth=Math.max(1,Math.min(2,f*.16)),s.beginPath(),s.moveTo(X,rt),s.lineTo(X,lt),s.stroke(),T)continue;const ct=Math.min(U,W),ut=Math.max(1,Math.abs(W-U)),Y=Math.max(1,f*K);s.fillStyle=at,s.fillRect(Math.round(y-Y/2),Math.round(ct),Math.round(Y),Math.round(ut))}const g=l||o[o.length-1];if(g){const r=Math.round(n.y(g.close))+.5;if(r>h.y&&r<h.y+h.h){const m=g.close>=g.open;s.save(),s.setLineDash([3,3]),s.strokeStyle=m?i.up:i.down,s.lineWidth=1,s.globalAlpha=.7,s.beginPath(),s.moveTo(0,r),s.lineTo(h.w,r),s.stroke(),s.restore();const{step:M}=B(n.lo,n.hi,Math.max(2,Math.floor(h.h/58))),y=g.close.toFixed(D(M));s.font=i.font,s.textBaseline="middle",s.textAlign="left";const C=s.measureText(y).width;s.fillStyle=m?i.up:i.down,s.fillRect(h.w+1,r-9,C+14,18),s.fillStyle=i.tagText,s.fillText(y,h.w+8,r)}}}function et(s,t){const{theme:i,ts:e,ps:n,plot:h,bars:o,width:p,height:u,cursor:l,magnet:v}=t;if(s.clearRect(0,0,p,u),!l||!o.length||l.x<0||l.x>h.w||l.y<0||l.y>h.h)return;const a=Math.round(e.index(l.x)),c=o[a];let f=l.x,d=l.y;if(c&&(f=e.x(a),v)){const w=[c.open,c.high,c.low,c.close];let g=null,r=1/0;for(const m of w){const M=n.y(m),y=Math.abs(M-l.y);y<r&&(r=y,g=M)}r<22&&(d=g)}s.save(),s.setLineDash([4,4]),s.strokeStyle=i.crosshair,s.lineWidth=1,s.beginPath(),s.moveTo(Math.round(f)+.5,0),s.lineTo(Math.round(f)+.5,h.h),s.moveTo(0,Math.round(d)+.5),s.lineTo(h.w,Math.round(d)+.5),s.stroke(),s.restore(),s.font=i.font,s.textBaseline="middle";const{step:T}=B(n.lo,n.hi,Math.max(2,Math.floor(h.h/58))),b=n.price(d).toFixed(D(T));s.textAlign="left";const S=s.measureText(b).width;if(s.fillStyle=i.labelBg,s.fillRect(h.w+1,d-9,S+14,18),s.fillStyle=i.labelText,s.fillText(b,h.w+8,d),c){const w=tt(c.time);s.textAlign="center";const g=s.measureText(w).width,r=Math.min(Math.max(f,g/2+6),h.w-g/2-6);s.fillStyle=i.labelBg,s.fillRect(r-g/2-7,h.h+3,g+14,18),s.fillStyle=i.labelText,s.fillText(w,r,h.h+12)}}class O{constructor(t,i={}){if(!t)throw new Error("Chart: container element is required");this.container=t,this.theme={...A,...i.theme||{}},this.options={volumeRatio:.18,magnet:!0,animate:!0,...i},this.bars=[],this.feed=null,this._unsub=null,this._loadingHistory=!1,this._exhausted=!1,this._listeners={crosshair:new Set,visibleRange:new Set},this.layers=new x(t,["base","main","overlay"]),this.ts=new I(i.timeScale),this.ps=new P(i.priceScale),this.live=new H,this.live.enabled=this.options.animate!==!1,this.inertia=new j,this.cursor=null,this.plot={x:0,y:0,w:1,h:1},this.loop=new q((e,n)=>this._frame(e,n)),this.layers.onResize=()=>{this._layout(),this.loop.invalidate("all")},this._layout(),this._bindEvents(),this.loop.start()}_layout(){const{width:t,height:i}=this.layers,e=Math.max(1,t-this.theme.priceAxisWidth),n=Math.max(1,i-this.theme.timeAxisHeight);this.plot={x:0,y:0,w:e,h:n},this.ts.resize(e),this.ps.layout(0,n)}setData(t){this.bars=Array.isArray(t)?t.slice():[],this._exhausted=!1,this.bars.length>1&&(this.ts.timeframeMs=this.bars[1].time-this.bars[0].time),this.ts.setBarCount(this.bars.length),this.ts.snapToRealtime(),this.live.reset(),this.ps._primed=!1,this.loop.invalidate("all")}update(t){if(!t)return;const i=this.bars.length;if(i&&this.bars[i-1].time===t.time)this.bars[i-1]=t;else{this.append(t);return}this.live.setTarget(t),this.loop.invalidate("main")}append(t){if(!t)return;const i=this.bars.length;i&&t.time<=this.bars[i-1].time?this.bars[i-1]=t:(this.bars.push(t),this.ts.setBarCount(this.bars.length)),this.live.setTarget(t),this.loop.invalidate("main")}async setFeed(t){if(this.detachFeed(),this.feed=t,!t)return;this.ts.timeframeMs=t.timeframe||this.ts.timeframeMs;const i=await t.getBars({symbol:t.symbol,timeframe:t.timeframe,to:null,limit:this.options.initialBars||1500});this.setData(i),typeof t.prime=="function"&&t.prime(i[i.length-1]),this._unsub=t.subscribe(e=>{!e||!e.bar||(e.type==="append"?this.append(e.bar):this.update(e.bar))})}detachFeed(){this._unsub&&this._unsub(),this._unsub=null,this.feed=null}async _maybeLoadHistory(){if(this._loadingHistory||this._exhausted||!this.feed)return;const{from:t}=this.ts.visibleRange();if(!(t>80||!this.bars.length)){this._loadingHistory=!0;try{const i=this.bars[0].time,e=await this.feed.getBars({symbol:this.feed.symbol,timeframe:this.feed.timeframe,to:i,limit:1e3});if(!e||!e.length)this._exhausted=!0;else{const n=e.filter(h=>h.time<i);if(!n.length)this._exhausted=!0;else{this.bars=n.concat(this.bars);const h=this.ts.follow;this.ts.barCount=this.bars.length,this.ts._right.jump(this.ts._right.value+n.length),this.ts._right.set(this.ts._right.target+n.length),this.ts.follow=h,this.loop.invalidate("all")}}}catch(i){console.error("[Emberwick] history load failed",i),this._exhausted=!0}finally{this._loadingHistory=!1}}}_bindEvents(){const t=this.container;t.style.touchAction="none",t.style.cursor="crosshair";let i=!1,e=null,n=0,h=0,o=0,p=!1;const u=new Map;let l=0;const v=a=>{const c=t.getBoundingClientRect();return{x:a.clientX-c.left,y:a.clientY-c.top}};this._onDown=a=>{if(u.set(a.pointerId,v(a)),u.size===2){const[f,d]=[...u.values()];l=Math.hypot(f.x-d.x,f.y-d.y),i=!1;return}const c=v(a);i=!0,p=!1,e=c.x>this.plot.w?"price":c.y>this.plot.h?"time":"pan",n=c.x,h=c.y,o=performance.now(),this.inertia.stop(),t.setPointerCapture(a.pointerId)},this._onMove=a=>{const c=v(a);if(u.has(a.pointerId)&&u.set(a.pointerId,c),u.size===2){const[S,w]=[...u.values()],g=Math.hypot(S.x-w.x,S.y-w.y);if(l>0&&g>0){const r=(S.x+w.x)/2;this.ts.zoomAt(r,g/l),this.loop.invalidate("all")}l=g;return}if(this.cursor=c,this._emitCrosshair(c),this.loop.invalidate("overlay"),!i)return;const f=performance.now(),d=f-o,T=c.x-n,b=c.y-h;(Math.abs(T)>1||Math.abs(b)>1)&&(p=!0),e==="pan"?(this.ts.panBy(T),this.inertia.sample(T,d),this.loop.invalidate("all"),this._maybeLoadHistory()):e==="price"?(this.ps.scaleBy(1+b/220),this.loop.invalidate("all")):e==="time"&&(this.ts.zoomAt(this.plot.w,1-T/260),this.loop.invalidate("all")),n=c.x,h=c.y,o=f},this._onUp=a=>{u.delete(a.pointerId),u.size<2&&(l=0),i&&e==="pan"&&p&&(this.inertia.release(),this.loop.invalidate("all")),i=!1,e=null;try{t.releasePointerCapture(a.pointerId)}catch{}},this._onLeave=()=>{this.cursor=null,this._emitCrosshair(null),this.loop.invalidate("overlay")},this._onWheel=a=>{a.preventDefault();const c=t.getBoundingClientRect(),f=a.clientX-c.left,d=Math.pow(.999,a.deltaY);this.ts.zoomAt(f,d),this.loop.invalidate("all"),this._maybeLoadHistory()},this._onDbl=()=>{this.ts.reset(),this.ps.resetAuto(),this.loop.invalidate("all")},this._onKey=a=>{const c=a.shiftKey?120:40;if(a.key==="ArrowLeft")this.ts.panBy(c),this.loop.invalidate("all"),this._maybeLoadHistory();else if(a.key==="ArrowRight")this.ts.panBy(-c),this.loop.invalidate("all");else if(a.key==="+"||a.key==="=")this.ts.zoomAt(this.plot.w/2,1.2),this.loop.invalidate("all");else if(a.key==="-"||a.key==="_")this.ts.zoomAt(this.plot.w/2,.8),this.loop.invalidate("all");else return;a.preventDefault()},t.addEventListener("pointerdown",this._onDown),t.addEventListener("pointermove",this._onMove),t.addEventListener("pointerup",this._onUp),t.addEventListener("pointercancel",this._onUp),t.addEventListener("pointerleave",this._onLeave),t.addEventListener("wheel",this._onWheel,{passive:!1}),t.addEventListener("dblclick",this._onDbl),t.addEventListener("keydown",this._onKey),t.hasAttribute("tabindex")||t.setAttribute("tabindex","0")}_emitCrosshair(t){if(!this._listeners.crosshair.size)return;let i=null;if(t&&this.bars.length&&t.x<=this.plot.w&&t.y<=this.plot.h){const e=Math.round(this.ts.index(t.x)),n=this.bars[e];n&&(i={index:e,bar:n,price:this.ps.price(t.y)})}for(const e of this._listeners.crosshair)e(i)}subscribe(t,i){const e=this._listeners[t];if(!e)throw new Error(`Chart: unknown event "${t}"`);return e.add(i),()=>e.delete(i)}_frame(t,i){let e=!1;this.ts.tick(i)&&(e=!0);const n=this.inertia.tick(i);n&&(this.ts.panBy(n),e=!0,this._maybeLoadHistory()),this.live.tick(i)&&(e=!0);const{from:h,to:o}=this.ts.visibleRange(),p=this.bars.length-1,u=this.bars.length?this.live.read(this.bars[p]):null,l=u&&o>=p?u:null;this.ps.fit(this.bars,h,o,l),this.ps.tick(i)&&(e=!0);const v=e||t.has("all")||t.has("base")||t.has("main"),a={theme:this.theme,ts:this.ts,ps:this.ps,plot:this.plot,bars:this.bars,width:this.layers.width,height:this.layers.height,live:l,volumeRatio:this.options.volumeRatio,cursor:this.cursor,magnet:this.options.magnet};return v&&(it(this.layers.ctx.base,a),st(this.layers.ctx.main,a)),(v||t.has("overlay"))&&et(this.layers.ctx.overlay,a),e}get fps(){return this.loop.fps}setTheme(t){this.theme={...this.theme,...t},this._layout(),this.loop.invalidate("all")}setPriceMode(t){this.ps.setMode(t),this.loop.invalidate("all")}setAnimate(t){this.live.enabled=!!t,this.loop.invalidate("all")}setMagnet(t){this.options.magnet=!!t,this.loop.invalidate("overlay")}snapToRealtime(){this.ts.snapToRealtime(),this.ps.resetAuto(),this.loop.invalidate("all")}toImage(){return this.layers.composite().toDataURL("image/png")}destroy(){const t=this.container;t.removeEventListener("pointerdown",this._onDown),t.removeEventListener("pointermove",this._onMove),t.removeEventListener("pointerup",this._onUp),t.removeEventListener("pointercancel",this._onUp),t.removeEventListener("pointerleave",this._onLeave),t.removeEventListener("wheel",this._onWheel),t.removeEventListener("dblclick",this._onDbl),t.removeEventListener("keydown",this._onKey),this.detachFeed(),this.loop.stop(),this.layers.destroy(),this._listeners.crosshair.clear(),this._listeners.visibleRange.clear(),this.bars=[]}}class ${constructor({symbol:t="DEMO",timeframe:i=6e4}={}){this.symbol=t,this.timeframe=i}async getBars({symbol:t,timeframe:i,to:e,limit:n}){throw new Error("DataFeed.getBars() not implemented")}subscribe(t){return()=>{}}destroy(){}}function E(s){let t=s>>>0;return function(){t=t+1831565813|0;let i=Math.imul(t^t>>>15,1|t);return i=i+Math.imul(i^i>>>7,61|i)^i,((i^i>>>14)>>>0)/4294967296}}class ht extends ${constructor({symbol:t="EMBR",timeframe:i=6e4,seed:e=7,start:n=100,volatility:h=.0022,drift:o=2e-5,ticksPerSecond:p=8,speed:u=1}={}){super({symbol:t,timeframe:i}),this.seed=e,this.start=n,this.volatility=h,this.drift=o,this.ticksPerSecond=p,this.speed=u,this._rnd=E(e),this._handlers=new Set,this._timer=null,this._forming=null,this._last=n,this._vol=h,this._anchorTime=Math.floor(Date.now()/i)*i}_gauss(){let t=0,i=0;for(;t===0;)t=this._rnd();for(;i===0;)i=this._rnd();return Math.sqrt(-2*Math.log(t))*Math.cos(2*Math.PI*i)}_step(t){const i=this._gauss();return this._vol+=(this.volatility-this._vol)*.02+Math.abs(i)*this.volatility*.015,this._vol=Math.min(this._vol,this.volatility*6),Math.max(.01,t*(1+this.drift+i*this._vol))}_makeBar(t,i){let e=i;const n=14;let h=i,o=i;for(let l=0;l<n;l++)e=this._step(e),e>h&&(h=e),e<o&&(o=e);const p=Math.max(1e-9,h-o),u=Math.round((300+this._rnd()*900)*(1+p/i*260));return{time:t,open:i,high:h,low:o,close:e,volume:u}}async getBars({to:t,limit:i=1500,timeframe:e=this.timeframe}={}){const n=t==null?this._anchorTime:t,h=[],o=n-i*e,p=E(this.seed^Math.floor(o/e)),u=this._rnd;this._rnd=p;let l=this.start*(1+(p()-.5)*.04);for(let v=0;v<i;v++){const a=o+v*e,c=this._makeBar(a,l);l=c.close,h.push(c)}return this._rnd=u,t==null&&(this._last=h.length?h[h.length-1].close:this.start),h}subscribe(t){return this._handlers.add(t),this._timer||this._start(),()=>{this._handlers.delete(t),this._handlers.size||this.stop()}}_emit(t){for(const i of this._handlers)i(t)}_start(){const t=Math.max(16,1e3/this.ticksPerSecond);this._timer=setInterval(()=>this._tick(),t)}prime(t){t&&(this._last=t.close,this._forming={...t})}_tick(){const t=this.timeframe/this.speed,i=Date.now(),e=Math.floor(i/t)*t;if(!this._forming||this._forming.time!==e){const o=this._last;this._forming={time:e,open:o,high:o,low:o,close:o,volume:0},this._emit({type:"append",bar:{...this._forming}});return}const n=this._step(this._last);this._last=n;const h=this._forming;h.close=n,n>h.high&&(h.high=n),n<h.low&&(h.low=n),h.volume+=Math.round(20+this._rnd()*120),this._emit({type:"update",bar:{...h}})}setSpeed(t){this.speed=t}setTicksPerSecond(t){this.ticksPerSecond=t,this._timer&&(this.stop(),this._start())}setPaused(t){t?this.stop():!this._timer&&this._handlers.size&&this._start()}get paused(){return!this._timer}stop(){this._timer&&clearInterval(this._timer),this._timer=null}destroy(){this.stop(),this._handlers.clear()}}function nt(s,t){return new O(s,t)}const ot="0.1.0";_.Chart=O,_.DataFeed=$,_.Inertia=j,_.LiveCandle=H,_.PriceScale=P,_.RandomFeed=ht,_.Smoothed=k,_.TimeScale=I,_.Tween=z,_.createChart=nt,_.defaultTheme=A,_.easeInOutCubic=G,_.easeOutCubic=F,_.lightTheme=J,_.mulberry32=E,_.version=ot,Object.defineProperty(_,Symbol.toStringTag,{value:"Module"})});
1
+ (function(w,L){typeof exports=="object"&&typeof module!="undefined"?L(exports):typeof define=="function"&&define.amd?define(["exports"],L):(w=typeof globalThis!="undefined"?globalThis:w||self,L(w.Emberwick={}))})(this,function(w){"use strict";class L{constructor(t,e){this.container=t,this.names=e,this.canvas={},this.ctx={},this.width=0,this.height=0,this.dpr=0,this.onResize=null,getComputedStyle(t).position==="static"&&(t.style.position="relative"),e.forEach((s,n)=>{const o=document.createElement("canvas");Object.assign(o.style,{position:"absolute",left:"0",top:"0",width:"100%",height:"100%",pointerEvents:"none",zIndex:String(n+1)}),t.appendChild(o),this.canvas[s]=o,this.ctx[s]=o.getContext("2d")}),this._ro=new ResizeObserver(()=>this.measure()),this._ro.observe(t),this.measure()}measure(){const t=this.container.getBoundingClientRect(),e=Math.max(1,Math.floor(t.width)),s=Math.max(1,Math.floor(t.height)),n=Math.min(window.devicePixelRatio||1,2);if(!(e===this.width&&s===this.height&&n===this.dpr)){this.width=e,this.height=s,this.dpr=n;for(const o of this.names){const a=this.canvas[o];a.width=Math.floor(e*n),a.height=Math.floor(s*n),this.ctx[o].setTransform(n,0,0,n,0,0)}this.onResize&&this.onResize(e,s)}}composite(){const t=document.createElement("canvas");t.width=Math.floor(this.width*this.dpr),t.height=Math.floor(this.height*this.dpr);const e=t.getContext("2d");for(const s of this.names)e.drawImage(this.canvas[s],0,0);return t}destroy(){this._ro.disconnect();for(const t of this.names)this.canvas[t].remove();this.canvas={},this.ctx={}}}class J{constructor(t){this.onFrame=t,this.fps=0,this._raf=0,this._dirty=new Set,this._last=0,this._running=!1,this._frames=0,this._fpsAt=0,this._tick=this._tick.bind(this)}invalidate(...t){if(!t.length)this._dirty.add("all");else for(const e of t)this._dirty.add(e);this._schedule()}start(){this._running||(this._running=!0,this._last=performance.now(),this._fpsAt=this._last,this.invalidate("all"))}stop(){this._running=!1,this._raf&&cancelAnimationFrame(this._raf),this._raf=0}_schedule(){this._raf||!this._running||(this._raf=requestAnimationFrame(this._tick))}_tick(t){if(this._raf=0,!this._running)return;const e=Math.min(Math.max(t-this._last,1),64);this._last=t,this._frames++,t-this._fpsAt>=500&&(this.fps=Math.round(this._frames*1e3/(t-this._fpsAt)),this._frames=0,this._fpsAt=t);const s=this._dirty;this._dirty=new Set;let n=!1;try{n=this.onFrame(s,e,t)===!0}catch(o){console.error("[Emberwick] frame error",o)}(n||this._dirty.size)&&this._schedule()}}const F=i=>1-Math.pow(1-i,3),Q=i=>i<.5?4*i*i*i:1-Math.pow(-2*i+2,3)/2;class S{constructor(t=0,e=90){this.value=t,this.target=t,this.tau=e}set(t){this.target=t}jump(t){this.value=t,this.target=t}get settled(){const t=1e-9+Math.abs(this.target)*1e-6;return Math.abs(this.target-this.value)<=t}tick(t){return this.settled?(this.value=this.target,!1):(this.value+=(this.target-this.value)*(1-Math.exp(-t/this.tau)),!0)}}class I{constructor(t=200,e=F){this.duration=t,this.ease=e,this.t=t}restart(){this.t=0}get done(){return this.t>=this.duration}get progress(){return this.ease(Math.min(1,this.t/this.duration))}tick(t){return this.done?!1:(this.t+=t,!0)}}const C=(i,t,e)=>i<t?t:i>e?e:i;class H{constructor({spacing:t=9,minSpacing:e=.8,maxSpacing:s=160,rightOffset:n=12}={}){this.minSpacing=e,this.maxSpacing=s,this.rightOffset=n,this.width=0,this.barCount=0,this.follow=!0,this.timeframeMs=6e4,this._spacing=new S(t,65),this._right=new S(n,65),this._initial=t}get spacing(){return this._spacing.value}get right(){return this._right.value}resize(t){this.width=Math.max(1,t)}setBarCount(t){const e=t>this.barCount;if(this.barCount=t,this.follow){const s=t-1+this.rightOffset;e?this._right.set(s):this._right.jump(s)}}x(t){return this.width-(this._right.value-t)*this._spacing.value}index(t){return this._right.value-(this.width-t)/this._spacing.value}barWidth(){const t=this._spacing.value;return Math.max(1,Math.floor(t*.72))}visibleRange(){const t=Math.floor(this.index(0))-1,e=Math.ceil(this.index(this.width))+1;return{from:C(t,0,Math.max(0,this.barCount-1)),to:C(e,0,Math.max(0,this.barCount-1))}}_clampRight(t){const e=this.barCount-1+this.rightOffset+this.width/this._spacing.target,s=Math.min(4,this.barCount-1+this.rightOffset);return C(t,s,e)}panBy(t){if(!t)return!1;const e=this._clampRight(this._right.value-t/this._spacing.value);return this._right.jump(e),this.follow=!1,!0}zoomAt(t,e){const s=this._spacing.target,n=C(s*e,this.minSpacing,this.maxSpacing);if(Math.abs(n-s)<1e-9)return!1;const o=this.follow?this.width:t,h=this._right.target-(this.width-o)/s+(this.width-o)/n;return this._spacing.set(n),this._right.set(this._clampRight(h)),!0}snapToRealtime(){this.follow=!0,this._right.set(this.barCount-1+this.rightOffset)}reset(){this._spacing.set(this._initial),this.snapToRealtime()}tick(t){const e=this._spacing.tick(t),s=this._right.tick(t);return e||s}get settled(){return this._spacing.settled&&this._right.settled}}const x=(i,t,e)=>i<t?t:i>e?e:i;class O{constructor({mode:t="linear",tau:e=120,marginTop:s=.12,marginBottom:n=.12}={}){this.mode=t,this.marginTop=s,this.marginBottom=n,this.auto=!0,this.top=0,this.height=1,this._lo=new S(0,e),this._hi=new S(1,e),this._primed=!1}_fwd(t){return this.mode==="log"?Math.log(Math.max(t,1e-9)):t}_inv(t){return this.mode==="log"?Math.exp(t):t}setMode(t){if(t===this.mode)return;const e=this._inv(this._lo.value),s=this._inv(this._hi.value);this.mode=t,this._lo.jump(this._fwd(e)),this._hi.jump(this._fwd(s))}layout(t,e){this.top=t,this.height=Math.max(1,e)}get lo(){return this._inv(this._lo.value)}get hi(){return this._inv(this._hi.value)}y(t){const e=this._lo.value,s=this._hi.value,n=(this._fwd(t)-e)/(s-e||1);return this.top+this.height*(1-n)}price(t){const e=this._lo.value,s=this._hi.value,n=1-(t-this.top)/this.height;return this._inv(e+n*(s-e))}fit(t,e,s,n){if(!this.auto||!t.length)return;let o=1/0,a=-1/0;for(let m=e;m<=s;m++){const r=t[m];r&&(r.low<o&&(o=r.low),r.high>a&&(a=r.high))}if(n&&(n.low<o&&(o=n.low),n.high>a&&(a=n.high)),!isFinite(o)||!isFinite(a))return;let f=this._fwd(o),h=this._fwd(a),l=(h-f)*this.marginTop;l>0||(l=Math.abs(h)*.01||1),f-=l,h+=(h-f)*0+l,this._lo.set(f),this._hi.set(h),this._primed||(this._lo.jump(f),this._hi.jump(h),this._primed=!0)}scaleBy(t){this.auto=!1;const e=this._lo.target,s=this._hi.target,n=(e+s)/2,o=(s-e)/2*x(t,.2,5);this._lo.set(n-o),this._hi.set(n+o)}resetAuto(){this.auto=!0}tick(t){const e=this._lo.tick(t),s=this._hi.tick(t);return e||s}}const P={background:"#0b0e14",grid:"rgba(255,255,255,0.045)",axisLine:"rgba(255,255,255,0.10)",text:"#8b93a7",textStrong:"#e6e9ef",up:"#26a69a",down:"#ef5350",upFill:"#26a69a",downFill:"#ef5350",wickUp:"#26a69a",wickDown:"#ef5350",volumeUp:"rgba(38,166,154,0.30)",volumeDown:"rgba(239,83,80,0.30)",crosshair:"rgba(255,255,255,0.32)",labelBg:"#2a3040",labelText:"#e6e9ef",tagText:"#06080d",font:'11px ui-sans-serif, -apple-system, "Segoe UI", Roboto, sans-serif',priceAxisWidth:68,timeAxisHeight:26},tt={...P,background:"#ffffff",grid:"rgba(0,0,0,0.06)",axisLine:"rgba(0,0,0,0.14)",text:"#6b7280",textStrong:"#111827",labelBg:"#374151",volumeUp:"rgba(38,166,154,0.25)",volumeDown:"rgba(239,83,80,0.25)",crosshair:"rgba(0,0,0,0.35)",tagText:"#ffffff"};class U{constructor(t=55){this.enabled=!0,this.o=new S(0,t),this.h=new S(0,t),this.l=new S(0,t),this.c=new S(0,t),this.vol=new S(0,t*2),this.spawn=new I(240),this._has=!1,this._time=null}setTarget(t){if(!t){this._has=!1;return}(!this._has||t.time!==this._time)&&(this.o.jump(t.open),this.h.jump(t.open),this.l.jump(t.open),this.c.jump(t.open),this.vol.jump(0),this.spawn.restart(),this._time=t.time,this._has=!0),this.o.set(t.open),this.h.set(t.high),this.l.set(t.low),this.c.set(t.close),this.vol.set(t.volume||0)}reset(){this._has=!1,this._time=null}tick(t){if(!this._has)return!1;let e=!1;return this.o.tick(t)&&(e=!0),this.h.tick(t)&&(e=!0),this.l.tick(t)&&(e=!0),this.c.tick(t)&&(e=!0),this.vol.tick(t)&&(e=!0),this.spawn.tick(t)&&(e=!0),e}read(t){if(!this._has||!this.enabled||t.time!==this._time)return t;const e=this.o.value,s=this.c.value;return{time:t.time,open:e,close:s,high:Math.max(this.h.value,e,s),low:Math.min(this.l.value,e,s),volume:this.vol.value,_spawn:this.spawn.progress}}}class j{constructor({friction:t=.92,min:e=.015}={}){this.friction=t,this.min=e,this.v=0,this.active=!1}sample(t,e){if(e<=0)return;const s=t/e;this.v=this.v*.6+s*.4,this.active=!1}release(){Math.abs(this.v)>this.min&&(this.active=!0)}stop(){this.v=0,this.active=!1}tick(t){if(!this.active)return 0;const e=this.v*t;return this.v*=Math.pow(this.friction,t/16.6667),Math.abs(this.v)<this.min&&this.stop(),e}}function et(i,t){const e=i/Math.max(1,t);if(!(e>0)||!isFinite(e))return 1;const s=Math.pow(10,Math.floor(Math.log10(e))),n=e/s;return(n<1.5?1:n<3?2:n<7?5:10)*s}function R(i,t,e){const s=et(t-i,e),n=[],o=Math.ceil(i/s)*s;for(let a=o;a<=t+s*1e-9;a+=s)n.push(a);return{ticks:n,step:s}}function D(i){return!isFinite(i)||i<=0?2:i>=100?0:i>=1?2:Math.min(8,Math.ceil(-Math.log10(i))+1)}function it(i){const t=[1,2,5,10,15,20,30,60,120,240,480,960,1920,3840,7680];for(const e of t)if(e>=i)return e;return Math.ceil(i/1e3)*1e3}const A=i=>String(i).padStart(2,"0");function st(i,t){const e=new Date(i);return t>=864e5?`${e.getDate()} ${e.toLocaleString("en",{month:"short"})}`:e.getHours()===0&&e.getMinutes()===0?`${e.getDate()} ${e.toLocaleString("en",{month:"short"})}`:`${A(e.getHours())}:${A(e.getMinutes())}`}function nt(i){const t=new Date(i);return`${t.getFullYear()}-${A(t.getMonth()+1)}-${A(t.getDate())} ${A(t.getHours())}:${A(t.getMinutes())}`}function ot(i,t){const{theme:e,ts:s,ps:n,plot:o,bars:a,width:f,height:h}=t;i.clearRect(0,0,f,h),i.fillStyle=e.background,i.fillRect(0,0,f,h),i.font=e.font,i.textBaseline="middle";const l=Math.max(2,Math.floor(o.h/58)),{ticks:m,step:r}=R(n.lo,n.hi,l),c=D(r);i.strokeStyle=e.grid,i.lineWidth=1,i.beginPath();for(const p of m){const u=Math.round(n.y(p))+.5;u<o.y||u>o.y+o.h||(i.moveTo(0,u),i.lineTo(o.w,u))}i.stroke(),i.fillStyle=e.text,i.textAlign="left";for(const p of m){const u=Math.round(n.y(p));u<o.y+6||u>o.y+o.h-6||i.fillText(p.toFixed(c),o.w+8,u)}if(a.length){const p=Math.ceil(74/Math.max(1e-4,s.spacing)),u=it(p),{from:v,to:b}=s.visibleRange(),M=Math.ceil(v/u)*u;i.strokeStyle=e.grid,i.beginPath();for(let g=M;g<=b;g+=u){const d=Math.round(s.x(g))+.5;d<0||d>o.w||(i.moveTo(d,0),i.lineTo(d,o.h))}i.stroke(),i.fillStyle=e.text,i.textAlign="center";const y=o.h+e.timeAxisHeight/2;for(let g=M;g<=b;g+=u){const d=a[g];if(!d)continue;const _=Math.round(s.x(g));_<28||_>o.w-28||i.fillText(st(d.time,s.timeframeMs),_,y)}}i.strokeStyle=e.axisLine,i.beginPath(),i.moveTo(o.w+.5,0),i.lineTo(o.w+.5,o.h),i.moveTo(0,o.h+.5),i.lineTo(f,o.h+.5),i.stroke()}function ht(i,t){const{theme:e,ts:s,ps:n,plot:o,bars:a,width:f,height:h,live:l,volumeRatio:m}=t;if(i.clearRect(0,0,f,h),!a.length)return;const{from:r,to:c}=s.visibleRange(),p=s.barWidth(),u=p/2,v=p<=2,b=o.h*m,M=o.y+o.h-b;let y=0;for(let d=r;d<=c;d++){const _=a[d];_&&_.volume>y&&(y=_.volume)}if(y>0)for(let d=r;d<=c;d++){let _=a[d];if(!_)continue;l&&d===a.length-1&&(_=l);const k=s.x(d);if(k<-p||k>o.w+p)continue;const T=_.volume/y*b*.9;i.fillStyle=_.close>=_.open?e.volumeUp:e.volumeDown,i.fillRect(Math.round(k-u),M+(b-T),Math.max(1,p),T)}for(let d=r;d<=c;d++){let _=a[d];if(!_)continue;const k=d===a.length-1;l&&k&&(_=l);const T=s.x(d);if(T<-p||T>o.w+p)continue;const B=_.close>=_.open,Tt=B?e.up:e.down,Y=n.y(_.open),N=n.y(_.close),St=n.y(_.high),At=n.y(_.low);let Z=1;l&&k&&typeof _._spawn=="number"&&(Z=.35+.65*_._spawn);const G=Math.round(T)+(p%2?.5:0);if(i.strokeStyle=B?e.wickUp:e.wickDown,i.lineWidth=Math.max(1,Math.min(2,p*.16)),i.beginPath(),i.moveTo(G,St),i.lineTo(G,At),i.stroke(),v)continue;const Lt=Math.min(Y,N),Ct=Math.max(1,Math.abs(N-Y)),V=Math.max(1,p*Z);i.fillStyle=Tt,i.fillRect(Math.round(T-V/2),Math.round(Lt),Math.round(V),Math.round(Ct))}const g=l||a[a.length-1];if(g){const d=Math.round(n.y(g.close))+.5;if(d>o.y&&d<o.y+o.h){const _=g.close>=g.open;i.save(),i.setLineDash([3,3]),i.strokeStyle=_?e.up:e.down,i.lineWidth=1,i.globalAlpha=.7,i.beginPath(),i.moveTo(0,d),i.lineTo(o.w,d),i.stroke(),i.restore();const{step:k}=R(n.lo,n.hi,Math.max(2,Math.floor(o.h/58))),T=g.close.toFixed(D(k));i.font=e.font,i.textBaseline="middle",i.textAlign="left";const B=i.measureText(T).width;i.fillStyle=_?e.up:e.down,i.fillRect(o.w+1,d-9,B+14,18),i.fillStyle=e.tagText,i.fillText(T,o.w+8,d)}}}function at(i,t){const{theme:e,ts:s,ps:n,plot:o,bars:a,width:f,height:h,cursor:l,magnet:m}=t;if(i.clearRect(0,0,f,h),!l||!a.length||l.x<0||l.x>o.w||l.y<0||l.y>o.h)return;const r=Math.round(s.index(l.x)),c=a[r];let p=l.x,u=l.y;if(c&&(p=s.x(r),m)){const y=[c.open,c.high,c.low,c.close];let g=null,d=1/0;for(const _ of y){const k=n.y(_),T=Math.abs(k-l.y);T<d&&(d=T,g=k)}d<22&&(u=g)}i.save(),i.setLineDash([4,4]),i.strokeStyle=e.crosshair,i.lineWidth=1,i.beginPath(),i.moveTo(Math.round(p)+.5,0),i.lineTo(Math.round(p)+.5,o.h),i.moveTo(0,Math.round(u)+.5),i.lineTo(o.w,Math.round(u)+.5),i.stroke(),i.restore(),i.font=e.font,i.textBaseline="middle";const{step:v}=R(n.lo,n.hi,Math.max(2,Math.floor(o.h/58))),b=n.price(u).toFixed(D(v));i.textAlign="left";const M=i.measureText(b).width;if(i.fillStyle=e.labelBg,i.fillRect(o.w+1,u-9,M+14,18),i.fillStyle=e.labelText,i.fillText(b,o.w+8,u),c){const y=nt(c.time);i.textAlign="center";const g=i.measureText(y).width,d=Math.min(Math.max(p,g/2+6),o.w-g/2-6);i.fillStyle=e.labelBg,i.fillRect(d-g/2-7,o.h+3,g+14,18),i.fillStyle=e.labelText,i.fillText(y,d,o.h+12)}}const rt=["arrowUp","arrowDown","triangleUp","triangleDown","circle","square","diamond","flag","label"],lt=new Set(rt),ft={arrowUp:"belowBar",triangleUp:"belowBar",arrowDown:"aboveBar",triangleDown:"aboveBar"},ct=new Set(["aboveBar","belowBar","inBar","atPrice"]);function ut(i,t){if(!i||!isFinite(i.time))return null;const e=lt.has(i.shape)?i.shape:"circle",s=ct.has(i.position)?i.position:ft[e]||"aboveBar";return{id:i.id!=null?String(i.id):`mk${t}`,time:+i.time,price:isFinite(i.price)?+i.price:null,shape:e,position:s,color:i.color||null,textColor:i.textColor||null,text:i.text!=null?String(i.text):"",size:isFinite(i.size)&&i.size>0?+i.size:1,data:i.data,index:-1}}function W(i){if(!Array.isArray(i))return[];const t=[];for(let e=0;e<i.length;e++){const s=ut(i[e],e);s&&t.push(s)}return t.sort((e,s)=>e.time-s.time),t}function z(i,t){const e=i.length;if(!e)return-1;if(t<=i[0].time)return 0;if(t>=i[e-1].time)return e-1;let s=0,n=e-1;for(;s<=n;){const f=s+n>>1,h=i[f].time;if(h===t)return f;h<t?s=f+1:n=f-1}const o=Math.max(0,n),a=Math.min(e-1,s);return Math.abs(i[o].time-t)<=Math.abs(i[a].time-t)?o:a}function dt(i,t){for(let e=0;e<i.length;e++)i[e].index=z(t,i[e].time);return i}function mt(i,t){const{ts:e,ps:s,plot:n,bars:o,live:a}=t;if(!i.length||!o.length)return[];const{from:f,to:h}=e.visibleRange(),l=o.length-1,m=e.barWidth()<=3,r=new Map,c=[];let p=-1/0;for(const u of i){const v=u.index;if(v<0||v<f-2||v>h+2)continue;const b=a&&v===l?a:o[v];if(!b)continue;const M=e.x(v);if(M<-48||M>n.w+48)continue;if(m){if(M-p<4)continue;p=M}const y=5*u.size;let g,d=0;if(u.position==="atPrice"&&u.price!=null?g=s.y(u.price):u.position==="inBar"?g=s.y((b.high+b.low)/2):u.position==="belowBar"?(g=s.y(b.low)+y+7,d=1):(g=s.y(b.high)-y-7,d=-1),d!==0){const _=v+u.position,k=r.get(_)||0;r.set(_,k+1),g+=d*k*(y*2+5)}c.push({m:u,x:M,y:g,r:y,dir:d})}return c}const $={solid:[],dashed:[6,4],dotted:[1,3]},pt=new Set(["arrowDown","triangleDown"]);function q(i,t,e,s,n,o){const a=Math.max(0,Math.min(o,n/2,s/2));i.beginPath(),i.moveTo(t+a,e),i.lineTo(t+s-a,e),i.quadraticCurveTo(t+s,e,t+s,e+a),i.lineTo(t+s,e+n-a),i.quadraticCurveTo(t+s,e+n,t+s-a,e+n),i.lineTo(t+a,e+n),i.quadraticCurveTo(t,e+n,t,e+n-a),i.lineTo(t,e+a),i.quadraticCurveTo(t,e,t+a,e),i.closePath()}function gt(i,t){const{zones:e,theme:s,ts:n,ps:o,plot:a,bars:f}=t;if(!(!e||!e.length)){i.save(),i.font=s.font,i.textBaseline="top",i.textAlign="left";for(const h of e){let l,m,r,c;if(isFinite(h.from)&&isFinite(h.to))m=o.y(Math.max(h.from,h.to)),c=Math.max(1,o.y(Math.min(h.from,h.to))-m),l=0,r=a.w;else if(isFinite(h.fromTime)&&isFinite(h.toTime)&&f.length){const p=n.x(z(f,Math.min(h.fromTime,h.toTime))),u=n.x(z(f,Math.max(h.fromTime,h.toTime)));l=p,r=Math.max(1,u-p),m=0,c=a.h}else continue;l>a.w||l+r<0||m>a.h||m+c<0||(i.fillStyle=h.color||"rgba(38,166,154,0.10)",i.fillRect(l,m,r,c),h.border&&(i.strokeStyle=h.border,i.lineWidth=1,i.strokeRect(Math.round(l)+.5,Math.round(m)+.5,Math.round(r),Math.round(c))),h.label&&(i.fillStyle=h.labelColor||s.text,i.fillText(h.label,Math.max(6,l+6),Math.max(4,m+4))))}i.restore()}}function _t(i,t){const{priceLines:e,theme:s,ps:n,plot:o}=t;if(!e||!e.length)return;const{step:a}=R(n.lo,n.hi,Math.max(2,Math.floor(o.h/58))),f=D(a);i.save(),i.font=s.font,i.textBaseline="middle";for(const h of e){if(!h||!isFinite(h.price))continue;const l=Math.round(n.y(h.price))+.5;if(l<0||l>o.h)continue;const m=h.color||s.textStrong;if(i.setLineDash($[h.lineStyle]||$.dashed),i.strokeStyle=m,i.lineWidth=h.lineWidth||1,i.beginPath(),i.moveTo(0,l),i.lineTo(o.w,l),i.stroke(),i.setLineDash([]),h.title){i.textAlign="left";const r=i.measureText(h.title).width;i.fillStyle=m,q(i,6,l-9,r+12,18,4),i.fill(),i.fillStyle=h.titleColor||s.tagText,i.fillText(h.title,12,l)}if(h.axisLabel!==!1){const r=h.price.toFixed(f);i.textAlign="left";const c=i.measureText(r).width;i.fillStyle=m,i.fillRect(o.w+1,l-9,c+14,18),i.fillStyle=h.tagTextColor||s.tagText,i.fillText(r,o.w+8,l)}}i.restore()}function vt(i,t,e,s,n){switch(i.beginPath(),t){case"arrowUp":i.moveTo(e,s-n),i.lineTo(e+n,s),i.lineTo(e+n*.45,s),i.lineTo(e+n*.45,s+n),i.lineTo(e-n*.45,s+n),i.lineTo(e-n*.45,s),i.lineTo(e-n,s),i.closePath();break;case"arrowDown":i.moveTo(e,s+n),i.lineTo(e+n,s),i.lineTo(e+n*.45,s),i.lineTo(e+n*.45,s-n),i.lineTo(e-n*.45,s-n),i.lineTo(e-n*.45,s),i.lineTo(e-n,s),i.closePath();break;case"triangleUp":i.moveTo(e,s-n),i.lineTo(e+n,s+n),i.lineTo(e-n,s+n),i.closePath();break;case"triangleDown":i.moveTo(e,s+n),i.lineTo(e+n,s-n),i.lineTo(e-n,s-n),i.closePath();break;case"square":i.rect(e-n,s-n,n*2,n*2);break;case"diamond":i.moveTo(e,s-n),i.lineTo(e+n,s),i.lineTo(e,s+n),i.lineTo(e-n,s),i.closePath();break;default:i.arc(e,s,n,0,Math.PI*2)}}function bt(i,t,e,s,n){i.fillStyle=n,i.fillRect(t-s*.8,e-s,Math.max(1,s*.3),s*2),i.beginPath(),i.moveTo(t-s*.5,e-s),i.lineTo(t+s,e-s*.55),i.lineTo(t-s*.5,e-s*.1),i.closePath(),i.fill()}function wt(i,t,e,s){const n=[];if(!e||!e.length)return n;const{theme:o}=t;i.save(),i.font=o.font,i.textAlign="center",i.textBaseline="middle";for(const a of e){const{m:f,x:h,y:l,r:m,dir:r}=a,c=f.color||(pt.has(f.shape)?o.down:o.up),p=s!=null&&f.id===s;if(f.shape==="label"){const u=f.text||"•",v=i.measureText(u).width+14,b=18*f.size;q(i,h-v/2,l-b/2,v,b,4),i.fillStyle=c,i.fill(),p&&(i.strokeStyle=o.textStrong,i.lineWidth=1.5,i.stroke()),i.fillStyle=f.textColor||o.tagText,i.fillText(u,h,l+.5),n.push({id:f.id,marker:f,x:h,y:l,r:Math.max(v,b)/2});continue}p&&(i.beginPath(),i.arc(h,l,m+4,0,Math.PI*2),i.fillStyle="rgba(255,255,255,0.14)",i.fill()),f.shape==="flag"?bt(i,h,l,m,c):(vt(i,f.shape,h,l,m),i.fillStyle=c,i.fill()),f.text&&(i.fillStyle=f.textColor||o.text,i.fillText(f.text,h,r>=0?l+m+9:l-m-9)),n.push({id:f.id,marker:f,x:h,y:l,r:m+3})}return i.restore(),n}class K{constructor(t,e={}){if(!t)throw new Error("Chart: container element is required");this.container=t,this.theme={...P,...e.theme||{}},this.options={volumeRatio:.18,magnet:!0,animate:!0,...e},this.bars=[],this.feed=null,this._unsub=null,this._loadingHistory=!1,this._exhausted=!1,this._listeners={crosshair:new Set,visibleRange:new Set,markerClick:new Set,markerHover:new Set},this._markers=W(e.markers),this.priceLines=Array.isArray(e.priceLines)?e.priceLines.slice():[],this.zones=Array.isArray(e.zones)?e.zones.slice():[],this._markerHits=[],this._hoverMarkerId=null,this._resolveKey="",this.layers=new L(t,["base","main","overlay"]),this.ts=new H(e.timeScale),this.ps=new O(e.priceScale),this.live=new U,this.live.enabled=this.options.animate!==!1,this.inertia=new j,this.cursor=null,this.plot={x:0,y:0,w:1,h:1},this.loop=new J((s,n)=>this._frame(s,n)),this.layers.onResize=()=>{this._layout(),this.loop.invalidate("all")},this._layout(),this._bindEvents(),this.loop.start()}_layout(){const{width:t,height:e}=this.layers,s=Math.max(1,t-this.theme.priceAxisWidth),n=Math.max(1,e-this.theme.timeAxisHeight);this.plot={x:0,y:0,w:s,h:n},this.ts.resize(s),this.ps.layout(0,n)}setData(t){this.bars=Array.isArray(t)?t.slice():[],this._exhausted=!1,this.bars.length>1&&(this.ts.timeframeMs=this.bars[1].time-this.bars[0].time),this.ts.setBarCount(this.bars.length),this.ts.snapToRealtime(),this.live.reset(),this.ps._primed=!1,this.loop.invalidate("all")}update(t){if(!t)return;const e=this.bars.length;if(e&&this.bars[e-1].time===t.time)this.bars[e-1]=t;else{this.append(t);return}this.live.setTarget(t),this.loop.invalidate("main")}append(t){if(!t)return;const e=this.bars.length;e&&t.time<=this.bars[e-1].time?this.bars[e-1]=t:(this.bars.push(t),this.ts.setBarCount(this.bars.length)),this.live.setTarget(t),this.loop.invalidate("main")}async setFeed(t){if(this.detachFeed(),this.feed=t,!t)return;this.ts.timeframeMs=t.timeframe||this.ts.timeframeMs;const e=await t.getBars({symbol:t.symbol,timeframe:t.timeframe,to:null,limit:this.options.initialBars||1500});this.setData(e),typeof t.prime=="function"&&t.prime(e[e.length-1]),this._unsub=t.subscribe(s=>{!s||!s.bar||(s.type==="append"?this.append(s.bar):this.update(s.bar))})}detachFeed(){this._unsub&&this._unsub(),this._unsub=null,this.feed=null}async _maybeLoadHistory(){if(this._loadingHistory||this._exhausted||!this.feed)return;const{from:t}=this.ts.visibleRange();if(!(t>80||!this.bars.length)){this._loadingHistory=!0;try{const e=this.bars[0].time,s=await this.feed.getBars({symbol:this.feed.symbol,timeframe:this.feed.timeframe,to:e,limit:1e3});if(!s||!s.length)this._exhausted=!0;else{const n=s.filter(o=>o.time<e);if(!n.length)this._exhausted=!0;else{this.bars=n.concat(this.bars);const o=this.ts.follow;this.ts.barCount=this.bars.length,this.ts._right.jump(this.ts._right.value+n.length),this.ts._right.set(this.ts._right.target+n.length),this.ts.follow=o,this.loop.invalidate("all")}}}catch(e){console.error("[Emberwick] history load failed",e),this._exhausted=!0}finally{this._loadingHistory=!1}}}_bindEvents(){const t=this.container;t.style.touchAction="none",t.style.cursor="crosshair";let e=!1,s=null,n=0,o=0,a=0,f=!1;const h=new Map;let l=0;const m=r=>{const c=t.getBoundingClientRect();return{x:r.clientX-c.left,y:r.clientY-c.top}};this._onDown=r=>{if(h.set(r.pointerId,m(r)),h.size===2){const[p,u]=[...h.values()];l=Math.hypot(p.x-u.x,p.y-u.y),e=!1;return}const c=m(r);e=!0,f=!1,s=c.x>this.plot.w?"price":c.y>this.plot.h?"time":"pan",n=c.x,o=c.y,a=performance.now(),this.inertia.stop(),t.setPointerCapture(r.pointerId)},this._onMove=r=>{const c=m(r);if(h.has(r.pointerId)&&h.set(r.pointerId,c),h.size===2){const[M,y]=[...h.values()],g=Math.hypot(M.x-y.x,M.y-y.y);if(l>0&&g>0){const d=(M.x+y.x)/2;this.ts.zoomAt(d,g/l),this.loop.invalidate("all")}l=g;return}if(this.cursor=c,this._emitCrosshair(c),this.loop.invalidate("overlay"),!e)return;const p=performance.now(),u=p-a,v=c.x-n,b=c.y-o;(Math.abs(v)>1||Math.abs(b)>1)&&(f=!0),s==="pan"?(this.ts.panBy(v),this.inertia.sample(v,u),this.loop.invalidate("all"),this._maybeLoadHistory()):s==="price"?(this.ps.scaleBy(1+b/220),this.loop.invalidate("all")):s==="time"&&(this.ts.zoomAt(this.plot.w,1-v/260),this.loop.invalidate("all")),n=c.x,o=c.y,a=p},this._onUp=r=>{h.delete(r.pointerId),h.size<2&&(l=0),e&&s==="pan"&&f&&(this.inertia.release(),this.loop.invalidate("all")),e=!1,s=null;try{t.releasePointerCapture(r.pointerId)}catch{}},this._onLeave=()=>{this.cursor=null,this._emitCrosshair(null),this.loop.invalidate("overlay")},this._onWheel=r=>{r.preventDefault();const c=t.getBoundingClientRect(),p=r.clientX-c.left,u=Math.pow(.999,r.deltaY);this.ts.zoomAt(p,u),this.loop.invalidate("all"),this._maybeLoadHistory()},this._onDbl=()=>{this.ts.reset(),this.ps.resetAuto(),this.loop.invalidate("all")},this._onKey=r=>{const c=r.shiftKey?120:40;if(r.key==="ArrowLeft")this.ts.panBy(c),this.loop.invalidate("all"),this._maybeLoadHistory();else if(r.key==="ArrowRight")this.ts.panBy(-c),this.loop.invalidate("all");else if(r.key==="+"||r.key==="=")this.ts.zoomAt(this.plot.w/2,1.2),this.loop.invalidate("all");else if(r.key==="-"||r.key==="_")this.ts.zoomAt(this.plot.w/2,.8),this.loop.invalidate("all");else return;r.preventDefault()},this._onClick=r=>{if(f||!this._listeners.markerClick.size)return;const c=m(r),p=this.markerAt(c.x,c.y);if(p)for(const u of this._listeners.markerClick)u(p)},t.addEventListener("click",this._onClick),t.addEventListener("pointerdown",this._onDown),t.addEventListener("pointermove",this._onMove),t.addEventListener("pointerup",this._onUp),t.addEventListener("pointercancel",this._onUp),t.addEventListener("pointerleave",this._onLeave),t.addEventListener("wheel",this._onWheel,{passive:!1}),t.addEventListener("dblclick",this._onDbl),t.addEventListener("keydown",this._onKey),t.hasAttribute("tabindex")||t.setAttribute("tabindex","0")}_emitCrosshair(t){if(this._listeners.crosshair.size){let e=null;if(t&&this.bars.length&&t.x<=this.plot.w&&t.y<=this.plot.h){const s=Math.round(this.ts.index(t.x)),n=this.bars[s];n&&(e={index:s,bar:n,price:this.ps.price(t.y)})}for(const s of this._listeners.crosshair)s(e)}this._updateHover(t)}markerAt(t,e){const s=this._markerHits;for(let n=s.length-1;n>=0;n--){const o=s[n],a=t-o.x,f=e-o.y;if(a*a+f*f<=o.r*o.r)return o.marker}return null}_updateHover(t){const e=t?this.markerAt(t.x,t.y):null,s=e?e.id:null;if(s!==this._hoverMarkerId){this._hoverMarkerId=s,this.container.style.cursor=e?"pointer":"crosshair",this.loop.invalidate("main");for(const n of this._listeners.markerHover)n(e)}}subscribe(t,e){const s=this._listeners[t];if(!s)throw new Error(`Chart: unknown event "${t}"`);return s.add(e),()=>s.delete(e)}setMarkers(t){this._markers=W(t),this._resolveKey="",this.loop.invalidate("main")}getMarkers(){return this._markers.slice()}addMarker(t){this.setMarkers(this._markers.concat([t]))}removeMarker(t){const e=String(t);this.setMarkers(this._markers.filter(s=>s.id!==e))}clearMarkers(){this.setMarkers([])}setPriceLines(t){this.priceLines=Array.isArray(t)?t.slice():[],this.loop.invalidate("main")}setZones(t){this.zones=Array.isArray(t)?t.slice():[],this.loop.invalidate("all")}_frame(t,e){let s=!1;this.ts.tick(e)&&(s=!0);const n=this.inertia.tick(e);n&&(this.ts.panBy(n),s=!0,this._maybeLoadHistory()),this.live.tick(e)&&(s=!0);const{from:o,to:a}=this.ts.visibleRange(),f=this.bars.length-1,h=this.bars.length?this.live.read(this.bars[f]):null,l=h&&a>=f?h:null;this.ps.fit(this.bars,o,a,l),this.ps.tick(e)&&(s=!0);const m=s||t.has("all")||t.has("base")||t.has("main"),r={theme:this.theme,ts:this.ts,ps:this.ps,plot:this.plot,bars:this.bars,width:this.layers.width,height:this.layers.height,live:l,volumeRatio:this.options.volumeRatio,cursor:this.cursor,magnet:this.options.magnet,priceLines:this.priceLines,zones:this.zones};if(this._markers.length){const c=this.bars.length+":"+(this.bars.length?this.bars[0].time:0);c!==this._resolveKey&&(dt(this._markers,this.bars),this._resolveKey=c)}return m&&(ot(this.layers.ctx.base,r),gt(this.layers.ctx.base,r),ht(this.layers.ctx.main,r),_t(this.layers.ctx.main,r),this._markerHits=wt(this.layers.ctx.main,r,mt(this._markers,r),this._hoverMarkerId)),(m||t.has("overlay"))&&at(this.layers.ctx.overlay,r),s}get fps(){return this.loop.fps}setTheme(t){this.theme={...this.theme,...t},this._layout(),this.loop.invalidate("all")}setPriceMode(t){this.ps.setMode(t),this.loop.invalidate("all")}setAnimate(t){this.live.enabled=!!t,this.loop.invalidate("all")}setMagnet(t){this.options.magnet=!!t,this.loop.invalidate("overlay")}snapToRealtime(){this.ts.snapToRealtime(),this.ps.resetAuto(),this.loop.invalidate("all")}toImage(){return this.layers.composite().toDataURL("image/png")}destroy(){const t=this.container;t.removeEventListener("pointerdown",this._onDown),t.removeEventListener("pointermove",this._onMove),t.removeEventListener("pointerup",this._onUp),t.removeEventListener("pointercancel",this._onUp),t.removeEventListener("pointerleave",this._onLeave),t.removeEventListener("wheel",this._onWheel),t.removeEventListener("dblclick",this._onDbl),t.removeEventListener("keydown",this._onKey),t.removeEventListener("click",this._onClick),this.detachFeed(),this.loop.stop(),this.layers.destroy();for(const e of Object.values(this._listeners))e.clear();this._markers=[],this._markerHits=[],this.priceLines=[],this.zones=[],this.bars=[]}}class X{constructor({symbol:t="DEMO",timeframe:e=6e4}={}){this.symbol=t,this.timeframe=e}async getBars({symbol:t,timeframe:e,to:s,limit:n}){throw new Error("DataFeed.getBars() not implemented")}subscribe(t){return()=>{}}destroy(){}}function E(i){let t=i>>>0;return function(){t=t+1831565813|0;let e=Math.imul(t^t>>>15,1|t);return e=e+Math.imul(e^e>>>7,61|e)^e,((e^e>>>14)>>>0)/4294967296}}class yt extends X{constructor({symbol:t="EMBR",timeframe:e=6e4,seed:s=7,start:n=100,volatility:o=.0022,drift:a=2e-5,ticksPerSecond:f=8,speed:h=1}={}){super({symbol:t,timeframe:e}),this.seed=s,this.start=n,this.volatility=o,this.drift=a,this.ticksPerSecond=f,this.speed=h,this._rnd=E(s),this._handlers=new Set,this._timer=null,this._forming=null,this._last=n,this._vol=o,this._anchorTime=Math.floor(Date.now()/e)*e}_gauss(){let t=0,e=0;for(;t===0;)t=this._rnd();for(;e===0;)e=this._rnd();return Math.sqrt(-2*Math.log(t))*Math.cos(2*Math.PI*e)}_step(t){const e=this._gauss();return this._vol+=(this.volatility-this._vol)*.02+Math.abs(e)*this.volatility*.015,this._vol=Math.min(this._vol,this.volatility*6),Math.max(.01,t*(1+this.drift+e*this._vol))}_makeBar(t,e){let s=e;const n=14;let o=e,a=e;for(let l=0;l<n;l++)s=this._step(s),s>o&&(o=s),s<a&&(a=s);const f=Math.max(1e-9,o-a),h=Math.round((300+this._rnd()*900)*(1+f/e*260));return{time:t,open:e,high:o,low:a,close:s,volume:h}}async getBars({to:t,limit:e=1500,timeframe:s=this.timeframe}={}){const n=t==null?this._anchorTime:t,o=[],a=n-e*s,f=E(this.seed^Math.floor(a/s)),h=this._rnd;this._rnd=f;let l=this.start*(1+(f()-.5)*.04);for(let m=0;m<e;m++){const r=a+m*s,c=this._makeBar(r,l);l=c.close,o.push(c)}return this._rnd=h,t==null&&(this._last=o.length?o[o.length-1].close:this.start),o}subscribe(t){return this._handlers.add(t),this._timer||this._start(),()=>{this._handlers.delete(t),this._handlers.size||this.stop()}}_emit(t){for(const e of this._handlers)e(t)}_start(){const t=Math.max(16,1e3/this.ticksPerSecond);this._timer=setInterval(()=>this._tick(),t)}prime(t){t&&(this._last=t.close,this._forming={...t})}_tick(){const t=this.timeframe/this.speed,e=Date.now(),s=Math.floor(e/t)*t;if(!this._forming||this._forming.time!==s){const a=this._last;this._forming={time:s,open:a,high:a,low:a,close:a,volume:0},this._emit({type:"append",bar:{...this._forming}});return}const n=this._step(this._last);this._last=n;const o=this._forming;o.close=n,n>o.high&&(o.high=n),n<o.low&&(o.low=n),o.volume+=Math.round(20+this._rnd()*120),this._emit({type:"update",bar:{...o}})}setSpeed(t){this.speed=t}setTicksPerSecond(t){this.ticksPerSecond=t,this._timer&&(this.stop(),this._start())}setPaused(t){t?this.stop():!this._timer&&this._handlers.size&&this._start()}get paused(){return!this._timer}stop(){this._timer&&clearInterval(this._timer),this._timer=null}destroy(){this.stop(),this._handlers.clear()}}function Mt(i,t){return new K(i,t)}const kt="0.2.0";w.Chart=K,w.DataFeed=X,w.Inertia=j,w.LiveCandle=U,w.PriceScale=O,w.RandomFeed=yt,w.Smoothed=S,w.TimeScale=H,w.Tween=I,w.createChart=Mt,w.defaultTheme=P,w.easeInOutCubic=Q,w.easeOutCubic=F,w.lightTheme=tt,w.mulberry32=E,w.version=kt,Object.defineProperty(w,Symbol.toStringTag,{value:"Module"})});
2
2
  //# sourceMappingURL=emberwick.umd.js.map