@c8y/ngx-components
Version:
Angular modules for Cumulocity IoT applications
445 lines • 63.5 kB
JavaScript
import { Component, ContentChild, ElementRef, EventEmitter, Inject, Input, Output, ViewChild } from '@angular/core';
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
import { DatePipe, GeoService, gettext, ManagedObjectRealtimeService, sortByPriority, WidgetGlobalAutoRefreshService } from '@c8y/ngx-components';
import { TranslateService } from '@ngx-translate/core';
import { every, flatten, isEmpty, isNull, isUndefined, remove } from 'lodash-es';
import { BehaviorSubject, combineLatest, fromEvent, NEVER, Observable, Subject } from 'rxjs';
import { filter, first, map, scan, switchMap, takeUntil } from 'rxjs/operators';
import { MapPopupDirective } from './map-popup.directive';
import { getC8yMarker, MAP_DEFAULT_CONFIG, MAP_TILE_LAYER } from './map.model';
import { MapService } from './map.service';
import * as i0 from "@angular/core";
import * as i1 from "@c8y/ngx-components";
import * as i2 from "./map.service";
import * as i3 from "@ngx-translate/core";
import * as i4 from "rxjs";
export class MapComponent {
constructor(moRealtimeService, mapService, layers$, defaultConfig$, translateService, geo, datePipe, widgetGlobalAutoRefreshService) {
this.moRealtimeService = moRealtimeService;
this.mapService = mapService;
this.layers$ = layers$;
this.defaultConfig$ = defaultConfig$;
this.translateService = translateService;
this.geo = geo;
this.datePipe = datePipe;
this.widgetGlobalAutoRefreshService = widgetGlobalAutoRefreshService;
/**
* The markers placed on the map.
*/
this.markers = [];
/**
* Tells if the map was already initialized.
*/
this.isInit = false;
this.config = {};
this.polyline$ = NEVER;
this.onRealtimeUpdate = new EventEmitter();
this.onMap = new BehaviorSubject(null);
this.onInit = new EventEmitter();
this.unsubscribeTrigger$ = new Subject();
this.destroy$ = new Subject();
this.markerTitle = gettext('Marker at position {{lat}}, {{lng}}');
this.initOutputs();
}
startRealtime() {
if (!this.assets || (Array.isArray(this.assets) && this.assets.length > 1)) {
this.config.realtime = false;
this.stopRealtime();
return;
}
const asset = Array.isArray(this.assets) ? this.assets[0] : this.assets;
this.realtimeSubscription = this.moRealtimeService
.onUpdate$(asset)
.subscribe((asset) => {
const marker = this.findMarker(asset.id);
const icon = this.getAssetIcon(asset);
marker.setIcon(icon);
marker.setLatLng(this.geo.getLatLong(asset));
if (Array.isArray(this.assets)) {
this.assets[0] = asset;
}
else {
this.assets = asset;
}
this.moveToPositionOfMo(asset);
this.onRealtimeUpdate.emit(asset);
});
}
moveToPositionOfMo(positions) {
const position = Array.isArray(positions) ? positions[0] : positions;
if (this.config.follow) {
this.map.setView([position.c8y_Position.lat, position.c8y_Position.lng]);
}
}
stopRealtime() {
if (this.realtimeSubscription) {
this.realtimeSubscription.unsubscribe();
}
}
findMarker(moOrId) {
const getId = moOrId => (typeof moOrId === 'string' ? moOrId : moOrId?.id);
return this.markers.find((marker) => marker.asset?.id === getId(moOrId) || marker.event?.id === getId(moOrId));
}
addMarkerToMap(marker) {
this.markers.push(marker);
marker.addTo(this.map);
}
getAssetMarker(asset) {
if (!asset) {
return;
}
const icon = this.getAssetIcon(asset);
const { lat, lng } = asset.c8y_Position;
const leafletMarker = this.leaflet.marker(this.geo.getLatLong(asset), {
icon,
title: this.translateService.instant(this.markerTitle, { lat, lng })
});
const marker = getC8yMarker(leafletMarker, asset);
this.bindPopup(marker, asset);
return marker;
}
getTrackingMarker(event) {
if (!event) {
return;
}
const icon = this.getTrackingIcon();
const { lat, lng } = event.c8y_Position;
const leafletMarker = this.leaflet.marker(this.geo.getLatLong(event), {
icon,
title: this.translateService.instant(this.markerTitle, { lat, lng })
});
const marker = getC8yMarker(leafletMarker, null, event);
this.bindPopup(marker, event);
return marker;
}
getAssetIcon(asset) {
const assetTypeIcon = this.config.icon || asset.icon?.name;
const status = MapService.getStatus(asset);
const color = this.config.color ? `style='color: ${this.config.color};'` : '';
const icon = this.leaflet.divIcon({
html: `<div class="dlt-c8y-icon-marker icon-3x ${status}" ${color}><i class="dlt-c8y-icon-${assetTypeIcon || 'data-transfer'}" /></div>`,
className: 'c8y-map-marker-icon',
// iconAnchor is used to set the marker accurately on click
iconAnchor: [8, 8]
});
return icon;
}
getTrackingIcon() {
const icon = this.leaflet.divIcon({
html: `<div class="dlt-c8y-icon-marker icon-3x text-muted"></div>`,
className: 'c8y-map-marker-icon',
// iconAnchor is used to set the marker accurately on click
iconAnchor: [8, 8]
});
return icon;
}
removeMarker(marker) {
if (marker) {
marker.remove();
remove(this.markers, m => m === marker);
}
}
clearMarkers(fragment) {
const matchingMarkers = marker => !fragment || !!marker[fragment];
this.markers.filter(matchingMarkers).forEach(marker => marker.remove());
this.markers = this.markers.filter(marker => !matchingMarkers(marker));
}
refreshMarkers() {
this.clearMarkers();
let assets = [];
if (!isUndefined(this.assets)) {
assets = Array.isArray(this.assets) ? this.assets : [this.assets];
}
assets.forEach(asset => {
const marker = this.getAssetMarker(asset);
this.addMarkerToMap(marker);
});
if (!this.config.center) {
this.zoomToBound(assets);
}
this.toggleControls();
}
center() {
this.map?.setView(this.config.center);
}
refresh() {
if (this.isInit) {
this.refreshMarkers();
}
}
async ngAfterViewInit() {
this.leaflet = await this.mapService.getLeaflet();
const initialized$ = combineLatest([this.layers$, this.defaultConfig$]).pipe(first(), takeUntil(this.unsubscribeTrigger$));
initialized$.subscribe(([layers, defaultConfig]) => {
this.initMap(layers, defaultConfig);
this.refreshMarkers();
});
combineLatest([this.polyline$, initialized$])
.pipe(map(([expressions]) => this.leaflet.polyline(expressions, this.polylineOptions)), scan((oldPolyline, newPolyline) => {
if (!!oldPolyline) {
this.map.removeLayer(oldPolyline);
}
if (!!newPolyline) {
newPolyline.addTo(this.map);
this.fitBounds(newPolyline.getBounds());
}
return newPolyline;
}, null), takeUntil(this.unsubscribeTrigger$))
.subscribe();
}
ngOnChanges(changes) {
if (!this.map) {
return;
}
if (changes.assets?.currentValue && !changes.assets?.firstChange) {
this.refreshMarkers();
}
if (changes.config?.currentValue && !changes.config?.firstChange) {
this.changeConfig(changes.config);
}
}
ngOnDestroy() {
this.unsubscribeAllListeners();
this.destroy$.next();
this.destroy$.complete();
}
unsubscribeAllListeners() {
this.unsubscribeTrigger$.next();
this.stopRealtime();
}
initOutputs() {
const getMapEventObservable = eventName => {
return this.onMap.pipe(filter(map => !!map), switchMap(map => fromEvent(map, eventName)), takeUntilDestroyed());
};
const dragStart$ = getMapEventObservable('dragstart');
const move$ = getMapEventObservable('move');
const dragEnd$ = getMapEventObservable('dragend');
this.onMove = dragStart$.pipe(switchMap(() => move$.pipe(takeUntil(dragEnd$))), takeUntil(this.unsubscribeTrigger$));
this.onMoveEnd = getMapEventObservable('moveend');
this.onZoomEnd = getMapEventObservable('zoomend');
this.onZoomStart = getMapEventObservable('zoomstart');
}
initMap(layers, defaultConfig) {
const defaultOptions = {
center: this.config.center || defaultConfig.center,
zoomSnap: 0,
zoom: this.config.zoomLevel || defaultConfig.zoomLevel,
worldCopyJump: true
};
if (this.map) {
this.map.remove();
}
this.map = this.leaflet.map(this.mapElement.nativeElement, defaultOptions);
this.map.attributionControl.setPrefix('');
this.fitBounds(this.config.bounds);
this.addLayers(layers);
this.handleMobile();
this.onMap.next(this.map);
if (this.config.realtime) {
this.startRealtime();
}
this.isInit = true;
this.onInit.emit(this.leaflet);
}
handleMobile() {
// adding event listener to do mobile 2 finger scrolling
if (this.leaflet.Browser.mobile) {
const touchMsg = this.translateService.instant(gettext('Use two fingers to move the map.'));
this.map.dragging.disable();
const container = this.map.getContainer();
container.setAttribute('data-touch-warning-content', touchMsg);
container.addEventListener('touchstart', event => this.handleTouch(event));
container.addEventListener('touchmove', event => this.handleTouch(event));
container.addEventListener('touchend', event => this.handleTouch(event));
container.addEventListener('touchcancel', event => this.handleTouch(event));
container.addEventListener('click', event => this.handleTouch(event));
}
}
addLayers(layers) {
const flattenLayers = flatten(layers);
const baseLayers = {};
const overlays = {};
let firstLayer = true;
for (const layer of sortByPriority(flattenLayers)) {
const objectToAddTo = layer.isOverlay ? overlays : baseLayers;
if (objectToAddTo[layer.label]) {
continue;
}
const tiles = this.leaflet.tileLayer(layer.layerUrl, layer.options);
if (!layer.isOverlay && firstLayer) {
firstLayer = false;
tiles.addTo(this.map);
}
objectToAddTo[layer.label] = tiles;
}
if (flattenLayers.length > 1) {
this.leaflet.control.layers(baseLayers, overlays, { position: 'bottomleft' }).addTo(this.map);
}
}
changeConfig(change) {
if (this.hasChanged(change, 'zoomLevel')) {
this.map.setZoom(this.config.zoomLevel);
}
if (this.hasChanged(change, 'center') && every(change.currentValue.center, p => !isNull(p))) {
this.map.setView(change.currentValue.center);
}
if (this.hasChanged(change, 'icon') || this.hasChanged(change, 'color')) {
this.refreshMarkers();
}
if (this.hasChanged(change, 'realtime') && change.currentValue.realtime) {
this.startRealtime();
}
if (change.currentValue.realtime === false) {
this.stopRealtime();
}
if (this.hasChanged(change, 'follow')) {
this.moveToPositionOfMo(this.assets);
}
if (this.hasChanged(change, 'disablePan') || this.hasChanged(change, 'disableZoom')) {
this.toggleControls();
}
}
hasChanged(change, prop) {
return change.currentValue[prop] !== change.previousValue[prop];
}
toggleControls() {
if (this.config.disableZoom) {
this.map.removeControl(this.map.zoomControl);
this.map.scrollWheelZoom.disable();
}
else {
this.map.addControl(this.map.zoomControl);
this.map.scrollWheelZoom.enable();
}
if (this.config.disablePan) {
this.map.dragging.disable();
}
else {
this.map.dragging.enable();
}
}
handleTouch(e) {
// Disregard touch events on the minimap if present
const ignoreList = [
'leaflet-control-minimap',
'leaflet-interactive',
'leaflet-popup-content',
'leaflet-popup-content-wrapper',
'leaflet-popup-close-button',
'leaflet-control-zoom-in',
'leaflet-control-zoom-out'
];
let ignoreElement = false;
for (let i = 0; i < ignoreList.length; i++) {
if (this.leaflet.DomUtil.hasClass(e.target, ignoreList[i])) {
ignoreElement = true;
}
}
const container = this.map.getContainer();
if (ignoreElement) {
if (this.leaflet.DomUtil.hasClass(e.target, 'leaflet-interactive') &&
e.type === 'touchmove' &&
e.touches.length === 1) {
this.leaflet.DomUtil.addClass(container, 'touch-warning');
this.map.dragging.disable();
}
else {
this.leaflet.DomUtil.removeClass(container, 'touch-warning');
}
return;
}
if (e.type !== 'touchmove' && e.type !== 'touchstart') {
this.leaflet.DomUtil.removeClass(container, 'touch-warning');
return;
}
if (e.touches.length === 1) {
this.leaflet.DomUtil.addClass(container, 'touch-warning');
this.map.dragging.disable();
}
else {
this.map.dragging.enable();
this.leaflet.DomUtil.removeClass(container, 'touch-warning');
}
}
zoomToBound(assets) {
if (isEmpty(assets))
return;
const bounds = assets.map(asset => [
asset.c8y_Position.lat,
asset.c8y_Position.lng
]);
if (assets.length > 1) {
this.map.flyToBounds(bounds, { animate: false });
return;
}
this.map.flyTo([assets[0].c8y_Position.lat, assets[0].c8y_Position.lng], this.map.options.zoom, {
animate: false
});
}
fitBounds(bounds) {
if (bounds?.isValid()) {
this.map.fitBounds(bounds, this.config.fitBoundsOptions);
}
}
bindPopup(marker, context) {
if (this.popup) {
marker.on('click', () => {
this.popup.viewContainer.clear();
const view = this.popup.viewContainer.createEmbeddedView(this.popup.template, {
$implicit: context
});
view.detectChanges();
marker
.unbindPopup()
.bindPopup(this.popup.elementRef.nativeElement.previousSibling, {
offset: [-3, -40],
maxWidth: 140,
autoPan: true,
closeButton: false
})
.openPopup();
});
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MapComponent, deps: [{ token: i1.ManagedObjectRealtimeService }, { token: i2.MapService }, { token: MAP_TILE_LAYER }, { token: MAP_DEFAULT_CONFIG }, { token: i3.TranslateService }, { token: i1.GeoService }, { token: i1.DatePipe }, { token: i1.WidgetGlobalAutoRefreshService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: MapComponent, selector: "c8y-map", inputs: { config: "config", assets: "assets", polyline$: "polyline$", polylineOptions: "polylineOptions" }, outputs: { onRealtimeUpdate: "onRealtimeUpdate", onMove: "onMove", onMoveEnd: "onMoveEnd", onZoomStart: "onZoomStart", onZoomEnd: "onZoomEnd", onMap: "onMap", onInit: "onInit" }, providers: [ManagedObjectRealtimeService], queries: [{ propertyName: "popup", first: true, predicate: MapPopupDirective, descendants: true }], viewQueries: [{ propertyName: "mapElement", first: true, predicate: ["map"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"c8y-map\">\n <div #map></div>\n</div>\n<ng-content></ng-content>\n" }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MapComponent, decorators: [{
type: Component,
args: [{ selector: 'c8y-map', providers: [ManagedObjectRealtimeService], template: "<div class=\"c8y-map\">\n <div #map></div>\n</div>\n<ng-content></ng-content>\n" }]
}], ctorParameters: () => [{ type: i1.ManagedObjectRealtimeService }, { type: i2.MapService }, { type: i4.Observable, decorators: [{
type: Inject,
args: [MAP_TILE_LAYER]
}] }, { type: i4.Observable, decorators: [{
type: Inject,
args: [MAP_DEFAULT_CONFIG]
}] }, { type: i3.TranslateService }, { type: i1.GeoService }, { type: i1.DatePipe }, { type: i1.WidgetGlobalAutoRefreshService }], propDecorators: { mapElement: [{
type: ViewChild,
args: ['map']
}], popup: [{
type: ContentChild,
args: [MapPopupDirective]
}], config: [{
type: Input
}], assets: [{
type: Input
}], polyline$: [{
type: Input
}], polylineOptions: [{
type: Input
}], onRealtimeUpdate: [{
type: Output
}], onMove: [{
type: Output
}], onMoveEnd: [{
type: Output
}], onZoomStart: [{
type: Output
}], onZoomEnd: [{
type: Output
}], onMap: [{
type: Output
}], onInit: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFwLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL21hcC9tYXAuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vbWFwL21hcC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULFlBQVksRUFDWixVQUFVLEVBQ1YsWUFBWSxFQUNaLE1BQU0sRUFDTixLQUFLLEVBQ0wsTUFBTSxFQUdOLFNBQVMsRUFDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUVoRSxPQUFPLEVBQ0wsUUFBUSxFQUNSLFVBQVUsRUFDVixPQUFPLEVBQ1AsNEJBQTRCLEVBQzVCLGNBQWMsRUFDZCw4QkFBOEIsRUFDL0IsTUFBTSxxQkFBcUIsQ0FBQztBQUU3QixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUV2RCxPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxNQUFNLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDakYsT0FBTyxFQUNMLGVBQWUsRUFDZixhQUFhLEVBQ2IsU0FBUyxFQUNULEtBQUssRUFDTCxVQUFVLEVBQ1YsT0FBTyxFQUVSLE1BQU0sTUFBTSxDQUFDO0FBQ2QsT0FBTyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDaEYsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDMUQsT0FBTyxFQUdMLFlBQVksRUFDWixrQkFBa0IsRUFDbEIsY0FBYyxFQUdmLE1BQU0sYUFBYSxDQUFDO0FBQ3JCLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7Ozs7OztBQU8zQyxNQUFNLE9BQU8s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QVM7K0JBQ0UsU0FBUyxhQUVSLENBQUMsNEJBQTRCLENBQUM7OzBCQW9FdEMsTUFBTTsyQkFBQyxjQUFjOzswQkFDckIsTUFBTTsyQkFBQyxrQkFBa0I7cUtBaEQ1QixVQUFVO3NCQURULFNBQVM7dUJBQUMsS0FBSztnQkFJaEIsS0FBSztzQkFESixZQUFZO3VCQUFDLGlCQUFpQjtnQkFJL0IsTUFBTTtzQkFETCxLQUFLO2dCQUlOLE1BQU07c0JBREwsS0FBSztnQkFJTixTQUFTO3NCQURSLEtBQUs7Z0JBSU4sZUFBZTtzQkFEZCxLQUFLO2dCQUlOLGdCQUFnQjtzQkFEZixNQUFNO2dCQUlQLE1BQU07c0JBREwsTUFBTTtnQkFJUCxTQUFTO3NCQURSLE1BQU07Z0JBSVAsV0FBVztzQkFEVixNQUFNO2dCQUlQLFNBQVM7c0JBRFIsTUFBTTtnQkFJUCxLQUFLO3NCQURKLE1BQU07Z0JBSVAsTUFBTTtzQkFETCxNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBDb250ZW50Q2hpbGQsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5qZWN0LFxuICBJbnB1dCxcbiAgT3V0cHV0LFxuICBTaW1wbGVDaGFuZ2UsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFZpZXdDaGlsZFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHRha2VVbnRpbERlc3Ryb3llZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7IElFdmVudCB9IGZyb20gJ0BjOHkvY2xpZW50JztcbmltcG9ydCB7XG4gIERhdGVQaXBlLFxuICBHZW9TZXJ2aWNlLFxuICBnZXR0ZXh0LFxuICBNYW5hZ2VkT2JqZWN0UmVhbHRpbWVTZXJ2aWNlLFxuICBzb3J0QnlQcmlvcml0eSxcbiAgV2lkZ2V0R2xvYmFsQXV0b1JlZnJlc2hTZXJ2aWNlXG59IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMnO1xuaW1wb3J0IHR5cGUgeyBNYXBEZWZhdWx0Q29uZmlnLCBNYXBUaWxlTGF5ZXIgfSBmcm9tICdAYzh5L29wdGlvbnMnO1xuaW1wb3J0IHsgVHJhbnNsYXRlU2VydmljZSB9IGZyb20gJ0BuZ3gtdHJhbnNsYXRlL2NvcmUnO1xuaW1wb3J0IHR5cGUgKiBhcyBMIGZyb20gJ2xlYWZsZXQnO1xuaW1wb3J0IHsgZXZlcnksIGZsYXR0ZW4sIGlzRW1wdHksIGlzTnVsbCwgaXNVbmRlZmluZWQsIHJlbW92ZSB9IGZyb20gJ2xvZGFzaC1lcyc7XG5pbXBvcnQge1xuICBCZWhhdmlvclN1YmplY3QsXG4gIGNvbWJpbmVMYXRlc3QsXG4gIGZyb21FdmVudCxcbiAgTkVWRVIsXG4gIE9ic2VydmFibGUsXG4gIFN1YmplY3QsXG4gIFN1YnNjcmlwdGlvblxufSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGZpbHRlciwgZmlyc3QsIG1hcCwgc2Nhbiwgc3dpdGNoTWFwLCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBNYXBQb3B1cERpcmVjdGl2ZSB9IGZyb20gJy4vbWFwLXBvcHVwLmRpcmVjdGl2ZSc7XG5pbXBvcnQge1xuICBDOHlNYXJrZXIsXG4gIEM4eU1hcmtlckF0dHJpYnV0ZXMsXG4gIGdldEM4eU1hcmtlcixcbiAgTUFQX0RFRkFVTFRfQ09ORklHLFxuICBNQVBfVElMRV9MQVlFUixcbiAgTWFwQ29uZmlnLFxuICBQb3NpdGlvbk1hbmFnZWRPYmplY3Rcbn0gZnJvbSAnLi9tYXAubW9kZWwnO1xuaW1wb3J0IHsgTWFwU2VydmljZSB9IGZyb20gJy4vbWFwLnNlcnZpY2UnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdjOHktbWFwJyxcbiAgdGVtcGxhdGVVcmw6ICcuL21hcC5jb21wb25lbnQuaHRtbCcsXG4gIHByb3ZpZGVyczogW01hbmFnZWRPYmplY3RSZWFsdGltZVNlcnZpY2VdXG59KVxuZXhwb3J0IGNsYXNzIE1hcENvbXBvbmVudCB7XG4gIC8qKlxuICAgKiBUaGUgbGVhZmxldCBtYXAgb2JqZWN0LlxuICAgKi9cbiAgbWFwOiBMLk1hcDtcbiAgLyoqXG4gICAqIFRoZSBtYXJrZXJzIHBsYWNlZCBvbiB0aGUgbWFwLlxuICAgKi9cbiAgbWFya2VyczogQXJyYXk8Qzh5TWFya2VyIHwgTC5NYXJrZXI+ID0gW107XG4gIC8qKlxuICAgKiBUaGUgbGVhZmxldCByZXByZXNlbnRhdGlvbiB1c2VkLlxuICAgKi9cbiAgbGVhZmxldDogdHlwZW9mIEw7XG4gIC8qKlxuICAgKiBUZWxscyBpZiB0aGUgbWFwIHdhcyBhbHJlYWR5IGluaXRpYWxpemVkLlxuICAgKi9cbiAgaXNJbml0ID0gZmFsc2U7XG5cbiAgQFZpZXdDaGlsZCgnbWFwJylcbiAgbWFwRWxlbWVudDogRWxlbWVudFJlZjtcblxuICBAQ29udGVudENoaWxkKE1hcFBvcHVwRGlyZWN0aXZlKVxuICBwb3B1cDogTWFwUG9wdXBEaXJlY3RpdmU7XG5cbiAgQElucHV0KClcbiAgY29uZmlnOiBNYXBDb25maWcgPSB7fTtcblxuICBASW5wdXQoKVxuICBhc3NldHM6IFBvc2l0aW9uTWFuYWdlZE9iamVjdCB8IFBvc2l0aW9uTWFuYWdlZE9iamVjdFtdO1xuXG4gIEBJbnB1dCgpXG4gIHBvbHlsaW5lJDogT2JzZXJ2YWJsZTxMLkxhdExuZ0V4cHJlc3Npb25bXSB8IEwuTGF0TG5nRXhwcmVzc2lvbltdW10+ID0gTkVWRVI7XG5cbiAgQElucHV0KClcbiAgcG9seWxpbmVPcHRpb25zOiBMLlBvbHlsaW5lT3B0aW9ucztcblxuICBAT3V0cHV0KClcbiAgb25SZWFsdGltZVVwZGF0ZSA9IG5ldyBFdmVudEVtaXR0ZXI8UG9zaXRpb25NYW5hZ2VkT2JqZWN0PigpO1xuXG4gIEBPdXRwdXQoKVxuICBvbk1vdmU6IE9ic2VydmFibGU8TC5MZWFmbGV0RXZlbnQ+O1xuXG4gIEBPdXRwdXQoKVxuICBvbk1vdmVFbmQ6IE9ic2VydmFibGU8TC5MZWFmbGV0RXZlbnQ+O1xuXG4gIEBPdXRwdXQoKVxuICBvblpvb21TdGFydDogT2JzZXJ2YWJsZTxMLkxlYWZsZXRFdmVudD47XG5cbiAgQE91dHB1dCgpXG4gIG9uWm9vbUVuZDogT2JzZXJ2YWJsZTxMLkxlYWZsZXRFdmVudD47XG5cbiAgQE91dHB1dCgpXG4gIG9uTWFwID0gbmV3IEJlaGF2aW9yU3ViamVjdDxMLk1hcCB8IG51bGw+KG51bGwpO1xuXG4gIEBPdXRwdXQoKVxuICBvbkluaXQgPSBuZXcgRXZlbnRFbWl0dGVyPHR5cGVvZiBMPigpO1xuXG4gIHByb3RlY3RlZCByZWFsdGltZVN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuICBwcm90ZWN0ZWQgdW5zdWJzY3JpYmVUcmlnZ2VyJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIHByb3RlY3RlZCBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgcHJpdmF0ZSBtYXJrZXJUaXRsZSA9IGdldHRleHQoJ01hcmtlciBhdCBwb3NpdGlvbiB7e2xhdH19LCB7e2xuZ319Jyk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIG1vUmVhbHRpbWVTZXJ2aWNlOiBNYW5hZ2VkT2JqZWN0UmVhbHRpbWVTZXJ2aWNlLFxuICAgIHByb3RlY3RlZCBtYXBTZXJ2aWNlOiBNYXBTZXJ2aWNlLFxuICAgIEBJbmplY3QoTUFQX1RJTEVfTEFZRVIpIHByb3RlY3RlZCBsYXllcnMkOiBPYnNlcnZhYmxlPE1hcFRpbGVMYXllcltdPixcbiAgICBASW5qZWN0KE1BUF9ERUZBVUxUX0NPTkZJRylcbiAgICBwcm90ZWN0ZWQgZGVmYXVsdENvbmZpZyQ6IE9ic2VydmFibGU8TWFwRGVmYXVsdENvbmZpZz4sXG4gICAgcHJvdGVjdGVkIHRyYW5zbGF0ZVNlcnZpY2U6IFRyYW5zbGF0ZVNlcnZpY2UsXG4gICAgcHJvdGVjdGVkIGdlbzogR2VvU2VydmljZSxcbiAgICBwcm90ZWN0ZWQgZGF0ZVBpcGU6IERhdGVQaXBlLFxuICAgIHByb3RlY3RlZCB3aWRnZXRHbG9iYWxBdXRvUmVmcmVzaFNlcnZpY2U6IFdpZGdldEdsb2JhbEF1dG9SZWZyZXNoU2VydmljZVxuICApIHtcbiAgICB0aGlzLmluaXRPdXRwdXRzKCk7XG4gIH1cblxuICBzdGFydFJlYWx0aW1lKCkge1xuICAgIGlmICghdGhpcy5hc3NldHMgfHwgKEFycmF5LmlzQXJyYXkodGhpcy5hc3NldHMpICYmIHRoaXMuYXNzZXRzLmxlbmd0aCA+IDEpKSB7XG4gICAgICB0aGlzLmNvbmZpZy5yZWFsdGltZSA9IGZhbHNlO1xuICAgICAgdGhpcy5zdG9wUmVhbHRpbWUoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgYXNzZXQgPSBBcnJheS5pc0FycmF5KHRoaXMuYXNzZXRzKSA/IHRoaXMuYXNzZXRzWzBdIDogdGhpcy5hc3NldHM7XG4gICAgdGhpcy5yZWFsdGltZVN1YnNjcmlwdGlvbiA9IHRoaXMubW9SZWFsdGltZVNlcnZpY2VcbiAgICAgIC5vblVwZGF0ZSQoYXNzZXQpXG4gICAgICAuc3Vic2NyaWJlKChhc3NldDogUG9zaXRpb25NYW5hZ2VkT2JqZWN0KSA9PiB7XG4gICAgICAgIGNvbnN0IG1hcmtlciA9IHRoaXMuZmluZE1hcmtlcihhc3NldC5pZCk7XG4gICAgICAgIGNvbnN0IGljb24gPSB0aGlzLmdldEFzc2V0SWNvbihhc3NldCk7XG4gICAgICAgIG1hcmtlci5zZXRJY29uKGljb24pO1xuICAgICAgICBtYXJrZXIuc2V0TGF0TG5nKHRoaXMuZ2VvLmdldExhdExvbmcoYXNzZXQpKTtcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkodGhpcy5hc3NldHMpKSB7XG4gICAgICAgICAgdGhpcy5hc3NldHNbMF0gPSBhc3NldDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLmFzc2V0cyA9IGFzc2V0O1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubW92ZVRvUG9zaXRpb25PZk1vKGFzc2V0KTtcbiAgICAgICAgdGhpcy5vblJlYWx0aW1lVXBkYXRlLmVtaXQoYXNzZXQpO1xuICAgICAgfSk7XG4gIH1cblxuICBtb3ZlVG9Qb3NpdGlvbk9mTW8ocG9zaXRpb25zOiBQb3NpdGlvbk1hbmFnZWRPYmplY3QgfCBQb3NpdGlvbk1hbmFnZWRPYmplY3RbXSkge1xuICAgIGNvbnN0IHBvc2l0aW9uID0gQXJyYXkuaXNBcnJheShwb3NpdGlvbnMpID8gcG9zaXRpb25zWzBdIDogcG9zaXRpb25zO1xuICAgIGlmICh0aGlzLmNvbmZpZy5mb2xsb3cpIHtcbiAgICAgIHRoaXMubWFwLnNldFZpZXcoW3Bvc2l0aW9uLmM4eV9Qb3NpdGlvbi5sYXQsIHBvc2l0aW9uLmM4eV9Qb3NpdGlvbi5sbmddKTtcbiAgICB9XG4gIH1cblxuICBzdG9wUmVhbHRpbWUoKSB7XG4gICAgaWYgKHRoaXMucmVhbHRpbWVTdWJzY3JpcHRpb24pIHtcbiAgICAgIHRoaXMucmVhbHRpbWVTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB9XG4gIH1cblxuICBmaW5kTWFya2VyKG1vT3JJZDogc3RyaW5nIHwgSUV2ZW50IHwgUG9zaXRpb25NYW5hZ2VkT2JqZWN0KSB7XG4gICAgY29uc3QgZ2V0SWQgPSBtb09ySWQgPT4gKHR5cGVvZiBtb09ySWQgPT09ICdzdHJpbmcnID8gbW9PcklkIDogbW9PcklkPy5pZCk7XG4gICAgcmV0dXJuIHRoaXMubWFya2Vycy5maW5kKFxuICAgICAgKG1hcmtlcjogQzh5TWFya2VyKSA9PlxuICAgICAgICBtYXJrZXIuYXNzZXQ/LmlkID09PSBnZXRJZChtb09ySWQpIHx8IG1hcmtlci5ldmVudD8uaWQgPT09IGdldElkKG1vT3JJZClcbiAgICApO1xuICB9XG5cbiAgYWRkTWFya2VyVG9NYXAobWFya2VyOiBDOHlNYXJrZXIgfCBMLk1hcmtlcikge1xuICAgIHRoaXMubWFya2Vycy5wdXNoKG1hcmtlcik7XG4gICAgbWFya2VyLmFkZFRvKHRoaXMubWFwKTtcbiAgfVxuXG4gIGdldEFzc2V0TWFya2VyKGFzc2V0OiBQb3NpdGlvbk1hbmFnZWRPYmplY3QpIHtcbiAgICBpZiAoIWFzc2V0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgaWNvbiA9IHRoaXMuZ2V0QXNzZXRJY29uKGFzc2V0KTtcbiAgICBjb25zdCB7IGxhdCwgbG5nIH0gPSBhc3NldC5jOHlfUG9zaXRpb247XG4gICAgY29uc3QgbGVhZmxldE1hcmtlciA9IHRoaXMubGVhZmxldC5tYXJrZXIodGhpcy5nZW8uZ2V0TGF0TG9uZyhhc3NldCksIHtcbiAgICAgIGljb24sXG4gICAgICB0aXRsZTogdGhpcy50cmFuc2xhdGVTZXJ2aWNlLmluc3RhbnQodGhpcy5tYXJrZXJUaXRsZSwgeyBsYXQsIGxuZyB9KVxuICAgIH0pO1xuICAgIGNvbnN0IG1hcmtlciA9IGdldEM4eU1hcmtlcihsZWFmbGV0TWFya2VyLCBhc3NldCk7XG4gICAgdGhpcy5iaW5kUG9wdXAobWFya2VyLCBhc3NldCk7XG5cbiAgICByZXR1cm4gbWFya2VyO1xuICB9XG5cbiAgZ2V0VHJhY2tpbmdNYXJrZXIoZXZlbnQ6IElFdmVudCkge1xuICAgIGlmICghZXZlbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBpY29uID0gdGhpcy5nZXRUcmFja2luZ0ljb24oKTtcbiAgICBjb25zdCB7IGxhdCwgbG5nIH0gPSBldmVudC5jOHlfUG9zaXRpb247XG4gICAgY29uc3QgbGVhZmxldE1hcmtlciA9IHRoaXMubGVhZmxldC5tYXJrZXIodGhpcy5nZW8uZ2V0TGF0TG9uZyhldmVudCksIHtcbiAgICAgIGljb24sXG4gICAgICB0aXRsZTogdGhpcy50cmFuc2xhdGVTZXJ2aWNlLmluc3RhbnQodGhpcy5tYXJrZXJUaXRsZSwgeyBsYXQsIGxuZyB9KVxuICAgIH0pO1xuICAgIGNvbnN0IG1hcmtlciA9IGdldEM4eU1hcmtlcihsZWFmbGV0TWFya2VyLCBudWxsLCBldmVudCk7XG4gICAgdGhpcy5iaW5kUG9wdXAobWFya2VyLCBldmVudCk7XG5cbiAgICByZXR1cm4gbWFya2VyO1xuICB9XG5cbiAgZ2V0QXNzZXRJY29uKGFzc2V0OiBQb3NpdGlvbk1hbmFnZWRPYmplY3QpIHtcbiAgICBjb25zdCBhc3NldFR5cGVJY29uID0gdGhpcy5jb25maWcuaWNvbiB8fCBhc3NldC5pY29uPy5uYW1lO1xuICAgIGNvbnN0IHN0YXR1cyA9IE1hcFNlcnZpY2UuZ2V0U3RhdHVzKGFzc2V0KTtcbiAgICBjb25zdCBjb2xvciA9IHRoaXMuY29uZmlnLmNvbG9yID8gYHN0eWxlPSdjb2xvcjogJHt0aGlzLmNvbmZpZy5jb2xvcn07J2AgOiAnJztcbiAgICBjb25zdCBpY29uID0gdGhpcy5sZWFmbGV0LmRpdkljb24oe1xuICAgICAgaHRtbDogYDxkaXYgY2xhc3M9XCJkbHQtYzh5LWljb24tbWFya2VyIGljb24tM3ggJHtzdGF0dXN9XCIgJHtjb2xvcn0+PGkgY2xhc3M9XCJkbHQtYzh5LWljb24tJHtcbiAgICAgICAgYXNzZXRUeXBlSWNvbiB8fCAnZGF0YS10cmFuc2ZlcidcbiAgICAgIH1cIiAvPjwvZGl2PmAsXG4gICAgICBjbGFzc05hbWU6ICdjOHktbWFwLW1hcmtlci1pY29uJyxcbiAgICAgIC8vIGljb25BbmNob3IgaXMgdXNlZCB0byBzZXQgdGhlIG1hcmtlciBhY2N1cmF0ZWx5IG9uIGNsaWNrXG4gICAgICBpY29uQW5jaG9yOiBbOCwgOF1cbiAgICB9KTtcbiAgICByZXR1cm4gaWNvbjtcbiAgfVxuXG4gIGdldFRyYWNraW5nSWNvbigpIHtcbiAgICBjb25zdCBpY29uID0gdGhpcy5sZWFmbGV0LmRpdkljb24oe1xuICAgICAgaHRtbDogYDxkaXYgY2xhc3M9XCJkbHQtYzh5LWljb24tbWFya2VyIGljb24tM3ggdGV4dC1tdXRlZFwiPjwvZGl2PmAsXG4gICAgICBjbGFzc05hbWU6ICdjOHktbWFwLW1hcmtlci1pY29uJyxcbiAgICAgIC8vIGljb25BbmNob3IgaXMgdXNlZCB0byBzZXQgdGhlIG1hcmtlciBhY2N1cmF0ZWx5IG9uIGNsaWNrXG4gICAgICBpY29uQW5jaG9yOiBbOCwgOF1cbiAgICB9KTtcbiAgICByZXR1cm4gaWNvbjtcbiAgfVxuX