@pazznetwork/ngx-chat
Version:
[](https://travis-ci.com/pazznetwork/ngx-chat) [](https://coveralls.io/github/pazzn
115 lines • 19.5 kB
JavaScript
import { xml } from '@xmpp/client';
import { BehaviorSubject } from 'rxjs';
import { first } from 'rxjs/operators';
import { AbstractStanzaBuilder } from '../abstract-stanza-builder';
import { AbstractXmppPlugin } from './abstract-xmpp-plugin';
class QueryStanzaBuilder extends AbstractStanzaBuilder {
constructor(xmlns, to) {
super();
this.xmlns = xmlns;
this.to = to;
}
toStanza() {
return xml('iq', {
type: 'get',
...(this.to ? { to: this.to } : {}),
}, xml('query', { xmlns: this.xmlns }));
}
}
/**
* see XEP-0030 Service Discovery
*/
export class ServiceDiscoveryPlugin extends AbstractXmppPlugin {
constructor(chatAdapter) {
super();
this.chatAdapter = chatAdapter;
this.servicesInitialized$ = new BehaviorSubject(false);
this.hostedServices = [];
this.resourceCache = new Map();
}
async onBeforeOnline() {
await this.discoverServices(this.chatAdapter.chatConnectionService.userJid.domain);
this.servicesInitialized$.next(true);
}
onOffline() {
this.servicesInitialized$.next(false);
this.hostedServices = [];
this.resourceCache.clear();
}
supportsFeature(jid, searchedFeature) {
return new Promise((resolve, reject) => {
this.servicesInitialized$.pipe(first(value => !!value)).subscribe(async () => {
try {
const service = this.resourceCache.get(jid) || await this.discoverServiceInformation(jid);
if (!service) {
reject(new Error('no service found for jid ' + jid));
}
resolve(service.features.includes(searchedFeature));
}
catch (e) {
reject(e);
}
});
});
}
findService(category, type) {
return new Promise((resolve, reject) => {
this.servicesInitialized$.pipe(first(value => !!value)).subscribe(() => {
const results = this.hostedServices.filter(service => service.identitiesAttrs.filter(identityAttrs => identityAttrs.category === category
&& identityAttrs.type === type).length > 0);
if (results.length === 0) {
reject(new Error(`no service matching category ${category} and type ${type} found!`));
}
else if (results.length > 1) {
reject(new Error(`multiple services matching category ${category} and type ${type} found! ${JSON.stringify(results)}`));
}
else {
return resolve(results[0]);
}
});
});
}
async discoverServices(mainDomain) {
const serviceListResponse = await this.chatAdapter.chatConnectionService.sendIq(new QueryStanzaBuilder(ServiceDiscoveryPlugin.DISCO_ITEMS, this.chatAdapter.chatConnectionService.userJid.domain).toStanza());
const serviceDomains = new Set(serviceListResponse
.getChild('query')
.getChildren('item')
.map((itemNode) => itemNode.attrs.jid));
serviceDomains.add(mainDomain);
const discoveredServices = await Promise.all([...serviceDomains.keys()]
.map((serviceDomain) => this.discoverServiceInformation(serviceDomain)));
this.hostedServices.push(...discoveredServices);
}
async discoverServiceInformation(serviceDomain) {
const serviceInformationResponse = await this.chatAdapter.chatConnectionService.sendIq(new QueryStanzaBuilder(ServiceDiscoveryPlugin.DISCO_INFO, serviceDomain).toStanza());
const queryNode = serviceInformationResponse.getChild('query');
const features = queryNode.getChildren('feature').map((featureNode) => featureNode.attrs.var);
const identitiesAttrs = queryNode
.getChildren('identity')
.filter((identityNode) => identityNode.attrs)
.map((identityNode) => identityNode.attrs);
const serviceInformation = {
identitiesAttrs: this.isIdentitiesAttrs(identitiesAttrs) ? identitiesAttrs : [],
features,
jid: serviceInformationResponse.attrs.from,
};
this.resourceCache.set(serviceInformationResponse.attrs.from, serviceInformation);
return serviceInformation;
}
isIdentitiesAttrs(elements) {
return elements.every((element) => {
const keys = Object.keys(element);
const mustHave = keys.includes('category') && keys.includes('type');
if (keys.length === 2) {
return mustHave;
}
else if (keys.length === 3) {
return mustHave && keys.includes('name');
}
return false;
});
}
}
ServiceDiscoveryPlugin.DISCO_INFO = 'http://jabber.org/protocol/disco#info';
ServiceDiscoveryPlugin.DISCO_ITEMS = 'http://jabber.org/protocol/disco#items';
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS1kaXNjb3ZlcnkucGx1Z2luLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9zZXJ2aWNlcy9hZGFwdGVycy94bXBwL3BsdWdpbnMvc2VydmljZS1kaXNjb3ZlcnkucGx1Z2luLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFFbkMsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN2QyxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDdkMsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFFbkUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFNUQsTUFBTSxrQkFBbUIsU0FBUSxxQkFBcUI7SUFFbEQsWUFBb0IsS0FBYSxFQUFVLEVBQVc7UUFDbEQsS0FBSyxFQUFFLENBQUM7UUFEUSxVQUFLLEdBQUwsS0FBSyxDQUFRO1FBQVUsT0FBRSxHQUFGLEVBQUUsQ0FBUztJQUV0RCxDQUFDO0lBRUQsUUFBUTtRQUNKLE9BQU8sR0FBRyxDQUFDLElBQUksRUFDWDtZQUNJLElBQUksRUFBRSxLQUFLO1lBQ1gsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFFLEVBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1NBQ3BDLEVBQ0QsR0FBRyxDQUFDLE9BQU8sRUFBRSxFQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFDLENBQUMsQ0FDcEMsQ0FBQztJQUNOLENBQUM7Q0FFSjtBQWNEOztHQUVHO0FBQ0gsTUFBTSxPQUFPLHNCQUF1QixTQUFRLGtCQUFrQjtJQVMxRCxZQUE2QixXQUE0QjtRQUNyRCxLQUFLLEVBQUUsQ0FBQztRQURpQixn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QUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNwRSxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO2dCQUNuQixPQUFPLFFBQVEsQ0FBQzthQUNuQjtpQkFBTSxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFO2dCQUMxQixPQUFPLFFBQVEsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2FBQzVDO1lBQ0QsT0FBTyxLQUFLLENBQUM7UUFDakIsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDOztBQXRIc0IsaUNBQVUsR0FBRyx1Q0FBdUMsQ0FBQztBQUNyRCxrQ0FBVyxHQUFHLHdDQUF3QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgeG1sIH0gZnJvbSAnQHhtcHAvY2xpZW50JztcbmltcG9ydCB7IEVsZW1lbnQgfSBmcm9tICdsdHgnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBmaXJzdCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IEFic3RyYWN0U3RhbnphQnVpbGRlciB9IGZyb20gJy4uL2Fic3RyYWN0LXN0YW56YS1idWlsZGVyJztcbmltcG9ydCB7IFhtcHBDaGF0QWRhcHRlciB9IGZyb20gJy4uL3htcHAtY2hhdC1hZGFwdGVyLnNlcnZpY2UnO1xuaW1wb3J0IHsgQWJzdHJhY3RYbXBwUGx1Z2luIH0gZnJvbSAnLi9hYnN0cmFjdC14bXBwLXBsdWdpbic7XG5cbmNsYXNzIFF1ZXJ5U3RhbnphQnVpbGRlciBleHRlbmRzIEFic3RyYWN0U3RhbnphQnVpbGRlciB7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIHhtbG5zOiBzdHJpbmcsIHByaXZhdGUgdG8/OiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG5cbiAgICB0b1N0YW56YSgpIHtcbiAgICAgICAgcmV0dXJuIHhtbCgnaXEnLFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR5cGU6ICdnZXQnLFxuICAgICAgICAgICAgICAgIC4uLih0aGlzLnRvID8ge3RvOiB0aGlzLnRvfSA6IHt9KSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB4bWwoJ3F1ZXJ5Jywge3htbG5zOiB0aGlzLnhtbG5zfSksXG4gICAgICAgICk7XG4gICAgfVxuXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSWRlbnRpdHlBdHRycyB7XG4gICAgY2F0ZWdvcnk6IHN0cmluZztcbiAgICB0eXBlOiBzdHJpbmc7XG4gICAgbmFtZT86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTZXJ2aWNlIHtcbiAgICBqaWQ6IHN0cmluZztcbiAgICBpZGVudGl0aWVzQXR0cnM6IElkZW50aXR5QXR0cnNbXTtcbiAgICBmZWF0dXJlczogc3RyaW5nW107XG59XG5cbi8qKlxuICogc2VlIFhFUC0wMDMwIFNlcnZpY2UgRGlzY292ZXJ5XG4gKi9cbmV4cG9ydCBjbGFzcyBTZXJ2aWNlRGlzY292ZXJ5UGx1Z2luIGV4dGVuZHMgQWJzdHJhY3RYbXBwUGx1Z2luIHtcblxuICAgIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgRElTQ09fSU5GTyA9ICdodHRwOi8vamFiYmVyLm9yZy9wcm90b2NvbC9kaXNjbyNpbmZvJztcbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IERJU0NPX0lURU1TID0gJ2h0dHA6Ly9qYWJiZXIub3JnL3Byb3RvY29sL2Rpc2NvI2l0ZW1zJztcblxuICAgIHByaXZhdGUgcmVhZG9ubHkgc2VydmljZXNJbml0aWFsaXplZCQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0KGZhbHNlKTtcbiAgICBwcml2YXRlIGhvc3RlZFNlcnZpY2VzOiBTZXJ2aWNlW10gPSBbXTtcbiAgICBwcml2YXRlIHJlYWRvbmx5IHJlc291cmNlQ2FjaGUgPSBuZXcgTWFwPHN0cmluZywgU2VydmljZT4oKTtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgY2hhdEFkYXB0ZXI6IFhtcHBDaGF0QWRhcHRlcikge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIGFzeW5jIG9uQmVmb3JlT25saW5lKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBhd2FpdCB0aGlzLmRpc2NvdmVyU2VydmljZXModGhpcy5jaGF0QWRhcHRlci5jaGF0Q29ubmVjdGlvblNlcnZpY2UudXNlckppZC5kb21haW4pO1xuICAgICAgICB0aGlzLnNlcnZpY2VzSW5pdGlhbGl6ZWQkLm5leHQodHJ1ZSk7XG4gICAgfVxuXG4gICAgb25PZmZsaW5lKCk6IHZvaWQge1xuICAgICAgICB0aGlzLnNlcnZpY2VzSW5pdGlhbGl6ZWQkLm5leHQoZmFsc2UpO1xuICAgICAgICB0aGlzLmhvc3RlZFNlcnZpY2VzID0gW107XG4gICAgICAgIHRoaXMucmVzb3VyY2VDYWNoZS5jbGVhcigpO1xuICAgIH1cblxuICAgIHN1cHBvcnRzRmVhdHVyZShqaWQ6IHN0cmluZywgc2VhcmNoZWRGZWF0dXJlOiBzdHJpbmcpOiBQcm9taXNlPGJvb2xlYW4+IHtcblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICB0aGlzLnNlcnZpY2VzSW5pdGlhbGl6ZWQkLnBpcGUoZmlyc3QodmFsdWUgPT4gISF2YWx1ZSkpLnN1YnNjcmliZShhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc2VydmljZSA9IHRoaXMucmVzb3VyY2VDYWNoZS5nZXQoamlkKSB8fCBhd2FpdCB0aGlzLmRpc2NvdmVyU2VydmljZUluZm9ybWF0aW9uKGppZCk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghc2VydmljZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcignbm8gc2VydmljZSBmb3VuZCBmb3IgamlkICcgKyBqaWQpKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXNvbHZlKHNlcnZpY2UuZmVhdHVyZXMuaW5jbHVkZXMoc2VhcmNoZWRGZWF0dXJlKSk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICByZWplY3QoZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgfSk7XG5cbiAgICB9XG5cbiAgICBmaW5kU2VydmljZShjYXRlZ29yeTogc3RyaW5nLCB0eXBlOiBzdHJpbmcpOiBQcm9taXNlPFNlcnZpY2U+IHtcblxuICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuXG4gICAgICAgICAgICB0aGlzLnNlcnZpY2VzSW5pdGlhbGl6ZWQkLnBpcGUoZmlyc3QodmFsdWUgPT4gISF2YWx1ZSkpLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0cyA9IHRoaXMuaG9zdGVkU2VydmljZXMuZmlsdGVyKHNlcnZpY2UgPT5cbiAgICAgICAgICAgICAgICAgICAgc2VydmljZS5pZGVudGl0aWVzQXR0cnMuZmlsdGVyKGlkZW50aXR5QXR0cnMgPT4gaWRlbnRpdHlBdHRycy5jYXRlZ29yeSA9PT0gY2F0ZWdvcnlcbiAgICAgICAgICAgICAgICAgICAgICAgICYmIGlkZW50aXR5QXR0cnMudHlwZSA9PT0gdHlwZSkubGVuZ3RoID4gMCxcbiAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlamVjdChuZXcgRXJyb3IoYG5vIHNlcnZpY2UgbWF0Y2hpbmcgY2F0ZWdvcnkgJHtjYXRlZ29yeX0gYW5kIHR5cGUgJHt0eXBlfSBmb3VuZCFgKSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChyZXN1bHRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgbXVsdGlwbGUgc2VydmljZXMgbWF0Y2hpbmcgY2F0ZWdvcnkgJHtjYXRlZ29yeX0gYW5kIHR5cGUgJHt0eXBlfSBmb3VuZCEgJHtKU09OLnN0cmluZ2lmeShyZXN1bHRzKX1gKSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmUocmVzdWx0c1swXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgfSk7XG5cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGRpc2NvdmVyU2VydmljZXMobWFpbkRvbWFpbjogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGNvbnN0IHNlcnZpY2VMaXN0UmVzcG9uc2UgPSBhd2FpdCB0aGlzLmNoYXRBZGFwdGVyLmNoYXRDb25uZWN0aW9uU2VydmljZS5zZW5kSXEoXG4gICAgICAgICAgICBuZXcgUXVlcnlTdGFuemFCdWlsZGVyKFxuICAgICAgICAgICAgICAgIFNlcnZpY2VEaXNjb3ZlcnlQbHVnaW4uRElTQ09fSVRFTVMsIHRoaXMuY2hhdEFkYXB0ZXIuY2hhdENvbm5lY3Rpb25TZXJ2aWNlLnVzZXJKaWQuZG9tYWluKS50b1N0YW56YSgpLFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IHNlcnZpY2VEb21haW5zID0gbmV3IFNldChcbiAgICAgICAgICAgIHNlcnZpY2VMaXN0UmVzcG9uc2VcbiAgICAgICAgICAgICAgICAuZ2V0Q2hpbGQoJ3F1ZXJ5JylcbiAgICAgICAgICAgICAgICAuZ2V0Q2hpbGRyZW4oJ2l0ZW0nKVxuICAgICAgICAgICAgICAgIC5tYXAoKGl0ZW1Ob2RlOiBFbGVtZW50KSA9PiBpdGVtTm9kZS5hdHRycy5qaWQgYXMgc3RyaW5nKSxcbiAgICAgICAgKTtcbiAgICAgICAgc2VydmljZURvbWFpbnMuYWRkKG1haW5Eb21haW4pO1xuXG4gICAgICAgIGNvbnN0IGRpc2NvdmVyZWRTZXJ2aWNlczogU2VydmljZVtdID0gYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICAgICAgICBbLi4uc2VydmljZURvbWFpbnMua2V5cygpXVxuICAgICAgICAgICAgICAgIC5tYXAoKHNlcnZpY2VEb21haW4pID0+IHRoaXMuZGlzY292ZXJTZXJ2aWNlSW5mb3JtYXRpb24oc2VydmljZURvbWFpbikpLFxuICAgICAgICApO1xuICAgICAgICB0aGlzLmhvc3RlZFNlcnZpY2VzLnB1c2goLi4uZGlzY292ZXJlZFNlcnZpY2VzKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIGRpc2NvdmVyU2VydmljZUluZm9ybWF0aW9uKHNlcnZpY2VEb21haW46IHN0cmluZyk6IFByb21pc2U8U2VydmljZT4ge1xuICAgICAgICBjb25zdCBzZXJ2aWNlSW5mb3JtYXRpb25SZXNwb25zZSA9IGF3YWl0IHRoaXMuY2hhdEFkYXB0ZXIuY2hhdENvbm5lY3Rpb25TZXJ2aWNlLnNlbmRJcShcbiAgICAgICAgICAgIG5ldyBRdWVyeVN0YW56YUJ1aWxkZXIoU2VydmljZURpc2NvdmVyeVBsdWdpbi5ESVNDT19JTkZPLCBzZXJ2aWNlRG9tYWluKS50b1N0YW56YSgpLFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IHF1ZXJ5Tm9kZSA9IHNlcnZpY2VJbmZvcm1hdGlvblJlc3BvbnNlLmdldENoaWxkKCdxdWVyeScpO1xuICAgICAgICBjb25zdCBmZWF0dXJlcyA9IHF1ZXJ5Tm9kZS5nZXRDaGlsZHJlbignZmVhdHVyZScpLm1hcCgoZmVhdHVyZU5vZGU6IEVsZW1lbnQpID0+IGZlYXR1cmVOb2RlLmF0dHJzLnZhcik7XG4gICAgICAgIGNvbnN0IGlkZW50aXRpZXNBdHRycyA9IHF1ZXJ5Tm9kZVxuICAgICAgICAgICAgLmdldENoaWxkcmVuKCdpZGVudGl0eScpXG4gICAgICAgICAgICAuZmlsdGVyKChpZGVudGl0eU5vZGU6IEVsZW1lbnQpID0+IGlkZW50aXR5Tm9kZS5hdHRycylcbiAgICAgICAgICAgIC5tYXAoKGlkZW50aXR5Tm9kZTogRWxlbWVudCkgPT4gaWRlbnRpdHlOb2RlLmF0dHJzKTtcblxuICAgICAgICBjb25zdCBzZXJ2aWNlSW5mb3JtYXRpb246IFNlcnZpY2UgPSB7XG4gICAgICAgICAgICBpZGVudGl0aWVzQXR0cnM6IHRoaXMuaXNJZGVudGl0aWVzQXR0cnMoaWRlbnRpdGllc0F0dHJzKSA/IGlkZW50aXRpZXNBdHRycyA6IFtdLFxuICAgICAgICAgICAgZmVhdHVyZXMsXG4gICAgICAgICAgICBqaWQ6IHNlcnZpY2VJbmZvcm1hdGlvblJlc3BvbnNlLmF0dHJzLmZyb20sXG4gICAgICAgIH07XG4gICAgICAgIHRoaXMucmVzb3VyY2VDYWNoZS5zZXQoc2VydmljZUluZm9ybWF0aW9uUmVzcG9uc2UuYXR0cnMuZnJvbSwgc2VydmljZUluZm9ybWF0aW9uKTtcbiAgICAgICAgcmV0dXJuIHNlcnZpY2VJbmZvcm1hdGlvbjtcbiAgICB9XG5cbiAgICBwcml2YXRlIGlzSWRlbnRpdGllc0F0dHJzKGVsZW1lbnRzOiB7IFthdHRyTmFtZTogc3RyaW5nXTogYW55IH1bXSk6IGVsZW1lbnRzIGlzIElkZW50aXR5QXR0cnNbXSB7XG4gICAgICAgIHJldHVybiBlbGVtZW50cy5ldmVyeSgoZWxlbWVudCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKGVsZW1lbnQpO1xuICAgICAgICAgICAgY29uc3QgbXVzdEhhdmUgPSBrZXlzLmluY2x1ZGVzKCdjYXRlZ29yeScpICYmIGtleXMuaW5jbHVkZXMoJ3R5cGUnKTtcbiAgICAgICAgICAgIGlmIChrZXlzLmxlbmd0aCA9PT0gMikge1xuICAgICAgICAgICAgICAgIHJldHVybiBtdXN0SGF2ZTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoa2V5cy5sZW5ndGggPT09IDMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbXVzdEhhdmUgJiYga2V5cy5pbmNsdWRlcygnbmFtZScpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9KTtcbiAgICB9XG59XG4iXX0=