iceye-angular-cesium-fork
Version:
Angular library for working with Cesium.
282 lines • 42.1 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, editOptions, positions) {
super();
this.id = id;
this.pointsLayer = pointsLayer;
this.polylinesLayer = polylinesLayer;
this.coordinateConverter = coordinateConverter;
this.editOptions = editOptions;
this.positions = [];
this.polylines = [];
this.doneCreation = false;
this._enableEdit = true;
this._labels = [];
this._pointProps = Object.assign({}, editOptions.pointProps);
this.props = Object.assign({}, 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() {
this.polylines.forEach(polyline => this.polylinesLayer.remove(polyline.getId()));
this.polylines = [];
const realPoints = this.positions.filter(point => !point.isVirtualEditPoint());
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.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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdGFibGUtcG9seWxpbmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLWNlc2l1bS9zcmMvbGliL2FuZ3VsYXItY2VzaXVtLXdpZGdldHMvbW9kZWxzL2VkaXRhYmxlLXBvbHlsaW5lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUNqRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQU0vQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sMkRBQTJELENBQUM7QUFDNUYsT0FBTyxFQUFFLGlCQUFpQixFQUFjLE1BQU0sZUFBZSxDQUFDO0FBRTlELE1BQU0sT0FBTyxnQkFBaUIsU0FBUSxRQUFRO0lBWTVDLFlBQW9CLEVBQVUsRUFDVixXQUE2QixFQUM3QixjQUFnQyxFQUNoQyxtQkFBd0MsRUFDeEMsV0FBZ0MsRUFDeEMsU0FBd0I7UUFDbEMsS0FBSyxFQUFFLENBQUM7UUFOVSxPQUFFLEdBQUYsRUFBRSxDQUFRO1FBQ1YsZ0JBQVcsR0FBWCxXQUFXLENBQWtCO1FBQzdCLG1CQUFjLEdBQWQsY0FBYyxDQUFrQjtRQUNoQyx3QkFBbUIsR0FBbkIsbUJBQW1CLENBQXFCO1FBQ3hDLGdCQUFXLEdBQVgsV0FBVyxDQUFxQjtRQWY1QyxjQUFTLEdBQWdCLEVBQUUsQ0FBQztRQUU1QixjQUFTLEdBQW1CLEVBQUUsQ0FBQztRQUUvQixpQkFBWSxHQUFHLEtBQUssQ0FBQztRQUNyQixnQkFBVyxHQUFHLElBQUksQ0FBQztRQUluQixZQUFPLEdBQWlCLEVBQUUsQ0FBQztRQVNqQyxJQUFJLENBQUMsV0FBVyxxQkFBTyxXQUFXLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDL0MsSUFBSSxDQUFDLEtBQUsscUJBQU8sV0FBVyxD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QUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN6RSxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUU7WUFDcEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDO1lBQ2xELElBQUksQ0FBQyxXQUFXLEdBQUcsU0FBUyxDQUFDO1NBQzlCO1FBQ0QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQzVCLENBQUM7SUFFRCxjQUFjO1FBQ1osT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQztJQUMvQixDQUFDO0lBRUQsS0FBSztRQUNILE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQztJQUNqQixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBY0VudGl0eSB9IGZyb20gJy4uLy4uL2FuZ3VsYXItY2VzaXVtL21vZGVscy9hYy1lbnRpdHknO1xuaW1wb3J0IHsgRWRpdFBvaW50IH0gZnJvbSAnLi9lZGl0LXBvaW50JztcbmltcG9ydCB7IEVkaXRQb2x5bGluZSB9IGZyb20gJy4vZWRpdC1wb2x5bGluZSc7XG5pbXBvcnQgeyBBY0xheWVyQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vYW5ndWxhci1jZXNpdW0vY29tcG9uZW50cy9hYy1sYXllci9hYy1sYXllci5jb21wb25lbnQnO1xuaW1wb3J0IHsgQ2FydGVzaWFuMyB9IGZyb20gJy4uLy4uL2FuZ3VsYXItY2VzaXVtL21vZGVscy9jYXJ0ZXNpYW4zJztcbmltcG9ydCB7IENvb3JkaW5hdGVDb252ZXJ0ZXIgfSBmcm9tICcuLi8uLi9hbmd1bGFyLWNlc2l1bS9zZXJ2aWNlcy9jb29yZGluYXRlLWNvbnZlcnRlci9jb29yZGluYXRlLWNvbnZlcnRlci5zZXJ2aWNlJztcbmltcG9ydCB7IFBvaW50UHJvcHMgfSBmcm9tICcuL3BvaW50LWVkaXQtb3B0aW9ucyc7XG5pbXBvcnQgeyBQb2x5bGluZUVkaXRPcHRpb25zLCBQb2x5bGluZVByb3BzIH0gZnJvbSAnLi9wb2x5bGluZS1lZGl0LW9wdGlvbnMnO1xuaW1wb3J0IHsgR2VvVXRpbHNTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vYW5ndWxhci1jZXNpdW0vc2VydmljZXMvZ2VvLXV0aWxzL2dlby11dGlscy5zZXJ2aWNlJztcbmltcG9ydCB7IGRlZmF1bHRMYWJlbFByb3BzLCBMYWJlbFByb3BzIH0gZnJvbSAnLi9sYWJlbC1wcm9wcyc7XG5cbmV4cG9ydCBjbGFzcyBFZGl0YWJsZVBvbHlsaW5lIGV4dGVuZHMgQWNFbnRpdHkge1xuICBwcml2YXRlIHBvc2l0aW9uczogRWRpdFBvaW50W10gPSBbXTtcblxuICBwcml2YXRlIHBvbHlsaW5lczogRWRpdFBvbHlsaW5lW10gPSBbXTtcbiAgcHJpdmF0ZSBtb3ZpbmdQb2ludDogRWRpdFBvaW50O1xuICBwcml2YXRlIGRvbmVDcmVhdGlvbiA9IGZhbHNlO1xuICBwcml2YXRlIF9lbmFibGVFZGl0ID0gdHJ1ZTtcbiAgcHJpdmF0ZSBfcG9pbnRQcm9wczogUG9pbnRQcm9wcztcbiAgcHJpdmF0ZSBwb2x5bGluZVByb3BzOiBQb2x5bGluZVByb3BzO1xuICBwcml2YXRlIGxhc3REcmFnZ2VkVG9Qb3NpdGlvbjogYW55O1xuICBwcml2YXRlIF9sYWJlbHM6IExhYmVsUHJvcHNbXSA9IFtdO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgaWQ6IHN0cmluZyxcbiAgICAgICAgICAgICAgcHJpdmF0ZSBwb2ludHNMYXllcjogQWNMYXllckNvbXBvbmVudCxcbiAgICAgICAgICAgICAgcHJpdmF0ZSBwb2x5bGluZXNMYXllcjogQWNMYXllckNvbXBvbmVudCxcbiAgICAgICAgICAgICAgcHJpdmF0ZSBjb29yZGluYXRlQ29udmVydGVyOiBDb29yZGluYXRlQ29udmVydGVyLFxuICAgICAgICAgICAgICBwcml2YXRlIGVkaXRPcHRpb25zOiBQb2x5bGluZUVkaXRPcHRpb25zLFxuICAgICAgICAgICAgICBwb3NpdGlvbnM/OiBDYXJ0ZXNpYW4zW10pIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuX3BvaW50UHJvcHMgPSB7Li4uZWRpdE9wdGlvbnMucG9pbnRQcm9wc307XG4gICAgdGhpcy5wcm9wcyA9IHsuLi5lZGl0T3B0aW9ucy5wb2x5bGluZVByb3BzfTtcbiAgICBpZiAocG9zaXRpb25zICYmIHBvc2l0aW9ucy5sZW5ndGggPj0gMikge1xuICAgICAgdGhpcy5jcmVhdGVGcm9tRXhpc3RpbmcocG9zaXRpb25zKTtcbiAgICB9XG4gIH1cblxuICBnZXQgbGFiZWxzKCk6IExhYmVsUHJvcHNbXSB7XG4gICAgcmV0dXJuIHRoaXMuX2xhYmVscztcbiAgfVxuXG4gIHNldCBsYWJlbHMobGFiZWxzOiBMYWJlbFByb3BzW10pIHtcbiAgICBpZiAoIWxhYmVscykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBwb3NpdGlvbnMgPSB0aGlzLmdldFJlYWxQb3NpdGlvbnMoKTtcbiAgICB0aGlzLl9sYWJlbHMgPSBsYWJlbHMubWFwKChsYWJlbCwgaW5kZXgpID0+IHtcbiAgICAgIGlmICghbGFiZWwucG9zaXRpb24pIHtcbiAgICAgICAgbGFiZWwucG9zaXRpb24gPSBwb3NpdGlvbnNbaW5kZXhdO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbih7fSwgZGVmYXVsdExhYmVsUHJvcHMsIGxhYmVsKTtcbiAgICB9KTtcbiAgfVxuXG4gIGdldCBwcm9wcygpOiBQb2x5bGluZVByb3BzIHtcbiAgICByZXR1cm4gdGhpcy5wb2x5bGluZVByb3BzO1xuICB9XG5cbiAgc2V0IHByb3BzKHZhbHVlOiBQb2x5bGluZVByb3BzKSB7XG4gICAgdGhpcy5wb2x5bGluZVByb3BzID0gdmFsdWU7XG4gIH1cblxuICBnZXQgcG9pbnRQcm9wcygpOiBQb2ludFByb3BzIHtcbiAgICByZXR1cm4gdGhpcy5fcG9pbnRQcm9wcztcbiAgfVxuXG4gIHNldCBwb2ludFByb3BzKHZhbHVlOiBQb2ludFByb3BzKSB7XG4gICAgdGhpcy5fcG9pbnRQcm9wcyA9IHZhbHVlO1xuICB9XG5cbiAgZ2V0IGVuYWJsZUVkaXQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX2VuYWJsZUVkaXQ7XG4gIH1cblxuICBzZXQgZW5hYmxlRWRpdCh2YWx1ZTogYm9vbGVhbikge1xuICAgIHRoaXMuX2VuYWJsZUVkaXQgPSB2YWx1ZTtcbiAgICB0aGlzLnBvc2l0aW9ucy5mb3JFYWNoKHBvaW50ID0+IHtcbiAgICAgIHBvaW50LnNob3cgPSB2YWx1ZTtcbiAgICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIoZmFsc2UsIHBvaW50KTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlRnJvbUV4aXN0aW5nKHBvc2l0aW9uczogQ2FydGVzaWFuM1tdKSB7XG4gICAgcG9zaXRpb25zLmZvckVhY2goKHBvc2l0aW9uKSA9PiB7XG4gICAgICB0aGlzLmFkZFBvaW50RnJvbUV4aXN0aW5nKHBvc2l0aW9uKTtcbiAgICB9KTtcbiAgICB0aGlzLmFkZEFsbFZpcnR1YWxFZGl0UG9pbnRzKCk7XG4gICAgdGhpcy5kb25lQ3JlYXRpb24gPSB0cnVlO1xuICB9XG5cbiAgc2V0TWFudWFsbHkocG9pbnRzOiB7XG4gICAgcG9zaXRpb246IENhcnRlc2lhbjMsXG4gICAgcG9pbnRQcm9wPzogUG9pbnRQcm9wc1xuICB9W10gfCBDYXJ0ZXNpYW4zW10sIHBvbHlsaW5lUHJvcHM/OiBQb2x5bGluZVByb3BzKSB7XG4gICAgaWYgKCF0aGlzLmRvbmVDcmVhdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVcGRhdGUgbWFudWFsbHkgb25seSBpbiBlZGl0IG1vZGUsIGFmdGVyIHBvbHlsaW5lIGlzIGNyZWF0ZWQnKTtcbiAgICB9XG4gICAgdGhpcy5wb3NpdGlvbnMuZm9yRWFjaChwID0+IHRoaXMucG9pbnRzTGF5ZXIucmVtb3ZlKHAuZ2V0SWQoKSkpO1xuXG4gICAgY29uc3QgbmV3UG9pbnRzOiBFZGl0UG9pbnRbXSA9IFtdO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBwb2ludE9yQ2FydGVzaWFuOiBhbnkgPSBwb2ludHNbaV07XG4gICAgICBsZXQgbmV3UG9pbnQgPSBudWxsO1xuICAgICAgaWYgKHBvaW50T3JDYXJ0ZXNpYW4ucG9pbnRQcm9wcykge1xuICAgICAgICBuZXdQb2ludCA9IG5ldyBFZGl0UG9pbnQodGhpcy5pZCwgcG9pbnRPckNhcnRlc2lhbi5wb3NpdGlvbiwgcG9pbnRPckNhcnRlc2lhbi5wb2ludFByb3BzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5ld1BvaW50ID0gbmV3IEVkaXRQb2ludCh0aGlzLmlkLCBwb2ludE9yQ2FydGVzaWFuLCB0aGlzLl9wb2ludFByb3BzKTtcbiAgICAgIH1cbiAgICAgIG5ld1BvaW50cy5wdXNoKG5ld1BvaW50KTtcbiAgICB9XG4gICAgdGhpcy5wb3NpdGlvbnMgPSBuZXdQb2ludHM7XG4gICAgdGhpcy5wb2x5bGluZVByb3BzID0gcG9seWxpbmVQcm9wcyA/IHBvbHlsaW5lUHJvcHMgOiB0aGlzLnBvbHlsaW5lUHJvcHM7XG5cbiAgICB0aGlzLnVwZGF0ZVBvaW50c0xheWVyKHRydWUsIC4uLnRoaXMucG9zaXRpb25zKTtcbiAgICB0aGlzLmFkZEFsbFZpcnR1YWxFZGl0UG9pbnRzKCk7XG4gIH1cblxuICBwcml2YXRlIGFkZEFsbFZpcnR1YWxFZGl0UG9pbnRzKCkge1xuICAgIGNvbnN0IGN1cnJlbnRQb2ludHMgPSBbLi4udGhpcy5wb3NpdGlvbnNdO1xuICAgIGN1cnJlbnRQb2ludHMuZm9yRWFjaCgocG9zLCBpbmRleCkgPT4ge1xuICAgICAgaWYgKGluZGV4ICE9PSBjdXJyZW50UG9pbnRzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgY29uc3QgY3VycmVudFBvaW50ID0gcG9zO1xuICAgICAgICBjb25zdCBuZXh0SW5kZXggPSAoaW5kZXggKyAxKSAlIChjdXJyZW50UG9pbnRzLmxlbmd0aCk7XG4gICAgICAgIGNvbnN0IG5leHRQb2ludCA9IGN1cnJlbnRQb2ludHNbbmV4dEluZGV4XTtcblxuICAgICAgICBjb25zdCBtaWRQb2ludCA9IHRoaXMuc2V0TWlkZGxlVmlydHVhbFBvaW50KGN1cnJlbnRQb2ludCwgbmV4dFBvaW50KTtcblxuICAgICAgICB0aGlzLnVwZGF0ZVBvaW50c0xheWVyKGZhbHNlLCBtaWRQb2ludCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHNldE1pZGRsZVZpcnR1YWxQb2ludChmaXJzdFA6IEVkaXRQb2ludCwgc2Vjb25kUDogRWRpdFBvaW50KTogRWRpdFBvaW50IHtcbiAgICBjb25zdCBtaWRQb2ludENhcnRlc2lhbjMgPSBDZXNpdW0uQ2FydGVzaWFuMy5sZXJwKGZpcnN0UC5nZXRQb3NpdGlvbigpLCBzZWNvbmRQLmdldFBvc2l0aW9uKCksIDAuNSwgbmV3IENlc2l1bS5DYXJ0ZXNpYW4zKCkpO1xuICAgIGNvbnN0IG1pZFBvaW50ID0gbmV3IEVkaXRQb2ludCh0aGlzLmlkLCBtaWRQb2ludENhcnRlc2lhbjMsIHRoaXMuX3BvaW50UHJvcHMpO1xuICAgIG1pZFBvaW50LnNldFZpcnR1YWxFZGl0UG9pbnQodHJ1ZSk7XG5cbiAgICBjb25zdCBmaXJzdEluZGV4ID0gdGhpcy5wb3NpdGlvbnMuaW5kZXhPZihmaXJzdFApO1xuICAgIHRoaXMucG9zaXRpb25zLnNwbGljZShmaXJzdEluZGV4ICsgMSwgMCwgbWlkUG9pbnQpO1xuICAgIHJldHVybiBtaWRQb2ludDtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlTWlkZGxlVmlydHVhbFBvaW50KHZpcnR1YWxFZGl0UG9pbnQ6IEVkaXRQb2ludCwgcHJldlBvaW50OiBFZGl0UG9pbnQsIG5leHRQb2ludDogRWRpdFBvaW50KSB7XG4gICAgY29uc3QgbWlkUG9pbnRDYXJ0ZXNpYW4zID0gQ2VzaXVtLkNhcnRlc2lhbjMubGVycChwcmV2UG9pbnQuZ2V0UG9zaXRpb24oKSwgbmV4dFBvaW50LmdldFBvc2l0aW9uKCksIDAuNSwgbmV3IENlc2l1bS5DYXJ0ZXNpYW4zKCkpO1xuICAgIHZpcnR1YWxFZGl0UG9pbnQuc2V0UG9zaXRpb24obWlkUG9pbnRDYXJ0ZXNpYW4zKTtcbiAgfVxuXG4gIGNoYW5nZVZpcnR1YWxQb2ludFRvUmVhbFBvaW50KHBvaW50OiBFZGl0UG9pbnQpIHtcbiAgICBwb2ludC5zZXRWaXJ0dWFsRWRpdFBvaW50KGZhbHNlKTsgLy8gYWN0dWFsIHBvaW50IGJlY29tZXMgYSByZWFsIHBvaW50XG4gICAgY29uc3QgcG9pbnRzQ291bnQgPSB0aGlzLnBvc2l0aW9ucy5sZW5ndGg7XG4gICAgY29uc3QgcG9pbnRJbmRleCA9IHRoaXMucG9zaXRpb25zLmluZGV4T2YocG9pbnQpO1xuICAgIGNvbnN0IG5leHRJbmRleCA9IChwb2ludEluZGV4ICsgMSkgJSAocG9pbnRzQ291bnQpO1xuICAgIGNvbnN0IHByZUluZGV4ID0gKChwb2ludEluZGV4IC0gMSkgKyBwb2ludHNDb3VudCkgJSBwb2ludHNDb3VudDtcblxuICAgIGNvbnN0IG5leHRQb2ludCA9IHRoaXMucG9zaXRpb25zW25leHRJbmRleF07XG4gICAgY29uc3QgcHJlUG9pbnQgPSB0aGlzLnBvc2l0aW9uc1twcmVJbmRleF07XG5cbiAgICBjb25zdCBmaXJzdE1pZFBvaW50ID0gdGhpcy5zZXRNaWRkbGVWaXJ0dWFsUG9pbnQocHJlUG9pbnQsIHBvaW50KTtcbiAgICBjb25zdCBzZWNNaWRQb2ludCA9IHRoaXMuc2V0TWlkZGxlVmlydHVhbFBvaW50KHBvaW50LCBuZXh0UG9pbnQpO1xuICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIoZmFsc2UsIGZpcnN0TWlkUG9pbnQsIHNlY01pZFBvaW50LCBwb2ludCk7XG5cbiAgfVxuXG4gIHByaXZhdGUgcmVuZGVyUG9seWxpbmVzKCkge1xuICAgIHRoaXMucG9seWxpbmVzLmZvckVhY2gocG9seWxpbmUgPT4gdGhpcy5wb2x5bGluZXNMYXllci5yZW1vdmUocG9seWxpbmUuZ2V0SWQoKSkpO1xuICAgIHRoaXMucG9seWxpbmVzID0gW107XG4gICAgY29uc3QgcmVhbFBvaW50cyA9IHRoaXMucG9zaXRpb25zLmZpbHRlcihwb2ludCA9PiAhcG9pbnQuaXNWaXJ0dWFsRWRpdFBvaW50KCkpO1xuICAgIHJlYWxQb2ludHMuZm9yRWFjaCgocG9pbnQsIGluZGV4KSA9PiB7XG4gICAgICBpZiAoaW5kZXggIT09IHJlYWxQb2ludHMubGVuZ3RoIC0gMSkge1xuICAgICAgICBjb25zdCBuZXh0SW5kZXggPSAoaW5kZXggKyAxKTtcbiAgICAgICAgY29uc3QgbmV4dFBvaW50ID0gcmVhbFBvaW50c1tuZXh0SW5kZXhdO1xuICAgICAgICBjb25zdCBwb2x5bGluZSA9IG5ldyBFZGl0UG9seWxpbmUodGhpcy5pZCwgcG9pbnQuZ2V0UG9zaXRpb24oKSwgbmV4dFBvaW50LmdldFBvc2l0aW9uKCksIHRoaXMucG9seWxpbmVQcm9wcyk7XG4gICAgICAgIHRoaXMucG9seWxpbmVzLnB1c2gocG9seWxpbmUpO1xuICAgICAgICB0aGlzLnBvbHlsaW5lc0xheWVyLnVwZGF0ZShwb2x5bGluZSwgcG9seWxpbmUuZ2V0SWQoKSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBhZGRQb2ludEZyb21FeGlzdGluZyhwb3NpdGlvbjogQ2FydGVzaWFuMykge1xuICAgIGNvbnN0IG5ld1BvaW50ID0gbmV3IEVkaXRQb2ludCh0aGlzLmlkLCBwb3NpdGlvbiwgdGhpcy5fcG9pbnRQcm9wcyk7XG4gICAgdGhpcy5wb3NpdGlvbnMucHVzaChuZXdQb2ludCk7XG4gICAgdGhpcy51cGRhdGVQb2ludHNMYXllcih0cnVlLCBuZXdQb2ludCk7XG4gIH1cblxuXG4gIGFkZFBvaW50KHBvc2l0aW9uOiBDYXJ0ZXNpYW4zKSB7XG4gICAgaWYgKHRoaXMuZG9uZUNyZWF0aW9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGlzRmlyc3RQb2ludCA9ICF0aGlzLnBvc2l0aW9ucy5sZW5ndGg7XG4gICAgaWYgKGlzRmlyc3RQb2ludCkge1xuICAgICAgY29uc3QgZmlyc3RQb2ludCA9IG5ldyBFZGl0UG9pbnQodGhpcy5pZCwgcG9zaXRpb24sIHRoaXMuX3BvaW50UHJvcHMpO1xuICAgICAgdGhpcy5wb3NpdGlvbnMucHVzaChmaXJzdFBvaW50KTtcbiAgICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIodHJ1ZSwgZmlyc3RQb2ludCk7XG4gICAgfVxuXG4gICAgdGhpcy5tb3ZpbmdQb2ludCA9IG5ldyBFZGl0UG9pbnQodGhpcy5pZCwgcG9zaXRpb24uY2xvbmUoKSwgdGhpcy5fcG9pbnRQcm9wcyk7XG4gICAgdGhpcy5wb3NpdGlvbnMucHVzaCh0aGlzLm1vdmluZ1BvaW50KTtcblxuICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIodHJ1ZSwgdGhpcy5tb3ZpbmdQb2ludCk7XG4gIH1cblxuICBtb3ZlUG9pbnRGaW5pc2goZWRpdFBvaW50OiBFZGl0UG9pbnQpIHtcbiAgICBpZiAodGhpcy5lZGl0T3B0aW9ucy5jbGFtcEhlaWdodFRvM0QpIHtcbiAgICAgIGVkaXRQb2ludC5wcm9wcy5kaXNhYmxlRGVwdGhUZXN0RGlzdGFuY2UgPSBOdW1iZXIuUE9TSVRJVkVfSU5GSU5JVFk7XG4gICAgICB0aGlzLnVwZGF0ZVBvaW50c0xheWVyKGZhbHNlLCBlZGl0UG9pbnQpO1xuICAgIH1cbiAgfVxuXG4gIG1vdmVQb2ludCh0b1Bvc2l0aW9uOiBDYXJ0ZXNpYW4zLCBlZGl0UG9pbnQ6IEVkaXRQb2ludCkge1xuICAgIGVkaXRQb2ludC5zZXRQb3NpdGlvbih0b1Bvc2l0aW9uKTtcbiAgICBpZiAodGhpcy5kb25lQ3JlYXRpb24pIHtcbiAgICAgIGlmIChlZGl0UG9pbnQucHJvcHMuZGlzYWJsZURlcHRoVGVzdERpc3RhbmNlICYmIHRoaXMuZWRpdE9wdGlvbnMuY2xhbXBIZWlnaHRUbzNEKSB7XG4gICAgICAgIC8vIFRvIGF2b2lkIGJ1ZyB3aXRoIHBpY2tQb3NpdGlvbigpIG9uIHBvaW50IHdpdGggZGlzYWJsZURlcHRoVGVzdERpc3RhbmNlXG4gICAgICAgIGVkaXRQb2ludC5wcm9wcy5kaXNhYmxlRGVwdGhUZXN0RGlzdGFuY2UgPSB1bmRlZmluZWQ7XG4gICAgICAgIHJldHVybjsgLy8gaWdub3JlIGZpcnN0IG1vdmUgYmVjYXVzZSB0aGUgcGlja1Bvc2l0aW9uKCkgY291bGQgYmUgd3JvbmdcbiAgICAgIH1cblxuICAgICAgaWYgKGVkaXRQb2ludC5pc1ZpcnR1YWxFZGl0UG9pbnQoKSkge1xuICAgICAgICB0aGlzLmNoYW5nZVZpcnR1YWxQb2ludFRvUmVhbFBvaW50KGVkaXRQb2ludCk7XG4gICAgICB9XG4gICAgICBjb25zdCBwb2ludHNDb3VudCA9IHRoaXMucG9zaXRpb25zLmxlbmd0aDtcbiAgICAgIGNvbnN0IHBvaW50SW5kZXggPSB0aGlzLnBvc2l0aW9ucy5pbmRleE9mKGVkaXRQb2ludCk7XG5cbiAgICAgIGlmIChwb2ludEluZGV4IDwgdGhpcy5wb3NpdGlvbnMubGVuZ3RoIC0gMSkge1xuICAgICAgICBjb25zdCBuZXh0VmlydHVhbFBvaW50ID0gdGhpcy5wb3NpdGlvbnNbKHBvaW50SW5kZXggKyAxKSAlIChwb2ludHNDb3VudCldO1xuICAgICAgICBjb25zdCBuZXh0UmVhbFBvaW50ID0gdGhpcy5wb3NpdGlvbnNbKHBvaW50SW5kZXggKyAyKSAlIChwb2ludHNDb3VudCldO1xuICAgICAgICB0aGlzLnVwZGF0ZU1pZGRsZVZpcnR1YWxQb2ludChuZXh0VmlydHVhbFBvaW50LCBlZGl0UG9pbnQsIG5leHRSZWFsUG9pbnQpO1xuICAgICAgfVxuICAgICAgaWYgKHBvaW50SW5kZXggPiAwKSB7XG4gICAgICAgIGNvbnN0IHByZXZWaXJ0dWFsUG9pbnQgPSB0aGlzLnBvc2l0aW9uc1soKHBvaW50SW5kZXggLSAxKSArIHBvaW50c0NvdW50KSAlIHBvaW50c0NvdW50XTtcbiAgICAgICAgY29uc3QgcHJldlJlYWxQb2ludCA9IHRoaXMucG9zaXRpb25zWygocG9pbnRJbmRleCAtIDIpICsgcG9pbnRzQ291bnQpICUgcG9pbnRzQ291bnRdO1xuICAgICAgICB0aGlzLnVwZGF0ZU1pZGRsZVZpcnR1YWxQb2ludChwcmV2VmlydHVhbFBvaW50LCBlZGl0UG9pbnQsIHByZXZSZWFsUG9pbnQpO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLnVwZGF0ZVBvaW50c0xheWVyKHRydWUsIGVkaXRQb2ludCk7XG4gIH1cblxuICBtb3ZlVGVtcE1vdmluZ1BvaW50KHRvUG9zaXRpb246IENhcnRlc2lhbjMpIHtcbiAgICBpZiAodGhpcy5tb3ZpbmdQb2ludCkge1xuICAgICAgdGhpcy5tb3ZlUG9pbnQodG9Qb3NpdGlvbiwgdGhpcy5tb3ZpbmdQb2ludCk7XG4gICAgfVxuICB9XG5cbiAgbW92ZVNoYXBlKHN0YXJ0TW92aW5nUG9zaXRpb246IENhcnRlc2lhbjMsIGRyYWdnZWRUb1Bvc2l0aW9uOiBDYXJ0ZXNpYW4zKSB7XG4gICAgaWYgKCF0aGlzLmRvbmVDcmVhdGlvbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIXRoaXMubGFzdERyYWdnZWRUb1Bvc2l0aW9uKSB7XG4gICAgICB0aGlzLmxhc3REcmFnZ2VkVG9Qb3NpdGlvbiA9IHN0YXJ0TW92aW5nUG9zaXRpb247XG4gICAgfVxuXG4gICAgY29uc3QgZGVsdGEgPSBHZW9VdGlsc1NlcnZpY2UuZ2V0UG9zaXRpb25zRGVsdGEodGhpcy5sYXN0RHJhZ2dlZFRvUG9zaXRpb24sIGRyYWdnZWRUb1Bvc2l0aW9uKTtcbiAgICB0aGlzLnBvc2l0aW9ucy5mb3JFYWNoKHBvaW50ID0+IHtcbiAgICAgIGNvbnN0IG5ld1BvcyA9IEdlb1V0aWxzU2VydmljZS5hZGREZWx0YVRvUG9zaXRpb24ocG9pbnQuZ2V0UG9zaXRpb24oKSwgZGVsdGEsIHRydWUpO1xuICAgICAgcG9pbnQuc2V0UG9zaXRpb24obmV3UG9zKTtcbiAgICB9KTtcbiAgICB0aGlzLnVwZGF0ZVBvaW50c0xheWVyKHRydWUsIC4uLnRoaXMucG9zaXRpb25zKTtcbiAgICB0aGlzLmxhc3REcmFnZ2VkVG9Qb3NpdGlvbiA9IGRyYWdnZWRUb1Bvc2l0aW9uO1xuICB9XG5cbiAgZW5kTW92ZVNoYXBlKCkge1xuICAgIHRoaXMubGFzdERyYWdnZWRUb1Bvc2l0aW9uID0gdW5kZWZpbmVkO1xuICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIodHJ1ZSwgLi4udGhpcy5wb3NpdGlvbnMpO1xuICB9XG5cbiAgcmVtb3ZlUG9pbnQocG9pbnRUb1JlbW92ZTogRWRpdFBvaW50KSB7XG4gICAgdGhpcy5yZW1vdmVQb3NpdGlvbihwb2ludFRvUmVtb3ZlKTtcbiAgICB0aGlzLnBvc2l0aW9uc1xuICAgICAgLmZpbHRlcihwID0+IHAuaXNWaXJ0dWFsRWRpdFBvaW50KCkpXG4gICAgICAuZm9yRWFjaChwID0+IHRoaXMucmVtb3ZlUG9zaXRpb24ocCkpO1xuICAgIHRoaXMuYWRkQWxsVmlydHVhbEVkaXRQb2ludHMoKTtcblxuICAgIHRoaXMucmVuZGVyUG9seWxpbmVzKCk7XG4gIH1cblxuICBhZGRMYXN0UG9pbnQocG9zaXRpb246IENhcnRlc2lhbjMpIHtcbiAgICB0aGlzLmRvbmVDcmVhdGlvbiA9IHRydWU7XG4gICAgdGhpcy5yZW1vdmVQb3NpdGlvbih0aGlzLm1vdmluZ1BvaW50KTsgLy8gcmVtb3ZlIG1vdmluZ1BvaW50XG4gICAgdGhpcy5tb3ZpbmdQb2ludCA9IG51bGw7XG5cbiAgICB0aGlzLmFkZEFsbFZpcnR1YWxFZGl0UG9pbnRzKCk7XG4gIH1cblxuICBnZXRSZWFsUG9zaXRpb25zKCk6IENhcnRlc2lhbjNbXSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0UmVhbFBvaW50cygpXG4gICAgICAubWFwKHBvc2l0aW9uID0+IHBvc2l0aW9uLmdldFBvc2l0aW9uKCkpO1xuICB9XG5cbiAgZ2V0UmVhbFBvaW50cygpOiBFZGl0UG9pbnRbXSB7XG4gICAgcmV0dXJuIHRoaXMucG9zaXRpb25zXG4gICAgICAuZmlsdGVyKHBvc2l0aW9uID0+ICFwb3NpdGlvbi5pc1ZpcnR1YWxFZGl0UG9pbnQoKSAmJiBwb3NpdGlvbiAhPT0gdGhpcy5tb3ZpbmdQb2ludCk7XG4gIH1cblxuICBnZXRQb2ludHMoKTogRWRpdFBvaW50W10ge1xuICAgIHJldHVybiB0aGlzLnBvc2l0aW9ucy5maWx0ZXIocG9zaXRpb24gPT4gcG9zaXRpb24gIT09IHRoaXMubW92aW5nUG9pbnQpO1xuICB9XG5cbiAgZ2V0UG9zaXRpb25zKCk6IENhcnRlc2lhbjNbXSB7XG4gICAgcmV0dXJuIHRoaXMucG9zaXRpb25zLm1hcChwb3NpdGlvbiA9PiBwb3NpdGlvbi5nZXRQb3NpdGlvbigpKTtcbiAgfVxuXG4gIGdldFBvc2l0aW9uc0NhbGxiYWNrUHJvcGVydHkoKTogQ2FydGVzaWFuM1tdIHtcbiAgICByZXR1cm4gbmV3IENlc2l1bS5DYWxsYmFja1Byb3BlcnR5KHRoaXMuZ2V0UG9zaXRpb25zLmJpbmQodGhpcyksIGZhbHNlKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlUG9zaXRpb24ocG9pbnQ6IEVkaXRQb2ludCkge1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5wb3NpdGlvbnMuZmluZEluZGV4KChwKSA9PiBwID09PSBwb2ludCk7XG4gICAgaWYgKGluZGV4IDwgMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnBvc2l0aW9ucy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgIHRoaXMucG9pbnRzTGF5ZXIucmVtb3ZlKHBvaW50LmdldElkKCkpO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVQb2ludHNMYXllcihyZW5kZXJQb2x5bGluZXMgPSB0cnVlLCAuLi5wb2ludDogRWRpdFBvaW50W10pIHtcbiAgICBpZiAocmVuZGVyUG9seWxpbmVzKSB7XG4gICAgICB0aGlzLnJlbmRlclBvbHlsaW5lcygpO1xuICAgIH1cbiAgICBwb2ludC5mb3JFYWNoKHAgPT4gdGhpcy5wb2ludHNMYXllci51cGRhdGUocCwgcC5nZXRJZCgpKSk7XG4gIH1cblxuICB1cGRhdGUoKSB7XG4gICAgdGhpcy51cGRhdGVQb2ludHNMYXllcigpO1xuICB9XG5cbiAgZGlzcG9zZSgpIHtcbiAgICB0aGlzLnBvc2l0aW9ucy5mb3JFYWNoKGVkaXRQb2ludCA9PiB7XG4gICAgICB0aGlzLnBvaW50c0xheWVyLnJlbW92ZShlZGl0UG9pbnQuZ2V0SWQoKSk7XG4gICAgfSk7XG4gICAgdGhpcy5wb2x5bGluZXMuZm9yRWFjaChsaW5lID0+IHRoaXMucG9seWxpbmVzTGF5ZXIucmVtb3ZlKGxpbmUuZ2V0SWQoKSkpO1xuICAgIGlmICh0aGlzLm1vdmluZ1BvaW50KSB7XG4gICAgICB0aGlzLnBvaW50c0xheWVyLnJlbW92ZSh0aGlzLm1vdmluZ1BvaW50LmdldElkKCkpO1xuICAgICAgdGhpcy5tb3ZpbmdQb2ludCA9IHVuZGVmaW5lZDtcbiAgICB9XG4gICAgdGhpcy5wb3NpdGlvbnMubGVuZ3RoID0gMDtcbiAgfVxuXG4gIGdldFBvaW50c0NvdW50KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMucG9zaXRpb25zLmxlbmd0aDtcbiAgfVxuXG4gIGdldElkKCkge1xuICAgIHJldHVybiB0aGlzLmlkO1xuICB9XG59XG4iXX0=