@kolektor/nucleus-notifications 0.0.12-pre.7931 → 0.1.130-pre.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -0
- package/esm2022/index.mjs +4 -0
- package/esm2022/kolektor-nucleus-notifications.mjs +5 -0
- package/esm2022/lib/models.mjs +23 -0
- package/esm2022/lib/nucleus-notifications.module.mjs +23 -0
- package/esm2022/lib/nucleus-notifications.service.mjs +387 -0
- package/{fesm2020 → fesm2022}/kolektor-nucleus-notifications.mjs +414 -389
- package/fesm2022/kolektor-nucleus-notifications.mjs.map +1 -0
- package/index.d.ts +3 -5
- package/lib/models.d.ts +65 -65
- package/lib/nucleus-notifications.module.d.ts +9 -9
- package/lib/nucleus-notifications.service.d.ts +56 -56
- package/package.json +25 -31
- package/esm2020/kolektor-nucleus-notifications.mjs +0 -5
- package/esm2020/lib/models.mjs +0 -23
- package/esm2020/lib/nucleus-notifications.module.mjs +0 -25
- package/esm2020/lib/nucleus-notifications.service.mjs +0 -356
- package/esm2020/public-api.mjs +0 -7
- package/fesm2015/kolektor-nucleus-notifications.mjs +0 -412
- package/fesm2015/kolektor-nucleus-notifications.mjs.map +0 -1
- package/fesm2020/kolektor-nucleus-notifications.mjs.map +0 -1
- package/public-api.d.ts +0 -3
package/README.md
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export * from './lib/nucleus-notifications.service';
|
|
2
|
+
export * from './lib/nucleus-notifications.module';
|
|
3
|
+
export * from './lib/models';
|
|
4
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9saWJzL25nL251Y2xldXMvbnVjbGV1cy1ub3RpZmljYXRpb25zL3NyYy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLHFDQUFxQyxDQUFDO0FBQ3BELGNBQWMsb0NBQW9DLENBQUM7QUFDbkQsY0FBYyxjQUFjLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tICcuL2xpYi9udWNsZXVzLW5vdGlmaWNhdGlvbnMuc2VydmljZSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9udWNsZXVzLW5vdGlmaWNhdGlvbnMubW9kdWxlJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL21vZGVscyc7XG4iXX0=
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generated bundle index. Do not edit.
|
|
3
|
+
*/
|
|
4
|
+
export * from './index';
|
|
5
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoia29sZWt0b3ItbnVjbGV1cy1ub3RpZmljYXRpb25zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9uZy9udWNsZXVzL251Y2xldXMtbm90aWZpY2F0aW9ucy9zcmMva29sZWt0b3ItbnVjbGV1cy1ub3RpZmljYXRpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBRUgsY0FBYyxTQUFTLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEdlbmVyYXRlZCBidW5kbGUgaW5kZXguIERvIG5vdCBlZGl0LlxuICovXG5cbmV4cG9ydCAqIGZyb20gJy4vaW5kZXgnO1xuIl19
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export class Notification {
|
|
2
|
+
}
|
|
3
|
+
export class Identity {
|
|
4
|
+
}
|
|
5
|
+
export class Recipient {
|
|
6
|
+
}
|
|
7
|
+
export class NotificationData {
|
|
8
|
+
}
|
|
9
|
+
export class WebKey {
|
|
10
|
+
}
|
|
11
|
+
export class Registration {
|
|
12
|
+
}
|
|
13
|
+
export class RegistrationResult {
|
|
14
|
+
}
|
|
15
|
+
export class PayloadData {
|
|
16
|
+
}
|
|
17
|
+
export class NucleusNotificationsConfig {
|
|
18
|
+
}
|
|
19
|
+
export class NotificationClick {
|
|
20
|
+
}
|
|
21
|
+
export class UserChannelConfig {
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kZWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9uZy9udWNsZXVzL251Y2xldXMtbm90aWZpY2F0aW9ucy9zcmMvbGliL21vZGVscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLE9BQU8sWUFBWTtDQU94QjtBQUVELE1BQU0sT0FBTyxRQUFRO0NBSXBCO0FBRUQsTUFBTSxPQUFPLFNBQVM7Q0FJckI7QUFFRCxNQUFNLE9BQU8sZ0JBQWdCO0NBTTVCO0FBRUQsTUFBTSxPQUFPLE1BQU07Q0FFbEI7QUFFRCxNQUFNLE9BQU8sWUFBWTtDQUl4QjtBQUVELE1BQU0sT0FBTyxrQkFBa0I7Q0FFOUI7QUFFRCxNQUFNLE9BQU8sV0FBVztDQUd2QjtBQUVELE1BQU0sT0FBTywwQkFBMEI7Q0FFdEM7QUFFRCxNQUFNLE9BQU8saUJBQWlCO0NBSTdCO0FBbUJELE1BQU0sT0FBTyxpQkFBaUI7Q0FPN0IiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY2xhc3MgTm90aWZpY2F0aW9uIHtcbiAgcHVibGljIGlkOiBzdHJpbmc7XG4gIHB1YmxpYyBzZW5kZXI6IElkZW50aXR5O1xuICBwdWJsaWMgZGF0YTogTm90aWZpY2F0aW9uRGF0YTtcbiAgcHVibGljIGlzUmVhZDogYm9vbGVhbjtcbiAgcHVibGljIGRhdGVDcmVhdGVkOiBEYXRlO1xuICBwdWJsaWMgZXhwaXJhdGlvbkRhdGU6IERhdGU7XG59XG5cbmV4cG9ydCBjbGFzcyBJZGVudGl0eSB7XG4gIHB1YmxpYyBzdWJqZWN0OiBzdHJpbmc7XG4gIHB1YmxpYyBuYW1lOiBzdHJpbmc7XG4gIHB1YmxpYyBwaWN0dXJlVXJsOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBSZWNpcGllbnQge1xuICBwdWJsaWMgYXR0cmlidXRlTmFtZTogc3RyaW5nO1xuICBwdWJsaWMgZGlyZWN0b3J5TmFtZTogc3RyaW5nO1xuICBwdWJsaWMgYXR0cmlidXRlVmFsdWU6IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIE5vdGlmaWNhdGlvbkRhdGEge1xuICB0aXRsZTogc3RyaW5nO1xuICBtZXNzYWdlOiBzdHJpbmc7XG4gIGh0bWxNZXNzYWdlOiBzdHJpbmc7XG4gIHByZXZlbnREaXNtaXNzYWw6IGJvb2xlYW47XG4gIGRlZXBMaW5rOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjbGFzcyBXZWJLZXkge1xuICBwdWJsaWNLZXk6IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIFJlZ2lzdHJhdGlvbiB7XG4gIGlkOiBzdHJpbmc7XG4gIHRva2VuOiBzdHJpbmc7XG4gIHBsYXRmb3JtOiBQbGF0Zm9ybVZhbHVlO1xufVxuXG5leHBvcnQgY2xhc3MgUmVnaXN0cmF0aW9uUmVzdWx0IHtcbiAgaWQ6IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIFBheWxvYWREYXRhIHtcbiAgbm90aWZpY2F0aW9uSWQ6IHN0cmluZztcbiAgZXZlbnRUeXBlOiBOb3RpZmljYXRpb25FdmVudFR5cGU7XG59XG5cbmV4cG9ydCBjbGFzcyBOdWNsZXVzTm90aWZpY2F0aW9uc0NvbmZpZyB7XG4gIHNlcnZlckFwaVVybDogc3RyaW5nO1xufVxuXG5leHBvcnQgY2xhc3MgTm90aWZpY2F0aW9uQ2xpY2sge1xuICBpZDogc3RyaW5nO1xuICB0eXBlOiBOb3RpZmljYXRpb25UeXBlO1xuICByb3V0ZXJMaW5rPzogc3RyaW5nO1xufVxuXG5leHBvcnQgdHlwZSBOb3RpZmljYXRpb25FdmVudFR5cGUgPVxuICB8ICduZXcnXG4gIHwgJ3VwZGF0ZWQnXG4gIHwgJ2RlbGV0ZWQnXG4gIHwgJ2RlbGV0ZWRBbGwnXG4gIHwgJ3VwZGF0ZWRBbGwnXG4gIHwgJ25ld1NpbGVudCc7XG5cbmV4cG9ydCB0eXBlIFBsYXRmb3JtVmFsdWUgPSAnaW9zJyB8ICdhbmRyb2lkJyB8ICd3ZWInIHwgJ25vbmUnO1xuXG5leHBvcnQgdHlwZSBOb3RpZmljYXRpb25UeXBlID0gJ2RlZmF1bHQnIHwgJ2RlZXBsaW5rJztcblxuZXhwb3J0IGludGVyZmFjZSBDaGFubmVsSWQge1xuICBzZW5kZXJJZDogc3RyaW5nO1xuICBjaGFubmVsSWQ6IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIFVzZXJDaGFubmVsQ29uZmlnIHtcbiAgY2hhbm5lbElkOiBzdHJpbmc7XG4gIGRpc3BsYXlOYW1lOiBzdHJpbmc7XG4gIGlzU3Vic2NyaWJlZDogYm9vbGVhbjtcbiAgc3Vic2NyaXB0aW9uVHlwZTogQ2hhbm5lbFN1YnNjcmlwdGlvblR5cGU7XG4gIG1ldGhvZHM6IE5vdGlmeU1ldGhvZFtdO1xuICBhbGxvd2VkTWV0aG9kczogTm90aWZ5TWV0aG9kW107XG59XG5cbmV4cG9ydCB0eXBlIENoYW5uZWxTdWJzY3JpcHRpb25UeXBlID0gJ2ludmFyaWFudCcgfCAnb3B0SW4nIHwgJ29wdE91dCc7XG5cbmV4cG9ydCB0eXBlIE5vdGlmeU1ldGhvZCA9ICdwdXNoJyB8ICdlbWFpbCcgfCAnc21zJztcbiJdfQ==
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { NgModule } from '@angular/core';
|
|
2
|
+
import { NucleusNotificationsConfig } from './models';
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
export class NucleusNotificationsModule {
|
|
5
|
+
static forRoot(config) {
|
|
6
|
+
return {
|
|
7
|
+
ngModule: NucleusNotificationsModule,
|
|
8
|
+
providers: [{ provide: NucleusNotificationsConfig, useValue: config }],
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NucleusNotificationsModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
12
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "16.2.12", ngImport: i0, type: NucleusNotificationsModule }); }
|
|
13
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NucleusNotificationsModule }); }
|
|
14
|
+
}
|
|
15
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NucleusNotificationsModule, decorators: [{
|
|
16
|
+
type: NgModule,
|
|
17
|
+
args: [{
|
|
18
|
+
declarations: [],
|
|
19
|
+
imports: [],
|
|
20
|
+
exports: [],
|
|
21
|
+
}]
|
|
22
|
+
}] });
|
|
23
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnVjbGV1cy1ub3RpZmljYXRpb25zLm1vZHVsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL2xpYnMvbmcvbnVjbGV1cy9udWNsZXVzLW5vdGlmaWNhdGlvbnMvc3JjL2xpYi9udWNsZXVzLW5vdGlmaWNhdGlvbnMubW9kdWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQXVCLE1BQU0sZUFBZSxDQUFDO0FBQzlELE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLFVBQVUsQ0FBQzs7QUFPdEQsTUFBTSxPQUFPLDBCQUEwQjtJQUNyQyxNQUFNLENBQUMsT0FBTyxDQUNaLE1BQWtDO1FBRWxDLE9BQU87WUFDTCxRQUFRLEVBQUUsMEJBQTBCO1lBQ3BDLFNBQVMsRUFBRSxDQUFDLEVBQUUsT0FBTyxFQUFFLDBCQUEwQixFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsQ0FBQztTQUN2RSxDQUFDO0lBQ0osQ0FBQzsrR0FSVSwwQkFBMEI7Z0hBQTFCLDBCQUEwQjtnSEFBMUIsMEJBQTBCOzs0RkFBMUIsMEJBQTBCO2tCQUx0QyxRQUFRO21CQUFDO29CQUNSLFlBQVksRUFBRSxFQUFFO29CQUNoQixPQUFPLEVBQUUsRUFBRTtvQkFDWCxPQUFPLEVBQUUsRUFBRTtpQkFDWiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE5nTW9kdWxlLCBNb2R1bGVXaXRoUHJvdmlkZXJzIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBOdWNsZXVzTm90aWZpY2F0aW9uc0NvbmZpZyB9IGZyb20gJy4vbW9kZWxzJztcblxuQE5nTW9kdWxlKHtcbiAgZGVjbGFyYXRpb25zOiBbXSxcbiAgaW1wb3J0czogW10sXG4gIGV4cG9ydHM6IFtdLFxufSlcbmV4cG9ydCBjbGFzcyBOdWNsZXVzTm90aWZpY2F0aW9uc01vZHVsZSB7XG4gIHN0YXRpYyBmb3JSb290KFxuICAgIGNvbmZpZzogTnVjbGV1c05vdGlmaWNhdGlvbnNDb25maWdcbiAgKTogTW9kdWxlV2l0aFByb3ZpZGVyczxOdWNsZXVzTm90aWZpY2F0aW9uc01vZHVsZT4ge1xuICAgIHJldHVybiB7XG4gICAgICBuZ01vZHVsZTogTnVjbGV1c05vdGlmaWNhdGlvbnNNb2R1bGUsXG4gICAgICBwcm92aWRlcnM6IFt7IHByb3ZpZGU6IE51Y2xldXNOb3RpZmljYXRpb25zQ29uZmlnLCB1c2VWYWx1ZTogY29uZmlnIH1dLFxuICAgIH07XG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
|
+
import { HttpClient } from '@angular/common/http';
|
|
3
|
+
import { Injectable } from '@angular/core';
|
|
4
|
+
import { SwPush } from '@angular/service-worker';
|
|
5
|
+
import { PushNotifications, } from '@capacitor/push-notifications';
|
|
6
|
+
import { NucleusAppService } from '@kolektor/nucleus-common';
|
|
7
|
+
import { of, Subject } from 'rxjs';
|
|
8
|
+
import { NucleusNotificationsConfig, } from './models';
|
|
9
|
+
import * as i0 from "@angular/core";
|
|
10
|
+
import * as i1 from "@angular/common/http";
|
|
11
|
+
import * as i2 from "@angular/service-worker";
|
|
12
|
+
import * as i3 from "@kolektor/nucleus-common";
|
|
13
|
+
import * as i4 from "./models";
|
|
14
|
+
export class NucleusNotificationsService {
|
|
15
|
+
constructor(http, swPush, appService, config) {
|
|
16
|
+
this.http = http;
|
|
17
|
+
this.swPush = swPush;
|
|
18
|
+
this.appService = appService;
|
|
19
|
+
this.registrationStorageKey = 'NucleusNotificationsRegistrationId';
|
|
20
|
+
this.notificationsStorageKey = 'NucleusNotificationsLocalCache';
|
|
21
|
+
this._isInitialized = false;
|
|
22
|
+
this._newNotifications = new Subject();
|
|
23
|
+
this._clicksSubject = new Subject();
|
|
24
|
+
this._stateChangesSubject = new Subject();
|
|
25
|
+
this.notifications = [];
|
|
26
|
+
let url = config.serverApiUrl;
|
|
27
|
+
if (!url.endsWith('/')) {
|
|
28
|
+
url += '/';
|
|
29
|
+
}
|
|
30
|
+
this.apiUrl = url;
|
|
31
|
+
}
|
|
32
|
+
get unreadCount() {
|
|
33
|
+
return this.notifications.filter((x) => !x.isRead).length;
|
|
34
|
+
}
|
|
35
|
+
get newNotifications() {
|
|
36
|
+
return this._newNotifications.asObservable();
|
|
37
|
+
}
|
|
38
|
+
get clicks() {
|
|
39
|
+
return this._clicksSubject.asObservable();
|
|
40
|
+
}
|
|
41
|
+
get stateChanges() {
|
|
42
|
+
return this._stateChangesSubject.asObservable();
|
|
43
|
+
}
|
|
44
|
+
get isInitialized() {
|
|
45
|
+
return this._isInitialized;
|
|
46
|
+
}
|
|
47
|
+
async initialize() {
|
|
48
|
+
// make sure app service has finished initializing
|
|
49
|
+
await this.appService.init();
|
|
50
|
+
this.loadFromStorage();
|
|
51
|
+
if (this.appService.isNative) {
|
|
52
|
+
this._platform = this.appService.deviceInfo.platform;
|
|
53
|
+
await this.registerCapacitorEvents();
|
|
54
|
+
}
|
|
55
|
+
else if (this.swPush.isEnabled) {
|
|
56
|
+
this._platform = 'web';
|
|
57
|
+
this.registerWebPushEvents();
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
console.warn('Nucleus.Notifications: There is no push capability, timer will be used to update notifications');
|
|
61
|
+
setInterval(() => {
|
|
62
|
+
console.log('Updating notifications...');
|
|
63
|
+
this.refresh(true);
|
|
64
|
+
}, 5 * 60 * 1000);
|
|
65
|
+
}
|
|
66
|
+
this._isInitialized = true;
|
|
67
|
+
this.refresh();
|
|
68
|
+
}
|
|
69
|
+
register() {
|
|
70
|
+
return new Promise((_resolve, _reject) => {
|
|
71
|
+
this.getRegistrationInfo()
|
|
72
|
+
.then((info) => {
|
|
73
|
+
this.http
|
|
74
|
+
.post(this.apiUrl + 'registration', info)
|
|
75
|
+
.subscribe((regResult) => {
|
|
76
|
+
window.localStorage.setItem(this.registrationStorageKey, regResult.id);
|
|
77
|
+
_resolve(null);
|
|
78
|
+
}, (error) => {
|
|
79
|
+
console.log('Nucleus.Notifications: Failed to send notification registration to server.', error);
|
|
80
|
+
_reject(error);
|
|
81
|
+
});
|
|
82
|
+
})
|
|
83
|
+
.catch((error) => _reject(error));
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
unregister() {
|
|
87
|
+
return new Promise((_resolve, _reject) => {
|
|
88
|
+
this.getRegistrationInfo()
|
|
89
|
+
.then((info) => {
|
|
90
|
+
this.http
|
|
91
|
+
.request('DELETE', this.apiUrl + 'registration', {
|
|
92
|
+
body: info,
|
|
93
|
+
})
|
|
94
|
+
.subscribe(() => {
|
|
95
|
+
window.localStorage.removeItem(this.registrationStorageKey);
|
|
96
|
+
_resolve(null);
|
|
97
|
+
}, (error) => {
|
|
98
|
+
console.log('Nucleus.Notifications: Failed to remove registration from server.', error);
|
|
99
|
+
_reject(error);
|
|
100
|
+
});
|
|
101
|
+
})
|
|
102
|
+
.catch((error) => _reject(error));
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
refresh(notifyAboutNew = false) {
|
|
106
|
+
this.http
|
|
107
|
+
.get(this.apiUrl + 'notifications')
|
|
108
|
+
.subscribe((res) => {
|
|
109
|
+
this.updateNotifications(res, notifyAboutNew);
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
getNotification(id) {
|
|
113
|
+
const localNotification = this.notifications.find((x) => x.id === id);
|
|
114
|
+
if (localNotification) {
|
|
115
|
+
return of(localNotification);
|
|
116
|
+
}
|
|
117
|
+
return this.http.get(this.apiUrl + 'notifications/' + id);
|
|
118
|
+
}
|
|
119
|
+
readNotification(id) {
|
|
120
|
+
const n = this.notifications.find((x) => x.id === id);
|
|
121
|
+
if (n && !n.isRead) {
|
|
122
|
+
n.isRead = true;
|
|
123
|
+
this.notifyStateChanged();
|
|
124
|
+
}
|
|
125
|
+
this.http.get(this.apiUrl + 'notifications/read/' + id).subscribe();
|
|
126
|
+
}
|
|
127
|
+
dismissNotification(id) {
|
|
128
|
+
this.deleteNotificaton(id);
|
|
129
|
+
this.http.delete(this.apiUrl + 'notifications/' + id).subscribe();
|
|
130
|
+
this.removeDeliveredNotification(id);
|
|
131
|
+
}
|
|
132
|
+
dismissAll() {
|
|
133
|
+
this.notifications.splice(0);
|
|
134
|
+
this.notifyStateChanged();
|
|
135
|
+
this.http.delete(this.apiUrl + 'notifications/all').subscribe();
|
|
136
|
+
if (this._platform === 'ios' || this._platform === 'android') {
|
|
137
|
+
PushNotifications.removeAllDeliveredNotifications();
|
|
138
|
+
}
|
|
139
|
+
else if (this._platform === 'web') {
|
|
140
|
+
// TODO: remove all web push notifications
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
readAll() {
|
|
144
|
+
for (const n of this.notifications) {
|
|
145
|
+
n.isRead = true;
|
|
146
|
+
}
|
|
147
|
+
this.notifyStateChanged();
|
|
148
|
+
this.http.get(this.apiUrl + 'notifications/read/all').subscribe();
|
|
149
|
+
}
|
|
150
|
+
getChannelConfig(senderId, channelId, language) {
|
|
151
|
+
return this.http.get(this.apiUrl +
|
|
152
|
+
`settings/channel/${senderId}/${channelId}?language=${language}`);
|
|
153
|
+
}
|
|
154
|
+
getChannelConfigsForSender(senderId, channelIds, language) {
|
|
155
|
+
const idsStr = channelIds.map((x) => senderId + ',' + x).join(';');
|
|
156
|
+
return this.getChannelConfigsInternal(idsStr, language);
|
|
157
|
+
}
|
|
158
|
+
getChannelConfigs(ids, language) {
|
|
159
|
+
const idsStr = ids.map((x) => x.senderId + ',' + x.channelId).join(';');
|
|
160
|
+
return this.getChannelConfigsInternal(idsStr, language);
|
|
161
|
+
}
|
|
162
|
+
setChannelConfig(senderId, config) {
|
|
163
|
+
return this.http.post(`${this.apiUrl}settings/channel/${senderId}`, config);
|
|
164
|
+
}
|
|
165
|
+
setChannelConfigs(configs) {
|
|
166
|
+
return this.http.post(`${this.apiUrl}settings/channels`, configs);
|
|
167
|
+
}
|
|
168
|
+
getChannelConfigsInternal(ids, language) {
|
|
169
|
+
return this.http.get(`${this.apiUrl}settings/channels?ids=${ids}&language=${language}`);
|
|
170
|
+
}
|
|
171
|
+
updateNotifications(newNotifications, notifyAboutNew = false) {
|
|
172
|
+
let stateChanged = false;
|
|
173
|
+
for (const n of newNotifications) {
|
|
174
|
+
const existing = this.notifications.find((x) => x.id === n.id);
|
|
175
|
+
if (existing) {
|
|
176
|
+
if (existing.isRead !== n.isRead) {
|
|
177
|
+
existing.isRead = n.isRead;
|
|
178
|
+
stateChanged = true;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
let i = 0;
|
|
183
|
+
while (i < this.notifications.length &&
|
|
184
|
+
n.dateCreated < this.notifications[i].dateCreated) {
|
|
185
|
+
i++;
|
|
186
|
+
}
|
|
187
|
+
this.notifications.splice(i, 0, n);
|
|
188
|
+
stateChanged = true;
|
|
189
|
+
if (notifyAboutNew) {
|
|
190
|
+
this._newNotifications.next(n);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
const now = Date.now();
|
|
195
|
+
for (let i = this.notifications.length - 1; i >= 0; i--) {
|
|
196
|
+
const n = this.notifications[i];
|
|
197
|
+
if (new Date(n.expirationDate).getTime() < now ||
|
|
198
|
+
!newNotifications.find((x) => x.id === n.id)) {
|
|
199
|
+
this.notifications.splice(i, 1);
|
|
200
|
+
stateChanged = true;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
if (stateChanged) {
|
|
204
|
+
this.notifyStateChanged();
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
saveToStorage() {
|
|
208
|
+
const str = JSON.stringify(this.notifications);
|
|
209
|
+
window.localStorage.setItem(this.notificationsStorageKey, str);
|
|
210
|
+
}
|
|
211
|
+
loadFromStorage() {
|
|
212
|
+
try {
|
|
213
|
+
const str = window.localStorage.getItem(this.notificationsStorageKey);
|
|
214
|
+
if (str) {
|
|
215
|
+
const notifications = JSON.parse(str);
|
|
216
|
+
this.notifications = notifications.filter((x) => !!x);
|
|
217
|
+
// precaution for notification.isRead of undefined error
|
|
218
|
+
this.notifyStateChanged(false);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
catch {
|
|
222
|
+
/* empty */
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
handleNotificationEvent(id, eventType) {
|
|
226
|
+
if (eventType.startsWith('new') || eventType === 'updated') {
|
|
227
|
+
// we are handling new and newSilent
|
|
228
|
+
this.getNotification(id).subscribe((n) => {
|
|
229
|
+
if (eventType.startsWith('new') && !n.isRead) {
|
|
230
|
+
this._newNotifications.next(n);
|
|
231
|
+
}
|
|
232
|
+
const existing = this.notifications.find((x) => x.id === n.id);
|
|
233
|
+
if (existing) {
|
|
234
|
+
existing.isRead = n.isRead;
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
this.notifications.splice(0, 0, n);
|
|
238
|
+
}
|
|
239
|
+
this.notifyStateChanged();
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
else if (eventType === 'deleted') {
|
|
243
|
+
this.deleteNotificaton(id);
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
this.refresh();
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
deleteNotificaton(id) {
|
|
250
|
+
const i = this.notifications.findIndex((x) => x.id === id);
|
|
251
|
+
if (i >= 0) {
|
|
252
|
+
this.notifications.splice(i, 1);
|
|
253
|
+
this.notifyStateChanged();
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
notifyStateChanged(persistState = true) {
|
|
257
|
+
if (persistState) {
|
|
258
|
+
this.saveToStorage();
|
|
259
|
+
}
|
|
260
|
+
this._stateChangesSubject.next();
|
|
261
|
+
}
|
|
262
|
+
handleNotificationAction(notificationAction) {
|
|
263
|
+
if (!notificationAction) {
|
|
264
|
+
throw new Error('Notification action is empty!');
|
|
265
|
+
}
|
|
266
|
+
const arr = notificationAction.split(':');
|
|
267
|
+
const notificationClick = {
|
|
268
|
+
id: arr[0],
|
|
269
|
+
type: arr[1],
|
|
270
|
+
routerLink: arr[2],
|
|
271
|
+
};
|
|
272
|
+
const validNotificationClickTypes = ['default', 'deeplink'];
|
|
273
|
+
if (validNotificationClickTypes.includes(notificationClick.type)) {
|
|
274
|
+
this._clicksSubject.next(notificationClick);
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
console.error(`Nucleus.Notifications: Unknown notification action: '${notificationAction}'.`);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
removeDeliveredNotification(id) {
|
|
281
|
+
if (this._platform === 'ios' || this._platform === 'android') {
|
|
282
|
+
PushNotifications.getDeliveredNotifications().then((list) => {
|
|
283
|
+
const toRemove = list.notifications.filter((n) => {
|
|
284
|
+
const data = this.getNotificationPayloadData(n);
|
|
285
|
+
return data.notificationId === id;
|
|
286
|
+
});
|
|
287
|
+
// TODO: On Android this does not currently work because notificationID is not set.
|
|
288
|
+
// This my solve the issue: https://github.com/ionic-team/capacitor/pull/3523
|
|
289
|
+
PushNotifications.removeDeliveredNotifications({
|
|
290
|
+
notifications: toRemove,
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
else if (this._platform === 'web') {
|
|
295
|
+
// TODO: remove web push notification
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
getNotificationPayloadData(pushNotification) {
|
|
299
|
+
return this._platform === 'ios'
|
|
300
|
+
? pushNotification.data.data
|
|
301
|
+
: pushNotification.data;
|
|
302
|
+
}
|
|
303
|
+
async registerCapacitorEvents() {
|
|
304
|
+
await PushNotifications.addListener('pushNotificationReceived', (n) => {
|
|
305
|
+
const data = this.getNotificationPayloadData(n);
|
|
306
|
+
console.log('Nucleus.Notifications: Received capacitor push event: ' +
|
|
307
|
+
data.eventType, n);
|
|
308
|
+
this.handleNotificationEvent(data.notificationId, data.eventType);
|
|
309
|
+
});
|
|
310
|
+
await PushNotifications.addListener('pushNotificationActionPerformed', (a) => {
|
|
311
|
+
let action = a.notification.data.notificationAction;
|
|
312
|
+
if (this._platform === 'ios') {
|
|
313
|
+
action = a.notification.data.data.notificationAction;
|
|
314
|
+
}
|
|
315
|
+
console.log('Nucleus.Notifications: Received capacitor action event', action);
|
|
316
|
+
this.handleNotificationAction(action);
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
registerWebPushEvents() {
|
|
320
|
+
this.swPush.messages.subscribe((n) => {
|
|
321
|
+
const data = n.data;
|
|
322
|
+
console.log('Nucleus.Notifications: Received WebPush event: ' + data.eventType, n);
|
|
323
|
+
this.handleNotificationEvent(data.notificationId, data.eventType);
|
|
324
|
+
});
|
|
325
|
+
this.swPush.notificationClicks.subscribe((action) => {
|
|
326
|
+
console.log('Nucleus.Notifications: Received WebPush action event', action);
|
|
327
|
+
const tag = action.notification.tag;
|
|
328
|
+
this.handleNotificationAction(tag);
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
getRegistrationInfo() {
|
|
332
|
+
return new Promise((_resolve, _reject) => {
|
|
333
|
+
const registrationId = window.localStorage.getItem(this.registrationStorageKey);
|
|
334
|
+
if (this._platform === 'android' || this._platform === 'ios') {
|
|
335
|
+
// capacitor platform
|
|
336
|
+
const listener = PushNotifications.addListener('registration', (token) => {
|
|
337
|
+
listener.remove();
|
|
338
|
+
_resolve({
|
|
339
|
+
id: registrationId,
|
|
340
|
+
token: token.value,
|
|
341
|
+
platform: this._platform,
|
|
342
|
+
});
|
|
343
|
+
});
|
|
344
|
+
PushNotifications.register().catch((error) => _reject('Could not register for notifications:' + error));
|
|
345
|
+
}
|
|
346
|
+
else if (this._platform === 'web') {
|
|
347
|
+
// Web Push API
|
|
348
|
+
this.http.get(this.apiUrl + 'registration/webkey').subscribe((key) => {
|
|
349
|
+
this.getWebPushSubscription(key.publicKey).then((subscription) => {
|
|
350
|
+
const t = JSON.stringify(subscription.toJSON());
|
|
351
|
+
_resolve({ id: registrationId, token: t, platform: 'web' });
|
|
352
|
+
});
|
|
353
|
+
}, (error) => _reject(error));
|
|
354
|
+
}
|
|
355
|
+
else {
|
|
356
|
+
_reject(`Nucleus.Notifications: Platform is not supported`);
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
getWebPushSubscription(publicKey) {
|
|
361
|
+
return new Promise((_resolve, _reject) => {
|
|
362
|
+
this.swPush.subscription.subscribe((subscription) => {
|
|
363
|
+
if (subscription != null) {
|
|
364
|
+
_resolve(subscription);
|
|
365
|
+
}
|
|
366
|
+
else {
|
|
367
|
+
this.swPush
|
|
368
|
+
.requestSubscription({ serverPublicKey: publicKey })
|
|
369
|
+
.then((s) => _resolve(s))
|
|
370
|
+
.catch((e) => _reject(e));
|
|
371
|
+
}
|
|
372
|
+
}, (error) => {
|
|
373
|
+
console.error('Nucleus.Notifications: Cannot get web push subscription', error);
|
|
374
|
+
_reject(error);
|
|
375
|
+
});
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NucleusNotificationsService, deps: [{ token: i1.HttpClient }, { token: i2.SwPush }, { token: i3.NucleusAppService }, { token: i4.NucleusNotificationsConfig }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
379
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NucleusNotificationsService, providedIn: 'root' }); }
|
|
380
|
+
}
|
|
381
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: NucleusNotificationsService, decorators: [{
|
|
382
|
+
type: Injectable,
|
|
383
|
+
args: [{
|
|
384
|
+
providedIn: 'root',
|
|
385
|
+
}]
|
|
386
|
+
}], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: i2.SwPush }, { type: i3.NucleusAppService }, { type: i4.NucleusNotificationsConfig }]; } });
|
|
387
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnVjbGV1cy1ub3RpZmljYXRpb25zLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9saWJzL25nL251Y2xldXMvbnVjbGV1cy1ub3RpZmljYXRpb25zL3NyYy9saWIvbnVjbGV1cy1ub3RpZmljYXRpb25zLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsdURBQXVEO0FBQ3ZELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNqRCxPQUFPLEVBQ0wsaUJBQWlCLEdBRWxCLE1BQU0sK0JBQStCLENBQUM7QUFDdkMsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDN0QsT0FBTyxFQUFjLEVBQUUsRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0MsT0FBTyxFQU1MLDBCQUEwQixHQU8zQixNQUFNLFVBQVUsQ0FBQzs7Ozs7O0FBS2xCLE1BQU0sT0FBTywyQkFBMkI7SUFDdEMsWUFDVSxJQUFnQixFQUNoQixNQUFjLEVBQ2QsVUFBNkIsRUFDckMsTUFBa0M7UUFIMUIsU0FBSSxHQUFKLElBQUksQ0FBWTtRQUNoQixXQUFNLEdBQU4sTUFBTSxDQUFRO1FBQ2QsZUFBVSxHQUFWLFVBQVUsQ0FBbUI7UUFXdEIsMkJBQXNCLEdBQ3JDLG9DQUFvQyxDQUFDO1FBQ3RCLDRCQUF1QixHQUFHLGdDQUFnQyxDQUFDO1FBRXBFLG1CQUFjLEdBQUcsS0FBSyxDQUFDO1FBQ3ZCLHNCQUFpQixHQUFHLElBQUksT0FBTyxFQUFnQixDQUFDO1FBQ2hELG1CQUFjLEdBQUcsSUFBSSxPQUFPLEVBQXFCLENBQUM7UUFDbEQseUJBQW9CLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztRQUU1Qyxr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OzRGQUVQLDJCQUEyQjtrQkFIdkMsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55ICovXG5pbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgU3dQdXNoIH0gZnJvbSAnQGFuZ3VsYXIvc2VydmljZS13b3JrZXInO1xuaW1wb3J0IHtcbiAgUHVzaE5vdGlmaWNhdGlvbnMsXG4gIFB1c2hOb3RpZmljYXRpb25TY2hlbWEsXG59IGZyb20gJ0BjYXBhY2l0b3IvcHVzaC1ub3RpZmljYXRpb25zJztcbmltcG9ydCB7IE51Y2xldXNBcHBTZXJ2aWNlIH0gZnJvbSAnQGtvbGVrdG9yL251Y2xldXMtY29tbW9uJztcbmltcG9ydCB7IE9ic2VydmFibGUsIG9mLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQge1xuICBDaGFubmVsSWQsXG4gIE5vdGlmaWNhdGlvbixcbiAgTm90aWZpY2F0aW9uQ2xpY2ssXG4gIE5vdGlmaWNhdGlvbkV2ZW50VHlwZSxcbiAgTm90aWZpY2F0aW9uVHlwZSxcbiAgTnVjbGV1c05vdGlmaWNhdGlvbnNDb25maWcsXG4gIFBheWxvYWREYXRhLFxuICBQbGF0Zm9ybVZhbHVlLFxuICBSZWdpc3RyYXRpb24sXG4gIFJlZ2lzdHJhdGlvblJlc3VsdCxcbiAgVXNlckNoYW5uZWxDb25maWcsXG4gIFdlYktleSxcbn0gZnJvbSAnLi9tb2RlbHMnO1xuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290Jyxcbn0pXG5leHBvcnQgY2xhc3MgTnVjbGV1c05vdGlmaWNhdGlvbnNTZXJ2aWNlIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBodHRwOiBIdHRwQ2xpZW50LFxuICAgIHByaXZhdGUgc3dQdXNoOiBTd1B1c2gsXG4gICAgcHJpdmF0ZSBhcHBTZXJ2aWNlOiBOdWNsZXVzQXBwU2VydmljZSxcbiAgICBjb25maWc6IE51Y2xldXNOb3RpZmljYXRpb25zQ29uZmlnXG4gICkge1xuICAgIGxldCB1cmwgPSBjb25maWcuc2VydmVyQXBpVXJsO1xuICAgIGlmICghdXJsLmVuZHNXaXRoKCcvJykpIHtcbiAgICAgIHVybCArPSAnLyc7XG4gICAgfVxuICAgIHRoaXMuYXBpVXJsID0gdXJsO1xuICB9XG5cbiAgcHJpdmF0ZSBhcGlVcmw6IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSByZWdpc3RyYXRpb25TdG9yYWdlS2V5ID1cbiAgICAnTnVjbGV1c05vdGlmaWNhdGlvbnNSZWdpc3RyYXRpb25JZCc7XG4gIHByaXZhdGUgcmVhZG9ubHkgbm90aWZpY2F0aW9uc1N0b3JhZ2VLZXkgPSAnTnVjbGV1c05vdGlmaWNhdGlvbnNMb2NhbENhY2hlJztcbiAgcHJpdmF0ZSBfcGxhdGZvcm06IFBsYXRmb3JtVmFsdWU7XG4gIHByaXZhdGUgX2lzSW5pdGlhbGl6ZWQgPSBmYWxzZTtcbiAgcHJpdmF0ZSBfbmV3Tm90aWZpY2F0aW9ucyA9IG5ldyBTdWJqZWN0PE5vdGlmaWNhdGlvbj4oKTtcbiAgcHJpdmF0ZSBfY2xpY2tzU3ViamVjdCA9IG5ldyBTdWJqZWN0PE5vdGlmaWNhdGlvbkNsaWNrPigpO1xuICBwcml2YXRlIF9zdGF0ZUNoYW5nZXNTdWJqZWN0ID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICBwdWJsaWMgbm90aWZpY2F0aW9uczogTm90aWZpY2F0aW9uW10gPSBbXTtcblxuICBwdWJsaWMgZ2V0IHVucmVhZENvdW50KCkge1xuICAgIHJldHVybiB0aGlzLm5vdGlmaWNhdGlvbnMuZmlsdGVyKCh4KSA9PiAheC5pc1JlYWQpLmxlbmd0aDtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgbmV3Tm90aWZpY2F0aW9ucygpIHtcbiAgICByZXR1cm4gdGhpcy5fbmV3Tm90aWZpY2F0aW9ucy5hc09ic2VydmFibGUoKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgY2xpY2tzKCkge1xuICAgIHJldHVybiB0aGlzLl9jbGlja3NTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICB9XG4gIHB1YmxpYyBnZXQgc3RhdGVDaGFuZ2VzKCkge1xuICAgIHJldHVybiB0aGlzLl9zdGF0ZUNoYW5nZXNTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICB9XG5cbiAgcHVibGljIGdldCBpc0luaXRpYWxpemVkKCkge1xuICAgIHJldHVybiB0aGlzLl9pc0luaXRpYWxpemVkO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGluaXRpYWxpemUoKSB7XG4gICAgLy8gbWFrZSBzdXJlIGFwcCBzZXJ2aWNlIGhhcyBmaW5pc2hlZCBpbml0aWFsaXppbmdcbiAgICBhd2FpdCB0aGlzLmFwcFNlcnZpY2UuaW5pdCgpO1xuXG4gICAgdGhpcy5sb2FkRnJvbVN0b3JhZ2UoKTtcblxuICAgIGlmICh0aGlzLmFwcFNlcnZpY2UuaXNOYXRpdmUpIHtcbiAgICAgIHRoaXMuX3BsYXRmb3JtID0gdGhpcy5hcHBTZXJ2aWNlLmRldmljZUluZm8ucGxhdGZvcm0gYXMgUGxhdGZvcm1WYWx1ZTtcbiAgICAgIGF3YWl0IHRoaXMucmVnaXN0ZXJDYXBhY2l0b3JFdmVudHMoKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuc3dQdXNoLmlzRW5hYmxlZCkge1xuICAgICAgdGhpcy5fcGxhdGZvcm0gPSAnd2ViJztcbiAgICAgIHRoaXMucmVnaXN0ZXJXZWJQdXNoRXZlbnRzKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgJ051Y2xldXMuTm90aWZpY2F0aW9uczogVGhlcmUgaXMgbm8gcHVzaCBjYXBhYmlsaXR5LCB0aW1lciB3aWxsIGJlIHVzZWQgdG8gdXBkYXRlIG5vdGlmaWNhdGlvbnMnXG4gICAgICApO1xuICAgICAgc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgICBjb25zb2xlLmxvZygnVXBkYXRpbmcgbm90aWZpY2F0aW9ucy4uLicpO1xuICAgICAgICB0aGlzLnJlZnJlc2godHJ1ZSk7XG4gICAgICB9LCA1ICogNjAgKiAxMDAwKTtcbiAgICB9XG4gICAgdGhpcy5faXNJbml0aWFsaXplZCA9IHRydWU7XG4gICAgdGhpcy5yZWZyZXNoKCk7XG4gIH1cblxuICBwdWJsaWMgcmVnaXN0ZXIoKTogUHJvbWlzZTxhbnk+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKF9yZXNvbHZlLCBfcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmdldFJlZ2lzdHJhdGlvbkluZm8oKVxuICAgICAgICAudGhlbigoaW5mbykgPT4ge1xuICAgICAgICAgIHRoaXMuaHR0cFxuICAgICAgICAgICAgLnBvc3Q8UmVnaXN0cmF0aW9uUmVzdWx0Pih0aGlzLmFwaVVybCArICdyZWdpc3RyYXRpb24nLCBpbmZvKVxuICAgICAgICAgICAgLnN1YnNjcmliZShcbiAgICAgICAgICAgICAgKHJlZ1Jlc3VsdCkgPT4ge1xuICAgICAgICAgICAgICAgIHdpbmRvdy5sb2NhbFN0b3JhZ2Uuc2V0SXRlbShcbiAgICAgICAgICAgICAgICAgIHRoaXMucmVnaXN0cmF0aW9uU3RvcmFnZUtleSxcbiAgICAgICAgICAgICAgICAgIHJlZ1Jlc3VsdC5pZFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgX3Jlc29sdmUobnVsbCk7XG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgIChlcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICAgICAgICAgJ051Y2xldXMuTm90aWZpY2F0aW9uczogRmFpbGVkIHRvIHNlbmQgbm90aWZpY2F0aW9uIHJlZ2lzdHJhdGlvbiB0byBzZXJ2ZXIuJyxcbiAgICAgICAgICAgICAgICAgIGVycm9yXG4gICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICBfcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfSlcbiAgICAgICAgLmNhdGNoKChlcnJvcikgPT4gX3JlamVjdChlcnJvcikpO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIHVucmVnaXN0ZXIoKTogUHJvbWlzZTxhbnk+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKF9yZXNvbHZlLCBfcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLmdldFJlZ2lzdHJhdGlvbkluZm8oKVxuICAgICAgICAudGhlbigoaW5mbykgPT4ge1xuICAgICAgICAgIHRoaXMuaHR0cFxuICAgICAgICAgICAgLnJlcXVlc3Q8YW55PignREVMRVRFJywgdGhpcy5hcGlVcmwgKyAncmVnaXN0cmF0aW9uJywge1xuICAgICAgICAgICAgICBib2R5OiBpbmZvLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoXG4gICAgICAgICAgICAgICgpID0+IHtcbiAgICAgICAgICAgICAgICB3aW5kb3cubG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0odGhpcy5yZWdpc3RyYXRpb25TdG9yYWdlS2V5KTtcbiAgICAgICAgICAgICAgICBfcmVzb2x2ZShudWxsKTtcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICAgICAgICAgICAnTnVjbGV1cy5Ob3RpZmljYXRpb25zOiBGYWlsZWQgdG8gcmVtb3ZlIHJlZ2lzdHJhdGlvbiBmcm9tIHNlcnZlci4nLFxuICAgICAgICAgICAgICAgICAgZXJyb3JcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIF9yZWplY3QoZXJyb3IpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICApO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2goKGVycm9yKSA9PiBfcmVqZWN0KGVycm9yKSk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgcmVmcmVzaChub3RpZnlBYm91dE5ldyA9IGZhbHNlKSB7XG4gICAgdGhpcy5odHRwXG4gICAgICAuZ2V0PE5vdGlmaWNhdGlvbltdPih0aGlzLmFwaVVybCArICdub3RpZmljYXRpb25zJylcbiAgICAgIC5zdWJzY3JpYmUoKHJlcykgPT4ge1xuICAgICAgICB0aGlzLnVwZGF0ZU5vdGlmaWNhdGlvbnMocmVzLCBub3RpZnlBYm91dE5ldyk7XG4gICAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBnZXROb3RpZmljYXRpb24oaWQ6IHN0cmluZyk6IE9ic2VydmFibGU8Tm90aWZpY2F0aW9uPiB7XG4gICAgY29uc3QgbG9jYWxOb3RpZmljYXRpb24gPSB0aGlzLm5vdGlmaWNhdGlvbnMuZmluZCgoeCkgPT4geC5pZCA9PT0gaWQpO1xuICAgIGlmIChsb2NhbE5vdGlmaWNhdGlvbikge1xuICAgICAgcmV0dXJuIG9mKGxvY2FsTm90aWZpY2F0aW9uKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8Tm90aWZpY2F0aW9uPih0aGlzLmFwaVVybCArICdub3RpZmljYXRpb25zLycgKyBpZCk7XG4gIH1cblxuICBwdWJsaWMgcmVhZE5vdGlmaWNhdGlvbihpZDogc3RyaW5nKSB7XG4gICAgY29uc3QgbiA9IHRoaXMubm90aWZpY2F0aW9ucy5maW5kKCh4KSA9PiB4LmlkID09PSBpZCk7XG4gICAgaWYgKG4gJiYgIW4uaXNSZWFkKSB7XG4gICAgICBuLmlzUmVhZCA9IHRydWU7XG4gICAgICB0aGlzLm5vdGlmeVN0YXRlQ2hhbmdlZCgpO1xuICAgIH1cbiAgICB0aGlzLmh0dHAuZ2V0KHRoaXMuYXBpVXJsICsgJ25vdGlmaWNhdGlvbnMvcmVhZC8nICsgaWQpLnN1YnNjcmliZSgpO1xuICB9XG5cbiAgcHVibGljIGRpc21pc3NOb3RpZmljYXRpb24oaWQ6IHN0cmluZykge1xuICAgIHRoaXMuZGVsZXRlTm90aWZpY2F0b24oaWQpO1xuICAgIHRoaXMuaHR0cC5kZWxldGUodGhpcy5hcGlVcmwgKyAnbm90aWZpY2F0aW9ucy8nICsgaWQpLnN1YnNjcmliZSgpO1xuICAgIHRoaXMucmVtb3ZlRGVsaXZlcmVkTm90aWZpY2F0aW9uKGlkKTtcbiAgfVxuXG4gIHB1YmxpYyBkaXNtaXNzQWxsKCkge1xuICAgIHRoaXMubm90aWZpY2F0aW9ucy5zcGxpY2UoMCk7XG4gICAgdGhpcy5ub3RpZnlTdGF0ZUNoYW5nZWQoKTtcbiAgICB0aGlzLmh0dHAuZGVsZXRlKHRoaXMuYXBpVXJsICsgJ25vdGlmaWNhdGlvbnMvYWxsJykuc3Vic2NyaWJlKCk7XG4gICAgaWYgKHRoaXMuX3BsYXRmb3JtID09PSAnaW9zJyB8fCB0aGlzLl9wbGF0Zm9ybSA9PT0gJ2FuZHJvaWQnKSB7XG4gICAgICBQdXNoTm90aWZpY2F0aW9ucy5yZW1vdmVBbGxEZWxpdmVyZWROb3RpZmljYXRpb25zKCk7XG4gICAgfSBlbHNlIGlmICh0aGlzLl9wbGF0Zm9ybSA9PT0gJ3dlYicpIHtcbiAgICAgIC8vIFRPRE86IHJlbW92ZSBhbGwgd2ViIHB1c2ggbm90aWZpY2F0aW9uc1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyByZWFkQWxsKCkge1xuICAgIGZvciAoY29uc3QgbiBvZiB0aGlzLm5vdGlmaWNhdGlvbnMpIHtcbiAgICAgIG4uaXNSZWFkID0gdHJ1ZTtcbiAgICB9XG4gICAgdGhpcy5ub3RpZnlTdGF0ZUNoYW5nZWQoKTtcbiAgICB0aGlzLmh0dHAuZ2V0KHRoaXMuYXBpVXJsICsgJ25vdGlmaWNhdGlvbnMvcmVhZC9hbGwnKS5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRDaGFubmVsQ29uZmlnKFxuICAgIHNlbmRlcklkOiBzdHJpbmcsXG4gICAgY2hhbm5lbElkOiBzdHJpbmcsXG4gICAgbGFuZ3VhZ2U/OiBzdHJpbmdcbiAgKSB7XG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8VXNlckNoYW5uZWxDb25maWc+KFxuICAgICAgdGhpcy5hcGlVcmwgK1xuICAgICAgICBgc2V0dGluZ3MvY2hhbm5lbC8ke3NlbmRlcklkfS8ke2NoYW5uZWxJZH0/bGFuZ3VhZ2U9JHtsYW5ndWFnZX1gXG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRDaGFubmVsQ29uZmlnc0ZvclNlbmRlcihcbiAgICBzZW5kZXJJZDogc3RyaW5nLFxuICAgIGNoYW5uZWxJZHM6IHN0cmluZ1tdLFxuICAgIGxhbmd1YWdlPzogc3RyaW5nXG4gICkge1xuICAgIGNvbnN0IGlkc1N0ciA9IGNoYW5uZWxJZHMubWFwKCh4KSA9PiBzZW5kZXJJZCArICcsJyArIHgpLmpvaW4oJzsnKTtcbiAgICByZXR1cm4gdGhpcy5nZXRDaGFubmVsQ29uZmlnc0ludGVybmFsKGlkc1N0ciwgbGFuZ3VhZ2UpO1xuICB9XG5cbiAgcHVibGljIGdldENoYW5uZWxDb25maWdzKGlkczogQ2hhbm5lbElkW10sIGxhbmd1YWdlPzogc3RyaW5nKSB7XG4gICAgY29uc3QgaWRzU3RyID0gaWRzLm1hcCgoeCkgPT4geC5zZW5kZXJJZCArICcsJyArIHguY2hhbm5lbElkKS5qb2luKCc7Jyk7XG4gICAgcmV0dXJuIHRoaXMuZ2V0Q2hhbm5lbENvbmZpZ3NJbnRlcm5hbChpZHNTdHIsIGxhbmd1YWdlKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRDaGFubmVsQ29uZmlnKHNlbmRlcklkOiBzdHJpbmcsIGNvbmZpZzogVXNlckNoYW5uZWxDb25maWcpIHtcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3Q8dm9pZD4oXG4gICAgICBgJHt0aGlzLmFwaVVybH1zZXR0aW5ncy9jaGFubmVsLyR7c2VuZGVySWR9YCxcbiAgICAgIGNvbmZpZ1xuICAgICk7XG4gIH1cblxuICBwdWJsaWMgc2V0Q2hhbm5lbENvbmZpZ3MoY29uZmlnczogVXNlckNoYW5uZWxDb25maWdbXSkge1xuICAgIHJldHVybiB0aGlzLmh0dHAucG9zdDx2b2lkPihgJHt0aGlzLmFwaVVybH1zZXR0aW5ncy9jaGFubmVsc2AsIGNvbmZpZ3MpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRDaGFubmVsQ29uZmlnc0ludGVybmFsKGlkczogc3RyaW5nLCBsYW5ndWFnZT86IHN0cmluZykge1xuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PFVzZXJDaGFubmVsQ29uZmlnW10+KFxuICAgICAgYCR7dGhpcy5hcGlVcmx9c2V0dGluZ3MvY2hhbm5lbHM/aWRzPSR7aWRzfSZsYW5ndWFnZT0ke2xhbmd1YWdlfWBcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVOb3RpZmljYXRpb25zKFxuICAgIG5ld05vdGlmaWNhdGlvbnM6IE5vdGlmaWNhdGlvbltdLFxuICAgIG5vdGlmeUFib3V0TmV3ID0gZmFsc2VcbiAgKSB7XG4gICAgbGV0IHN0YXRlQ2hhbmdlZCA9IGZhbHNlO1xuICAgIGZvciAoY29uc3QgbiBvZiBuZXdOb3RpZmljYXRpb25zKSB7XG4gICAgICBjb25zdCBleGlzdGluZyA9IHRoaXMubm90aWZpY2F0aW9ucy5maW5kKCh4KSA9PiB4LmlkID09PSBuLmlkKTtcbiAgICAgIGlmIChleGlzdGluZykge1xuICAgICAgICBpZiAoZXhpc3RpbmcuaXNSZWFkICE9PSBuLmlzUmVhZCkge1xuICAgICAgICAgIGV4aXN0aW5nLmlzUmVhZCA9IG4uaXNSZWFkO1xuICAgICAgICAgIHN0YXRlQ2hhbmdlZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGxldCBpID0gMDtcbiAgICAgICAgd2hpbGUgKFxuICAgICAgICAgIGkgPCB0aGlzLm5vdGlmaWNhdGlvbnMubGVuZ3RoICYmXG4gICAgICAgICAgbi5kYXRlQ3JlYXRlZCA8IHRoaXMubm90aWZpY2F0aW9uc1tpXS5kYXRlQ3JlYXRlZFxuICAgICAgICApIHtcbiAgICAgICAgICBpKys7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5ub3RpZmljYXRpb25zLnNwbGljZShpLCAwLCBuKTtcbiAgICAgICAgc3RhdGVDaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgaWYgKG5vdGlmeUFib3V0TmV3KSB7XG4gICAgICAgICAgdGhpcy5fbmV3Tm90aWZpY2F0aW9ucy5uZXh0KG4pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKTtcbiAgICBmb3IgKGxldCBpID0gdGhpcy5ub3RpZmljYXRpb25zLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBjb25zdCBuID0gdGhpcy5ub3RpZmljYXRpb25zW2ldO1xuICAgICAgaWYgKFxuICAgICAgICBuZXcgRGF0ZShuLmV4cGlyYXRpb25EYXRlKS5nZXRUaW1lKCkgPCBub3cgfHxcbiAgICAgICAgIW5ld05vdGlmaWNhdGlvbnMuZmluZCgoeCkgPT4geC5pZCA9PT0gbi5pZClcbiAgICAgICkge1xuICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbnMuc3BsaWNlKGksIDEpO1xuICAgICAgICBzdGF0ZUNoYW5nZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzdGF0ZUNoYW5nZWQpIHtcbiAgICAgIHRoaXMubm90aWZ5U3RhdGVDaGFuZ2VkKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzYXZlVG9TdG9yYWdlKCkge1xuICAgIGNvbnN0IHN0ciA9IEpTT04uc3RyaW5naWZ5KHRoaXMubm90aWZpY2F0aW9ucyk7XG4gICAgd2luZG93LmxvY2FsU3RvcmFnZS5zZXRJdGVtKHRoaXMubm90aWZpY2F0aW9uc1N0b3JhZ2VLZXksIHN0cik7XG4gIH1cblxuICBwcml2YXRlIGxvYWRGcm9tU3RvcmFnZSgpIHtcbiAgICB0cnkge1xuICAgICAgY29uc3Qgc3RyID0gd2luZG93LmxvY2FsU3RvcmFnZS5nZXRJdGVtKHRoaXMubm90aWZpY2F0aW9uc1N0b3JhZ2VLZXkpO1xuICAgICAgaWYgKHN0cikge1xuICAgICAgICBjb25zdCBub3RpZmljYXRpb25zID0gSlNPTi5wYXJzZShzdHIpIGFzIE5vdGlmaWNhdGlvbltdO1xuICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbnMgPSBub3RpZmljYXRpb25zLmZpbHRlcigoeCkgPT4gISF4KTtcbiAgICAgICAgLy8gcHJlY2F1dGlvbiBmb3Igbm90aWZpY2F0aW9uLmlzUmVhZCBvZiB1bmRlZmluZWQgZXJyb3JcbiAgICAgICAgdGhpcy5ub3RpZnlTdGF0ZUNoYW5nZWQoZmFsc2UpO1xuICAgICAgfVxuICAgIH0gY2F0Y2gge1xuICAgICAgLyogZW1wdHkgKi9cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGhhbmRsZU5vdGlmaWNhdGlvbkV2ZW50KFxuICAgIGlkOiBzdHJpbmcsXG4gICAgZXZlbnRUeXBlOiBOb3RpZmljYXRpb25FdmVudFR5cGVcbiAgKSB7XG4gICAgaWYgKGV2ZW50VHlwZS5zdGFydHNXaXRoKCduZXcnKSB8fCBldmVudFR5cGUgPT09ICd1cGRhdGVkJykge1xuICAgICAgLy8gd2UgYXJlIGhhbmRsaW5nIG5ldyBhbmQgbmV3U2lsZW50XG4gICAgICB0aGlzLmdldE5vdGlmaWNhdGlvbihpZCkuc3Vic2NyaWJlKChuKSA9PiB7XG4gICAgICAgIGlmIChldmVudFR5cGUuc3RhcnRzV2l0aCgnbmV3JykgJiYgIW4uaXNSZWFkKSB7XG4gICAgICAgICAgdGhpcy5fbmV3Tm90aWZpY2F0aW9ucy5uZXh0KG4pO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGV4aXN0aW5nID0gdGhpcy5ub3RpZmljYXRpb25zLmZpbmQoKHgpID0+IHguaWQgPT09IG4uaWQpO1xuICAgICAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgICAgICBleGlzdGluZy5pc1JlYWQgPSBuLmlzUmVhZDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0aGlzLm5vdGlmaWNhdGlvbnMuc3BsaWNlKDAsIDAsIG4pO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubm90aWZ5U3RhdGVDaGFuZ2VkKCk7XG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKGV2ZW50VHlwZSA9PT0gJ2RlbGV0ZWQnKSB7XG4gICAgICB0aGlzLmRlbGV0ZU5vdGlmaWNhdG9uKGlkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5yZWZyZXNoKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBkZWxldGVOb3RpZmljYXRvbihpZDogc3RyaW5nKSB7XG4gICAgY29uc3QgaSA9IHRoaXMubm90aWZpY2F0aW9ucy5maW5kSW5kZXgoKHgpID0+IHguaWQgPT09IGlkKTtcbiAgICBpZiAoaSA+PSAwKSB7XG4gICAgICB0aGlzLm5vdGlmaWNhdGlvbnMuc3BsaWNlKGksIDEpO1xuICAgICAgdGhpcy5ub3RpZnlTdGF0ZUNoYW5nZWQoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIG5vdGlmeVN0YXRlQ2hhbmdlZChwZXJzaXN0U3RhdGUgPSB0cnVlKSB7XG4gICAgaWYgKHBlcnNpc3RTdGF0ZSkge1xuICAgICAgdGhpcy5zYXZlVG9TdG9yYWdlKCk7XG4gICAgfVxuICAgIHRoaXMuX3N0YXRlQ2hhbmdlc1N1YmplY3QubmV4dCgpO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVOb3RpZmljYXRpb25BY3Rpb24obm90aWZpY2F0aW9uQWN0aW9uOiBzdHJpbmcgfCB1bmRlZmluZWQpIHtcbiAgICBpZiAoIW5vdGlmaWNhdGlvbkFjdGlvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdOb3RpZmljYXRpb24gYWN0aW9uIGlzIGVtcHR5IScpO1xuICAgIH1cblxuICAgIGNvbnN0IGFyciA9IG5vdGlmaWNhdGlvbkFjdGlvbi5zcGxpdCgnOicpO1xuICAgIGNvbnN0IG5vdGlmaWNhdGlvbkNsaWNrOiBOb3RpZmljYXRpb25DbGljayA9IHtcbiAgICAgIGlkOiBhcnJbMF0sXG4gICAgICB0eXBlOiBhcnJbMV0gYXMgTm90aWZpY2F0aW9uVHlwZSxcbiAgICAgIHJvdXRlckxpbms6IGFyclsyXSxcbiAgICB9O1xuXG4gICAgY29uc3QgdmFsaWROb3RpZmljYXRpb25DbGlja1R5cGVzID0gWydkZWZhdWx0JywgJ2RlZXBsaW5rJ107XG4gICAgaWYgKHZhbGlkTm90aWZpY2F0aW9uQ2xpY2tUeXBlcy5pbmNsdWRlcyhub3RpZmljYXRpb25DbGljay50eXBlKSkge1xuICAgICAgdGhpcy5fY2xpY2tzU3ViamVjdC5uZXh0KG5vdGlmaWNhdGlvbkNsaWNrKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgYE51Y2xldXMuTm90aWZpY2F0aW9uczogVW5rbm93biBub3RpZmljYXRpb24gYWN0aW9uOiAnJHtub3RpZmljYXRpb25BY3Rpb259Jy5gXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlRGVsaXZlcmVkTm90aWZpY2F0aW9uKGlkOiBzdHJpbmcpIHtcbiAgICBpZiAodGhpcy5fcGxhdGZvcm0gPT09ICdpb3MnIHx8IHRoaXMuX3BsYXRmb3JtID09PSAnYW5kcm9pZCcpIHtcbiAgICAgIFB1c2hOb3RpZmljYXRpb25zLmdldERlbGl2ZXJlZE5vdGlmaWNhdGlvbnMoKS50aGVuKChsaXN0KSA9PiB7XG4gICAgICAgIGNvbnN0IHRvUmVtb3ZlID0gbGlzdC5ub3RpZmljYXRpb25zLmZpbHRlcigobikgPT4ge1xuICAgICAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmdldE5vdGlmaWNhdGlvblBheWxvYWREYXRhKG4pO1xuICAgICAgICAgIHJldHVybiBkYXRhLm5vdGlmaWNhdGlvbklkID09PSBpZDtcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gVE9ETzogT24gQW5kcm9pZCB0aGlzIGRvZXMgbm90IGN1cnJlbnRseSB3b3JrIGJlY2F1c2Ugbm90aWZpY2F0aW9uSUQgaXMgbm90IHNldC5cbiAgICAgICAgLy8gVGhpcyBteSBzb2x2ZSB0aGUgaXNzdWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9pb25pYy10ZWFtL2NhcGFjaXRvci9wdWxsLzM1MjNcbiAgICAgICAgUHVzaE5vdGlmaWNhdGlvbnMucmVtb3ZlRGVsaXZlcmVkTm90aWZpY2F0aW9ucyh7XG4gICAgICAgICAgbm90aWZpY2F0aW9uczogdG9SZW1vdmUsXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmICh0aGlzLl9wbGF0Zm9ybSA9PT0gJ3dlYicpIHtcbiAgICAgIC8vIFRPRE86IHJlbW92ZSB3ZWIgcHVzaCBub3RpZmljYXRpb25cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldE5vdGlmaWNhdGlvblBheWxvYWREYXRhKFxuICAgIHB1c2hOb3RpZmljYXRpb246IFB1c2hOb3RpZmljYXRpb25TY2hlbWFcbiAgKTogUGF5bG9hZERhdGEge1xuICAgIHJldHVybiB0aGlzLl9wbGF0Zm9ybSA9PT0gJ2lvcydcbiAgICAgID8gcHVzaE5vdGlmaWNhdGlvbi5kYXRhLmRhdGFcbiAgICAgIDogcHVzaE5vdGlmaWNhdGlvbi5kYXRhO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyByZWdpc3RlckNhcGFjaXRvckV2ZW50cygpIHtcbiAgICBhd2FpdCBQdXNoTm90aWZpY2F0aW9ucy5hZGRMaXN0ZW5lcigncHVzaE5vdGlmaWNhdGlvblJlY2VpdmVkJywgKG4pID0+IHtcbiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmdldE5vdGlmaWNhdGlvblBheWxvYWREYXRhKG4pO1xuICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICdOdWNsZXVzLk5vdGlmaWNhdGlvbnM6IFJlY2VpdmVkIGNhcGFjaXRvciBwdXNoIGV2ZW50OiAnICtcbiAgICAgICAgICBkYXRhLmV2ZW50VHlwZSxcbiAgICAgICAgblxuICAgICAgKTtcbiAgICAgIHRoaXMuaGFuZGxlTm90aWZpY2F0aW9uRXZlbnQoZGF0YS5ub3RpZmljYXRpb25JZCwgZGF0YS5ldmVudFR5cGUpO1xuICAgIH0pO1xuXG4gICAgYXdhaXQgUHVzaE5vdGlmaWNhdGlvbnMuYWRkTGlzdGVuZXIoXG4gICAgICAncHVzaE5vdGlmaWNhdGlvbkFjdGlvblBlcmZvcm1lZCcsXG4gICAgICAoYSkgPT4ge1xuICAgICAgICBsZXQgYWN0aW9uID0gKGEgYXMgYW55KS5ub3RpZmljYXRpb24uZGF0YS5ub3RpZmljYXRpb25BY3Rpb247XG4gICAgICAgIGlmICh0aGlzLl9wbGF0Zm9ybSA9PT0gJ2lvcycpIHtcbiAgICAgICAgICBhY3Rpb24gPSAoYSBhcyBhbnkpLm5vdGlmaWNhdGlvbi5kYXRhLmRhdGEubm90aWZpY2F0aW9uQWN0aW9uO1xuICAgICAgICB9XG4gICAgICAgIGNvbnNvbGUubG9nKFxuICAgICAgICAgICdOdWNsZXVzLk5vdGlmaWNhdGlvbnM6IFJlY2VpdmVkIGNhcGFjaXRvciBhY3Rpb24gZXZlbnQnLFxuICAgICAgICAgIGFjdGlvblxuICAgICAgICApO1xuICAgICAgICB0aGlzLmhhbmRsZU5vdGlmaWNhdGlvbkFjdGlvbihhY3Rpb24pO1xuICAgICAgfVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHJlZ2lzdGVyV2ViUHVzaEV2ZW50cygpIHtcbiAgICB0aGlzLnN3UHVzaC5tZXNzYWdlcy5zdWJzY3JpYmUoKG4pID0+IHtcbiAgICAgIGNvbnN0IGRhdGE6IFBheWxvYWREYXRhID0gKG4gYXMgYW55KS5kYXRhO1xuICAgICAgY29uc29sZS5sb2coXG4gICAgICAgICdOdWNsZXVzLk5vdGlmaWNhdGlvbnM6IFJlY2VpdmVkIFdlYlB1c2ggZXZlbnQ6ICcgKyBkYXRhLmV2ZW50VHlwZSxcbiAgICAgICAgblxuICAgICAgKTtcbiAgICAgIHRoaXMuaGFuZGxlTm90aWZpY2F0aW9uRXZlbnQoZGF0YS5ub3RpZmljYXRpb25JZCwgZGF0YS5ldmVudFR5cGUpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5zd1B1c2gubm90aWZpY2F0aW9uQ2xpY2tzLnN1YnNjcmliZSgoYWN0aW9uKSA9PiB7XG4gICAgICBjb25zb2xlLmxvZyhcbiAgICAgICAgJ051Y2xldXMuTm90aWZpY2F0aW9uczogUmVjZWl2ZWQgV2ViUHVzaCBhY3Rpb24gZXZlbnQnLFxuICAgICAgICBhY3Rpb25cbiAgICAgICk7XG4gICAgICBjb25zdCB0YWcgPSBhY3Rpb24ubm90aWZpY2F0aW9uLnRhZztcbiAgICAgIHRoaXMuaGFuZGxlTm90aWZpY2F0aW9uQWN0aW9uKHRhZyk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGdldFJlZ2lzdHJhdGlvbkluZm8oKTogUHJvbWlzZTxSZWdpc3RyYXRpb24+IHtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKF9yZXNvbHZlLCBfcmVqZWN0KSA9PiB7XG4gICAgICBjb25zdCByZWdpc3RyYXRpb25JZCA9IHdpbmRvdy5sb2NhbFN0b3JhZ2UuZ2V0SXRlbShcbiAgICAgICAgdGhpcy5yZWdpc3RyYXRpb25TdG9yYWdlS2V5XG4gICAgICApIGFzIHN0cmluZztcbiAgICAgIGlmICh0aGlzLl9wbGF0Zm9ybSA9PT0gJ2FuZHJvaWQnIHx8IHRoaXMuX3BsYXRmb3JtID09PSAnaW9zJykge1xuICAgICAgICAvLyBjYXBhY2l0b3IgcGxhdGZvcm1cbiAgICAgICAgY29uc3QgbGlzdGVuZXIgPSBQdXNoTm90aWZpY2F0aW9ucy5hZGRMaXN0ZW5lcihcbiAgICAgICAgICAncmVnaXN0cmF0aW9uJyxcbiAgICAgICAgICAodG9rZW4pID0+IHtcbiAgICAgICAgICAgIGxpc3RlbmVyLnJlbW92ZSgpO1xuICAgICAgICAgICAgX3Jlc29sdmUoe1xuICAgICAgICAgICAgICBpZDogcmVnaXN0cmF0aW9uSWQsXG4gICAgICAgICAgICAgIHRva2VuOiB0b2tlbi52YWx1ZSxcbiAgICAgICAgICAgICAgcGxhdGZvcm06IHRoaXMuX3BsYXRmb3JtLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICApO1xuICAgICAgICBQdXNoTm90aWZpY2F0aW9ucy5yZWdpc3RlcigpLmNhdGNoKChlcnJvcikgPT5cbiAgICAgICAgICBfcmVqZWN0KCdDb3VsZCBub3QgcmVnaXN0ZXIgZm9yIG5vdGlmaWNhdGlvbnM6JyArIGVycm9yKVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLl9wbGF0Zm9ybSA9PT0gJ3dlYicpIHtcbiAgICAgICAgLy8gV2ViIFB1c2ggQVBJXG4gICAgICAgIHRoaXMuaHR0cC5nZXQ8V2ViS2V5Pih0aGlzLmFwaVVybCArICdyZWdpc3RyYXRpb24vd2Via2V5Jykuc3Vic2NyaWJlKFxuICAgICAgICAgIChrZXkpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZ2V0V2ViUHVzaFN1YnNjcmlwdGlvbihrZXkucHVibGljS2V5KS50aGVuKChzdWJzY3JpcHRpb24pID0+IHtcbiAgICAgICAgICAgICAgY29uc3QgdCA9IEpTT04uc3RyaW5naWZ5KHN1YnNjcmlwdGlvbi50b0pTT04oKSk7XG4gICAgICAgICAgICAgIF9yZXNvbHZlKHsgaWQ6IHJlZ2lzdHJhdGlvbklkLCB0b2tlbjogdCwgcGxhdGZvcm06ICd3ZWInIH0pO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfSxcbiAgICAgICAgICAoZXJyb3IpID0+IF9yZWplY3QoZXJyb3IpXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBfcmVqZWN0KGBOdWNsZXVzLk5vdGlmaWNhdGlvbnM6IFBsYXRmb3JtIGlzIG5vdCBzdXBwb3J0ZWRgKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0V2ViUHVzaFN1YnNjcmlwdGlvbihwdWJsaWNLZXk6IHN0cmluZyk6IFByb21pc2U8UHVzaFN1YnNjcmlwdGlvbj4ge1xuICAgIHJldHVybiBuZXcgUHJvbWlzZSgoX3Jlc29sdmUsIF9yZWplY3QpID0+IHtcbiAgICAgIHRoaXMuc3dQdXNoLnN1YnNjcmlwdGlvbi5zdWJzY3JpYmUoXG4gICAgICAgIChzdWJzY3JpcHRpb24pID0+IHtcbiAgICAgICAgICBpZiAoc3Vic2NyaXB0aW9uICE9IG51bGwpIHtcbiAgICAgICAgICAgIF9yZXNvbHZlKHN1YnNjcmlwdGlvbik7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc3dQdXNoXG4gICAgICAgICAgICAgIC5yZXF1ZXN0U3Vic2NyaXB0aW9uKHsgc2VydmVyUHVibGljS2V5OiBwdWJsaWNLZXkgfSlcbiAgICAgICAgICAgICAgLnRoZW4oKHMpID0+IF9yZXNvbHZlKHMpKVxuICAgICAgICAgICAgICAuY2F0Y2goKGUpID0+IF9yZWplY3QoZSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgKGVycm9yKSA9PiB7XG4gICAgICAgICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgICAgICdOdWNsZXVzLk5vdGlmaWNhdGlvbnM6IENhbm5vdCBnZXQgd2ViIHB1c2ggc3Vic2NyaXB0aW9uJyxcbiAgICAgICAgICAgIGVycm9yXG4gICAgICAgICAgKTtcbiAgICAgICAgICBfcmVqZWN0KGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgKTtcbiAgICB9KTtcbiAgfVxufVxuIl19
|