UNPKG

ngx-echarts

Version:
281 lines 36.2 kB
import { Directive, EventEmitter, Inject, InjectionToken, Input, Output, } from '@angular/core'; import { Observable, Subject, asyncScheduler } from 'rxjs'; import { switchMap, throttleTime } from 'rxjs/operators'; import { ChangeFilter } from './change-filter'; import * as i0 from "@angular/core"; export const NGX_ECHARTS_CONFIG = new InjectionToken('NGX_ECHARTS_CONFIG'); export class NgxEchartsDirective { constructor(config, el, ngZone) { this.el = el; this.ngZone = ngZone; this.autoResize = true; this.loadingType = 'default'; // ngx-echarts events this.chartInit = new EventEmitter(); this.optionsError = new EventEmitter(); // echarts mouse events this.chartClick = this.createLazyEvent('click'); this.chartDblClick = this.createLazyEvent('dblclick'); this.chartMouseDown = this.createLazyEvent('mousedown'); this.chartMouseMove = this.createLazyEvent('mousemove'); this.chartMouseUp = this.createLazyEvent('mouseup'); this.chartMouseOver = this.createLazyEvent('mouseover'); this.chartMouseOut = this.createLazyEvent('mouseout'); this.chartGlobalOut = this.createLazyEvent('globalout'); this.chartContextMenu = this.createLazyEvent('contextmenu'); // echarts mouse events this.chartLegendSelectChanged = this.createLazyEvent('legendselectchanged'); this.chartLegendSelected = this.createLazyEvent('legendselected'); this.chartLegendUnselected = this.createLazyEvent('legendunselected'); this.chartLegendScroll = this.createLazyEvent('legendscroll'); this.chartDataZoom = this.createLazyEvent('datazoom'); this.chartDataRangeSelected = this.createLazyEvent('datarangeselected'); this.chartTimelineChanged = this.createLazyEvent('timelinechanged'); this.chartTimelinePlayChanged = this.createLazyEvent('timelineplaychanged'); this.chartRestore = this.createLazyEvent('restore'); this.chartDataViewChanged = this.createLazyEvent('dataviewchanged'); this.chartMagicTypeChanged = this.createLazyEvent('magictypechanged'); this.chartPieSelectChanged = this.createLazyEvent('pieselectchanged'); this.chartPieSelected = this.createLazyEvent('pieselected'); this.chartPieUnselected = this.createLazyEvent('pieunselected'); this.chartMapSelectChanged = this.createLazyEvent('mapselectchanged'); this.chartMapSelected = this.createLazyEvent('mapselected'); this.chartMapUnselected = this.createLazyEvent('mapunselected'); this.chartAxisAreaSelected = this.createLazyEvent('axisareaselected'); this.chartFocusNodeAdjacency = this.createLazyEvent('focusnodeadjacency'); this.chartUnfocusNodeAdjacency = this.createLazyEvent('unfocusnodeadjacency'); this.chartBrush = this.createLazyEvent('brush'); this.chartBrushEnd = this.createLazyEvent('brushend'); this.chartBrushSelected = this.createLazyEvent('brushselected'); this.chartRendered = this.createLazyEvent('rendered'); this.chartFinished = this.createLazyEvent('finished'); this.animationFrameID = null; this.resize$ = new Subject(); this.echarts = config.echarts; } ngOnChanges(changes) { const filter = ChangeFilter.of(changes); filter.notFirstAndEmpty('options').subscribe((opt) => this.onOptionsChange(opt)); filter.notFirstAndEmpty('merge').subscribe((opt) => this.setOption(opt)); filter.has('loading').subscribe((v) => this.toggleLoading(!!v)); filter.notFirst('theme').subscribe(() => this.refreshChart()); } ngOnInit() { if (!window.ResizeObserver) { throw new Error('please install a polyfill for ResizeObserver'); } this.resizeSub = this.resize$.pipe(throttleTime(100, asyncScheduler, { leading: false, trailing: true })).subscribe(() => this.resize()); if (this.autoResize) { this.resizeOb = this.ngZone.runOutsideAngular(() => new window.ResizeObserver(() => { this.animationFrameID = window.requestAnimationFrame(() => this.resize$.next()); })); this.resizeOb.observe(this.el.nativeElement); } } ngOnDestroy() { window.clearTimeout(this.initChartTimer); if (this.resizeSub) { this.resizeSub.unsubscribe(); } if (this.animationFrameID) { window.cancelAnimationFrame(this.animationFrameID); } if (this.resizeOb) { this.resizeOb.unobserve(this.el.nativeElement); } this.dispose(); } ngAfterViewInit() { this.initChartTimer = window.setTimeout(() => this.initChart()); } dispose() { if (this.chart) { if (!this.chart.isDisposed()) { this.chart.dispose(); } this.chart = null; } } /** * resize chart */ resize() { if (this.chart) { this.chart.resize(); } } toggleLoading(loading) { if (this.chart) { loading ? this.chart.showLoading(this.loadingType, this.loadingOpts) : this.chart.hideLoading(); } } setOption(option, opts) { if (this.chart) { try { this.chart.setOption(option, opts); } catch (e) { console.error(e); this.optionsError.emit(e); } } } /** * dispose old chart and create a new one. */ async refreshChart() { this.dispose(); await this.initChart(); } createChart() { const dom = this.el.nativeElement; if (window && window.getComputedStyle) { const prop = window.getComputedStyle(dom, null).getPropertyValue('height'); if ((!prop || prop === '0px') && (!dom.style.height || dom.style.height === '0px')) { dom.style.height = '400px'; } } // here a bit tricky: we check if the echarts module is provided as function returning native import('...') then use the promise // otherwise create the function that imitates behaviour above with a provided as is module return this.ngZone.runOutsideAngular(() => { const load = typeof this.echarts === 'function' ? this.echarts : () => Promise.resolve(this.echarts); return load().then(({ init }) => init(dom, this.theme, this.initOpts)); }); } async initChart() { await this.onOptionsChange(this.options); if (this.merge && this.chart) { this.setOption(this.merge); } } async onOptionsChange(opt) { if (!opt) { return; } if (this.chart) { this.setOption(this.options, true); } else { this.chart = await this.createChart(); this.chartInit.emit(this.chart); this.setOption(this.options, true); } } // allows to lazily bind to only those events that are requested through the `@Output` by parent components // see https://stackoverflow.com/questions/51787972/optimal-reentering-the-ngzone-from-eventemitter-event for more info createLazyEvent(eventName) { return this.chartInit.pipe(switchMap((chart) => new Observable((observer) => { chart.on(eventName, (data) => this.ngZone.run(() => observer.next(data))); return () => { if (this.chart) { if (!this.chart.isDisposed()) { chart.off(eventName); } } }; }))); } } NgxEchartsDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: NgxEchartsDirective, deps: [{ token: NGX_ECHARTS_CONFIG }, { token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive }); NgxEchartsDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.0.2", type: NgxEchartsDirective, selector: "echarts, [echarts]", inputs: { options: "options", theme: "theme", loading: "loading", initOpts: "initOpts", merge: "merge", autoResize: "autoResize", loadingType: "loadingType", loadingOpts: "loadingOpts" }, outputs: { chartInit: "chartInit", optionsError: "optionsError", chartClick: "chartClick", chartDblClick: "chartDblClick", chartMouseDown: "chartMouseDown", chartMouseMove: "chartMouseMove", chartMouseUp: "chartMouseUp", chartMouseOver: "chartMouseOver", chartMouseOut: "chartMouseOut", chartGlobalOut: "chartGlobalOut", chartContextMenu: "chartContextMenu", chartLegendSelectChanged: "chartLegendSelectChanged", chartLegendSelected: "chartLegendSelected", chartLegendUnselected: "chartLegendUnselected", chartLegendScroll: "chartLegendScroll", chartDataZoom: "chartDataZoom", chartDataRangeSelected: "chartDataRangeSelected", chartTimelineChanged: "chartTimelineChanged", chartTimelinePlayChanged: "chartTimelinePlayChanged", chartRestore: "chartRestore", chartDataViewChanged: "chartDataViewChanged", chartMagicTypeChanged: "chartMagicTypeChanged", chartPieSelectChanged: "chartPieSelectChanged", chartPieSelected: "chartPieSelected", chartPieUnselected: "chartPieUnselected", chartMapSelectChanged: "chartMapSelectChanged", chartMapSelected: "chartMapSelected", chartMapUnselected: "chartMapUnselected", chartAxisAreaSelected: "chartAxisAreaSelected", chartFocusNodeAdjacency: "chartFocusNodeAdjacency", chartUnfocusNodeAdjacency: "chartUnfocusNodeAdjacency", chartBrush: "chartBrush", chartBrushEnd: "chartBrushEnd", chartBrushSelected: "chartBrushSelected", chartRendered: "chartRendered", chartFinished: "chartFinished" }, exportAs: ["echarts"], usesOnChanges: true, ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.0.2", ngImport: i0, type: NgxEchartsDirective, decorators: [{ type: Directive, args: [{ selector: 'echarts, [echarts]', exportAs: 'echarts', }] }], ctorParameters: function () { return [{ type: undefined, decorators: [{ type: Inject, args: [NGX_ECHARTS_CONFIG] }] }, { type: i0.ElementRef }, { type: i0.NgZone }]; }, propDecorators: { options: [{ type: Input }], theme: [{ type: Input }], loading: [{ type: Input }], initOpts: [{ type: Input }], merge: [{ type: Input }], autoResize: [{ type: Input }], loadingType: [{ type: Input }], loadingOpts: [{ type: Input }], chartInit: [{ type: Output }], optionsError: [{ type: Output }], chartClick: [{ type: Output }], chartDblClick: [{ type: Output }], chartMouseDown: [{ type: Output }], chartMouseMove: [{ type: Output }], chartMouseUp: [{ type: Output }], chartMouseOver: [{ type: Output }], chartMouseOut: [{ type: Output }], chartGlobalOut: [{ type: Output }], chartContextMenu: [{ type: Output }], chartLegendSelectChanged: [{ type: Output }], chartLegendSelected: [{ type: Output }], chartLegendUnselected: [{ type: Output }], chartLegendScroll: [{ type: Output }], chartDataZoom: [{ type: Output }], chartDataRangeSelected: [{ type: Output }], chartTimelineChanged: [{ type: Output }], chartTimelinePlayChanged: [{ type: Output }], chartRestore: [{ type: Output }], chartDataViewChanged: [{ type: Output }], chartMagicTypeChanged: [{ type: Output }], chartPieSelectChanged: [{ type: Output }], chartPieSelected: [{ type: Output }], chartPieUnselected: [{ type: Output }], chartMapSelectChanged: [{ type: Output }], chartMapSelected: [{ type: Output }], chartMapUnselected: [{ type: Output }], chartAxisAreaSelected: [{ type: Output }], chartFocusNodeAdjacency: [{ type: Output }], chartUnfocusNodeAdjacency: [{ type: Output }], chartBrush: [{ type: Output }], chartBrushEnd: [{ type: Output }], chartBrushSelected: [{ type: Output }], chartRendered: [{ type: Output }], chartFinished: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWVjaGFydHMuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWVjaGFydHMvc3JjL2xpYi9uZ3gtZWNoYXJ0cy5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVMLFNBQVMsRUFFVCxZQUFZLEVBQ1osTUFBTSxFQUNOLGNBQWMsRUFDZCxLQUFLLEVBS0wsTUFBTSxHQUVQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxVQUFVLEVBQUUsT0FBTyxFQUFnQixjQUFjLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDekUsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN6RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7O0FBUy9DLE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLElBQUksY0FBYyxDQUFtQixvQkFBb0IsQ0FBQyxDQUFDO0FBTTdGLE1BQU0sT0FBTyxtQkFBbUI7SUFrRTlCLFlBQzhCLE1BQXdCLEVBQzVDLEVBQWMsRUFDZCxNQUFjO1FBRGQsT0FBRSxHQUFGLEVBQUUsQ0FBWTtRQUNkLFdBQU0sR0FBTixNQUFNLENBQVE7UUF6RGYsZUFBVSxHQUFHLElBQUksQ0FBQztRQUNsQixnQkFBVyxHQUFHLFNBQVMsQ0FBQztRQUdqQyxxQkFBcUI7UUFDWCxjQUFTLEdBQUcsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQUNwQyxpQkFBWSxHQUFHLElBQUksWUFBWSxFQUFTLENBQUM7UUFFbkQsdUJBQXVCO1FBQ2IsZUFBVSxHQUFHLElBQUksQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDM0Msa0JBQWEsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ2pELG1CQUFjLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxXQUFXLENBQUMsQ0FBQztR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Q0cscUJBQXFCO3NCQUE5QixNQUFNO2dCQUNHLGdCQUFnQjtzQkFBekIsTUFBTTtnQkFDRyxrQkFBa0I7c0JBQTNCLE1BQU07Z0JBQ0cscUJBQXFCO3NCQUE5QixNQUFNO2dCQUNHLHVCQUF1QjtzQkFBaEMsTUFBTTtnQkFDRyx5QkFBeUI7c0JBQWxDLE1BQU07Z0JBQ0csVUFBVTtzQkFBbkIsTUFBTTtnQkFDRyxhQUFhO3NCQUF0QixNQUFNO2dCQUNHLGtCQUFrQjtzQkFBM0IsTUFBTTtnQkFDRyxhQUFhO3NCQUF0QixNQUFNO2dCQUNHLGFBQWE7c0JBQXRCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBEaXJlY3RpdmUsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5qZWN0LFxuICBJbmplY3Rpb25Ub2tlbixcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgT3V0cHV0LFxuICBTaW1wbGVDaGFuZ2VzLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IE9ic2VydmFibGUsIFN1YmplY3QsIFN1YnNjcmlwdGlvbiwgYXN5bmNTY2hlZHVsZXIgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHN3aXRjaE1hcCwgdGhyb3R0bGVUaW1lIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgQ2hhbmdlRmlsdGVyIH0gZnJvbSAnLi9jaGFuZ2UtZmlsdGVyJztcbmltcG9ydCB0eXBlIHsgRUNoYXJ0c09wdGlvbiwgRUNoYXJ0cyB9IGZyb20gJ2VjaGFydHMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIE5neEVjaGFydHNDb25maWcge1xuICBlY2hhcnRzOiBhbnkgfCAoKCkgPT4gUHJvbWlzZTxhbnk+KTtcbn1cblxuZXhwb3J0IHR5cGUgVGhlbWVPcHRpb24gPSBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuXG5leHBvcnQgY29uc3QgTkdYX0VDSEFSVFNfQ09ORklHID0gbmV3IEluamVjdGlvblRva2VuPE5neEVjaGFydHNDb25maWc+KCdOR1hfRUNIQVJUU19DT05GSUcnKTtcblxuQERpcmVjdGl2ZSh7XG4gIHNlbGVjdG9yOiAnZWNoYXJ0cywgW2VjaGFydHNdJyxcbiAgZXhwb3J0QXM6ICdlY2hhcnRzJyxcbn0pXG5leHBvcnQgY2xhc3MgTmd4RWNoYXJ0c0RpcmVjdGl2ZSBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgT25EZXN0cm95LCBPbkluaXQsIEFmdGVyVmlld0luaXQge1xuICBASW5wdXQoKSBvcHRpb25zOiBFQ2hhcnRzT3B0aW9uO1xuICBASW5wdXQoKSB0aGVtZTogc3RyaW5nIHwgVGhlbWVPcHRpb247XG4gIEBJbnB1dCgpIGxvYWRpbmc6IGJvb2xlYW47XG4gIEBJbnB1dCgpIGluaXRPcHRzOiB7XG4gICAgZGV2aWNlUGl4ZWxSYXRpbz86IG51bWJlcjtcbiAgICByZW5kZXJlcj86IHN0cmluZztcbiAgICB3aWR0aD86IG51bWJlciB8IHN0cmluZztcbiAgICBoZWlnaHQ/OiBudW1iZXIgfCBzdHJpbmc7XG4gICAgbG9jYWxlPzogc3RyaW5nO1xuICB9O1xuICBASW5wdXQoKSBtZXJnZTogRUNoYXJ0c09wdGlvbjtcbiAgQElucHV0KCkgYXV0b1Jlc2l6ZSA9IHRydWU7XG4gIEBJbnB1dCgpIGxvYWRpbmdUeXBlID0gJ2RlZmF1bHQnO1xuICBASW5wdXQoKSBsb2FkaW5nT3B0czogb2JqZWN0O1xuXG4gIC8vIG5neC1lY2hhcnRzIGV2ZW50c1xuICBAT3V0cHV0KCkgY2hhcnRJbml0ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gIEBPdXRwdXQoKSBvcHRpb25zRXJyb3IgPSBuZXcgRXZlbnRFbWl0dGVyPEVycm9yPigpO1xuXG4gIC8vIGVjaGFydHMgbW91c2UgZXZlbnRzXG4gIEBPdXRwdXQoKSBjaGFydENsaWNrID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ2NsaWNrJyk7XG4gIEBPdXRwdXQoKSBjaGFydERibENsaWNrID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ2RibGNsaWNrJyk7XG4gIEBPdXRwdXQoKSBjaGFydE1vdXNlRG93biA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCdtb3VzZWRvd24nKTtcbiAgQE91dHB1dCgpIGNoYXJ0TW91c2VNb3ZlID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ21vdXNlbW92ZScpO1xuICBAT3V0cHV0KCkgY2hhcnRNb3VzZVVwID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ21vdXNldXAnKTtcbiAgQE91dHB1dCgpIGNoYXJ0TW91c2VPdmVyID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ21vdXNlb3ZlcicpO1xuICBAT3V0cHV0KCkgY2hhcnRNb3VzZU91dCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCdtb3VzZW91dCcpO1xuICBAT3V0cHV0KCkgY2hhcnRHbG9iYWxPdXQgPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgnZ2xvYmFsb3V0Jyk7XG4gIEBPdXRwdXQoKSBjaGFydENvbnRleHRNZW51ID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ2NvbnRleHRtZW51Jyk7XG5cbiAgLy8gZWNoYXJ0cyBtb3VzZSBldmVudHNcbiAgQE91dHB1dCgpIGNoYXJ0TGVnZW5kU2VsZWN0Q2hhbmdlZCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCdsZWdlbmRzZWxlY3RjaGFuZ2VkJyk7XG4gIEBPdXRwdXQoKSBjaGFydExlZ2VuZFNlbGVjdGVkID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ2xlZ2VuZHNlbGVjdGVkJyk7XG4gIEBPdXRwdXQoKSBjaGFydExlZ2VuZFVuc2VsZWN0ZWQgPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgnbGVnZW5kdW5zZWxlY3RlZCcpO1xuICBAT3V0cHV0KCkgY2hhcnRMZWdlbmRTY3JvbGwgPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgnbGVnZW5kc2Nyb2xsJyk7XG4gIEBPdXRwdXQoKSBjaGFydERhdGFab29tID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ2RhdGF6b29tJyk7XG4gIEBPdXRwdXQoKSBjaGFydERhdGFSYW5nZVNlbGVjdGVkID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ2RhdGFyYW5nZXNlbGVjdGVkJyk7XG4gIEBPdXRwdXQoKSBjaGFydFRpbWVsaW5lQ2hhbmdlZCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCd0aW1lbGluZWNoYW5nZWQnKTtcbiAgQE91dHB1dCgpIGNoYXJ0VGltZWxpbmVQbGF5Q2hhbmdlZCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCd0aW1lbGluZXBsYXljaGFuZ2VkJyk7XG4gIEBPdXRwdXQoKSBjaGFydFJlc3RvcmUgPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgncmVzdG9yZScpO1xuICBAT3V0cHV0KCkgY2hhcnREYXRhVmlld0NoYW5nZWQgPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgnZGF0YXZpZXdjaGFuZ2VkJyk7XG4gIEBPdXRwdXQoKSBjaGFydE1hZ2ljVHlwZUNoYW5nZWQgPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgnbWFnaWN0eXBlY2hhbmdlZCcpO1xuICBAT3V0cHV0KCkgY2hhcnRQaWVTZWxlY3RDaGFuZ2VkID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ3BpZXNlbGVjdGNoYW5nZWQnKTtcbiAgQE91dHB1dCgpIGNoYXJ0UGllU2VsZWN0ZWQgPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgncGllc2VsZWN0ZWQnKTtcbiAgQE91dHB1dCgpIGNoYXJ0UGllVW5zZWxlY3RlZCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCdwaWV1bnNlbGVjdGVkJyk7XG4gIEBPdXRwdXQoKSBjaGFydE1hcFNlbGVjdENoYW5nZWQgPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgnbWFwc2VsZWN0Y2hhbmdlZCcpO1xuICBAT3V0cHV0KCkgY2hhcnRNYXBTZWxlY3RlZCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCdtYXBzZWxlY3RlZCcpO1xuICBAT3V0cHV0KCkgY2hhcnRNYXBVbnNlbGVjdGVkID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ21hcHVuc2VsZWN0ZWQnKTtcbiAgQE91dHB1dCgpIGNoYXJ0QXhpc0FyZWFTZWxlY3RlZCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCdheGlzYXJlYXNlbGVjdGVkJyk7XG4gIEBPdXRwdXQoKSBjaGFydEZvY3VzTm9kZUFkamFjZW5jeSA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCdmb2N1c25vZGVhZGphY2VuY3knKTtcbiAgQE91dHB1dCgpIGNoYXJ0VW5mb2N1c05vZGVBZGphY2VuY3kgPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgndW5mb2N1c25vZGVhZGphY2VuY3knKTtcbiAgQE91dHB1dCgpIGNoYXJ0QnJ1c2ggPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgnYnJ1c2gnKTtcbiAgQE91dHB1dCgpIGNoYXJ0QnJ1c2hFbmQgPSB0aGlzLmNyZWF0ZUxhenlFdmVudCgnYnJ1c2hlbmQnKTtcbiAgQE91dHB1dCgpIGNoYXJ0QnJ1c2hTZWxlY3RlZCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50KCdicnVzaHNlbGVjdGVkJyk7XG4gIEBPdXRwdXQoKSBjaGFydFJlbmRlcmVkID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ3JlbmRlcmVkJyk7XG4gIEBPdXRwdXQoKSBjaGFydEZpbmlzaGVkID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQoJ2ZpbmlzaGVkJyk7XG5cbiAgcHVibGljIGFuaW1hdGlvbkZyYW1lSUQgPSBudWxsO1xuICBwcml2YXRlIGNoYXJ0OiBFQ2hhcnRzO1xuICBwcml2YXRlIGVjaGFydHM6IGFueTtcbiAgcHJpdmF0ZSByZXNpemVPYjogUmVzaXplT2JzZXJ2ZXI7XG4gIHByaXZhdGUgcmVzaXplJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIHByaXZhdGUgcmVzaXplU3ViOiBTdWJzY3JpcHRpb247XG4gIHByaXZhdGUgaW5pdENoYXJ0VGltZXI/OiBudW1iZXI7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgQEluamVjdChOR1hfRUNIQVJUU19DT05GSUcpIGNvbmZpZzogTmd4RWNoYXJ0c0NvbmZpZyxcbiAgICBwcml2YXRlIGVsOiBFbGVtZW50UmVmLFxuICAgIHByaXZhdGUgbmdab25lOiBOZ1pvbmUsXG4gICkge1xuICAgIHRoaXMuZWNoYXJ0cyA9IGNvbmZpZy5lY2hhcnRzO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xuICAgIGNvbnN0IGZpbHRlciA9IENoYW5nZUZpbHRlci5vZihjaGFuZ2VzKTtcbiAgICBmaWx0ZXIubm90Rmlyc3RBbmRFbXB0eTxhbnk+KCdvcHRpb25zJykuc3Vic2NyaWJlKChvcHQpID0+IHRoaXMub25PcHRpb25zQ2hhbmdlKG9wdCkpO1xuICAgIGZpbHRlci5ub3RGaXJzdEFuZEVtcHR5PGFueT4oJ21lcmdlJykuc3Vic2NyaWJlKChvcHQpID0+IHRoaXMuc2V0T3B0aW9uKG9wdCkpO1xuICAgIGZpbHRlci5oYXM8Ym9vbGVhbj4oJ2xvYWRpbmcnKS5zdWJzY3JpYmUoKHYpID0+IHRoaXMudG9nZ2xlTG9hZGluZyghIXYpKTtcbiAgICBmaWx0ZXIubm90Rmlyc3Q8c3RyaW5nIHwgVGhlbWVPcHRpb24+KCd0aGVtZScpLnN1YnNjcmliZSgoKSA9PiB0aGlzLnJlZnJlc2hDaGFydCgpKTtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIGlmICghd2luZG93LlJlc2l6ZU9ic2VydmVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3BsZWFzZSBpbnN0YWxsIGEgcG9seWZpbGwgZm9yIFJlc2l6ZU9ic2VydmVyJyk7XG4gICAgfVxuICAgIHRoaXMucmVzaXplU3ViID0gdGhpcy5yZXNpemUkLnBpcGUoXG4gICAgICB0aHJvdHRsZVRpbWUoMTAwLCBhc3luY1NjaGVkdWxlciwgeyBsZWFkaW5nOiBmYWxzZSwgdHJhaWxpbmc6IHRydWUgfSlcbiAgICApLnN1YnNjcmliZSgoKSA9PiB0aGlzLnJlc2l6ZSgpKVxuXG4gICAgaWYgKHRoaXMuYXV0b1Jlc2l6ZSkge1xuICAgICAgdGhpcy5yZXNpemVPYiA9IHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IG5ldyB3aW5kb3cuUmVzaXplT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgICB0aGlzLmFuaW1hdGlvbkZyYW1lSUQgPSB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHRoaXMucmVzaXplJC5uZXh0KCkpXG4gICAgICB9KSlcbiAgICAgIHRoaXMucmVzaXplT2Iub2JzZXJ2ZSh0aGlzLmVsLm5hdGl2ZUVsZW1lbnQpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHdpbmRvdy5jbGVhclRpbWVvdXQodGhpcy5pbml0Q2hhcnRUaW1lcik7XG4gICAgaWYgKHRoaXMucmVzaXplU3ViKSB7XG4gICAgICB0aGlzLnJlc2l6ZVN1Yi51bnN1YnNjcmliZSgpXG4gICAgfVxuICAgIGlmICh0aGlzLmFuaW1hdGlvbkZyYW1lSUQpIHtcbiAgICAgIHdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLmFuaW1hdGlvbkZyYW1lSUQpO1xuICAgIH1cbiAgICBpZiAodGhpcy5yZXNpemVPYikge1xuICAgICAgdGhpcy5yZXNpemVPYi51bm9ic2VydmUodGhpcy5lbC5uYXRpdmVFbGVtZW50KTtcbiAgICB9XG4gICAgdGhpcy5kaXNwb3NlKCk7XG4gIH1cblxuICBuZ0FmdGVyVmlld0luaXQoKSB7XG4gICAgdGhpcy5pbml0Q2hhcnRUaW1lciA9IHdpbmRvdy5zZXRUaW1lb3V0KCgpID0+IHRoaXMuaW5pdENoYXJ0KCkpO1xuICB9XG5cbiAgcHJpdmF0ZSBkaXNwb3NlKCkge1xuICAgIGlmICh0aGlzLmNoYXJ0KSB7XG4gICAgICBpZiAoIXRoaXMuY2hhcnQuaXNEaXNwb3NlZCgpKSB7XG4gICAgICAgIHRoaXMuY2hhcnQuZGlzcG9zZSgpO1xuICAgICAgfVxuICAgICAgdGhpcy5jaGFydCA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIHJlc2l6ZSBjaGFydFxuICAgKi9cbiAgcmVzaXplKCkge1xuICAgIGlmICh0aGlzLmNoYXJ0KSB7XG4gICAgICB0aGlzLmNoYXJ0LnJlc2l6ZSgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdG9nZ2xlTG9hZGluZyhsb2FkaW5nOiBib29sZWFuKSB7XG4gICAgaWYgKHRoaXMuY2hhcnQpIHtcbiAgICAgIGxvYWRpbmdcbiAgICAgICAgPyB0aGlzLmNoYXJ0LnNob3dMb2FkaW5nKHRoaXMubG9hZGluZ1R5cGUsIHRoaXMubG9hZGluZ09wdHMpXG4gICAgICAgIDogdGhpcy5jaGFydC5oaWRlTG9hZGluZygpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2V0T3B0aW9uKG9wdGlvbjogYW55LCBvcHRzPzogYW55KSB7XG4gICAgaWYgKHRoaXMuY2hhcnQpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRoaXMuY2hhcnQuc2V0T3B0aW9uKG9wdGlvbiwgb3B0cyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgIHRoaXMub3B0aW9uc0Vycm9yLmVtaXQoZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIGRpc3Bvc2Ugb2xkIGNoYXJ0IGFuZCBjcmVhdGUgYSBuZXcgb25lLlxuICAgKi9cbiAgYXN5bmMgcmVmcmVzaENoYXJ0KCkge1xuICAgIHRoaXMuZGlzcG9zZSgpO1xuICAgIGF3YWl0IHRoaXMuaW5pdENoYXJ0KCk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUNoYXJ0KCkge1xuICAgIGNvbnN0IGRvbSA9IHRoaXMuZWwubmF0aXZlRWxlbWVudDtcblxuICAgIGlmICh3aW5kb3cgJiYgd2luZG93LmdldENvbXB1dGVkU3R5bGUpIHtcbiAgICAgIGNvbnN0IHByb3AgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShkb20sIG51bGwpLmdldFByb3BlcnR5VmFsdWUoJ2hlaWdodCcpO1xuICAgICAgaWYgKCghcHJvcCB8fCBwcm9wID09PSAnMHB4JykgJiYgKCFkb20uc3R5bGUuaGVpZ2h0IHx8IGRvbS5zdHlsZS5oZWlnaHQgPT09ICcwcHgnKSkge1xuICAgICAgICBkb20uc3R5bGUuaGVpZ2h0ID0gJzQwMHB4JztcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBoZXJlIGEgYml0IHRyaWNreTogd2UgY2hlY2sgaWYgdGhlIGVjaGFydHMgbW9kdWxlIGlzIHByb3ZpZGVkIGFzIGZ1bmN0aW9uIHJldHVybmluZyBuYXRpdmUgaW1wb3J0KCcuLi4nKSB0aGVuIHVzZSB0aGUgcHJvbWlzZVxuICAgIC8vIG90aGVyd2lzZSBjcmVhdGUgdGhlIGZ1bmN0aW9uIHRoYXQgaW1pdGF0ZXMgYmVoYXZpb3VyIGFib3ZlIHdpdGggYSBwcm92aWRlZCBhcyBpcyBtb2R1bGVcbiAgICByZXR1cm4gdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgY29uc3QgbG9hZCA9XG4gICAgICAgIHR5cGVvZiB0aGlzLmVjaGFydHMgPT09ICdmdW5jdGlvbicgPyB0aGlzLmVjaGFydHMgOiAoKSA9PiBQcm9taXNlLnJlc29sdmUodGhpcy5lY2hhcnRzKTtcblxuICAgICAgcmV0dXJuIGxvYWQoKS50aGVuKCh7IGluaXQgfSkgPT4gaW5pdChkb20sIHRoaXMudGhlbWUsIHRoaXMuaW5pdE9wdHMpKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaW5pdENoYXJ0KCkge1xuICAgIGF3YWl0IHRoaXMub25PcHRpb25zQ2hhbmdlKHRoaXMub3B0aW9ucyk7XG5cbiAgICBpZiAodGhpcy5tZXJnZSAmJiB0aGlzLmNoYXJ0KSB7XG4gICAgICB0aGlzLnNldE9wdGlvbih0aGlzLm1lcmdlKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIG9uT3B0aW9uc0NoYW5nZShvcHQ6IGFueSkge1xuICAgIGlmICghb3B0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY2hhcnQpIHtcbiAgICAgIHRoaXMuc2V0T3B0aW9uKHRoaXMub3B0aW9ucywgdHJ1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY2hhcnQgPSBhd2FpdCB0aGlzLmNyZWF0ZUNoYXJ0KCk7XG4gICAgICB0aGlzLmNoYXJ0SW5pdC5lbWl0KHRoaXMuY2hhcnQpO1xuICAgICAgdGhpcy5zZXRPcHRpb24odGhpcy5vcHRpb25zLCB0cnVlKTtcbiAgICB9XG4gIH1cblxuICAvLyBhbGxvd3MgdG8gbGF6aWx5IGJpbmQgdG8gb25seSB0aG9zZSBldmVudHMgdGhhdCBhcmUgcmVxdWVzdGVkIHRocm91Z2ggdGhlIGBAT3V0cHV0YCBieSBwYXJlbnQgY29tcG9uZW50c1xuICAvLyBzZWUgaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNTE3ODc5NzIvb3B0aW1hbC1yZWVudGVyaW5nLXRoZS1uZ3pvbmUtZnJvbS1ldmVudGVtaXR0ZXItZXZlbnQgZm9yIG1vcmUgaW5mb1xuICBwcml2YXRlIGNyZWF0ZUxhenlFdmVudDxUPihldmVudE5hbWU6IHN0cmluZyk6IEV2ZW50RW1pdHRlcjxUPiB7XG4gICAgcmV0dXJuIHRoaXMuY2hhcnRJbml0LnBpcGUoXG4gICAgICBzd2l0Y2hNYXAoXG4gICAgICAgIChjaGFydDogYW55KSA9PlxuICAgICAgICAgIG5ldyBPYnNlcnZhYmxlKChvYnNlcnZlcikgPT4ge1xuICAgICAgICAgICAgY2hhcnQub24oZXZlbnROYW1lLCAoZGF0YTogVCkgPT4gdGhpcy5uZ1pvbmUucnVuKCgpID0+IG9ic2VydmVyLm5leHQoZGF0YSkpKTtcbiAgICAgICAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgICAgICAgIGlmICh0aGlzLmNoYXJ0KSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmNoYXJ0LmlzRGlzcG9zZWQoKSkge1xuICAgICAgICAgICAgICAgICAgY2hhcnQub2ZmKGV2ZW50TmFtZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH0pLFxuICAgICAgKSxcbiAgICApIGFzIEV2ZW50RW1pdHRlcjxUPjtcbiAgfVxufVxuIl19