@project-sunbird/sunbird-video-player-v9
Version:
The Video player library is powered by Angular. This player is primarily designed to be used on Sunbird consumption platforms _(mobile app, web portal, offline desktop app)_ to drive reusability and maintainability, hence reducing the redundant developmen
299 lines • 41.3 kB
JavaScript
import { EventEmitter, Injectable, Optional } from '@angular/core';
import { errorCode, errorMessage } from '@project-sunbird/sunbird-player-sdk-v9';
import { of } from 'rxjs';
import { map } from 'rxjs/operators';
import * as _ from 'lodash-es';
import * as i0 from "@angular/core";
import * as i1 from "../sunbird-video-player.service";
import * as i2 from "./util.service";
import * as i3 from "@angular/common/http";
import * as i4 from "@project-sunbird/sunbird-quml-player-v9";
export class ViewerService {
constructor(videoPlayerService, utilService, http, questionCursor) {
this.videoPlayerService = videoPlayerService;
this.utilService = utilService;
this.http = http;
this.questionCursor = questionCursor;
this.endPageSeen = false;
this.timeSpent = '0:0';
this.version = '1.0';
this.playerEvent = new EventEmitter();
this.totalSeekedLength = 0;
this.visitedLength = 0;
this.sidebarMenuEvent = new EventEmitter();
this.isAvailableLocally = false;
this.interceptionResponses = {};
this.showScore = false;
this.scoreObtained = 0;
this.contentMap = {};
this.playerTimeSlots = [];
this.isEndEventRaised = false;
this.playBitStartTime = 0;
this.playBitEndTime = 0;
this.PlayerLoadStartedAt = new Date().getTime();
}
initialize({ context, config, metadata }) {
this.contentName = metadata.name;
this.isAvailableLocally = metadata.isAvailableLocally;
this.streamingUrl = metadata.streamingUrl;
this.artifactUrl = metadata.artifactUrl;
this.mimeType = metadata.streamingUrl ? 'application/x-mpegURL' : metadata.mimeType;
this.artifactMimeType = metadata.mimeType;
this.isAvailableLocally = metadata.isAvailableLocally;
this.traceId = config.traceId;
this.interceptionPoints = metadata.interceptionPoints;
if (context.userData) {
const { userData: { firstName, lastName } } = context;
this.userName = firstName === lastName ? firstName : `${firstName} ${lastName}`;
}
this.metaData = {
actions: [],
volume: [],
playBackSpeeds: [],
totalDuration: 0,
muted: undefined,
currentDuration: undefined,
transcripts: []
};
this.transcripts = metadata.transcripts ? metadata.transcripts : [];
this.showDownloadPopup = false;
this.endPageSeen = false;
if (this.isAvailableLocally) {
const basePath = (metadata.streamingUrl) ? (metadata.streamingUrl) : (metadata.basePath || metadata.baseDir);
this.streamingUrl = `${basePath}/${metadata.artifactUrl}`;
this.mimeType = metadata.mimeType;
}
}
handleTranscriptsData(selectedTranscripts) {
this.metaData.transcripts = selectedTranscripts;
if (!_.isArray(this.transcripts)) {
this.raiseExceptionLog('INVALID_TRANSCRIPT_DATATYPE', 'TRANSCRIPT', new Error('Transcript data should be array'), this.traceId);
return [];
}
else {
_.forEach(this.transcripts, (value) => {
if (!(_.some(this.transcripts, { language: value.language, artifactUrl: value.artifactUrl,
languageCode: value.languageCode, identifier: value.identifier }))) {
this.raiseExceptionLog('TRANSCRIPT_DATA_MISSING', 'TRANSCRIPT', new Error('Transcript object dose not have required fields'), this.traceId);
return [];
}
else if (!_.isEmpty(selectedTranscripts) &&
(_.last(selectedTranscripts) !== 'off' && _.last(selectedTranscripts) === value.languageCode)) {
value.default = true;
}
});
}
return this.transcripts;
}
async getPlayerOptions() {
if (!this.streamingUrl) {
return [{ src: this.artifactUrl, type: this.artifactMimeType }];
}
else {
const data = await this.http.head(this.streamingUrl, { responseType: 'blob' }).toPromise().catch(error => {
// eslint-disable-next-line max-len
this.raiseExceptionLog(errorCode.streamingUrlSupport, errorMessage.streamingUrlSupport, new Error(`Streaming Url Not Supported ${this.streamingUrl}`), this.traceId);
});
if (data) {
return [{ src: this.streamingUrl, type: this.mimeType }];
}
else {
return [{ src: this.artifactUrl, type: this.artifactMimeType }];
}
}
}
getMarkers() {
if (this?.interceptionPoints?.items) {
try {
const interceptionPoints = this.interceptionPoints;
this.showScore = true;
return interceptionPoints.items.map(({ interceptionPoint, identifier, type }) => {
return { time: interceptionPoint, type, identifier, duration: 3 };
});
}
catch (error) {
console.log(error);
this.raiseExceptionLog('CPV2_CONT_INTERCEPTION_PARSE', 'error parsing the inteception points string', error, '');
this.showScore = false;
}
}
return null;
}
getQuestionSet(identifier) {
const content = this.contentMap[identifier];
if (!content) {
if (!this.questionCursor) {
return null;
}
else {
return this.questionCursor.getQuestionSet(identifier)
.pipe(map((response) => {
this.contentMap[identifier] = response.questionSet;
return this.contentMap[identifier];
}));
}
}
else {
return of(content);
}
}
preFetchContent() {
const nextMarker = this.getNextMarker();
if (nextMarker) {
const identifier = nextMarker.identifier;
this.getQuestionSet(nextMarker.identifier);
}
}
getUniqueVisitedLength() {
const uniqSecondsList = [];
for (let slot of this.playerTimeSlots) {
if (slot[0] < slot[1]) {
let sec = slot[0];
while (sec <= slot[1]) {
sec = Math.floor(sec);
if (uniqSecondsList.indexOf(sec) == -1 && sec != 0) {
uniqSecondsList.push(sec);
}
sec += 1;
}
}
}
return uniqSecondsList.length;
}
getVisitedLength() {
const secondsList = [];
for (let slot of this.playerTimeSlots) {
if (slot[0] < slot[1]) {
let sec = slot[0];
while (sec <= slot[1]) {
sec = Math.floor(sec);
if (sec != 0) {
secondsList.push(sec);
}
sec += 1;
}
}
}
return secondsList.length;
}
getNextMarker() {
const currentTime = this.playerInstance.currentTime();
const markersList = this.getMarkers();
if (!markersList) {
return null;
}
return markersList.find(marker => {
const markerTime = marker.time;
return markerTime > currentTime;
});
}
raiseStartEvent(event) {
const duration = new Date().getTime() - this.PlayerLoadStartedAt;
const startEvent = {
eid: 'START',
ver: this.version,
edata: {
type: 'START',
mode: 'play',
duration
},
metaData: this.metaData
};
this.playerEvent.emit(startEvent);
this.videoPlayerService.start(duration);
this.PlayerLoadStartedAt = new Date().getTime();
}
calculateScore() {
this.scoreObtained = Object.values(this.interceptionResponses).reduce(
// eslint-disable-next-line @typescript-eslint/dot-notation
(acc, response) => acc + response['score'], 0);
}
raiseEndEvent(isOnPlayInterrupt = false) {
if (!this.isEndEventRaised) {
this.calculateScore();
const duration = new Date().getTime() - this.PlayerLoadStartedAt;
const endEvent = {
eid: 'END',
ver: this.version,
edata: {
type: 'END',
currentTime: this.currentlength,
totalTime: this.totalLength,
duration
},
metaData: this.metaData
};
this.playerEvent.emit(endEvent);
if (isOnPlayInterrupt) {
this.playerTimeSlots.push([this.playBitStartTime, this.currentlength]);
}
this.uniqueVisitedLength = this.getUniqueVisitedLength();
if (this.uniqueVisitedLength > this.totalLength) {
this.uniqueVisitedLength = this.totalLength;
}
this.visitedLength = this.getVisitedLength();
this.timeSpent = this.utilService.getTimeSpentText(_.floor(this.totalLength));
this.videoPlayerService.end(duration, this.totalLength, this.currentlength, this.endPageSeen, this.totalSeekedLength, this.visitedLength, this.scoreObtained, this.uniqueVisitedLength);
this.isEndEventRaised = true;
}
}
raiseHeartBeatEvent(type, extraValues) {
if (type === 'REPLAY') {
this.interceptionResponses = {};
this.showScore = false;
this.scoreObtained = 0;
this.playerTimeSlots = [];
this.playBitEndTime = 0;
this.playBitStartTime = 0;
}
const hearBeatEvent = {
eid: 'HEARTBEAT',
ver: this.version,
edata: {
type,
currentPage: 'videostage',
extra: extraValues
},
metaData: this.metaData
};
this.playerEvent.emit(hearBeatEvent);
this.videoPlayerService.heartBeat(hearBeatEvent);
const interactItems = ['PLAY', 'PAUSE', 'EXIT', 'VOLUME_CHANGE', 'DRAG',
'RATE_CHANGE', 'CLOSE_DOWNLOAD', 'DOWNLOAD', 'NAVIGATE_TO_PAGE',
'NEXT', 'OPEN_MENU', 'PREVIOUS', 'CLOSE_MENU', 'DOWNLOAD_MENU', 'DOWNLOAD_POPUP_CLOSE', 'DOWNLOAD_POPUP_CANCEL',
'SHARE', 'REPLAY', 'FORWARD', 'BACKWARD', 'FULLSCREEN', 'NEXT_CONTENT_PLAY', 'TRANSCRIPT_LANGUAGE_OFF',
'TRANSCRIPT_LANGUAGE_SELECTED', 'VIDEO_MARKER_SELECTED'
];
if (interactItems.includes(type)) {
this.videoPlayerService.interact(type.toLowerCase(), 'videostage', extraValues);
}
}
raiseImpressionEvent(pageId, cdata = {}) {
this.videoPlayerService.impression(pageId, cdata);
}
// eslint-disable-next-line @typescript-eslint/no-shadow
raiseExceptionLog(errorCode, errorType, stacktrace, traceId) {
const exceptionLogEvent = {
eid: 'ERROR',
edata: {
err: errorCode,
errtype: errorType,
requestid: traceId || '',
stacktrace: (stacktrace && stacktrace.toString()) || '',
}
};
this.playerEvent.emit(exceptionLogEvent);
this.videoPlayerService.error(errorCode, errorType, stacktrace);
}
}
/** @nocollapse */ ViewerService.ɵfac = function ViewerService_Factory(t) { return new (t || ViewerService)(i0.ɵɵinject(i1.SunbirdVideoPlayerService), i0.ɵɵinject(i2.UtilService), i0.ɵɵinject(i3.HttpClient), i0.ɵɵinject(i4.QuestionCursor, 8)); };
/** @nocollapse */ ViewerService.ɵprov = /** @pureOrBreakMyCode */ i0.ɵɵdefineInjectable({ token: ViewerService, factory: ViewerService.ɵfac, providedIn: 'root' });
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ViewerService, [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}], function () { return [{ type: i1.SunbirdVideoPlayerService }, { type: i2.UtilService }, { type: i3.HttpClient }, { type: i4.QuestionCursor, decorators: [{
type: Optional
}] }]; }, null); })();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlld2VyLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zdW5iaXJkLXZpZGVvLXBsYXllci9zcmMvbGliL3NlcnZpY2VzL3ZpZXdlci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUluRSxPQUFPLEVBQUUsU0FBUyxFQUFHLFlBQVksRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBRWxGLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDMUIsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3JDLE9BQU8sS0FBSyxDQUFDLE1BQU0sV0FBVyxDQUFDOzs7Ozs7QUFLL0IsTUFBTSxPQUFPLGFBQWE7SUFtQ3hCLFlBQW9CLGtCQUE2QyxFQUM3QyxXQUF3QixFQUN4QixJQUFnQixFQUNMLGNBQThCO1FBSHpDLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBMkI7UUFDN0MsZ0JBQVcsR0FBWCxXQUFXLENBQWE7UUFDeEIsU0FBSSxHQUFKLElBQUksQ0FBWTtRQUNMLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQXBDdEQsZ0JBQVcsR0FBRyxLQUFLLENBQUM7UUFDcEIsY0FBUyxHQUFHLEtBQUssQ0FBQztRQUNqQixZQUFPLEdBQUcsS0FBSyxDQUFDO1FBQ2pCLGdCQUFXLEdBQUcsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQVd0QyxzQkFBaUIsR0FBRyxDQUFDLENBQUM7UUFFdEIsa0JBQWEsR0FBRyxDQUFDLENBQUM7UUFFbEIscUJBQWdCLEdBQUcsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQUUzQyx1QkFBa0IsR0FBRyxLQUFLLENBQUM7UUFFM0IsMEJBQXFCLEdBQVEsRUFBRSxDQUFDO1FBQ2hDLGNBQVMsR0FBRyxLQUFLLENBQUM7UUFDbEIsa0JB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QUN4QixVQUFVLEVBQUUsQ0FBQyxVQUFVLElBQUksVUFBVSxDQUFDLFFBQVEsRUFBRSxDQUFDLElBQUksRUFBRTthQUN4RDtTQUNGLENBQUM7UUFDRixJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBQ3pDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFHLFNBQVMsRUFBRyxVQUFVLENBQUMsQ0FBQztJQUNwRSxDQUFDOzs2RkExVFUsYUFBYTtrR0FBYixhQUFhLFdBQWIsYUFBYSxtQkFGWixNQUFNO3VGQUVQLGFBQWE7Y0FIekIsVUFBVTtlQUFDO2dCQUNWLFVBQVUsRUFBRSxNQUFNO2FBQ25COztzQkF1Q2MsUUFBUSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEh0dHBDbGllbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBFdmVudEVtaXR0ZXIsIEluamVjdGFibGUsIE9wdGlvbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBQbGF5ZXJDb25maWcsIFRyYW5zY3JpcHRzIH0gZnJvbSAnLi4vcGxheWVySW50ZXJmYWNlcyc7XG5pbXBvcnQgeyBTdW5iaXJkVmlkZW9QbGF5ZXJTZXJ2aWNlIH0gZnJvbSAnLi4vc3VuYmlyZC12aWRlby1wbGF5ZXIuc2VydmljZSc7XG5pbXBvcnQgeyBVdGlsU2VydmljZSB9IGZyb20gJy4vdXRpbC5zZXJ2aWNlJztcbmltcG9ydCB7IGVycm9yQ29kZSAsIGVycm9yTWVzc2FnZSB9IGZyb20gJ0Bwcm9qZWN0LXN1bmJpcmQvc3VuYmlyZC1wbGF5ZXItc2RrLXY5JztcbmltcG9ydCB7IFF1ZXN0aW9uQ3Vyc29yIH0gZnJvbSAnQHByb2plY3Qtc3VuYmlyZC9zdW5iaXJkLXF1bWwtcGxheWVyLXY5JztcbmltcG9ydCB7IG9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBtYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaC1lcyc7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXG59KVxuZXhwb3J0IGNsYXNzIFZpZXdlclNlcnZpY2Uge1xuXG4gIHB1YmxpYyBlbmRQYWdlU2VlbiA9IGZhbHNlO1xuICBwdWJsaWMgdGltZVNwZW50ID0gJzA6MCc7XG4gIHByaXZhdGUgdmVyc2lvbiA9ICcxLjAnO1xuICBwdWJsaWMgcGxheWVyRXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcbiAgcHVibGljIGNvbnRlbnROYW1lOiBzdHJpbmc7XG4gIHB1YmxpYyBzaG93RG93bmxvYWRQb3B1cDogYm9vbGVhbjtcbiAgcHVibGljIHN0cmVhbWluZ1VybDogc3RyaW5nO1xuICBwdWJsaWMgbWltZVR5cGU6IHN0cmluZztcbiAgcHVibGljIGFydGlmYWN0TWltZVR5cGU6IHN0cmluZztcbiAgcHVibGljIHVzZXJOYW1lOiBzdHJpbmc7XG4gIHB1YmxpYyBtZXRhRGF0YTogYW55O1xuICBwdWJsaWMgUGxheWVyTG9hZFN0YXJ0ZWRBdDogbnVtYmVyO1xuICBwdWJsaWMgdG90YWxMZW5ndGg7XG4gIHB1YmxpYyBjdXJyZW50bGVuZ3RoO1xuICBwdWJsaWMgdG90YWxTZWVrZWRMZW5ndGggPSAwO1xuICBwdWJsaWMgYXJ0aWZhY3RVcmw7XG4gIHB1YmxpYyB2aXNpdGVkTGVuZ3RoID0gMDtcbiAgcHVibGljIHVuaXF1ZVZpc2l0ZWRMZW5ndGg7XG4gIHB1YmxpYyBzaWRlYmFyTWVudUV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gIHB1YmxpYyB0cmFjZUlkOiBzdHJpbmc7XG4gIHB1YmxpYyBpc0F2YWlsYWJsZUxvY2FsbHkgPSBmYWxzZTtcbiAgcHVibGljIGludGVyY2VwdGlvblBvaW50czogYW55O1xuICBwdWJsaWMgaW50ZXJjZXB0aW9uUmVzcG9uc2VzOiBhbnkgPSB7fTtcbiAgcHVibGljIHNob3dTY29yZSA9IGZhbHNlO1xuICBwdWJsaWMgc2NvcmVPYnRhaW5lZDogYW55ID0gMDtcbiAgcHVibGljIG1heFNjb3JlOiBudW1iZXI7XG4gIHB1YmxpYyBwbGF5ZXJJbnN0YW5jZTogYW55O1xuICBwdWJsaWMgY29udGVudE1hcCA9IHt9O1xuICBwdWJsaWMgcGxheWVyVGltZVNsb3RzID0gW107XG4gIHB1YmxpYyBpc0VuZEV2ZW50UmFpc2VkID0gZmFsc2U7XG4gIHB1YmxpYyB0cmFuc2NyaXB0czogVHJhbnNjcmlwdHM7XG4gIHB1YmxpYyBwbGF5Qml0U3RhcnRUaW1lID0gMDtcbiAgcHVibGljIHBsYXlCaXRFbmRUaW1lID0gMDtcbiAgY29uc3RydWN0b3IocHJpdmF0ZSB2aWRlb1BsYXllclNlcnZpY2U6IFN1bmJpcmRWaWRlb1BsYXllclNlcnZpY2UsXG4gICAgICAgICAgICAgIHByaXZhdGUgdXRpbFNlcnZpY2U6IFV0aWxTZXJ2aWNlLFxuICAgICAgICAgICAgICBwcml2YXRlIGh0dHA6IEh0dHBDbGllbnQsXG4gICAgICAgICAgICAgIEBPcHRpb25hbCgpIHB1YmxpYyBxdWVzdGlvbkN1cnNvcjogUXVlc3Rpb25DdXJzb3IpIHtcbiAgICB0aGlzLlBsYXllckxvYWRTdGFydGVkQXQgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgfVxuXG4gIGluaXRpYWxpemUoeyBjb250ZXh0LCBjb25maWcsIG1ldGFkYXRhIH06IFBsYXllckNvbmZpZykge1xuICAgIHRoaXMuY29udGVudE5hbWUgPSBtZXRhZGF0YS5uYW1lO1xuICAgIHRoaXMuaXNBdmFpbGFibGVMb2NhbGx5ID0gbWV0YWRhdGEuaXNBdmFpbGFibGVMb2NhbGx5O1xuICAgIHRoaXMuc3RyZWFtaW5nVXJsID0gbWV0YWRhdGEuc3RyZWFtaW5nVXJsO1xuICAgIHRoaXMuYXJ0aWZhY3RVcmwgPSBtZXRhZGF0YS5hcnRpZmFjdFVybDtcbiAgICB0aGlzLm1pbWVUeXBlID0gbWV0YWRhdGEuc3RyZWFtaW5nVXJsID8gJ2FwcGxpY2F0aW9uL3gtbXBlZ1VSTCcgOiBtZXRhZGF0YS5taW1lVHlwZTtcbiAgICB0aGlzLmFydGlmYWN0TWltZVR5cGUgPSBtZXRhZGF0YS5taW1lVHlwZTtcbiAgICB0aGlzLmlzQXZhaWxhYmxlTG9jYWxseSA9IG1ldGFkYXRhLmlzQXZhaWxhYmxlTG9jYWxseTtcbiAgICB0aGlzLnRyYWNlSWQgPSBjb25maWcudHJhY2VJZDtcbiAgICB0aGlzLmludGVyY2VwdGlvblBvaW50cyA9IG1ldGFkYXRhLmludGVyY2VwdGlvblBvaW50cztcbiAgICBpZiAoY29udGV4dC51c2VyRGF0YSkge1xuICAgICAgY29uc3QgeyB1c2VyRGF0YTogeyBmaXJzdE5hbWUsIGxhc3ROYW1lIH0gfSA9IGNvbnRleHQ7XG4gICAgICB0aGlzLnVzZXJOYW1lID0gZmlyc3ROYW1lID09PSBsYXN0TmFtZSA/IGZpcnN0TmFtZSA6IGAke2ZpcnN0TmFtZX0gJHtsYXN0TmFtZX1gO1xuICAgIH1cbiAgICB0aGlzLm1ldGFEYXRhID0ge1xuICAgICAgYWN0aW9uczogW1xuICAgICAgXSxcbiAgICAgIHZvbHVtZTogW10sXG4gICAgICBwbGF5QmFja1NwZWVkczogW10sXG4gICAgICB0b3RhbER1cmF0aW9uOiAwLFxuICAgICAgbXV0ZWQ6IHVuZGVmaW5lZCxcbiAgICAgIGN1cnJlbnREdXJhdGlvbjogdW5kZWZpbmVkLFxuICAgICAgdHJhbnNjcmlwdHM6IFtdXG4gICAgfTtcbiAgICB0aGlzLnRyYW5zY3JpcHRzID0gbWV0YWRhdGEudHJhbnNjcmlwdHMgPyBtZXRhZGF0YS50cmFuc2NyaXB0cyA6IFtdO1xuICAgIHRoaXMuc2hvd0Rvd25sb2FkUG9wdXAgPSBmYWxzZTtcbiAgICB0aGlzLmVuZFBhZ2VTZWVuID0gZmFsc2U7XG4gICAgaWYgKHRoaXMuaXNBdmFpbGFibGVMb2NhbGx5KSB7XG4gICAgICBjb25zdCBiYXNlUGF0aCA9IChtZXRhZGF0YS5zdHJlYW1pbmdVcmwpID8gKG1ldGFkYXRhLnN0cmVhbWluZ1VybCkgOiAobWV0YWRhdGEuYmFzZVBhdGggfHwgbWV0YWRhdGEuYmFzZURpcik7XG4gICAgICB0aGlzLnN0cmVhbWluZ1VybCA9IGAke2Jhc2VQYXRofS8ke21ldGFkYXRhLmFydGlmYWN0VXJsfWA7XG4gICAgICB0aGlzLm1pbWVUeXBlID0gbWV0YWRhdGEubWltZVR5cGU7XG4gICAgfVxuICB9XG4gIGhhbmRsZVRyYW5zY3JpcHRzRGF0YShzZWxlY3RlZFRyYW5zY3JpcHRzKSB7XG4gICAgdGhpcy5tZXRhRGF0YS50cmFuc2NyaXB0cyA9IHNlbGVjdGVkVHJhbnNjcmlwdHM7XG4gICAgaWYgKCFfLmlzQXJyYXkodGhpcy50cmFuc2NyaXB0cykpIHtcbiAgICAgIHRoaXMucmFpc2VFeGNlcHRpb25Mb2coJ0lOVkFMSURfVFJBTlNDUklQVF9EQVRBVFlQRScsICdUUkFOU0NSSVBUJywgbmV3IEVycm9yKCdUcmFuc2NyaXB0IGRhdGEgc2hvdWxkIGJlIGFycmF5JyksIHRoaXMudHJhY2VJZCk7XG4gICAgICByZXR1cm4gW107XG4gICAgfSBlbHNlIHtcbiAgICAgICAgICAgXy5mb3JFYWNoKHRoaXMudHJhbnNjcmlwdHMsICh2YWx1ZSkgPT4ge1xuICAgICAgICBpZiAoIShfLnNvbWUodGhpcy50cmFuc2NyaXB0cywgeyBsYW5ndWFnZTogdmFsdWUubGFuZ3VhZ2UsIGFydGlmYWN0VXJsOiB2YWx1ZS5hcnRpZmFjdFVybCAsXG4gICAgICAgICAgbGFuZ3VhZ2VDb2RlOiB2YWx1ZS5sYW5ndWFnZUNvZGUsIGlkZW50aWZpZXI6IHZhbHVlLmlkZW50aWZpZXJ9KSkpIHtcbiAgICAgICAgICB0aGlzLnJhaXNlRXhjZXB0aW9uTG9nKCdUUkFOU0NSSVBUX0RBVEFfTUlTU0lORycsICdUUkFOU0NSSVBUJyxcbiAgICAgICAgICAgbmV3IEVycm9yKCdUcmFuc2NyaXB0IG9iamVjdCBkb3NlIG5vdCBoYXZlIHJlcXVpcmVkIGZpZWxkcycpLCB0aGlzLnRyYWNlSWQpO1xuICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfSBlbHNlIGlmICghXy5pc0VtcHR5KHNlbGVjdGVkVHJhbnNjcmlwdHMpICYmXG4gICAgICAgICAgKCBfLmxhc3Qoc2VsZWN0ZWRUcmFuc2NyaXB0cykgIT09ICdvZmYnICYmICBfLmxhc3Qoc2VsZWN0ZWRUcmFuc2NyaXB0cykgPT09IHZhbHVlLmxhbmd1YWdlQ29kZSkpIHtcbiAgICAgICAgICB2YWx1ZS5kZWZhdWx0ID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnRyYW5zY3JpcHRzO1xuICB9XG4gIGFzeW5jIGdldFBsYXllck9wdGlvbnMoKSB7XG4gICAgaWYgKCF0aGlzLnN0cmVhbWluZ1VybCkge1xuICAgICAgcmV0dXJuIFt7IHNyYzogdGhpcy5hcnRpZmFjdFVybCwgdHlwZTogdGhpcy5hcnRpZmFjdE1pbWVUeXBlIH1dO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgdGhpcy5odHRwLmhlYWQodGhpcy5zdHJlYW1pbmdVcmwsIHsgcmVzcG9uc2VUeXBlOiAnYmxvYicgfSkudG9Qcm9taXNlKCkuY2F0Y2goZXJyb3IgPT4ge1xuICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbWF4LWxlblxuICAgICAgICB0aGlzLnJhaXNlRXhjZXB0aW9uTG9nKGVycm9yQ29kZS5zdHJlYW1pbmdVcmxTdXBwb3J0ICwgZXJyb3JNZXNzYWdlLnN0cmVhbWluZ1VybFN1cHBvcnQgLCBuZXcgRXJyb3IoYFN0cmVhbWluZyBVcmwgTm90IFN1cHBvcnRlZCAgJHt0aGlzLnN0cmVhbWluZ1VybH1gKSwgdGhpcy50cmFjZUlkKTtcbiAgICAgIH0pO1xuICAgICAgaWYgKGRhdGEpIHtcbiAgICAgICAgcmV0dXJuIFt7IHNyYzogdGhpcy5zdHJlYW1pbmdVcmwsIHR5cGU6IHRoaXMubWltZVR5cGUgfV07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gW3sgc3JjOiB0aGlzLmFydGlmYWN0VXJsLCB0eXBlOiB0aGlzLmFydGlmYWN0TWltZVR5cGUgfV07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ2V0TWFya2VycygpICB7XG4gICAgaWYgKHRoaXM/LmludGVyY2VwdGlvblBvaW50cz8uaXRlbXMpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IGludGVyY2VwdGlvblBvaW50cyA9IHRoaXMuaW50ZXJjZXB0aW9uUG9pbnRzO1xuICAgICAgICB0aGlzLnNob3dTY29yZSA9IHRydWU7XG4gICAgICAgIHJldHVybiBpbnRlcmNlcHRpb25Qb2ludHMuaXRlbXMubWFwKCh7aW50ZXJjZXB0aW9uUG9pbnQsIGlkZW50aWZpZXIsIHR5cGV9KSA9PiB7XG4gICAgICAgIHJldHVybiB7IHRpbWU6IGludGVyY2VwdGlvblBvaW50LCB0eXBlLCBpZGVudGlmaWVyLCBkdXJhdGlvbjogMyB9O1xuICAgICAgICB9KTtcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGVycm9yKTtcbiAgICAgICAgdGhpcy5yYWlzZUV4Y2VwdGlvbkxvZygnQ1BWMl9DT05UX0lOVEVSQ0VQVElPTl9QQVJTRScsICdlcnJvciBwYXJzaW5nIHRoZSBpbnRlY2VwdGlvbiBwb2ludHMgc3RyaW5nJywgZXJyb3IsICcnKTtcbiAgICAgICAgdGhpcy5zaG93U2NvcmUgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuXG4gIGdldFF1ZXN0aW9uU2V0KGlkZW50aWZpZXIpIHtcbiAgICBjb25zdCBjb250ZW50ID0gdGhpcy5jb250ZW50TWFwW2lkZW50aWZpZXJdO1xuICAgIGlmICghY29udGVudCkge1xuICAgICAgaWYgKCF0aGlzLnF1ZXN0aW9uQ3Vyc29yKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfSBlbHNlIHtcbiAgICAgcmV0dXJuIHRoaXMucXVlc3Rpb25DdXJzb3IuZ2V0UXVlc3Rpb25TZXQoaWRlbnRpZmllcilcbiAgICAgLnBpcGUobWFwKChyZXNwb25zZSkgPT4ge1xuICAgICAgICB0aGlzLmNvbnRlbnRNYXBbaWRlbnRpZmllcl0gPSByZXNwb25zZS5xdWVzdGlvblNldDtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGVudE1hcFtpZGVudGlmaWVyXTtcbiAgICAgICB9KSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBvZihjb250ZW50KTtcbiAgICB9XG4gIH1cblxuICBwcmVGZXRjaENvbnRlbnQoKSB7XG4gICAgY29uc3QgbmV4dE1hcmtlciA9IHRoaXMuZ2V0TmV4dE1hcmtlcigpO1xuICAgIGlmIChuZXh0TWFya2VyKSB7XG4gICAgICBjb25zdCBpZGVudGlmaWVyID0gbmV4dE1hcmtlci5pZGVudGlmaWVyO1xuICAgICAgdGhpcy5nZXRRdWVzdGlvblNldChuZXh0TWFya2VyLmlkZW50aWZpZXIpO1xuICAgIH1cbiAgfVxuXG4gIGdldFVuaXF1ZVZpc2l0ZWRMZW5ndGgoKSB7XG4gICAgY29uc3QgdW5pcVNlY29uZHNMaXN0ID0gW107XG4gICAgZm9yIChsZXQgc2xvdCBvZiB0aGlzLnBsYXllclRpbWVTbG90cykge1xuICAgICAgICBpZihzbG90WzBdIDwgc2xvdFsxXSkge1xuICAgICAgICAgIGxldCBzZWMgPSBzbG90WzBdO1xuICAgICAgICAgIHdoaWxlICggc2VjIDw9IHNsb3RbMV0pIHtcbiAgICAgICAgICAgIHNlYyA9IE1hdGguZmxvb3Ioc2VjKVxuICAgICAgICAgICAgaWYodW5pcVNlY29uZHNMaXN0LmluZGV4T2Yoc2VjKSA9PSAtMSAmJiBzZWMgIT0gMCkge1xuICAgICAgICAgICAgICB1bmlxU2Vjb25kc0xpc3QucHVzaChzZWMpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBzZWMgKz0gMVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICAgIHJldHVybiB1bmlxU2Vjb25kc0xpc3QubGVuZ3RoO1xuICB9XG5cbiAgZ2V0VmlzaXRlZExlbmd0aCgpIHtcbiAgICBjb25zdCBzZWNvbmRzTGlzdCA9IFtdO1xuICAgIGZvciAobGV0IHNsb3Qgb2YgdGhpcy5wbGF5ZXJUaW1lU2xvdHMpIHtcbiAgICAgICAgaWYoc2xvdFswXSA8IHNsb3RbMV0pIHtcbiAgICAgICAgICBsZXQgc2VjID0gc2xvdFswXTtcbiAgICAgICAgICB3aGlsZSAoIHNlYyA8PSBzbG90WzFdKSB7XG4gICAgICAgICAgICBzZWMgPSBNYXRoLmZsb29yKHNlYylcbiAgICAgICAgICAgIGlmKHNlYyAhPSAwKSB7XG4gICAgICAgICAgICAgIHNlY29uZHNMaXN0LnB1c2goc2VjKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc2VjICs9IDFcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgICByZXR1cm4gc2Vjb25kc0xpc3QubGVuZ3RoO1xuICB9XG5cbiAgZ2V0TmV4dE1hcmtlcigpIHtcbiAgICBjb25zdCBjdXJyZW50VGltZSA9IHRoaXMucGxheWVySW5zdGFuY2UuY3VycmVudFRpbWUoKTtcbiAgICBjb25zdCBtYXJrZXJzTGlzdCA9IHRoaXMuZ2V0TWFya2VycygpO1xuICAgIGlmICghbWFya2Vyc0xpc3QpIHsgcmV0dXJuIG51bGw7IH1cblxuICAgIHJldHVybiBtYXJrZXJzTGlzdC5maW5kKG1hcmtlciA9PiB7XG4gICAgICBjb25zdCBtYXJrZXJUaW1lID0gbWFya2VyLnRpbWU7XG4gICAgICByZXR1cm4gbWFya2VyVGltZSA+IGN1cnJlbnRUaW1lO1xuICAgIH0pO1xuICB9XG5cbiAgcmFpc2VTdGFydEV2ZW50KGV2ZW50KSB7XG4gICAgY29uc3QgZHVyYXRpb24gPSBuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIHRoaXMuUGxheWVyTG9hZFN0YXJ0ZWRBdDtcbiAgICBjb25zdCBzdGFydEV2ZW50ID0ge1xuICAgICAgZWlkOiAnU1RBUlQnLFxuICAgICAgdmVyOiB0aGlzLnZlcnNpb24sXG4gICAgICBlZGF0YToge1xuICAgICAgICB0eXBlOiAnU1RBUlQnLFxuICAgICAgICBtb2RlOiAncGxheScsXG4gICAgICAgIGR1cmF0aW9uXG4gICAgICB9LFxuICAgICAgbWV0YURhdGE6IHRoaXMubWV0YURhdGFcbiAgICB9O1xuICAgIHRoaXMucGxheWVyRXZlbnQuZW1pdChzdGFydEV2ZW50KTtcbiAgICB0aGlzLnZpZGVvUGxheWVyU2VydmljZS5zdGFydChkdXJhdGlvbik7XG4gICAgdGhpcy5QbGF5ZXJMb2FkU3RhcnRlZEF0ID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gIH1cblxuICBjYWxjdWxhdGVTY29yZSgpIHtcbiAgICB0aGlzLnNjb3JlT2J0YWluZWQgPSAgT2JqZWN0LnZhbHVlcyh0aGlzLmludGVyY2VwdGlvblJlc3BvbnNlcykucmVkdWNlKFxuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9kb3Qtbm90YXRpb25cbiAgICAgIChhY2MsIHJlc3BvbnNlKSA9PiBhY2MgKyByZXNwb25zZVsnc2NvcmUnXSAsIDApO1xuICB9XG5cbiAgcmFpc2VFbmRFdmVudChpc09uUGxheUludGVycnVwdCA9IGZhbHNlKSB7XG5cbiAgICBpZiAoIXRoaXMuaXNFbmRFdmVudFJhaXNlZCkge1xuICAgICAgdGhpcy5jYWxjdWxhdGVTY29yZSgpO1xuICAgICAgY29uc3QgZHVyYXRpb24gPSBuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIHRoaXMuUGxheWVyTG9hZFN0YXJ0ZWRBdDtcbiAgICAgIGNvbnN0IGVuZEV2ZW50ID0ge1xuICAgICAgICBlaWQ6ICdFTkQnLFxuICAgICAgICB2ZXI6IHRoaXMudmVyc2lvbixcbiAgICAgICAgZWRhdGE6IHtcbiAgICAgICAgICB0eXBlOiAnRU5EJyxcbiAgICAgICAgICBjdXJyZW50VGltZTogdGhpcy5jdXJyZW50bGVuZ3RoLFxuICAgICAgICAgIHRvdGFsVGltZTogdGhpcy50b3RhbExlbmd0aCxcbiAgICAgICAgICBkdXJhdGlvblxuICAgICAgICB9LFxuICAgICAgICBtZXRhRGF0YTogdGhpcy5tZXRhRGF0YVxuICAgICAgfTtcbiAgICAgIHRoaXMucGxheWVyRXZlbnQuZW1pdChlbmRFdmVudCk7XG4gICAgICBcbiAgICAgIGlmKGlzT25QbGF5SW50ZXJydXB0KSB7XG4gICAgICAgIHRoaXMucGxheWVyVGltZVNsb3RzLnB1c2goW3RoaXMucGxheUJpdFN0YXJ0VGltZSwgdGhpcy5jdXJyZW50bGVuZ3RoXSk7XG4gICAgICB9XG4gICAgICB0aGlzLnVuaXF1ZVZpc2l0ZWRMZW5ndGggPSB0aGlzLmdldFVuaXF1ZVZpc2l0ZWRMZW5ndGgoKTtcbiAgICAgIGlmKHRoaXMudW5pcXVlVmlzaXRlZExlbmd0aCA+IHRoaXMudG90YWxMZW5ndGgpIHtcbiAgICAgICAgdGhpcy51bmlxdWVWaXNpdGVkTGVuZ3RoID0gdGhpcy50b3RhbExlbmd0aDtcbiAgICAgIH1cbiAgICAgIHRoaXMudmlzaXRlZExlbmd0aCA9IHRoaXMuZ2V0VmlzaXRlZExlbmd0aCgpO1xuICAgICAgdGhpcy50aW1lU3BlbnQgPSB0aGlzLnV0aWxTZXJ2aWNlLmdldFRpbWVTcGVudFRleHQoXy5mbG9vcih0aGlzLnRvdGFsTGVuZ3RoKSk7XG4gICAgICBcbiAgICAgIHRoaXMudmlkZW9QbGF5ZXJTZXJ2aWNlLmVuZChcbiAgICAgICAgZHVyYXRpb24sXG4gICAgICAgIHRoaXMudG90YWxMZW5ndGgsXG4gICAgICAgIHRoaXMuY3VycmVudGxlbmd0aCxcbiAgICAgICAgdGhpcy5lbmRQYWdlU2VlbixcbiAgICAgICAgdGhpcy50b3RhbFNlZWtlZExlbmd0aCxcbiAgICAgICAgdGhpcy52aXNpdGVkTGVuZ3RoLFxuICAgICAgICB0aGlzLnNjb3JlT2J0YWluZWQsXG4gICAgICAgIHRoaXMudW5pcXVlVmlzaXRlZExlbmd0aFxuICAgICAgKTtcbiAgICAgIHRoaXMuaXNFbmRFdmVudFJhaXNlZCA9IHRydWU7XG4gICAgfVxuICB9XG5cblxuICByYWlzZUhlYXJ0QmVhdEV2ZW50KHR5cGU6IHN0cmluZywgZXh0cmFWYWx1ZXM/KSB7XG4gICAgaWYgKHR5cGUgPT09ICdSRVBMQVknKSB7XG4gICAgICB0aGlzLmludGVyY2VwdGlvblJlc3BvbnNlcyA9IHt9O1xuICAgICAgdGhpcy5zaG93U2NvcmUgPSBmYWxzZTtcbiAgICAgIHRoaXMuc2NvcmVPYnRhaW5lZCA9IDA7XG4gICAgICB0aGlzLnBsYXllclRpbWVTbG90cyA9IFtdO1xuICAgICAgdGhpcy5wbGF5Qml0RW5kVGltZSA9IDA7XG4gICAgICB0aGlzLnBsYXlCaXRTdGFydFRpbWUgPSAwO1xuICAgIH1cbiAgICBjb25zdCBoZWFyQmVhdEV2ZW50ID0ge1xuICAgICAgZWlkOiAnSEVBUlRCRUFUJyxcbiAgICAgIHZlcjogdGhpcy52ZXJzaW9uLFxuICAgICAgZWRhdGE6IHtcbiAgICAgICAgdHlwZSxcbiAgICAgICAgY3VycmVudFBhZ2U6ICd2aWRlb3N0YWdlJyxcbiAgICAgICAgZXh0cmE6IGV4dHJhVmFsdWVzXG4gICAgICB9LFxuICAgICAgbWV0YURhdGE6IHRoaXMubWV0YURhdGFcbiAgICB9O1xuICAgIHRoaXMucGxheWVyRXZlbnQuZW1pdChoZWFyQmVhdEV2ZW50KTtcbiAgICB0aGlzLnZpZGVvUGxheWVyU2VydmljZS5oZWFydEJlYXQoaGVhckJlYXRFdmVudCk7XG4gICAgY29uc3QgaW50ZXJhY3RJdGVtcyA9IFsnUExBWScsICdQQVVTRScsICdFWElUJywgJ1ZPTFVNRV9DSEFOR0UnLCAnRFJBRycsXG4gICAgICAnUkFURV9DSEFOR0UnLCAnQ0xPU0VfRE9XTkxPQUQnLCAnRE9XTkxPQUQnLCAnTkFWSUdBVEVfVE9fUEFHRScsXG4gICAgICAnTkVYVCcsICdPUEVOX01FTlUnLCAnUFJFVklPVVMnLCAnQ0xPU0VfTUVOVScsICdET1dOTE9BRF9NRU5VJywgJ0RPV05MT0FEX1BPUFVQX0NMT1NFJywgJ0RPV05MT0FEX1BPUFVQX0NBTkNFTCcsXG4gICAgICAnU0hBUkUnLCAnUkVQTEFZJywgJ0ZPUldBUkQnLCAnQkFDS1dBUkQnLCAnRlVMTFNDUkVFTicsICdORVhUX0NPTlRFTlRfUExBWScsICdUUkFOU0NSSVBUX0xBTkdVQUdFX09GRicsXG4gICAgICAnVFJBTlNDUklQVF9MQU5HVUFHRV9TRUxFQ1RFRCcsICdWSURFT19NQVJLRVJfU0VMRUNURUQnXG4gICAgXTtcbiAgICBpZiAoaW50ZXJhY3RJdGVtcy5pbmNsdWRlcyh0eXBlKSkge1xuICAgICAgdGhpcy52aWRlb1BsYXllclNlcnZpY2UuaW50ZXJhY3QodHlwZS50b0xvd2VyQ2FzZSgpLCAndmlkZW9zdGFnZScsIGV4dHJhVmFsdWVzKTtcbiAgICB9XG4gIH1cblxuICByYWlzZUltcHJlc3Npb25FdmVudChwYWdlSWQ6IHN0cmluZywgY2RhdGE6IGFueSA9IHt9KSB7XG4gICAgdGhpcy52aWRlb1BsYXllclNlcnZpY2UuaW1wcmVzc2lvbihwYWdlSWQsIGNkYXRhKTtcbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tc2hhZG93XG4gIHJhaXNlRXhjZXB0aW9uTG9nKGVycm9yQ29kZTogc3RyaW5nLCBlcnJvclR5cGU6IHN0cmluZywgc3RhY2t0cmFjZSwgdHJhY2VJZCkge1xuICAgIGNvbnN0IGV4Y2VwdGlvbkxvZ0V2ZW50ID0ge1xuICAgICAgZWlkOiAnRVJST1InLFxuICAgICAgZWRhdGE6IHtcbiAgICAgICAgZXJyOiBlcnJvckNvZGUsXG4gICAgICAgIGVycnR5cGU6IGVycm9yVHlwZSxcbiAgICAgICAgcmVxdWVzdGlkOiB0cmFjZUlkIHx8ICcnLFxuICAgICAgICBzdGFja3RyYWNlOiAoc3RhY2t0cmFjZSAmJiBzdGFja3RyYWNlLnRvU3RyaW5nKCkpIHx8ICcnLFxuICAgICAgfVxuICAgIH07XG4gICAgdGhpcy5wbGF5ZXJFdmVudC5lbWl0KGV4Y2VwdGlvbkxvZ0V2ZW50KTtcbiAgICB0aGlzLnZpZGVvUGxheWVyU2VydmljZS5lcnJvcihlcnJvckNvZGUgLCBlcnJvclR5cGUgLCBzdGFja3RyYWNlKTtcbiAgfVxuXG59XG4iXX0=