UNPKG

@c8y/ngx-components

Version:

Angular modules for Cumulocity IoT applications

100 lines 14.7 kB
import { Injectable } from '@angular/core'; import { EventService } from '@c8y/client'; import { GeoService } from '@c8y/ngx-components'; import { first, identity, isEmpty, last } from 'lodash-es'; import { BehaviorSubject, Subject, combineLatest, pipe } from 'rxjs'; import { distinctUntilChanged, map, share, switchMap, tap } from 'rxjs/operators'; import * as i0 from "@angular/core"; import * as i1 from "@c8y/client"; import * as i2 from "@c8y/ngx-components"; const LOCATION_UPDATE_EVENT_TYPE = 'c8y_LocationUpdate'; export class TrackingService { static { this.BASE_FILTER = { pageSize: 1000, withTotalPages: true, type: LOCATION_UPDATE_EVENT_TYPE }; } constructor(eventService, geo) { this.eventService = eventService; this.geo = geo; this.trackVisible = true; this.hasEvents = false; this._polylineEventsSubject$ = new BehaviorSubject([]); this.deviceId$ = new Subject(); this.timeInterval$ = new Subject(); this.reload$ = new BehaviorSubject(null); this.polyline$ = this._polylineEventsSubject$.asObservable().pipe(map(events => (events || []).map(event => this.geo.getLatLong(event)).filter(identity)), share()); this.events$ = combineLatest([ this.deviceId$.pipe(distinctUntilChanged()), this.timeInterval$, this.reload$ ]).pipe(switchMap(([source, interval]) => { const { dateFrom, dateTo } = interval; return this.eventService.list({ ...TrackingService.BASE_FILTER, source, dateFrom: dateFrom.toISOString(), dateTo: dateTo.toISOString() }); }), tap(() => this._polylineEventsSubject$.next([])), share()); this.pipe = pipe(tap(events => (this.hasEvents = !isEmpty(events))), map((events) => (events || []).filter(event => this.isMatchingEvent(event))), tap((events) => { const prepend = this.compareEvents(last(this._polylineEventsSubject$.value), first(events)) < 0; const polyline = prepend ? [...events, ...this._polylineEventsSubject$.value] : [...this._polylineEventsSubject$.value, ...events]; this._polylineEventsSubject$.next(polyline); })); } setDeviceId(deviceId) { this.deviceId$.next(deviceId); } setInterval(interval) { this.timeInterval$.next(interval); } clearTrack() { this._polylineEventsSubject$.next([]); } reload() { this.reload$.next(); } async latestPositionUpdate(mo) { const dateTo = new Date(); dateTo.setDate(dateTo.getDate() + 1); const filters = { fragmentType: 'c8y_Position', dateFrom: new Date(0).toISOString(), dateTo: dateTo.toISOString(), pageSize: 1, source: mo.id }; const events = await this.eventService.list(filters); return events?.data?.length ? new Date(events.data[0].time) : undefined; } toggleTrack() { if (this.trackVisible) { this.clearTrack(); } else { this.reload(); } this.trackVisible = !this.trackVisible; } isLocationUpdateEvent(event) { return event.type === LOCATION_UPDATE_EVENT_TYPE; } isMatchingEvent(event) { return this.isLocationUpdateEvent(event); } compareEvents(a, b) { return Date.parse(a?.time) - Date.parse(b?.time); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TrackingService, deps: [{ token: i1.EventService }, { token: i2.GeoService }], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TrackingService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TrackingService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: i1.EventService }, { type: i2.GeoService }] }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhY2tpbmcuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3RyYWNraW5nL3RyYWNraW5nLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzQyxPQUFPLEVBQUUsWUFBWSxFQUF1QixNQUFNLGFBQWEsQ0FBQztBQUNoRSxPQUFPLEVBQW1CLFVBQVUsRUFBZ0IsTUFBTSxxQkFBcUIsQ0FBQztBQUVoRixPQUFPLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQzNELE9BQU8sRUFBRSxlQUFlLEVBQWMsT0FBTyxFQUFFLGFBQWEsRUFBRSxJQUFJLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDakYsT0FBTyxFQUFFLG9CQUFvQixFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDOzs7O0FBRWxGLE1BQU0sMEJBQTBCLEdBQUcsb0JBQW9CLENBQUM7QUFLeEQsTUFBTSxPQUFPLGVBQWU7YUFDRixnQkFBVyxHQUFHO1FBQ3BDLFFBQVEsRUFBRSxJQUFJO1FBQ2QsY0FBYyxFQUFFLElBQUk7UUFDcEIsSUFBSSxFQUFFLDBCQUEwQjtLQUNqQyxBQUprQyxDQUlqQztJQWNGLFlBQ1UsWUFBMEIsRUFDMUIsR0FBZTtRQURmLGlCQUFZLEdBQVosWUFBWSxDQUFjO1FBQzFCLFFBQUcsR0FBSCxHQUFHLENBQVk7UUFYekIsaUJBQVksR0FBRyxJQUFJLENBQUM7UUFDcEIsY0FBUyxHQUFHLEtBQUssQ0FBQztRQUVWLDRCQUF1QixHQUFHLElBQUksZUFBZSxDQUFXLEVBQUUsQ0FBQyxDQUFDO1FBRTVELGNBQVMsR0FBNkIsSUFBSSxPQUFPLEVBQUUsQ0FBQztRQUNwRCxrQkFBYSxHQUEwQixJQUFJLE9BQU8sRUFBRSxDQUFDO1FBQ3JELFlBQU8sR0FBMEIsSUFBSSxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7UUFNakUsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUMsWUFBWSxFQUFFLENBQUMsSUFBSSxDQUMvRCxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxDQUFDLE1BQU0sSUFBSSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUN2RixLQUFLLEVBQUUsQ0FDUixDQUFDO1FBRUYsSUFBSSxDQUFDLE9BQU8sR0FBRyxhQUFhLENBQUM7WUFDM0IsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztZQUMzQyxJQUFJLENBQUMsYUFBYTtZQUNsQixJQUFJLENBQUMsT0FBTztTQUNiLENBQUMsQ0FBQyxJQUFJLENBQ0wsU0FBUyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsUUFBUSxDQUFDLEVBQUUsRUFBRTtZQUMvQixNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxHQUFHLFFBQVEsQ0FBQztZQUN0QyxPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDO2dCQUM1QixHQUFHLGVBQWUsQ0FBQyxXQUFXO2dCQUM5QixNQUFNO2dCQUNOLFFBQVEsRUFBRSxRQUFRLENBQUMsV0FBVyxFQUFFO2dCQUNoQyxNQUFNLEVBQUUsTUFBTSxDQUFDLFdBQVcsRUFBRTthQUM3QixDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsRUFDRixHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUNoRCxLQUFLLEVBQUUsQ0FDUixDQUFDO1FBRUYsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQ2QsR0FBRyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxHQUFHLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFDbEQsR0FBRyxDQUFDLENBQUMsTUFBZ0IsRUFBRSxFQUFFLENBQUMsQ0FBQyxNQUFNLElBQUksRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQ3RGLEdBQUcsQ0FBQyxDQUFDLE1BQWdCLEVBQUUsRUFBRTtZQUN2QixNQUFNLE9BQU8sR0FDWCxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsdUJBQXVCLENBQUMsS0FBSyxDQUFDLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2xGLE1BQU0sUUFBUSxHQUFhLE9BQU87Z0JBQ2hDLENBQUMsQ0FBQyxDQUFDLEdBQUcsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUFDLEtBQUssQ0FBQztnQkFDcEQsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUMsS0FBSyxFQUFFLEdBQUcsTUFBTSxDQUFDLENBQUM7WUFFdkQsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUM5QyxDQUFDLENBQUMsQ0FDSCxDQUFDO0lBQ0osQ0FBQztJQUVELFdBQVcsQ0FBQyxRQUF5QjtRQUNuQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUNoQyxDQUFDO0lBRUQsV0FBVyxDQUFDLFFBQXNCO1FBQ2hDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFRCxVQUFVO1FBQ1IsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBRUQsTUFBTTtRQUNKLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDdEIsQ0FBQztJQUVELEtBQUssQ0FBQyxvQkFBb0IsQ0FBQyxFQUF5QjtRQUNsRCxNQUFNLE1BQU0sR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO1FBQzFCLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBRXJDLE1BQU0sT0FBTyxHQUFHO1lBQ2QsWUFBWSxFQUFFLGNBQWM7WUFDNUIsUUFBUSxFQUFFLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRTtZQUNuQyxNQUFNLEVBQUUsTUFBTSxDQUFDLFdBQVcsRUFBRTtZQUM1QixRQUFRLEVBQUUsQ0FBQztZQUNYLE1BQU0sRUFBRSxFQUFFLENBQUMsRUFBRTtTQUNkLENBQUM7UUFDRixNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3JELE9BQU8sTUFBTSxFQUFFLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztJQUMxRSxDQUFDO0lBRUQsV0FBVztRQUNULElBQUksSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3RCLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNwQixDQUFDO2FBQU0sQ0FBQztZQUNOLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNoQixDQUFDO1FBQ0QsSUFBSSxDQUFDLFlBQVksR0FBRyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUM7SUFDekMsQ0FBQztJQUVELHFCQUFxQixDQUFDLEtBQWE7UUFDakMsT0FBTyxLQUFLLENBQUMsSUFBSSxLQUFLLDBCQUEwQixDQUFDO0lBQ25ELENBQUM7SUFFTyxlQUFlLENBQUMsS0FBYTtRQUNuQyxPQUFPLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMzQyxDQUFDO0lBRU8sYUFBYSxDQUFDLENBQVMsRUFBRSxDQUFTO1FBQ3hDLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDbkQsQ0FBQzsrR0EvR1UsZUFBZTttSEFBZixlQUFlLGNBRmQsTUFBTTs7NEZBRVAsZUFBZTtrQkFIM0IsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBFdmVudFNlcnZpY2UsIElFdmVudCwgSVJlc3VsdExpc3QgfSBmcm9tICdAYzh5L2NsaWVudCc7XG5pbXBvcnQgeyBGb3JPZkZpbHRlclBpcGUsIEdlb1NlcnZpY2UsIFRpbWVJbnRlcnZhbCB9IGZyb20gJ0BjOHkvbmd4LWNvbXBvbmVudHMnO1xuaW1wb3J0IHsgUG9zaXRpb25NYW5hZ2VkT2JqZWN0IH0gZnJvbSAnQGM4eS9uZ3gtY29tcG9uZW50cy9tYXAnO1xuaW1wb3J0IHsgZmlyc3QsIGlkZW50aXR5LCBpc0VtcHR5LCBsYXN0IH0gZnJvbSAnbG9kYXNoLWVzJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgT2JzZXJ2YWJsZSwgU3ViamVjdCwgY29tYmluZUxhdGVzdCwgcGlwZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGlzdGluY3RVbnRpbENoYW5nZWQsIG1hcCwgc2hhcmUsIHN3aXRjaE1hcCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5jb25zdCBMT0NBVElPTl9VUERBVEVfRVZFTlRfVFlQRSA9ICdjOHlfTG9jYXRpb25VcGRhdGUnO1xuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBUcmFja2luZ1NlcnZpY2Uge1xuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBCQVNFX0ZJTFRFUiA9IHtcbiAgICBwYWdlU2l6ZTogMTAwMCxcbiAgICB3aXRoVG90YWxQYWdlczogdHJ1ZSxcbiAgICB0eXBlOiBMT0NBVElPTl9VUERBVEVfRVZFTlRfVFlQRVxuICB9O1xuXG4gIGV2ZW50cyQ6IE9ic2VydmFibGU8SVJlc3VsdExpc3Q8SUV2ZW50Pj47XG4gIHBvbHlsaW5lJDogT2JzZXJ2YWJsZTxMLkxhdExuZ0V4cHJlc3Npb25bXT47XG4gIHBpcGU6IEZvck9mRmlsdGVyUGlwZTtcbiAgdHJhY2tWaXNpYmxlID0gdHJ1ZTtcbiAgaGFzRXZlbnRzID0gZmFsc2U7XG5cbiAgcHJpdmF0ZSBfcG9seWxpbmVFdmVudHNTdWJqZWN0JCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8SUV2ZW50W10+KFtdKTtcblxuICBwcml2YXRlIGRldmljZUlkJDogU3ViamVjdDxzdHJpbmcgfCBudW1iZXI+ID0gbmV3IFN1YmplY3QoKTtcbiAgcHJpdmF0ZSB0aW1lSW50ZXJ2YWwkOiBTdWJqZWN0PFRpbWVJbnRlcnZhbD4gPSBuZXcgU3ViamVjdCgpO1xuICBwcml2YXRlIHJlbG9hZCQ6IEJlaGF2aW9yU3ViamVjdDx2b2lkPiA9IG5ldyBCZWhhdmlvclN1YmplY3QobnVsbCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBldmVudFNlcnZpY2U6IEV2ZW50U2VydmljZSxcbiAgICBwcml2YXRlIGdlbzogR2VvU2VydmljZVxuICApIHtcbiAgICB0aGlzLnBvbHlsaW5lJCA9IHRoaXMuX3BvbHlsaW5lRXZlbnRzU3ViamVjdCQuYXNPYnNlcnZhYmxlKCkucGlwZShcbiAgICAgIG1hcChldmVudHMgPT4gKGV2ZW50cyB8fCBbXSkubWFwKGV2ZW50ID0+IHRoaXMuZ2VvLmdldExhdExvbmcoZXZlbnQpKS5maWx0ZXIoaWRlbnRpdHkpKSxcbiAgICAgIHNoYXJlKClcbiAgICApO1xuXG4gICAgdGhpcy5ldmVudHMkID0gY29tYmluZUxhdGVzdChbXG4gICAgICB0aGlzLmRldmljZUlkJC5waXBlKGRpc3RpbmN0VW50aWxDaGFuZ2VkKCkpLFxuICAgICAgdGhpcy50aW1lSW50ZXJ2YWwkLFxuICAgICAgdGhpcy5yZWxvYWQkXG4gICAgXSkucGlwZShcbiAgICAgIHN3aXRjaE1hcCgoW3NvdXJjZSwgaW50ZXJ2YWxdKSA9PiB7XG4gICAgICAgIGNvbnN0IHsgZGF0ZUZyb20sIGRhdGVUbyB9ID0gaW50ZXJ2YWw7XG4gICAgICAgIHJldHVybiB0aGlzLmV2ZW50U2VydmljZS5saXN0KHtcbiAgICAgICAgICAuLi5UcmFja2luZ1NlcnZpY2UuQkFTRV9GSUxURVIsXG4gICAgICAgICAgc291cmNlLFxuICAgICAgICAgIGRhdGVGcm9tOiBkYXRlRnJvbS50b0lTT1N0cmluZygpLFxuICAgICAgICAgIGRhdGVUbzogZGF0ZVRvLnRvSVNPU3RyaW5nKClcbiAgICAgICAgfSk7XG4gICAgICB9KSxcbiAgICAgIHRhcCgoKSA9PiB0aGlzLl9wb2x5bGluZUV2ZW50c1N1YmplY3QkLm5leHQoW10pKSxcbiAgICAgIHNoYXJlKClcbiAgICApO1xuXG4gICAgdGhpcy5waXBlID0gcGlwZShcbiAgICAgIHRhcChldmVudHMgPT4gKHRoaXMuaGFzRXZlbnRzID0gIWlzRW1wdHkoZXZlbnRzKSkpLFxuICAgICAgbWFwKChldmVudHM6IElFdmVudFtdKSA9PiAoZXZlbnRzIHx8IFtdKS5maWx0ZXIoZXZlbnQgPT4gdGhpcy5pc01hdGNoaW5nRXZlbnQoZXZlbnQpKSksXG4gICAgICB0YXAoKGV2ZW50czogSUV2ZW50W10pID0+IHtcbiAgICAgICAgY29uc3QgcHJlcGVuZCA9XG4gICAgICAgICAgdGhpcy5jb21wYXJlRXZlbnRzKGxhc3QodGhpcy5fcG9seWxpbmVFdmVudHNTdWJqZWN0JC52YWx1ZSksIGZpcnN0KGV2ZW50cykpIDwgMDtcbiAgICAgICAgY29uc3QgcG9seWxpbmU6IElFdmVudFtdID0gcHJlcGVuZFxuICAgICAgICAgID8gWy4uLmV2ZW50cywgLi4udGhpcy5fcG9seWxpbmVFdmVudHNTdWJqZWN0JC52YWx1ZV1cbiAgICAgICAgICA6IFsuLi50aGlzLl9wb2x5bGluZUV2ZW50c1N1YmplY3QkLnZhbHVlLCAuLi5ldmVudHNdO1xuXG4gICAgICAgIHRoaXMuX3BvbHlsaW5lRXZlbnRzU3ViamVjdCQubmV4dChwb2x5bGluZSk7XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICBzZXREZXZpY2VJZChkZXZpY2VJZDogc3RyaW5nIHwgbnVtYmVyKSB7XG4gICAgdGhpcy5kZXZpY2VJZCQubmV4dChkZXZpY2VJZCk7XG4gIH1cblxuICBzZXRJbnRlcnZhbChpbnRlcnZhbDogVGltZUludGVydmFsKSB7XG4gICAgdGhpcy50aW1lSW50ZXJ2YWwkLm5leHQoaW50ZXJ2YWwpO1xuICB9XG5cbiAgY2xlYXJUcmFjaygpIHtcbiAgICB0aGlzLl9wb2x5bGluZUV2ZW50c1N1YmplY3QkLm5leHQoW10pO1xuICB9XG5cbiAgcmVsb2FkKCkge1xuICAgIHRoaXMucmVsb2FkJC5uZXh0KCk7XG4gIH1cblxuICBhc3luYyBsYXRlc3RQb3NpdGlvblVwZGF0ZShtbzogUG9zaXRpb25NYW5hZ2VkT2JqZWN0KTogUHJvbWlzZTxEYXRlPiB7XG4gICAgY29uc3QgZGF0ZVRvID0gbmV3IERhdGUoKTtcbiAgICBkYXRlVG8uc2V0RGF0ZShkYXRlVG8uZ2V0RGF0ZSgpICsgMSk7XG5cbiAgICBjb25zdCBmaWx0ZXJzID0ge1xuICAgICAgZnJhZ21lbnRUeXBlOiAnYzh5X1Bvc2l0aW9uJyxcbiAgICAgIGRhdGVGcm9tOiBuZXcgRGF0ZSgwKS50b0lTT1N0cmluZygpLFxuICAgICAgZGF0ZVRvOiBkYXRlVG8udG9JU09TdHJpbmcoKSxcbiAgICAgIHBhZ2VTaXplOiAxLFxuICAgICAgc291cmNlOiBtby5pZFxuICAgIH07XG4gICAgY29uc3QgZXZlbnRzID0gYXdhaXQgdGhpcy5ldmVudFNlcnZpY2UubGlzdChmaWx0ZXJzKTtcbiAgICByZXR1cm4gZXZlbnRzPy5kYXRhPy5sZW5ndGggPyBuZXcgRGF0ZShldmVudHMuZGF0YVswXS50aW1lKSA6IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHRvZ2dsZVRyYWNrKCkge1xuICAgIGlmICh0aGlzLnRyYWNrVmlzaWJsZSkge1xuICAgICAgdGhpcy5jbGVhclRyYWNrKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucmVsb2FkKCk7XG4gICAgfVxuICAgIHRoaXMudHJhY2tWaXNpYmxlID0gIXRoaXMudHJhY2tWaXNpYmxlO1xuICB9XG5cbiAgaXNMb2NhdGlvblVwZGF0ZUV2ZW50KGV2ZW50OiBJRXZlbnQpOiBib29sZWFuIHtcbiAgICByZXR1cm4gZXZlbnQudHlwZSA9PT0gTE9DQVRJT05fVVBEQVRFX0VWRU5UX1RZUEU7XG4gIH1cblxuICBwcml2YXRlIGlzTWF0Y2hpbmdFdmVudChldmVudDogSUV2ZW50KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuaXNMb2NhdGlvblVwZGF0ZUV2ZW50KGV2ZW50KTtcbiAgfVxuXG4gIHByaXZhdGUgY29tcGFyZUV2ZW50cyhhOiBJRXZlbnQsIGI6IElFdmVudCk6IG51bWJlciB7XG4gICAgcmV0dXJuIERhdGUucGFyc2UoYT8udGltZSkgLSBEYXRlLnBhcnNlKGI/LnRpbWUpO1xuICB9XG59XG4iXX0=