zoriakinc-messaging
Version:
Angular Messaging Module
441 lines • 42.8 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: lib/chat-box/chat-box.component.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import * as tslib_1 from "tslib";
import { Component, Input, ViewChild, ViewChildren, ElementRef, QueryList } from '@angular/core';
import { MessagingService } from './messaging.service';
import { forkJoin } from 'rxjs';
import { map } from 'rxjs/operators';
var ChatBoxComponent = /** @class */ (function () {
function ChatBoxComponent(messagingService) {
this.messagingService = messagingService;
this.messageList = [];
this.groupedMessageList = [];
this.GROUP_MIN_RANGE_IN_MINUTES = 20;
this.isFullScreenMode = false;
this.showSenderName = true;
this.replyContent = '';
if (this.messagingService.configObject.theme_color) {
document.documentElement.style
.setProperty('--theme-color', this.messagingService.configObject.theme_color);
}
this.isFullScreenMode = this.messagingService.configObject.full_screen_mode;
if (this.isFullScreenMode) {
document.documentElement.style
.setProperty('--window-width', '100%');
}
if ('show_sender_name' in this.messagingService.configObject) {
this.showSenderName = this.messagingService.configObject.show_sender_name;
}
// https://stackoverflow.com/a/48216423
this.isLoading = true;
}
/**
* @return {?}
*/
ChatBoxComponent.prototype.ngOnInit = /**
* @return {?}
*/
function () {
var _this = this;
/** @type {?} */
var readAllRequest = this.messagingService.readAll(this.donor_id);
readAllRequest.subscribe();
/** @type {?} */
var loadMessagesRequest = this.loadMessages(0);
loadMessagesRequest.subscribe((/**
* @param {?} list
* @return {?}
*/
function (list) {
_this.messageList = list;
_this.addNewMessagesPage(list);
}));
forkJoin(readAllRequest, loadMessagesRequest).subscribe((/**
* @return {?}
*/
function () { return _this.isLoading = false; }));
/** @type {?} */
var onMessageCallback = (/**
* @param {?} message
* @return {?}
*/
function (message) {
if (_this.messageList.some((/**
* @param {?} el
* @return {?}
*/
function (el) { return el.id === message.id; }))) {
return;
}
if (!_this.recipient_user_id || (parseInt(message.sender_user_id) === parseInt(_this.recipient_user_id))
|| (parseInt(message.recipient_user_id) === parseInt(_this.recipient_user_id))) {
_this.addNewMessage(tslib_1.__assign({ id: message.id, content: message.content, created_at: message.created_at, is_self_message: message.sender_user_id === _this.user_id }, !message.is_donor_message && { sender_display_name: _this.user_display_name }));
_this.messageList.push(message);
// TODO: read this message not all!
_this.messagingService.readAll(_this.donor_id)
.subscribe();
}
});
this.messagingService.startLiveChat(onMessageCallback);
};
/**
* @return {?}
*/
ChatBoxComponent.prototype.loadMore = /**
* @return {?}
*/
function () {
var _this = this;
this.isLoading = true;
/** @type {?} */
var loadingSubscription = this.loadMessages(this.messageList.length)
.subscribe((/**
* @param {?} list
* @return {?}
*/
function (list) {
_this.messageList = list.concat(_this.messageList);
_this.addNewMessagesPage(list);
_this.isLoading = false;
loadingSubscription.unsubscribe();
}));
};
/**
* @param {?} offset
* @return {?}
*/
ChatBoxComponent.prototype.loadMessages = /**
* @param {?} offset
* @return {?}
*/
function (offset) {
/** @type {?} */
var self = this;
return this.messagingService.list(offset, this.donor_id)
.pipe(map((/**
* @param {?} list
* @return {?}
*/
function (list) {
list.reverse();
return list.map((/**
* @param {?} message
* @return {?}
*/
function (message) {
return {
id: message.id,
content: message.content,
created_at: message.created_at,
is_self_message: message.sender === self.user_id,
sender_display_name: message.sender_display_name
};
}));
})));
};
/**
* @return {?}
*/
ChatBoxComponent.prototype.ngAfterViewInit = /**
* @return {?}
*/
function () {
var _this = this;
this.chatContainerElement.nativeElement.style.height = this.height || 'calc(100vh - 500px)';
if (this.msgDivs && this.msgDivs.last) {
this.msgDivs.last.nativeElement.focus();
}
this.msgDivs.changes.subscribe((/**
* @return {?}
*/
function () {
if (_this.msgDivs && _this.msgDivs.last) {
_this.msgDivs.last.nativeElement.focus();
}
}));
};
/**
* @param {?} msg
* @return {?}
*/
ChatBoxComponent.prototype.addNewMessage = /**
* @param {?} msg
* @return {?}
*/
function (msg) {
if (this.latestMsgDatetime && (new Date(msg.created_at.toString()).getTime()
- this.latestMsgDatetime.getTime()) / 60000 < this.GROUP_MIN_RANGE_IN_MINUTES) {
this.groupedMessageList[this.groupedMessageList.length - 1].push(msg);
}
else {
this.groupedMessageList.push([msg]);
}
this.latestMsgDatetime = new Date(msg.created_at.toString());
};
/**
* @param {?} msgList
* @return {?}
*/
ChatBoxComponent.prototype.addNewMessagesPage = /**
* @param {?} msgList
* @return {?}
*/
function (msgList) {
var _this = this;
if (this.msgDivs && this.msgDivs.first) {
/** @type {?} */
var firstDiv_1 = this.msgDivs.first;
/** @type {?} */
var onNewPageAdded_1 = (/**
* @return {?}
*/
function () {
firstDiv_1.nativeElement.scrollIntoView(true);
_this.msgsContainer.nativeElement.scrollBy(0, -90);
});
this.msgsContainer.nativeElement.addEventListener('DOMNodeInserted', onNewPageAdded_1, false);
setTimeout((/**
* @return {?}
*/
function () { return _this.msgsContainer.nativeElement.removeEventListener('DOMNodeInserted', onNewPageAdded_1, false); }));
}
/** @type {?} */
var groupingObj = this.groupByTime(msgList);
if (groupingObj) {
this.groupedMessageList = groupingObj.groupedList.concat(this.groupedMessageList);
this.latestMsgDatetime = groupingObj.latestMsgDatetime;
}
};
/**
* @param {?} msgList
* @return {?}
*/
ChatBoxComponent.prototype.groupByTime = /**
* @param {?} msgList
* @return {?}
*/
function (msgList) {
var _this = this;
if (!msgList.length) {
return;
}
/** @type {?} */
var groupedList = [];
/** @type {?} */
var adjacentList = [];
/** @type {?} */
var latestMsgDatetime = new Date(msgList[0].created_at.toString());
msgList.forEach((/**
* @param {?} message
* @return {?}
*/
function (message) {
if ((new Date(message.created_at.toString()).getTime() - latestMsgDatetime.getTime()) / 60000 < _this.GROUP_MIN_RANGE_IN_MINUTES) {
adjacentList.push(message);
latestMsgDatetime = new Date(message.created_at.toString());
}
else {
groupedList.push(adjacentList);
adjacentList = [message];
latestMsgDatetime = new Date(message.created_at.toString());
}
}));
groupedList.push(adjacentList);
return {
groupedList: groupedList,
latestMsgDatetime: latestMsgDatetime
};
};
/**
* @return {?}
*/
ChatBoxComponent.prototype.reply = /**
* @return {?}
*/
function () {
this.messagingService.send_message(this.replyContent, this.donor_id);
this.replyContent = '';
this.msgInput.nativeElement.addEventListener('focusout', this.focusOnInputAgain.bind(this));
};
/**
* @param {?} event
* @return {?}
*/
ChatBoxComponent.prototype.focusOnInputAgain = /**
* @param {?} event
* @return {?}
*/
function (event) {
var _this = this;
setTimeout((/**
* @return {?}
*/
function () {
_this.msgInput.nativeElement.focus();
_this.msgInput.nativeElement.removeEventListener('focusout', _this.focusOnInputAgain.bind(_this));
}));
};
/**
* @param {?} event
* @return {?}
*/
ChatBoxComponent.prototype.onScroll = /**
* @param {?} event
* @return {?}
*/
function (event) {
if (event.target.scrollTop === 0) {
this.loadMore();
}
};
/**
* @param {?} date
* @return {?}
*/
ChatBoxComponent.prototype.isToday = /**
* @param {?} date
* @return {?}
*/
function (date) {
date = new Date(date.toString());
/** @type {?} */
var today = new Date();
return date.getDate() === today.getDate() &&
date.getMonth() === today.getMonth() &&
date.getFullYear() === today.getFullYear();
};
/**
* @param {?} date
* @return {?}
*/
ChatBoxComponent.prototype.isYesterday = /**
* @param {?} date
* @return {?}
*/
function (date) {
date = new Date(date.toString());
/** @type {?} */
var toBeYesterday = new Date();
toBeYesterday.setDate(toBeYesterday.getDate() - 1);
/** @type {?} */
var yesterday = toBeYesterday;
return date.getDate() === yesterday.getDate() &&
date.getMonth() === yesterday.getMonth() &&
date.getFullYear() === yesterday.getFullYear();
};
/**
* @param {?} date
* @return {?}
*/
ChatBoxComponent.prototype.isWeekDay = /**
* @param {?} date
* @return {?}
*/
function (date) {
if (this.isToday(date) || this.isYesterday(date)) {
return false;
}
/** @type {?} */
var weekAgo = new Date();
weekAgo.setDate(weekAgo.getDate() - 7);
return new Date(date.toString()) > weekAgo;
};
/**
* @param {?} date
* @return {?}
*/
ChatBoxComponent.prototype.getDayName = /**
* @param {?} date
* @return {?}
*/
function (date) {
return new Date(date.toString()).toLocaleString('en-us', { weekday: 'short' });
};
/**
* @return {?}
*/
ChatBoxComponent.prototype.ngOnDestroy = /**
* @return {?}
*/
function () {
this.messagingService.removeOnMessageListener();
};
ChatBoxComponent.decorators = [
{ type: Component, args: [{
selector: 'lib-chat-box',
template: "<div class=\"chatbox\" #chatContainer>\n\n <div *ngIf=\"recipient_display_name && !isFullScreenMode\" class=\"chat-header\">\n <span class=\"avatar\">\n <mat-icon *ngIf=\"!recipient_avatar_src\" class=\"avatar__icon\">person</mat-icon>\n <img *ngIf=\"recipient_avatar_src\" [src]=\"recipient_avatar_src\" class=\"avatar__img\">\n </span>\n <span class=\"name\">\n {{recipient_display_name}}\n </span>\n </div>\n\n <div class=\"messages\" #msgsContainer (scroll)=\"onScroll($event)\">\n <div *ngFor=\"let group of groupedMessageList\">\n <div class=\"messages-group\">\n <div class=\"messages-group-label\">\n <div class=\"hr-sect\" *ngIf=\"isToday(group[0]?.created_at)\">\n <span style=\"padding: 0 10px;\">{{group[0]?.created_at | date: 'shortTime'}}</span>\n </div>\n <div class=\"hr-sect\" *ngIf=\"isYesterday(group[0]?.created_at)\">\n <span style=\"padding: 0 10px;\">Yesterday {{group[0]?.created_at | date: 'shortTime'}}</span>\n </div>\n <div class=\"hr-sect\" *ngIf=\"isWeekDay(group[0]?.created_at)\">\n <span style=\"padding: 0 10px;\">{{group[0]?.created_at | date: 'EEEE'}} {{group[0]?.created_at | date: 'shortTime'}}</span>\n </div>\n <div class=\"hr-sect\" *ngIf=\"!isToday(group[0]?.created_at) &&\n !isYesterday(group[0]?.created_at) &&\n !isWeekDay(group[0]?.created_at)\">\n <span style=\"padding: 0 10px;\"> {{group[0]?.created_at | date: 'MMM d, y, h:mm a'}}</span>\n </div>\n </div>\n <div tabindex=\"1\" class=\"message-div\" #msgDiv *ngFor=\"let message of group\">\n <div class=\"text-icon\" [class.self-messages]=\"message.is_self_message\">\n <span class=\"avatar\" *ngIf=\"!message.is_self_message\">\n <mat-icon class=\"avatar__icon\">person</mat-icon>\n <img *ngIf=\"recipient_avatar_src\" [src]=\"recipient_avatar_src\" class=\"avatar__img\">\n </span>\n <div>\n <div class=\"sender-name\" *ngIf=\"message.is_self_message && this.showSenderName\">\n {{message.sender_display_name}}\n </div>\n <p class=\"message-item\">\n {{message.content}}\n </p>\n </div>\n <span class=\"avatar\" style=\"vertical-align: middle;\" *ngIf=\"message.is_self_message\">\n <mat-icon>person</mat-icon>\n <img *ngIf=\"sender_avatar_src\" [src]=\"sender_avatar_src\" class=\"avatar__img\">\n </span>\n\n <!--<div class=\"timeform\">-->\n <!--<mat-icon>date</mat-icon> <span class=\"timestamp\">at {{message.created_at | date : 'dd/MM/yyyy' }}</span>-->\n <!--</div>-->\n </div>\n </div>\n </div>\n </div>\n\n </div>\n\n <div class=\"input-container\">\n <mat-form-field>\n <textarea #msgInput matInput\n cdkTextareaAutosize\n #autosize=\"cdkTextareaAutosize\"\n cdkAutosizeMinRows=\"2\"\n cdkAutosizeMaxRows=\"5\"\n (keyup.enter)=\"reply()\" placeholder=\"Type a message..\" [(ngModel)]=\"replyContent\">\n </textarea>\n </mat-form-field>\n\n <div class=\"button-wrap\">\n <button mat-raised-button\n color=\"primary\"\n class=\"replyBtn\"\n (click)=\"reply()\">\n Send\n </button>\n </div>\n </div>\n\n</div>\n",
styles: [":root{--theme-color:#3498db;--window-width:90%}.chatbox{width:var(--window-width,90%);display:flex;flex-direction:column;margin:0 auto;border-radius:5px 5px 0 0;background-color:#fff;box-shadow:0 2px 4px 0 rgba(0,0,0,.2)}.chatbox .chat-header{height:120px;padding:20px;text-align:center;border-radius:5px 5px 0 0;background:#3498db;color:#fff}.chatbox .chat-header .avatar{margin:0 0 10px;width:55px;min-width:55px;height:55px;min-height:55px;text-align:center!important;background-color:#fff!important;vertical-align:middle;color:#000!important}.chatbox .chat-header .name{font-size:20px;font-style:oblique;font-weight:700;display:block}.chatbox .messages{flex:1;overflow:auto;padding:50px 16px 6px;background-color:#fafafa;box-shadow:inset 0 2px 2px rgba(0,0,0,.1)}.chatbox .messages .messages-group{margin-bottom:10px}.chatbox .messages .messages-group .messages-group-label{text-align:center;margin-bottom:10px}.chatbox .messages .messages-group .messages-group-label .hr-sect{display:flex;flex-basis:100%;align-items:center;margin:8px 0}.chatbox .messages .messages-group .messages-group-label .hr-sect::after,.chatbox .messages .messages-group .messages-group-label .hr-sect::before{content:\"\";flex-grow:1;background:rgba(0,0,0,.1);height:1.5px;font-size:0;line-height:0;margin:0 8px}.chatbox .messages .messages-group .message-div{padding:1px;outline:0}.chatbox .messages .message-item{background-color:#ccc;padding:8px;border-radius:14px;margin-top:0;margin-bottom:0}.chatbox .messages .text-icon{display:flex;flex-direction:row;justify-content:flex-start}.chatbox .messages .self-messages{justify-content:flex-end}.chatbox .messages .self-messages .sender-name{font-size:14px;font-weight:700;margin:2px 5px;text-align:right}.chatbox .messages .self-messages p{color:#fff;background-color:var(--theme-color,#3498db);white-space:pre-line}.chatbox .messages .avatar{margin:0 5px;width:25px;min-width:25px;height:25px;min-height:25px;text-align:center!important;background-color:#fff!important;vertical-align:middle;color:#000!important}.chatbox .input-container{display:flex;flex-direction:row;align-items:center;width:100%;margin:0 auto;background-color:#fff;box-shadow:0 2px 4px 0 rgba(0,0,0,.2);border-radius:0 0 5px 5px;padding:8px;vertical-align:middle;border-top:1px solid #ebebeb}.chatbox .input-container mat-form-field{flex:1}.chatbox .input-container mat-form-field textarea{width:100%}.chatbox .input-container .button-wrap{margin:4px}.chatbox .input-container .button-wrap button{width:70px;margin-left:20px}"]
}] }
];
/** @nocollapse */
ChatBoxComponent.ctorParameters = function () { return [
{ type: MessagingService }
]; };
ChatBoxComponent.propDecorators = {
msgDivs: [{ type: ViewChildren, args: ['msgDiv',] }],
msgsContainer: [{ type: ViewChild, args: ['msgsContainer', { static: false },] }],
chatContainerElement: [{ type: ViewChild, args: ['chatContainer', { static: false },] }],
sender_avatar_src: [{ type: Input }],
recipient_avatar_src: [{ type: Input }],
recipient_display_name: [{ type: Input }],
donor_id: [{ type: Input }],
user_display_name: [{ type: Input }],
user_id: [{ type: Input }],
recipient_user_id: [{ type: Input }],
height: [{ type: Input }],
msgInput: [{ type: ViewChild, args: ['msgInput', { static: false },] }]
};
return ChatBoxComponent;
}());
export { ChatBoxComponent };
if (false) {
/** @type {?} */
ChatBoxComponent.prototype.msgDivs;
/** @type {?} */
ChatBoxComponent.prototype.msgsContainer;
/** @type {?} */
ChatBoxComponent.prototype.chatContainerElement;
/** @type {?} */
ChatBoxComponent.prototype.sender_avatar_src;
/** @type {?} */
ChatBoxComponent.prototype.recipient_avatar_src;
/** @type {?} */
ChatBoxComponent.prototype.recipient_display_name;
/** @type {?} */
ChatBoxComponent.prototype.donor_id;
/** @type {?} */
ChatBoxComponent.prototype.user_display_name;
/** @type {?} */
ChatBoxComponent.prototype.user_id;
/** @type {?} */
ChatBoxComponent.prototype.recipient_user_id;
/** @type {?} */
ChatBoxComponent.prototype.height;
/** @type {?} */
ChatBoxComponent.prototype.messageList;
/** @type {?} */
ChatBoxComponent.prototype.groupedMessageList;
/** @type {?} */
ChatBoxComponent.prototype.latestMsgDatetime;
/** @type {?} */
ChatBoxComponent.prototype.GROUP_MIN_RANGE_IN_MINUTES;
/** @type {?} */
ChatBoxComponent.prototype.isFullScreenMode;
/** @type {?} */
ChatBoxComponent.prototype.showSenderName;
/** @type {?} */
ChatBoxComponent.prototype.isLoading;
/** @type {?} */
ChatBoxComponent.prototype.replyContent;
/** @type {?} */
ChatBoxComponent.prototype.msgInput;
/**
* @type {?}
* @private
*/
ChatBoxComponent.prototype.messagingService;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hhdC1ib3guY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vem9yaWFraW5jLW1lc3NhZ2luZy8iLCJzb3VyY2VzIjpbImxpYi9jaGF0LWJveC9jaGF0LWJveC5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsT0FBTyxFQUNMLFNBQVMsRUFDVCxLQUFLLEVBQ0wsU0FBUyxFQUNULFlBQVksRUFDWixVQUFVLEVBQ1YsU0FBUyxFQUVWLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBQ3JELE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFDOUIsT0FBTyxFQUFDLEdBQUcsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBR25DO0lBbUNFLDBCQUFvQixnQkFBa0M7UUFBbEMscUJBQWdCLEdBQWhCLGdCQUFnQixDQUFrQjtRQWZ0RCxnQkFBVyxHQUFxQixFQUFFLENBQUM7UUFFbkMsdUJBQWtCLEdBQXVCLEVBQUUsQ0FBQztRQUc1QywrQkFBMEIsR0FBRyxFQUFFLENBQUM7UUFDaEMscUJBQWdCLEdBQUcsS0FBSyxDQUFDO1FBQ3pCLG1CQUFjLEdBQUcsSUFBSSxDQUFDO1FBSXRCLGlCQUFZLEdBQUcsRUFBRSxDQUFDO1FBS2hCLElBQUksSUFBSSxDQUFDLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxXQUFXLEVBQUU7WUFDbEQsUUFBUSxDQUFDLGVBQWUsQ0FBQyxLQUFLO2lCQUMzQixXQUFXLENBQUMsZUFBZSxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDLENBQUM7U0FDakY7UUFDRCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFlBQVksQ0FBQyxnQkFBZ0IsQ0FBQztRQUM1RSxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtZQUN2QixRQUFRLENBQUMsZUFBZSxDQUFD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OztJQUUzQixtQ0FBdUQ7O0lBQ3ZELHlDQUF1RTs7SUFDdkUsZ0RBQThFOztJQUU5RSw2Q0FBbUM7O0lBQ25DLGdEQUFzQzs7SUFDdEMsa0RBQXdDOztJQUN4QyxvQ0FBMEI7O0lBQzFCLDZDQUFtQzs7SUFDbkMsbUNBQXlCOztJQUN6Qiw2Q0FBbUM7O0lBQ25DLGtDQUF3Qjs7SUFFeEIsdUNBQW1DOztJQUVuQyw4Q0FBNEM7O0lBQzVDLDZDQUF3Qjs7SUFFeEIsc0RBQWdDOztJQUNoQyw0Q0FBeUI7O0lBQ3pCLDBDQUFzQjs7SUFFdEIscUNBQVU7O0lBRVYsd0NBQWtCOztJQUVsQixvQ0FBNkQ7Ozs7O0lBRWpELDRDQUEwQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgSW5wdXQsXG4gIFZpZXdDaGlsZCxcbiAgVmlld0NoaWxkcmVuLFxuICBFbGVtZW50UmVmLFxuICBRdWVyeUxpc3QsXG4gIE9uSW5pdCwgT25EZXN0cm95XG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtQcmV2aWV3TWVzc2FnZX0gZnJvbSAnLi4vbW9kZWxzJztcbmltcG9ydCB7TWVzc2FnaW5nU2VydmljZX0gZnJvbSAnLi9tZXNzYWdpbmcuc2VydmljZSc7XG5pbXBvcnQge2ZvcmtKb2lufSBmcm9tICdyeGpzJztcbmltcG9ydCB7bWFwfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQge1NlcnZlck1lc3NhZ2V9IGZyb20gJy4uL21vZGVscyc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2xpYi1jaGF0LWJveCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9jaGF0LWJveC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2NoYXQtYm94LmNvbXBvbmVudC5zY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgQ2hhdEJveENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcblxuICBAVmlld0NoaWxkcmVuKCdtc2dEaXYnKSBtc2dEaXZzOiBRdWVyeUxpc3Q8RWxlbWVudFJlZj47XG4gIEBWaWV3Q2hpbGQoJ21zZ3NDb250YWluZXInLCB7c3RhdGljOiBmYWxzZX0pIG1zZ3NDb250YWluZXI6IEVsZW1lbnRSZWY7XG4gIEBWaWV3Q2hpbGQoJ2NoYXRDb250YWluZXInLCB7c3RhdGljOiBmYWxzZX0pIGNoYXRDb250YWluZXJFbGVtZW50OiBFbGVtZW50UmVmO1xuXG4gIEBJbnB1dCgpIHNlbmRlcl9hdmF0YXJfc3JjOiBzdHJpbmc7XG4gIEBJbnB1dCgpIHJlY2lwaWVudF9hdmF0YXJfc3JjOiBudW1iZXI7XG4gIEBJbnB1dCgpIHJlY2lwaWVudF9kaXNwbGF5X25hbWU6IHN0cmluZztcbiAgQElucHV0KCkgZG9ub3JfaWQ6IHN0cmluZztcbiAgQElucHV0KCkgdXNlcl9kaXNwbGF5X25hbWU6IHN0cmluZztcbiAgQElucHV0KCkgdXNlcl9pZDogbnVtYmVyO1xuICBASW5wdXQoKSByZWNpcGllbnRfdXNlcl9pZDogc3RyaW5nO1xuICBASW5wdXQoKSBoZWlnaHQ6IHN0cmluZztcblxuICBtZXNzYWdlTGlzdDogUHJldmlld01lc3NhZ2VbXSA9IFtdO1xuXG4gIGdyb3VwZWRNZXNzYWdlTGlzdDogUHJldmlld01lc3NhZ2VbXVtdID0gW107XG4gIGxhdGVzdE1zZ0RhdGV0aW1lOiBEYXRlO1xuXG4gIEdST1VQX01JTl9SQU5HRV9JTl9NSU5VVEVTID0gMjA7XG4gIGlzRnVsbFNjcmVlbk1vZGUgPSBmYWxzZTtcbiAgc2hvd1NlbmRlck5hbWUgPSB0cnVlO1xuXG4gIGlzTG9hZGluZztcblxuICByZXBseUNvbnRlbnQgPSAnJztcblxuICBAVmlld0NoaWxkKCdtc2dJbnB1dCcsIHtzdGF0aWM6IGZhbHNlfSkgbXNnSW5wdXQ6IEVsZW1lbnRSZWY7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBtZXNzYWdpbmdTZXJ2aWNlOiBNZXNzYWdpbmdTZXJ2aWNlKSB7XG4gICAgaWYgKHRoaXMubWVzc2FnaW5nU2VydmljZS5jb25maWdPYmplY3QudGhlbWVfY29sb3IpIHtcbiAgICAgIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zdHlsZVxuICAgICAgICAuc2V0UHJvcGVydHkoJy0tdGhlbWUtY29sb3InLCB0aGlzLm1lc3NhZ2luZ1NlcnZpY2UuY29uZmlnT2JqZWN0LnRoZW1lX2NvbG9yKTtcbiAgICB9XG4gICAgdGhpcy5pc0Z1bGxTY3JlZW5Nb2RlID0gdGhpcy5tZXNzYWdpbmdTZXJ2aWNlLmNvbmZpZ09iamVjdC5mdWxsX3NjcmVlbl9tb2RlO1xuICAgIGlmICh0aGlzLmlzRnVsbFNjcmVlbk1vZGUpIHtcbiAgICAgICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnN0eWxlXG4gICAgICAgICAgLnNldFByb3BlcnR5KCctLXdpbmRvdy13aWR0aCcsICcxMDAlJyk7XG4gICAgfVxuXG4gICAgaWYgKCdzaG93X3NlbmRlcl9uYW1lJyBpbiB0aGlzLm1lc3NhZ2luZ1NlcnZpY2UuY29uZmlnT2JqZWN0KSB7XG4gICAgICB0aGlzLnNob3dTZW5kZXJOYW1lID0gdGhpcy5tZXNzYWdpbmdTZXJ2aWNlLmNvbmZpZ09iamVjdC5zaG93X3NlbmRlcl9uYW1lO1xuICAgIH1cblxuICAgIC8vIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vYS80ODIxNjQyM1xuICAgIHRoaXMuaXNMb2FkaW5nID0gdHJ1ZTtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuXG4gICAgY29uc3QgcmVhZEFsbFJlcXVlc3QgPSB0aGlzLm1lc3NhZ2luZ1NlcnZpY2UucmVhZEFsbCh0aGlzLmRvbm9yX2lkKTtcbiAgICByZWFkQWxsUmVxdWVzdC5zdWJzY3JpYmUoKTtcblxuICAgIGNvbnN0IGxvYWRNZXNzYWdlc1JlcXVlc3QgPSB0aGlzLmxvYWRNZXNzYWdlcygwKTtcbiAgICBsb2FkTWVzc2FnZXNSZXF1ZXN0LnN1YnNjcmliZSgobGlzdDogUHJldmlld01lc3NhZ2VbXSkgPT4ge1xuICAgICAgdGhpcy5tZXNzYWdlTGlzdCA9IGxpc3Q7XG4gICAgICB0aGlzLmFkZE5ld01lc3NhZ2VzUGFnZShsaXN0KTtcbiAgICB9KTtcblxuICAgIGZvcmtKb2luKHJlYWRBbGxSZXF1ZXN0LCBsb2FkTWVzc2FnZXNSZXF1ZXN0KS5zdWJzY3JpYmUoKCkgPT4gdGhpcy5pc0xvYWRpbmcgPSBmYWxzZSk7XG5cbiAgICBjb25zdCBvbk1lc3NhZ2VDYWxsYmFjayA9IChtZXNzYWdlKSA9PiB7XG4gICAgICBpZiAodGhpcy5tZXNzYWdlTGlzdC5zb21lKGVsID0+IGVsLmlkID09PSBtZXNzYWdlLmlkKSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBpZiAoIXRoaXMucmVjaXBpZW50X3VzZXJfaWQgfHwgKHBhcnNlSW50KG1lc3NhZ2Uuc2VuZGVyX3VzZXJfaWQpID09PSBwYXJzZUludCh0aGlzLnJlY2lwaWVudF91c2VyX2lkKSlcbiAgICAgICAgfHwgKHBhcnNlSW50KG1lc3NhZ2UucmVjaXBpZW50X3VzZXJfaWQpID09PSBwYXJzZUludCh0aGlzLnJlY2lwaWVudF91c2VyX2lkKSkpIHtcbiAgICAgICAgdGhpcy5hZGROZXdNZXNzYWdlKHtcbiAgICAgICAgICBpZDogbWVzc2FnZS5pZCxcbiAgICAgICAgICBjb250ZW50OiBtZXNzYWdlLmNvbnRlbnQsXG4gICAgICAgICAgY3JlYXRlZF9hdDogbWVzc2FnZS5jcmVhdGVkX2F0LFxuICAgICAgICAgIGlzX3NlbGZfbWVzc2FnZTogbWVzc2FnZS5zZW5kZXJfdXNlcl9pZCA9PT0gdGhpcy51c2VyX2lkLFxuICAgICAgICAgIC4uLiFtZXNzYWdlLmlzX2Rvbm9yX21lc3NhZ2UgJiYge3NlbmRlcl9kaXNwbGF5X25hbWU6IHRoaXMudXNlcl9kaXNwbGF5X25hbWV9XG4gICAgICAgIH0pO1xuICAgICAgICB0aGlzLm1lc3NhZ2VMaXN0LnB1c2gobWVzc2FnZSk7XG4gICAgICAgIC8vIFRPRE86IHJlYWQgdGhpcyBtZXNzYWdlIG5vdCBhbGwhXG4gICAgICAgIHRoaXMubWVzc2FnaW5nU2VydmljZS5yZWFkQWxsKHRoaXMuZG9ub3JfaWQpXG4gICAgICAgICAgLnN1YnNjcmliZSgpO1xuICAgICAgfVxuICAgIH07XG4gICAgdGhpcy5tZXNzYWdpbmdTZXJ2aWNlLnN0YXJ0TGl2ZUNoYXQob25NZXNzYWdlQ2FsbGJhY2spO1xuICB9XG5cbiAgbG9hZE1vcmUoKSB7XG4gICAgdGhpcy5pc0xvYWRpbmcgPSB0cnVlO1xuICAgIGNvbnN0IGxvYWRpbmdTdWJzY3JpcHRpb24gPSB0aGlzLmxvYWRNZXNzYWdlcyh0aGlzLm1lc3NhZ2VMaXN0Lmxlbmd0aClcbiAgICAgIC5zdWJzY3JpYmUoKGxpc3Q6IFByZXZpZXdNZXNzYWdlW10pID0+IHtcbiAgICAgICAgdGhpcy5tZXNzYWdlTGlzdCA9IGxpc3QuY29uY2F0KHRoaXMubWVzc2FnZUxpc3QpO1xuICAgICAgICB0aGlzLmFkZE5ld01lc3NhZ2VzUGFnZShsaXN0KTtcbiAgICAgICAgdGhpcy5pc0xvYWRpbmcgPSBmYWxzZTtcbiAgICAgICAgbG9hZGluZ1N1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgICAgfSk7XG4gIH1cblxuICBsb2FkTWVzc2FnZXMob2Zmc2V0KSB7XG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgcmV0dXJuIHRoaXMubWVzc2FnaW5nU2VydmljZS5saXN0KG9mZnNldCwgdGhpcy5kb25vcl9pZClcbiAgICAgIC5waXBlKG1hcCgobGlzdDogU2VydmVyTWVzc2FnZVtdKSA9PiB7XG4gICAgICAgIGxpc3QucmV2ZXJzZSgpO1xuICAgICAgICByZXR1cm4gbGlzdC5tYXAobWVzc2FnZSA9PiB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICBpZDogbWVzc2FnZS5pZCxcbiAgICAgICAgICAgICAgY29udGVudDogbWVzc2FnZS5jb250ZW50LFxuICAgICAgICAgICAgICBjcmVhdGVkX2F0OiBtZXNzYWdlLmNyZWF0ZWRfYXQsXG4gICAgICAgICAgICAgIGlzX3NlbGZfbWVzc2FnZTogbWVzc2FnZS5zZW5kZXIgPT09IHNlbGYudXNlcl9pZCxcbiAgICAgICAgICAgICAgc2VuZGVyX2Rpc3BsYXlfbmFtZTogbWVzc2FnZS5zZW5kZXJfZGlzcGxheV9uYW1lXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgIH0pKTtcbiAgfVxuXG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIHRoaXMuY2hhdENvbnRhaW5lckVsZW1lbnQubmF0aXZlRWxlbWVudC5zdHlsZS5oZWlnaHQgPSB0aGlzLmhlaWdodCB8fCAnY2FsYygxMDB2aCAtIDUwMHB4KSc7XG5cbiAgICBpZiAodGhpcy5tc2dEaXZzICYmIHRoaXMubXNnRGl2cy5sYXN0KSB7XG4gICAgICB0aGlzLm1zZ0RpdnMubGFzdC5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XG4gICAgfVxuICAgIHRoaXMubXNnRGl2cy5jaGFuZ2VzLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICBpZiAodGhpcy5tc2dEaXZzICYmIHRoaXMubXNnRGl2cy5sYXN0KSB7XG4gICAgICAgIHRoaXMubXNnRGl2cy5sYXN0Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGFkZE5ld01lc3NhZ2UobXNnKSB7XG4gICAgaWYgKHRoaXMubGF0ZXN0TXNnRGF0ZXRpbWUgJiYgKG5ldyBEYXRlKG1zZy5jcmVhdGVkX2F0LnRvU3RyaW5nKCkpLmdldFRpbWUoKVxuICAgICAgLSB0aGlzLmxhdGVzdE1zZ0RhdGV0aW1lLmdldFRpbWUoKSkgLyA2MDAwMCA8IHRoaXMuR1JPVVBfTUlOX1JBTkdFX0lOX01JTlVURVMpIHtcbiAgICAgIHRoaXMuZ3JvdXBlZE1lc3NhZ2VMaXN0W3RoaXMuZ3JvdXBlZE1lc3NhZ2VMaXN0Lmxlbmd0aCAtIDFdLnB1c2gobXNnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5ncm91cGVkTWVzc2FnZUxpc3QucHVzaChbbXNnXSk7XG4gICAgfVxuICAgIHRoaXMubGF0ZXN0TXNnRGF0ZXRpbWUgPSBuZXcgRGF0ZShtc2cuY3JlYXRlZF9hdC50b1N0cmluZygpKTtcbiAgfVxuXG4gIGFkZE5ld01lc3NhZ2VzUGFnZShtc2dMaXN0OiBQcmV2aWV3TWVzc2FnZVtdKSB7XG4gICAgaWYgKHRoaXMubXNnRGl2cyAmJiB0aGlzLm1zZ0RpdnMuZmlyc3QpIHtcbiAgICAgIGNvbnN0IGZpcnN0RGl2ID0gdGhpcy5tc2dEaXZzLmZpcnN0O1xuICAgICAgY29uc3Qgb25OZXdQYWdlQWRkZWQgPSAoKSA9PiB7XG4gICAgICAgIGZpcnN0RGl2Lm5hdGl2ZUVsZW1lbnQuc2Nyb2xsSW50b1ZpZXcodHJ1ZSk7XG4gICAgICAgIHRoaXMubXNnc0NvbnRhaW5lci5uYXRpdmVFbGVtZW50LnNjcm9sbEJ5KDAsIC05MCk7XG4gICAgICB9O1xuICAgICAgdGhpcy5tc2dzQ29udGFpbmVyLm5hdGl2ZUVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignRE9NTm9kZUluc2VydGVkJywgb25OZXdQYWdlQWRkZWQsIGZhbHNlKTtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5tc2dzQ29udGFpbmVyLm5hdGl2ZUVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcignRE9NTm9kZUluc2VydGVkJywgb25OZXdQYWdlQWRkZWQsIGZhbHNlKSk7XG4gICAgfVxuXG4gICAgY29uc3QgZ3JvdXBpbmdPYmogPSB0aGlzLmdyb3VwQnlUaW1lKG1zZ0xpc3QpO1xuICAgIGlmIChncm91cGluZ09iaikge1xuICAgICAgdGhpcy5ncm91cGVkTWVzc2FnZUxpc3QgPSBncm91cGluZ09iai5ncm91cGVkTGlzdC5jb25jYXQodGhpcy5ncm91cGVkTWVzc2FnZUxpc3QpO1xuICAgICAgdGhpcy5sYXRlc3RNc2dEYXRldGltZSA9IGdyb3VwaW5nT2JqLmxhdGVzdE1zZ0RhdGV0aW1lO1xuICAgIH1cblxuICB9XG5cbiAgZ3JvdXBCeVRpbWUobXNnTGlzdDogUHJldmlld01lc3NhZ2VbXSkge1xuICAgIGlmICghbXNnTGlzdC5sZW5ndGgpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGV0IGdyb3VwZWRMaXN0ID0gW107XG4gICAgbGV0IGFkamFjZW50TGlzdCA9IFtdO1xuICAgIGxldCBsYXRlc3RNc2dEYXRldGltZSA9IG5ldyBEYXRlKG1zZ0xpc3RbMF0uY3JlYXRlZF9hdC50b1N0cmluZygpKTtcbiAgICBtc2dMaXN0LmZvckVhY2goKG1lc3NhZ2UpID0+IHtcbiAgICAgIGlmICgobmV3IERhdGUobWVzc2FnZS5jcmVhdGVkX2F0LnRvU3RyaW5nKCkpLmdldFRpbWUoKSAtIGxhdGVzdE1zZ0RhdGV0aW1lLmdldFRpbWUoKSkgLyA2MDAwMCA8IHRoaXMuR1JPVVBfTUlOX1JBTkdFX0lOX01JTlVURVMpIHtcbiAgICAgICAgYWRqYWNlbnRMaXN0LnB1c2gobWVzc2FnZSk7XG4gICAgICAgIGxhdGVzdE1zZ0RhdGV0aW1lID0gbmV3IERhdGUobWVzc2FnZS5jcmVhdGVkX2F0LnRvU3RyaW5nKCkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZ3JvdXBlZExpc3QucHVzaChhZGphY2VudExpc3QpO1xuICAgICAgICBhZGphY2VudExpc3QgPSBbbWVzc2FnZV07XG4gICAgICAgIGxhdGVzdE1zZ0RhdGV0aW1lID0gbmV3IERhdGUobWVzc2FnZS5jcmVhdGVkX2F0LnRvU3RyaW5nKCkpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGdyb3VwZWRMaXN0LnB1c2goYWRqYWNlbnRMaXN0KTtcblxuICAgIHJldHVybiB7XG4gICAgICBncm91cGVkTGlzdCxcbiAgICAgIGxhdGVzdE1zZ0RhdGV0aW1lXG4gICAgfTtcbiAgfVxuXG4gIHJlcGx5KCkge1xuICAgIHRoaXMubWVzc2FnaW5nU2VydmljZS5zZW5kX21lc3NhZ2UodGhpcy5yZXBseUNvbnRlbnQsIHRoaXMuZG9ub3JfaWQpO1xuICAgIHRoaXMucmVwbHlDb250ZW50ID0gJyc7XG4gICAgdGhpcy5tc2dJbnB1dC5uYXRpdmVFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2ZvY3Vzb3V0JywgdGhpcy5mb2N1c09uSW5wdXRBZ2Fpbi5iaW5kKHRoaXMpKTtcbiAgfVxuXG4gIGZvY3VzT25JbnB1dEFnYWluKGV2ZW50KSB7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLm1zZ0lucHV0Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcbiAgICAgIHRoaXMubXNnSW5wdXQubmF0aXZlRWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdmb2N1c291dCcsIHRoaXMuZm9jdXNPbklucHV0QWdhaW4uYmluZCh0aGlzKSk7XG4gICAgfSk7XG4gIH1cblxuICBvblNjcm9sbChldmVudDogYW55KSB7XG4gICAgaWYgKGV2ZW50LnRhcmdldC5zY3JvbGxUb3AgPT09IDApIHtcbiAgICAgIHRoaXMubG9hZE1vcmUoKTtcbiAgICB9XG4gIH1cblxuICBpc1RvZGF5KGRhdGUpIHtcbiAgICBkYXRlID0gbmV3IERhdGUoZGF0ZS50b1N0cmluZygpKTtcbiAgICBjb25zdCB0b2RheSA9IG5ldyBEYXRlKCk7XG4gICAgcmV0dXJuIGRhdGUuZ2V0RGF0ZSgpID09PSB0b2RheS5nZXREYXRlKCkgJiZcbiAgICAgIGRhdGUuZ2V0TW9udGgoKSA9PT0gdG9kYXkuZ2V0TW9udGgoKSAmJlxuICAgICAgZGF0ZS5nZXRGdWxsWWVhcigpID09PSB0b2RheS5nZXRGdWxsWWVhcigpO1xuICB9XG5cbiAgaXNZZXN0ZXJkYXkoZGF0ZSkge1xuICAgIGRhdGUgPSBuZXcgRGF0ZShkYXRlLnRvU3RyaW5nKCkpO1xuICAgIGxldCB0b0JlWWVzdGVyZGF5ID0gbmV3IERhdGUoKTtcbiAgICB0b0JlWWVzdGVyZGF5LnNldERhdGUodG9CZVllc3RlcmRheS5nZXREYXRlKCkgLSAxKTtcbiAgICBjb25zdCB5ZXN0ZXJkYXkgPSB0b0JlWWVzdGVyZGF5O1xuICAgIHJldHVybiBkYXRlLmdldERhdGUoKSA9PT0geWVzdGVyZGF5LmdldERhdGUoKSAmJlxuICAgICAgZGF0ZS5nZXRNb250aCgpID09PSB5ZXN0ZXJkYXkuZ2V0TW9udGgoKSAmJlxuICAgICAgZGF0ZS5nZXRGdWxsWWVhcigpID09PSB5ZXN0ZXJkYXkuZ2V0RnVsbFllYXIoKTtcbiAgfVxuXG4gIGlzV2Vla0RheShkYXRlKSB7XG4gICAgaWYgKHRoaXMuaXNUb2RheShkYXRlKSB8fCB0aGlzLmlzWWVzdGVyZGF5KGRhdGUpKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGxldCB3ZWVrQWdvID0gbmV3IERhdGUoKTtcbiAgICB3ZWVrQWdvLnNldERhdGUod2Vla0Fnby5nZXREYXRlKCkgLSA3KTtcbiAgICByZXR1cm4gbmV3IERhdGUoZGF0ZS50b1N0cmluZygpKSA+IHdlZWtBZ287XG4gIH1cblxuICBnZXREYXlOYW1lKGRhdGUpIHtcbiAgICByZXR1cm4gbmV3IERhdGUoZGF0ZS50b1N0cmluZygpKS50b0xvY2FsZVN0cmluZygnZW4tdXMnLCB7d2Vla2RheTogJ3Nob3J0JyB9KTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMubWVzc2FnaW5nU2VydmljZS5yZW1vdmVPbk1lc3NhZ2VMaXN0ZW5lcigpO1xuICB9XG5cbn1cbiJdfQ==