@greenmice/ngx-cesium
Version:
Angular library for working with Cesium.
309 lines • 46.4 kB
JavaScript
import { AcEntity } from '../../angular-cesium/models/ac-entity';
import { EditPoint } from './edit-point';
import { EditPolyline } from './edit-polyline';
import { GeoUtilsService } from '../../angular-cesium/services/geo-utils/geo-utils.service';
import { defaultLabelProps } from './label-props';
export class EditablePolyline extends AcEntity {
constructor(id, pointsLayer, polylinesLayer, coordinateConverter, scene, editOptions, positions) {
super();
this.id = id;
this.pointsLayer = pointsLayer;
this.polylinesLayer = polylinesLayer;
this.coordinateConverter = coordinateConverter;
this.scene = scene;
this.editOptions = editOptions;
this.positions = [];
this.polylines = [];
this.doneCreation = false;
this._enableEdit = true;
this._labels = [];
this._outlineInstance = null;
this._pointProps = { ...editOptions.pointProps };
this.props = { ...editOptions.polylineProps };
if (positions && positions.length >= 2) {
this.createFromExisting(positions);
}
}
get labels() {
return this._labels;
}
set labels(labels) {
if (!labels) {
return;
}
const positions = this.getRealPositions();
this._labels = labels.map((label, index) => {
if (!label.position) {
label.position = positions[index];
}
return Object.assign({}, defaultLabelProps, label);
});
}
get props() {
return this.polylineProps;
}
set props(value) {
this.polylineProps = value;
}
get pointProps() {
return this._pointProps;
}
set pointProps(value) {
this._pointProps = value;
}
get enableEdit() {
return this._enableEdit;
}
set enableEdit(value) {
this._enableEdit = value;
this.positions.forEach(point => {
point.show = value;
this.updatePointsLayer(false, point);
});
}
createFromExisting(positions) {
positions.forEach((position) => {
this.addPointFromExisting(position);
});
this.addAllVirtualEditPoints();
this.doneCreation = true;
}
setManually(points, polylineProps) {
if (!this.doneCreation) {
throw new Error('Update manually only in edit mode, after polyline is created');
}
this.positions.forEach(p => this.pointsLayer.remove(p.getId()));
const newPoints = [];
for (let i = 0; i < points.length; i++) {
const pointOrCartesian = points[i];
let newPoint = null;
if (pointOrCartesian.pointProps) {
newPoint = new EditPoint(this.id, pointOrCartesian.position, pointOrCartesian.pointProps);
}
else {
newPoint = new EditPoint(this.id, pointOrCartesian, this._pointProps);
}
newPoints.push(newPoint);
}
this.positions = newPoints;
this.polylineProps = polylineProps ? polylineProps : this.polylineProps;
this.updatePointsLayer(true, ...this.positions);
this.addAllVirtualEditPoints();
}
addAllVirtualEditPoints() {
const currentPoints = [...this.positions];
currentPoints.forEach((pos, index) => {
if (index !== currentPoints.length - 1) {
const currentPoint = pos;
const nextIndex = (index + 1) % (currentPoints.length);
const nextPoint = currentPoints[nextIndex];
const midPoint = this.setMiddleVirtualPoint(currentPoint, nextPoint);
this.updatePointsLayer(false, midPoint);
}
});
}
setMiddleVirtualPoint(firstP, secondP) {
const midPointCartesian3 = Cesium.Cartesian3.lerp(firstP.getPosition(), secondP.getPosition(), 0.5, new Cesium.Cartesian3());
const midPoint = new EditPoint(this.id, midPointCartesian3, this._pointProps);
midPoint.setVirtualEditPoint(true);
const firstIndex = this.positions.indexOf(firstP);
this.positions.splice(firstIndex + 1, 0, midPoint);
return midPoint;
}
updateMiddleVirtualPoint(virtualEditPoint, prevPoint, nextPoint) {
const midPointCartesian3 = Cesium.Cartesian3.lerp(prevPoint.getPosition(), nextPoint.getPosition(), 0.5, new Cesium.Cartesian3());
virtualEditPoint.setPosition(midPointCartesian3);
}
changeVirtualPointToRealPoint(point) {
point.setVirtualEditPoint(false); // actual point becomes a real point
const pointsCount = this.positions.length;
const pointIndex = this.positions.indexOf(point);
const nextIndex = (pointIndex + 1) % (pointsCount);
const preIndex = ((pointIndex - 1) + pointsCount) % pointsCount;
const nextPoint = this.positions[nextIndex];
const prePoint = this.positions[preIndex];
const firstMidPoint = this.setMiddleVirtualPoint(prePoint, point);
const secMidPoint = this.setMiddleVirtualPoint(point, nextPoint);
this.updatePointsLayer(false, firstMidPoint, secMidPoint, point);
}
renderPolylines() {
const realPoints = this.positions.filter(point => !point.isVirtualEditPoint());
if (this.polylineProps.useGroundPrimitiveOutline) {
if (realPoints.length < 2) {
return;
}
this.scene.groundPrimitives.remove(this._outlineInstance);
const instance = new Cesium.GeometryInstance({
geometry: new Cesium.GroundPolylineGeometry({
positions: this.positions.map(p => p.getPosition()),
width: this.polylineProps.width,
loop: false
}),
id: 'edit-polygon-outline-' + this.id,
attributes: {
color: Cesium.ColorGeometryInstanceAttribute.fromColor(this.polylineProps.material())
}
});
this._outlineInstance = this.scene.groundPrimitives.add(new Cesium.GroundPolylinePrimitive({
geometryInstances: instance,
asynchronous: false,
appearance: new Cesium.PolylineColorAppearance()
}));
}
else {
this.polylines.forEach(polyline => this.polylinesLayer.remove(polyline.getId()));
this.polylines = [];
realPoints.forEach((point, index) => {
if (index !== realPoints.length - 1) {
const nextIndex = (index + 1);
const nextPoint = realPoints[nextIndex];
const polyline = new EditPolyline(this.id, point.getPosition(), nextPoint.getPosition(), this.polylineProps);
this.polylines.push(polyline);
this.polylinesLayer.update(polyline, polyline.getId());
}
});
}
}
addPointFromExisting(position) {
const newPoint = new EditPoint(this.id, position, this._pointProps);
this.positions.push(newPoint);
this.updatePointsLayer(true, newPoint);
}
addPoint(position) {
if (this.doneCreation) {
return;
}
const isFirstPoint = !this.positions.length;
if (isFirstPoint) {
const firstPoint = new EditPoint(this.id, position, this._pointProps);
this.positions.push(firstPoint);
this.updatePointsLayer(true, firstPoint);
}
this.movingPoint = new EditPoint(this.id, position.clone(), this._pointProps);
this.positions.push(this.movingPoint);
this.updatePointsLayer(true, this.movingPoint);
}
movePointFinish(editPoint) {
if (this.editOptions.clampHeightTo3D) {
editPoint.props.disableDepthTestDistance = Number.POSITIVE_INFINITY;
this.updatePointsLayer(false, editPoint);
}
}
movePoint(toPosition, editPoint) {
editPoint.setPosition(toPosition);
if (this.doneCreation) {
if (editPoint.props.disableDepthTestDistance && this.editOptions.clampHeightTo3D) {
// To avoid bug with pickPosition() on point with disableDepthTestDistance
editPoint.props.disableDepthTestDistance = undefined;
return; // ignore first move because the pickPosition() could be wrong
}
if (editPoint.isVirtualEditPoint()) {
this.changeVirtualPointToRealPoint(editPoint);
}
const pointsCount = this.positions.length;
const pointIndex = this.positions.indexOf(editPoint);
if (pointIndex < this.positions.length - 1) {
const nextVirtualPoint = this.positions[(pointIndex + 1) % (pointsCount)];
const nextRealPoint = this.positions[(pointIndex + 2) % (pointsCount)];
this.updateMiddleVirtualPoint(nextVirtualPoint, editPoint, nextRealPoint);
}
if (pointIndex > 0) {
const prevVirtualPoint = this.positions[((pointIndex - 1) + pointsCount) % pointsCount];
const prevRealPoint = this.positions[((pointIndex - 2) + pointsCount) % pointsCount];
this.updateMiddleVirtualPoint(prevVirtualPoint, editPoint, prevRealPoint);
}
}
this.updatePointsLayer(true, editPoint);
}
moveTempMovingPoint(toPosition) {
if (this.movingPoint) {
this.movePoint(toPosition, this.movingPoint);
}
}
moveShape(startMovingPosition, draggedToPosition) {
if (!this.doneCreation) {
return;
}
if (!this.lastDraggedToPosition) {
this.lastDraggedToPosition = startMovingPosition;
}
const delta = GeoUtilsService.getPositionsDelta(this.lastDraggedToPosition, draggedToPosition);
this.positions.forEach(point => {
const newPos = GeoUtilsService.addDeltaToPosition(point.getPosition(), delta, true);
point.setPosition(newPos);
});
this.updatePointsLayer(true, ...this.positions);
this.lastDraggedToPosition = draggedToPosition;
}
endMoveShape() {
this.lastDraggedToPosition = undefined;
this.updatePointsLayer(true, ...this.positions);
}
removePoint(pointToRemove) {
this.removePosition(pointToRemove);
this.positions
.filter(p => p.isVirtualEditPoint())
.forEach(p => this.removePosition(p));
this.addAllVirtualEditPoints();
this.renderPolylines();
}
addLastPoint(position) {
this.doneCreation = true;
this.removePosition(this.movingPoint); // remove movingPoint
this.movingPoint = null;
this.addAllVirtualEditPoints();
}
getRealPositions() {
return this.getRealPoints()
.map(position => position.getPosition());
}
getRealPoints() {
return this.positions
.filter(position => !position.isVirtualEditPoint() && position !== this.movingPoint);
}
getPoints() {
return this.positions.filter(position => position !== this.movingPoint);
}
getPositions() {
return this.positions.map(position => position.getPosition());
}
getPositionsCallbackProperty() {
return new Cesium.CallbackProperty(this.getPositions.bind(this), false);
}
removePosition(point) {
const index = this.positions.findIndex((p) => p === point);
if (index < 0) {
return;
}
this.positions.splice(index, 1);
this.pointsLayer.remove(point.getId());
}
updatePointsLayer(renderPolylines = true, ...point) {
if (renderPolylines) {
this.renderPolylines();
}
point.forEach(p => this.pointsLayer.update(p, p.getId()));
}
update() {
this.updatePointsLayer();
}
dispose() {
this.scene.groundPrimitives.remove(this._outlineInstance);
this.positions.forEach(editPoint => {
this.pointsLayer.remove(editPoint.getId());
});
this.polylines.forEach(line => this.polylinesLayer.remove(line.getId()));
if (this.movingPoint) {
this.pointsLayer.remove(this.movingPoint.getId());
this.movingPoint = undefined;
}
this.positions.length = 0;
}
getPointsCount() {
return this.positions.length;
}
getId() {
return this.id;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdGFibGUtcG9seWxpbmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLWNlc2l1bS9zcmMvbGliL2FuZ3VsYXItY2VzaXVtLXdpZGdldHMvbW9kZWxzL2VkaXRhYmxlLXBvbHlsaW5lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUNqRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQU0vQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMkRBQTJELENBQUM7QUFDNUYsT0FBTyxFQUFFLGlCQUFpQixFQUFjLE1BQU0sZUFBZSxDQUFDO0FBRTlELE1BQU0sT0FBTyxnQkFBaUIsU0FBUSxRQUFRO0lBYTVDLFlBQW9CLEVBQVUsRUFDVixXQUE2QixFQUM3QixjQUFnQyxFQUNoQyxtQkFBd0MsRUFDeEMsS0FBVSxFQUNWLFdBQWdDLEVBQ3hDLFNBQXdCO1FBQ2xDLEtBQUssRUFBRSxDQUFDO1FBUFUsT0FBRSxHQUFGLEVBQUUsQ0FBUTtRQUNWLGdCQUFXLEdBQVgsV0FBVyxDQUFrQjtRQUM3QixtQkFBYyxHQUFkLGNBQWMsQ0FBa0I7UUFDaEMsd0JBQW1CLEdBQW5CLG1CQUFtQixDQUFxQjtRQUN4QyxVQUFLLEdBQUwsS0FBSyxDQUFLO1FBQ1YsZ0JBQVcsR0FBWCxXQUFXLENBQXFCO1FBakI1QyxjQUFTLEdBQWdCLEVBQUUsQ0FBQztRQUU1QixjQUFTLEdBQW1CLEVBQUUsQ0FBQztRQUUvQixpQkFBWSxHQUFHLEtBQUssQ0FBQztRQUNyQixnQkFBVyxHQUFHLElBQUksQ0FBQztRQUluQixZQUFPLEdBQWlCLEVBQUUsQ0FBQztRQUMzQixxQkFBZ0IsR0FBRyxJQUFJLENBQUM7UUFVOUIsSUFBSSxDQUFDLFdBQVcs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QzVELENBQUM7SUFFRCxNQUFNO1FBQ0osSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7SUFDM0IsQ0FBQztJQUVELE9BQU87UUFDTCxJQUFJLENBQUMsS0FBSyxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztRQUMxRCxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBRTtZQUNqQyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUM3QyxDQUFDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN6RSxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNyQixJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7WUFDbEQsSUFBSSxDQUFDLFdBQVcsR0FBRyxTQUFTLENBQUM7UUFDL0IsQ0FBQztRQUNELElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztJQUM1QixDQUFDO0lBRUQsY0FBYztRQUNaLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUM7SUFDL0IsQ0FBQztJQUVELEtBQUs7UUFDSCxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUM7SUFDakIsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWNFbnRpdHkgfSBmcm9tICcuLi8uLi9hbmd1bGFyLWNlc2l1bS9tb2RlbHMvYWMtZW50aXR5JztcbmltcG9ydCB7IEVkaXRQb2ludCB9IGZyb20gJy4vZWRpdC1wb2ludCc7XG5pbXBvcnQgeyBFZGl0UG9seWxpbmUgfSBmcm9tICcuL2VkaXQtcG9seWxpbmUnO1xuaW1wb3J0IHsgQWNMYXllckNvbXBvbmVudCB9IGZyb20gJy4uLy4uL2FuZ3VsYXItY2VzaXVtL2NvbXBvbmVudHMvYWMtbGF5ZXIvYWMtbGF5ZXIuY29tcG9uZW50JztcbmltcG9ydCB7IENhcnRlc2lhbjMgfSBmcm9tICcuLi8uLi9hbmd1bGFyLWNlc2l1bS9tb2RlbHMvY2FydGVzaWFuMyc7XG5pbXBvcnQgeyBDb29yZGluYXRlQ29udmVydGVyIH0gZnJvbSAnLi4vLi4vYW5ndWxhci1jZXNpdW0vc2VydmljZXMvY29vcmRpbmF0ZS1jb252ZXJ0ZXIvY29vcmRpbmF0ZS1jb252ZXJ0ZXIuc2VydmljZSc7XG5pbXBvcnQgeyBQb2ludFByb3BzIH0gZnJvbSAnLi9wb2ludC1lZGl0LW9wdGlvbnMnO1xuaW1wb3J0IHsgUG9seWxpbmVFZGl0T3B0aW9ucywgUG9seWxpbmVQcm9wcyB9IGZyb20gJy4vcG9seWxpbmUtZWRpdC1vcHRpb25zJztcbmltcG9ydCB7IEdlb1V0aWxzU2VydmljZSB9IGZyb20gJy4uLy4uL2FuZ3VsYXItY2VzaXVtL3NlcnZpY2VzL2dlby11dGlscy9nZW8tdXRpbHMuc2VydmljZSc7XG5pbXBvcnQgeyBkZWZhdWx0TGFiZWxQcm9wcywgTGFiZWxQcm9wcyB9IGZyb20gJy4vbGFiZWwtcHJvcHMnO1xuXG5leHBvcnQgY2xhc3MgRWRpdGFibGVQb2x5bGluZSBleHRlbmRzIEFjRW50aXR5IHtcbiAgcHJpdmF0ZSBwb3NpdGlvbnM6IEVkaXRQb2ludFtdID0gW107XG5cbiAgcHJpdmF0ZSBwb2x5bGluZXM6IEVkaXRQb2x5bGluZVtdID0gW107XG4gIHByaXZhdGUgbW92aW5nUG9pbnQ6IEVkaXRQb2ludDtcbiAgcHJpdmF0ZSBkb25lQ3JlYXRpb24gPSBmYWxzZTtcbiAgcHJpdmF0ZSBfZW5hYmxlRWRpdCA9IHRydWU7XG4gIHByaXZhdGUgX3BvaW50UHJvcHM6IFBvaW50UHJvcHM7XG4gIHByaXZhdGUgcG9seWxpbmVQcm9wczogUG9seWxpbmVQcm9wcztcbiAgcHJpdmF0ZSBsYXN0RHJhZ2dlZFRvUG9zaXRpb246IGFueTtcbiAgcHJpdmF0ZSBfbGFiZWxzOiBMYWJlbFByb3BzW10gPSBbXTtcbiAgcHJpdmF0ZSBfb3V0bGluZUluc3RhbmNlID0gbnVsbDtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGlkOiBzdHJpbmcsXG4gICAgICAgICAgICAgIHByaXZhdGUgcG9pbnRzTGF5ZXI6IEFjTGF5ZXJDb21wb25lbnQsXG4gICAgICAgICAgICAgIHByaXZhdGUgcG9seWxpbmVzTGF5ZXI6IEFjTGF5ZXJDb21wb25lbnQsXG4gICAgICAgICAgICAgIHByaXZhdGUgY29vcmRpbmF0ZUNvbnZlcnRlcjogQ29vcmRpbmF0ZUNvbnZlcnRlcixcbiAgICAgICAgICAgICAgcHJpdmF0ZSBzY2VuZTogYW55LFxuICAgICAgICAgICAgICBwcml2YXRlIGVkaXRPcHRpb25zOiBQb2x5bGluZUVkaXRPcHRpb25zLFxuICAgICAgICAgICAgICBwb3NpdGlvbnM/OiBDYXJ0ZXNpYW4zW10pIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuX3BvaW50UHJvcHMgPSB7Li4uZWRpdE9wdGlvbnMucG9pbnRQcm9wc307XG4gICAgdGhpcy5wcm9wcyA9IHsuLi5lZGl0T3B0aW9ucy5wb2x5bGluZVByb3BzfTtcbiAgICBpZiAocG9zaXRpb25zICYmIHBvc2l0aW9ucy5sZW5ndGggPj0gMikge1xuICAgICAgdGhpcy5jcmVhdGVGcm9tRXhpc3RpbmcocG9zaXRpb25zKTtcbiAgICB9XG4gIH1cblxuICBnZXQgbGFiZWxzKCk6IExhYmVsUHJvcHNbXSB7XG4gICAgcmV0dXJuIHRoaXMuX2xhYmVscztcbiAgfVxuXG4gIHNldCBsYWJlbHMobGFiZWxzOiBMYWJlbFByb3BzW10pIHtcbiAgICBpZiAoIWxhYmVscykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBwb3NpdGlvbnMgPSB0aGlzLmdldFJlYWxQb3NpdGlvbnMoKTtcbiAgICB0aGlzLl9sYWJlbHMgPSBsYWJlbHMubWFwKChsYWJlbCwgaW5kZXgpID0+IHtcbiAgICAgIGlmICghbGFiZWwucG9zaXRpb24pIHtcbiAgICAgICAgbGFiZWwucG9zaXRpb24gPSBwb3NpdGlvbnNbaW5kZXhdO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgZGVmYXVsdExhYmVsUHJvcHMsIGxhYmVsKTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldCBwcm9wcygpOiBQb2x5bGluZVByb3BzIHtcbiAgICByZXR1cm4gdGhpcy5wb2x5bGluZVByb3BzO1xuICB9XG5cbiAgc2V0IHByb3BzKHZhbHVlOiBQb2x5bGluZVByb3BzKSB7XG4gICAgdGhpcy5wb2x5bGluZVByb3BzID0gdmFsdWU7XG4gIH1cblxuICBnZXQgcG9pbnRQcm9wcygpOiBQb2ludFByb3BzIHtcbiAgICByZXR1cm4gdGhpcy5fcG9pbnRQcm9wcztcbiAgfVxuXG4gIHNldCBwb2ludFByb3BzKHZhbHVlOiBQb2ludFByb3BzKSB7XG4gICAgdGhpcy5fcG9pbnRQcm9wcyA9IHZhbHVlO1xuICB9XG5cbiAgZ2V0IGVuYWJsZUVkaXQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2VuYWJsZUVkaXQ7XG4gIH1cblxuICBzZXQgZW5hYmxlRWRpdCh2YWx1ZTogYm9vbGVhbikge1xuICAgIHRoaXMuX2VuYWJsZUVkaXQgPSB2YWx1ZTtcbiAgICB0aGlzLnBvc2l0aW9ucy5mb3JFYWNoKHBvaW50ID0+IHtcbiAgICAgIHBvaW50LnNob3cgPSB2YWx1ZTtcbiAgICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIoZmFsc2UsIHBvaW50KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlRnJvbUV4aXN0aW5nKHBvc2l0aW9uczogQ2FydGVzaWFuM1tdKSB7XG4gICAgcG9zaXRpb25zLmZvckVhY2goKHBvc2l0aW9uKSA9PiB7XG4gICAgICB0aGlzLmFkZFBvaW50RnJvbUV4aXN0aW5nKHBvc2l0aW9uKTtcbiAgICB9KTtcbiAgICB0aGlzLmFkZEFsbFZpcnR1YWxFZGl0UG9pbnRzKCk7XG4gICAgdGhpcy5kb25lQ3JlYXRpb24gPSB0cnVlO1xuICB9XG5cbiAgc2V0TWFudWFsbHkocG9pbnRzOiB7XG4gICAgcG9zaXRpb246IENhcnRlc2lhbjMsXG4gICAgcG9pbnRQcm9wPzogUG9pbnRQcm9wc1xuICB9W10gfCBDYXJ0ZXNpYW4zW10sIHBvbHlsaW5lUHJvcHM/OiBQb2x5bGluZVByb3BzKSB7XG4gICAgaWYgKCF0aGlzLmRvbmVDcmVhdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVcGRhdGUgbWFudWFsbHkgb25seSBpbiBlZGl0IG1vZGUsIGFmdGVyIHBvbHlsaW5lIGlzIGNyZWF0ZWQnKTtcbiAgICB9XG4gICAgdGhpcy5wb3NpdGlvbnMuZm9yRWFjaChwID0+IHRoaXMucG9pbnRzTGF5ZXIucmVtb3ZlKHAuZ2V0SWQoKSkpO1xuXG4gICAgY29uc3QgbmV3UG9pbnRzOiBFZGl0UG9pbnRbXSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBwb2ludE9yQ2FydGVzaWFuOiBhbnkgPSBwb2ludHNbaV07XG4gICAgICBsZXQgbmV3UG9pbnQgPSBudWxsO1xuICAgICAgaWYgKHBvaW50T3JDYXJ0ZXNpYW4ucG9pbnRQcm9wcykge1xuICAgICAgICBuZXdQb2ludCA9IG5ldyBFZGl0UG9pbnQodGhpcy5pZCwgcG9pbnRPckNhcnRlc2lhbi5wb3NpdGlvbiwgcG9pbnRPckNhcnRlc2lhbi5wb2ludFByb3BzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5ld1BvaW50ID0gbmV3IEVkaXRQb2ludCh0aGlzLmlkLCBwb2ludE9yQ2FydGVzaWFuLCB0aGlzLl9wb2ludFByb3BzKTtcbiAgICAgIH1cbiAgICAgIG5ld1BvaW50cy5wdXNoKG5ld1BvaW50KTtcbiAgICB9XG4gICAgdGhpcy5wb3NpdGlvbnMgPSBuZXdQb2ludHM7XG4gICAgdGhpcy5wb2x5bGluZVByb3BzID0gcG9seWxpbmVQcm9wcyA/IHBvbHlsaW5lUHJvcHMgOiB0aGlzLnBvbHlsaW5lUHJvcHM7XG5cbiAgICB0aGlzLnVwZGF0ZVBvaW50c0xheWVyKHRydWUsIC4uLnRoaXMucG9zaXRpb25zKTtcbiAgICB0aGlzLmFkZEFsbFZpcnR1YWxFZGl0UG9pbnRzKCk7XG4gIH1cblxuICBwcml2YXRlIGFkZEFsbFZpcnR1YWxFZGl0UG9pbnRzKCkge1xuICAgIGNvbnN0IGN1cnJlbnRQb2ludHMgPSBbLi4udGhpcy5wb3NpdGlvbnNdO1xuICAgIGN1cnJlbnRQb2ludHMuZm9yRWFjaCgocG9zLCBpbmRleCkgPT4ge1xuICAgICAgaWYgKGluZGV4ICE9PSBjdXJyZW50UG9pbnRzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgY29uc3QgY3VycmVudFBvaW50ID0gcG9zO1xuICAgICAgICBjb25zdCBuZXh0SW5kZXggPSAoaW5kZXggKyAxKSAlIChjdXJyZW50UG9pbnRzLmxlbmd0aCk7XG4gICAgICAgIGNvbnN0IG5leHRQb2ludCA9IGN1cnJlbnRQb2ludHNbbmV4dEluZGV4XTtcblxuICAgICAgICBjb25zdCBtaWRQb2ludCA9IHRoaXMuc2V0TWlkZGxlVmlydHVhbFBvaW50KGN1cnJlbnRQb2ludCwgbmV4dFBvaW50KTtcblxuICAgICAgICB0aGlzLnVwZGF0ZVBvaW50c0xheWVyKGZhbHNlLCBtaWRQb2ludCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHNldE1pZGRsZVZpcnR1YWxQb2ludChmaXJzdFA6IEVkaXRQb2ludCwgc2Vjb25kUDogRWRpdFBvaW50KTogRWRpdFBvaW50IHtcbiAgICBjb25zdCBtaWRQb2ludENhcnRlc2lhbjMgPSBDZXNpdW0uQ2FydGVzaWFuMy5sZXJwKGZpcnN0UC5nZXRQb3NpdGlvbigpLCBzZWNvbmRQLmdldFBvc2l0aW9uKCksIDAuNSwgbmV3IENlc2l1bS5DYXJ0ZXNpYW4zKCkpO1xuICAgIGNvbnN0IG1pZFBvaW50ID0gbmV3IEVkaXRQb2ludCh0aGlzLmlkLCBtaWRQb2ludENhcnRlc2lhbjMsIHRoaXMuX3BvaW50UHJvcHMpO1xuICAgIG1pZFBvaW50LnNldFZpcnR1YWxFZGl0UG9pbnQodHJ1ZSk7XG5cbiAgICBjb25zdCBmaXJzdEluZGV4ID0gdGhpcy5wb3NpdGlvbnMuaW5kZXhPZihmaXJzdFApO1xuICAgIHRoaXMucG9zaXRpb25zLnNwbGljZShmaXJzdEluZGV4ICsgMSwgMCwgbWlkUG9pbnQpO1xuICAgIHJldHVybiBtaWRQb2ludDtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlTWlkZGxlVmlydHVhbFBvaW50KHZpcnR1YWxFZGl0UG9pbnQ6IEVkaXRQb2ludCwgcHJldlBvaW50OiBFZGl0UG9pbnQsIG5leHRQb2ludDogRWRpdFBvaW50KSB7XG4gICAgY29uc3QgbWlkUG9pbnRDYXJ0ZXNpYW4zID0gQ2VzaXVtLkNhcnRlc2lhbjMubGVycChwcmV2UG9pbnQuZ2V0UG9zaXRpb24oKSwgbmV4dFBvaW50LmdldFBvc2l0aW9uKCksIDAuNSwgbmV3IENlc2l1bS5DYXJ0ZXNpYW4zKCkpO1xuICAgIHZpcnR1YWxFZGl0UG9pbnQuc2V0UG9zaXRpb24obWlkUG9pbnRDYXJ0ZXNpYW4zKTtcbiAgfVxuXG4gIGNoYW5nZVZpcnR1YWxQb2ludFRvUmVhbFBvaW50KHBvaW50OiBFZGl0UG9pbnQpIHtcbiAgICBwb2ludC5zZXRWaXJ0dWFsRWRpdFBvaW50KGZhbHNlKTsgLy8gYWN0dWFsIHBvaW50IGJlY29tZXMgYSByZWFsIHBvaW50XG4gICAgY29uc3QgcG9pbnRzQ291bnQgPSB0aGlzLnBvc2l0aW9ucy5sZW5ndGg7XG4gICAgY29uc3QgcG9pbnRJbmRleCA9IHRoaXMucG9zaXRpb25zLmluZGV4T2YocG9pbnQpO1xuICAgIGNvbnN0IG5leHRJbmRleCA9IChwb2ludEluZGV4ICsgMSkgJSAocG9pbnRzQ291bnQpO1xuICAgIGNvbnN0IHByZUluZGV4ID0gKChwb2ludEluZGV4IC0gMSkgKyBwb2ludHNDb3VudCkgJSBwb2ludHNDb3VudDtcblxuICAgIGNvbnN0IG5leHRQb2ludCA9IHRoaXMucG9zaXRpb25zW25leHRJbmRleF07XG4gICAgY29uc3QgcHJlUG9pbnQgPSB0aGlzLnBvc2l0aW9uc1twcmVJbmRleF07XG5cbiAgICBjb25zdCBmaXJzdE1pZFBvaW50ID0gdGhpcy5zZXRNaWRkbGVWaXJ0dWFsUG9pbnQocHJlUG9pbnQsIHBvaW50KTtcbiAgICBjb25zdCBzZWNNaWRQb2ludCA9IHRoaXMuc2V0TWlkZGxlVmlydHVhbFBvaW50KHBvaW50LCBuZXh0UG9pbnQpO1xuICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIoZmFsc2UsIGZpcnN0TWlkUG9pbnQsIHNlY01pZFBvaW50LCBwb2ludCk7XG5cbiAgfVxuXG4gIHByaXZhdGUgcmVuZGVyUG9seWxpbmVzKCkge1xuICAgIGNvbnN0IHJlYWxQb2ludHMgPSB0aGlzLnBvc2l0aW9ucy5maWx0ZXIocG9pbnQgPT4gIXBvaW50LmlzVmlydHVhbEVkaXRQb2ludCgpKTtcbiAgICBpZiAodGhpcy5wb2x5bGluZVByb3BzLnVzZUdyb3VuZFByaW1pdGl2ZU91dGxpbmUpIHtcbiAgICAgIGlmIChyZWFsUG9pbnRzLmxlbmd0aCA8IDIpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy5zY2VuZS5ncm91bmRQcmltaXRpdmVzLnJlbW92ZSh0aGlzLl9vdXRsaW5lSW5zdGFuY2UpO1xuICAgICAgY29uc3QgaW5zdGFuY2UgPSBuZXcgQ2VzaXVtLkdlb21ldHJ5SW5zdGFuY2Uoe1xuICAgICAgICBnZW9tZXRyeTogbmV3IENlc2l1bS5Hcm91bmRQb2x5bGluZUdlb21ldHJ5KHtcbiAgICAgICAgICBwb3NpdGlvbnM6IHRoaXMucG9zaXRpb25zLm1hcChwID0+IHAuZ2V0UG9zaXRpb24oKSksXG4gICAgICAgICAgd2lkdGg6IHRoaXMucG9seWxpbmVQcm9wcy53aWR0aCxcbiAgICAgICAgICBsb29wOiBmYWxzZVxuICAgICAgICB9KSxcbiAgICAgICAgaWQ6ICdlZGl0LXBvbHlnb24tb3V0bGluZS0nICsgdGhpcy5pZCxcbiAgICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAgIGNvbG9yOiBDZXNpdW0uQ29sb3JHZW9tZXRyeUluc3RhbmNlQXR0cmlidXRlLmZyb21Db2xvcih0aGlzLnBvbHlsaW5lUHJvcHMubWF0ZXJpYWwoKSlcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICB0aGlzLl9vdXRsaW5lSW5zdGFuY2UgPSB0aGlzLnNjZW5lLmdyb3VuZFByaW1pdGl2ZXMuYWRkKFxuICAgICAgICBuZXcgQ2VzaXVtLkdyb3VuZFBvbHlsaW5lUHJpbWl0aXZlKHtcbiAgICAgICAgICBnZW9tZXRyeUluc3RhbmNlczogaW5zdGFuY2UsXG4gICAgICAgICAgYXN5bmNocm9ub3VzOiBmYWxzZSxcbiAgICAgICAgICBhcHBlYXJhbmNlOiBuZXcgQ2VzaXVtLlBvbHlsaW5lQ29sb3JBcHBlYXJhbmNlKClcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucG9seWxpbmVzLmZvckVhY2gocG9seWxpbmUgPT4gdGhpcy5wb2x5bGluZXNMYXllci5yZW1vdmUocG9seWxpbmUuZ2V0SWQoKSkpO1xuICAgICAgdGhpcy5wb2x5bGluZXMgPSBbXTtcbiAgICAgIHJlYWxQb2ludHMuZm9yRWFjaCgocG9pbnQsIGluZGV4KSA9PiB7XG4gICAgICAgIGlmIChpbmRleCAhPT0gcmVhbFBvaW50cy5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgY29uc3QgbmV4dEluZGV4ID0gKGluZGV4ICsgMSk7XG4gICAgICAgICAgY29uc3QgbmV4dFBvaW50ID0gcmVhbFBvaW50c1tuZXh0SW5kZXhdO1xuICAgICAgICAgIGNvbnN0IHBvbHlsaW5lID0gbmV3IEVkaXRQb2x5bGluZSh0aGlzLmlkLCBwb2ludC5nZXRQb3NpdGlvbigpLCBuZXh0UG9pbnQuZ2V0UG9zaXRpb24oKSwgdGhpcy5wb2x5bGluZVByb3BzKTtcbiAgICAgICAgICB0aGlzLnBvbHlsaW5lcy5wdXNoKHBvbHlsaW5lKTtcbiAgICAgICAgICB0aGlzLnBvbHlsaW5lc0xheWVyLnVwZGF0ZShwb2x5bGluZSwgcG9seWxpbmUuZ2V0SWQoKSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGFkZFBvaW50RnJvbUV4aXN0aW5nKHBvc2l0aW9uOiBDYXJ0ZXNpYW4zKSB7XG4gICAgY29uc3QgbmV3UG9pbnQgPSBuZXcgRWRpdFBvaW50KHRoaXMuaWQsIHBvc2l0aW9uLCB0aGlzLl9wb2ludFByb3BzKTtcbiAgICB0aGlzLnBvc2l0aW9ucy5wdXNoKG5ld1BvaW50KTtcbiAgICB0aGlzLnVwZGF0ZVBvaW50c0xheWVyKHRydWUsIG5ld1BvaW50KTtcbiAgfVxuXG5cbiAgYWRkUG9pbnQocG9zaXRpb246IENhcnRlc2lhbjMpIHtcbiAgICBpZiAodGhpcy5kb25lQ3JlYXRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgaXNGaXJzdFBvaW50ID0gIXRoaXMucG9zaXRpb25zLmxlbmd0aDtcbiAgICBpZiAoaXNGaXJzdFBvaW50KSB7XG4gICAgICBjb25zdCBmaXJzdFBvaW50ID0gbmV3IEVkaXRQb2ludCh0aGlzLmlkLCBwb3NpdGlvbiwgdGhpcy5fcG9pbnRQcm9wcyk7XG4gICAgICB0aGlzLnBvc2l0aW9ucy5wdXNoKGZpcnN0UG9pbnQpO1xuICAgICAgdGhpcy51cGRhdGVQb2ludHNMYXllcih0cnVlLCBmaXJzdFBvaW50KTtcbiAgICB9XG5cbiAgICB0aGlzLm1vdmluZ1BvaW50ID0gbmV3IEVkaXRQb2ludCh0aGlzLmlkLCBwb3NpdGlvbi5jbG9uZSgpLCB0aGlzLl9wb2ludFByb3BzKTtcbiAgICB0aGlzLnBvc2l0aW9ucy5wdXNoKHRoaXMubW92aW5nUG9pbnQpO1xuXG4gICAgdGhpcy51cGRhdGVQb2ludHNMYXllcih0cnVlLCB0aGlzLm1vdmluZ1BvaW50KTtcbiAgfVxuXG4gIG1vdmVQb2ludEZpbmlzaChlZGl0UG9pbnQ6IEVkaXRQb2ludCkge1xuICAgIGlmICh0aGlzLmVkaXRPcHRpb25zLmNsYW1wSGVpZ2h0VG8zRCkge1xuICAgICAgZWRpdFBvaW50LnByb3BzLmRpc2FibGVEZXB0aFRlc3REaXN0YW5jZSA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTtcbiAgICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIoZmFsc2UsIGVkaXRQb2ludCk7XG4gICAgfVxuICB9XG5cbiAgbW92ZVBvaW50KHRvUG9zaXRpb246IENhcnRlc2lhbjMsIGVkaXRQb2ludDogRWRpdFBvaW50KSB7XG4gICAgZWRpdFBvaW50LnNldFBvc2l0aW9uKHRvUG9zaXRpb24pO1xuICAgIGlmICh0aGlzLmRvbmVDcmVhdGlvbikge1xuICAgICAgaWYgKGVkaXRQb2ludC5wcm9wcy5kaXNhYmxlRGVwdGhUZXN0RGlzdGFuY2UgJiYgdGhpcy5lZGl0T3B0aW9ucy5jbGFtcEhlaWdodFRvM0QpIHtcbiAgICAgICAgLy8gVG8gYXZvaWQgYnVnIHdpdGggcGlja1Bvc2l0aW9uKCkgb24gcG9pbnQgd2l0aCBkaXNhYmxlRGVwdGhUZXN0RGlzdGFuY2VcbiAgICAgICAgZWRpdFBvaW50LnByb3BzLmRpc2FibGVEZXB0aFRlc3REaXN0YW5jZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuOyAvLyBpZ25vcmUgZmlyc3QgbW92ZSBiZWNhdXNlIHRoZSBwaWNrUG9zaXRpb24oKSBjb3VsZCBiZSB3cm9uZ1xuICAgICAgfVxuXG4gICAgICBpZiAoZWRpdFBvaW50LmlzVmlydHVhbEVkaXRQb2ludCgpKSB7XG4gICAgICAgIHRoaXMuY2hhbmdlVmlydHVhbFBvaW50VG9SZWFsUG9pbnQoZWRpdFBvaW50KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHBvaW50c0NvdW50ID0gdGhpcy5wb3NpdGlvbnMubGVuZ3RoO1xuICAgICAgY29uc3QgcG9pbnRJbmRleCA9IHRoaXMucG9zaXRpb25zLmluZGV4T2YoZWRpdFBvaW50KTtcblxuICAgICAgaWYgKHBvaW50SW5kZXggPCB0aGlzLnBvc2l0aW9ucy5sZW5ndGggLSAxKSB7XG4gICAgICAgIGNvbnN0IG5leHRWaXJ0dWFsUG9pbnQgPSB0aGlzLnBvc2l0aW9uc1socG9pbnRJbmRleCArIDEpICUgKHBvaW50c0NvdW50KV07XG4gICAgICAgIGNvbnN0IG5leHRSZWFsUG9pbnQgPSB0aGlzLnBvc2l0aW9uc1socG9pbnRJbmRleCArIDIpICUgKHBvaW50c0NvdW50KV07XG4gICAgICAgIHRoaXMudXBkYXRlTWlkZGxlVmlydHVhbFBvaW50KG5leHRWaXJ0dWFsUG9pbnQsIGVkaXRQb2ludCwgbmV4dFJlYWxQb2ludCk7XG4gICAgICB9XG4gICAgICBpZiAocG9pbnRJbmRleCA+IDApIHtcbiAgICAgICAgY29uc3QgcHJldlZpcnR1YWxQb2ludCA9IHRoaXMucG9zaXRpb25zWygocG9pbnRJbmRleCAtIDEpICsgcG9pbnRzQ291bnQpICUgcG9pbnRzQ291bnRdO1xuICAgICAgICBjb25zdCBwcmV2UmVhbFBvaW50ID0gdGhpcy5wb3NpdGlvbnNbKChwb2ludEluZGV4IC0gMikgKyBwb2ludHNDb3VudCkgJSBwb2ludHNDb3VudF07XG4gICAgICAgIHRoaXMudXBkYXRlTWlkZGxlVmlydHVhbFBvaW50KHByZXZWaXJ0dWFsUG9pbnQsIGVkaXRQb2ludCwgcHJldlJlYWxQb2ludCk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIodHJ1ZSwgZWRpdFBvaW50KTtcbiAgfVxuXG4gIG1vdmVUZW1wTW92aW5nUG9pbnQodG9Qb3NpdGlvbjogQ2FydGVzaWFuMykge1xuICAgIGlmICh0aGlzLm1vdmluZ1BvaW50KSB7XG4gICAgICB0aGlzLm1vdmVQb2ludCh0b1Bvc2l0aW9uLCB0aGlzLm1vdmluZ1BvaW50KTtcbiAgICB9XG4gIH1cblxuICBtb3ZlU2hhcGUoc3RhcnRNb3ZpbmdQb3NpdGlvbjogQ2FydGVzaWFuMywgZHJhZ2dlZFRvUG9zaXRpb246IENhcnRlc2lhbjMpIHtcbiAgICBpZiAoIXRoaXMuZG9uZUNyZWF0aW9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghdGhpcy5sYXN0RHJhZ2dlZFRvUG9zaXRpb24pIHtcbiAgICAgIHRoaXMubGFzdERyYWdnZWRUb1Bvc2l0aW9uID0gc3RhcnRNb3ZpbmdQb3NpdGlvbjtcbiAgICB9XG5cbiAgICBjb25zdCBkZWx0YSA9IEdlb1V0aWxzU2VydmljZS5nZXRQb3NpdGlvbnNEZWx0YSh0aGlzLmxhc3REcmFnZ2VkVG9Qb3NpdGlvbiwgZHJhZ2dlZFRvUG9zaXRpb24pO1xuICAgIHRoaXMucG9zaXRpb25zLmZvckVhY2gocG9pbnQgPT4ge1xuICAgICAgY29uc3QgbmV3UG9zID0gR2VvVXRpbHNTZXJ2aWNlLmFkZERlbHRhVG9Qb3NpdGlvbihwb2ludC5nZXRQb3NpdGlvbigpLCBkZWx0YSwgdHJ1ZSk7XG4gICAgICBwb2ludC5zZXRQb3NpdGlvbihuZXdQb3MpO1xuICAgIH0pO1xuICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIodHJ1ZSwgLi4udGhpcy5wb3NpdGlvbnMpO1xuICAgIHRoaXMubGFzdERyYWdnZWRUb1Bvc2l0aW9uID0gZHJhZ2dlZFRvUG9zaXRpb247XG4gIH1cblxuICBlbmRNb3ZlU2hhcGUoKSB7XG4gICAgdGhpcy5sYXN0RHJhZ2dlZFRvUG9zaXRpb24gPSB1bmRlZmluZWQ7XG4gICAgdGhpcy51cGRhdGVQb2ludHNMYXllcih0cnVlLCAuLi50aGlzLnBvc2l0aW9ucyk7XG4gIH1cblxuICByZW1vdmVQb2ludChwb2ludFRvUmVtb3ZlOiBFZGl0UG9pbnQpIHtcbiAgICB0aGlzLnJlbW92ZVBvc2l0aW9uKHBvaW50VG9SZW1vdmUpO1xuICAgIHRoaXMucG9zaXRpb25zXG4gICAgICAuZmlsdGVyKHAgPT4gcC5pc1ZpcnR1YWxFZGl0UG9pbnQoKSlcbiAgICAgIC5mb3JFYWNoKHAgPT4gdGhpcy5yZW1vdmVQb3NpdGlvbihwKSk7XG4gICAgdGhpcy5hZGRBbGxWaXJ0dWFsRWRpdFBvaW50cygpO1xuXG4gICAgdGhpcy5yZW5kZXJQb2x5bGluZXMoKTtcbiAgfVxuXG4gIGFkZExhc3RQb2ludChwb3NpdGlvbjogQ2FydGVzaWFuMykge1xuICAgIHRoaXMuZG9uZUNyZWF0aW9uID0gdHJ1ZTtcbiAgICB0aGlzLnJlbW92ZVBvc2l0aW9uKHRoaXMubW92aW5nUG9pbnQpOyAvLyByZW1vdmUgbW92aW5nUG9pbnRcbiAgICB0aGlzLm1vdmluZ1BvaW50ID0gbnVsbDtcblxuICAgIHRoaXMuYWRkQWxsVmlydHVhbEVkaXRQb2ludHMoKTtcbiAgfVxuXG4gIGdldFJlYWxQb3NpdGlvbnMoKTogQ2FydGVzaWFuM1tdIHtcbiAgICByZXR1cm4gdGhpcy5nZXRSZWFsUG9pbnRzKClcbiAgICAgIC5tYXAocG9zaXRpb24gPT4gcG9zaXRpb24uZ2V0UG9zaXRpb24oKSk7XG4gIH1cblxuICBnZXRSZWFsUG9pbnRzKCk6IEVkaXRQb2ludFtdIHtcbiAgICByZXR1cm4gdGhpcy5wb3NpdGlvbnNcbiAgICAgIC5maWx0ZXIocG9zaXRpb24gPT4gIXBvc2l0aW9uLmlzVmlydHVhbEVkaXRQb2ludCgpICYmIHBvc2l0aW9uICE9PSB0aGlzLm1vdmluZ1BvaW50KTtcbiAgfVxuXG4gIGdldFBvaW50cygpOiBFZGl0UG9pbnRbXSB7XG4gICAgcmV0dXJuIHRoaXMucG9zaXRpb25zLmZpbHRlcihwb3NpdGlvbiA9PiBwb3NpdGlvbiAhPT0gdGhpcy5tb3ZpbmdQb2ludCk7XG4gIH1cblxuICBnZXRQb3NpdGlvbnMoKTogQ2FydGVzaWFuM1tdIHtcbiAgICByZXR1cm4gdGhpcy5wb3NpdGlvbnMubWFwKHBvc2l0aW9uID0+IHBvc2l0aW9uLmdldFBvc2l0aW9uKCkpO1xuICB9XG5cbiAgZ2V0UG9zaXRpb25zQ2FsbGJhY2tQcm9wZXJ0eSgpOiBDYXJ0ZXNpYW4zW10ge1xuICAgIHJldHVybiBuZXcgQ2VzaXVtLkNhbGxiYWNrUHJvcGVydHkodGhpcy5nZXRQb3NpdGlvbnMuYmluZCh0aGlzKSwgZmFsc2UpO1xuICB9XG5cbiAgcHJpdmF0ZSByZW1vdmVQb3NpdGlvbihwb2ludDogRWRpdFBvaW50KSB7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLnBvc2l0aW9ucy5maW5kSW5kZXgoKHApID0+IHAgPT09IHBvaW50KTtcbiAgICBpZiAoaW5kZXggPCAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMucG9zaXRpb25zLnNwbGljZShpbmRleCwgMSk7XG4gICAgdGhpcy5wb2ludHNMYXllci5yZW1vdmUocG9pbnQuZ2V0SWQoKSk7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZVBvaW50c0xheWVyKHJlbmRlclBvbHlsaW5lcyA9IHRydWUsIC4uLnBvaW50OiBFZGl0UG9pbnRbXSkge1xuICAgIGlmIChyZW5kZXJQb2x5bGluZXMpIHtcbiAgICAgIHRoaXMucmVuZGVyUG9seWxpbmVzKCk7XG4gICAgfVxuICAgIHBvaW50LmZvckVhY2gocCA9PiB0aGlzLnBvaW50c0xheWVyLnVwZGF0ZShwLCBwLmdldElkKCkpKTtcbiAgfVxuXG4gIHVwZGF0ZSgpIHtcbiAgICB0aGlzLnVwZGF0ZVBvaW50c0xheWVyKCk7XG4gIH1cblxuICBkaXNwb3NlKCkge1xuICAgIHRoaXMuc2NlbmUuZ3JvdW5kUHJpbWl0aXZlcy5yZW1vdmUodGhpcy5fb3V0bGluZUluc3RhbmNlKTtcbiAgICB0aGlzLnBvc2l0aW9ucy5mb3JFYWNoKGVkaXRQb2ludCA9PiB7XG4gICAgICB0aGlzLnBvaW50c0xheWVyLnJlbW92ZShlZGl0UG9pbnQuZ2V0SWQoKSk7XG4gICAgfSk7XG4gICAgdGhpcy5wb2x5bGluZXMuZm9yRWFjaChsaW5lID0+IHRoaXMucG9seWxpbmVzTGF5ZXIucmVtb3ZlKGxpbmUuZ2V0SWQoKSkpO1xuICAgIGlmICh0aGlzLm1vdmluZ1BvaW50KSB7XG4gICAgICB0aGlzLnBvaW50c0xheWVyLnJlbW92ZSh0aGlzLm1vdmluZ1BvaW50LmdldElkKCkpO1xuICAgICAgdGhpcy5tb3ZpbmdQb2ludCA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgdGhpcy5wb3NpdGlvbnMubGVuZ3RoID0gMDtcbiAgfVxuXG4gIGdldFBvaW50c0NvdW50KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMucG9zaXRpb25zLmxlbmd0aDtcbiAgfVxuXG4gIGdldElkKCkge1xuICAgIHJldHVybiB0aGlzLmlkO1xuICB9XG59XG4iXX0=