UNPKG

@hsaadawy/ngx-chat

Version:
194 lines 31.6 kB
import { __awaiter } from "tslib"; import { Injectable } from '@angular/core'; import { jid as parseJid } from '@xmpp/client'; import { BehaviorSubject, combineLatest, merge, Subject } from 'rxjs'; import { filter, map } from 'rxjs/operators'; import { dummyAvatarContact } from '../../../core/contact-avatar'; import { defaultTranslations } from '../../../core/translations-default'; import { ContactFactoryService } from '../../contact-factory.service'; import { LogService } from '../../log.service'; import { MessageArchivePlugin } from './plugins/message-archive.plugin'; import { MessagePlugin } from './plugins/message.plugin'; import { MultiUserChatPlugin } from './plugins/multi-user-chat.plugin'; import { RosterPlugin } from './plugins/roster.plugin'; import { XmppChatConnectionService } from './xmpp-chat-connection.service'; export class XmppChatAdapter { constructor(chatConnectionService, logService, contactFactory) { this.chatConnectionService = chatConnectionService; this.logService = logService; this.contactFactory = contactFactory; this.message$ = new Subject(); this.messageSent$ = new Subject(); this.contacts$ = new BehaviorSubject([]); this.contactCreated$ = new Subject(); this.blockedContactIds$ = new BehaviorSubject(new Set()); this.blockedContacts$ = combineLatest([this.contacts$, this.blockedContactIds$]) .pipe(map(([contacts, blockedJids]) => contacts.filter(contact => blockedJids.has(contact.jidBare.toString())))); this.notBlockedContacts$ = combineLatest([this.contacts$, this.blockedContactIds$]) .pipe(map(([contacts, blockedJids]) => contacts.filter(contact => !blockedJids.has(contact.jidBare.toString())))); this.contactsSubscribed$ = this.notBlockedContacts$.pipe(map(contacts => contacts.filter(contact => contact.isSubscribed()))); this.contactRequestsReceived$ = this.notBlockedContacts$.pipe(map(contacts => contacts.filter(contact => contact.pendingIn$.getValue()))); this.contactRequestsSent$ = this.notBlockedContacts$.pipe(map(contacts => contacts.filter(contact => contact.pendingOut$.getValue()))); this.contactsUnaffiliated$ = this.notBlockedContacts$.pipe(map(contacts => contacts.filter(contact => contact.isUnaffiliated() && contact.messages.length > 0))); this.state$ = new BehaviorSubject('disconnected'); this.plugins = []; this.enableDebugging = false; this.userAvatar$ = new BehaviorSubject(dummyAvatarContact); this.translations = defaultTranslations(); this.chatActions = [{ id: 'sendMessage', cssClass: 'chat-window-send', html: '&raquo;', onClick: (chatActionContext) => { chatActionContext.chatWindow.sendMessage(); }, }]; this.state$.subscribe((state) => this.logService.info('state changed to:', state)); chatConnectionService.state$ .pipe(filter(nextState => nextState !== this.state$.getValue())) .subscribe((nextState) => { this.handleInternalStateChange(nextState); }); this.chatConnectionService.stanzaUnknown$.subscribe((stanza) => this.onUnknownStanza(stanza)); merge(this.messageSent$, this.message$).subscribe(() => { // re-emit contacts when sending or receiving a message to refresh contcat groups // if the sending contact was in 'other', he still is in other now, but passes the 'messages.length > 0' predicate, so that // he should be seen now. this.contacts$.next(this.contacts$.getValue()); }); } handleInternalStateChange(internalState) { if (internalState === 'online') { this.state$.next('connecting'); Promise.all(this.plugins.map(plugin => plugin.onBeforeOnline())) .then(() => this.announceAvailability(), (e) => { this.logService.error('error while connecting', e); this.announceAvailability(); }); } else { if (this.state$.getValue() === 'online') { // clear data the first time we transition to a not-online state this.onOffline(); } this.state$.next('disconnected'); } } onOffline() { this.contacts$.next([]); this.plugins.forEach(plugin => { try { plugin.onOffline(); } catch (e) { this.logService.error('error while handling offline in ', plugin); } }); } announceAvailability() { this.logService.info('announcing availability'); this.chatConnectionService.sendPresence(); this.state$.next('online'); } addPlugins(plugins) { plugins.forEach(plugin => { this.plugins.push(plugin); }); } reloadContacts() { this.getPlugin(RosterPlugin).refreshRosterContacts(); } getContactById(jidPlain) { const bareJidToFind = parseJid(jidPlain).bare(); return this.contacts$.getValue().find(contact => contact.jidBare.equals(bareJidToFind)); } getOrCreateContactById(jidPlain, name) { let contact = this.getContactById(jidPlain); if (!contact) { contact = this.contactFactory.createContact(parseJid(jidPlain).bare().toString(), name); this.contacts$.next([contact, ...this.contacts$.getValue()]); this.contactCreated$.next(contact); } return contact; } addContact(identifier) { this.getPlugin(RosterPlugin).addRosterContact(identifier); } removeContact(identifier) { this.getPlugin(RosterPlugin).removeRosterContact(identifier); } logIn(logInRequest) { return __awaiter(this, void 0, void 0, function* () { this.lastLogInRequest = logInRequest; if (this.state$.getValue() === 'disconnected') { yield this.chatConnectionService.logIn(logInRequest); } }); } logOut() { return this.chatConnectionService.logOut(); } sendMessage(recipient, body) { var _a; return __awaiter(this, void 0, void 0, function* () { const trimmedBody = body.trim(); if (trimmedBody.length === 0) { return; } switch (recipient.recipientType) { case 'room': yield this.getPlugin(MultiUserChatPlugin).sendMessage(recipient, trimmedBody); break; case 'contact': this.getPlugin(MessagePlugin).sendMessage(recipient, trimmedBody); this.messageSent$.next(recipient); break; default: throw new Error('invalid recipient type: ' + ((_a = recipient) === null || _a === void 0 ? void 0 : _a.recipientType)); } }); } loadCompleteHistory() { return this.getPlugin(MessageArchivePlugin).loadAllMessages(); } getPlugin(constructor) { for (const plugin of this.plugins) { if (plugin.constructor === constructor) { return plugin; } } throw new Error('plugin not found: ' + constructor); } onUnknownStanza(stanza) { let handled = false; for (const plugin of this.plugins) { try { if (plugin.handleStanza(stanza)) { this.logService.debug(plugin.constructor.name, 'handled', stanza.toString()); handled = true; } } catch (e) { this.logService.error('error handling stanza in ', plugin.constructor.name, e); } } if (!handled) { this.logService.warn('unknown stanza <=', stanza.toString()); } } reconnectSilently() { this.chatConnectionService.reconnectSilently(); } reconnect() { return this.logIn(this.lastLogInRequest); } } XmppChatAdapter.decorators = [ { type: Injectable } ]; XmppChatAdapter.ctorParameters = () => [ { type: XmppChatConnectionService }, { type: LogService }, { type: ContactFactoryService } ]; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieG1wcC1jaGF0LWFkYXB0ZXIuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3BhenpuZXR3b3JrL25neC1jaGF0L3NyYy9saWIvc2VydmljZXMvYWRhcHRlcnMveG1wcC94bXBwLWNoYXQtYWRhcHRlci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxHQUFHLElBQUksUUFBUSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQy9DLE9BQU8sRUFBRSxlQUFlLEVBQUUsYUFBYSxFQUFFLEtBQUssRUFBYyxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDbEYsT0FBTyxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUc3QyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQU1sRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQztBQUV6RSxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUN0RSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDL0MsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDeEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN2RCxPQUFPLEVBQUUseUJBQXlCLEVBQWtCLE1BQU0sZ0NBQWdDLENBQUM7QUFHM0YsTUFBTSxPQUFPLGVBQWU7SUFnRHhCLFlBQ1cscUJBQWdELEVBQy9DLFVBQXNCLEVBQ3RCLGNBQXFDO1FB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USxFQUFFLENBQUMsQ0FBQztTQUNoRTtJQUVMLENBQUM7SUFFRCxpQkFBaUI7UUFDYixJQUFJLENBQUMscUJBQXFCLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztJQUNuRCxDQUFDO0lBRUQsU0FBUztRQUNMLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUM3QyxDQUFDOzs7WUFqTkosVUFBVTs7O1lBRkYseUJBQXlCO1lBTHpCLFVBQVU7WUFEVixxQkFBcUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IGppZCBhcyBwYXJzZUppZCB9IGZyb20gJ0B4bXBwL2NsaWVudCc7XHJcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgY29tYmluZUxhdGVzdCwgbWVyZ2UsIE9ic2VydmFibGUsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgZmlsdGVyLCBtYXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcbmltcG9ydCB7IENoYXRBY3Rpb25Db250ZXh0IH0gZnJvbSAnLi4vLi4vLi4vY29tcG9uZW50cy9jaGF0LXdpbmRvdy9jaGF0LXdpbmRvdy5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBDb250YWN0IH0gZnJvbSAnLi4vLi4vLi4vY29yZS9jb250YWN0JztcclxuaW1wb3J0IHsgZHVtbXlBdmF0YXJDb250YWN0IH0gZnJvbSAnLi4vLi4vLi4vY29yZS9jb250YWN0LWF2YXRhcic7XHJcbmltcG9ydCB7IExvZ0luUmVxdWVzdCB9IGZyb20gJy4uLy4uLy4uL2NvcmUvbG9nLWluLXJlcXVlc3QnO1xyXG5pbXBvcnQgeyBDaGF0UGx1Z2luIH0gZnJvbSAnLi4vLi4vLi4vY29yZS9wbHVnaW4nO1xyXG5pbXBvcnQgeyBSZWNpcGllbnQgfSBmcm9tICcuLi8uLi8uLi9jb3JlL3JlY2lwaWVudCc7XHJcbmltcG9ydCB7IFN0YW56YSB9IGZyb20gJy4uLy4uLy4uL2NvcmUvc3RhbnphJztcclxuaW1wb3J0IHsgVHJhbnNsYXRpb25zIH0gZnJvbSAnLi4vLi4vLi4vY29yZS90cmFuc2xhdGlvbnMnO1xyXG5pbXBvcnQgeyBkZWZhdWx0VHJhbnNsYXRpb25zIH0gZnJvbSAnLi4vLi4vLi4vY29yZS90cmFuc2xhdGlvbnMtZGVmYXVsdCc7XHJcbmltcG9ydCB7IENoYXRTZXJ2aWNlLCBDb25uZWN0aW9uU3RhdGVzIH0gZnJvbSAnLi4vLi4vY2hhdC1zZXJ2aWNlJztcclxuaW1wb3J0IHsgQ29udGFjdEZhY3RvcnlTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vY29udGFjdC1mYWN0b3J5LnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBMb2dTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vbG9nLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBNZXNzYWdlQXJjaGl2ZVBsdWdpbiB9IGZyb20gJy4vcGx1Z2lucy9tZXNzYWdlLWFyY2hpdmUucGx1Z2luJztcclxuaW1wb3J0IHsgTWVzc2FnZVBsdWdpbiB9IGZyb20gJy4vcGx1Z2lucy9tZXNzYWdlLnBsdWdpbic7XHJcbmltcG9ydCB7IE11bHRpVXNlckNoYXRQbHVnaW4gfSBmcm9tICcuL3BsdWdpbnMvbXVsdGktdXNlci1jaGF0LnBsdWdpbic7XHJcbmltcG9ydCB7IFJvc3RlclBsdWdpbiB9IGZyb20gJy4vcGx1Z2lucy9yb3N0ZXIucGx1Z2luJztcclxuaW1wb3J0IHsgWG1wcENoYXRDb25uZWN0aW9uU2VydmljZSwgWG1wcENoYXRTdGF0ZXMgfSBmcm9tICcuL3htcHAtY2hhdC1jb25uZWN0aW9uLnNlcnZpY2UnO1xyXG5cclxuQEluamVjdGFibGUoKVxyXG5leHBvcnQgY2xhc3MgWG1wcENoYXRBZGFwdGVyIGltcGxlbWVudHMgQ2hhdFNlcnZpY2Uge1xyXG5cclxuICAgIHJlYWRvbmx5IG1lc3NhZ2UkID0gbmV3IFN1YmplY3Q8Q29udGFjdD4oKTtcclxuICAgIHJlYWRvbmx5IG1lc3NhZ2VTZW50JDogU3ViamVjdDxDb250YWN0PiA9IG5ldyBTdWJqZWN0KCk7XHJcblxyXG4gICAgcmVhZG9ubHkgY29udGFjdHMkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxDb250YWN0W10+KFtdKTtcclxuICAgIHJlYWRvbmx5IGNvbnRhY3RDcmVhdGVkJCA9IG5ldyBTdWJqZWN0PENvbnRhY3Q+KCk7XHJcblxyXG4gICAgcmVhZG9ubHkgYmxvY2tlZENvbnRhY3RJZHMkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxTZXQ8c3RyaW5nPj4obmV3IFNldDxzdHJpbmc+KCkpO1xyXG4gICAgcmVhZG9ubHkgYmxvY2tlZENvbnRhY3RzJCA9IGNvbWJpbmVMYXRlc3QoW3RoaXMuY29udGFjdHMkLCB0aGlzLmJsb2NrZWRDb250YWN0SWRzJF0pXHJcbiAgICAgICAgLnBpcGUoXHJcbiAgICAgICAgICAgIG1hcChcclxuICAgICAgICAgICAgICAgIChbY29udGFjdHMsIGJsb2NrZWRKaWRzXSkgPT5cclxuICAgICAgICAgICAgICAgICAgICBjb250YWN0cy5maWx0ZXIoY29udGFjdCA9PiBibG9ja2VkSmlkcy5oYXMoY29udGFjdC5qaWRCYXJlLnRvU3RyaW5nKCkpKSxcclxuICAgICAgICAgICAgKSxcclxuICAgICAgICApO1xyXG4gICAgcmVhZG9ubHkgbm90QmxvY2tlZENvbnRhY3RzJCA9IGNvbWJpbmVMYXRlc3QoW3RoaXMuY29udGFjdHMkLCB0aGlzLmJsb2NrZWRDb250YWN0SWRzJF0pXHJcbiAgICAgICAgLnBpcGUoXHJcbiAgICAgICAgICAgIG1hcChcclxuICAgICAgICAgICAgICAgIChbY29udGFjdHMsIGJsb2NrZWRKaWRzXSkgPT5cclxuICAgICAgICAgICAgICAgICAgICBjb250YWN0cy5maWx0ZXIoY29udGFjdCA9PiAhYmxvY2tlZEppZHMuaGFzKGNvbnRhY3QuamlkQmFyZS50b1N0cmluZygpKSksXHJcbiAgICAgICAgICAgICksXHJcbiAgICAgICAgKTtcclxuICAgIHJlYWRvbmx5IGNvbnRhY3RzU3Vic2NyaWJlZCQ6IE9ic2VydmFibGU8Q29udGFjdFtdPiA9IHRoaXMubm90QmxvY2tlZENvbnRhY3RzJC5waXBlKFxyXG4gICAgICAgIG1hcChjb250YWN0cyA9PiBjb250YWN0cy5maWx0ZXIoY29udGFjdCA9PiBjb250YWN0LmlzU3Vic2NyaWJlZCgpKSkpO1xyXG4gICAgcmVhZG9ubHkgY29udGFjdFJlcXVlc3RzUmVjZWl2ZWQkOiBPYnNlcnZhYmxlPENvbnRhY3RbXT4gPSB0aGlzLm5vdEJsb2NrZWRDb250YWN0cyQucGlwZShcclxuICAgICAgICBtYXAoY29udGFjdHMgPT4gY29udGFjdHMuZmlsdGVyKGNvbnRhY3QgPT4gY29udGFjdC5wZW5kaW5nSW4kLmdldFZhbHVlKCkpKSk7XHJcbiAgICByZWFkb25seSBjb250YWN0UmVxdWVzdHNTZW50JDogT2JzZXJ2YWJsZTxDb250YWN0W10+ID0gdGhpcy5ub3RCbG9ja2VkQ29udGFjdHMkLnBpcGUoXHJcbiAgICAgICAgbWFwKGNvbnRhY3RzID0+IGNvbnRhY3RzLmZpbHRlcihjb250YWN0ID0+IGNvbnRhY3QucGVuZGluZ091dCQuZ2V0VmFsdWUoKSkpKTtcclxuICAgIHJlYWRvbmx5IGNvbnRhY3RzVW5hZmZpbGlhdGVkJDogT2JzZXJ2YWJsZTxDb250YWN0W10+ID0gdGhpcy5ub3RCbG9ja2VkQ29udGFjdHMkLnBpcGUoXHJcbiAgICAgICAgbWFwKGNvbnRhY3RzID0+IGNvbnRhY3RzLmZpbHRlcihjb250YWN0ID0+IGNvbnRhY3QuaXNVbmFmZmlsaWF0ZWQoKSAmJiBjb250YWN0Lm1lc3NhZ2VzLmxlbmd0aCA+IDApKSk7XHJcbiAgICByZWFkb25seSBzdGF0ZSQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PENvbm5lY3Rpb25TdGF0ZXM+KCdkaXNjb25uZWN0ZWQnKTtcclxuICAgIHJlYWRvbmx5IHBsdWdpbnM6IENoYXRQbHVnaW5bXSA9IFtdO1xyXG4gICAgZW5hYmxlRGVidWdnaW5nID0gZmFsc2U7XHJcbiAgICByZWFkb25seSB1c2VyQXZhdGFyJCA9IG5ldyBCZWhhdmlvclN1YmplY3QoZHVtbXlBdmF0YXJDb250YWN0KTtcclxuICAgIHRyYW5zbGF0aW9uczogVHJhbnNsYXRpb25zID0gZGVmYXVsdFRyYW5zbGF0aW9ucygpO1xyXG5cclxuICAgIGNoYXRBY3Rpb25zID0gW3tcclxuICAgICAgICBpZDogJ3NlbmRNZXNzYWdlJyxcclxuICAgICAgICBjc3NDbGFzczogJ2NoYXQtd2luZG93LXNlbmQnLFxyXG4gICAgICAgIGh0bWw6ICcmcmFxdW87JyxcclxuICAgICAgICBvbkNsaWNrOiAoY2hhdEFjdGlvbkNvbnRleHQ6IENoYXRBY3Rpb25Db250ZXh0KSA9PiB7XHJcbiAgICAgICAgICAgIGNoYXRBY3Rpb25Db250ZXh0LmNoYXRXaW5kb3cuc2VuZE1lc3NhZ2UoKTtcclxuICAgICAgICB9LFxyXG4gICAgfV07XHJcblxyXG4gICAgcHJpdmF0ZSBsYXN0TG9nSW5SZXF1ZXN0OiBMb2dJblJlcXVlc3Q7XHJcblxyXG4gICAgY29uc3RydWN0b3IoXHJcbiAgICAgICAgcHVibGljIGNoYXRDb25uZWN0aW9uU2VydmljZTogWG1wcENoYXRDb25uZWN0aW9uU2VydmljZSxcclxuICAgICAgICBwcml2YXRlIGxvZ1NlcnZpY2U6IExvZ1NlcnZpY2UsXHJcbiAgICAgICAgcHJpdmF0ZSBjb250YWN0RmFjdG9yeTogQ29udGFjdEZhY3RvcnlTZXJ2aWNlLFxyXG4gICAgKSB7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSQuc3Vic2NyaWJlKChzdGF0ZSkgPT4gdGhpcy5sb2dTZXJ2aWNlLmluZm8oJ3N0YXRlIGNoYW5nZWQgdG86Jywgc3RhdGUpKTtcclxuICAgICAgICBjaGF0Q29ubmVjdGlvblNlcnZpY2Uuc3RhdGUkXHJcbiAgICAgICAgICAgIC5waXBlKGZpbHRlcihuZXh0U3RhdGUgPT4gbmV4dFN0YXRlICE9PSB0aGlzLnN0YXRlJC5nZXRWYWx1ZSgpKSlcclxuICAgICAgICAgICAgLnN1YnNjcmliZSgobmV4dFN0YXRlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmhhbmRsZUludGVybmFsU3RhdGVDaGFuZ2UobmV4dFN0YXRlKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5jaGF0Q29ubmVjdGlvblNlcnZpY2Uuc3RhbnphVW5rbm93biQuc3Vic2NyaWJlKChzdGFuemEpID0+IHRoaXMub25Vbmtub3duU3RhbnphKHN0YW56YSkpO1xyXG5cclxuICAgICAgICBtZXJnZSh0aGlzLm1lc3NhZ2VTZW50JCwgdGhpcy5tZXNzYWdlJCkuc3Vic2NyaWJlKCgpID0+IHtcclxuICAgICAgICAgICAgLy8gcmUtZW1pdCBjb250YWN0cyB3aGVuIHNlbmRpbmcgb3IgcmVjZWl2aW5nIGEgbWVzc2FnZSB0byByZWZyZXNoIGNvbnRjYXQgZ3JvdXBzXHJcbiAgICAgICAgICAgIC8vIGlmIHRoZSBzZW5kaW5nIGNvbnRhY3Qgd2FzIGluICdvdGhlcicsIGhlIHN0aWxsIGlzIGluIG90aGVyIG5vdywgYnV0IHBhc3NlcyB0aGUgJ21lc3NhZ2VzLmxlbmd0aCA+IDAnIHByZWRpY2F0ZSwgc28gdGhhdFxyXG4gICAgICAgICAgICAvLyBoZSBzaG91bGQgYmUgc2VlbiBub3cuXHJcbiAgICAgICAgICAgIHRoaXMuY29udGFjdHMkLm5leHQodGhpcy5jb250YWN0cyQuZ2V0VmFsdWUoKSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBoYW5kbGVJbnRlcm5hbFN0YXRlQ2hhbmdlKGludGVybmFsU3RhdGU6IFhtcHBDaGF0U3RhdGVzKSB7XHJcbiAgICAgICAgaWYgKGludGVybmFsU3RhdGUgPT09ICdvbmxpbmUnKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc3RhdGUkLm5leHQoJ2Nvbm5lY3RpbmcnKTtcclxuICAgICAgICAgICAgUHJvbWlzZS5hbGwodGhpcy5wbHVnaW5zLm1hcChwbHVnaW4gPT4gcGx1Z2luLm9uQmVmb3JlT25saW5lKCkpKVxyXG4gICAgICAgICAgICAgICAgLnRoZW4oXHJcbiAgICAgICAgICAgICAgICAgICAgKCkgPT4gdGhpcy5hbm5vdW5jZUF2YWlsYWJpbGl0eSgpLFxyXG4gICAgICAgICAgICAgICAgICAgIChlKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMubG9nU2VydmljZS5lcnJvcignZXJyb3Igd2hpbGUgY29ubmVjdGluZycsIGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFubm91bmNlQXZhaWxhYmlsaXR5KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuc3RhdGUkLmdldFZhbHVlKCkgPT09ICdvbmxpbmUnKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBjbGVhciBkYXRhIHRoZSBmaXJzdCB0aW1lIHdlIHRyYW5zaXRpb24gdG8gYSBub3Qtb25saW5lIHN0YXRlXHJcbiAgICAgICAgICAgICAgICB0aGlzLm9uT2ZmbGluZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuc3RhdGUkLm5leHQoJ2Rpc2Nvbm5lY3RlZCcpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIG9uT2ZmbGluZSgpIHtcclxuICAgICAgICB0aGlzLmNvbnRhY3RzJC5uZXh0KFtdKTtcclxuICAgICAgICB0aGlzLnBsdWdpbnMuZm9yRWFjaChwbHVnaW4gPT4ge1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgcGx1Z2luLm9uT2ZmbGluZSgpO1xyXG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxvZ1NlcnZpY2UuZXJyb3IoJ2Vycm9yIHdoaWxlIGhhbmRsaW5nIG9mZmxpbmUgaW4gJywgcGx1Z2luKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHByaXZhdGUgYW5ub3VuY2VBdmFpbGFiaWxpdHkoKSB7XHJcbiAgICAgICAgdGhpcy5sb2dTZXJ2aWNlLmluZm8oJ2Fubm91bmNpbmcgYXZhaWxhYmlsaXR5Jyk7XHJcbiAgICAgICAgdGhpcy5jaGF0Q29ubmVjdGlvblNlcnZpY2Uuc2VuZFByZXNlbmNlKCk7XHJcbiAgICAgICAgdGhpcy5zdGF0ZSQubmV4dCgnb25saW5lJyk7XHJcbiAgICB9XHJcblxyXG4gICAgYWRkUGx1Z2lucyhwbHVnaW5zOiBDaGF0UGx1Z2luW10pIHtcclxuICAgICAgICBwbHVnaW5zLmZvckVhY2gocGx1Z2luID0+IHtcclxuICAgICAgICAgICAgdGhpcy5wbHVnaW5zLnB1c2gocGx1Z2luKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICByZWxvYWRDb250YWN0cygpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmdldFBsdWdpbihSb3N0ZXJQbHVnaW4pLnJlZnJlc2hSb3N0ZXJDb250YWN0cygpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldENvbnRhY3RCeUlkKGppZFBsYWluOiBzdHJpbmcpIHtcclxuICAgICAgICBjb25zdCBiYXJlSmlkVG9GaW5kID0gcGFyc2VKaWQoamlkUGxhaW4pLmJhcmUoKTtcclxuICAgICAgICByZXR1cm4gdGhpcy5jb250YWN0cyQuZ2V0VmFsdWUoKS5maW5kKGNvbnRhY3QgPT4gY29udGFjdC5qaWRCYXJlLmVxdWFscyhiYXJlSmlkVG9GaW5kKSk7XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0T3JDcmVhdGVDb250YWN0QnlJZChqaWRQbGFpbjogc3RyaW5nLCBuYW1lPzogc3RyaW5nKSB7XHJcbiAgICAgICAgbGV0IGNvbnRhY3QgPSB0aGlzLmdldENvbnRhY3RCeUlkKGppZFBsYWluKTtcclxuICAgICAgICBpZiAoIWNvbnRhY3QpIHtcclxuICAgICAgICAgICAgY29udGFjdCA9IHRoaXMuY29udGFjdEZhY3RvcnkuY3JlYXRlQ29udGFjdChwYXJzZUppZChqaWRQbGFpbikuYmFyZSgpLnRvU3RyaW5nKCksIG5hbWUpO1xyXG4gICAgICAgICAgICB0aGlzLmNvbnRhY3RzJC5uZXh0KFtjb250YWN0LCAuLi50aGlzLmNvbnRhY3RzJC5nZXRWYWx1ZSgpXSk7XHJcbiAgICAgICAgICAgIHRoaXMuY29udGFjdENyZWF0ZWQkLm5leHQoY29udGFjdCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBjb250YWN0O1xyXG4gICAgfVxyXG5cclxuICAgIGFkZENvbnRhY3QoaWRlbnRpZmllcjogc3RyaW5nKSB7XHJcbiAgICAgICAgdGhpcy5nZXRQbHVnaW4oUm9zdGVyUGx1Z2luKS5hZGRSb3N0ZXJDb250YWN0KGlkZW50aWZpZXIpO1xyXG4gICAgfVxyXG5cclxuICAgIHJlbW92ZUNvbnRhY3QoaWRlbnRpZmllcjogc3RyaW5nKSB7XHJcbiAgICAgICAgdGhpcy5nZXRQbHVnaW4oUm9zdGVyUGx1Z2luKS5yZW1vdmVSb3N0ZXJDb250YWN0KGlkZW50aWZpZXIpO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIGxvZ0luKGxvZ0luUmVxdWVzdDogTG9nSW5SZXF1ZXN0KSB7XHJcbiAgICAgICAgdGhpcy5sYXN0TG9nSW5SZXF1ZXN0ID0gbG9nSW5SZXF1ZXN0O1xyXG4gICAgICAgIGlmICh0aGlzLnN0YXRlJC5nZXRWYWx1ZSgpID09PSAnZGlzY29ubmVjdGVkJykge1xyXG4gICAgICAgICAgICBhd2FpdCB0aGlzLmNoYXRDb25uZWN0aW9uU2VydmljZS5sb2dJbihsb2dJblJlcXVlc3QpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBsb2dPdXQoKTogUHJvbWlzZTx2b2lkPiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY2hhdENvbm5lY3Rpb25TZXJ2aWNlLmxvZ091dCgpO1xyXG4gICAgfVxyXG5cclxuICAgIGFzeW5jIHNlbmRNZXNzYWdlKHJlY2lwaWVudDogUmVjaXBpZW50LCBib2R5OiBzdHJpbmcpIHtcclxuICAgICAgICBjb25zdCB0cmltbWVkQm9keSA9IGJvZHkudHJpbSgpO1xyXG4gICAgICAgIGlmICh0cmltbWVkQm9keS5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICBzd2l0Y2ggKHJlY2lwaWVudC5yZWNpcGllbnRUeXBlKSB7XHJcbiAgICAgICAgICAgIGNhc2UgJ3Jvb20nOlxyXG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5nZXRQbHVnaW4oTXVsdGlVc2VyQ2hhdFBsdWdpbikuc2VuZE1lc3NhZ2UocmVjaXBpZW50LCB0cmltbWVkQm9keSk7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSAnY29udGFjdCc6XHJcbiAgICAgICAgICAgICAgICB0aGlzLmdldFBsdWdpbihNZXNzYWdlUGx1Z2luKS5zZW5kTWVzc2FnZShyZWNpcGllbnQsIHRyaW1tZWRCb2R5KTtcclxuICAgICAgICAgICAgICAgIHRoaXMubWVzc2FnZVNlbnQkLm5leHQocmVjaXBpZW50KTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdpbnZhbGlkIHJlY2lwaWVudCB0eXBlOiAnICsgKHJlY2lwaWVudCBhcyBhbnkpPy5yZWNpcGllbnRUeXBlKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgbG9hZENvbXBsZXRlSGlzdG9yeSgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5nZXRQbHVnaW4oTWVzc2FnZUFyY2hpdmVQbHVnaW4pLmxvYWRBbGxNZXNzYWdlcygpO1xyXG4gICAgfVxyXG5cclxuICAgIGdldFBsdWdpbjxUIGV4dGVuZHMgQ2hhdFBsdWdpbj4oY29uc3RydWN0b3I6IG5ldyguLi5hcmdzOiBhbnlbXSkgPT4gVCk6IFQge1xyXG4gICAgICAgIGZvciAoY29uc3QgcGx1Z2luIG9mIHRoaXMucGx1Z2lucykge1xyXG4gICAgICAgICAgICBpZiAocGx1Z2luLmNvbnN0cnVjdG9yID09PSBjb25zdHJ1Y3Rvcikge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHBsdWdpbiBhcyBUO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcigncGx1Z2luIG5vdCBmb3VuZDogJyArIGNvbnN0cnVjdG9yKTtcclxuICAgIH1cclxuXHJcbiAgICBwcml2YXRlIG9uVW5rbm93blN0YW56YShzdGFuemE6IFN0YW56YSkge1xyXG5cclxuICAgICAgICBsZXQgaGFuZGxlZCA9IGZhbHNlO1xyXG5cclxuICAgICAgICBmb3IgKGNvbnN0IHBsdWdpbiBvZiB0aGlzLnBsdWdpbnMpIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIGlmIChwbHVnaW4uaGFuZGxlU3RhbnphKHN0YW56YSkpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmxvZ1NlcnZpY2UuZGVidWcocGx1Z2luLmNvbnN0cnVjdG9yLm5hbWUsICdoYW5kbGVkJywgc3RhbnphLnRvU3RyaW5nKCkpO1xyXG4gICAgICAgICAgICAgICAgICAgIGhhbmRsZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxvZ1NlcnZpY2UuZXJyb3IoJ2Vycm9yIGhhbmRsaW5nIHN0YW56YSBpbiAnLCBwbHVnaW4uY29uc3RydWN0b3IubmFtZSwgZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghaGFuZGxlZCkge1xyXG4gICAgICAgICAgICB0aGlzLmxvZ1NlcnZpY2Uud2FybigndW5rbm93biBzdGFuemEgPD0nLCBzdGFuemEudG9TdHJpbmcoKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgIH1cclxuXHJcbiAgICByZWNvbm5lY3RTaWxlbnRseSgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLmNoYXRDb25uZWN0aW9uU2VydmljZS5yZWNvbm5lY3RTaWxlbnRseSgpO1xyXG4gICAgfVxyXG5cclxuICAgIHJlY29ubmVjdCgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5sb2dJbih0aGlzLmxhc3RMb2dJblJlcXVlc3QpO1xyXG4gICAgfVxyXG5cclxufVxyXG4iXX0=