UNPKG

40.3 kBJavaScriptView Raw
1import { Directive, EventEmitter, Inject, InjectionToken, Input, Output, } from '@angular/core';
2import { Observable, ReplaySubject, Subject, asyncScheduler } from 'rxjs';
3import { switchMap, throttleTime } from 'rxjs/operators';
4import { ChangeFilterV2 } from './change-filter-v2';
5import * as i0 from "@angular/core";
6export const NGX_ECHARTS_CONFIG = new InjectionToken('NGX_ECHARTS_CONFIG');
7export class NgxEchartsDirective {
8 constructor(config, el, ngZone) {
9 this.el = el;
10 this.ngZone = ngZone;
11 this.options = null;
12 this.theme = null;
13 this.initOpts = null;
14 this.merge = null;
15 this.autoResize = true;
16 this.loading = false;
17 this.loadingType = 'default';
18 this.loadingOpts = null;
19 // ngx-echarts events
20 this.chartInit = new EventEmitter();
21 this.optionsError = new EventEmitter();
22 // echarts mouse events
23 this.chartClick = this.createLazyEvent('click');
24 this.chartDblClick = this.createLazyEvent('dblclick');
25 this.chartMouseDown = this.createLazyEvent('mousedown');
26 this.chartMouseMove = this.createLazyEvent('mousemove');
27 this.chartMouseUp = this.createLazyEvent('mouseup');
28 this.chartMouseOver = this.createLazyEvent('mouseover');
29 this.chartMouseOut = this.createLazyEvent('mouseout');
30 this.chartGlobalOut = this.createLazyEvent('globalout');
31 this.chartContextMenu = this.createLazyEvent('contextmenu');
32 // echarts events
33 this.chartHighlight = this.createLazyEvent('highlight');
34 this.chartDownplay = this.createLazyEvent('downplay');
35 this.chartSelectChanged = this.createLazyEvent('selectchanged');
36 this.chartLegendSelectChanged = this.createLazyEvent('legendselectchanged');
37 this.chartLegendSelected = this.createLazyEvent('legendselected');
38 this.chartLegendUnselected = this.createLazyEvent('legendunselected');
39 this.chartLegendLegendSelectAll = this.createLazyEvent('legendselectall');
40 this.chartLegendLegendInverseSelect = this.createLazyEvent('legendinverseselect');
41 this.chartLegendScroll = this.createLazyEvent('legendscroll');
42 this.chartDataZoom = this.createLazyEvent('datazoom');
43 this.chartDataRangeSelected = this.createLazyEvent('datarangeselected');
44 this.chartGraphRoam = this.createLazyEvent('graphroam');
45 this.chartGeoRoam = this.createLazyEvent('georoam');
46 this.chartTreeRoam = this.createLazyEvent('treeroam');
47 this.chartTimelineChanged = this.createLazyEvent('timelinechanged');
48 this.chartTimelinePlayChanged = this.createLazyEvent('timelineplaychanged');
49 this.chartRestore = this.createLazyEvent('restore');
50 this.chartDataViewChanged = this.createLazyEvent('dataviewchanged');
51 this.chartMagicTypeChanged = this.createLazyEvent('magictypechanged');
52 this.chartGeoSelectChanged = this.createLazyEvent('geoselectchanged');
53 this.chartGeoSelected = this.createLazyEvent('geoselected');
54 this.chartGeoUnselected = this.createLazyEvent('geounselected');
55 this.chartAxisAreaSelected = this.createLazyEvent('axisareaselected');
56 this.chartBrush = this.createLazyEvent('brush');
57 this.chartBrushEnd = this.createLazyEvent('brushend');
58 this.chartBrushSelected = this.createLazyEvent('brushselected');
59 this.chartGlobalCursorTaken = this.createLazyEvent('globalcursortaken');
60 this.chartRendered = this.createLazyEvent('rendered');
61 this.chartFinished = this.createLazyEvent('finished');
62 this.animationFrameID = null;
63 this.chart$ = new ReplaySubject(1);
64 this.resize$ = new Subject();
65 this.changeFilter = new ChangeFilterV2();
66 this.echarts = config.echarts;
67 }
68 ngOnChanges(changes) {
69 this.changeFilter.doFilter(changes);
70 }
71 ngOnInit() {
72 if (!window.ResizeObserver) {
73 throw new Error('please install a polyfill for ResizeObserver');
74 }
75 this.resizeSub = this.resize$
76 .pipe(throttleTime(100, asyncScheduler, { leading: false, trailing: true }))
77 .subscribe(() => this.resize());
78 if (this.autoResize) {
79 this.resizeOb = this.ngZone.runOutsideAngular(() => new window.ResizeObserver(() => {
80 this.animationFrameID = window.requestAnimationFrame(() => this.resize$.next());
81 }));
82 this.resizeOb.observe(this.el.nativeElement);
83 }
84 this.changeFilter.notFirstAndEmpty('options', opt => this.onOptionsChange(opt));
85 this.changeFilter.notFirstAndEmpty('merge', opt => this.setOption(opt));
86 this.changeFilter.has('loading', v => this.toggleLoading(!!v));
87 this.changeFilter.notFirst('theme', () => this.refreshChart());
88 }
89 ngOnDestroy() {
90 window.clearTimeout(this.initChartTimer);
91 if (this.resizeSub) {
92 this.resizeSub.unsubscribe();
93 }
94 if (this.animationFrameID) {
95 window.cancelAnimationFrame(this.animationFrameID);
96 }
97 if (this.resizeOb) {
98 this.resizeOb.unobserve(this.el.nativeElement);
99 }
100 if (this.loadingSub) {
101 this.loadingSub.unsubscribe();
102 }
103 this.changeFilter.dispose();
104 this.dispose();
105 }
106 ngAfterViewInit() {
107 this.initChartTimer = window.setTimeout(() => this.initChart());
108 }
109 dispose() {
110 if (this.chart) {
111 if (!this.chart.isDisposed()) {
112 this.chart.dispose();
113 }
114 this.chart = null;
115 }
116 }
117 /**
118 * resize chart
119 */
120 resize() {
121 if (this.chart) {
122 this.chart.resize();
123 }
124 }
125 toggleLoading(loading) {
126 if (this.chart) {
127 loading
128 ? this.chart.showLoading(this.loadingType, this.loadingOpts)
129 : this.chart.hideLoading();
130 }
131 else {
132 this.loadingSub = this.chart$.subscribe(chart => loading ? chart.showLoading(this.loadingType, this.loadingOpts) : chart.hideLoading());
133 }
134 }
135 setOption(option, opts) {
136 if (this.chart) {
137 try {
138 this.chart.setOption(option, opts);
139 }
140 catch (e) {
141 console.error(e);
142 this.optionsError.emit(e);
143 }
144 }
145 }
146 /**
147 * dispose old chart and create a new one.
148 */
149 async refreshChart() {
150 this.dispose();
151 await this.initChart();
152 }
153 createChart() {
154 const dom = this.el.nativeElement;
155 if (window && window.getComputedStyle) {
156 const prop = window.getComputedStyle(dom, null).getPropertyValue('height');
157 if ((!prop || prop === '0px') && (!dom.style.height || dom.style.height === '0px')) {
158 dom.style.height = '400px';
159 }
160 }
161 // here a bit tricky: we check if the echarts module is provided as function returning native import('...') then use the promise
162 // otherwise create the function that imitates behaviour above with a provided as is module
163 return this.ngZone.runOutsideAngular(() => {
164 const load = typeof this.echarts === 'function' ? this.echarts : () => Promise.resolve(this.echarts);
165 return load().then(({ init }) => init(dom, this.theme, this.initOpts));
166 });
167 }
168 async initChart() {
169 await this.onOptionsChange(this.options);
170 if (this.merge && this.chart) {
171 this.setOption(this.merge);
172 }
173 }
174 async onOptionsChange(opt) {
175 if (!opt) {
176 return;
177 }
178 if (this.chart) {
179 this.setOption(this.options, true);
180 }
181 else {
182 this.chart = await this.createChart();
183 this.chart$.next(this.chart);
184 this.chartInit.emit(this.chart);
185 this.setOption(this.options, true);
186 }
187 }
188 // allows to lazily bind to only those events that are requested through the `@Output` by parent components
189 // see https://stackoverflow.com/questions/51787972/optimal-reentering-the-ngzone-from-eventemitter-event for more info
190 createLazyEvent(eventName) {
191 return this.chartInit.pipe(switchMap((chart) => new Observable(observer => {
192 chart.on(eventName, (data) => this.ngZone.run(() => observer.next(data)));
193 return () => {
194 if (this.chart) {
195 if (!this.chart.isDisposed()) {
196 chart.off(eventName);
197 }
198 }
199 };
200 })));
201 }
202 static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: NgxEchartsDirective, deps: [{ token: NGX_ECHARTS_CONFIG }, { token: i0.ElementRef }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Directive }); }
203 static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.0.1", type: NgxEchartsDirective, isStandalone: true, selector: "echarts, [echarts]", inputs: { options: "options", theme: "theme", initOpts: "initOpts", merge: "merge", autoResize: "autoResize", loading: "loading", 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", chartHighlight: "chartHighlight", chartDownplay: "chartDownplay", chartSelectChanged: "chartSelectChanged", chartLegendSelectChanged: "chartLegendSelectChanged", chartLegendSelected: "chartLegendSelected", chartLegendUnselected: "chartLegendUnselected", chartLegendLegendSelectAll: "chartLegendLegendSelectAll", chartLegendLegendInverseSelect: "chartLegendLegendInverseSelect", chartLegendScroll: "chartLegendScroll", chartDataZoom: "chartDataZoom", chartDataRangeSelected: "chartDataRangeSelected", chartGraphRoam: "chartGraphRoam", chartGeoRoam: "chartGeoRoam", chartTreeRoam: "chartTreeRoam", chartTimelineChanged: "chartTimelineChanged", chartTimelinePlayChanged: "chartTimelinePlayChanged", chartRestore: "chartRestore", chartDataViewChanged: "chartDataViewChanged", chartMagicTypeChanged: "chartMagicTypeChanged", chartGeoSelectChanged: "chartGeoSelectChanged", chartGeoSelected: "chartGeoSelected", chartGeoUnselected: "chartGeoUnselected", chartAxisAreaSelected: "chartAxisAreaSelected", chartBrush: "chartBrush", chartBrushEnd: "chartBrushEnd", chartBrushSelected: "chartBrushSelected", chartGlobalCursorTaken: "chartGlobalCursorTaken", chartRendered: "chartRendered", chartFinished: "chartFinished" }, exportAs: ["echarts"], usesOnChanges: true, ngImport: i0 }); }
204}
205i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.1", ngImport: i0, type: NgxEchartsDirective, decorators: [{
206 type: Directive,
207 args: [{
208 standalone: true,
209 selector: 'echarts, [echarts]',
210 exportAs: 'echarts',
211 }]
212 }], ctorParameters: () => [{ type: undefined, decorators: [{
213 type: Inject,
214 args: [NGX_ECHARTS_CONFIG]
215 }] }, { type: i0.ElementRef }, { type: i0.NgZone }], propDecorators: { options: [{
216 type: Input
217 }], theme: [{
218 type: Input
219 }], initOpts: [{
220 type: Input
221 }], merge: [{
222 type: Input
223 }], autoResize: [{
224 type: Input
225 }], loading: [{
226 type: Input
227 }], loadingType: [{
228 type: Input
229 }], loadingOpts: [{
230 type: Input
231 }], chartInit: [{
232 type: Output
233 }], optionsError: [{
234 type: Output
235 }], chartClick: [{
236 type: Output
237 }], chartDblClick: [{
238 type: Output
239 }], chartMouseDown: [{
240 type: Output
241 }], chartMouseMove: [{
242 type: Output
243 }], chartMouseUp: [{
244 type: Output
245 }], chartMouseOver: [{
246 type: Output
247 }], chartMouseOut: [{
248 type: Output
249 }], chartGlobalOut: [{
250 type: Output
251 }], chartContextMenu: [{
252 type: Output
253 }], chartHighlight: [{
254 type: Output
255 }], chartDownplay: [{
256 type: Output
257 }], chartSelectChanged: [{
258 type: Output
259 }], chartLegendSelectChanged: [{
260 type: Output
261 }], chartLegendSelected: [{
262 type: Output
263 }], chartLegendUnselected: [{
264 type: Output
265 }], chartLegendLegendSelectAll: [{
266 type: Output
267 }], chartLegendLegendInverseSelect: [{
268 type: Output
269 }], chartLegendScroll: [{
270 type: Output
271 }], chartDataZoom: [{
272 type: Output
273 }], chartDataRangeSelected: [{
274 type: Output
275 }], chartGraphRoam: [{
276 type: Output
277 }], chartGeoRoam: [{
278 type: Output
279 }], chartTreeRoam: [{
280 type: Output
281 }], chartTimelineChanged: [{
282 type: Output
283 }], chartTimelinePlayChanged: [{
284 type: Output
285 }], chartRestore: [{
286 type: Output
287 }], chartDataViewChanged: [{
288 type: Output
289 }], chartMagicTypeChanged: [{
290 type: Output
291 }], chartGeoSelectChanged: [{
292 type: Output
293 }], chartGeoSelected: [{
294 type: Output
295 }], chartGeoUnselected: [{
296 type: Output
297 }], chartAxisAreaSelected: [{
298 type: Output
299 }], chartBrush: [{
300 type: Output
301 }], chartBrushEnd: [{
302 type: Output
303 }], chartBrushSelected: [{
304 type: Output
305 }], chartGlobalCursorTaken: [{
306 type: Output
307 }], chartRendered: [{
308 type: Output
309 }], chartFinished: [{
310 type: Output
311 }] } });
312//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWVjaGFydHMuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWVjaGFydHMvc3JjL2xpYi9uZ3gtZWNoYXJ0cy5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUVMLFNBQVMsRUFFVCxZQUFZLEVBQ1osTUFBTSxFQUNOLGNBQWMsRUFDZCxLQUFLLEVBS0wsTUFBTSxHQUVQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxVQUFVLEVBQUUsYUFBYSxFQUFFLE9BQU8sRUFBZ0IsY0FBYyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3hGLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDekQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG9CQUFvQixDQUFDOztBQVNwRCxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLGNBQWMsQ0FBbUIsb0JBQW9CLENBQUMsQ0FBQztBQU83RixNQUFNLE9BQU8sbUJBQW1CO0lBeUU5QixZQUM4QixNQUF3QixFQUM1QyxFQUFjLEVBQ2QsTUFBYztRQURkLE9BQUUsR0FBRixFQUFFLENBQVk7UUFDZCxXQUFNLEdBQU4sTUFBTSxDQUFRO1FBM0VmLFlBQU8sR0FBeUIsSUFBSSxDQUFDO1FBQ3JDLFVBQUssR0FBZ0MsSUFBSSxDQUFDO1FBQzFDLGFBQVEsR0FNTixJQUFJLENBQUM7UUFDUCxVQUFLLEdBQXlCLElBQUksQ0FBQztRQUNuQyxlQUFVLEdBQUcsSUFBSSxDQUFDO1FBQ2xCLFlBQU8sR0FBRyxLQUFLLENBQUM7UUFDaEIsZ0JBQVcsR0FBRyxTQUFTLENBQUM7UUFDeEIsZ0JBQVcsR0FBa0IsSUFBSSxDQUFDO1FBRTNDLHFCQUFxQjtRQUNYLGNBQVMsR0FBRyxJQUFJLFlBQVksRUFBTyxDQUFDO1FBQ3BDLGlCQUFZLEdBQUcsSUFBSSxZQUFZLEVBQVMsQ0FB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Z0JBQ0csb0JBQW9CO3NCQUE3QixNQUFNO2dCQUNHLHFCQUFxQjtzQkFBOUIsTUFBTTtnQkFDRyxxQkFBcUI7c0JBQTlCLE1BQU07Z0JBQ0csZ0JBQWdCO3NCQUF6QixNQUFNO2dCQUNHLGtCQUFrQjtzQkFBM0IsTUFBTTtnQkFDRyxxQkFBcUI7c0JBQTlCLE1BQU07Z0JBQ0csVUFBVTtzQkFBbkIsTUFBTTtnQkFDRyxhQUFhO3NCQUF0QixNQUFNO2dCQUNHLGtCQUFrQjtzQkFBM0IsTUFBTTtnQkFDRyxzQkFBc0I7c0JBQS9CLE1BQU07Z0JBQ0csYUFBYTtzQkFBdEIsTUFBTTtnQkFDRyxhQUFhO3NCQUF0QixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgRGlyZWN0aXZlLFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEluamVjdCxcbiAgSW5qZWN0aW9uVG9rZW4sXG4gIElucHV0LFxuICBOZ1pvbmUsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlcyxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBSZXBsYXlTdWJqZWN0LCBTdWJqZWN0LCBTdWJzY3JpcHRpb24sIGFzeW5jU2NoZWR1bGVyIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBzd2l0Y2hNYXAsIHRocm90dGxlVGltZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IENoYW5nZUZpbHRlclYyIH0gZnJvbSAnLi9jaGFuZ2UtZmlsdGVyLXYyJztcbmltcG9ydCB0eXBlIHsgRUNoYXJ0c09wdGlvbiwgRUNoYXJ0cywgRUNFbGVtZW50RXZlbnQgfSBmcm9tICdlY2hhcnRzJztcblxuZXhwb3J0IGludGVyZmFjZSBOZ3hFY2hhcnRzQ29uZmlnIHtcbiAgZWNoYXJ0czogYW55IHwgKCgpID0+IFByb21pc2U8YW55Pik7XG59XG5cbmV4cG9ydCB0eXBlIFRoZW1lT3B0aW9uID0gUmVjb3JkPHN0cmluZywgYW55PjtcblxuZXhwb3J0IGNvbnN0IE5HWF9FQ0hBUlRTX0NPTkZJRyA9IG5ldyBJbmplY3Rpb25Ub2tlbjxOZ3hFY2hhcnRzQ29uZmlnPignTkdYX0VDSEFSVFNfQ09ORklHJyk7XG5cbkBEaXJlY3RpdmUoe1xuICBzdGFuZGFsb25lOiB0cnVlLFxuICBzZWxlY3RvcjogJ2VjaGFydHMsIFtlY2hhcnRzXScsXG4gIGV4cG9ydEFzOiAnZWNoYXJ0cycsXG59KVxuZXhwb3J0IGNsYXNzIE5neEVjaGFydHNEaXJlY3RpdmUgaW1wbGVtZW50cyBPbkNoYW5nZXMsIE9uRGVzdHJveSwgT25Jbml0LCBBZnRlclZpZXdJbml0IHtcbiAgQElucHV0KCkgb3B0aW9uczogRUNoYXJ0c09wdGlvbiB8IG51bGwgPSBudWxsO1xuICBASW5wdXQoKSB0aGVtZTogc3RyaW5nIHwgVGhlbWVPcHRpb24gfCBudWxsID0gbnVsbDtcbiAgQElucHV0KCkgaW5pdE9wdHM6IHtcbiAgICBkZXZpY2VQaXhlbFJhdGlvPzogbnVtYmVyO1xuICAgIHJlbmRlcmVyPzogc3RyaW5nO1xuICAgIHdpZHRoPzogbnVtYmVyIHwgc3RyaW5nO1xuICAgIGhlaWdodD86IG51bWJlciB8IHN0cmluZztcbiAgICBsb2NhbGU/OiBzdHJpbmc7XG4gIH0gfCBudWxsID0gbnVsbDtcbiAgQElucHV0KCkgbWVyZ2U6IEVDaGFydHNPcHRpb24gfCBudWxsID0gbnVsbDtcbiAgQElucHV0KCkgYXV0b1Jlc2l6ZSA9IHRydWU7XG4gIEBJbnB1dCgpIGxvYWRpbmcgPSBmYWxzZTtcbiAgQElucHV0KCkgbG9hZGluZ1R5cGUgPSAnZGVmYXVsdCc7XG4gIEBJbnB1dCgpIGxvYWRpbmdPcHRzOiBvYmplY3QgfCBudWxsID0gbnVsbDtcblxuICAvLyBuZ3gtZWNoYXJ0cyBldmVudHNcbiAgQE91dHB1dCgpIGNoYXJ0SW5pdCA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuICBAT3V0cHV0KCkgb3B0aW9uc0Vycm9yID0gbmV3IEV2ZW50RW1pdHRlcjxFcnJvcj4oKTtcblxuICAvLyBlY2hhcnRzIG1vdXNlIGV2ZW50c1xuICBAT3V0cHV0KCkgY2hhcnRDbGljayA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50PEVDRWxlbWVudEV2ZW50PignY2xpY2snKTtcbiAgQE91dHB1dCgpIGNoYXJ0RGJsQ2xpY2sgPSB0aGlzLmNyZWF0ZUxhenlFdmVudDxFQ0VsZW1lbnRFdmVudD4oJ2RibGNsaWNrJyk7XG4gIEBPdXRwdXQoKSBjaGFydE1vdXNlRG93biA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50PEVDRWxlbWVudEV2ZW50PignbW91c2Vkb3duJyk7XG4gIEBPdXRwdXQoKSBjaGFydE1vdXNlTW92ZSA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50PEVDRWxlbWVudEV2ZW50PignbW91c2Vtb3ZlJyk7XG4gIEBPdXRwdXQoKSBjaGFydE1vdXNlVXAgPSB0aGlzLmNyZWF0ZUxhenlFdmVudDxFQ0VsZW1lbnRFdmVudD4oJ21vdXNldXAnKTtcbiAgQE91dHB1dCgpIGNoYXJ0TW91c2VPdmVyID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQ8RUNFbGVtZW50RXZlbnQ+KCdtb3VzZW92ZXInKTtcbiAgQE91dHB1dCgpIGNoYXJ0TW91c2VPdXQgPSB0aGlzLmNyZWF0ZUxhenlFdmVudDxFQ0VsZW1lbnRFdmVudD4oJ21vdXNlb3V0Jyk7XG4gIEBPdXRwdXQoKSBjaGFydEdsb2JhbE91dCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50PEVDRWxlbWVudEV2ZW50PignZ2xvYmFsb3V0Jyk7XG4gIEBPdXRwdXQoKSBjaGFydENvbnRleHRNZW51ID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQ8RUNFbGVtZW50RXZlbnQ+KCdjb250ZXh0bWVudScpO1xuXG4gIC8vIGVjaGFydHMgZXZlbnRzXG4gIEBPdXRwdXQoKSBjaGFydEhpZ2hsaWdodCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50PGFueT4oJ2hpZ2hsaWdodCcpO1xuICBAT3V0cHV0KCkgY2hhcnREb3ducGxheSA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50PGFueT4oJ2Rvd25wbGF5Jyk7XG4gIEBPdXRwdXQoKSBjaGFydFNlbGVjdENoYW5nZWQgPSB0aGlzLmNyZWF0ZUxhenlFdmVudDxhbnk+KCdzZWxlY3RjaGFuZ2VkJyk7XG4gIEBPdXRwdXQoKSBjaGFydExlZ2VuZFNlbGVjdENoYW5nZWQgPSB0aGlzLmNyZWF0ZUxhenlFdmVudDxhbnk+KCdsZWdlbmRzZWxlY3RjaGFuZ2VkJyk7XG4gIEBPdXRwdXQoKSBjaGFydExlZ2VuZFNlbGVjdGVkID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQ8YW55PignbGVnZW5kc2VsZWN0ZWQnKTtcbiAgQE91dHB1dCgpIGNoYXJ0TGVnZW5kVW5zZWxlY3RlZCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50PGFueT4oJ2xlZ2VuZHVuc2VsZWN0ZWQnKTtcbiAgQE91dHB1dCgpIGNoYXJ0TGVnZW5kTGVnZW5kU2VsZWN0QWxsID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQ8YW55PignbGVnZW5kc2VsZWN0YWxsJyk7XG4gIEBPdXRwdXQoKSBjaGFydExlZ2VuZExlZ2VuZEludmVyc2VTZWxlY3QgPSB0aGlzLmNyZWF0ZUxhenlFdmVudDxhbnk+KCdsZWdlbmRpbnZlcnNlc2VsZWN0Jyk7XG4gIEBPdXRwdXQoKSBjaGFydExlZ2VuZFNjcm9sbCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50PGFueT4oJ2xlZ2VuZHNjcm9sbCcpO1xuICBAT3V0cHV0KCkgY2hhcnREYXRhWm9vbSA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50PGFueT4oJ2RhdGF6b29tJyk7XG4gIEBPdXRwdXQoKSBjaGFydERhdGFSYW5nZVNlbGVjdGVkID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQ8YW55PignZGF0YXJhbmdlc2VsZWN0ZWQnKTtcbiAgQE91dHB1dCgpIGNoYXJ0R3JhcGhSb2FtID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQ8YW55PignZ3JhcGhyb2FtJyk7XG4gIEBPdXRwdXQoKSBjaGFydEdlb1JvYW0gPSB0aGlzLmNyZWF0ZUxhenlFdmVudDxhbnk+KCdnZW9yb2FtJyk7XG4gIEBPdXRwdXQoKSBjaGFydFRyZWVSb2FtID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQ8YW55PigndHJlZXJvYW0nKTtcbiAgQE91dHB1dCgpIGNoYXJ0VGltZWxpbmVDaGFuZ2VkID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQ8YW55PigndGltZWxpbmVjaGFuZ2VkJyk7XG4gIEBPdXRwdXQoKSBjaGFydFRpbWVsaW5lUGxheUNoYW5nZWQgPSB0aGlzLmNyZWF0ZUxhenlFdmVudDxhbnk+KCd0aW1lbGluZXBsYXljaGFuZ2VkJyk7XG4gIEBPdXRwdXQoKSBjaGFydFJlc3RvcmUgPSB0aGlzLmNyZWF0ZUxhenlFdmVudDxhbnk+KCdyZXN0b3JlJyk7XG4gIEBPdXRwdXQoKSBjaGFydERhdGFWaWV3Q2hhbmdlZCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50PGFueT4oJ2RhdGF2aWV3Y2hhbmdlZCcpO1xuICBAT3V0cHV0KCkgY2hhcnRNYWdpY1R5cGVDaGFuZ2VkID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQ8YW55PignbWFnaWN0eXBlY2hhbmdlZCcpO1xuICBAT3V0cHV0KCkgY2hhcnRHZW9TZWxlY3RDaGFuZ2VkID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQ8YW55PignZ2Vvc2VsZWN0Y2hhbmdlZCcpO1xuICBAT3V0cHV0KCkgY2hhcnRHZW9TZWxlY3RlZCA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50PGFueT4oJ2dlb3NlbGVjdGVkJyk7XG4gIEBPdXRwdXQoKSBjaGFydEdlb1Vuc2VsZWN0ZWQgPSB0aGlzLmNyZWF0ZUxhenlFdmVudDxhbnk+KCdnZW91bnNlbGVjdGVkJyk7XG4gIEBPdXRwdXQoKSBjaGFydEF4aXNBcmVhU2VsZWN0ZWQgPSB0aGlzLmNyZWF0ZUxhenlFdmVudDxhbnk+KCdheGlzYXJlYXNlbGVjdGVkJyk7XG4gIEBPdXRwdXQoKSBjaGFydEJydXNoID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQ8YW55PignYnJ1c2gnKTtcbiAgQE91dHB1dCgpIGNoYXJ0QnJ1c2hFbmQgPSB0aGlzLmNyZWF0ZUxhenlFdmVudDxhbnk+KCdicnVzaGVuZCcpO1xuICBAT3V0cHV0KCkgY2hhcnRCcnVzaFNlbGVjdGVkID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQ8YW55PignYnJ1c2hzZWxlY3RlZCcpO1xuICBAT3V0cHV0KCkgY2hhcnRHbG9iYWxDdXJzb3JUYWtlbiA9IHRoaXMuY3JlYXRlTGF6eUV2ZW50PGFueT4oJ2dsb2JhbGN1cnNvcnRha2VuJyk7XG4gIEBPdXRwdXQoKSBjaGFydFJlbmRlcmVkID0gdGhpcy5jcmVhdGVMYXp5RXZlbnQ8YW55PigncmVuZGVyZWQnKTtcbiAgQE91dHB1dCgpIGNoYXJ0RmluaXNoZWQgPSB0aGlzLmNyZWF0ZUxhenlFdmVudDxhbnk+KCdmaW5pc2hlZCcpO1xuXG4gIHB1YmxpYyBhbmltYXRpb25GcmFtZUlEID0gbnVsbDtcbiAgcHJpdmF0ZSBjaGFydDogRUNoYXJ0cztcbiAgcHJpdmF0ZSBjaGFydCQgPSBuZXcgUmVwbGF5U3ViamVjdDxFQ2hhcnRzPigxKTtcbiAgcHJpdmF0ZSBlY2hhcnRzOiBhbnk7XG4gIHByaXZhdGUgcmVzaXplT2I6IFJlc2l6ZU9ic2VydmVyO1xuICBwcml2YXRlIHJlc2l6ZSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICBwcml2YXRlIHJlc2l6ZVN1YjogU3Vic2NyaXB0aW9uO1xuICBwcml2YXRlIGluaXRDaGFydFRpbWVyPzogbnVtYmVyO1xuICBwcml2YXRlIGNoYW5nZUZpbHRlciA9IG5ldyBDaGFuZ2VGaWx0ZXJWMigpO1xuICBwcml2YXRlIGxvYWRpbmdTdWI6IFN1YnNjcmlwdGlvbjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBASW5qZWN0KE5HWF9FQ0hBUlRTX0NPTkZJRykgY29uZmlnOiBOZ3hFY2hhcnRzQ29uZmlnLFxuICAgIHByaXZhdGUgZWw6IEVsZW1lbnRSZWYsXG4gICAgcHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZVxuICApIHtcbiAgICB0aGlzLmVjaGFydHMgPSBjb25maWcuZWNoYXJ0cztcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcbiAgICB0aGlzLmNoYW5nZUZpbHRlci5kb0ZpbHRlcihjaGFuZ2VzKTtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIGlmICghd2luZG93LlJlc2l6ZU9ic2VydmVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ3BsZWFzZSBpbnN0YWxsIGEgcG9seWZpbGwgZm9yIFJlc2l6ZU9ic2VydmVyJyk7XG4gICAgfVxuICAgIHRoaXMucmVzaXplU3ViID0gdGhpcy5yZXNpemUkXG4gICAgICAucGlwZSh0aHJvdHRsZVRpbWUoMTAwLCBhc3luY1NjaGVkdWxlciwgeyBsZWFkaW5nOiBmYWxzZSwgdHJhaWxpbmc6IHRydWUgfSkpXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHRoaXMucmVzaXplKCkpO1xuXG4gICAgaWYgKHRoaXMuYXV0b1Jlc2l6ZSkge1xuICAgICAgdGhpcy5yZXNpemVPYiA9IHRoaXMubmdab25lLnJ1bk91dHNpZGVBbmd1bGFyKFxuICAgICAgICAoKSA9PlxuICAgICAgICAgIG5ldyB3aW5kb3cuUmVzaXplT2JzZXJ2ZXIoKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5hbmltYXRpb25GcmFtZUlEID0gd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB0aGlzLnJlc2l6ZSQubmV4dCgpKTtcbiAgICAgICAgICB9KVxuICAgICAgKTtcbiAgICAgIHRoaXMucmVzaXplT2Iub2JzZXJ2ZSh0aGlzLmVsLm5hdGl2ZUVsZW1lbnQpO1xuICAgIH1cblxuICAgIHRoaXMuY2hhbmdlRmlsdGVyLm5vdEZpcnN0QW5kRW1wdHkoJ29wdGlvbnMnLCBvcHQgPT4gdGhpcy5vbk9wdGlvbnNDaGFuZ2Uob3B0KSk7XG4gICAgdGhpcy5jaGFuZ2VGaWx0ZXIubm90Rmlyc3RBbmRFbXB0eSgnbWVyZ2UnLCBvcHQgPT4gdGhpcy5zZXRPcHRpb24ob3B0KSk7XG4gICAgdGhpcy5jaGFuZ2VGaWx0ZXIuaGFzPGJvb2xlYW4+KCdsb2FkaW5nJywgdiA9PiB0aGlzLnRvZ2dsZUxvYWRpbmcoISF2KSk7XG4gICAgdGhpcy5jaGFuZ2VGaWx0ZXIubm90Rmlyc3Q8c3RyaW5nIHwgVGhlbWVPcHRpb24+KCd0aGVtZScsICgpID0+IHRoaXMucmVmcmVzaENoYXJ0KCkpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgd2luZG93LmNsZWFyVGltZW91dCh0aGlzLmluaXRDaGFydFRpbWVyKTtcbiAgICBpZiAodGhpcy5yZXNpemVTdWIpIHtcbiAgICAgIHRoaXMucmVzaXplU3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuICAgIGlmICh0aGlzLmFuaW1hdGlvbkZyYW1lSUQpIHtcbiAgICAgIHdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLmFuaW1hdGlvbkZyYW1lSUQpO1xuICAgIH1cbiAgICBpZiAodGhpcy5yZXNpemVPYikge1xuICAgICAgdGhpcy5yZXNpemVPYi51bm9ic2VydmUodGhpcy5lbC5uYXRpdmVFbGVtZW50KTtcbiAgICB9XG4gICAgaWYgKHRoaXMubG9hZGluZ1N1Yikge1xuICAgICAgdGhpcy5sb2FkaW5nU3ViLnVuc3Vic2NyaWJlKCk7XG4gICAgfVxuICAgIHRoaXMuY2hhbmdlRmlsdGVyLmRpc3Bvc2UoKTtcbiAgICB0aGlzLmRpc3Bvc2UoKTtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICB0aGlzLmluaXRDaGFydFRpbWVyID0gd2luZG93LnNldFRpbWVvdXQoKCkgPT4gdGhpcy5pbml0Q2hhcnQoKSk7XG4gIH1cblxuICBwcml2YXRlIGRpc3Bvc2UoKSB7XG4gICAgaWYgKHRoaXMuY2hhcnQpIHtcbiAgICAgIGlmICghdGhpcy5jaGFydC5pc0Rpc3Bvc2VkKCkpIHtcbiAgICAgICAgdGhpcy5jaGFydC5kaXNwb3NlKCk7XG4gICAgICB9XG4gICAgICB0aGlzLmNoYXJ0ID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogcmVzaXplIGNoYXJ0XG4gICAqL1xuICByZXNpemUoKSB7XG4gICAgaWYgKHRoaXMuY2hhcnQpIHtcbiAgICAgIHRoaXMuY2hhcnQucmVzaXplKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB0b2dnbGVMb2FkaW5nKGxvYWRpbmc6IGJvb2xlYW4pIHtcbiAgICBpZiAodGhpcy5jaGFydCkge1xuICAgICAgbG9hZGluZ1xuICAgICAgICA/IHRoaXMuY2hhcnQuc2hvd0xvYWRpbmcodGhpcy5sb2FkaW5nVHlwZSwgdGhpcy5sb2FkaW5nT3B0cylcbiAgICAgICAgOiB0aGlzLmNoYXJ0LmhpZGVMb2FkaW5nKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubG9hZGluZ1N1YiA9IHRoaXMuY2hhcnQkLnN1YnNjcmliZShjaGFydCA9PlxuICAgICAgICBsb2FkaW5nID8gY2hhcnQuc2hvd0xvYWRpbmcodGhpcy5sb2FkaW5nVHlwZSwgdGhpcy5sb2FkaW5nT3B0cykgOiBjaGFydC5oaWRlTG9hZGluZygpXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2V0T3B0aW9uKG9wdGlvbjogYW55LCBvcHRzPzogYW55KSB7XG4gICAgaWYgKHRoaXMuY2hhcnQpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRoaXMuY2hhcnQuc2V0T3B0aW9uKG9wdGlvbiwgb3B0cyk7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZSk7XG4gICAgICAgIHRoaXMub3B0aW9uc0Vycm9yLmVtaXQoZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIGRpc3Bvc2Ugb2xkIGNoYXJ0IGFuZCBjcmVhdGUgYSBuZXcgb25lLlxuICAgKi9cbiAgYXN5bmMgcmVmcmVzaENoYXJ0KCkge1xuICAgIHRoaXMuZGlzcG9zZSgpO1xuICAgIGF3YWl0IHRoaXMuaW5pdENoYXJ0KCk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUNoYXJ0KCkge1xuICAgIGNvbnN0IGRvbSA9IHRoaXMuZWwubmF0aXZlRWxlbWVudDtcblxuICAgIGlmICh3aW5kb3cgJiYgd2luZG93LmdldENvbXB1dGVkU3R5bGUpIHtcbiAgICAgIGNvbnN0IHByb3AgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShkb20sIG51bGwpLmdldFByb3BlcnR5VmFsdWUoJ2hlaWdodCcpO1xuICAgICAgaWYgKCghcHJvcCB8fCBwcm9wID09PSAnMHB4JykgJiYgKCFkb20uc3R5bGUuaGVpZ2h0IHx8IGRvbS5zdHlsZS5oZWlnaHQgPT09ICcwcHgnKSkge1xuICAgICAgICBkb20uc3R5bGUuaGVpZ2h0ID0gJzQwMHB4JztcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBoZXJlIGEgYml0IHRyaWNreTogd2UgY2hlY2sgaWYgdGhlIGVjaGFydHMgbW9kdWxlIGlzIHByb3ZpZGVkIGFzIGZ1bmN0aW9uIHJldHVybmluZyBuYXRpdmUgaW1wb3J0KCcuLi4nKSB0aGVuIHVzZSB0aGUgcHJvbWlzZVxuICAgIC8vIG90aGVyd2lzZSBjcmVhdGUgdGhlIGZ1bmN0aW9uIHRoYXQgaW1pdGF0ZXMgYmVoYXZpb3VyIGFib3ZlIHdpdGggYSBwcm92aWRlZCBhcyBpcyBtb2R1bGVcbiAgICByZXR1cm4gdGhpcy5uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgY29uc3QgbG9hZCA9XG4gICAgICAgIHR5cGVvZiB0aGlzLmVjaGFydHMgPT09ICdmdW5jdGlvbicgPyB0aGlzLmVjaGFydHMgOiAoKSA9PiBQcm9taXNlLnJlc29sdmUodGhpcy5lY2hhcnRzKTtcblxuICAgICAgcmV0dXJuIGxvYWQoKS50aGVuKCh7IGluaXQgfSkgPT4gaW5pdChkb20sIHRoaXMudGhlbWUsIHRoaXMuaW5pdE9wdHMpKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaW5pdENoYXJ0KCkge1xuICAgIGF3YWl0IHRoaXMub25PcHRpb25zQ2hhbmdlKHRoaXMub3B0aW9ucyk7XG5cbiAgICBpZiAodGhpcy5tZXJnZSAmJiB0aGlzLmNoYXJ0KSB7XG4gICAgICB0aGlzLnNldE9wdGlvbih0aGlzLm1lcmdlKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIG9uT3B0aW9uc0NoYW5nZShvcHQ6IGFueSkge1xuICAgIGlmICghb3B0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuY2hhcnQpIHtcbiAgICAgIHRoaXMuc2V0T3B0aW9uKHRoaXMub3B0aW9ucywgdHJ1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY2hhcnQgPSBhd2FpdCB0aGlzLmNyZWF0ZUNoYXJ0KCk7XG4gICAgICB0aGlzLmNoYXJ0JC5uZXh0KHRoaXMuY2hhcnQpO1xuICAgICAgdGhpcy5jaGFydEluaXQuZW1pdCh0aGlzLmNoYXJ0KTtcbiAgICAgIHRoaXMuc2V0T3B0aW9uKHRoaXMub3B0aW9ucywgdHJ1ZSk7XG4gICAgfVxuICB9XG5cbiAgLy8gYWxsb3dzIHRvIGxhemlseSBiaW5kIHRvIG9ubHkgdGhvc2UgZXZlbnRzIHRoYXQgYXJlIHJlcXVlc3RlZCB0aHJvdWdoIHRoZSBgQE91dHB1dGAgYnkgcGFyZW50IGNvbXBvbmVudHNcbiAgLy8gc2VlIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzUxNzg3OTcyL29wdGltYWwtcmVlbnRlcmluZy10aGUtbmd6b25lLWZyb20tZXZlbnRlbWl0dGVyLWV2ZW50IGZvciBtb3JlIGluZm9cbiAgcHJpdmF0ZSBjcmVhdGVMYXp5RXZlbnQ8VD4oZXZlbnROYW1lOiBzdHJpbmcpOiBFdmVudEVtaXR0ZXI8VD4ge1xuICAgIHJldHVybiB0aGlzLmNoYXJ0SW5pdC5waXBlKFxuICAgICAgc3dpdGNoTWFwKFxuICAgICAgICAoY2hhcnQ6IGFueSkgPT5cbiAgICAgICAgICBuZXcgT2JzZXJ2YWJsZShvYnNlcnZlciA9PiB7XG4gICAgICAgICAgICBjaGFydC5vbihldmVudE5hbWUsIChkYXRhOiBUKSA9PiB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gb2JzZXJ2ZXIubmV4dChkYXRhKSkpO1xuICAgICAgICAgICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKHRoaXMuY2hhcnQpIHtcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuY2hhcnQuaXNEaXNwb3NlZCgpKSB7XG4gICAgICAgICAgICAgICAgICBjaGFydC5vZmYoZXZlbnROYW1lKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfSlcbiAgICAgIClcbiAgICApIGFzIEV2ZW50RW1pdHRlcjxUPjtcbiAgfVxufVxuIl19
\No newline at end of file