UNPKG

acdc-gis-utils

Version:

Requires following dependencies: <br/> "bootstrap": "^4.4.1" or "@angular/material": "^8.0.0" <br/> "leaflet": "^1.6.0", <br/> "terraformer": "^1.0.10", <br/> "terraformer-wkt-parser": "^1.2.1"

310 lines (309 loc) 32.5 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,uselessCode} checked by tsc */ import { Component, Input, TemplateRef, forwardRef, ElementRef, ViewChild } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import * as L from "leaflet"; import { AcdcGisUtilsService } from '../acdc-gis-utils.service'; export class LocationPickerInputComponent { /** * @param {?} acdcGisUtilsService */ constructor(acdcGisUtilsService) { this.acdcGisUtilsService = acdcGisUtilsService; this.mapHeight = '200px'; this.mapWidth = '100%'; this.configs = { showMap: true, map: null, expandOnInputClick: false }; this.propagateChange = (_) => { }; } /** * @param {?} value * @return {?} */ set defaultShowMap(value) { this._defaultShowMap = value; this.configs.showMap = value; } /** * @return {?} */ get defaultShowMap() { return this._defaultShowMap; } /** * @return {?} */ get locationValue() { return this._locationValue; } /** * @param {?} value * @return {?} */ set locationValue(value) { this._locationValue = value; this.propagateChange(this._locationValue); if (value) { /** @type {?} */ let center = this.acdcGisUtilsService.fromWkt(this.locationValue); /** @type {?} */ let latlng = L.latLng(center['coordinates'][1], center['coordinates'][0]); this.setMapView(latlng); } } /** * @return {?} */ ngOnInit() { this.configs.showMap = this.defaultShowMap; this.configs.expandOnInputClick = this.expandOnInputClick; this.initMap(); if (this.map) { setTimeout(() => { this.map.invalidateSize(false); }, 100); this.configs.map = this.map; } } /** * initialize map, set initial zoom, add osm layer, call map locate * @return {?} */ initMap() { /** @type {?} */ let initialLatLng; if (this.initialLongitude && this.initialLatitude) { initialLatLng = L.latLng(this.initialLatitude, this.initialLongitude); } else { initialLatLng = L.latLng(0, 0); } /** @type {?} */ let initialZoomLoc; if (this.initialZoom && this.initialZoom > 0 && this.initialZoom < 23) { initialZoomLoc = this.initialZoom; } else { initialZoomLoc = 1; } this.map = L.map(this.leafletMapDivRef.nativeElement, { drawControl: false }).setView(initialLatLng, initialZoomLoc); L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors' }).addTo(this.map); this.initMapLocate(); } /** * start listening to click events for choosing location * @return {?} */ initMapLocate() { this.map.on('click', (event) => { if (!this.readonly) { /** @type {?} */ let centerWkt = this.acdcGisUtilsService.toWkt(event.latlng); this._locationValue = centerWkt; this.propagateChange(this._locationValue); this.setMapView(event.latlng); if (this.closeOnChoose) { setTimeout(() => { this.configs.showMap = false; }, 500); } } }); } /** * unregister listening click event * @return {?} */ offMapLocate() { this.map.off('click'); } /** * input field trigger (show/hide map) * @param {?} props * @return {?} */ onChooseLocation(props) { props['configs'].showMap = !props['configs'].showMap; setTimeout(() => { props['configs'].map.invalidateSize(false); }); } /** * input field click event handler * @param {?} props * @return {?} */ onInputClick(props) { if (props['configs'].expandOnInputClick) { props['configs'].showMap = true; setTimeout(() => { props['configs'].map.invalidateSize(false); }); } } /** * close map button click handler * @return {?} */ onCloseMapBtnClick() { this.configs.showMap = false; setTimeout(() => { this.map.invalidateSize(false); }); } /** * form field required functions * @param {?} obj * @return {?} */ writeValue(obj) { this.locationValue = obj; } /** * @param {?} fn * @return {?} */ registerOnChange(fn) { this.propagateChange = fn; } /** * @param {?} fn * @return {?} */ registerOnTouched(fn) { } /** * @param {?} isDisabled * @return {?} */ setDisabledState(isDisabled) { } /** * zoom map to passed location and pin location with marker * @param {?} latlng * @return {?} */ setMapView(latlng) { this.map.flyTo(latlng, this.map.getZoom(), { pan: { animate: true, duration: 3 }, zoom: { animate: true, duration: 3 } }); this.locateMarker(latlng); } /** * locate marker at passed location * @param {?} latlng * @return {?} */ locateMarker(latlng) { if (this.marker) { this.marker.setLatLng(latlng); } else { /** @type {?} */ const defaultMarker = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAApCAYAAADAk4LOAAAFgUlEQVR4Aa1XA5BjWRTN2oW17d3YaZtr2962HUzbDNpjszW24mRt28p47v7zq/bXZtrp/lWnXr337j3nPCe85NcypgSFdugCpW5YoDAMRaIMqRi6aKq5E3YqDQO3qAwjVWrD8Ncq/RBpykd8oZUb/kaJutow8r1aP9II0WmLKLIsJyv1w/kqw9Ch2MYdB++12Onxee/QMwvf4/Dk/Lfp/i4nxTXtOoQ4pW5Aj7wpici1A9erdAN2OH64x8OSP9j3Ft3b7aWkTg/Fm91siTra0f9on5sQr9INejH6CUUUpavjFNq1B+Oadhxmnfa8RfEmN8VNAsQhPqF55xHkMzz3jSmChWU6f7/XZKNH+9+hBLOHYozuKQPxyMPUKkrX/K0uWnfFaJGS1QPRtZsOPtr3NsW0uyh6NNCOkU3Yz+bXbT3I8G3xE5EXLXtCXbbqwCO9zPQYPRTZ5vIDXD7U+w7rFDEoUUf7ibHIR4y6bLVPXrz8JVZEql13trxwue/uDivd3fkWRbS6/IA2bID4uk0UpF1N8qLlbBlXs4Ee7HLTfV1j54APvODnSfOWBqtKVvjgLKzF5YdEk5ewRkGlK0i33Eofffc7HT56jD7/6U+qH3Cx7SBLNntH5YIPvODnyfIXZYRVDPqgHtLs5ABHD3YzLuespb7t79FY34DjMwrVrcTuwlT55YMPvOBnRrJ4VXTdNnYug5ucHLBjEpt30701A3Ts+HEa73u6dT3FNWwflY86eMHPk+Yu+i6pzUpRrW7SNDg5JHR4KapmM5Wv2E8Tfcb1HoqqHMHU+uWDD7zg54mz5/2BSnizi9T1Dg4QQXLToGNCkb6tb1NU+QAlGr1++eADrzhn/u8Q2YZhQVlZ5+CAOtqfbhmaUCS1ezNFVm2imDbPmPng5wmz+gwh+oHDce0eUtQ6OGDIyR0uUhUsoO3vfDmmgOezH0mZN59x7MBi++WDL1g/eEiU3avlidO671bkLfwbw5XV2P8Pzo0ydy4t2/0eu33xYSOMOD8hTf4CrBtGMSoXfPLchX+J0ruSePw3LZeK0juPJbYzrhkH0io7B3k164hiGvawhOKMLkrQLyVpZg8rHFW7E2uHOL888IBPlNZ1FPzstSJM694fWr6RwpvcJK60+0HCILTBzZLFNdtAzJaohze60T8qBzyh5ZuOg5e7uwQppofEmf2++DYvmySqGBuKaicF1blQjhuHdvCIMvp8whTTfZzI7RldpwtSzL+F1+wkdZ2TBOW2gIF88PBTzD/gpeREAMEbxnJcaJHNHrpzji0gQCS6hdkEeYt9DF/2qPcEC8RM28Hwmr3sdNyht00byAut2k3gufWNtgtOEOFGUwcXWNDbdNbpgBGxEvKkOQsxivJx33iow0Vw5S6SVTrpVq11ysA2Rp7gTfPfktc6zhtXBBC+adRLshf6sG2RfHPZ5EAc4sVZ83yCN00Fk/4kggu40ZTvIEm5g24qtU4KjBrx/BTTH8ifVASAG7gKrnWxJDcU7x8X6Ecczhm3o6YicvsLXWfh3Ch1W0k8x0nXF+0fFxgt4phz8QvypiwCCFKMqXCnqXExjq10beH+UUA7+nG6mdG/Pu0f3LgFcGrl2s0kNNjpmoJ9o4B29CMO8dMT4Q5ox8uitF6fqsrJOr8qnwNbRzv6hSnG5wP+64C7h9lp30hKNtKdWjtdkbuPA19nJ7Tz3zR/ibgARbhb4AlhavcBebmTHcFl2fvYEnW0ox9xMxKBS8btJ+KiEbq9zA4RthQXDhPa0T9TEe69gWupwc6uBUphquXgf+/FrIjweHQS4/pduMe5ERUMHUd9xv8ZR98CxkS4F2n3EUrUZ10EYNw7BWm9x1GiPssi3GgiGRDKWRYZfXlON+dfNbM+GgIwYdwAAAAASUVORK5CYII='; /** @type {?} */ const defaultMarkerShadow = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACkAAAApCAQAAAACach9AAACMUlEQVR4Ae3ShY7jQBAE0Aoz/f9/HTMzhg1zrdKUrJbdx+Kd2nD8VNudfsL/Th///dyQN2TH6f3y/BGpC379rV+S+qqetBOxImNQXL8JCAr2V4iMQXHGNJxeCfZXhSRBcQMfvkOWUdtfzlLgAENmZDcmo2TVmt8OSM2eXxBp3DjHSMFutqS7SbmemzBiR+xpKCNUIRkdkkYxhAkyGoBvyQFEJEefwSmmvBfJuJ6aKqKWnAkvGZOaZXTUgFqYULWNSHUckZuR1HIIimUExutRxwzOLROIG4vKmCKQt364mIlhSyzAf1m9lHZHJZrlAOMMztRRiKimp/rpdJDc9Awry5xTZCte7FHtuS8wJgeYGrex28xNTd086Dik7vUMscQOa8y4DoGtCCSkAKlNwpgNtphjrC6MIHUkR6YWxxs6Sc5xqn222mmCRFzIt8lEdKx+ikCtg91qS2WpwVfBelJCiQJwvzixfI9cxZQWgiSJelKnwBElKYtDOb2MFbhmUigbReQBV0Cg4+qMXSxXSyGUn4UbF8l+7qdSGnTC0XLCmahIgUHLhLOhpVCtw4CzYXvLQWQbJNmxoCsOKAxSgBJno75avolkRw8iIAFcsdc02e9iyCd8tHwmeSSoKTowIgvscSGZUOA7PuCN5b2BX9mQM7S0wYhMNU74zgsPBj3HU7wguAfnxxjFQGBE6pwN+GjME9zHY7zGp8wVxMShYX9NXvEWD3HbwJf4giO4CFIQxXScH1/TM+04kkBiAAAAAElFTkSuQmCC'; /** @type {?} */ var defaultIcon = new L.Icon({ iconUrl: defaultMarker, iconAnchor: [12, 41], shadowUrl: defaultMarkerShadow, }); this.marker = L.marker(latlng, { icon: defaultIcon }).addTo(this.map); } } /** * @return {?} */ ngOnDestroy() { this.offMapLocate(); } } LocationPickerInputComponent.decorators = [ { type: Component, args: [{ selector: 'location-picker-input', template: "\n<!-- leaflet map -->\n<div [hidden]=\"!configs.showMap\" #leafletMapDivRef [style.width]=\"mapWidth\" [style.height]=\"mapHeight\">\n <div class=\"app-close-map-button\" *ngIf=\"showCloseBtn\" (click)=\"onCloseMapBtnClick();$event.stopPropagation();\">x</div>\n</div>\n\n<!-- container for input template -->\n<ng-container *ngTemplateOutlet=\"inputFIeldTpl || defaultInputFIeldTpl; context: {\n props: {locationValue: locationValue, configs: configs}, \n onChooseLocation: onChooseLocation,\n propagateChange: propagateChange,\n onInputClick: onInputClick\n}\"></ng-container>\n\n<!-- default template -->\n<ng-template #defaultInputFIeldTpl let-onInputClick=\"onInputClick\" let-props=\"props\" let-onChooseLocation=\"onChooseLocation\">\n <div class=\"input-group\">\n <input type=\"text\" class=\"form-control\" name=\"locationValue\" (click)=\"onInputClick(props)\" [(ngModel)]=\"props.locationValue\" placeholder=\"Click on map to choose location...\" aria-label=\"Location\" readonly>\n <div class=\"input-group-append\">\n <span class=\"input-group-text\" style=\"cursor: pointer;\" (click)=\"onChooseLocation(props)\">\n <svg aria-hidden=\"true\" class=\"acdc-svg\" viewBox=\"0 0 512 512\"><path fill=\"currentColor\" d=\"M505.04 442.66l-99.71-99.69c-4.5-4.5-10.6-7-17-7h-16.3c27.6-35.3 44-79.69 44-127.99C416.03 93.09 322.92 0 208.02 0S0 93.09 0 207.98s93.11 207.98 208.02 207.98c48.3 0 92.71-16.4 128.01-44v16.3c0 6.4 2.5 12.5 7 17l99.71 99.69c9.4 9.4 24.6 9.4 33.9 0l28.3-28.3c9.4-9.4 9.4-24.59.1-33.99zm-297.02-90.7c-79.54 0-144-64.34-144-143.98 0-79.53 64.35-143.98 144-143.98 79.54 0 144 64.34 144 143.98 0 79.53-64.35 143.98-144 143.98zm.02-239.96c-40.78 0-73.84 33.05-73.84 73.83 0 32.96 48.26 93.05 66.75 114.86a9.24 9.24 0 0 0 14.18 0c18.49-21.81 66.75-81.89 66.75-114.86 0-40.78-33.06-73.83-73.84-73.83zm0 96c-13.26 0-24-10.75-24-24 0-13.26 10.75-24 24-24s24 10.74 24 24c0 13.25-10.75 24-24 24z\"></path></svg>\n </span>\n </div>\n </div>\n</ng-template>", providers: [ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => LocationPickerInputComponent), multi: true } ], styles: [":host ::ng-deep .acdc-svg{fill:#fff;width:16px;height:16px}.app-close-map-button{width:30px;height:30px;position:absolute;right:5px;top:5px;color:gray;z-index:1001;font-size:20px;background:0 0;font-weight:700;text-align:center;cursor:pointer;vertical-align:middle}"] }] } ]; /** @nocollapse */ LocationPickerInputComponent.ctorParameters = () => [ { type: AcdcGisUtilsService } ]; LocationPickerInputComponent.propDecorators = { leafletMapDivRef: [{ type: ViewChild, args: ["leafletMapDivRef", { static: true },] }], initialZoom: [{ type: Input }], initialLongitude: [{ type: Input }], initialLatitude: [{ type: Input }], closeOnChoose: [{ type: Input }], readonly: [{ type: Input }], expandOnInputClick: [{ type: Input }], showCloseBtn: [{ type: Input }], defaultShowMap: [{ type: Input }], mapHeight: [{ type: Input }], mapWidth: [{ type: Input }], _locationValue: [{ type: Input }], inputFIeldTpl: [{ type: Input }] }; if (false) { /** @type {?} */ LocationPickerInputComponent.prototype.leafletMapDivRef; /** @type {?} */ LocationPickerInputComponent.prototype.map; /** @type {?} */ LocationPickerInputComponent.prototype.marker; /** @type {?} */ LocationPickerInputComponent.prototype.initialZoom; /** @type {?} */ LocationPickerInputComponent.prototype.initialLongitude; /** @type {?} */ LocationPickerInputComponent.prototype.initialLatitude; /** @type {?} */ LocationPickerInputComponent.prototype.closeOnChoose; /** @type {?} */ LocationPickerInputComponent.prototype.readonly; /** @type {?} */ LocationPickerInputComponent.prototype.expandOnInputClick; /** @type {?} */ LocationPickerInputComponent.prototype.showCloseBtn; /** @type {?} */ LocationPickerInputComponent.prototype._defaultShowMap; /** @type {?} */ LocationPickerInputComponent.prototype.mapHeight; /** @type {?} */ LocationPickerInputComponent.prototype.mapWidth; /** @type {?} */ LocationPickerInputComponent.prototype._locationValue; /** @type {?} */ LocationPickerInputComponent.prototype.configs; /** @type {?} */ LocationPickerInputComponent.prototype.inputFIeldTpl; /** @type {?} */ LocationPickerInputComponent.prototype.propagateChange; /** @type {?} */ LocationPickerInputComponent.prototype.acdcGisUtilsService; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9jYXRpb24tcGlja2VyLWlucHV0LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2FjZGMtZ2lzLXV0aWxzLyIsInNvdXJjZXMiOlsibGliL2xvY2F0aW9uLXBpY2tlci1pbnB1dC9sb2NhdGlvbi1waWNrZXItaW5wdXQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFVLEtBQUssRUFBRSxXQUFXLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQWEsTUFBTSxlQUFlLENBQUM7QUFDcEgsT0FBTyxFQUF3QixpQkFBaUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXpFLE9BQU8sS0FBSyxDQUFDLE1BQU0sU0FBUyxDQUFDO0FBQzdCLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBY2hFLE1BQU0sT0FBTyw0QkFBNEI7Ozs7SUFzRXZDLFlBQW9CLG1CQUF3QztRQUF4Qyx3QkFBbUIsR0FBbkIsbUJBQW1CLENBQXFCO3lCQTdCeEMsT0FBTzt3QkFHUixNQUFNO1FBaUJ6QixlQUFVO1lBQ1IsT0FBTyxFQUFFLElBQUk7WUFDYixHQUFHLEVBQUUsSUFBSTtZQUNULGtCQUFrQixFQUFFLEtBQUs7U0FDMUIsQ0FBQzsrQkE2SGdCLENBQUMsQ0FBTSxFQUFFLEVBQUUsSUFBRztLQXhIaUM7Ozs7O0lBdkNqRSxJQUNJLGNBQWMsQ0FBQyxLQUFLO1FBQ3RCLElBQUksQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDO1FBQzdCLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztLQUM5Qjs7OztJQUNELElBQUksY0FBYztRQUNoQixPQUFPLElBQUksQ0FBQyxlQUFlLENBQUM7S0FDN0I7Ozs7SUFVRCxJQUFJLGFBQWE7UUFDZixPQUFRLElBQUksQ0FBQyxjQUFjLENBQUM7S0FDN0I7Ozs7O0lBQ0QsSUFBSSxhQUFhLENBQUMsS0FBSztRQUNy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Ozs7SUFHSCxXQUFXO1FBQ1QsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO0tBQ3JCOzs7WUE3UEYsU0FBUyxTQUFDO2dCQUNULFFBQVEsRUFBRSx1QkFBdUI7Z0JBQ2pDLHErREFBcUQ7Z0JBRXJELFNBQVMsRUFBRTtvQkFDVDt3QkFDRSxPQUFPLEVBQUUsaUJBQWlCO3dCQUMxQixXQUFXLEVBQUUsVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLDRCQUE0QixDQUFDO3dCQUMzRCxLQUFLLEVBQUUsSUFBSTtxQkFDWjtpQkFDRjs7YUFDRjs7OztZQWJRLG1CQUFtQjs7OytCQWdCekIsU0FBUyxTQUFDLGtCQUFrQixFQUFFLEVBQUMsTUFBTSxFQUFFLElBQUksRUFBQzswQkFPNUMsS0FBSzsrQkFHTCxLQUFLOzhCQUdMLEtBQUs7NEJBR0wsS0FBSzt1QkFHTCxLQUFLO2lDQUdMLEtBQUs7MkJBR0wsS0FBSzs2QkFJTCxLQUFLO3dCQVNMLEtBQUs7dUJBR0wsS0FBSzs2QkFHTCxLQUFLOzRCQXFCTCxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBPbkluaXQsIElucHV0LCBUZW1wbGF0ZVJlZiwgZm9yd2FyZFJlZiwgRWxlbWVudFJlZiwgVmlld0NoaWxkLCBPbkRlc3Ryb3kgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBOR19WQUxVRV9BQ0NFU1NPUiB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcblxuaW1wb3J0ICogYXMgTCBmcm9tIFwibGVhZmxldFwiO1xuaW1wb3J0IHsgQWNkY0dpc1V0aWxzU2VydmljZSB9IGZyb20gJy4uL2FjZGMtZ2lzLXV0aWxzLnNlcnZpY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdsb2NhdGlvbi1waWNrZXItaW5wdXQnLFxuICB0ZW1wbGF0ZVVybDogJy4vbG9jYXRpb24tcGlja2VyLWlucHV0LmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vbG9jYXRpb24tcGlja2VyLWlucHV0LmNvbXBvbmVudC5jc3MnXSxcbiAgcHJvdmlkZXJzOiBbXG4gICAgeyBcbiAgICAgIHByb3ZpZGU6IE5HX1ZBTFVFX0FDQ0VTU09SLFxuICAgICAgdXNlRXhpc3Rpbmc6IGZvcndhcmRSZWYoKCkgPT4gTG9jYXRpb25QaWNrZXJJbnB1dENvbXBvbmVudCksXG4gICAgICBtdWx0aTogdHJ1ZVxuICAgIH1cbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBMb2NhdGlvblBpY2tlcklucHV0Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3ksIENvbnRyb2xWYWx1ZUFjY2Vzc29yIHtcbiAgXG4gIEBWaWV3Q2hpbGQoXCJsZWFmbGV0TWFwRGl2UmVmXCIsIHtzdGF0aWM6IHRydWV9KVxuICBsZWFmbGV0TWFwRGl2UmVmOiBFbGVtZW50UmVmO1xuXG4gIHByaXZhdGUgbWFwOiBhbnk7XG5cbiAgcHJpdmF0ZSBtYXJrZXI6IGFueTtcblxuICBASW5wdXQoKVxuICBpbml0aWFsWm9vbTogbnVtYmVyO1xuXG4gIEBJbnB1dCgpXG4gIGluaXRpYWxMb25naXR1ZGU6IG51bWJlcjtcblxuICBASW5wdXQoKVxuICBpbml0aWFsTGF0aXR1ZGU6IG51bWJlcjtcblxuICBASW5wdXQoKVxuICBjbG9zZU9uQ2hvb3NlOiBib29sZWFuO1xuXG4gIEBJbnB1dCgpXG4gIHJlYWRvbmx5OiBib29sZWFuO1xuXG4gIEBJbnB1dCgpXG4gIGV4cGFuZE9uSW5wdXRDbGljazogYm9vbGVhbjtcbiAgXG4gIEBJbnB1dCgpXG4gIHNob3dDbG9zZUJ0bjogYm9vbGVhbjtcbiAgXG4gIF9kZWZhdWx0U2hvd01hcDogYm9vbGVhbjtcbiAgQElucHV0KClcbiAgc2V0IGRlZmF1bHRTaG93TWFwKHZhbHVlKXtcbiAgICB0aGlzLl9kZWZhdWx0U2hvd01hcCA9IHZhbHVlO1xuICAgIHRoaXMuY29uZmlncy5zaG93TWFwID0gdmFsdWU7XG4gIH1cbiAgZ2V0IGRlZmF1bHRTaG93TWFwKCl7XG4gICAgcmV0dXJuIHRoaXMuX2RlZmF1bHRTaG93TWFwO1xuICB9XG5cbiAgQElucHV0KClcbiAgbWFwSGVpZ2h0OiBzdHJpbmcgPSAnMjAwcHgnO1xuXG4gIEBJbnB1dCgpXG4gIG1hcFdpZHRoOiBzdHJpbmcgPSAnMTAwJSc7XG5cbiAgQElucHV0KClcbiAgX2xvY2F0aW9uVmFsdWU6IHN0cmluZztcbiAgZ2V0IGxvY2F0aW9uVmFsdWUoKSB7XG4gICAgcmV0dXJuICB0aGlzLl9sb2NhdGlvblZhbHVlO1xuICB9XG4gIHNldCBsb2NhdGlvblZhbHVlKHZhbHVlKSB7XG4gICAgdGhpcy5fbG9jYXRpb25WYWx1ZSA9IHZhbHVlO1xuICAgIHRoaXMucHJvcGFnYXRlQ2hhbmdlKHRoaXMuX2xvY2F0aW9uVmFsdWUpO1xuICAgIGlmKHZhbHVlKXtcbiAgICAgIGxldCBjZW50ZXIgPSB0aGlzLmFjZGNHaXNVdGlsc1NlcnZpY2UuZnJvbVdrdCh0aGlzLmxvY2F0aW9uVmFsdWUpO1xuICAgICAgbGV0IGxhdGxuZyA9IEwubGF0TG5nKGNlbnRlclsnY29vcmRpbmF0ZXMnXVsxXSwgY2VudGVyWydjb29yZGluYXRlcyddWzBdKTtcbiAgICAgIHRoaXMuc2V0TWFwVmlldyhsYXRsbmcpO1xuICAgIH1cbiAgfVxuXG4gIGNvbmZpZ3MgPSB7XG4gICAgc2hvd01hcDogdHJ1ZSxcbiAgICBtYXA6IG51bGwsXG4gICAgZXhwYW5kT25JbnB1dENsaWNrOiBmYWxzZVxuICB9O1xuXG4gIEBJbnB1dCgpIFxuICBpbnB1dEZJZWxkVHBsOiBUZW1wbGF0ZVJlZjxhbnk+O1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgYWNkY0dpc1V0aWxzU2VydmljZTogQWNkY0dpc1V0aWxzU2VydmljZSkgeyB9XG5cbiAgbmdPbkluaXQoKSB7XG5cbiAgICB0aGlzLmNvbmZpZ3Muc2hvd01hcCA9IHRoaXMuZGVmYXVsdFNob3dNYXA7XG4gICAgdGhpcy5jb25maWdzLmV4cGFuZE9uSW5wdXRDbGljayA9IHRoaXMuZXhwYW5kT25JbnB1dENsaWNrO1xuXG4gICAgdGhpcy5pbml0TWFwKClcblxuICAgIGlmKHRoaXMubWFwKXtcbiAgICAgIHNldFRpbWVvdXQoICgpID0+IHtcbiAgICAgICAgdGhpcy5tYXAuaW52YWxpZGF0ZVNpemUoZmFsc2UpO1xuICAgICAgfSwxMDApO1xuICAgICAgdGhpcy5jb25maWdzLm1hcCA9IHRoaXMubWFwO1xuICAgIH1cblxuICB9XG5cbiAgLyoqXG4gICAqIGluaXRpYWxpemUgbWFwLCBzZXQgaW5pdGlhbCB6b29tLCBhZGQgb3NtIGxheWVyLCBjYWxsIG1hcCBsb2NhdGVcbiAgICovXG4gIGluaXRNYXAoKXtcblxuICAgIGxldCBpbml0aWFsTGF0TG5nO1xuICAgIGlmKHRoaXMuaW5pdGlhbExvbmdpdHVkZSAmJiB0aGlzLmluaXRpYWxMYXRpdHVkZSl7XG4gICAgICBpbml0aWFsTGF0TG5nID0gTC5sYXRMbmcoIHRoaXMuaW5pdGlhbExhdGl0dWRlLCB0aGlzLmluaXRpYWxMb25naXR1ZGUgKTtcbiAgICB9ZWxzZXtcbiAgICAgIGluaXRpYWxMYXRMbmcgPSBMLmxhdExuZyggMCwgMCApO1xuICAgIH1cblxuICAgIGxldCBpbml0aWFsWm9vbUxvYztcbiAgICBpZih0aGlzLmluaXRpYWxab29tICYmIHRoaXMuaW5pdGlhbFpvb20+MCAmJiB0aGlzLmluaXRpYWxab29tPDIzKXtcbiAgICAgIGluaXRpYWxab29tTG9jID0gdGhpcy5pbml0aWFsWm9vbTtcbiAgICB9ZWxzZXtcbiAgICAgIGluaXRpYWxab29tTG9jID0gMTtcbiAgICB9XG5cbiAgICB0aGlzLm1hcCA9IEwubWFwKHRoaXMubGVhZmxldE1hcERpdlJlZi5uYXRpdmVFbGVtZW50LCB7XG4gICAgICBkcmF3Q29udHJvbDogZmFsc2VcbiAgICB9KS5zZXRWaWV3KFxuICAgICAgaW5pdGlhbExhdExuZywgXG4gICAgICBpbml0aWFsWm9vbUxvY1xuICAgICk7XG5cbiAgICBMLnRpbGVMYXllcignaHR0cHM6Ly97c30udGlsZS5vcGVuc3RyZWV0bWFwLm9yZy97en0ve3h9L3t5fS5wbmcnLCB7XG4gICAgICAgIGF0dHJpYnV0aW9uOiAnJmNvcHk7IDxhIGhyZWY9XCJodHRwczovL3d3dy5vcGVuc3RyZWV0bWFwLm9yZy9jb3B5cmlnaHRcIj5PcGVuU3RyZWV0TWFwPC9hPiBjb250cmlidXRvcnMnXG4gICAgfSkuYWRkVG8odGhpcy5tYXApO1xuXG4gICAgdGhpcy5pbml0TWFwTG9jYXRlKCk7XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBzdGFydCBsaXN0ZW5pbmcgdG8gY2xpY2sgZXZlbnRzIGZvciBjaG9vc2luZyBsb2NhdGlvblxuICAgKi9cbiAgcHJpdmF0ZSBpbml0TWFwTG9jYXRlKCl7XG4gICAgdGhpcy5tYXAub24oJ2NsaWNrJywgKGV2ZW50KSA9PiB7XG5cbiAgICAgICAgaWYoIXRoaXMucmVhZG9ubHkpe1xuXG4gICAgICAgICAgbGV0IGNlbnRlcldrdCA9IHRoaXMuYWNkY0dpc1V0aWxzU2VydmljZS50b1drdChldmVudC5sYXRsbmcpO1xuICAgICAgICAgIHRoaXMuX2xvY2F0aW9uVmFsdWUgPSBjZW50ZXJXa3Q7XG4gICAgICAgICAgdGhpcy5wcm9wYWdhdGVDaGFuZ2UodGhpcy5fbG9jYXRpb25WYWx1ZSk7XG4gICAgICAgICAgdGhpcy5zZXRNYXBWaWV3KGV2ZW50LmxhdGxuZyk7XG4gICAgICAgICAgaWYodGhpcy5jbG9zZU9uQ2hvb3NlKXtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoICgpID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5jb25maWdzLnNob3dNYXAgPSBmYWxzZTtcbiAgICAgICAgICAgIH0sIDUwMCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiB1bnJlZ2lzdGVyIGxpc3RlbmluZyBjbGljayBldmVudFxuICAgKi9cbiAgcHJpdmF0ZSBvZmZNYXBMb2NhdGUoKXtcbiAgICB0aGlzLm1hcC5vZmYoJ2NsaWNrJyk7XG4gIH1cblxuICAvKipcbiAgICogaW5wdXQgZmllbGQgdHJpZ2dlciAoc2hvdy9oaWRlIG1hcClcbiAgICovXG4gIG9uQ2hvb3NlTG9jYXRpb24ocHJvcHMpIHtcbiAgICBwcm9wc1snY29uZmlncyddLnNob3dNYXAgPSAhcHJvcHNbJ2NvbmZpZ3MnXS5zaG93TWFwO1xuICAgIHNldFRpbWVvdXQoICgpID0+IHtcbiAgICAgIHByb3BzWydjb25maWdzJ10ubWFwLmludmFsaWRhdGVTaXplKGZhbHNlKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBpbnB1dCBmaWVsZCBjbGljayBldmVudCBoYW5kbGVyXG4gICAqL1xuICBvbklucHV0Q2xpY2socHJvcHMpe1xuICAgIGlmKHByb3BzWydjb25maWdzJ10uZXhwYW5kT25JbnB1dENsaWNrKXtcbiAgICAgIHByb3BzWydjb25maWdzJ10uc2hvd01hcCA9IHRydWU7XG4gICAgICBzZXRUaW1lb3V0KCAoKSA9PiB7XG4gICAgICAgIHByb3BzWydjb25maWdzJ10ubWFwLmludmFsaWRhdGVTaXplKGZhbHNlKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBjbG9zZSBtYXAgYnV0dG9uIGNsaWNrIGhhbmRsZXJcbiAgICovXG4gIG9uQ2xvc2VNYXBCdG5DbGljaygpe1xuICAgIHRoaXMuY29uZmlncy5zaG93TWFwID0gZmFsc2U7XG4gICAgc2V0VGltZW91dCggKCkgPT4ge1xuICAgICAgdGhpcy5tYXAuaW52YWxpZGF0ZVNpemUoZmFsc2UpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIGZvcm0gZmllbGQgcmVxdWlyZWQgZnVuY3Rpb25zXG4gICAqIEBwYXJhbSBvYmogXG4gICAqL1xuICB3cml0ZVZhbHVlKG9iajogYW55KTogdm9pZCB7XG4gICAgdGhpcy5sb2NhdGlvblZhbHVlID0gb2JqO1xuICB9XG4gIHByb3BhZ2F0ZUNoYW5nZSA9IChfOiBhbnkpID0+IHt9O1xuICByZWdpc3Rlck9uQ2hhbmdlKGZuKSB7XG4gICAgdGhpcy5wcm9wYWdhdGVDaGFuZ2UgPSBmbjtcbiAgfVxuICByZWdpc3Rlck9uVG91Y2hlZChmbjogYW55KTogdm9pZCB7XG4gIH1cbiAgc2V0RGlzYWJsZWRTdGF0ZT8oaXNEaXNhYmxlZDogYm9vbGVhbik6IHZvaWQge1xuICB9XG5cbiAgLyoqXG4gICAqIHpvb20gbWFwIHRvIHBhc3NlZCBsb2NhdGlvbiBhbmQgcGluIGxvY2F0aW9uIHdpdGggbWFya2VyXG4gICAqIEBwYXJhbSBsYXRsbmcgXG4gICAqL1xuICBwcml2YXRlIHNldE1hcFZpZXcobGF0bG5nKXtcblxuICAgIHRoaXMubWFwLmZseVRvKGxhdGxuZywgdGhpcy5tYXAuZ2V0Wm9vbSgpLCB7XG4gICAgICBwYW46IHtcbiAgICAgICAgYW5pbWF0ZTogdHJ1ZSxcbiAgICAgICAgZHVyYXRpb246IDNcbiAgICAgIH0sXG4gICAgICB6b29tOiB7XG4gICAgICAgIGFuaW1hdGU6IHRydWUsXG4gICAgICAgIGR1cmF0aW9uOiAzXG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5sb2NhdGVNYXJrZXIobGF0bG5nKTtcbiAgICBcbiAgfVxuICAvKipcbiAgICogbG9jYXRlIG1hcmtlciBhdCBwYXNzZWQgbG9jYXRpb25cbiAgICogQHBhcmFtIGxhdGxuZyBcbiAgICovXG4gIHByaXZhdGUgbG9jYXRlTWFya2VyKGxhdGxuZyl7XG4gICAgaWYodGhpcy5tYXJrZXIpe1xuICAgICAgdGhpcy5tYXJrZXIuc2V0TGF0TG5nKGxhdGxuZyk7XG4gICAgfWVsc2V7XG4gICAgICBjb25zdCBkZWZhdWx0TWFya2VyID0gJ2RhdGE6aW1hZ2UvcG5nO2Jhc2U2NCxpVkJPUncwS0dnb0FBQUFOU1VoRVVnQUFBQmtBQUFBcENBWUFBQURBazRMT0FBQUZnVWxFUVZSNEFhMVhBNUJqV1JUTjJvVzE3ZDNZYVp0cjI5NjJIVXpiRE5wanN6VzI0bVJ0MjhwNDd2N3pxL2JYWnRycC9sV25YcjMzN2ozblBDZTg1TmN5cGdTRmR1Z0NwVzVZb0RBTVJhSU1xUmk2YUtxNUUzWXFEUU8zcUF3alZXckQ4TmNxL1JCcHlrZDhvWlViL2thSnV0b3c4cjFhUDlJSTBXbUxLTElzSnl2MXcva3F3OUNoMk1ZZEIrKzEyT254ZWUvUU13dmY0L0RrL0xmcC9pNG54VFh0T29RNHBXNUFqN3dwaWNpMUE5ZXJkQU4yT0g2NHg4T1NQOWozRnQzYjdhV2tUZy9GbTkxc2lUcmEwZjlvbjVzUXI5SU5lakg2Q1VVVXBhdmpGTnExQitPYWRoeG1uZmE4UmZFbU44Vk5Bc1FoUHFGNTV4SGtNenozalNtQ2hXVTZmNy9YWktOSCs5K2hCTE9IWW96dUtRUHh5TVBVS2tyWC9LMHVXbmZGYUpHUzFRUFJ0WnNPUHRyM05zVzB1eWg2Tk5DT2tVM1l6K2JYYlQzSThHM3hFNUVYTFh0Q1hiYnF3Q085elBRWVBSVFo1dklEWEQ3VSt3N3JGREVvVVVmN2liSElSNHk2YkxWUFhyejhKVlpFcWwxM3RyeHd1ZS91RGl2ZDNma1dSYlM2L0lBMmJJRDR1azBVcEYxTjhxTGxiQmxYczRFZTdITFRmVjFqNTRBUHZPRG5TZk9XQnF0S1Z2amdMS3pGNVlkRWs1ZXdSa0dsSzBpMzNFb2ZmZmM3SFQ1NmpENy82VStxSDNDeDdTQkxObnRINVlJUHZPRG55ZklYWllSVkRQcWdIdExzNUFCSEQzWXpMdWVzcGI3dDc5RlkzNERqTXdyVnJjVHV3bFQ1NVlNUHZPQm5Scko0VlhUZE5uWXVnNXVjSExCakVwdDMwNzAxQTNUcytIRWE3M3U2ZFQzRk5Xd2ZsWTg2ZU1IUGsrWXUraTZwelVwUnJXN1NORGc1SkhSNEthcG1NNVd2MkU4VGZjYjFIb3FxSE1IVSt1V0REN3pnNTRtejUvMkJTbml6aTlUMURnNFFRWExUb0dOQ2tiNnRiMU5VK1FBbEdyMSsrZUFEcnpobi91OFEyWVpoUVZsWjUrQ0FPdHFmYmhtYVVDUzFlek5GVm0yaW1EYlBtUG5nNXdteitnd2grb0hEY2UwZVV0UTZPR0RJeVIwdVVoVXNvTzN2ZkRtbWdPZXpIMG1aTjU5eDdNQmkrK1dETDFnL2VFaVUzYXZsaWRPNjcxYmtMZndidzVYVjJQOFB6bzB5ZHk0dDIvMGV1MzN4WVNPTU9EOGhUZjRDckJ0R01Tb1hmUExjaFgrSjBydVNlUHczTFplSzBqdVBKYll6cmhrSDBpbzdCM2sxNjRoaUd2YXdoT0tNTGtyUUx5VnBaZzhySEZXN0UydUhPTDg4OElCUGxOWjFGUHpzdFNKTTY5NGZXcjZSd3B2Y0pLNjArMEhDSUxUQnpaTEZOZHRBekphb2h6ZTYwVDhxQnp5aDVadU9nNWU3dXdRcHBvZkVtZjIrK0RZdm15U3FHQnVLYWljRjFibFFqaHVIZHZDSU12cDh3aFRUZlp6STdSbGRwd3RTekwrRjErd2tkWjJUQk9XMmdJRjg4UEJUekQvZ3BlUkVBTUVieG5KY2FKSE5IcnB6amkwZ1FDUzZoZGtFZVl0OURGLzJxUGNFQzhSTTI4SHdtcjNzZE55aHQwMGJ5QXV0MmszZ3VmV050Z3RPRU9GR1V3Y1hXTkRiZE5icGdCR3hFdktrT1FzeGl2SngzM2lvdzBWdzVTNlNWVHJwVnExMXlzQTJScDdnVGZQZmt0YzZ6aHRYQkJDK2FkUkxzaGY2c0cyUmZIUFo1RUFjNHNWWjgzeUNOMDBGay80a2dndTQwWlR2SUVtNWcyNHF0VTRLakJyeC9CVFRIOGlmVkFTQUc3Z0tybld4SkRjVTd4OFg2RWNjemhtM282WWljdnNMWFdmaDNDaDFXMGs4eDBuWEYrMGZGeGd0NHBoejhRdnlwaXdDQ0ZLTXFYQ25xWEV4anExMGJlSCtVVUE3K25HNm1kRy9QdTBmM0xnRmNHcmwyczBrTk5qcG1vSjlvNEIyOUNNTzhkTVQ0UTVveDh1aXRGNmZxc3JKT3I4cW53TmJSenY2aFNuRzV3UCs2NEM3aDlscDMwaEtOdEtkV2p0ZGtidVBBMTluSjdUejN6Ui9pYmdBUmJoYjRBbGhhdmNCZWJtVEhjRmwyZnZZRW5XMG94OXhNeEtCUzhidEorS2lFYnE5ekE0UnRoUVhEaFBhMFQ5VEVlNjlnV3Vwd2M2dUJVcGhxdVhnZisvRnJJandlSFFTNC9wZHVNZTVFUlVNSFVkOXh2OFpSOThDeGtTNEYybjNFVXJVWjEwRVlOdzdCV205eDFHaVBzc2kzR2dpR1JES1dSWVpmWGxPTitkZk5iTStHZ0l3WWR3QUFBQUFTVVZPUks1Q1lJST0nO1xuICAgICAgY29uc3QgZGVmYXVsdE1hcmtlclNoYWRvdyA9ICdkYXRhOmltYWdlL3BuZztiYXNlNjQsaVZCT1J3MEtHZ29BQUFBTlNVaEVVZ0FBQUNrQUFBQXBDQVFBQUFBQ2FjaDlBQUFDTVVsRVFWUjRBZTNTaFk3alFCQUUwQW96L2Y5L0hUTXpoZzF6cmRLVXJKYmR4K0tkMm5EOFZOdWRmc0wvVGgvLy9keVFOMlRINmYzeS9CR3BDMzc5clYrUytxcWV0Qk94SW1OUVhMOEpDQXIyVjRpTVFYSEdOSnhlQ2ZaWGhTUkJjUU1mdmtPV1VkdGZ6bExnQUVObVpEY21vMlRWbXQ4T1NNMmVYeEJwM0RqSFNNRnV0cVM3U2JtZW16QmlSK3hwS0NOVUlSa2Rra1l4aEFreUdvQnZ5UUZFSkVlZndTbW12QmZKdUo2YUtxS1duQWt2R1pPYVpYVFVnRnFZVUxXTlNIVWNrWnVSMUhJSWltVUV4dXRSeHd6T0xST0lHNHZLbUNLUXQzNjRtSWxoU3l6QWYxbTlsSFpISlpybEFPTU16dFJSaUtpbXAvcnBkSkRjOUF3cnk1eFRaQ3RlN0ZIdHVTOHdKZ2VZR3JleDI4eE5UZDA4NkRpazd2VU1zY1FPYTh5NERvR3RDQ1NrQUtsTndwZ050cGhqckM2TUlIVWtSNllXeHhzNlNjNXhxbjIyMm1tQ1JGekl0OGxFZEt4K2lrQ3RnOTFxUzJXcHdWZkJlbEpDaVFKd3Z6aXhmSTljeFpRV2dpU0plbEtud0JFbEtZdERPYjJNRmJobVVpZ2JSZVFCVjBDZzQrcU1YU3hYU3lHVW40VWJGOGwrN3FkU0duVEMwWExDbWFoSWdVSExoTE9ocFZDdHc0Q3pZWHZMUVdRYkpObXhvQ3NPS0F4U2dCSm5vNzVhdm9sa1J3OGlJQUZjc2RjMDJlOWl5Q2Q4dEh3bWVTU29LVG93SWd2c2NTR1pVT0E3UHVDTjViMkJYOW1RTTdTMHdZaE1OVTc0emdzUEJqM0hVN3dndUFmbnh4akZRR0JFNnB3TitHak1FOXpIWTd6R3A4d1Z4TVNoWVg5Tlh2RVdEM0hid0pmNGdpTzRDRklReFhTY0gxL1RNKzA0a2tCaUFBQUFBRWxGVGtTdVFtQ0MnO1xuXG4gICAgICB2YXIgZGVmYXVsdEljb24gPSBuZXcgTC5JY29uKHtcbiAgICAgICAgICBpY29uVXJsOiBkZWZhdWx0TWFya2VyLFxuICAgICAgICAgIGljb25BbmNob3I6IFsxMiwgNDFdLFxuICAgICAgICAgIHNoYWRvd1VybDogZGVmYXVsdE1hcmtlclNoYWRvdyxcbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLm1hcmtlciA9IEwubWFya2VyKGxhdGxuZywgeyBpY29uOiBkZWZhdWx0SWNvbiB9KS5hZGRUbyh0aGlzLm1hcCk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5vZmZNYXBMb2NhdGUoKTtcbiAgfVxuXG59XG4iXX0=