UNPKG

@eliorar/angular-cesium

Version:

Angular library for working with Cesium.

315 lines 47.9 kB
import { CallbackProperty, Cartesian3, ColorGeometryInstanceAttribute, GeometryInstance, GroundPolylineGeometry, GroundPolylinePrimitive, PolylineColorAppearance } from 'cesium'; 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 pos1 = firstP.getPosition(); const pos2 = secondP.getPosition(); const midPointCartesian3 = Cartesian3.lerp(new Cartesian3(pos1.x, pos1.y, pos1.z), new Cartesian3(pos2.x, pos2.y, pos2.z), 0.5, new 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 pos1 = prevPoint.getPosition(); const pos2 = nextPoint.getPosition(); const midPointCartesian3 = Cartesian3.lerp(new Cartesian3(pos1.x, pos1.y, pos1.z), new Cartesian3(pos2.x, pos2.y, pos2.z), 0.5, new 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 GeometryInstance({ geometry: new GroundPolylineGeometry({ positions: this.positions.map(p => p.getPosition()), width: this.polylineProps.width, loop: false }), id: 'edit-polygon-outline-' + this.id, attributes: { color: ColorGeometryInstanceAttribute.fromColor(this.polylineProps.material()) } }); this._outlineInstance = this.scene.groundPrimitives.add(new GroundPolylinePrimitive({ geometryInstances: instance, asynchronous: false, appearance: new 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, new Cartesian3(draggedToPosition.x, draggedToPosition.y, draggedToPosition.z)); this.positions.forEach(point => { const pos = point.getPosition(); const newPos = GeoUtilsService.addDeltaToPosition(new Cartesian3(pos.x, pos.y, pos.z), 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 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWRpdGFibGUtcG9seWxpbmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9hbmd1bGFyLWNlc2l1bS9zcmMvbGliL2FuZ3VsYXItY2VzaXVtLXdpZGdldHMvbW9kZWxzL2VkaXRhYmxlLXBvbHlsaW5lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCxnQkFBZ0IsRUFDaEIsVUFBVSxFQUNWLDhCQUE4QixFQUM5QixnQkFBZ0IsRUFDaEIsc0JBQXNCLEVBQ3RCLHVCQUF1QixFQUN2Qix1QkFBdUIsRUFDeEIsTUFBTSxRQUFRLENBQUM7QUFDaEIsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLHVDQUF1QyxDQUFDO0FBQy9ELE9BQU8sRUFBQyxTQUFTLEVBQUMsTUFBTSxjQUFjLENBQUM7QUFDdkMsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBSzdDLE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSwyREFBMkQsQ0FBQztBQUMxRixPQUFPLEVBQUMsaUJBQWlCLEVBQWEsTUFBTSxlQUFlLENBQUM7QUFFNUQsTUFBTSxPQUFPLGdCQUFpQixTQUFRLFFBQVE7SUFhNUMsWUFBb0IsRUFBVSxFQUNWLFdBQTZCLEVBQzdCLGNBQWdDLEVBQ2hDLG1CQUF3QyxFQUN4QyxLQUFVLEVBQ1YsV0FBZ0MsRUFDeEMsU0FBd0I7UUFDbEMsS0FBSyxFQUFFLENBQUM7UUFQVSxPQUFFLEdBQUYsRUFBRSxDQUFRO1FBQ1YsZ0JBQVcsR0FBWCxXQUFXLENBQWtCO1FBQzdCLG1CQUFjLEdBQWQsY0FBYyxDQUFrQjtRQUNoQyx3QkFBbUIsR0FBbkIsbUJBQW1CLENBQXFCO1FBQ3hDLFVBQUssR0FBTCxLQUFLLENBQUs7UUFDVixnQkFBVyxHQUFYLFdBQVcsQ0FBcUI7UUFqQjVDLGNBQVMsR0FBZ0IsRUFBRSxDQUFDO1FBRTVCLGNBQVMsR0FBbUIsRUFBRSxDQUFDO1FBRS9CLGlCQUFZ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O1FBQ0QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQzVCLENBQUM7SUFFRCxjQUFjO1FBQ1osT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQztJQUMvQixDQUFDO0lBRUQsS0FBSztRQUNILE9BQU8sSUFBSSxDQUFDLEVBQUUsQ0FBQztJQUNqQixDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDYWxsYmFja1Byb3BlcnR5LFxuICBDYXJ0ZXNpYW4zLFxuICBDb2xvckdlb21ldHJ5SW5zdGFuY2VBdHRyaWJ1dGUsXG4gIEdlb21ldHJ5SW5zdGFuY2UsXG4gIEdyb3VuZFBvbHlsaW5lR2VvbWV0cnksXG4gIEdyb3VuZFBvbHlsaW5lUHJpbWl0aXZlLFxuICBQb2x5bGluZUNvbG9yQXBwZWFyYW5jZVxufSBmcm9tICdjZXNpdW0nO1xuaW1wb3J0IHtBY0VudGl0eX0gZnJvbSAnLi4vLi4vYW5ndWxhci1jZXNpdW0vbW9kZWxzL2FjLWVudGl0eSc7XG5pbXBvcnQge0VkaXRQb2ludH0gZnJvbSAnLi9lZGl0LXBvaW50JztcbmltcG9ydCB7RWRpdFBvbHlsaW5lfSBmcm9tICcuL2VkaXQtcG9seWxpbmUnO1xuaW1wb3J0IHtBY0xheWVyQ29tcG9uZW50fSBmcm9tICcuLi8uLi9hbmd1bGFyLWNlc2l1bS9jb21wb25lbnRzL2FjLWxheWVyL2FjLWxheWVyLmNvbXBvbmVudCc7XG5pbXBvcnQge0Nvb3JkaW5hdGVDb252ZXJ0ZXJ9IGZyb20gJy4uLy4uL2FuZ3VsYXItY2VzaXVtL3NlcnZpY2VzL2Nvb3JkaW5hdGUtY29udmVydGVyL2Nvb3JkaW5hdGUtY29udmVydGVyLnNlcnZpY2UnO1xuaW1wb3J0IHtQb2ludFByb3BzfSBmcm9tICcuL3BvaW50LWVkaXQtb3B0aW9ucyc7XG5pbXBvcnQge1BvbHlsaW5lRWRpdE9wdGlvbnMsIFBvbHlsaW5lUHJvcHN9IGZyb20gJy4vcG9seWxpbmUtZWRpdC1vcHRpb25zJztcbmltcG9ydCB7R2VvVXRpbHNTZXJ2aWNlfSBmcm9tICcuLi8uLi9hbmd1bGFyLWNlc2l1bS9zZXJ2aWNlcy9nZW8tdXRpbHMvZ2VvLXV0aWxzLnNlcnZpY2UnO1xuaW1wb3J0IHtkZWZhdWx0TGFiZWxQcm9wcywgTGFiZWxQcm9wc30gZnJvbSAnLi9sYWJlbC1wcm9wcyc7XG5cbmV4cG9ydCBjbGFzcyBFZGl0YWJsZVBvbHlsaW5lIGV4dGVuZHMgQWNFbnRpdHkge1xuICBwcml2YXRlIHBvc2l0aW9uczogRWRpdFBvaW50W10gPSBbXTtcblxuICBwcml2YXRlIHBvbHlsaW5lczogRWRpdFBvbHlsaW5lW10gPSBbXTtcbiAgcHJpdmF0ZSBtb3ZpbmdQb2ludDogRWRpdFBvaW50O1xuICBwcml2YXRlIGRvbmVDcmVhdGlvbiA9IGZhbHNlO1xuICBwcml2YXRlIF9lbmFibGVFZGl0ID0gdHJ1ZTtcbiAgcHJpdmF0ZSBfcG9pbnRQcm9wczogUG9pbnRQcm9wcztcbiAgcHJpdmF0ZSBwb2x5bGluZVByb3BzOiBQb2x5bGluZVByb3BzO1xuICBwcml2YXRlIGxhc3REcmFnZ2VkVG9Qb3NpdGlvbjogYW55O1xuICBwcml2YXRlIF9sYWJlbHM6IExhYmVsUHJvcHNbXSA9IFtdO1xuICBwcml2YXRlIF9vdXRsaW5lSW5zdGFuY2UgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgaWQ6IHN0cmluZyxcbiAgICAgICAgICAgICAgcHJpdmF0ZSBwb2ludHNMYXllcjogQWNMYXllckNvbXBvbmVudCxcbiAgICAgICAgICAgICAgcHJpdmF0ZSBwb2x5bGluZXNMYXllcjogQWNMYXllckNvbXBvbmVudCxcbiAgICAgICAgICAgICAgcHJpdmF0ZSBjb29yZGluYXRlQ29udmVydGVyOiBDb29yZGluYXRlQ29udmVydGVyLFxuICAgICAgICAgICAgICBwcml2YXRlIHNjZW5lOiBhbnksXG4gICAgICAgICAgICAgIHByaXZhdGUgZWRpdE9wdGlvbnM6IFBvbHlsaW5lRWRpdE9wdGlvbnMsXG4gICAgICAgICAgICAgIHBvc2l0aW9ucz86IENhcnRlc2lhbjNbXSkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5fcG9pbnRQcm9wcyA9IHsuLi5lZGl0T3B0aW9ucy5wb2ludFByb3BzfTtcbiAgICB0aGlzLnByb3BzID0gey4uLmVkaXRPcHRpb25zLnBvbHlsaW5lUHJvcHN9O1xuICAgIGlmIChwb3NpdGlvbnMgJiYgcG9zaXRpb25zLmxlbmd0aCA+PSAyKSB7XG4gICAgICB0aGlzLmNyZWF0ZUZyb21FeGlzdGluZyhwb3NpdGlvbnMpO1xuICAgIH1cbiAgfVxuXG4gIGdldCBsYWJlbHMoKTogTGFiZWxQcm9wc1tdIHtcbiAgICByZXR1cm4gdGhpcy5fbGFiZWxzO1xuICB9XG5cbiAgc2V0IGxhYmVscyhsYWJlbHM6IExhYmVsUHJvcHNbXSkge1xuICAgIGlmICghbGFiZWxzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHBvc2l0aW9ucyA9IHRoaXMuZ2V0UmVhbFBvc2l0aW9ucygpO1xuICAgIHRoaXMuX2xhYmVscyA9IGxhYmVscy5tYXAoKGxhYmVsLCBpbmRleCkgPT4ge1xuICAgICAgaWYgKCFsYWJlbC5wb3NpdGlvbikge1xuICAgICAgICBsYWJlbC5wb3NpdGlvbiA9IHBvc2l0aW9uc1tpbmRleF07XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBkZWZhdWx0TGFiZWxQcm9wcywgbGFiZWwpO1xuICAgIH0pO1xuICB9XG5cbiAgZ2V0IHByb3BzKCk6IFBvbHlsaW5lUHJvcHMge1xuICAgIHJldHVybiB0aGlzLnBvbHlsaW5lUHJvcHM7XG4gIH1cblxuICBzZXQgcHJvcHModmFsdWU6IFBvbHlsaW5lUHJvcHMpIHtcbiAgICB0aGlzLnBvbHlsaW5lUHJvcHMgPSB2YWx1ZTtcbiAgfVxuXG4gIGdldCBwb2ludFByb3BzKCk6IFBvaW50UHJvcHMge1xuICAgIHJldHVybiB0aGlzLl9wb2ludFByb3BzO1xuICB9XG5cbiAgc2V0IHBvaW50UHJvcHModmFsdWU6IFBvaW50UHJvcHMpIHtcbiAgICB0aGlzLl9wb2ludFByb3BzID0gdmFsdWU7XG4gIH1cblxuICBnZXQgZW5hYmxlRWRpdCgpIHtcbiAgICByZXR1cm4gdGhpcy5fZW5hYmxlRWRpdDtcbiAgfVxuXG4gIHNldCBlbmFibGVFZGl0KHZhbHVlOiBib29sZWFuKSB7XG4gICAgdGhpcy5fZW5hYmxlRWRpdCA9IHZhbHVlO1xuICAgIHRoaXMucG9zaXRpb25zLmZvckVhY2gocG9pbnQgPT4ge1xuICAgICAgcG9pbnQuc2hvdyA9IHZhbHVlO1xuICAgICAgdGhpcy51cGRhdGVQb2ludHNMYXllcihmYWxzZSwgcG9pbnQpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVGcm9tRXhpc3RpbmcocG9zaXRpb25zOiBDYXJ0ZXNpYW4zW10pIHtcbiAgICBwb3NpdGlvbnMuZm9yRWFjaCgocG9zaXRpb24pID0+IHtcbiAgICAgIHRoaXMuYWRkUG9pbnRGcm9tRXhpc3RpbmcocG9zaXRpb24pO1xuICAgIH0pO1xuICAgIHRoaXMuYWRkQWxsVmlydHVhbEVkaXRQb2ludHMoKTtcbiAgICB0aGlzLmRvbmVDcmVhdGlvbiA9IHRydWU7XG4gIH1cblxuICBzZXRNYW51YWxseShwb2ludHM6IHtcbiAgICBwb3NpdGlvbjogQ2FydGVzaWFuMyxcbiAgICBwb2ludFByb3A/OiBQb2ludFByb3BzXG4gIH1bXSB8IENhcnRlc2lhbjNbXSwgcG9seWxpbmVQcm9wcz86IFBvbHlsaW5lUHJvcHMpIHtcbiAgICBpZiAoIXRoaXMuZG9uZUNyZWF0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1VwZGF0ZSBtYW51YWxseSBvbmx5IGluIGVkaXQgbW9kZSwgYWZ0ZXIgcG9seWxpbmUgaXMgY3JlYXRlZCcpO1xuICAgIH1cbiAgICB0aGlzLnBvc2l0aW9ucy5mb3JFYWNoKHAgPT4gdGhpcy5wb2ludHNMYXllci5yZW1vdmUocC5nZXRJZCgpKSk7XG5cbiAgICBjb25zdCBuZXdQb2ludHM6IEVkaXRQb2ludFtdID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwb2ludHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHBvaW50T3JDYXJ0ZXNpYW46IGFueSA9IHBvaW50c1tpXTtcbiAgICAgIGxldCBuZXdQb2ludCA9IG51bGw7XG4gICAgICBpZiAocG9pbnRPckNhcnRlc2lhbi5wb2ludFByb3BzKSB7XG4gICAgICAgIG5ld1BvaW50ID0gbmV3IEVkaXRQb2ludCh0aGlzLmlkLCBwb2ludE9yQ2FydGVzaWFuLnBvc2l0aW9uLCBwb2ludE9yQ2FydGVzaWFuLnBvaW50UHJvcHMpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbmV3UG9pbnQgPSBuZXcgRWRpdFBvaW50KHRoaXMuaWQsIHBvaW50T3JDYXJ0ZXNpYW4sIHRoaXMuX3BvaW50UHJvcHMpO1xuICAgICAgfVxuICAgICAgbmV3UG9pbnRzLnB1c2gobmV3UG9pbnQpO1xuICAgIH1cbiAgICB0aGlzLnBvc2l0aW9ucyA9IG5ld1BvaW50cztcbiAgICB0aGlzLnBvbHlsaW5lUHJvcHMgPSBwb2x5bGluZVByb3BzID8gcG9seWxpbmVQcm9wcyA6IHRoaXMucG9seWxpbmVQcm9wcztcblxuICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIodHJ1ZSwgLi4udGhpcy5wb3NpdGlvbnMpO1xuICAgIHRoaXMuYWRkQWxsVmlydHVhbEVkaXRQb2ludHMoKTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkQWxsVmlydHVhbEVkaXRQb2ludHMoKSB7XG4gICAgY29uc3QgY3VycmVudFBvaW50cyA9IFsuLi50aGlzLnBvc2l0aW9uc107XG4gICAgY3VycmVudFBvaW50cy5mb3JFYWNoKChwb3MsIGluZGV4KSA9PiB7XG4gICAgICBpZiAoaW5kZXggIT09IGN1cnJlbnRQb2ludHMubGVuZ3RoIC0gMSkge1xuICAgICAgICBjb25zdCBjdXJyZW50UG9pbnQgPSBwb3M7XG4gICAgICAgIGNvbnN0IG5leHRJbmRleCA9IChpbmRleCArIDEpICUgKGN1cnJlbnRQb2ludHMubGVuZ3RoKTtcbiAgICAgICAgY29uc3QgbmV4dFBvaW50ID0gY3VycmVudFBvaW50c1tuZXh0SW5kZXhdO1xuXG4gICAgICAgIGNvbnN0IG1pZFBvaW50ID0gdGhpcy5zZXRNaWRkbGVWaXJ0dWFsUG9pbnQoY3VycmVudFBvaW50LCBuZXh0UG9pbnQpO1xuXG4gICAgICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIoZmFsc2UsIG1pZFBvaW50KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0TWlkZGxlVmlydHVhbFBvaW50KGZpcnN0UDogRWRpdFBvaW50LCBzZWNvbmRQOiBFZGl0UG9pbnQpOiBFZGl0UG9pbnQge1xuICAgIGNvbnN0IHBvczEgPSBmaXJzdFAuZ2V0UG9zaXRpb24oKTtcbiAgICBjb25zdCBwb3MyID0gc2Vjb25kUC5nZXRQb3NpdGlvbigpO1xuICAgIGNvbnN0IG1pZFBvaW50Q2FydGVzaWFuMyA9IENhcnRlc2lhbjMubGVycChuZXcgQ2FydGVzaWFuMyhwb3MxLngsIHBvczEueSwgcG9zMS56KSwgbmV3IENhcnRlc2lhbjMocG9zMi54LCBwb3MyLnksIHBvczIueiksIDAuNSwgbmV3IENhcnRlc2lhbjMoKSk7XG4gICAgY29uc3QgbWlkUG9pbnQgPSBuZXcgRWRpdFBvaW50KHRoaXMuaWQsIG1pZFBvaW50Q2FydGVzaWFuMywgdGhpcy5fcG9pbnRQcm9wcyk7XG4gICAgbWlkUG9pbnQuc2V0VmlydHVhbEVkaXRQb2ludCh0cnVlKTtcblxuICAgIGNvbnN0IGZpcnN0SW5kZXggPSB0aGlzLnBvc2l0aW9ucy5pbmRleE9mKGZpcnN0UCk7XG4gICAgdGhpcy5wb3NpdGlvbnMuc3BsaWNlKGZpcnN0SW5kZXggKyAxLCAwLCBtaWRQb2ludCk7XG4gICAgcmV0dXJuIG1pZFBvaW50O1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVNaWRkbGVWaXJ0dWFsUG9pbnQodmlydHVhbEVkaXRQb2ludDogRWRpdFBvaW50LCBwcmV2UG9pbnQ6IEVkaXRQb2ludCwgbmV4dFBvaW50OiBFZGl0UG9pbnQpIHtcbiAgICBjb25zdCBwb3MxID0gcHJldlBvaW50LmdldFBvc2l0aW9uKCk7XG4gICAgY29uc3QgcG9zMiA9IG5leHRQb2ludC5nZXRQb3NpdGlvbigpO1xuICAgIGNvbnN0IG1pZFBvaW50Q2FydGVzaWFuMyA9IENhcnRlc2lhbjMubGVycChuZXcgQ2FydGVzaWFuMyhwb3MxLngsIHBvczEueSwgcG9zMS56KSwgbmV3IENhcnRlc2lhbjMocG9zMi54LCBwb3MyLnksIHBvczIueiksIDAuNSwgbmV3IENhcnRlc2lhbjMoKSk7XG4gICAgdmlydHVhbEVkaXRQb2ludC5zZXRQb3NpdGlvbihtaWRQb2ludENhcnRlc2lhbjMpO1xuICB9XG5cbiAgY2hhbmdlVmlydHVhbFBvaW50VG9SZWFsUG9pbnQocG9pbnQ6IEVkaXRQb2ludCkge1xuICAgIHBvaW50LnNldFZpcnR1YWxFZGl0UG9pbnQoZmFsc2UpOyAvLyBhY3R1YWwgcG9pbnQgYmVjb21lcyBhIHJlYWwgcG9pbnRcbiAgICBjb25zdCBwb2ludHNDb3VudCA9IHRoaXMucG9zaXRpb25zLmxlbmd0aDtcbiAgICBjb25zdCBwb2ludEluZGV4ID0gdGhpcy5wb3NpdGlvbnMuaW5kZXhPZihwb2ludCk7XG4gICAgY29uc3QgbmV4dEluZGV4ID0gKHBvaW50SW5kZXggKyAxKSAlIChwb2ludHNDb3VudCk7XG4gICAgY29uc3QgcHJlSW5kZXggPSAoKHBvaW50SW5kZXggLSAxKSArIHBvaW50c0NvdW50KSAlIHBvaW50c0NvdW50O1xuXG4gICAgY29uc3QgbmV4dFBvaW50ID0gdGhpcy5wb3NpdGlvbnNbbmV4dEluZGV4XTtcbiAgICBjb25zdCBwcmVQb2ludCA9IHRoaXMucG9zaXRpb25zW3ByZUluZGV4XTtcblxuICAgIGNvbnN0IGZpcnN0TWlkUG9pbnQgPSB0aGlzLnNldE1pZGRsZVZpcnR1YWxQb2ludChwcmVQb2ludCwgcG9pbnQpO1xuICAgIGNvbnN0IHNlY01pZFBvaW50ID0gdGhpcy5zZXRNaWRkbGVWaXJ0dWFsUG9pbnQocG9pbnQsIG5leHRQb2ludCk7XG4gICAgdGhpcy51cGRhdGVQb2ludHNMYXllcihmYWxzZSwgZmlyc3RNaWRQb2ludCwgc2VjTWlkUG9pbnQsIHBvaW50KTtcblxuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXJQb2x5bGluZXMoKSB7XG4gICAgY29uc3QgcmVhbFBvaW50cyA9IHRoaXMucG9zaXRpb25zLmZpbHRlcihwb2ludCA9PiAhcG9pbnQuaXNWaXJ0dWFsRWRpdFBvaW50KCkpO1xuICAgIGlmICh0aGlzLnBvbHlsaW5lUHJvcHMudXNlR3JvdW5kUHJpbWl0aXZlT3V0bGluZSkge1xuICAgICAgaWYgKHJlYWxQb2ludHMubGVuZ3RoIDwgMikge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLnNjZW5lLmdyb3VuZFByaW1pdGl2ZXMucmVtb3ZlKHRoaXMuX291dGxpbmVJbnN0YW5jZSk7XG4gICAgICBjb25zdCBpbnN0YW5jZSA9IG5ldyBHZW9tZXRyeUluc3RhbmNlKHtcbiAgICAgICAgZ2VvbWV0cnk6IG5ldyBHcm91bmRQb2x5bGluZUdlb21ldHJ5KHtcbiAgICAgICAgICBwb3NpdGlvbnM6IHRoaXMucG9zaXRpb25zLm1hcChwID0+IHAuZ2V0UG9zaXRpb24oKSksXG4gICAgICAgICAgd2lkdGg6IHRoaXMucG9seWxpbmVQcm9wcy53aWR0aCxcbiAgICAgICAgICBsb29wOiBmYWxzZVxuICAgICAgICB9KSxcbiAgICAgICAgaWQ6ICdlZGl0LXBvbHlnb24tb3V0bGluZS0nICsgdGhpcy5pZCxcbiAgICAgICAgYXR0cmlidXRlczoge1xuICAgICAgICAgIGNvbG9yOiBDb2xvckdlb21ldHJ5SW5zdGFuY2VBdHRyaWJ1dGUuZnJvbUNvbG9yKHRoaXMucG9seWxpbmVQcm9wcy5tYXRlcmlhbCgpKVxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHRoaXMuX291dGxpbmVJbnN0YW5jZSA9IHRoaXMuc2NlbmUuZ3JvdW5kUHJpbWl0aXZlcy5hZGQoXG4gICAgICAgIG5ldyBHcm91bmRQb2x5bGluZVByaW1pdGl2ZSh7XG4gICAgICAgICAgZ2VvbWV0cnlJbnN0YW5jZXM6IGluc3RhbmNlLFxuICAgICAgICAgIGFzeW5jaHJvbm91czogZmFsc2UsXG4gICAgICAgICAgYXBwZWFyYW5jZTogbmV3IFBvbHlsaW5lQ29sb3JBcHBlYXJhbmNlKClcbiAgICAgICAgfSlcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucG9seWxpbmVzLmZvckVhY2gocG9seWxpbmUgPT4gdGhpcy5wb2x5bGluZXNMYXllci5yZW1vdmUocG9seWxpbmUuZ2V0SWQoKSkpO1xuICAgICAgdGhpcy5wb2x5bGluZXMgPSBbXTtcbiAgICAgIHJlYWxQb2ludHMuZm9yRWFjaCgocG9pbnQsIGluZGV4KSA9PiB7XG4gICAgICAgIGlmIChpbmRleCAhPT0gcmVhbFBvaW50cy5sZW5ndGggLSAxKSB7XG4gICAgICAgICAgY29uc3QgbmV4dEluZGV4ID0gKGluZGV4ICsgMSk7XG4gICAgICAgICAgY29uc3QgbmV4dFBvaW50ID0gcmVhbFBvaW50c1tuZXh0SW5kZXhdO1xuICAgICAgICAgIGNvbnN0IHBvbHlsaW5lID0gbmV3IEVkaXRQb2x5bGluZSh0aGlzLmlkLCBwb2ludC5nZXRQb3NpdGlvbigpLCBuZXh0UG9pbnQuZ2V0UG9zaXRpb24oKSwgdGhpcy5wb2x5bGluZVByb3BzKTtcbiAgICAgICAgICB0aGlzLnBvbHlsaW5lcy5wdXNoKHBvbHlsaW5lKTtcbiAgICAgICAgICB0aGlzLnBvbHlsaW5lc0xheWVyLnVwZGF0ZShwb2x5bGluZSwgcG9seWxpbmUuZ2V0SWQoKSk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGFkZFBvaW50RnJvbUV4aXN0aW5nKHBvc2l0aW9uOiBDYXJ0ZXNpYW4zKSB7XG4gICAgY29uc3QgbmV3UG9pbnQgPSBuZXcgRWRpdFBvaW50KHRoaXMuaWQsIHBvc2l0aW9uLCB0aGlzLl9wb2ludFByb3BzKTtcbiAgICB0aGlzLnBvc2l0aW9ucy5wdXNoKG5ld1BvaW50KTtcbiAgICB0aGlzLnVwZGF0ZVBvaW50c0xheWVyKHRydWUsIG5ld1BvaW50KTtcbiAgfVxuXG5cbiAgYWRkUG9pbnQocG9zaXRpb246IENhcnRlc2lhbjMpIHtcbiAgICBpZiAodGhpcy5kb25lQ3JlYXRpb24pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgaXNGaXJzdFBvaW50ID0gIXRoaXMucG9zaXRpb25zLmxlbmd0aDtcbiAgICBpZiAoaXNGaXJzdFBvaW50KSB7XG4gICAgICBjb25zdCBmaXJzdFBvaW50ID0gbmV3IEVkaXRQb2ludCh0aGlzLmlkLCBwb3NpdGlvbiwgdGhpcy5fcG9pbnRQcm9wcyk7XG4gICAgICB0aGlzLnBvc2l0aW9ucy5wdXNoKGZpcnN0UG9pbnQpO1xuICAgICAgdGhpcy51cGRhdGVQb2ludHNMYXllcih0cnVlLCBmaXJzdFBvaW50KTtcbiAgICB9XG5cbiAgICB0aGlzLm1vdmluZ1BvaW50ID0gbmV3IEVkaXRQb2ludCh0aGlzLmlkLCBwb3NpdGlvbi5jbG9uZSgpLCB0aGlzLl9wb2ludFByb3BzKTtcbiAgICB0aGlzLnBvc2l0aW9ucy5wdXNoKHRoaXMubW92aW5nUG9pbnQpO1xuXG4gICAgdGhpcy51cGRhdGVQb2ludHNMYXllcih0cnVlLCB0aGlzLm1vdmluZ1BvaW50KTtcbiAgfVxuXG4gIG1vdmVQb2ludEZpbmlzaChlZGl0UG9pbnQ6IEVkaXRQb2ludCkge1xuICAgIGlmICh0aGlzLmVkaXRPcHRpb25zLmNsYW1wSGVpZ2h0VG8zRCkge1xuICAgICAgZWRpdFBvaW50LnByb3BzLmRpc2FibGVEZXB0aFRlc3REaXN0YW5jZSA9IE51bWJlci5QT1NJVElWRV9JTkZJTklUWTtcbiAgICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIoZmFsc2UsIGVkaXRQb2ludCk7XG4gICAgfVxuICB9XG5cbiAgbW92ZVBvaW50KHRvUG9zaXRpb246IENhcnRlc2lhbjMsIGVkaXRQb2ludDogRWRpdFBvaW50KSB7XG4gICAgZWRpdFBvaW50LnNldFBvc2l0aW9uKHRvUG9zaXRpb24pO1xuICAgIGlmICh0aGlzLmRvbmVDcmVhdGlvbikge1xuICAgICAgaWYgKGVkaXRQb2ludC5wcm9wcy5kaXNhYmxlRGVwdGhUZXN0RGlzdGFuY2UgJiYgdGhpcy5lZGl0T3B0aW9ucy5jbGFtcEhlaWdodFRvM0QpIHtcbiAgICAgICAgLy8gVG8gYXZvaWQgYnVnIHdpdGggcGlja1Bvc2l0aW9uKCkgb24gcG9pbnQgd2l0aCBkaXNhYmxlRGVwdGhUZXN0RGlzdGFuY2VcbiAgICAgICAgZWRpdFBvaW50LnByb3BzLmRpc2FibGVEZXB0aFRlc3REaXN0YW5jZSA9IHVuZGVmaW5lZDtcbiAgICAgICAgcmV0dXJuOyAvLyBpZ25vcmUgZmlyc3QgbW92ZSBiZWNhdXNlIHRoZSBwaWNrUG9zaXRpb24oKSBjb3VsZCBiZSB3cm9uZ1xuICAgICAgfVxuXG4gICAgICBpZiAoZWRpdFBvaW50LmlzVmlydHVhbEVkaXRQb2ludCgpKSB7XG4gICAgICAgIHRoaXMuY2hhbmdlVmlydHVhbFBvaW50VG9SZWFsUG9pbnQoZWRpdFBvaW50KTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHBvaW50c0NvdW50ID0gdGhpcy5wb3NpdGlvbnMubGVuZ3RoO1xuICAgICAgY29uc3QgcG9pbnRJbmRleCA9IHRoaXMucG9zaXRpb25zLmluZGV4T2YoZWRpdFBvaW50KTtcblxuICAgICAgaWYgKHBvaW50SW5kZXggPCB0aGlzLnBvc2l0aW9ucy5sZW5ndGggLSAxKSB7XG4gICAgICAgIGNvbnN0IG5leHRWaXJ0dWFsUG9pbnQgPSB0aGlzLnBvc2l0aW9uc1socG9pbnRJbmRleCArIDEpICUgKHBvaW50c0NvdW50KV07XG4gICAgICAgIGNvbnN0IG5leHRSZWFsUG9pbnQgPSB0aGlzLnBvc2l0aW9uc1socG9pbnRJbmRleCArIDIpICUgKHBvaW50c0NvdW50KV07XG4gICAgICAgIHRoaXMudXBkYXRlTWlkZGxlVmlydHVhbFBvaW50KG5leHRWaXJ0dWFsUG9pbnQsIGVkaXRQb2ludCwgbmV4dFJlYWxQb2ludCk7XG4gICAgICB9XG4gICAgICBpZiAocG9pbnRJbmRleCA+IDApIHtcbiAgICAgICAgY29uc3QgcHJldlZpcnR1YWxQb2ludCA9IHRoaXMucG9zaXRpb25zWygocG9pbnRJbmRleCAtIDEpICsgcG9pbnRzQ291bnQpICUgcG9pbnRzQ291bnRdO1xuICAgICAgICBjb25zdCBwcmV2UmVhbFBvaW50ID0gdGhpcy5wb3NpdGlvbnNbKChwb2ludEluZGV4IC0gMikgKyBwb2ludHNDb3VudCkgJSBwb2ludHNDb3VudF07XG4gICAgICAgIHRoaXMudXBkYXRlTWlkZGxlVmlydHVhbFBvaW50KHByZXZWaXJ0dWFsUG9pbnQsIGVkaXRQb2ludCwgcHJldlJlYWxQb2ludCk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIodHJ1ZSwgZWRpdFBvaW50KTtcbiAgfVxuXG4gIG1vdmVUZW1wTW92aW5nUG9pbnQodG9Qb3NpdGlvbjogQ2FydGVzaWFuMykge1xuICAgIGlmICh0aGlzLm1vdmluZ1BvaW50KSB7XG4gICAgICB0aGlzLm1vdmVQb2ludCh0b1Bvc2l0aW9uLCB0aGlzLm1vdmluZ1BvaW50KTtcbiAgICB9XG4gIH1cblxuICBtb3ZlU2hhcGUoc3RhcnRNb3ZpbmdQb3NpdGlvbjogQ2FydGVzaWFuMywgZHJhZ2dlZFRvUG9zaXRpb246IENhcnRlc2lhbjMpIHtcbiAgICBpZiAoIXRoaXMuZG9uZUNyZWF0aW9uKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghdGhpcy5sYXN0RHJhZ2dlZFRvUG9zaXRpb24pIHtcbiAgICAgIHRoaXMubGFzdERyYWdnZWRUb1Bvc2l0aW9uID0gc3RhcnRNb3ZpbmdQb3NpdGlvbjtcbiAgICB9XG5cbiAgICBjb25zdCBkZWx0YSA9IEdlb1V0aWxzU2VydmljZS5nZXRQb3NpdGlvbnNEZWx0YSh0aGlzLmxhc3REcmFnZ2VkVG9Qb3NpdGlvbiwgbmV3IENhcnRlc2lhbjMoZHJhZ2dlZFRvUG9zaXRpb24ueCwgZHJhZ2dlZFRvUG9zaXRpb24ueSwgZHJhZ2dlZFRvUG9zaXRpb24ueikpO1xuICAgIHRoaXMucG9zaXRpb25zLmZvckVhY2gocG9pbnQgPT4ge1xuICAgICAgY29uc3QgcG9zID0gcG9pbnQuZ2V0UG9zaXRpb24oKTtcbiAgICAgIGNvbnN0IG5ld1BvcyA9IEdlb1V0aWxzU2VydmljZS5hZGREZWx0YVRvUG9zaXRpb24obmV3IENhcnRlc2lhbjMocG9zLngsIHBvcy55LCBwb3MueiksIGRlbHRhLCB0cnVlKTtcbiAgICAgIHBvaW50LnNldFBvc2l0aW9uKG5ld1Bvcyk7XG4gICAgfSk7XG4gICAgdGhpcy51cGRhdGVQb2ludHNMYXllcih0cnVlLCAuLi50aGlzLnBvc2l0aW9ucyk7XG4gICAgdGhpcy5sYXN0RHJhZ2dlZFRvUG9zaXRpb24gPSBkcmFnZ2VkVG9Qb3NpdGlvbjtcbiAgfVxuXG4gIGVuZE1vdmVTaGFwZSgpIHtcbiAgICB0aGlzLmxhc3REcmFnZ2VkVG9Qb3NpdGlvbiA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLnVwZGF0ZVBvaW50c0xheWVyKHRydWUsIC4uLnRoaXMucG9zaXRpb25zKTtcbiAgfVxuXG4gIHJlbW92ZVBvaW50KHBvaW50VG9SZW1vdmU6IEVkaXRQb2ludCkge1xuICAgIHRoaXMucmVtb3ZlUG9zaXRpb24ocG9pbnRUb1JlbW92ZSk7XG4gICAgdGhpcy5wb3NpdGlvbnNcbiAgICAgIC5maWx0ZXIocCA9PiBwLmlzVmlydHVhbEVkaXRQb2ludCgpKVxuICAgICAgLmZvckVhY2gocCA9PiB0aGlzLnJlbW92ZVBvc2l0aW9uKHApKTtcbiAgICB0aGlzLmFkZEFsbFZpcnR1YWxFZGl0UG9pbnRzKCk7XG5cbiAgICB0aGlzLnJlbmRlclBvbHlsaW5lcygpO1xuICB9XG5cbiAgYWRkTGFzdFBvaW50KHBvc2l0aW9uOiBDYXJ0ZXNpYW4zKSB7XG4gICAgdGhpcy5kb25lQ3JlYXRpb24gPSB0cnVlO1xuICAgIHRoaXMucmVtb3ZlUG9zaXRpb24odGhpcy5tb3ZpbmdQb2ludCk7IC8vIHJlbW92ZSBtb3ZpbmdQb2ludFxuICAgIHRoaXMubW92aW5nUG9pbnQgPSBudWxsO1xuXG4gICAgdGhpcy5hZGRBbGxWaXJ0dWFsRWRpdFBvaW50cygpO1xuICB9XG5cbiAgZ2V0UmVhbFBvc2l0aW9ucygpOiBDYXJ0ZXNpYW4zW10ge1xuICAgIHJldHVybiB0aGlzLmdldFJlYWxQb2ludHMoKVxuICAgICAgLm1hcChwb3NpdGlvbiA9PiBwb3NpdGlvbi5nZXRQb3NpdGlvbigpKTtcbiAgfVxuXG4gIGdldFJlYWxQb2ludHMoKTogRWRpdFBvaW50W10ge1xuICAgIHJldHVybiB0aGlzLnBvc2l0aW9uc1xuICAgICAgLmZpbHRlcihwb3NpdGlvbiA9PiAhcG9zaXRpb24uaXNWaXJ0dWFsRWRpdFBvaW50KCkgJiYgcG9zaXRpb24gIT09IHRoaXMubW92aW5nUG9pbnQpO1xuICB9XG5cbiAgZ2V0UG9pbnRzKCk6IEVkaXRQb2ludFtdIHtcbiAgICByZXR1cm4gdGhpcy5wb3NpdGlvbnMuZmlsdGVyKHBvc2l0aW9uID0+IHBvc2l0aW9uICE9PSB0aGlzLm1vdmluZ1BvaW50KTtcbiAgfVxuXG4gIGdldFBvc2l0aW9ucygpOiBDYXJ0ZXNpYW4zW10ge1xuICAgIHJldHVybiB0aGlzLnBvc2l0aW9ucy5tYXAocG9zaXRpb24gPT4gcG9zaXRpb24uZ2V0UG9zaXRpb24oKSk7XG4gIH1cblxuICBnZXRQb3NpdGlvbnNDYWxsYmFja1Byb3BlcnR5KCk6IENhbGxiYWNrUHJvcGVydHkge1xuICAgIHJldHVybiBuZXcgQ2FsbGJhY2tQcm9wZXJ0eSh0aGlzLmdldFBvc2l0aW9ucy5iaW5kKHRoaXMpLCBmYWxzZSk7XG4gIH1cblxuICBwcml2YXRlIHJlbW92ZVBvc2l0aW9uKHBvaW50OiBFZGl0UG9pbnQpIHtcbiAgICBjb25zdCBpbmRleCA9IHRoaXMucG9zaXRpb25zLmZpbmRJbmRleCgocCkgPT4gcCA9PT0gcG9pbnQpO1xuICAgIGlmIChpbmRleCA8IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5wb3NpdGlvbnMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICB0aGlzLnBvaW50c0xheWVyLnJlbW92ZShwb2ludC5nZXRJZCgpKTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlUG9pbnRzTGF5ZXIocmVuZGVyUG9seWxpbmVzID0gdHJ1ZSwgLi4ucG9pbnQ6IEVkaXRQb2ludFtdKSB7XG4gICAgaWYgKHJlbmRlclBvbHlsaW5lcykge1xuICAgICAgdGhpcy5yZW5kZXJQb2x5bGluZXMoKTtcbiAgICB9XG4gICAgcG9pbnQuZm9yRWFjaChwID0+IHRoaXMucG9pbnRzTGF5ZXIudXBkYXRlKHAsIHAuZ2V0SWQoKSkpO1xuICB9XG5cbiAgdXBkYXRlKCkge1xuICAgIHRoaXMudXBkYXRlUG9pbnRzTGF5ZXIoKTtcbiAgfVxuXG4gIGRpc3Bvc2UoKSB7XG4gICAgdGhpcy5zY2VuZS5ncm91bmRQcmltaXRpdmVzLnJlbW92ZSh0aGlzLl9vdXRsaW5lSW5zdGFuY2UpO1xuICAgIHRoaXMucG9zaXRpb25zLmZvckVhY2goZWRpdFBvaW50ID0+IHtcbiAgICAgIHRoaXMucG9pbnRzTGF5ZXIucmVtb3ZlKGVkaXRQb2ludC5nZXRJZCgpKTtcbiAgICB9KTtcbiAgICB0aGlzLnBvbHlsaW5lcy5mb3JFYWNoKGxpbmUgPT4gdGhpcy5wb2x5bGluZXNMYXllci5yZW1vdmUobGluZS5nZXRJZCgpKSk7XG4gICAgaWYgKHRoaXMubW92aW5nUG9pbnQpIHtcbiAgICAgIHRoaXMucG9pbnRzTGF5ZXIucmVtb3ZlKHRoaXMubW92aW5nUG9pbnQuZ2V0SWQoKSk7XG4gICAgICB0aGlzLm1vdmluZ1BvaW50ID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgICB0aGlzLnBvc2l0aW9ucy5sZW5ndGggPSAwO1xuICB9XG5cbiAgZ2V0UG9pbnRzQ291bnQoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5wb3NpdGlvbnMubGVuZ3RoO1xuICB9XG5cbiAgZ2V0SWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuaWQ7XG4gIH1cbn1cbiJdfQ==