UNPKG

@amin-karimi/agm-direction

Version:
337 lines 46.6 kB
import { Directive, Input, Output, EventEmitter } from '@angular/core'; import * as i0 from "@angular/core"; import * as i1 from "@amin-karimi/agm-core"; export class AgmDirection { constructor(gmapsApi) { this.gmapsApi = gmapsApi; this.waypoints = []; this.optimizeWaypoints = true; this.provideRouteAlternatives = false; this.avoidHighways = false; this.avoidTolls = false; this.avoidFerries = false; // Remove or draw direction this.visible = true; // Direction change event handler this.onChange = new EventEmitter(); // Direction response for the new request this.onResponse = new EventEmitter(); // Send a custom infowindow this.sendInfoWindow = new EventEmitter(); // Status of Directions Query (google.maps.DirectionsStatus.OVER_QUERY_LIMIT) this.status = new EventEmitter(); // Marker drag event handler this.originDrag = new EventEmitter(); this.destinationDrag = new EventEmitter(); this.waypointsMarker = []; // Use for visible flag this.isFirstChange = true; } ngOnInit() { if (this.visible === true) { this.directionDraw(); } } ngOnChanges(obj) { /** * When visible is false then remove the direction layer */ if (!this.visible) { try { this.removeMarkers(); this.removeDirections(); } catch (e) { } } else { if (this.isFirstChange) { /** * When visible is false at the first time */ if (typeof this.directionsRenderer === 'undefined') { this.directionDraw(); } this.isFirstChange = false; return; } /** * When renderOptions are not first change then reset the display */ if (typeof obj.renderOptions !== 'undefined') { if (obj.renderOptions.firstChange === false) { this.removeMarkers(); this.removeDirections(); } } this.directionDraw(); } } ngOnDestroy() { this.destroyMarkers(); this.removeDirections(); } /** * This event is fired when the user creating or updating this direction */ directionDraw() { this.gmapsApi.getNativeMap().then(_map => { // const map = _map as unknown | google.maps.Map; const map = _map; if (typeof this.directionsRenderer === 'undefined') { this.directionsRenderer = new google.maps.DirectionsRenderer(this.renderOptions); // @ts-ignore this.directionsRenderer.setMap(map); this.directionsRenderer.addListener('directions_changed', () => { this.onChange.emit(this.directionsRenderer.getDirections()); }); } if (typeof this.directionsService === 'undefined') { this.directionsService = new google.maps.DirectionsService(); } if (typeof this.panel === 'undefined') { // @ts-ignore this.directionsRenderer.setPanel(null); } else { this.directionsRenderer.setPanel(this.panel); } // Render exist direction if (this.renderRoute) { this.directionsRenderer.setDirections(this.renderRoute); this.renderRoute = undefined; } else { // Request new direction this.directionsService.route({ origin: this.origin, destination: this.destination, travelMode: this.travelMode || google.maps.TravelMode.DRIVING, transitOptions: this.transitOptions, drivingOptions: this.drivingOptions, waypoints: this.waypoints, optimizeWaypoints: this.optimizeWaypoints, provideRouteAlternatives: this.provideRouteAlternatives, avoidHighways: this.avoidHighways, avoidTolls: this.avoidTolls, avoidFerries: this.avoidFerries, unitSystem: this.unitSystem, }, (response, status) => { this.onResponse.emit(response); // Emit Query Status this.status.emit(status); /** * DirectionsStatus * https://developers.google.com/maps/documentation/javascript/directions#DirectionsStatus */ switch (status) { case google.maps.DirectionsStatus.OK: this.directionsRenderer.setDirections(response); /** * Emit The DirectionsResult Object * https://developers.google.com/maps/documentation/javascript/directions?hl=en#DirectionsResults */ // Custom Markers if (typeof this.markerOptions !== 'undefined') { this.destroyMarkers(); // Set custom markers const _route = response.routes[0].legs[0]; try { // Origin Marker if (typeof this.markerOptions.origin !== 'undefined') { this.markerOptions.origin.map = map; this.markerOptions.origin.position = _route.start_location; this.originMarker = this.setMarker(map, this.originMarker, this.markerOptions.origin, _route.start_address); if (this.markerOptions.origin.draggable) { this.originMarker.addListener('dragend', () => { this.origin = this.originMarker.position; this.directionDraw(); this.originDrag.emit(this.origin); }); } } // Destination Marker if (typeof this.markerOptions.destination !== 'undefined') { this.markerOptions.destination.map = map; this.markerOptions.destination.position = _route.end_location; this.destinationMarker = this.setMarker(map, this.destinationMarker, this.markerOptions.destination, _route.end_address); if (this.markerOptions.destination.draggable) { this.destinationMarker.addListener('dragend', () => { this.destination = this.destinationMarker.position; this.directionDraw(); this.destinationDrag.emit(this.destination); }); } } // Waypoints Marker if (typeof this.markerOptions.waypoints !== 'undefined') { this.waypoints.forEach((waypoint, index) => { // If waypoints are not array then set all the same if (!Array.isArray(this.markerOptions.waypoints)) { this.markerOptions.waypoints.map = map; this.markerOptions.waypoints.position = _route.via_waypoints[index]; this.waypointsMarker.push(this.setMarker(map, waypoint, this.markerOptions.waypoints, _route.via_waypoints[index])); } else { this.markerOptions.waypoints[index].map = map; this.markerOptions.waypoints[index].position = _route.via_waypoints[index]; this.waypointsMarker.push(this.setMarker(map, waypoint, this.markerOptions.waypoints[index], _route.via_waypoints[index])); } }); // End forEach } } catch (err) { console.error('MarkerOptions error.', err); } } break; case google.maps.DirectionsStatus.OVER_QUERY_LIMIT: console.warn('The webpage has sent too many requests within the allowed time period.'); break; default: // console.warn(status); break; } // End switch }); } }); } /** * Custom Origin and Destination Icon * @param map map * @param marker marker * @param markerOpts properties * @param content marker's infowindow content * @returns new marker * @memberof AgmDirection */ setMarker(map, marker, markerOpts, content) { if (typeof this.infoWindow === 'undefined') { this.infoWindow = new google.maps.InfoWindow(); this.sendInfoWindow.emit(this.infoWindow); } marker = new google.maps.Marker(markerOpts); // https://developers.google.com/maps/documentation/javascript/reference/marker?hl=zh-tw#MarkerOptions.clickable if (marker.getClickable()) { marker.addListener('click', () => { const infowindoContent = typeof markerOpts.infoWindow === 'undefined' ? content : markerOpts.infoWindow; this.infoWindow.setContent(infowindoContent); this.infoWindow.open(map, marker); }); } return marker; } /** * This event is fired when remove markers */ removeMarkers() { if (typeof this.originMarker !== 'undefined') { this.originMarker.setMap(null); } if (typeof this.destinationMarker !== 'undefined') { this.destinationMarker.setMap(null); } this.waypointsMarker.forEach((w) => { if (typeof w !== 'undefined') { w.setMap(null); } }); } /** * This event is fired when remove directions */ removeDirections() { if (this.directionsRenderer !== undefined) { // @ts-ignore this.directionsRenderer.setPanel(null); this.directionsRenderer.setMap(null); // @ts-ignore this.directionsRenderer = undefined; } } /** * This event is fired when destroy markers */ destroyMarkers() { // Remove origin markers try { if (typeof this.originMarker !== 'undefined') { google.maps.event.clearListeners(this.originMarker, 'click'); if (this.markerOptions.origin.draggable) { google.maps.event.clearListeners(this.originMarker, 'dragend'); } } if (typeof this.destinationMarker !== 'undefined') { google.maps.event.clearListeners(this.destinationMarker, 'click'); if (this.markerOptions.origin.draggable) { google.maps.event.clearListeners(this.destinationMarker, 'dragend'); } } this.waypointsMarker.forEach((w) => { if (typeof w !== 'undefined') { google.maps.event.clearListeners(w, 'click'); } }); this.removeMarkers(); } catch (err) { console.error('Can not reset custom marker.', err); } } } AgmDirection.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: AgmDirection, deps: [{ token: i1.GoogleMapsAPIWrapper }], target: i0.ɵɵFactoryTarget.Directive }); AgmDirection.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.12", type: AgmDirection, selector: "agm-direction", inputs: { origin: "origin", destination: "destination", travelMode: "travelMode", transitOptions: "transitOptions", drivingOptions: "drivingOptions", waypoints: "waypoints", optimizeWaypoints: "optimizeWaypoints", provideRouteAlternatives: "provideRouteAlternatives", avoidHighways: "avoidHighways", avoidTolls: "avoidTolls", avoidFerries: "avoidFerries", unitSystem: "unitSystem", renderOptions: "renderOptions", panel: "panel", markerOptions: "markerOptions", infoWindow: "infoWindow", visible: "visible", renderRoute: "renderRoute" }, outputs: { onChange: "onChange", onResponse: "onResponse", sendInfoWindow: "sendInfoWindow", status: "status", originDrag: "originDrag", destinationDrag: "destinationDrag" }, usesOnChanges: true, ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: AgmDirection, decorators: [{ type: Directive, args: [{ selector: 'agm-direction', }] }], ctorParameters: function () { return [{ type: i1.GoogleMapsAPIWrapper }]; }, propDecorators: { origin: [{ type: Input }], destination: [{ type: Input }], travelMode: [{ type: Input }], transitOptions: [{ type: Input }], drivingOptions: [{ type: Input }], waypoints: [{ type: Input }], optimizeWaypoints: [{ type: Input }], provideRouteAlternatives: [{ type: Input }], avoidHighways: [{ type: Input }], avoidTolls: [{ type: Input }], avoidFerries: [{ type: Input }], unitSystem: [{ type: Input }], renderOptions: [{ type: Input }], panel: [{ type: Input }], markerOptions: [{ type: Input }], infoWindow: [{ type: Input }], visible: [{ type: Input }], renderRoute: [{ type: Input }], onChange: [{ type: Output }], onResponse: [{ type: Output }], sendInfoWindow: [{ type: Output }], status: [{ type: Output }], originDrag: [{ type: Output }], destinationDrag: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWdtLWRpcmVjdGlvbi5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9hZ20tZGlyZWN0aW9uL3NyYy9saWIvYWdtLWRpcmVjdGlvbi5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFxQixZQUFZLEVBQWEsTUFBTSxlQUFlLENBQUM7OztBQU1yRyxNQUFNLE9BQU8sWUFBWTtJQXVFdkIsWUFDVSxRQUE4QjtRQUE5QixhQUFRLEdBQVIsUUFBUSxDQUFzQjtRQTVEL0IsY0FBUyxHQUFxQyxFQUFFLENBQUM7UUFFakQsc0JBQWlCLEdBQUcsSUFBSSxDQUFDO1FBRXpCLDZCQUF3QixHQUFHLEtBQUssQ0FBQztRQUVqQyxrQkFBYSxHQUFHLEtBQUssQ0FBQztRQUV0QixlQUFVLEdBQUcsS0FBSyxDQUFDO1FBRW5CLGlCQUFZLEdBQUcsS0FBSyxDQUFDO1FBZ0I5QiwyQkFBMkI7UUFDbEIsWUFBTyxHQUFHLElBQUksQ0FBQztRQUt4QixpQ0FBaUM7UUFDdkIsYUFBUSxHQUFzQixJQUFJLFlBQVksRUFBTyxDQUFDO1FBRWhFLHlDQUF5QztRQUMvQixlQUFVLEdBQStDLElBQUksWUFBWSxFQUFnQyxDQUFDO1FBRXBILDJCQUEyQjtRQUNqQixtQkFBYyxHQUF5QyxJQUFJLFlBQVksRUFBMEIsQ0FBQztRQUU1Ryw2RUFBNkU7UUFDbkUsV0FBTSxHQUErQyxJQUFJLFlBQVksRUFBZ0MsQ0FBQztRQUVoSCw0QkFBNEI7UUFDbEIsZUFBVSxHQUFzQixJQUFJLFlBQVksRUFBTyxDQUFDO1FBQ3hELG9CQUFlLEdBQXNCLElBQUksWUFBWSxFQUFPLENBQUM7UUFRL0Qsb0JBQWUsR0FBOEIsRUFBRSxDQUFDO1FBRXhELHVCQUF1QjtRQUNmLGtCQUFhLEdBQUcsSUFBSSxDQUFDO0lBSXpCLENBQUM7SUFFTCxRQUFRO1FBQ04s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LCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEaXJlY3RpdmUsIElucHV0LCBPdXRwdXQsIE9uQ2hhbmdlcywgT25Jbml0LCBFdmVudEVtaXR0ZXIsIE9uRGVzdHJveSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBHb29nbGVNYXBzQVBJV3JhcHBlciB9IGZyb20gJ0BhbWluLWthcmltaS9hZ20tY29yZSc7XHJcblxyXG5ARGlyZWN0aXZlKHtcclxuICBzZWxlY3RvcjogJ2FnbS1kaXJlY3Rpb24nLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgQWdtRGlyZWN0aW9uIGltcGxlbWVudHMgT25DaGFuZ2VzLCBPbkluaXQsIE9uRGVzdHJveSB7XHJcblxyXG4gIEBJbnB1dCgpIG9yaWdpbjogc3RyaW5nIHwgZ29vZ2xlLm1hcHMuUGxhY2UgfCBnb29nbGUubWFwcy5MYXRMbmcgfCBnb29nbGUubWFwcy5MYXRMbmdMaXRlcmFsO1xyXG5cclxuICBASW5wdXQoKSBkZXN0aW5hdGlvbjogc3RyaW5nIHwgZ29vZ2xlLm1hcHMuUGxhY2UgfCBnb29nbGUubWFwcy5MYXRMbmcgfCBnb29nbGUubWFwcy5MYXRMbmdMaXRlcmFsO1xyXG5cclxuICBASW5wdXQoKSB0cmF2ZWxNb2RlPzogZ29vZ2xlLm1hcHMuVHJhdmVsTW9kZTtcclxuXHJcbiAgQElucHV0KCkgdHJhbnNpdE9wdGlvbnM/OiBnb29nbGUubWFwcy5UcmFuc2l0T3B0aW9ucztcclxuXHJcbiAgQElucHV0KCkgZHJpdmluZ09wdGlvbnM/OiBnb29nbGUubWFwcy5Ecml2aW5nT3B0aW9ucztcclxuXHJcbiAgQElucHV0KCkgd2F5cG9pbnRzOiBnb29nbGUubWFwcy5EaXJlY3Rpb25zV2F5cG9pbnRbXSA9IFtdO1xyXG5cclxuICBASW5wdXQoKSBvcHRpbWl6ZVdheXBvaW50cyA9IHRydWU7XHJcblxyXG4gIEBJbnB1dCgpIHByb3ZpZGVSb3V0ZUFsdGVybmF0aXZlcyA9IGZhbHNlO1xyXG5cclxuICBASW5wdXQoKSBhdm9pZEhpZ2h3YXlzID0gZmFsc2U7XHJcblxyXG4gIEBJbnB1dCgpIGF2b2lkVG9sbHMgPSBmYWxzZTtcclxuXHJcbiAgQElucHV0KCkgYXZvaWRGZXJyaWVzID0gZmFsc2U7XHJcblxyXG4gIEBJbnB1dCgpIHVuaXRTeXN0ZW0/OiBnb29nbGUubWFwcy5Vbml0U3lzdGVtO1xyXG5cclxuICBASW5wdXQoKSByZW5kZXJPcHRpb25zPzogZ29vZ2xlLm1hcHMuRGlyZWN0aW9uc1JlbmRlcmVyT3B0aW9ucztcclxuXHJcbiAgQElucHV0KCkgcGFuZWw/OiBFbGVtZW50O1xyXG5cclxuICBASW5wdXQoKSBtYXJrZXJPcHRpb25zOiB7XHJcbiAgICBvcmlnaW46IGdvb2dsZS5tYXBzLk1hcmtlck9wdGlvbnMsXHJcbiAgICBkZXN0aW5hdGlvbjogZ29vZ2xlLm1hcHMuTWFya2VyT3B0aW9ucyxcclxuICAgIHdheXBvaW50cz86IGdvb2dsZS5tYXBzLk1hcmtlck9wdGlvbnMsXHJcbiAgfTtcclxuXHJcbiAgQElucHV0KCkgaW5mb1dpbmRvdzogZ29vZ2xlLm1hcHMuSW5mb1dpbmRvdztcclxuXHJcbiAgLy8gUmVtb3ZlIG9yIGRyYXcgZGlyZWN0aW9uXHJcbiAgQElucHV0KCkgdmlzaWJsZSA9IHRydWU7XHJcblxyXG4gIC8vIFJlbmRlciBleGlzdCBkaXJlY3Rpb25cclxuICBASW5wdXQoKSByZW5kZXJSb3V0ZT86IGdvb2dsZS5tYXBzLkRpcmVjdGlvbnNSZXN1bHQgfCBudWxsO1xyXG5cclxuICAvLyBEaXJlY3Rpb24gY2hhbmdlIGV2ZW50IGhhbmRsZXJcclxuICBAT3V0cHV0KCkgb25DaGFuZ2U6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XHJcblxyXG4gIC8vIERpcmVjdGlvbiByZXNwb25zZSBmb3IgdGhlIG5ldyByZXF1ZXN0XHJcbiAgQE91dHB1dCgpIG9uUmVzcG9uc2U6IEV2ZW50RW1pdHRlcjxnb29nbGUubWFwcy5EaXJlY3Rpb25zUmVzdWx0PiA9IG5ldyBFdmVudEVtaXR0ZXI8Z29vZ2xlLm1hcHMuRGlyZWN0aW9uc1Jlc3VsdD4oKTtcclxuXHJcbiAgLy8gU2VuZCBhIGN1c3RvbSBpbmZvd2luZG93XHJcbiAgQE91dHB1dCgpIHNlbmRJbmZvV2luZG93OiBFdmVudEVtaXR0ZXI8Z29vZ2xlLm1hcHMuSW5mb1dpbmRvdz4gPSBuZXcgRXZlbnRFbWl0dGVyPGdvb2dsZS5tYXBzLkluZm9XaW5kb3c+KCk7XHJcblxyXG4gIC8vIFN0YXR1cyBvZiBEaXJlY3Rpb25zIFF1ZXJ5IChnb29nbGUubWFwcy5EaXJlY3Rpb25zU3RhdHVzLk9WRVJfUVVFUllfTElNSVQpXHJcbiAgQE91dHB1dCgpIHN0YXR1czogRXZlbnRFbWl0dGVyPGdvb2dsZS5tYXBzLkRpcmVjdGlvbnNTdGF0dXM+ID0gbmV3IEV2ZW50RW1pdHRlcjxnb29nbGUubWFwcy5EaXJlY3Rpb25zU3RhdHVzPigpO1xyXG5cclxuICAvLyBNYXJrZXIgZHJhZyBldmVudCBoYW5kbGVyXHJcbiAgQE91dHB1dCgpIG9yaWdpbkRyYWc6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XHJcbiAgQE91dHB1dCgpIGRlc3RpbmF0aW9uRHJhZzogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcclxuXHJcbiAgcHVibGljIGRpcmVjdGlvbnNTZXJ2aWNlOiBnb29nbGUubWFwcy5EaXJlY3Rpb25zU2VydmljZTtcclxuICBwdWJsaWMgZGlyZWN0aW9uc1JlbmRlcmVyOiBnb29nbGUubWFwcy5EaXJlY3Rpb25zUmVuZGVyZXI7XHJcblxyXG4gIC8vIFVzZSBmb3IgY3VzdG9tIG1hcmtlclxyXG4gIHByaXZhdGUgb3JpZ2luTWFya2VyPzogYW55O1xyXG4gIHByaXZhdGUgZGVzdGluYXRpb25NYXJrZXI/OiBhbnk7XHJcbiAgcHJpdmF0ZSB3YXlwb2ludHNNYXJrZXI6IEFycmF5PGdvb2dsZS5tYXBzLk1hcmtlcj4gPSBbXTtcclxuXHJcbiAgLy8gVXNlIGZvciB2aXNpYmxlIGZsYWdcclxuICBwcml2YXRlIGlzRmlyc3RDaGFuZ2UgPSB0cnVlO1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgZ21hcHNBcGk6IEdvb2dsZU1hcHNBUElXcmFwcGVyLFxyXG4gICkgeyB9XHJcblxyXG4gIG5nT25Jbml0KCkge1xyXG4gICAgaWYgKHRoaXMudmlzaWJsZSA9PT0gdHJ1ZSkge1xyXG4gICAgICB0aGlzLmRpcmVjdGlvbkRyYXcoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIG5nT25DaGFuZ2VzKG9iajogYW55KSB7XHJcbiAgICAvKipcclxuICAgICAqIFdoZW4gdmlzaWJsZSBpcyBmYWxzZSB0aGVuIHJlbW92ZSB0aGUgZGlyZWN0aW9uIGxheWVyXHJcbiAgICAgKi9cclxuICAgIGlmICghdGhpcy52aXNpYmxlKSB7XHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgdGhpcy5yZW1vdmVNYXJrZXJzKCk7XHJcbiAgICAgICAgdGhpcy5yZW1vdmVEaXJlY3Rpb25zKCk7XHJcbiAgICAgIH0gY2F0Y2ggKGUpIHsgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgaWYgKHRoaXMuaXNGaXJzdENoYW5nZSkge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFdoZW4gdmlzaWJsZSBpcyBmYWxzZSBhdCB0aGUgZmlyc3QgdGltZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGlmICh0eXBlb2YgdGhpcy5kaXJlY3Rpb25zUmVuZGVyZXIgPT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgICB0aGlzLmRpcmVjdGlvbkRyYXcoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5pc0ZpcnN0Q2hhbmdlID0gZmFsc2U7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvKipcclxuICAgICAgICogV2hlbiByZW5kZXJPcHRpb25zIGFyZSBub3QgZmlyc3QgY2hhbmdlIHRoZW4gcmVzZXQgdGhlIGRpc3BsYXlcclxuICAgICAgICovXHJcbiAgICAgIGlmICh0eXBlb2Ygb2JqLnJlbmRlck9wdGlvbnMgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgaWYgKG9iai5yZW5kZXJPcHRpb25zLmZpcnN0Q2hhbmdlID09PSBmYWxzZSkge1xyXG4gICAgICAgICAgdGhpcy5yZW1vdmVNYXJrZXJzKCk7XHJcbiAgICAgICAgICB0aGlzLnJlbW92ZURpcmVjdGlvbnMoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5kaXJlY3Rpb25EcmF3KCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpIHtcclxuICAgIHRoaXMuZGVzdHJveU1hcmtlcnMoKTtcclxuICAgIHRoaXMucmVtb3ZlRGlyZWN0aW9ucygpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVGhpcyBldmVudCBpcyBmaXJlZCB3aGVuIHRoZSB1c2VyIGNyZWF0aW5nIG9yIHVwZGF0aW5nIHRoaXMgZGlyZWN0aW9uXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBkaXJlY3Rpb25EcmF3KCkge1xyXG4gICAgdGhpcy5nbWFwc0FwaS5nZXROYXRpdmVNYXAoKS50aGVuKF9tYXAgPT4ge1xyXG5cclxuICAgICAgLy8gY29uc3QgbWFwID0gX21hcCBhcyB1bmtub3duIHwgZ29vZ2xlLm1hcHMuTWFwO1xyXG4gICAgICBjb25zdCBtYXAgPSBfbWFwO1xyXG5cclxuICAgICAgaWYgKHR5cGVvZiB0aGlzLmRpcmVjdGlvbnNSZW5kZXJlciA9PT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICB0aGlzLmRpcmVjdGlvbnNSZW5kZXJlciA9IG5ldyBnb29nbGUubWFwcy5EaXJlY3Rpb25zUmVuZGVyZXIodGhpcy5yZW5kZXJPcHRpb25zKTtcclxuICAgICAgICAvLyBAdHMtaWdub3JlXHJcbiAgICAgICAgdGhpcy5kaXJlY3Rpb25zUmVuZGVyZXIuc2V0TWFwKG1hcCk7XHJcbiAgICAgICAgdGhpcy5kaXJlY3Rpb25zUmVuZGVyZXIuYWRkTGlzdGVuZXIoJ2RpcmVjdGlvbnNfY2hhbmdlZCcsICgpID0+IHtcclxuICAgICAgICAgIHRoaXMub25DaGFuZ2UuZW1pdCh0aGlzLmRpcmVjdGlvbnNSZW5kZXJlci5nZXREaXJlY3Rpb25zKCkpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAodHlwZW9mIHRoaXMuZGlyZWN0aW9uc1NlcnZpY2UgPT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgdGhpcy5kaXJlY3Rpb25zU2VydmljZSA9IG5ldyBnb29nbGUubWFwcy5EaXJlY3Rpb25zU2VydmljZSgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAodHlwZW9mIHRoaXMucGFuZWwgPT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxyXG4gICAgICAgIHRoaXMuZGlyZWN0aW9uc1JlbmRlcmVyLnNldFBhbmVsKG51bGwpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuZGlyZWN0aW9uc1JlbmRlcmVyLnNldFBhbmVsKHRoaXMucGFuZWwgYXMgYW55KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gUmVuZGVyIGV4aXN0IGRpcmVjdGlvblxyXG4gICAgICBpZiAodGhpcy5yZW5kZXJSb3V0ZSkge1xyXG4gICAgICAgIHRoaXMuZGlyZWN0aW9uc1JlbmRlcmVyLnNldERpcmVjdGlvbnModGhpcy5yZW5kZXJSb3V0ZSk7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJSb3V0ZSA9IHVuZGVmaW5lZDtcclxuICAgICAgfSBlbHNlIHtcclxuXHJcbiAgICAgICAgLy8gUmVxdWVzdCBuZXcgZGlyZWN0aW9uXHJcbiAgICAgICAgdGhpcy5kaXJlY3Rpb25zU2VydmljZS5yb3V0ZSh7XHJcbiAgICAgICAgICBvcmlnaW46IHRoaXMub3JpZ2luLFxyXG4gICAgICAgICAgZGVzdGluYXRpb246IHRoaXMuZGVzdGluYXRpb24sXHJcbiAgICAgICAgICB0cmF2ZWxNb2RlOiB0aGlzLnRyYXZlbE1vZGUgfHwgZ29vZ2xlLm1hcHMuVHJhdmVsTW9kZS5EUklWSU5HLFxyXG4gICAgICAgICAgdHJhbnNpdE9wdGlvbnM6IHRoaXMudHJhbnNpdE9wdGlvbnMsXHJcbiAgICAgICAgICBkcml2aW5nT3B0aW9uczogdGhpcy5kcml2aW5nT3B0aW9ucyxcclxuICAgICAgICAgIHdheXBvaW50czogdGhpcy53YXlwb2ludHMsXHJcbiAgICAgICAgICBvcHRpbWl6ZVdheXBvaW50czogdGhpcy5vcHRpbWl6ZVdheXBvaW50cyxcclxuICAgICAgICAgIHByb3ZpZGVSb3V0ZUFsdGVybmF0aXZlczogdGhpcy5wcm92aWRlUm91dGVBbHRlcm5hdGl2ZXMsXHJcbiAgICAgICAgICBhdm9pZEhpZ2h3YXlzOiB0aGlzLmF2b2lkSGlnaHdheXMsXHJcbiAgICAgICAgICBhdm9pZFRvbGxzOiB0aGlzLmF2b2lkVG9sbHMsXHJcbiAgICAgICAgICBhdm9pZEZlcnJpZXM6IHRoaXMuYXZvaWRGZXJyaWVzLFxyXG4gICAgICAgICAgdW5pdFN5c3RlbTogdGhpcy51bml0U3lzdGVtLFxyXG4gICAgICAgIH0sIChyZXNwb25zZTogYW55LCBzdGF0dXMpID0+IHtcclxuXHJcbiAgICAgICAgICB0aGlzLm9uUmVzcG9uc2UuZW1pdChyZXNwb25zZSk7XHJcblxyXG4gICAgICAgICAgLy8gRW1pdCBRdWVyeSBTdGF0dXNcclxuICAgICAgICAgIHRoaXMuc3RhdHVzLmVtaXQoc3RhdHVzKTtcclxuXHJcbiAgICAgICAgICAvKipcclxuICAgICAgICAgICAqIERpcmVjdGlvbnNTdGF0dXNcclxuICAgICAgICAgICAqIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL21hcHMvZG9jdW1lbnRhdGlvbi9qYXZhc2NyaXB0L2RpcmVjdGlvbnMjRGlyZWN0aW9uc1N0YXR1c1xyXG4gICAgICAgICAgICovXHJcbiAgICAgICAgICBzd2l0Y2ggKHN0YXR1cykge1xyXG4gICAgICAgICAgICBjYXNlIGdvb2dsZS5tYXBzLkRpcmVjdGlvbnNTdGF0dXMuT0s6XHJcblxyXG4gICAgICAgICAgICAgIHRoaXMuZGlyZWN0aW9uc1JlbmRlcmVyLnNldERpcmVjdGlvbnMocmVzcG9uc2UpO1xyXG5cclxuICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgKiBFbWl0IFRoZSBEaXJlY3Rpb25zUmVzdWx0IE9iamVjdFxyXG4gICAgICAgICAgICAgICAqIGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL21hcHMvZG9jdW1lbnRhdGlvbi9qYXZhc2NyaXB0L2RpcmVjdGlvbnM/aGw9ZW4jRGlyZWN0aW9uc1Jlc3VsdHNcclxuICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAvLyBDdXN0b20gTWFya2Vyc1xyXG4gICAgICAgICAgICAgIGlmICh0eXBlb2YgdGhpcy5tYXJrZXJPcHRpb25zICE9PSAndW5kZWZpbmVkJykge1xyXG5cclxuICAgICAgICAgICAgICAgIHRoaXMuZGVzdHJveU1hcmtlcnMoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBTZXQgY3VzdG9tIG1hcmtlcnNcclxuICAgICAgICAgICAgICAgIGNvbnN0IF9yb3V0ZSA9IHJlc3BvbnNlLnJvdXRlc1swXS5sZWdzWzBdO1xyXG4gICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgLy8gT3JpZ2luIE1hcmtlclxyXG4gICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHRoaXMubWFya2VyT3B0aW9ucy5vcmlnaW4gIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tYXJrZXJPcHRpb25zLm9yaWdpbi5tYXAgPSBtYXA7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tYXJrZXJPcHRpb25zLm9yaWdpbi5wb3NpdGlvbiA9IF9yb3V0ZS5zdGFydF9sb2NhdGlvbjtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm9yaWdpbk1hcmtlciA9IHRoaXMuc2V0TWFya2VyKFxyXG4gICAgICAgICAgICAgICAgICAgICAgbWFwLFxyXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5vcmlnaW5NYXJrZXIsXHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hcmtlck9wdGlvbnMub3JpZ2luLFxyXG4gICAgICAgICAgICAgICAgICAgICAgX3JvdXRlLnN0YXJ0X2FkZHJlc3MsXHJcbiAgICAgICAgICAgICAgICAgICAgKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMubWFya2VyT3B0aW9ucy5vcmlnaW4uZHJhZ2dhYmxlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLm9yaWdpbk1hcmtlci5hZGRMaXN0ZW5lcignZHJhZ2VuZCcsICgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5vcmlnaW4gPSB0aGlzLm9yaWdpbk1hcmtlci5wb3NpdGlvbjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kaXJlY3Rpb25EcmF3KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub3JpZ2luRHJhZy5lbWl0KHRoaXMub3JpZ2luKTtcclxuICAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAvLyBEZXN0aW5hdGlvbiBNYXJrZXJcclxuICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiB0aGlzLm1hcmtlck9wdGlvbnMuZGVzdGluYXRpb24gIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tYXJrZXJPcHRpb25zLmRlc3RpbmF0aW9uLm1hcCA9IG1hcDtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm1hcmtlck9wdGlvbnMuZGVzdGluYXRpb24ucG9zaXRpb24gPSBfcm91dGUuZW5kX2xvY2F0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGVzdGluYXRpb25NYXJrZXIgPSB0aGlzLnNldE1hcmtlcihcclxuICAgICAgICAgICAgICAgICAgICAgIG1hcCxcclxuICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGVzdGluYXRpb25NYXJrZXIsXHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hcmtlck9wdGlvbnMuZGVzdGluYXRpb24sXHJcbiAgICAgICAgICAgICAgICAgICAgICBfcm91dGUuZW5kX2FkZHJlc3MsXHJcbiAgICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5tYXJrZXJPcHRpb25zLmRlc3RpbmF0aW9uLmRyYWdnYWJsZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5kZXN0aW5hdGlvbk1hcmtlci5hZGRMaXN0ZW5lcignZHJhZ2VuZCcsICgpID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kZXN0aW5hdGlvbiA9IHRoaXMuZGVzdGluYXRpb25NYXJrZXIucG9zaXRpb247XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGlyZWN0aW9uRHJhdygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRlc3RpbmF0aW9uRHJhZy5lbWl0KHRoaXMuZGVzdGluYXRpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAvLyBXYXlwb2ludHMgTWFya2VyXHJcbiAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdGhpcy5tYXJrZXJPcHRpb25zLndheXBvaW50cyAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy53YXlwb2ludHMuZm9yRWFjaCgod2F5cG9pbnQsIGluZGV4KSA9PiB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgLy8gSWYgd2F5cG9pbnRzIGFyZSBub3QgYXJyYXkgdGhlbiBzZXQgYWxsIHRoZSBzYW1lXHJcbiAgICAgICAgICAgICAgICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkodGhpcy5tYXJrZXJPcHRpb25zLndheXBvaW50cykpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5tYXJrZXJPcHRpb25zLndheXBvaW50cyEubWFwID0gbWFwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hcmtlck9wdGlvbnMud2F5cG9pbnRzIS5wb3NpdGlvbiA9IF9yb3V0ZS52aWFfd2F5cG9pbnRzW2luZGV4XTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy53YXlwb2ludHNNYXJrZXIucHVzaCh0aGlzLnNldE1hcmtlcihcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBtYXAsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgd2F5cG9pbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5tYXJrZXJPcHRpb25zLndheXBvaW50cyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBfcm91dGUudmlhX3dheXBvaW50c1tpbmRleF0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5tYXJrZXJPcHRpb25zLndheXBvaW50c1tpbmRleF0ubWFwID0gbWFwO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hcmtlck9wdGlvbnMud2F5cG9pbnRzW2luZGV4XS5wb3NpdGlvbiA9IF9yb3V0ZS52aWFfd2F5cG9pbnRzW2luZGV4XTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy53YXlwb2ludHNNYXJrZXIucHVzaCh0aGlzLnNldE1hcmtlcihcclxuICAgICAgICAgICAgICAgICAgICAgICAgICBtYXAsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgd2F5cG9pbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5tYXJrZXJPcHRpb25zLndheXBvaW50c1tpbmRleF0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgX3JvdXRlLnZpYV93YXlwb2ludHNbaW5kZXhdLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICApKTtcclxuICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgfSk7IC8vIEVuZCBmb3JFYWNoXHJcblxyXG4gICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignTWFya2VyT3B0aW9ucyBlcnJvci4nLCBlcnIpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgICAgICBjYXNlIGdvb2dsZS5tYXBzLkRpcmVjdGlvbnNTdGF0dXMuT1ZFUl9RVUVSWV9MSU1JVDpcclxuICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ1RoZSB3ZWJwYWdlIGhhcyBzZW50IHRvbyBtYW55IHJlcXVlc3RzIHdpdGhpbiB0aGUgYWxsb3dlZCB0aW1lIHBlcmlvZC4nKTtcclxuICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgICAvLyBjb25zb2xlLndhcm4oc3RhdHVzKTtcclxuICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIH0gLy8gRW5kIHN3aXRjaFxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEN1c3RvbSBPcmlnaW4gYW5kIERlc3RpbmF0aW9uIEljb25cclxuICAgKiBAcGFyYW0gbWFwIG1hcFxyXG4gICAqIEBwYXJhbSBtYXJrZXIgbWFya2VyXHJcbiAgICogQHBhcmFtIG1hcmtlck9wdHMgcHJvcGVydGllc1xyXG4gICAqIEBwYXJhbSBjb250ZW50IG1hcmtlcidzIGluZm93aW5kb3cgY29udGVudFxyXG4gICAqIEByZXR1cm5zIG5ldyBtYXJrZXJcclxuICAgKiBAbWVtYmVyb2YgQWdtRGlyZWN0aW9uXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBzZXRNYXJrZXIoXHJcbiAgICBtYXA6IGdvb2dsZS5tYXBzLk1hcCxcclxuICAgIG1hcmtlcjogZ29vZ2xlLm1hcHMuTWFya2VyIHwgZ29vZ2xlLm1hcHMuRGlyZWN0aW9uc1dheXBvaW50LFxyXG4gICAgbWFya2VyT3B0czogYW55LFxyXG4gICAgY29udGVudDogZ29vZ2xlLm1hcHMuTGF0TG5nIHwgc3RyaW5nXHJcbiAgKTogZ29vZ2xlLm1hcHMuTWFya2VyIHtcclxuICAgIGlmICh0eXBlb2YgdGhpcy5pbmZvV2luZG93ID09PSAndW5kZWZpbmVkJykge1xyXG4gICAgICB0aGlzLmluZm9XaW5kb3cgPSBuZXcgZ29vZ2xlLm1hcHMuSW5mb1dpbmRvdygpO1xyXG4gICAgICB0aGlzLnNlbmRJbmZvV2luZG93LmVtaXQodGhpcy5pbmZvV2luZG93KTtcclxuICAgIH1cclxuXHJcbiAgICBtYXJrZXIgPSBuZXcgZ29vZ2xlLm1hcHMuTWFya2VyKG1hcmtlck9wdHMpO1xyXG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXJzLmdvb2dsZS5jb20vbWFwcy9kb2N1bWVudGF0aW9uL2phdmFzY3JpcHQvcmVmZXJlbmNlL21hcmtlcj9obD16aC10dyNNYXJrZXJPcHRpb25zLmNsaWNrYWJsZVxyXG4gICAgaWYgKG1hcmtlci5nZXRDbGlja2FibGUoKSkge1xyXG4gICAgICBtYXJrZXIuYWRkTGlzdGVuZXIoJ2NsaWNrJywgKCkgPT4ge1xyXG4gICAgICAgIGNvbnN0IGluZm93aW5kb0NvbnRlbnQ6IHN0cmluZyA9IHR5cGVvZiBtYXJrZXJPcHRzLmluZm9XaW5kb3cgPT09ICd1bmRlZmluZWQnID8gY29udGVudCA6IG1hcmtlck9wdHMuaW5mb1dpbmRvdztcclxuICAgICAgICB0aGlzLmluZm9XaW5kb3cuc2V0Q29udGVudChpbmZvd2luZG9Db250ZW50KTtcclxuICAgICAgICB0aGlzLmluZm9XaW5kb3cub3BlbihtYXAsIG1hcmtlciBhcyBnb29nbGUubWFwcy5NVkNPYmplY3QpO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuICAgIHJldHVybiBtYXJrZXI7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBUaGlzIGV2ZW50IGlzIGZpcmVkIHdoZW4gcmVtb3ZlIG1hcmtlcnNcclxuICAgKi9cclxuICBwcml2YXRlIHJlbW92ZU1hcmtlcnMoKTogdm9pZCB7XHJcbiAgICBpZiAodHlwZW9mIHRoaXMub3JpZ2luTWFya2VyICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICB0aGlzLm9yaWdpbk1hcmtlci5zZXRNYXAobnVsbCk7XHJcbiAgICB9XHJcbiAgICBpZiAodHlwZW9mIHRoaXMuZGVzdGluYXRpb25NYXJrZXIgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgIHRoaXMuZGVzdGluYXRpb25NYXJrZXIuc2V0TWFwKG51bGwpO1xyXG4gICAgfVxyXG4gICAgdGhpcy53YXlwb2ludHNNYXJrZXIuZm9yRWFjaCgodzogYW55KSA9PiB7XHJcbiAgICAgIGlmICh0eXBlb2YgdyAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICB3LnNldE1hcChudWxsKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBUaGlzIGV2ZW50IGlzIGZpcmVkIHdoZW4gcmVtb3ZlIGRpcmVjdGlvbnNcclxuICAgKi9cclxuICBwcml2YXRlIHJlbW92ZURpcmVjdGlvbnMoKTogdm9pZCB7XHJcbiAgICBpZiAodGhpcy5kaXJlY3Rpb25zUmVuZGVyZXIgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAvLyBAdHMtaWdub3JlXHJcbiAgICAgIHRoaXMuZGlyZWN0aW9uc1JlbmRlcmVyLnNldFBhbmVsKG51bGwpO1xyXG4gICAgICB0aGlzLmRpcmVjdGlvbnNSZW5kZXJlci5zZXRNYXAobnVsbCk7XHJcbiAgICAgIC8vIEB0cy1pZ25vcmVcclxuICAgICAgdGhpcy5kaXJlY3Rpb25zUmVuZGVyZXIgPSB1bmRlZmluZWQ7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBUaGlzIGV2ZW50IGlzIGZpcmVkIHdoZW4gZGVzdHJveSBtYXJrZXJzXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBkZXN0cm95TWFya2VycygpOiB2b2lkIHtcclxuICAgIC8vIFJlbW92ZSBvcmlnaW4gbWFya2Vyc1xyXG4gICAgdHJ5IHtcclxuICAgICAgaWYgKHR5cGVvZiB0aGlzLm9yaWdpbk1hcmtlciAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICBnb29nbGUubWFwcy5ldmVudC5jbGVhckxpc3RlbmVycyh0aGlzLm9yaWdpbk1hcmtlciwgJ2NsaWNrJyk7XHJcbiAgICAgICAgaWYgKHRoaXMubWFya2VyT3B0aW9ucy5vcmlnaW4uZHJhZ2dhYmxlKSB7XHJcbiAgICAgICAgICBnb29nbGUubWFwcy5ldmVudC5jbGVhckxpc3RlbmVycyh0aGlzLm9yaWdpbk1hcmtlciwgJ2RyYWdlbmQnKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHR5cGVvZiB0aGlzLmRlc3RpbmF0aW9uTWFya2VyICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgIGdvb2dsZS5tYXBzLmV2ZW50LmNsZWFyTGlzdGVuZXJzKHRoaXMuZGVzdGluYXRpb25NYXJrZXIsICdjbGljaycpO1xyXG4gICAgICAgIGlmICh0aGlzLm1hcmtlck9wdGlvbnMub3JpZ2luLmRyYWdnYWJsZSkge1xyXG4gICAgICAgICAgZ29vZ2xlLm1hcHMuZXZlbnQuY2xlYXJMaXN0ZW5lcnModGhpcy5kZXN0aW5hdGlvbk1hcmtlciwgJ2RyYWdlbmQnKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy53YXlwb2ludHNNYXJrZXIuZm9yRWFjaCgodzogYW55KSA9PiB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiB3ICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgICAgZ29vZ2xlLm1hcHMuZXZlbnQuY2xlYXJMaXN0ZW5lcnModywgJ2NsaWNrJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgICAgdGhpcy5yZW1vdmVNYXJrZXJzKCk7XHJcblxyXG4gICAgfSBjYXRjaCAoZXJyKSB7XHJcbiAgICAgIGNvbnNvbGUuZXJyb3IoJ0NhbiBub3QgcmVzZXQgY3VzdG9tIG1hcmtlci4nLCBlcnIpO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG4iXX0=