ng-zorro-antd
Version:
An enterprise-class UI components based on Ant Design and Angular
150 lines • 19.6 kB
JavaScript
/**
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE
*/
import { Directive, EventEmitter, Input, Output } from '@angular/core';
import { Subject } from 'rxjs';
import { transition } from 'd3-transition';
import { zoom, zoomIdentity, zoomTransform } from 'd3-zoom';
import { calculateTransform } from './core/utils';
import * as i0 from "@angular/core";
export class NzGraphZoomDirective {
constructor(element, cdr) {
this.element = element;
this.cdr = cdr;
this.nzMinZoom = 0.1;
this.nzMaxZoom = 10;
this.nzTransformEvent = new EventEmitter();
this.nzZoomChange = new EventEmitter();
this.destroy$ = new Subject();
}
ngAfterViewInit() {
this.bind();
}
ngOnDestroy() {
this.unbind();
this.destroy$.next();
this.destroy$.complete();
}
bind() {
this.svgElement = this.element.nativeElement.querySelector('svg');
this.gZoomElement = this.element.nativeElement.querySelector('svg > g');
const { width, height } = this.element.nativeElement.getBoundingClientRect();
this.svgSelection = transition()
.selection()
.select(() => this.svgElement);
this.zoomBehavior = zoom()
.extent([
[0, 0],
[width, height]
])
.scaleExtent([this.nzMinZoom, this.nzMaxZoom])
.on('zoom', e => {
this.zoomed(e);
});
this.svgSelection.call(this.zoomBehavior, zoomIdentity.translate(0, 0).scale(this.nzZoom || 1));
// Init with nzZoom
this.reScale(0, this.nzZoom);
}
unbind() {
// Destroy listener
this.svgSelection?.interrupt().selectAll('*').interrupt();
if (this.zoomBehavior) {
this.zoomBehavior.on('end', null).on('zoom', null);
}
}
// Methods
fitCenter(duration = 0) {
this.reScale(duration);
}
focus(id, duration = 0) {
// Make sure this node is under SVG container
if (!this.svgElement.getElementById(`${id}`)) {
return;
}
const node = this.svgElement.getElementById(`${id}`);
const svgRect = this.svgElement.getBoundingClientRect();
const position = this.getRelativePositionInfo(node);
const svgTransform = zoomTransform(this.svgElement);
const centerX = (position.topLeft.x + position.bottomRight.x) / 2;
const centerY = (position.topLeft.y + position.bottomRight.y) / 2;
const dx = svgRect.left + svgRect.width / 2 - centerX;
const dy = svgRect.top + svgRect.height / 2 - centerY;
this.svgSelection
.transition()
.duration(duration)
.call(this.zoomBehavior.translateBy, dx / svgTransform.k, dy / svgTransform.k);
}
/**
* Handle zoom event
*
* @param transform
*/
zoomed({ transform }) {
const { x, y, k } = transform;
// Update g element transform
this.gZoomElement.setAttribute('transform', `translate(${x}, ${y})scale(${k})`);
this.nzZoom = k;
this.nzZoomChange.emit(this.nzZoom);
this.nzTransformEvent.emit(transform);
this.cdr.markForCheck();
}
/**
* Scale with zoom and duration
*
* @param duration
* @param scale
* @private
*/
reScale(duration, scale) {
const transform = calculateTransform(this.svgElement, this.gZoomElement, scale);
if (!transform) {
return;
}
const { x, y, k } = transform;
const zTransform = zoomIdentity.translate(x, y).scale(Math.max(k, this.nzMinZoom));
this.svgSelection
.transition()
.duration(duration)
.call(this.zoomBehavior.transform, zTransform)
.on('end.fitted', () => {
this.zoomBehavior.on('end.fitted', null);
});
}
getRelativePositionInfo(node) {
const nodeBox = node.getBBox();
const nodeCtm = node.getScreenCTM();
let pointTL = this.svgElement.createSVGPoint();
let pointBR = this.svgElement.createSVGPoint();
pointTL.x = nodeBox.x;
pointTL.y = nodeBox.y;
pointBR.x = nodeBox.x + nodeBox.width;
pointBR.y = nodeBox.y + nodeBox.height;
pointTL = pointTL.matrixTransform(nodeCtm);
pointBR = pointBR.matrixTransform(nodeCtm);
return {
topLeft: pointTL,
bottomRight: pointBR
};
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: NzGraphZoomDirective, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.0.3", type: NzGraphZoomDirective, selector: "[nz-graph-zoom]", inputs: { nzZoom: "nzZoom", nzMinZoom: "nzMinZoom", nzMaxZoom: "nzMaxZoom" }, outputs: { nzTransformEvent: "nzTransformEvent", nzZoomChange: "nzZoomChange" }, exportAs: ["nzGraphZoom"], ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.3", ngImport: i0, type: NzGraphZoomDirective, decorators: [{
type: Directive,
args: [{
selector: '[nz-graph-zoom]',
exportAs: 'nzGraphZoom'
}]
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }], propDecorators: { nzZoom: [{
type: Input
}], nzMinZoom: [{
type: Input
}], nzMaxZoom: [{
type: Input
}], nzTransformEvent: [{
type: Output
}], nzZoomChange: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ3JhcGgtem9vbS5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9jb21wb25lbnRzL2dyYXBoL2dyYXBoLXpvb20uZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7R0FHRztBQUVILE9BQU8sRUFHTCxTQUFTLEVBRVQsWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEVBQ1AsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUcvQixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxJQUFJLEVBQWdCLFlBQVksRUFBRSxhQUFhLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFJMUUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sY0FBYyxDQUFDOztBQU9sRCxNQUFNLE9BQU8sb0JBQW9CO0lBa0IvQixZQUFvQixPQUFtQixFQUFVLEdBQXNCO1FBQW5ELFlBQU8sR0FBUCxPQUFPLENBQVk7UUFBVSxRQUFHLEdBQUgsR0FBRyxDQUFtQjtRQWhCOUQsY0FBUyxHQUFHLEdBQUcsQ0FBQztRQUNoQixjQUFTLEdBQUcsRUFBRSxDQUFDO1FBRUwscUJBQWdCLEdBQWtDLElBQUksWUFBWSxFQUFFLENBQUM7UUFDckUsaUJBQVksR0FBeUIsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQVVuRSxhQUFRLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztJQUVtQyxDQUFDO0lBRTNFLGVBQWU7UUFDYixJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDZCxDQUFDO0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNkLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDckIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRUQsSUFBSTtRQUNGLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBa0IsQ0FBQztRQUNuRixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQWdCLENBQUM7UUFDdkYsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQzdFLElBQUksQ0FBQyxZQUFZLEdBQUcsVUFBVSxFQUFFO2FBQzdCLFNBQVMsRUFBRTthQUNYLE1BQU0sQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDakMsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLEVBQUU7YUFDdkIsTUFBTSxDQUFDO1lBQ04sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ04sQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDO1NBQ2hCLENBQUM7YUFDRCxXQUFXLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQzthQUM3QyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxFQUFFO1lBQ2QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNqQixDQUFDLENBQUMsQ0FBQztRQUNMLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLEVBQUUsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNoRyxtQkFBbUI7UUFDbkIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQy9CLENBQUM7SUFFRCxNQUFNO1FBQ0osbUJBQW1CO1FBQ25CLElBQUksQ0FBQyxZQUFZLEVBQUUsU0FBUyxFQUFFLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQzFELElBQUksSUFBSSxDQUFDLFlBQVksRUFBRTtZQUNyQixJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztTQUNwRDtJQUNILENBQUM7SUFFRCxVQUFVO0lBQ1YsU0FBUyxDQUFDLFdBQW1CLENBQUM7UUFDNUIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUN6QixDQUFDO0lBRUQsS0FBSyxDQUFDLEVBQWEsRUFBRSxXQUFtQixDQUFDO1FBQ3ZDLDZDQUE2QztRQUM3QyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxjQUFjLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxFQUFFO1lBQzVDLE9BQU87U0FDUjtRQUVELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsY0FBYyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQWdCLENBQUM7UUFDcEUsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQ3hELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUNwRCxNQUFNLFlBQVksR0FBRyxhQUFhLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBRXBELE1BQU0sT0FBTyxHQUFHLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsUUFBUSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDbEUsTUFBTSxPQUFPLEdBQUcsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsR0FBRyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNsRSxNQUFNLEVBQUUsR0FBRyxPQUFPLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQyxLQUFLLEdBQUcsQ0FBQyxHQUFHLE9BQU8sQ0FBQztRQUN0RCxNQUFNLEVBQUUsR0FBRyxPQUFPLENBQUMsR0FBRyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxHQUFHLE9BQU8sQ0FBQztRQUV0RCxJQUFJLENBQUMsWUFBWTthQUNkLFVBQVUsRUFBRTthQUNaLFFBQVEsQ0FBQyxRQUFRLENBQUM7YUFDbEIsSUFBSSxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsV0FBVyxFQUFFLEVBQUUsR0FBRyxZQUFZLENBQUMsQ0FBQyxFQUFFLEVBQUUsR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbkYsQ0FBQztJQUVEOzs7O09BSUc7SUFDSyxNQUFNLENBQUMsRUFBRSxTQUFTLEVBQWE7UUFDckMsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLEdBQUcsU0FBUyxDQUFDO1FBQzlCLDZCQUE2QjtRQUM1QixJQUFJLENBQUMsWUFBNEIsQ0FBQyxZQUFZLENBQUMsV0FBVyxFQUFFLGFBQWEsQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2pHLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ2hCLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUNwQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3RDLElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDMUIsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNLLE9BQU8sQ0FBQyxRQUFnQixFQUFFLEtBQWM7UUFDOUMsTUFBTSxTQUFTLEdBQUcsa0JBQWtCLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsWUFBWSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ2hGLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDZCxPQUFPO1NBQ1I7UUFDRCxNQUFNLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsR0FBRyxTQUFTLENBQUM7UUFDOUIsTUFBTSxVQUFVLEdBQUcsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1FBQ25GLElBQUksQ0FBQyxZQUFZO2FBQ2QsVUFBVSxFQUFFO2FBQ1osUUFBUSxDQUFDLFFBQVEsQ0FBQzthQUNsQixJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxTQUFTLEVBQUUsVUFBVSxDQUFDO2FBQzdDLEVBQUUsQ0FBQyxZQUFZLEVBQUUsR0FBRyxFQUFFO1lBQ3JCLElBQUksQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLFlBQVksRUFBRSxJQUFJLENBQUMsQ0FBQztRQUMzQyxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFTyx1QkFBdUIsQ0FBQyxJQUFpQjtRQUMvQyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDL0IsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3BDLElBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDL0MsSUFBSSxPQUFPLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUUvQyxPQUFPLENBQUMsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFDdEIsT0FBTyxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDO1FBQ3RCLE9BQU8sQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDO1FBQ3RDLE9BQU8sQ0FBQyxDQUFDLEdBQUcsT0FBTyxDQUFDLENBQUMsR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDO1FBQ3ZDLE9BQU8sR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDLE9BQVEsQ0FBQyxDQUFDO1FBQzVDLE9BQU8sR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFDLE9BQVEsQ0FBQyxDQUFDO1FBQzVDLE9BQU87WUFDTCxPQUFPLEVBQUUsT0FBTztZQUNoQixXQUFXLEVBQUUsT0FBTztTQUNyQixDQUFDO0lBQ0osQ0FBQzs4R0E1SVUsb0JBQW9CO2tHQUFwQixvQkFBb0I7OzJGQUFwQixvQkFBb0I7a0JBSmhDLFNBQVM7bUJBQUM7b0JBQ1QsUUFBUSxFQUFFLGlCQUFpQjtvQkFDM0IsUUFBUSxFQUFFLGFBQWE7aUJBQ3hCOytHQUVVLE1BQU07c0JBQWQsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUNHLFNBQVM7c0JBQWpCLEtBQUs7Z0JBRWEsZ0JBQWdCO3NCQUFsQyxNQUFNO2dCQUNZLFlBQVk7c0JBQTlCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9ORy1aT1JSTy9uZy16b3Jyby1hbnRkL2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAqL1xuXG5pbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgRGlyZWN0aXZlLFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE91dHB1dFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgU2VsZWN0aW9uIH0gZnJvbSAnZDMtc2VsZWN0aW9uJztcbmltcG9ydCB7IHRyYW5zaXRpb24gfSBmcm9tICdkMy10cmFuc2l0aW9uJztcbmltcG9ydCB7IHpvb20sIFpvb21CZWhhdmlvciwgem9vbUlkZW50aXR5LCB6b29tVHJhbnNmb3JtIH0gZnJvbSAnZDMtem9vbSc7XG5cbmltcG9ydCB7IE56U2FmZUFueSB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS90eXBlcyc7XG5cbmltcG9ydCB7IGNhbGN1bGF0ZVRyYW5zZm9ybSB9IGZyb20gJy4vY29yZS91dGlscyc7XG5pbXBvcnQgeyBOelpvb21UcmFuc2Zvcm0sIFJlbGF0aXZlUG9zaXRpb25JbmZvIH0gZnJvbSAnLi9pbnRlcmZhY2UnO1xuXG5ARGlyZWN0aXZlKHtcbiAgc2VsZWN0b3I6ICdbbnotZ3JhcGgtem9vbV0nLFxuICBleHBvcnRBczogJ256R3JhcGhab29tJ1xufSlcbmV4cG9ydCBjbGFzcyBOekdyYXBoWm9vbURpcmVjdGl2ZSBpbXBsZW1lbnRzIE9uRGVzdHJveSwgQWZ0ZXJWaWV3SW5pdCB7XG4gIEBJbnB1dCgpIG56Wm9vbT86IG51bWJlcjtcbiAgQElucHV0KCkgbnpNaW5ab29tID0gMC4xO1xuICBASW5wdXQoKSBuek1heFpvb20gPSAxMDtcblxuICBAT3V0cHV0KCkgcmVhZG9ubHkgbnpUcmFuc2Zvcm1FdmVudDogRXZlbnRFbWl0dGVyPE56Wm9vbVRyYW5zZm9ybT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSByZWFkb25seSBuelpvb21DaGFuZ2U6IEV2ZW50RW1pdHRlcjxudW1iZXI+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIHN2Z1NlbGVjdGlvbiE6IFNlbGVjdGlvbjxOelNhZmVBbnksIE56U2FmZUFueSwgTnpTYWZlQW55LCBOelNhZmVBbnk+O1xuICB6b29tQmVoYXZpb3IhOiBab29tQmVoYXZpb3I8TnpTYWZlQW55LCBOelNhZmVBbnk+O1xuXG4gIC8vIFRPRE9cbiAgLy8gU3VwcG9ydCBzdmcgZWxlbWVudCBvbmx5IG5vd1xuICBzdmdFbGVtZW50ITogU1ZHU1ZHRWxlbWVudDtcbiAgZ1pvb21FbGVtZW50ITogU1ZHR0VsZW1lbnQ7XG5cbiAgcHJpdmF0ZSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBlbGVtZW50OiBFbGVtZW50UmVmLCBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYpIHt9XG5cbiAgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xuICAgIHRoaXMuYmluZCgpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy51bmJpbmQoKTtcbiAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcbiAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gIH1cblxuICBiaW5kKCk6IHZvaWQge1xuICAgIHRoaXMuc3ZnRWxlbWVudCA9IHRoaXMuZWxlbWVudC5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJ3N2ZycpIGFzIFNWR1NWR0VsZW1lbnQ7XG4gICAgdGhpcy5nWm9vbUVsZW1lbnQgPSB0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKCdzdmcgPiBnJykgYXMgU1ZHR0VsZW1lbnQ7XG4gICAgY29uc3QgeyB3aWR0aCwgaGVpZ2h0IH0gPSB0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICB0aGlzLnN2Z1NlbGVjdGlvbiA9IHRyYW5zaXRpb24oKVxuICAgICAgLnNlbGVjdGlvbigpXG4gICAgICAuc2VsZWN0KCgpID0+IHRoaXMuc3ZnRWxlbWVudCk7XG4gICAgdGhpcy56b29tQmVoYXZpb3IgPSB6b29tKClcbiAgICAgIC5leHRlbnQoW1xuICAgICAgICBbMCwgMF0sXG4gICAgICAgIFt3aWR0aCwgaGVpZ2h0XVxuICAgICAgXSlcbiAgICAgIC5zY2FsZUV4dGVudChbdGhpcy5uek1pblpvb20sIHRoaXMubnpNYXhab29tXSlcbiAgICAgIC5vbignem9vbScsIGUgPT4ge1xuICAgICAgICB0aGlzLnpvb21lZChlKTtcbiAgICAgIH0pO1xuICAgIHRoaXMuc3ZnU2VsZWN0aW9uLmNhbGwodGhpcy56b29tQmVoYXZpb3IsIHpvb21JZGVudGl0eS50cmFuc2xhdGUoMCwgMCkuc2NhbGUodGhpcy5uelpvb20gfHwgMSkpO1xuICAgIC8vIEluaXQgd2l0aCBuelpvb21cbiAgICB0aGlzLnJlU2NhbGUoMCwgdGhpcy5uelpvb20pO1xuICB9XG5cbiAgdW5iaW5kKCk6IHZvaWQge1xuICAgIC8vIERlc3Ryb3kgbGlzdGVuZXJcbiAgICB0aGlzLnN2Z1NlbGVjdGlvbj8uaW50ZXJydXB0KCkuc2VsZWN0QWxsKCcqJykuaW50ZXJydXB0KCk7XG4gICAgaWYgKHRoaXMuem9vbUJlaGF2aW9yKSB7XG4gICAgICB0aGlzLnpvb21CZWhhdmlvci5vbignZW5kJywgbnVsbCkub24oJ3pvb20nLCBudWxsKTtcbiAgICB9XG4gIH1cblxuICAvLyBNZXRob2RzXG4gIGZpdENlbnRlcihkdXJhdGlvbjogbnVtYmVyID0gMCk6IHZvaWQge1xuICAgIHRoaXMucmVTY2FsZShkdXJhdGlvbik7XG4gIH1cblxuICBmb2N1cyhpZDogTnpTYWZlQW55LCBkdXJhdGlvbjogbnVtYmVyID0gMCk6IHZvaWQge1xuICAgIC8vIE1ha2Ugc3VyZSB0aGlzIG5vZGUgaXMgdW5kZXIgU1ZHIGNvbnRhaW5lclxuICAgIGlmICghdGhpcy5zdmdFbGVtZW50LmdldEVsZW1lbnRCeUlkKGAke2lkfWApKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgbm9kZSA9IHRoaXMuc3ZnRWxlbWVudC5nZXRFbGVtZW50QnlJZChgJHtpZH1gKSBhcyBTVkdHRWxlbWVudDtcbiAgICBjb25zdCBzdmdSZWN0ID0gdGhpcy5zdmdFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IHBvc2l0aW9uID0gdGhpcy5nZXRSZWxhdGl2ZVBvc2l0aW9uSW5mbyhub2RlKTtcbiAgICBjb25zdCBzdmdUcmFuc2Zvcm0gPSB6b29tVHJhbnNmb3JtKHRoaXMuc3ZnRWxlbWVudCk7XG5cbiAgICBjb25zdCBjZW50ZXJYID0gKHBvc2l0aW9uLnRvcExlZnQueCArIHBvc2l0aW9uLmJvdHRvbVJpZ2h0LngpIC8gMjtcbiAgICBjb25zdCBjZW50ZXJZID0gKHBvc2l0aW9uLnRvcExlZnQueSArIHBvc2l0aW9uLmJvdHRvbVJpZ2h0LnkpIC8gMjtcbiAgICBjb25zdCBkeCA9IHN2Z1JlY3QubGVmdCArIHN2Z1JlY3Qud2lkdGggLyAyIC0gY2VudGVyWDtcbiAgICBjb25zdCBkeSA9IHN2Z1JlY3QudG9wICsgc3ZnUmVjdC5oZWlnaHQgLyAyIC0gY2VudGVyWTtcblxuICAgIHRoaXMuc3ZnU2VsZWN0aW9uXG4gICAgICAudHJhbnNpdGlvbigpXG4gICAgICAuZHVyYXRpb24oZHVyYXRpb24pXG4gICAgICAuY2FsbCh0aGlzLnpvb21CZWhhdmlvci50cmFuc2xhdGVCeSwgZHggLyBzdmdUcmFuc2Zvcm0uaywgZHkgLyBzdmdUcmFuc2Zvcm0uayk7XG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlIHpvb20gZXZlbnRcbiAgICpcbiAgICogQHBhcmFtIHRyYW5zZm9ybVxuICAgKi9cbiAgcHJpdmF0ZSB6b29tZWQoeyB0cmFuc2Zvcm0gfTogTnpTYWZlQW55KTogdm9pZCB7XG4gICAgY29uc3QgeyB4LCB5LCBrIH0gPSB0cmFuc2Zvcm07XG4gICAgLy8gVXBkYXRlIGcgZWxlbWVudCB0cmFuc2Zvcm1cbiAgICAodGhpcy5nWm9vbUVsZW1lbnQgYXMgU1ZHR0VsZW1lbnQpLnNldEF0dHJpYnV0ZSgndHJhbnNmb3JtJywgYHRyYW5zbGF0ZSgke3h9LCAke3l9KXNjYWxlKCR7a30pYCk7XG4gICAgdGhpcy5uelpvb20gPSBrO1xuICAgIHRoaXMubnpab29tQ2hhbmdlLmVtaXQodGhpcy5uelpvb20pO1xuICAgIHRoaXMubnpUcmFuc2Zvcm1FdmVudC5lbWl0KHRyYW5zZm9ybSk7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICAvKipcbiAgICogU2NhbGUgd2l0aCB6b29tIGFuZCBkdXJhdGlvblxuICAgKlxuICAgKiBAcGFyYW0gZHVyYXRpb25cbiAgICogQHBhcmFtIHNjYWxlXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIHJlU2NhbGUoZHVyYXRpb246IG51bWJlciwgc2NhbGU/OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCB0cmFuc2Zvcm0gPSBjYWxjdWxhdGVUcmFuc2Zvcm0odGhpcy5zdmdFbGVtZW50LCB0aGlzLmdab29tRWxlbWVudCwgc2NhbGUpO1xuICAgIGlmICghdHJhbnNmb3JtKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHsgeCwgeSwgayB9ID0gdHJhbnNmb3JtO1xuICAgIGNvbnN0IHpUcmFuc2Zvcm0gPSB6b29tSWRlbnRpdHkudHJhbnNsYXRlKHgsIHkpLnNjYWxlKE1hdGgubWF4KGssIHRoaXMubnpNaW5ab29tKSk7XG4gICAgdGhpcy5zdmdTZWxlY3Rpb25cbiAgICAgIC50cmFuc2l0aW9uKClcbiAgICAgIC5kdXJhdGlvbihkdXJhdGlvbilcbiAgICAgIC5jYWxsKHRoaXMuem9vbUJlaGF2aW9yLnRyYW5zZm9ybSwgelRyYW5zZm9ybSlcbiAgICAgIC5vbignZW5kLmZpdHRlZCcsICgpID0+IHtcbiAgICAgICAgdGhpcy56b29tQmVoYXZpb3Iub24oJ2VuZC5maXR0ZWQnLCBudWxsKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRSZWxhdGl2ZVBvc2l0aW9uSW5mbyhub2RlOiBTVkdHRWxlbWVudCk6IFJlbGF0aXZlUG9zaXRpb25JbmZvIHtcbiAgICBjb25zdCBub2RlQm94ID0gbm9kZS5nZXRCQm94KCk7XG4gICAgY29uc3Qgbm9kZUN0bSA9IG5vZGUuZ2V0U2NyZWVuQ1RNKCk7XG4gICAgbGV0IHBvaW50VEwgPSB0aGlzLnN2Z0VsZW1lbnQuY3JlYXRlU1ZHUG9pbnQoKTtcbiAgICBsZXQgcG9pbnRCUiA9IHRoaXMuc3ZnRWxlbWVudC5jcmVhdGVTVkdQb2ludCgpO1xuXG4gICAgcG9pbnRUTC54ID0gbm9kZUJveC54O1xuICAgIHBvaW50VEwueSA9IG5vZGVCb3gueTtcbiAgICBwb2ludEJSLnggPSBub2RlQm94LnggKyBub2RlQm94LndpZHRoO1xuICAgIHBvaW50QlIueSA9IG5vZGVCb3gueSArIG5vZGVCb3guaGVpZ2h0O1xuICAgIHBvaW50VEwgPSBwb2ludFRMLm1hdHJpeFRyYW5zZm9ybShub2RlQ3RtISk7XG4gICAgcG9pbnRCUiA9IHBvaW50QlIubWF0cml4VHJhbnNmb3JtKG5vZGVDdG0hKTtcbiAgICByZXR1cm4ge1xuICAgICAgdG9wTGVmdDogcG9pbnRUTCxcbiAgICAgIGJvdHRvbVJpZ2h0OiBwb2ludEJSXG4gICAgfTtcbiAgfVxufVxuIl19