dictrigyn-video-player
Version:
Contains Video player library components powered by angular. These components are designed to be used in sunbird consumption platforms *(mobile app, web portal, offline desktop app)* to drive reusability, maintainability hence reducing the redundant devel
445 lines • 41.9 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: lib/services/viewer.service.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { __awaiter } from "tslib";
import { HttpClient } from '@angular/common/http';
import { EventEmitter, Injectable, Optional } from '@angular/core';
import { SunbirdVideoPlayerService } from '../sunbird-video-player.service';
import { UtilService } from './util.service';
import { errorCode, errorMessage } from '@dicdikshaorg/player-sdk-v9';
import { QuestionCursor } from '@project-sunbird/sunbird-quml-player-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 {
/**
* @param {?} videoPlayerService
* @param {?} utilService
* @param {?} http
* @param {?} questionCursor
*/
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.sidebarMenuEvent = new EventEmitter();
this.isAvailableLocally = false;
this.interceptionResponses = {};
this.showScore = false;
this.scoreObtained = 0;
this.contentMap = {};
this.isEndEventRaised = false;
this.PlayerLoadStartedAt = new Date().getTime();
}
/**
* @param {?} __0
* @return {?}
*/
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) {
/** @type {?} */
const basePath = (metadata.streamingUrl) ? (metadata.streamingUrl) : (metadata.basePath || metadata.baseDir);
this.streamingUrl = `${basePath}/${metadata.artifactUrl}`;
this.mimeType = metadata.mimeType;
}
}
/**
* @param {?} selectedTranscripts
* @return {?}
*/
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, (/**
* @param {?} value
* @return {?}
*/
(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;
}
/**
* @return {?}
*/
getPlayerOptions() {
return __awaiter(this, void 0, void 0, function* () {
if (!this.streamingUrl) {
return [{ src: this.artifactUrl, type: this.artifactMimeType }];
}
else {
/** @type {?} */
const data = yield this.http.head(this.streamingUrl, { responseType: 'blob' }).toPromise().catch((/**
* @param {?} error
* @return {?}
*/
error => {
// tslint:disable-next-line:max-line-length
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 }];
}
}
});
}
/**
* @return {?}
*/
getMarkers() {
var _a, _b;
if ((_b = (_a = this) === null || _a === void 0 ? void 0 : _a.interceptionPoints) === null || _b === void 0 ? void 0 : _b.items) {
try {
/** @type {?} */
const interceptionPoints = this.interceptionPoints;
this.showScore = true;
return interceptionPoints.items.map((/**
* @param {?} __0
* @return {?}
*/
({ 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;
}
/**
* @param {?} identifier
* @return {?}
*/
getQuestionSet(identifier) {
/** @type {?} */
const content = this.contentMap[identifier];
if (!content) {
if (!this.questionCursor) {
return null;
}
else {
return this.questionCursor.getQuestionSet(identifier)
.pipe(map((/**
* @param {?} response
* @return {?}
*/
(response) => {
this.contentMap[identifier] = response.questionSet;
return this.contentMap[identifier];
})));
}
}
else {
return of(content);
}
}
/**
* @return {?}
*/
preFetchContent() {
/** @type {?} */
const nextMarker = this.getNextMarker();
if (nextMarker) {
/** @type {?} */
const identifier = nextMarker.identifier;
this.getQuestionSet(nextMarker.identifier);
}
}
/**
* @return {?}
*/
getNextMarker() {
/** @type {?} */
const currentTime = this.playerInstance.currentTime();
/** @type {?} */
const markersList = this.getMarkers();
if (!markersList) {
return null;
}
return markersList.find((/**
* @param {?} marker
* @return {?}
*/
marker => {
/** @type {?} */
const markerTime = marker.time;
return markerTime > currentTime;
}));
}
/**
* @param {?} event
* @return {?}
*/
raiseStartEvent(event) {
/** @type {?} */
const duration = new Date().getTime() - this.PlayerLoadStartedAt;
/** @type {?} */
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();
}
/**
* @return {?}
*/
calculateScore() {
this.scoreObtained = Object.values(this.interceptionResponses).reduce((
// tslint:disable-next-line:no-string-literal
/**
* @param {?} acc
* @param {?} response
* @return {?}
*/
(acc, response) => acc + response['score']), 0);
}
/**
* @return {?}
*/
raiseEndEvent() {
if (!this.isEndEventRaised) {
this.calculateScore();
/** @type {?} */
const duration = new Date().getTime() - this.PlayerLoadStartedAt;
/** @type {?} */
const endEvent = {
eid: 'END',
ver: this.version,
edata: {
type: 'END',
currentTime: this.currentlength,
totalTime: this.totalLength,
duration
},
metaData: this.metaData
};
this.playerEvent.emit(endEvent);
this.timeSpent = this.utilService.getTimeSpentText(this.visitedLength);
this.videoPlayerService.end(duration, this.totalLength, this.currentlength, this.endPageSeen, this.totalSeekedLength, this.visitedLength / 1000, this.scoreObtained);
this.isEndEventRaised = true;
}
}
/**
* @param {?} type
* @param {?=} extraValues
* @return {?}
*/
raiseHeartBeatEvent(type, extraValues) {
if (type === 'REPLAY') {
this.interceptionResponses = {};
this.showScore = false;
this.scoreObtained = 0;
}
/** @type {?} */
const hearBeatEvent = {
eid: 'HEARTBEAT',
ver: this.version,
edata: {
type,
currentPage: 'videostage',
extra: extraValues
},
metaData: this.metaData
};
this.playerEvent.emit(hearBeatEvent);
this.videoPlayerService.heartBeat(hearBeatEvent);
/** @type {?} */
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);
}
}
/**
* @param {?} pageId
* @param {?=} cdata
* @return {?}
*/
raiseImpressionEvent(pageId, cdata = {}) {
this.videoPlayerService.impression(pageId, cdata);
}
// tslint:disable-next-line:no-shadowed-variable
/**
* @param {?} errorCode
* @param {?} errorType
* @param {?} stacktrace
* @param {?} traceId
* @return {?}
*/
raiseExceptionLog(errorCode, errorType, stacktrace, traceId) {
/** @type {?} */
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);
}
}
ViewerService.decorators = [
{ type: Injectable, args: [{
providedIn: 'root'
},] }
];
/** @nocollapse */
ViewerService.ctorParameters = () => [
{ type: SunbirdVideoPlayerService },
{ type: UtilService },
{ type: HttpClient },
{ type: QuestionCursor, decorators: [{ type: Optional }] }
];
/** @nocollapse */ ViewerService.ɵprov = i0.ɵɵdefineInjectable({ factory: function ViewerService_Factory() { return new ViewerService(i0.ɵɵinject(i1.SunbirdVideoPlayerService), i0.ɵɵinject(i2.UtilService), i0.ɵɵinject(i3.HttpClient), i0.ɵɵinject(i4.QuestionCursor, 8)); }, token: ViewerService, providedIn: "root" });
if (false) {
/** @type {?} */
ViewerService.prototype.endPageSeen;
/** @type {?} */
ViewerService.prototype.timeSpent;
/**
* @type {?}
* @private
*/
ViewerService.prototype.version;
/** @type {?} */
ViewerService.prototype.playerEvent;
/** @type {?} */
ViewerService.prototype.contentName;
/** @type {?} */
ViewerService.prototype.showDownloadPopup;
/** @type {?} */
ViewerService.prototype.streamingUrl;
/** @type {?} */
ViewerService.prototype.mimeType;
/** @type {?} */
ViewerService.prototype.artifactMimeType;
/** @type {?} */
ViewerService.prototype.userName;
/** @type {?} */
ViewerService.prototype.metaData;
/** @type {?} */
ViewerService.prototype.PlayerLoadStartedAt;
/** @type {?} */
ViewerService.prototype.totalLength;
/** @type {?} */
ViewerService.prototype.currentlength;
/** @type {?} */
ViewerService.prototype.totalSeekedLength;
/** @type {?} */
ViewerService.prototype.artifactUrl;
/** @type {?} */
ViewerService.prototype.visitedLength;
/** @type {?} */
ViewerService.prototype.sidebarMenuEvent;
/** @type {?} */
ViewerService.prototype.traceId;
/** @type {?} */
ViewerService.prototype.isAvailableLocally;
/** @type {?} */
ViewerService.prototype.interceptionPoints;
/** @type {?} */
ViewerService.prototype.interceptionResponses;
/** @type {?} */
ViewerService.prototype.showScore;
/** @type {?} */
ViewerService.prototype.scoreObtained;
/** @type {?} */
ViewerService.prototype.maxScore;
/** @type {?} */
ViewerService.prototype.playerInstance;
/** @type {?} */
ViewerService.prototype.contentMap;
/** @type {?} */
ViewerService.prototype.isEndEventRaised;
/** @type {?} */
ViewerService.prototype.transcripts;
/**
* @type {?}
* @private
*/
ViewerService.prototype.videoPlayerService;
/**
* @type {?}
* @private
*/
ViewerService.prototype.utilService;
/**
* @type {?}
* @private
*/
ViewerService.prototype.http;
/** @type {?} */
ViewerService.prototype.questionCursor;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlld2VyLnNlcnZpY2UuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9kaWN0cmlneW4tdmlkZW8tcGxheWVyLyIsInNvdXJjZXMiOlsibGliL3NlcnZpY2VzL3ZpZXdlci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFbkUsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFDNUUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxTQUFTLEVBQUcsWUFBWSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDdkUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHlDQUF5QyxDQUFDO0FBQ3pFLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDMUIsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3JDLE9BQU8sS0FBSyxDQUFDLE1BQU0sV0FBVyxDQUFDOzs7Ozs7QUFLL0IsTUFBTSxPQUFPLGFBQWE7Ozs7Ozs7SUErQnhCLFlBQW9CLGtCQUE2QyxFQUM3QyxXQUF3QixFQUN4QixJQUFnQixFQUNMLGNBQThCO1FBSHpDLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBMkI7UUFDN0MsZ0JBQVcsR0FBWCxXQUFXLENBQWE7UUFDeEIsU0FBSSxHQUFKLElBQUksQ0FBWTtRQUNMLG1CQUFjLEdBQWQsY0FBYyxDQUFnQjtRQWhDdEQsZ0JBQVcsR0FBRyxLQUFLLENBQUM7UUFDcEIsY0FBUyxHQUFHLEtBQUssQ0FBQztRQUNqQixZQUFPLEdBQUcsS0FBSyxDQUFDO1FBQ2pCLGdCQUFXLEdBQUcsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQWN0QyxxQkFBZ0IsR0FBRyxJ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LGtDQUF5Qjs7SUFDekIsc0NBQThCOztJQUM5QixpQ0FBd0I7O0lBQ3hCLHVDQUEyQjs7SUFDM0IsbUNBQXVCOztJQUN2Qix5Q0FBZ0M7O0lBQ2hDLG9DQUFnQzs7Ozs7SUFDcEIsMkNBQXFEOzs7OztJQUNyRCxvQ0FBZ0M7Ozs7O0lBQ2hDLDZCQUF3Qjs7SUFDeEIsdUNBQWlEIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcclxuaW1wb3J0IHsgRXZlbnRFbWl0dGVyLCBJbmplY3RhYmxlLCBPcHRpb25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBQbGF5ZXJDb25maWcsIFRyYW5zY3JpcHRzIH0gZnJvbSAnLi4vcGxheWVySW50ZXJmYWNlcyc7XHJcbmltcG9ydCB7IFN1bmJpcmRWaWRlb1BsYXllclNlcnZpY2UgfSBmcm9tICcuLi9zdW5iaXJkLXZpZGVvLXBsYXllci5zZXJ2aWNlJztcclxuaW1wb3J0IHsgVXRpbFNlcnZpY2UgfSBmcm9tICcuL3V0aWwuc2VydmljZSc7XHJcbmltcG9ydCB7IGVycm9yQ29kZSAsIGVycm9yTWVzc2FnZSB9IGZyb20gJ0BkaWNkaWtzaGFvcmcvcGxheWVyLXNkay12OSc7XHJcbmltcG9ydCB7IFF1ZXN0aW9uQ3Vyc29yIH0gZnJvbSAnQHByb2plY3Qtc3VuYmlyZC9zdW5iaXJkLXF1bWwtcGxheWVyLXY5JztcclxuaW1wb3J0IHsgb2YgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgbWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5pbXBvcnQgKiBhcyBfIGZyb20gJ2xvZGFzaC1lcyc7XHJcblxyXG5ASW5qZWN0YWJsZSh7XHJcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBWaWV3ZXJTZXJ2aWNlIHtcclxuXHJcbiAgcHVibGljIGVuZFBhZ2VTZWVuID0gZmFsc2U7XHJcbiAgcHVibGljIHRpbWVTcGVudCA9ICcwOjAnO1xyXG4gIHByaXZhdGUgdmVyc2lvbiA9ICcxLjAnO1xyXG4gIHB1YmxpYyBwbGF5ZXJFdmVudCA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xyXG4gIHB1YmxpYyBjb250ZW50TmFtZTogc3RyaW5nO1xyXG4gIHB1YmxpYyBzaG93RG93bmxvYWRQb3B1cDogYm9vbGVhbjtcclxuICBwdWJsaWMgc3RyZWFtaW5nVXJsOiBzdHJpbmc7XHJcbiAgcHVibGljIG1pbWVUeXBlOiBzdHJpbmc7XHJcbiAgcHVibGljIGFydGlmYWN0TWltZVR5cGU6IHN0cmluZztcclxuICBwdWJsaWMgdXNlck5hbWU6IHN0cmluZztcclxuICBwdWJsaWMgbWV0YURhdGE6IGFueTtcclxuICBwdWJsaWMgUGxheWVyTG9hZFN0YXJ0ZWRBdDogbnVtYmVyO1xyXG4gIHB1YmxpYyB0b3RhbExlbmd0aDtcclxuICBwdWJsaWMgY3VycmVudGxlbmd0aDtcclxuICBwdWJsaWMgdG90YWxTZWVrZWRMZW5ndGg7XHJcbiAgcHVibGljIGFydGlmYWN0VXJsO1xyXG4gIHB1YmxpYyB2aXNpdGVkTGVuZ3RoO1xyXG4gIHB1YmxpYyBzaWRlYmFyTWVudUV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XHJcbiAgcHVibGljIHRyYWNlSWQ6IHN0cmluZztcclxuICBwdWJsaWMgaXNBdmFpbGFibGVMb2NhbGx5ID0gZmFsc2U7XHJcbiAgcHVibGljIGludGVyY2VwdGlvblBvaW50czogYW55O1xyXG4gIHB1YmxpYyBpbnRlcmNlcHRpb25SZXNwb25zZXM6IGFueSA9IHt9O1xyXG4gIHB1YmxpYyBzaG93U2NvcmUgPSBmYWxzZTtcclxuICBwdWJsaWMgc2NvcmVPYnRhaW5lZDogYW55ID0gMDtcclxuICBwdWJsaWMgbWF4U2NvcmU6IG51bWJlcjtcclxuICBwdWJsaWMgcGxheWVySW5zdGFuY2U6IGFueTtcclxuICBwdWJsaWMgY29udGVudE1hcCA9IHt9O1xyXG4gIHB1YmxpYyBpc0VuZEV2ZW50UmFpc2VkID0gZmFsc2U7XHJcbiAgcHVibGljIHRyYW5zY3JpcHRzOiBUcmFuc2NyaXB0cztcclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHZpZGVvUGxheWVyU2VydmljZTogU3VuYmlyZFZpZGVvUGxheWVyU2VydmljZSxcclxuICAgICAgICAgICAgICBwcml2YXRlIHV0aWxTZXJ2aWNlOiBVdGlsU2VydmljZSxcclxuICAgICAgICAgICAgICBwcml2YXRlIGh0dHA6IEh0dHBDbGllbnQsXHJcbiAgICAgICAgICAgICAgQE9wdGlvbmFsKCkgcHVibGljIHF1ZXN0aW9uQ3Vyc29yOiBRdWVzdGlvbkN1cnNvcikge1xyXG4gICAgdGhpcy5QbGF5ZXJMb2FkU3RhcnRlZEF0ID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XHJcbiAgfVxyXG5cclxuICBpbml0aWFsaXplKHsgY29udGV4dCwgY29uZmlnLCBtZXRhZGF0YSB9OiBQbGF5ZXJDb25maWcpIHtcclxuICAgIHRoaXMuY29udGVudE5hbWUgPSBtZXRhZGF0YS5uYW1lO1xyXG4gICAgdGhpcy5pc0F2YWlsYWJsZUxvY2FsbHkgPSBtZXRhZGF0YS5pc0F2YWlsYWJsZUxvY2FsbHk7XHJcbiAgICB0aGlzLnN0cmVhbWluZ1VybCA9IG1ldGFkYXRhLnN0cmVhbWluZ1VybDtcclxuICAgIHRoaXMuYXJ0aWZhY3RVcmwgPSBtZXRhZGF0YS5hcnRpZmFjdFVybDtcclxuICAgIHRoaXMubWltZVR5cGUgPSBtZXRhZGF0YS5zdHJlYW1pbmdVcmwgPyAnYXBwbGljYXRpb24veC1tcGVnVVJMJyA6IG1ldGFkYXRhLm1pbWVUeXBlO1xyXG4gICAgdGhpcy5hcnRpZmFjdE1pbWVUeXBlID0gbWV0YWRhdGEubWltZVR5cGU7XHJcbiAgICB0aGlzLmlzQXZhaWxhYmxlTG9jYWxseSA9IG1ldGFkYXRhLmlzQXZhaWxhYmxlTG9jYWxseTtcclxuICAgIHRoaXMudHJhY2VJZCA9IGNvbmZpZy50cmFjZUlkO1xyXG4gICAgdGhpcy5pbnRlcmNlcHRpb25Qb2ludHMgPSBtZXRhZGF0YS5pbnRlcmNlcHRpb25Qb2ludHM7XHJcbiAgICBpZiAoY29udGV4dC51c2VyRGF0YSkge1xyXG4gICAgICBjb25zdCB7IHVzZXJEYXRhOiB7IGZpcnN0TmFtZSwgbGFzdE5hbWUgfSB9ID0gY29udGV4dDtcclxuICAgICAgdGhpcy51c2VyTmFtZSA9IGZpcnN0TmFtZSA9PT0gbGFzdE5hbWUgPyBmaXJzdE5hbWUgOiBgJHtmaXJzdE5hbWV9ICR7bGFzdE5hbWV9YDtcclxuICAgIH1cclxuICAgIHRoaXMubWV0YURhdGEgPSB7XHJcbiAgICAgIGFjdGlvbnM6IFtcclxuICAgICAgXSxcclxuICAgICAgdm9sdW1lOiBbXSxcclxuICAgICAgcGxheUJhY2tTcGVlZHM6IFtdLFxyXG4gICAgICB0b3RhbER1cmF0aW9uOiAwLFxyXG4gICAgICBtdXRlZDogdW5kZWZpbmVkLFxyXG4gICAgICBjdXJyZW50RHVyYXRpb246IHVuZGVmaW5lZCxcclxuICAgICAgdHJhbnNjcmlwdHM6IFtdXHJcbiAgICB9O1xyXG4gICAgdGhpcy50cmFuc2NyaXB0cyA9IG1ldGFkYXRhLnRyYW5zY3JpcHRzID8gbWV0YWRhdGEudHJhbnNjcmlwdHMgOiBbXTtcclxuICAgIHRoaXMuc2hvd0Rvd25sb2FkUG9wdXAgPSBmYWxzZTtcclxuICAgIHRoaXMuZW5kUGFnZVNlZW4gPSBmYWxzZTtcclxuICAgIGlmICh0aGlzLmlzQXZhaWxhYmxlTG9jYWxseSkge1xyXG4gICAgICBjb25zdCBiYXNlUGF0aCA9IChtZXRhZGF0YS5zdHJlYW1pbmdVcmwpID8gKG1ldGFkYXRhLnN0cmVhbWluZ1VybCkgOiAobWV0YWRhdGEuYmFzZVBhdGggfHwgbWV0YWRhdGEuYmFzZURpcik7XHJcbiAgICAgIHRoaXMuc3RyZWFtaW5nVXJsID0gYCR7YmFzZVBhdGh9LyR7bWV0YWRhdGEuYXJ0aWZhY3RVcmx9YDtcclxuICAgICAgdGhpcy5taW1lVHlwZSA9IG1ldGFkYXRhLm1pbWVUeXBlO1xyXG4gICAgfVxyXG4gIH1cclxuICBoYW5kbGVUcmFuc2NyaXB0c0RhdGEoc2VsZWN0ZWRUcmFuc2NyaXB0cykge1xyXG4gICAgdGhpcy5tZXRhRGF0YS50cmFuc2NyaXB0cyA9IHNlbGVjdGVkVHJhbnNjcmlwdHM7XHJcbiAgICBpZiAoIV8uaXNBcnJheSh0aGlzLnRyYW5zY3JpcHRzKSkge1xyXG4gICAgICB0aGlzLnJhaXNlRXhjZXB0aW9uTG9nKCdJTlZBTElEX1RSQU5TQ1JJUFRfREFUQVRZUEUnLCAnVFJBTlNDUklQVCcsIG5ldyBFcnJvcignVHJhbnNjcmlwdCBkYXRhIHNob3VsZCBiZSBhcnJheScpLCB0aGlzLnRyYWNlSWQpO1xyXG4gICAgICByZXR1cm4gW107XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgIF8uZm9yRWFjaCh0aGlzLnRyYW5zY3JpcHRzLCAodmFsdWUpID0+IHtcclxuICAgICAgICBpZiAoIShfLnNvbWUodGhpcy50cmFuc2NyaXB0cywgeyBsYW5ndWFnZTogdmFsdWUubGFuZ3VhZ2UsIGFydGlmYWN0VXJsOiB2YWx1ZS5hcnRpZmFjdFVybCAsXHJcbiAgICAgICAgICBsYW5ndWFnZUNvZGU6IHZhbHVlLmxhbmd1YWdlQ29kZSwgaWRlbnRpZmllcjogdmFsdWUuaWRlbnRpZmllcn0pKSkge1xyXG4gICAgICAgICAgdGhpcy5yYWlzZUV4Y2VwdGlvbkxvZygnVFJBTlNDUklQVF9EQVRBX01JU1NJTkcnLCAnVFJBTlNDUklQVCcsXHJcbiAgICAgICAgICAgbmV3IEVycm9yKCdUcmFuc2NyaXB0IG9iamVjdCBkb3NlIG5vdCBoYXZlIHJlcXVpcmVkIGZpZWxkcycpLCB0aGlzLnRyYWNlSWQpO1xyXG4gICAgICAgICAgcmV0dXJuIFtdO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoIV8uaXNFbXB0eShzZWxlY3RlZFRyYW5zY3JpcHRzKSAmJlxyXG4gICAgICAgICAgKCBfLmxhc3Qoc2VsZWN0ZWRUcmFuc2NyaXB0cykgIT09ICdvZmYnICYmICBfLmxhc3Qoc2VsZWN0ZWRUcmFuc2NyaXB0cykgPT09IHZhbHVlLmxhbmd1YWdlQ29kZSkpIHtcclxuICAgICAgICAgIHZhbHVlLmRlZmF1bHQgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy50cmFuc2NyaXB0cztcclxuICB9XHJcbiAgYXN5bmMgZ2V0UGxheWVyT3B0aW9ucygpIHtcclxuICAgIGlmICghdGhpcy5zdHJlYW1pbmdVcmwpIHtcclxuICAgICAgcmV0dXJuIFt7IHNyYzogdGhpcy5hcnRpZmFjdFVybCwgdHlwZTogdGhpcy5hcnRpZmFjdE1pbWVUeXBlIH1dO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHRoaXMuaHR0cC5oZWFkKHRoaXMuc3RyZWFtaW5nVXJsLCB7IHJlc3BvbnNlVHlwZTogJ2Jsb2InIH0pLnRvUHJvbWlzZSgpLmNhdGNoKGVycm9yID0+IHtcclxuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6bWF4LWxpbmUtbGVuZ3RoXHJcbiAgICAgICAgdGhpcy5yYWlzZUV4Y2VwdGlvbkxvZyhlcnJvckNvZGUuc3RyZWFtaW5nVXJsU3VwcG9ydCAsIGVycm9yTWVzc2FnZS5zdHJlYW1pbmdVcmxTdXBwb3J0ICwgbmV3IEVycm9yKGBTdHJlYW1pbmcgVXJsIE5vdCBTdXBwb3J0ZWQgICR7dGhpcy5zdHJlYW1pbmdVcmx9YCksIHRoaXMudHJhY2VJZCk7XHJcbiAgICAgIH0pO1xyXG4gICAgICBpZiAoZGF0YSkge1xyXG4gICAgICAgIHJldHVybiBbeyBzcmM6IHRoaXMuc3RyZWFtaW5nVXJsLCB0eXBlOiB0aGlzLm1pbWVUeXBlIH1dO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHJldHVybiBbeyBzcmM6IHRoaXMuYXJ0aWZhY3RVcmwsIHR5cGU6IHRoaXMuYXJ0aWZhY3RNaW1lVHlwZSB9XTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZ2V0TWFya2VycygpICB7XHJcbiAgICBpZiAodGhpcz8uaW50ZXJjZXB0aW9uUG9pbnRzPy5pdGVtcykge1xyXG4gICAgICB0cnkge1xyXG4gICAgICAgIGNvbnN0IGludGVyY2VwdGlvblBvaW50cyA9IHRoaXMuaW50ZXJjZXB0aW9uUG9pbnRzO1xyXG4gICAgICAgIHRoaXMuc2hvd1Njb3JlID0gdHJ1ZTtcclxuICAgICAgICByZXR1cm4gaW50ZXJjZXB0aW9uUG9pbnRzLml0ZW1zLm1hcCgoe2ludGVyY2VwdGlvblBvaW50LCBpZGVudGlmaWVyLCB0eXBlfSkgPT4ge1xyXG4gICAgICAgIHJldHVybiB7IHRpbWU6IGludGVyY2VwdGlvblBvaW50LCB0eXBlLCBpZGVudGlmaWVyLCBkdXJhdGlvbjogMyB9O1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICAgIGNvbnNvbGUubG9nKGVycm9yKTtcclxuICAgICAgICB0aGlzLnJhaXNlRXhjZXB0aW9uTG9nKCdDUFYyX0NPTlRfSU5URVJDRVBUSU9OX1BBUlNFJywgJ2Vycm9yIHBhcnNpbmcgdGhlIGludGVjZXB0aW9uIHBvaW50cyBzdHJpbmcnLCBlcnJvciwgJycpO1xyXG4gICAgICAgIHRoaXMuc2hvd1Njb3JlID0gZmFsc2U7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiBudWxsO1xyXG4gIH1cclxuXHJcblxyXG4gIGdldFF1ZXN0aW9uU2V0KGlkZW50aWZpZXIpIHtcclxuICAgIGNvbnN0IGNvbnRlbnQgPSB0aGlzLmNvbnRlbnRNYXBbaWRlbnRpZmllcl07XHJcbiAgICBpZiAoIWNvbnRlbnQpIHtcclxuICAgICAgaWYgKCF0aGlzLnF1ZXN0aW9uQ3Vyc29yKSB7XHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgcmV0dXJuIHRoaXMucXVlc3Rpb25DdXJzb3IuZ2V0UXVlc3Rpb25TZXQoaWRlbnRpZmllcilcclxuICAgICAucGlwZShtYXAoKHJlc3BvbnNlKSA9PiB7XHJcbiAgICAgICAgdGhpcy5jb250ZW50TWFwW2lkZW50aWZpZXJdID0gcmVzcG9uc2UucXVlc3Rpb25TZXQ7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGVudE1hcFtpZGVudGlmaWVyXTtcclxuICAgICAgIH0pKTtcclxuICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuIG9mKGNvbnRlbnQpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJlRmV0Y2hDb250ZW50KCkge1xyXG4gICAgY29uc3QgbmV4dE1hcmtlciA9IHRoaXMuZ2V0TmV4dE1hcmtlcigpO1xyXG4gICAgaWYgKG5leHRNYXJrZXIpIHtcclxuICAgICAgY29uc3QgaWRlbnRpZmllciA9IG5leHRNYXJrZXIuaWRlbnRpZmllcjtcclxuICAgICAgdGhpcy5nZXRRdWVzdGlvblNldChuZXh0TWFya2VyLmlkZW50aWZpZXIpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZ2V0TmV4dE1hcmtlcigpIHtcclxuICAgIGNvbnN0IGN1cnJlbnRUaW1lID0gdGhpcy5wbGF5ZXJJbnN0YW5jZS5jdXJyZW50VGltZSgpO1xyXG4gICAgY29uc3QgbWFya2Vyc0xpc3QgPSB0aGlzLmdldE1hcmtlcnMoKTtcclxuICAgIGlmICghbWFya2Vyc0xpc3QpIHsgcmV0dXJuIG51bGw7IH1cclxuXHJcbiAgICByZXR1cm4gbWFya2Vyc0xpc3QuZmluZChtYXJrZXIgPT4ge1xyXG4gICAgICBjb25zdCBtYXJrZXJUaW1lID0gbWFya2VyLnRpbWU7XHJcbiAgICAgIHJldHVybiBtYXJrZXJUaW1lID4gY3VycmVudFRpbWU7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHJhaXNlU3RhcnRFdmVudChldmVudCkge1xyXG4gICAgY29uc3QgZHVyYXRpb24gPSBuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIHRoaXMuUGxheWVyTG9hZFN0YXJ0ZWRBdDtcclxuICAgIGNvbnN0IHN0YXJ0RXZlbnQgPSB7XHJcbiAgICAgIGVpZDogJ1NUQVJUJyxcclxuICAgICAgdmVyOiB0aGlzLnZlcnNpb24sXHJcbiAgICAgIGVkYXRhOiB7XHJcbiAgICAgICAgdHlwZTogJ1NUQVJUJyxcclxuICAgICAgICBtb2RlOiAncGxheScsXHJcbiAgICAgICAgZHVyYXRpb25cclxuICAgICAgfSxcclxuICAgICAgbWV0YURhdGE6IHRoaXMubWV0YURhdGFcclxuICAgIH07XHJcbiAgICB0aGlzLnBsYXllckV2ZW50LmVtaXQoc3RhcnRFdmVudCk7XHJcbiAgICB0aGlzLnZpZGVvUGxheWVyU2VydmljZS5zdGFydChkdXJhdGlvbik7XHJcbiAgICB0aGlzLlBsYXllckxvYWRTdGFydGVkQXQgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcclxuICB9XHJcblxyXG4gIGNhbGN1bGF0ZVNjb3JlKCkge1xyXG4gICAgdGhpcy5zY29yZU9idGFpbmVkID0gIE9iamVjdC52YWx1ZXModGhpcy5pbnRlcmNlcHRpb25SZXNwb25zZXMpLnJlZHVjZShcclxuICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLXN0cmluZy1saXRlcmFsXHJcbiAgICAgIChhY2MsIHJlc3BvbnNlKSA9PiBhY2MgKyByZXNwb25zZVsnc2NvcmUnXSAsIDApO1xyXG4gIH1cclxuXHJcbiAgcmFpc2VFbmRFdmVudCgpIHtcclxuICAgIGlmICghdGhpcy5pc0VuZEV2ZW50UmFpc2VkKSB7XHJcbiAgICAgIHRoaXMuY2FsY3VsYXRlU2NvcmUoKTtcclxuICAgICAgY29uc3QgZHVyYXRpb24gPSBuZXcgRGF0ZSgpLmdldFRpbWUoKSAtIHRoaXMuUGxheWVyTG9hZFN0YXJ0ZWRBdDtcclxuICAgICAgY29uc3QgZW5kRXZlbnQgPSB7XHJcbiAgICAgICAgZWlkOiAnRU5EJyxcclxuICAgICAgICB2ZXI6IHRoaXMudmVyc2lvbixcclxuICAgICAgICBlZGF0YToge1xyXG4gICAgICAgICAgdHlwZTogJ0VORCcsXHJcbiAgICAgICAgICBjdXJyZW50VGltZTogdGhpcy5jdXJyZW50bGVuZ3RoLFxyXG4gICAgICAgICAgdG90YWxUaW1lOiB0aGlzLnRvdGFsTGVuZ3RoLFxyXG4gICAgICAgICAgZHVyYXRpb25cclxuICAgICAgICB9LFxyXG4gICAgICAgIG1ldGFEYXRhOiB0aGlzLm1ldGFEYXRhXHJcbiAgICAgIH07XHJcbiAgICAgIHRoaXMucGxheWVyRXZlbnQuZW1pdChlbmRFdmVudCk7XHJcbiAgICAgIHRoaXMudGltZVNwZW50ID0gdGhpcy51dGlsU2VydmljZS5nZXRUaW1lU3BlbnRUZXh0KHRoaXMudmlzaXRlZExlbmd0aCk7XHJcbiAgICAgIHRoaXMudmlkZW9QbGF5ZXJTZXJ2aWNlLmVuZChcclxuICAgICAgICBkdXJhdGlvbixcclxuICAgICAgICB0aGlzLnRvdGFsTGVuZ3RoLFxyXG4gICAgICAgIHRoaXMuY3VycmVudGxlbmd0aCxcclxuICAgICAgICB0aGlzLmVuZFBhZ2VTZWVuLFxyXG4gICAgICAgIHRoaXMudG90YWxTZWVrZWRMZW5ndGgsXHJcbiAgICAgICAgdGhpcy52aXNpdGVkTGVuZ3RoIC8gMTAwMCxcclxuICAgICAgICB0aGlzLnNjb3JlT2J0YWluZWRcclxuICAgICAgKTtcclxuICAgICAgdGhpcy5pc0VuZEV2ZW50UmFpc2VkID0gdHJ1ZTtcclxuICAgIH1cclxuICB9XHJcblxyXG5cclxuICByYWlzZUhlYXJ0QmVhdEV2ZW50KHR5cGU6IHN0cmluZywgZXh0cmFWYWx1ZXM/KSB7XHJcbiAgICBpZiAodHlwZSA9PT0gJ1JFUExBWScpIHtcclxuICAgICAgdGhpcy5pbnRlcmNlcHRpb25SZXNwb25zZXMgPSB7fTtcclxuICAgICAgdGhpcy5zaG93U2NvcmUgPSBmYWxzZTtcclxuICAgICAgdGhpcy5zY29yZU9idGFpbmVkID0gMDtcclxuICAgIH1cclxuICAgIGNvbnN0IGhlYXJCZWF0RXZlbnQgPSB7XHJcbiAgICAgIGVpZDogJ0hFQVJUQkVBVCcsXHJcbiAgICAgIHZlcjogdGhpcy52ZXJzaW9uLFxyXG4gICAgICBlZGF0YToge1xyXG4gICAgICAgIHR5cGUsXHJcbiAgICAgICAgY3VycmVudFBhZ2U6ICd2aWRlb3N0YWdlJyxcclxuICAgICAgICBleHRyYTogZXh0cmFWYWx1ZXNcclxuICAgICAgfSxcclxuICAgICAgbWV0YURhdGE6IHRoaXMubWV0YURhdGFcclxuICAgIH07XHJcbiAgICB0aGlzLnBsYXllckV2ZW50LmVtaXQoaGVhckJlYXRFdmVudCk7XHJcbiAgICB0aGlzLnZpZGVvUGxheWVyU2VydmljZS5oZWFydEJlYXQoaGVhckJlYXRFdmVudCk7XHJcbiAgICBjb25zdCBpbnRlcmFjdEl0ZW1zID0gWydQTEFZJywgJ1BBVVNFJywgJ0VYSVQnLCAnVk9MVU1FX0NIQU5HRScsICdEUkFHJyxcclxuICAgICAgJ1JBVEVfQ0hBTkdFJywgJ0NMT1NFX0RPV05MT0FEJywgJ0RPV05MT0FEJywgJ05BVklHQVRFX1RPX1BBR0UnLFxyXG4gICAgICAnTkVYVCcsICdPUEVOX01FTlUnLCAnUFJFVklPVVMnLCAnQ0xPU0VfTUVOVScsICdET1dOTE9BRF9NRU5VJywgJ0RPV05MT0FEX1BPUFVQX0NMT1NFJywgJ0RPV05MT0FEX1BPUFVQX0NBTkNFTCcsXHJcbiAgICAgICdTSEFSRScsICdSRVBMQVknLCAnRk9SV0FSRCcsICdCQUNLV0FSRCcsICdGVUxMU0NSRUVOJywgJ05FWFRfQ09OVEVOVF9QTEFZJywgJ1RSQU5TQ1JJUFRfTEFOR1VBR0VfT0ZGJyxcclxuICAgICAgJ1RSQU5TQ1JJUFRfTEFOR1VBR0VfU0VMRUNURUQnLCAnVklERU9fTUFSS0VSX1NFTEVDVEVEJ1xyXG4gICAgXTtcclxuICAgIGlmIChpbnRlcmFjdEl0ZW1zLmluY2x1ZGVzKHR5cGUpKSB7XHJcbiAgICAgIHRoaXMudmlkZW9QbGF5ZXJTZXJ2aWNlLmludGVyYWN0KHR5cGUudG9Mb3dlckNhc2UoKSwgJ3ZpZGVvc3RhZ2UnLCBleHRyYVZhbHVlcyk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByYWlzZUltcHJlc3Npb25FdmVudChwYWdlSWQ6IHN0cmluZywgY2RhdGE6IGFueSA9IHt9KSB7XHJcbiAgICB0aGlzLnZpZGVvUGxheWVyU2VydmljZS5pbXByZXNzaW9uKHBhZ2VJZCwgY2RhdGEpO1xyXG4gIH1cclxuXHJcbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5vLXNoYWRvd2VkLXZhcmlhYmxlXHJcbiAgcmFpc2VFeGNlcHRpb25Mb2coZXJyb3JDb2RlOiBzdHJpbmcsIGVycm9yVHlwZTogc3RyaW5nLCBzdGFja3RyYWNlLCB0cmFjZUlkKSB7XHJcbiAgICBjb25zdCBleGNlcHRpb25Mb2dFdmVudCA9IHtcclxuICAgICAgZWlkOiAnRVJST1InLFxyXG4gICAgICBlZGF0YToge1xyXG4gICAgICAgIGVycjogZXJyb3JDb2RlLFxyXG4gICAgICAgIGVycnR5cGU6IGVycm9yVHlwZSxcclxuICAgICAgICByZXF1ZXN0aWQ6IHRyYWNlSWQgfHwgJycsXHJcbiAgICAgICAgc3RhY2t0cmFjZTogKHN0YWNrdHJhY2UgJiYgc3RhY2t0cmFjZS50b1N0cmluZygpKSB8fCAnJyxcclxuICAgICAgfVxyXG4gICAgfTtcclxuICAgIHRoaXMucGxheWVyRXZlbnQuZW1pdChleGNlcHRpb25Mb2dFdmVudCk7XHJcbiAgICB0aGlzLnZpZGVvUGxheWVyU2VydmljZS5lcnJvcihlcnJvckNvZGUgLCBlcnJvclR5cGUgLCBzdGFja3RyYWNlKTtcclxuICB9XHJcblxyXG59XHJcbiJdfQ==