@po-ui/ng-sync 5.22.4 → 5.22.7
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 +22 -22
- package/bundles/po-ui-ng-sync.umd.js +2915 -2915
- package/bundles/po-ui-ng-sync.umd.js.map +1 -1
- package/esm2015/lib/index.js +15 -15
- package/esm2015/lib/models/index.js +6 -6
- package/esm2015/lib/models/po-data-message.model.js +57 -57
- package/esm2015/lib/models/po-data-transform.model.js +22 -22
- package/esm2015/lib/models/po-entity/po-entity.model.js +229 -229
- package/esm2015/lib/models/po-event-sourcing-error-response.model.js +17 -17
- package/esm2015/lib/models/po-network-status.model.js +44 -44
- package/esm2015/lib/models/po-network-type.enum.js +30 -30
- package/esm2015/lib/models/po-query-builder/po-query-builder.model.js +241 -241
- package/esm2015/lib/models/po-request-type.enum.js +16 -16
- package/esm2015/lib/po-sync.module.js +31 -31
- package/esm2015/lib/services/po-event-sourcing/enums/po-event-sourcing-operation.enum.js +17 -17
- package/esm2015/lib/services/po-event-sourcing/index.js +4 -4
- package/esm2015/lib/services/po-event-sourcing/interfaces/po-event-sourcing-item.interface.js +2 -2
- package/esm2015/lib/services/po-event-sourcing/interfaces/po-event-sourcing-summary-item.interface.js +2 -2
- package/esm2015/lib/services/po-event-sourcing/po-event-sourcing.service.js +411 -411
- package/esm2015/lib/services/po-http-client/interfaces/po-http-header-option.interface.js +11 -11
- package/esm2015/lib/services/po-http-client/interfaces/po-http-request-data.interface.js +2 -2
- package/esm2015/lib/services/po-http-client/interfaces/po-response-api.interface.js +2 -2
- package/esm2015/lib/services/po-http-client/po-http-client.service.js +147 -147
- package/esm2015/lib/services/po-http-client/po-http-request-type.enum.js +25 -25
- package/esm2015/lib/services/po-network/po-network.service.js +58 -58
- package/esm2015/lib/services/po-schema/index.js +4 -4
- package/esm2015/lib/services/po-schema/po-schema-definition/po-schema-definition.service.js +80 -80
- package/esm2015/lib/services/po-schema/po-schema-util/po-schema-util.model.js +124 -124
- package/esm2015/lib/services/po-schema/po-schema.service.js +198 -198
- package/esm2015/lib/services/po-sync/interfaces/po-sync-config.interface.js +2 -2
- package/esm2015/lib/services/po-sync/interfaces/po-sync-field-options.interface.js +2 -2
- package/esm2015/lib/services/po-sync/interfaces/po-sync-response.interface.js +2 -2
- package/esm2015/lib/services/po-sync/interfaces/po-sync-schema.interface.js +2 -2
- package/esm2015/lib/services/po-sync/po-sync.service.js +336 -336
- package/esm2015/lib/utils/utils.js +63 -63
- package/esm2015/po-ui-ng-sync.js +8 -8
- package/esm2015/public-api.js +2 -2
- package/fesm2015/po-ui-ng-sync.js +2047 -2047
- package/fesm2015/po-ui-ng-sync.js.map +1 -1
- package/lib/index.d.ts +14 -14
- package/lib/models/index.d.ts +5 -5
- package/lib/models/po-data-message.model.d.ts +46 -46
- package/lib/models/po-data-transform.model.d.ts +52 -52
- package/lib/models/po-entity/po-entity.model.d.ts +122 -122
- package/lib/models/po-event-sourcing-error-response.model.d.ts +20 -20
- package/lib/models/po-network-status.model.d.ts +25 -25
- package/lib/models/po-network-type.enum.d.ts +28 -28
- package/lib/models/po-query-builder/po-query-builder.model.d.ts +126 -126
- package/lib/models/po-request-type.enum.d.ts +14 -14
- package/lib/po-sync.module.d.ts +7 -7
- package/lib/services/po-event-sourcing/enums/po-event-sourcing-operation.enum.d.ts +11 -11
- package/lib/services/po-event-sourcing/index.d.ts +3 -3
- package/lib/services/po-event-sourcing/interfaces/po-event-sourcing-item.interface.d.ts +26 -26
- package/lib/services/po-event-sourcing/interfaces/po-event-sourcing-summary-item.interface.d.ts +16 -16
- package/lib/services/po-event-sourcing/po-event-sourcing.service.d.ts +71 -71
- package/lib/services/po-http-client/interfaces/po-http-header-option.interface.d.ts +15 -15
- package/lib/services/po-http-client/interfaces/po-http-request-data.interface.d.ts +24 -24
- package/lib/services/po-http-client/interfaces/po-response-api.interface.d.ts +14 -14
- package/lib/services/po-http-client/po-http-client.service.d.ts +75 -75
- package/lib/services/po-http-client/po-http-request-type.enum.d.ts +23 -23
- package/lib/services/po-network/po-network.service.d.ts +33 -33
- package/lib/services/po-schema/index.d.ts +3 -3
- package/lib/services/po-schema/po-schema-definition/po-schema-definition.service.d.ts +48 -48
- package/lib/services/po-schema/po-schema-util/po-schema-util.model.d.ts +79 -79
- package/lib/services/po-schema/po-schema.service.d.ts +95 -95
- package/lib/services/po-sync/interfaces/po-sync-config.interface.d.ts +24 -24
- package/lib/services/po-sync/interfaces/po-sync-field-options.interface.d.ts +15 -15
- package/lib/services/po-sync/interfaces/po-sync-response.interface.d.ts +20 -20
- package/lib/services/po-sync/interfaces/po-sync-schema.interface.d.ts +37 -37
- package/lib/services/po-sync/po-sync.service.d.ts +159 -159
- package/lib/utils/utils.d.ts +36 -36
- package/package.json +4 -4
- package/po-ui-ng-sync-5.22.7.tgz +0 -0
- package/po-ui-ng-sync.d.ts +8 -8
- package/public-api.d.ts +1 -1
- package/schematics/README.md +169 -169
- package/schematics/collection.json +15 -15
- package/schematics/migrations.json +25 -25
- package/schematics/ng-add/index.d.ts +7 -7
- package/schematics/ng-add/index.js +33 -33
- package/schematics/ng-add/index.spec.d.ts +1 -1
- package/schematics/ng-add/index.spec.js +62 -62
- package/schematics/ng-add/schema.json +7 -7
- package/schematics/ng-generate/schema/files/__path__/__name@dasherize__/__name@dasherize__.constants.ts.template +13 -13
- package/schematics/ng-generate/schema/index.d.ts +4 -4
- package/schematics/ng-generate/schema/index.js +12 -12
- package/schematics/ng-generate/schema/index.spec.d.ts +1 -1
- package/schematics/ng-generate/schema/index.spec.js +44 -44
- package/schematics/ng-generate/schema/schema.d.ts +3 -3
- package/schematics/ng-generate/schema/schema.js +2 -2
- package/schematics/ng-generate/schema/schema.json +31 -31
- package/schematics/ng-update/v2/changes.d.ts +8 -8
- package/schematics/ng-update/v2/changes.js +20 -20
- package/schematics/ng-update/v2/index.d.ts +5 -5
- package/schematics/ng-update/v2/index.js +101 -101
- package/schematics/ng-update/v3/changes.d.ts +2 -2
- package/schematics/ng-update/v3/changes.js +14 -14
- package/schematics/ng-update/v3/index.d.ts +1 -1
- package/schematics/ng-update/v3/index.js +16 -16
- package/schematics/ng-update/v4/changes.d.ts +2 -2
- package/schematics/ng-update/v4/changes.js +14 -14
- package/schematics/ng-update/v4/index.d.ts +1 -1
- package/schematics/ng-update/v4/index.js +15 -15
- package/schematics/ng-update/v5/changes.d.ts +2 -2
- package/schematics/ng-update/v5/changes.js +13 -13
- package/schematics/ng-update/v5/index.d.ts +1 -1
- package/schematics/ng-update/v5/index.js +15 -15
- package/po-ui-ng-sync-5.22.4.tgz +0 -0
|
@@ -1,411 +1,411 @@
|
|
|
1
|
-
import { __awaiter } from "tslib";
|
|
2
|
-
import { Injectable } from '@angular/core';
|
|
3
|
-
import * as HttpStatus from 'http-status-codes';
|
|
4
|
-
import { Observable, of, Subject } from 'rxjs';
|
|
5
|
-
import { expand, map, reduce } from 'rxjs/operators';
|
|
6
|
-
import { PoStorageService } from '@po-ui/ng-storage';
|
|
7
|
-
import { toBase64, toFile } from '../../utils/utils';
|
|
8
|
-
import { PoEventSourcingErrorResponse } from '../../models/po-event-sourcing-error-response.model';
|
|
9
|
-
import { PoEventSourcingOperation } from './enums/po-event-sourcing-operation.enum';
|
|
10
|
-
import { PoHttpClientService } from './../po-http-client/po-http-client.service';
|
|
11
|
-
import { PoHttpRequestType } from '../po-http-client/po-http-request-type.enum';
|
|
12
|
-
import { PoRequestType } from '../../models/po-request-type.enum';
|
|
13
|
-
import { PoSchemaDefinitionService } from './../po-schema/po-schema-definition/po-schema-definition.service';
|
|
14
|
-
import { PoSchemaService } from './../po-schema/po-schema.service';
|
|
15
|
-
import { PoSchemaUtil } from './../po-schema/po-schema-util/po-schema-util.model';
|
|
16
|
-
export class PoEventSourcingService {
|
|
17
|
-
constructor(poSchemaDefinition, poSchemaService, poStorage, poHttpClient) {
|
|
18
|
-
this.poSchemaDefinition = poSchemaDefinition;
|
|
19
|
-
this.poSchemaService = poSchemaService;
|
|
20
|
-
this.poStorage = poStorage;
|
|
21
|
-
this.poHttpClient = poHttpClient;
|
|
22
|
-
this.stoppedQueueEventSourcing = false;
|
|
23
|
-
this.responseSubject = new Subject();
|
|
24
|
-
this.schemasSyncConfig = {};
|
|
25
|
-
}
|
|
26
|
-
static getUrl(eventSourcingItem, schema, requestType) {
|
|
27
|
-
const schemaUrl = PoSchemaUtil.getUrl(schema, requestType);
|
|
28
|
-
const schemaId = eventSourcingItem.record[schema.idField];
|
|
29
|
-
if (requestType === PoRequestType.GET) {
|
|
30
|
-
return schemaUrl;
|
|
31
|
-
}
|
|
32
|
-
if ([PoRequestType.DELETE, PoRequestType.PATCH].includes(requestType)) {
|
|
33
|
-
return schemaUrl ? `${schemaUrl}/${schemaId}` : `${PoSchemaUtil.getUrl(schema, PoRequestType.GET)}/${schemaId}`;
|
|
34
|
-
}
|
|
35
|
-
if (requestType === PoRequestType.POST) {
|
|
36
|
-
return schemaUrl ? schemaUrl : PoSchemaUtil.getUrl(schema, PoRequestType.GET);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
create(schemaName, newItem, customRequestId) {
|
|
40
|
-
const eventSourcingItem = this.createEventSourcingItem(PoEventSourcingOperation.Insert, newItem, schemaName, customRequestId);
|
|
41
|
-
return this.insertEventSourcingQueue(eventSourcingItem);
|
|
42
|
-
}
|
|
43
|
-
createBatchEvents(schemaName, eventList) {
|
|
44
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
45
|
-
const eventSourcingList = this.createEventSourcingList(schemaName, eventList);
|
|
46
|
-
yield this.poStorage.appendArrayToArray(PoEventSourcingService.event_sourcing_name, eventSourcingList);
|
|
47
|
-
this.notifyEventCreation();
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Destrói a chave do *storage* que contém a fila de dados que estão esperando para serem enviados ao
|
|
52
|
-
* servidor *(EventSourcing)*.
|
|
53
|
-
*
|
|
54
|
-
* @returns {Promise<void>} Promessa que é resolvida quando a chave referente a fila de *EventSourcing* for destruída.
|
|
55
|
-
*/
|
|
56
|
-
destroyEventSourcingQueue() {
|
|
57
|
-
return this.poStorage.remove(PoEventSourcingService.event_sourcing_name);
|
|
58
|
-
}
|
|
59
|
-
httpCommand(httpOperationData, customRequestId) {
|
|
60
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
61
|
-
httpOperationData = yield this.serializeBody(httpOperationData);
|
|
62
|
-
const eventSourcingItem = this.createEventSourcingItem(PoEventSourcingOperation.Http, httpOperationData, undefined, customRequestId);
|
|
63
|
-
yield this.insertEventSourcingQueue(eventSourcingItem);
|
|
64
|
-
return eventSourcingItem.id;
|
|
65
|
-
});
|
|
66
|
-
}
|
|
67
|
-
responsesSubject() {
|
|
68
|
-
return this.responseSubject.asObservable();
|
|
69
|
-
}
|
|
70
|
-
onSaveData() {
|
|
71
|
-
if (!this.eventSub) {
|
|
72
|
-
this.eventSub = Observable.create(subscriber => (this.emitter = subscriber));
|
|
73
|
-
}
|
|
74
|
-
return this.eventSub;
|
|
75
|
-
}
|
|
76
|
-
remove(schemaName, itemToDelete, customRequestId) {
|
|
77
|
-
const eventSourcingItem = this.createEventSourcingItem(PoEventSourcingOperation.Delete, itemToDelete, schemaName, customRequestId);
|
|
78
|
-
return this.insertEventSourcingQueue(eventSourcingItem);
|
|
79
|
-
}
|
|
80
|
-
removeEventSourcingItem(idEventSourcingItem) {
|
|
81
|
-
return this.poStorage.removeItemFromArray(PoEventSourcingService.event_sourcing_name, 'id', idEventSourcingItem);
|
|
82
|
-
}
|
|
83
|
-
syncGet() {
|
|
84
|
-
const syncGetFunction = () => __awaiter(this, void 0, void 0, function* () {
|
|
85
|
-
return this.poSchemaDefinition.getAll().then(schemas => {
|
|
86
|
-
const schemaPromises = this.updateStorageSchemas(schemas);
|
|
87
|
-
return Promise.all(schemaPromises);
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
return this.poSchemaService.limitedCallWrap(syncGetFunction);
|
|
91
|
-
}
|
|
92
|
-
syncSend() {
|
|
93
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
94
|
-
const syncSendFunction = () => __awaiter(this, void 0, void 0, function* () {
|
|
95
|
-
const itemOfQueue = yield this.poStorage.getFirstItem(PoEventSourcingService.event_sourcing_name);
|
|
96
|
-
if (itemOfQueue) {
|
|
97
|
-
yield this.selectOperation(itemOfQueue);
|
|
98
|
-
}
|
|
99
|
-
if (this.stoppedQueueEventSourcing || !itemOfQueue) {
|
|
100
|
-
this.stoppedQueueEventSourcing = false;
|
|
101
|
-
return Promise.resolve();
|
|
102
|
-
}
|
|
103
|
-
return syncSendFunction();
|
|
104
|
-
});
|
|
105
|
-
return this.poSchemaService.limitedCallWrap(syncSendFunction);
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
update(schemaName, itemUpdated, customRequestId) {
|
|
109
|
-
const eventSourcingItem = this.createEventSourcingItem(PoEventSourcingOperation.Update, itemUpdated, schemaName, customRequestId);
|
|
110
|
-
return this.insertEventSourcingQueue(eventSourcingItem);
|
|
111
|
-
}
|
|
112
|
-
/* Avalia se o body é do tipo File e se for converte para base64 */
|
|
113
|
-
serializeBody(requestData) {
|
|
114
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
115
|
-
let { body, mimeType, bodyType, fileName } = requestData;
|
|
116
|
-
if (body instanceof File) {
|
|
117
|
-
bodyType = 'File';
|
|
118
|
-
mimeType = body.type;
|
|
119
|
-
fileName = body.name;
|
|
120
|
-
body = yield toBase64(body);
|
|
121
|
-
}
|
|
122
|
-
return Object.assign(Object.assign({}, requestData), { body, mimeType, bodyType, fileName });
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
buildUrlParams(schema, baseUrl, pageNumber) {
|
|
126
|
-
const params = [];
|
|
127
|
-
params.push(`${this.config.dataTransform.getPageSizeParamName()}=${schema.pageSize}`);
|
|
128
|
-
params.push(`${this.config.dataTransform.getPageParamName()}=${pageNumber}`);
|
|
129
|
-
return `${baseUrl}?${params.join('&')}`;
|
|
130
|
-
}
|
|
131
|
-
checkRecordIdExists(recordId, operation) {
|
|
132
|
-
if (!recordId) {
|
|
133
|
-
const error = {
|
|
134
|
-
message: 'Identifier not defined',
|
|
135
|
-
operation: operation
|
|
136
|
-
};
|
|
137
|
-
throw new PoEventSourcingErrorResponse(error);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
concatPageItems(pageAcumulator, requestBody) {
|
|
141
|
-
if (requestBody[this.config.dataTransform.getItemsFieldName()]) {
|
|
142
|
-
pageAcumulator.data = [...pageAcumulator.data, ...requestBody[this.config.dataTransform.getItemsFieldName()]];
|
|
143
|
-
}
|
|
144
|
-
return pageAcumulator;
|
|
145
|
-
}
|
|
146
|
-
createEventSourcingItem(operation, newItem, schemaName, customRequestId, id) {
|
|
147
|
-
if (!schemaName && operation !== PoEventSourcingOperation.Http) {
|
|
148
|
-
throw new Error('PoSyncSchema is not defined.');
|
|
149
|
-
}
|
|
150
|
-
return {
|
|
151
|
-
id: id ? id : new Date().getTime(),
|
|
152
|
-
dateTime: new Date().getTime(),
|
|
153
|
-
schema: schemaName,
|
|
154
|
-
operation: operation,
|
|
155
|
-
record: newItem,
|
|
156
|
-
customRequestId: customRequestId
|
|
157
|
-
};
|
|
158
|
-
}
|
|
159
|
-
createEventSourcingList(schemaName, eventList) {
|
|
160
|
-
return eventList.map((eventItem, index) => {
|
|
161
|
-
const id = new Date().getTime() + index;
|
|
162
|
-
return this.createEventSourcingItem(eventItem.operation, eventItem.record, schemaName, eventItem.customRequestId, id);
|
|
163
|
-
});
|
|
164
|
-
}
|
|
165
|
-
createSchemaSyncConfig(schemaName) {
|
|
166
|
-
this.schemasSyncConfig[schemaName] = {
|
|
167
|
-
page: undefined,
|
|
168
|
-
currentUrlDiff: undefined,
|
|
169
|
-
responseDate: undefined
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
deleteOperation(eventSourcingItem) {
|
|
173
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
174
|
-
try {
|
|
175
|
-
const schema = yield this.poSchemaDefinition.get(eventSourcingItem.schema);
|
|
176
|
-
const recordId = eventSourcingItem.record[schema.idField];
|
|
177
|
-
this.checkRecordIdExists(recordId, PoEventSourcingOperation.Delete);
|
|
178
|
-
const url = PoEventSourcingService.getUrl(eventSourcingItem, schema, PoRequestType.DELETE);
|
|
179
|
-
const response = yield this.sendServerItem(url, PoHttpRequestType.DELETE);
|
|
180
|
-
yield this.removeEventSourcingValidItem(response.status, eventSourcingItem);
|
|
181
|
-
return yield this.sendResponseSubject(eventSourcingItem, response);
|
|
182
|
-
}
|
|
183
|
-
catch (errorResponse) {
|
|
184
|
-
return this.sendResponseSubject(eventSourcingItem, errorResponse, true);
|
|
185
|
-
}
|
|
186
|
-
});
|
|
187
|
-
}
|
|
188
|
-
diffServerItems(currentUrlDiff) {
|
|
189
|
-
return this.poHttpClient.get(currentUrlDiff);
|
|
190
|
-
}
|
|
191
|
-
getBodyAndDate(schemaName, response) {
|
|
192
|
-
const getDateFieldName = this.config.dataTransform.getDateFieldName();
|
|
193
|
-
const responseSyncDate = response.body[getDateFieldName];
|
|
194
|
-
this.schemasSyncConfig[schemaName]['responseDate'] = responseSyncDate;
|
|
195
|
-
return response.body;
|
|
196
|
-
}
|
|
197
|
-
getServerDiffRecords(schema, baseUrl) {
|
|
198
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
199
|
-
const initialAcumulatorPage = { entity: schema.name, data: [] };
|
|
200
|
-
const diffUrl = this.schemasSyncConfig[schema.name]['currentUrlDiff'];
|
|
201
|
-
const serverResponse = yield this.diffServerItems(diffUrl)
|
|
202
|
-
.pipe(map(response => this.getBodyAndDate(schema.name, response)), expand(data => this.paginateSchemaData(data, schema, baseUrl)), reduce((pageAcumulator, requestBody) => this.concatPageItems(pageAcumulator, requestBody), initialAcumulatorPage))
|
|
203
|
-
.toPromise();
|
|
204
|
-
return serverResponse.data;
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
httpOperation(eventSourcingItem) {
|
|
208
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
209
|
-
try {
|
|
210
|
-
const requestData = yield this.createPoHttpRequestData(eventSourcingItem.record.url, eventSourcingItem.record.method, eventSourcingItem.record, eventSourcingItem.record.headers);
|
|
211
|
-
const response = yield this.poHttpClient.createRequest(requestData).toPromise();
|
|
212
|
-
const poHttpCommandResponse = {
|
|
213
|
-
id: eventSourcingItem.id,
|
|
214
|
-
customRequestId: eventSourcingItem.customRequestId,
|
|
215
|
-
request: eventSourcingItem.record,
|
|
216
|
-
response: response
|
|
217
|
-
};
|
|
218
|
-
this.responseSubject.next(poHttpCommandResponse);
|
|
219
|
-
return this.removeEventSourcingValidItem(response.status, eventSourcingItem);
|
|
220
|
-
}
|
|
221
|
-
catch (errorHttpClient) {
|
|
222
|
-
return this.sendResponseSubject(eventSourcingItem, errorHttpClient, true);
|
|
223
|
-
}
|
|
224
|
-
});
|
|
225
|
-
}
|
|
226
|
-
insertEventSourcingQueue(eventSourcingItem) {
|
|
227
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
228
|
-
const eventSourcingUpdatedQueue = yield this.poStorage.appendItemToArray(PoEventSourcingService.event_sourcing_name, eventSourcingItem);
|
|
229
|
-
this.notifyEventCreation();
|
|
230
|
-
return Promise.resolve(eventSourcingUpdatedQueue);
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
insertOperation(currentEventSourcingItem) {
|
|
234
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
235
|
-
const schema = yield this.poSchemaDefinition.get(currentEventSourcingItem.schema);
|
|
236
|
-
const url = PoEventSourcingService.getUrl(currentEventSourcingItem, schema, PoRequestType.POST);
|
|
237
|
-
try {
|
|
238
|
-
const response = yield this.sendServerItem(url, PoHttpRequestType.POST, currentEventSourcingItem.record);
|
|
239
|
-
const recordUpdatedByServer = response.body;
|
|
240
|
-
yield this.removeEventSourcingValidItem(response.status, currentEventSourcingItem);
|
|
241
|
-
const id = currentEventSourcingItem.record[PoSchemaUtil.syncInternalIdFieldName];
|
|
242
|
-
yield this.poSchemaService.update(schema, recordUpdatedByServer, id);
|
|
243
|
-
const eventSourcingItems = yield this.poStorage.get(PoEventSourcingService.event_sourcing_name);
|
|
244
|
-
yield this.updatePendingEventSourcing(currentEventSourcingItem, schema.idField, recordUpdatedByServer, eventSourcingItems);
|
|
245
|
-
return this.sendResponseSubject(currentEventSourcingItem, response);
|
|
246
|
-
}
|
|
247
|
-
catch (errorHttpClient) {
|
|
248
|
-
return this.sendResponseSubject(currentEventSourcingItem, errorHttpClient, true);
|
|
249
|
-
}
|
|
250
|
-
});
|
|
251
|
-
}
|
|
252
|
-
isValidStatus(status) {
|
|
253
|
-
return PoEventSourcingService.VALID_HTTP_STATUS_CODES.includes(status);
|
|
254
|
-
}
|
|
255
|
-
notifyEventCreation() {
|
|
256
|
-
if (this.emitter) {
|
|
257
|
-
this.emitter.next();
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
paginateSchemaData(data, schema, baseUrl) {
|
|
261
|
-
this.config.dataTransform.transform(data);
|
|
262
|
-
if (this.config.dataTransform.hasNext()) {
|
|
263
|
-
this.schemasSyncConfig[schema.name]['currentUrlDiff'] = this.buildUrlParams(schema, baseUrl, ++this.schemasSyncConfig[schema.name]['page']);
|
|
264
|
-
return this.diffServerItems(this.schemasSyncConfig[schema.name]['currentUrlDiff']).pipe(map(response => this.getBodyAndDate(schema.name, response)));
|
|
265
|
-
}
|
|
266
|
-
return of();
|
|
267
|
-
}
|
|
268
|
-
removeEventSourcingValidItem(status, eventSourcingItem) {
|
|
269
|
-
if (this.isValidStatus(status) || eventSourcingItem.operation === PoEventSourcingOperation.Http) {
|
|
270
|
-
return this.removeEventSourcingItem(eventSourcingItem.id);
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
selectOperation(eventSourcingItem) {
|
|
274
|
-
switch (eventSourcingItem.operation) {
|
|
275
|
-
case PoEventSourcingOperation.Insert:
|
|
276
|
-
return this.insertOperation(eventSourcingItem);
|
|
277
|
-
case PoEventSourcingOperation.Update:
|
|
278
|
-
return this.updateOperation(eventSourcingItem);
|
|
279
|
-
case PoEventSourcingOperation.Delete:
|
|
280
|
-
return this.deleteOperation(eventSourcingItem);
|
|
281
|
-
case PoEventSourcingOperation.Http:
|
|
282
|
-
return this.httpOperation(eventSourcingItem);
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
sendResponseSubject(eventSourcingItem, response, isSubjectError = false) {
|
|
286
|
-
const poSyncResponse = {
|
|
287
|
-
id: eventSourcingItem.id,
|
|
288
|
-
customRequestId: eventSourcingItem.customRequestId,
|
|
289
|
-
request: eventSourcingItem.record,
|
|
290
|
-
response: response
|
|
291
|
-
};
|
|
292
|
-
this.stoppedQueueEventSourcing = isSubjectError;
|
|
293
|
-
this.responseSubject.next(poSyncResponse);
|
|
294
|
-
return Promise.resolve();
|
|
295
|
-
}
|
|
296
|
-
sendServerItem(url, method, body) {
|
|
297
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
298
|
-
const requestData = yield this.createPoHttpRequestData(url, method, body);
|
|
299
|
-
return this.poHttpClient.createRequest(requestData).toPromise();
|
|
300
|
-
});
|
|
301
|
-
}
|
|
302
|
-
createPoHttpRequestData(url, method, record, headers) {
|
|
303
|
-
var _a;
|
|
304
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
305
|
-
let body = (_a = record.body) !== null && _a !== void 0 ? _a : record;
|
|
306
|
-
if (record.bodyType === 'File') {
|
|
307
|
-
body = yield this.createFormData(body, record.fileName, record.mimeType, record.formField);
|
|
308
|
-
}
|
|
309
|
-
return { url, method, body, headers };
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
createFormData(body, fileName, mimeType, formField = 'file') {
|
|
313
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
314
|
-
const file = yield toFile(body, fileName, mimeType);
|
|
315
|
-
const formData = new FormData();
|
|
316
|
-
formData.append(formField, file, fileName);
|
|
317
|
-
return formData;
|
|
318
|
-
});
|
|
319
|
-
}
|
|
320
|
-
updateOperation(eventSourcingItem) {
|
|
321
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
322
|
-
const schema = yield this.poSchemaDefinition.get(eventSourcingItem.schema);
|
|
323
|
-
const url = PoEventSourcingService.getUrl(eventSourcingItem, schema, PoRequestType.PATCH);
|
|
324
|
-
try {
|
|
325
|
-
const recordId = eventSourcingItem.record[schema.idField];
|
|
326
|
-
this.checkRecordIdExists(recordId, PoEventSourcingOperation.Update);
|
|
327
|
-
const response = yield this.sendServerItem(url, PoHttpRequestType.PUT, eventSourcingItem.record);
|
|
328
|
-
yield this.removeEventSourcingValidItem(response.status, eventSourcingItem);
|
|
329
|
-
return yield this.sendResponseSubject(eventSourcingItem, response);
|
|
330
|
-
}
|
|
331
|
-
catch (errorHttpClient) {
|
|
332
|
-
return this.sendResponseSubject(eventSourcingItem, errorHttpClient, true);
|
|
333
|
-
}
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
updatePendingEventSourcing(currentEventSourcingItem, idFieldSchema, inserted, eventSourcingItems) {
|
|
337
|
-
if (currentEventSourcingItem.record[PoSchemaUtil.syncInternalIdFieldName]) {
|
|
338
|
-
eventSourcingItems.forEach((eventSourcingItem, position) => {
|
|
339
|
-
const isCurrentEventSourcingItem = !eventSourcingItem.record[idFieldSchema] &&
|
|
340
|
-
eventSourcingItem.record[PoSchemaUtil.syncInternalIdFieldName] ===
|
|
341
|
-
currentEventSourcingItem.record[PoSchemaUtil.syncInternalIdFieldName];
|
|
342
|
-
if (isCurrentEventSourcingItem) {
|
|
343
|
-
eventSourcingItems[position].record[idFieldSchema] = inserted[idFieldSchema];
|
|
344
|
-
}
|
|
345
|
-
});
|
|
346
|
-
return this.poStorage.set(PoEventSourcingService.event_sourcing_name, eventSourcingItems);
|
|
347
|
-
}
|
|
348
|
-
else {
|
|
349
|
-
return Promise.resolve();
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
updateRecords(serverRecords, schema) {
|
|
353
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
354
|
-
for (const serverRecord of serverRecords) {
|
|
355
|
-
yield this.updateRecordByServerRecord(serverRecord, schema);
|
|
356
|
-
}
|
|
357
|
-
});
|
|
358
|
-
}
|
|
359
|
-
updateRecordByServerRecord(serverRecord, schema) {
|
|
360
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
361
|
-
const recordId = serverRecord[schema.idField];
|
|
362
|
-
const storageRecord = yield this.poSchemaService.get(schema.name, recordId);
|
|
363
|
-
const existsStorageRecord = !!Object.keys(storageRecord).length;
|
|
364
|
-
if (existsStorageRecord && serverRecord[schema.deletedField]) {
|
|
365
|
-
return yield this.poSchemaService.remove(schema.name, serverRecord[schema.idField]);
|
|
366
|
-
}
|
|
367
|
-
if (existsStorageRecord && !serverRecord[schema.deletedField]) {
|
|
368
|
-
return yield this.poSchemaService.update(schema, serverRecord);
|
|
369
|
-
}
|
|
370
|
-
if (!existsStorageRecord && !serverRecord[schema.deletedField]) {
|
|
371
|
-
return yield this.poSchemaService.create(schema, serverRecord);
|
|
372
|
-
}
|
|
373
|
-
});
|
|
374
|
-
}
|
|
375
|
-
updateStorageBySchema(schema) {
|
|
376
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
377
|
-
this.createSchemaSyncConfig(schema.name);
|
|
378
|
-
this.schemasSyncConfig[schema.name]['page'] = 1;
|
|
379
|
-
const baseUrl = `${PoSchemaUtil.getUrl(schema, PoRequestType.DIFF)}/${schema.lastSync}`;
|
|
380
|
-
this.schemasSyncConfig[schema.name]['currentUrlDiff'] = this.buildUrlParams(schema, baseUrl, this.schemasSyncConfig[schema.name]['page']);
|
|
381
|
-
const serverRecords = yield this.getServerDiffRecords(schema, baseUrl);
|
|
382
|
-
yield this.updateRecords(serverRecords, schema);
|
|
383
|
-
schema.lastSync = this.schemasSyncConfig[schema.name]['responseDate'];
|
|
384
|
-
yield this.poSchemaDefinition.update(schema);
|
|
385
|
-
});
|
|
386
|
-
}
|
|
387
|
-
updateStorageSchemas(schemas) {
|
|
388
|
-
return schemas.map((schema) => this.updateStorageBySchema(schema));
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
PoEventSourcingService.event_sourcing_name = 'EventSourcing';
|
|
392
|
-
PoEventSourcingService.VALID_HTTP_STATUS_CODES = [
|
|
393
|
-
HttpStatus.OK,
|
|
394
|
-
HttpStatus.CREATED,
|
|
395
|
-
HttpStatus.ACCEPTED,
|
|
396
|
-
HttpStatus.NON_AUTHORITATIVE_INFORMATION,
|
|
397
|
-
HttpStatus.NO_CONTENT,
|
|
398
|
-
HttpStatus.RESET_CONTENT,
|
|
399
|
-
HttpStatus.PARTIAL_CONTENT,
|
|
400
|
-
HttpStatus.MULTI_STATUS // 207
|
|
401
|
-
];
|
|
402
|
-
PoEventSourcingService.decorators = [
|
|
403
|
-
{ type: Injectable }
|
|
404
|
-
];
|
|
405
|
-
PoEventSourcingService.ctorParameters = () => [
|
|
406
|
-
{ type: PoSchemaDefinitionService },
|
|
407
|
-
{ type: PoSchemaService },
|
|
408
|
-
{ type: PoStorageService },
|
|
409
|
-
{ type: PoHttpClientService }
|
|
410
|
-
];
|
|
411
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG8tZXZlbnQtc291cmNpbmcuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3N5bmMvc3JjL2xpYi9zZXJ2aWNlcy9wby1ldmVudC1zb3VyY2luZy9wby1ldmVudC1zb3VyY2luZy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFDQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTNDLE9BQU8sS0FBSyxVQUFVLE1BQU0sbUJBQW1CLENBQUM7QUFDaEQsT0FBTyxFQUFFLFVBQVUsRUFBRSxFQUFFLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9DLE9BQU8sRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXJELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRXJELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFckQsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0scURBQXFELENBQUM7QUFFbkcsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sMENBQTBDLENBQUM7QUFHcEYsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFFakYsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNkNBQTZDLENBQUM7QUFDaEYsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQ2xFLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLGtFQUFrRSxDQUFDO0FBQzdHLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUNuRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0RBQW9ELENBQUM7QUFNbEYsTUFBTSxPQUFPLHNCQUFzQjtJQXVCakMsWUFDVSxrQkFBNkMsRUFD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QUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQy9DLENBQUM7S0FBQTtJQUVPLG9CQUFvQixDQUFDLE9BQU87UUFDbEMsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBb0IsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFDbkYsQ0FBQzs7QUE5aEJlLDBDQUFtQixHQUFXLGVBQWUsQ0FBQztBQUV0Qyw4Q0FBdUIsR0FBRztJQUNoRCxVQUFVLENBQUMsRUFBRTtJQUNiLFVBQVUsQ0FBQyxPQUFPO0lBQ2xCLFVBQVUsQ0FBQyxRQUFRO0lBQ25CLFVBQVUsQ0FBQyw2QkFBNkI7SUFDeEMsVUFBVSxDQUFDLFVBQVU7SUFDckIsVUFBVSxDQUFDLGFBQWE7SUFDeEIsVUFBVSxDQUFDLGVBQWU7SUFDMUIsVUFBVSxDQUFDLFlBQVksQ0FBQyxNQUFNO0NBQy9CLENBQUM7O1lBYkgsVUFBVTs7O1lBUEYseUJBQXlCO1lBQ3pCLGVBQWU7WUFkZixnQkFBZ0I7WUFTaEIsbUJBQW1CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSHR0cFJlc3BvbnNlLCBIdHRwRXJyb3JSZXNwb25zZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcclxuaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5cclxuaW1wb3J0ICogYXMgSHR0cFN0YXR1cyBmcm9tICdodHRwLXN0YXR1cy1jb2Rlcyc7XHJcbmltcG9ydCB7IE9ic2VydmFibGUsIG9mLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IGV4cGFuZCwgbWFwLCByZWR1Y2UgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcblxyXG5pbXBvcnQgeyBQb1N0b3JhZ2VTZXJ2aWNlIH0gZnJvbSAnQHBvLXVpL25nLXN0b3JhZ2UnO1xyXG5cclxuaW1wb3J0IHsgdG9CYXNlNjQsIHRvRmlsZSB9IGZyb20gJy4uLy4uL3V0aWxzL3V0aWxzJztcclxuXHJcbmltcG9ydCB7IFBvRXZlbnRTb3VyY2luZ0Vycm9yUmVzcG9uc2UgfSBmcm9tICcuLi8uLi9tb2RlbHMvcG8tZXZlbnQtc291cmNpbmctZXJyb3ItcmVzcG9uc2UubW9kZWwnO1xyXG5pbXBvcnQgeyBQb0V2ZW50U291cmNpbmdJdGVtIH0gZnJvbSAnLi9pbnRlcmZhY2VzL3BvLWV2ZW50LXNvdXJjaW5nLWl0ZW0uaW50ZXJmYWNlJztcclxuaW1wb3J0IHsgUG9FdmVudFNvdXJjaW5nT3BlcmF0aW9uIH0gZnJvbSAnLi9lbnVtcy9wby1ldmVudC1zb3VyY2luZy1vcGVyYXRpb24uZW51bSc7XHJcbmltcG9ydCB7IFBvRXZlbnRTb3VyY2luZ1N1bW1hcnlJdGVtIH0gZnJvbSAnLi9pbnRlcmZhY2VzL3BvLWV2ZW50LXNvdXJjaW5nLXN1bW1hcnktaXRlbS5pbnRlcmZhY2UnO1xyXG5pbXBvcnQgeyBQb0h0dHBIZWFkZXJPcHRpb24gfSBmcm9tICcuLy4uL3BvLWh0dHAtY2xpZW50L2ludGVyZmFjZXMvcG8taHR0cC1oZWFkZXItb3B0aW9uLmludGVyZmFjZSc7XHJcbmltcG9ydCB7IFBvSHR0cENsaWVudFNlcnZpY2UgfSBmcm9tICcuLy4uL3BvLWh0dHAtY2xpZW50L3BvLWh0dHAtY2xpZW50LnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBQb0h0dHBSZXF1ZXN0RGF0YSB9IGZyb20gJy4uL3BvLWh0dHAtY2xpZW50L2ludGVyZmFjZXMvcG8taHR0cC1yZXF1ZXN0LWRhdGEuaW50ZXJmYWNlJztcclxuaW1wb3J0IHsgUG9IdHRwUmVxdWVzdFR5cGUgfSBmcm9tICcuLi9wby1odHRwLWNsaWVudC9wby1odHRwLXJlcXVlc3QtdHlwZS5lbnVtJztcclxuaW1wb3J0IHsgUG9SZXF1ZXN0VHlwZSB9IGZyb20gJy4uLy4uL21vZGVscy9wby1yZXF1ZXN0LXR5cGUuZW51bSc7XHJcbmltcG9ydCB7IFBvU2NoZW1hRGVmaW5pdGlvblNlcnZpY2UgfSBmcm9tICcuLy4uL3BvLXNjaGVtYS9wby1zY2hlbWEtZGVmaW5pdGlvbi9wby1zY2hlbWEtZGVmaW5pdGlvbi5zZXJ2aWNlJztcclxuaW1wb3J0IHsgUG9TY2hlbWFTZXJ2aWNlIH0gZnJvbSAnLi8uLi9wby1zY2hlbWEvcG8tc2NoZW1hLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBQb1NjaGVtYVV0aWwgfSBmcm9tICcuLy4uL3BvLXNjaGVtYS9wby1zY2hlbWEtdXRpbC9wby1zY2hlbWEtdXRpbC5tb2RlbCc7XHJcbmltcG9ydCB7IFBvU3luY0NvbmZpZyB9IGZyb20gJy4uL3BvLXN5bmMvaW50ZXJmYWNlcy9wby1zeW5jLWNvbmZpZy5pbnRlcmZhY2UnO1xyXG5pbXBvcnQgeyBQb1N5bmNSZXNwb25zZSB9IGZyb20gJy4uL3BvLXN5bmMvaW50ZXJmYWNlcy9wby1zeW5jLXJlc3BvbnNlLmludGVyZmFjZSc7XHJcbmltcG9ydCB7IFBvU3luY1NjaGVtYSB9IGZyb20gJy4vLi4vcG8tc3luYy9pbnRlcmZhY2VzL3BvLXN5bmMtc2NoZW1hLmludGVyZmFjZSc7XHJcblxyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBQb0V2ZW50U291cmNpbmdTZXJ2aWNlIHtcclxuICBzdGF0aWMgcmVhZG9ubHkgZXZlbnRfc291cmNpbmdfbmFtZTogc3RyaW5nID0gJ0V2ZW50U291cmNpbmcnO1xyXG5cclxuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBWQUxJRF9IVFRQX1NUQVRVU19DT0RFUyA9IFtcclxuICAgIEh0dHBTdGF0dXMuT0ssIC8vIDIwMFxyXG4gICAgSHR0cFN0YXR1cy5DUkVBVEVELCAvLyAyMDFcclxuICAgIEh0dHBTdGF0dXMuQUNDRVBURUQsIC8vIDIwMlxyXG4gICAgSHR0cFN0YXR1cy5OT05fQVVUSE9SSVRBVElWRV9JTkZPUk1BVElPTiwgLy8gMjAzXHJcbiAgICBIdHRwU3RhdHVzLk5PX0NPTlRFTlQsIC8vIDIwNFxyXG4gICAgSHR0cFN0YXR1cy5SRVNFVF9DT05URU5ULCAvLyAyMDVcclxuICAgIEh0dHBTdGF0dXMuUEFSVElBTF9DT05URU5ULCAvLyAyMDZcclxuICAgIEh0dHBTdGF0dXMuTVVMVElfU1RBVFVTIC8vIDIwN1xyXG4gIF07XHJcblxyXG4gIGNvbmZpZzogUG9TeW5jQ29uZmlnO1xyXG4gIHN0b3BwZWRRdWV1ZUV2ZW50U291cmNpbmc6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgcHJpdmF0ZSBlbWl0dGVyOiBhbnk7XHJcbiAgcHJpdmF0ZSBldmVudFN1YjogT2JzZXJ2YWJsZTxudWxsPjtcclxuICBwcml2YXRlIHJlc3BvbnNlU3ViamVjdCA9IG5ldyBTdWJqZWN0PFBvU3luY1Jlc3BvbnNlPigpO1xyXG5cclxuICBwcml2YXRlIHNjaGVtYXNTeW5jQ29uZmlnID0ge307XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJpdmF0ZSBwb1NjaGVtYURlZmluaXRpb246IFBvU2NoZW1hRGVmaW5pdGlvblNlcnZpY2UsXHJcbiAgICBwcml2YXRlIHBvU2NoZW1hU2VydmljZTogUG9TY2hlbWFTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBwb1N0b3JhZ2U6IFBvU3RvcmFnZVNlcnZpY2UsXHJcbiAgICBwcml2YXRlIHBvSHR0cENsaWVudDogUG9IdHRwQ2xpZW50U2VydmljZVxyXG4gICkge31cclxuXHJcbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0VXJsKGV2ZW50U291cmNpbmdJdGVtLCBzY2hlbWEsIHJlcXVlc3RUeXBlKTogc3RyaW5nIHtcclxuICAgIGNvbnN0IHNjaGVtYVVybCA9IFBvU2NoZW1hVXRpbC5nZXRVcmwoc2NoZW1hLCByZXF1ZXN0VHlwZSk7XHJcbiAgICBjb25zdCBzY2hlbWFJZCA9IGV2ZW50U291cmNpbmdJdGVtLnJlY29yZFtzY2hlbWEuaWRGaWVsZF07XHJcblxyXG4gICAgaWYgKHJlcXVlc3RUeXBlID09PSBQb1JlcXVlc3RUeXBlLkdFVCkge1xyXG4gICAgICByZXR1cm4gc2NoZW1hVXJsO1xyXG4gICAgfVxyXG5cclxuICAgIGlmIChbUG9SZXF1ZXN0VHlwZS5ERUxFVEUsIFBvUmVxdWVzdFR5cGUuUEFUQ0hdLmluY2x1ZGVzKHJlcXVlc3RUeXBlKSkge1xyXG4gICAgICByZXR1cm4gc2NoZW1hVXJsID8gYCR7c2NoZW1hVXJsfS8ke3NjaGVtYUlkfWAgOiBgJHtQb1NjaGVtYVV0aWwuZ2V0VXJsKHNjaGVtYSwgUG9SZXF1ZXN0VHlwZS5HRVQpfS8ke3NjaGVtYUlkfWA7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHJlcXVlc3RUeXBlID09PSBQb1JlcXVlc3RUeXBlLlBPU1QpIHtcclxuICAgICAgcmV0dXJuIHNjaGVtYVVybCA/IHNjaGVtYVVybCA6IFBvU2NoZW1hVXRpbC5nZXRVcmwoc2NoZW1hLCBQb1JlcXVlc3RUeXBlLkdFVCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBjcmVhdGUoc2NoZW1hTmFtZTogc3RyaW5nLCBuZXdJdGVtOiBhbnksIGN1c3RvbVJlcXVlc3RJZD86IHN0cmluZyk6IFByb21pc2U8YW55PiB7XHJcbiAgICBjb25zdCBldmVudFNvdXJjaW5nSXRlbSA9IHRoaXMuY3JlYXRlRXZlbnRTb3VyY2luZ0l0ZW0oXHJcbiAgICAgIFBvRXZlbnRTb3VyY2luZ09wZXJhdGlvbi5JbnNlcnQsXHJcbiAgICAgIG5ld0l0ZW0sXHJcbiAgICAgIHNjaGVtYU5hbWUsXHJcbiAgICAgIGN1c3RvbVJlcXVlc3RJZFxyXG4gICAgKTtcclxuICAgIHJldHVybiB0aGlzLmluc2VydEV2ZW50U291cmNpbmdRdWV1ZShldmVudFNvdXJjaW5nSXRlbSk7XHJcbiAgfVxyXG5cclxuICBhc3luYyBjcmVhdGVCYXRjaEV2ZW50cyhzY2hlbWFOYW1lOiBzdHJpbmcsIGV2ZW50TGlzdDogQXJyYXk8UG9FdmVudFNvdXJjaW5nU3VtbWFyeUl0ZW0+KSB7XHJcbiAgICBjb25zdCBldmVudFNvdXJjaW5nTGlzdCA9IHRoaXMuY3JlYXRlRXZlbnRTb3VyY2luZ0xpc3Qoc2NoZW1hTmFtZSwgZXZlbnRMaXN0KTtcclxuXHJcbiAgICBhd2FpdCB0aGlzLnBvU3RvcmFnZS5hcHBlbmRBcnJheVRvQXJyYXkoUG9FdmVudFNvdXJjaW5nU2VydmljZS5ldmVudF9zb3VyY2luZ19uYW1lLCBldmVudFNvdXJjaW5nTGlzdCk7XHJcblxyXG4gICAgdGhpcy5ub3RpZnlFdmVudENyZWF0aW9uKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBEZXN0csOzaSBhIGNoYXZlIGRvICpzdG9yYWdlKiBxdWUgY29udMOpbSBhIGZpbGEgZGUgZGFkb3MgcXVlIGVzdMOjbyBlc3BlcmFuZG8gcGFyYSBzZXJlbSBlbnZpYWRvcyBhb1xyXG4gICAqIHNlcnZpZG9yICooRXZlbnRTb3VyY2luZykqLlxyXG4gICAqXHJcbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IFByb21lc3NhIHF1ZSDDqSByZXNvbHZpZGEgcXVhbmRvIGEgY2hhdmUgcmVmZXJlbnRlIGEgZmlsYSBkZSAqRXZlbnRTb3VyY2luZyogZm9yIGRlc3RydcOtZGEuXHJcbiAgICovXHJcbiAgZGVzdHJveUV2ZW50U291cmNpbmdRdWV1ZSgpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIHJldHVybiB0aGlzLnBvU3RvcmFnZS5yZW1vdmUoUG9FdmVudFNvdXJjaW5nU2VydmljZS5ldmVudF9zb3VyY2luZ19uYW1lKTtcclxuICB9XHJcblxyXG4gIGFzeW5jIGh0dHBDb21tYW5kKGh0dHBPcGVyYXRpb25EYXRhOiBQb0h0dHBSZXF1ZXN0RGF0YSwgY3VzdG9tUmVxdWVzdElkPzogc3RyaW5nKTogUHJvbWlzZTxudW1iZXI+IHtcclxuICAgIGh0dHBPcGVyYXRpb25EYXRhID0gYXdhaXQgdGhpcy5zZXJpYWxpemVCb2R5KGh0dHBPcGVyYXRpb25EYXRhKTtcclxuXHJcbiAgICBjb25zdCBldmVudFNvdXJjaW5nSXRlbSA9IHRoaXMuY3JlYXRlRXZlbnRTb3VyY2luZ0l0ZW0oXHJcbiAgICAgIFBvRXZlbnRTb3VyY2luZ09wZXJhdGlvbi5IdHRwLFxyXG4gICAgICBodHRwT3BlcmF0aW9uRGF0YSxcclxuICAgICAgdW5kZWZpbmVkLFxyXG4gICAgICBjdXN0b21SZXF1ZXN0SWRcclxuICAgICk7XHJcblxyXG4gICAgYXdhaXQgdGhpcy5pbnNlcnRFdmVudFNvdXJjaW5nUXVldWUoZXZlbnRTb3VyY2luZ0l0ZW0pO1xyXG4gICAgcmV0dXJuIGV2ZW50U291cmNpbmdJdGVtLmlkO1xyXG4gIH1cclxuXHJcbiAgcmVzcG9uc2VzU3ViamVjdCgpOiBPYnNlcnZhYmxlPFBvU3luY1Jlc3BvbnNlPiB7XHJcbiAgICByZXR1cm4gdGhpcy5yZXNwb25zZVN1YmplY3QuYXNPYnNlcnZhYmxlKCk7XHJcbiAgfVxyXG5cclxuICBvblNhdmVEYXRhKCk6IE9ic2VydmFibGU8bnVsbD4ge1xyXG4gICAgaWYgKCF0aGlzLmV2ZW50U3ViKSB7XHJcbiAgICAgIHRoaXMuZXZlbnRTdWIgPSBPYnNlcnZhYmxlLmNyZWF0ZShzdWJzY3JpYmVyID0+ICh0aGlzLmVtaXR0ZXIgPSBzdWJzY3JpYmVyKSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy5ldmVudFN1YjtcclxuICB9XHJcblxyXG4gIHJlbW92ZShzY2hlbWFOYW1lOiBzdHJpbmcsIGl0ZW1Ub0RlbGV0ZTogYW55LCBjdXN0b21SZXF1ZXN0SWQ/OiBzdHJpbmcpOiBQcm9taXNlPGFueT4ge1xyXG4gICAgY29uc3QgZXZlbnRTb3VyY2luZ0l0ZW0gPSB0aGlzLmNyZWF0ZUV2ZW50U291cmNpbmdJdGVtKFxyXG4gICAgICBQb0V2ZW50U291cmNpbmdPcGVyYXRpb24uRGVsZXRlLFxyXG4gICAgICBpdGVtVG9EZWxldGUsXHJcbiAgICAgIHNjaGVtYU5hbWUsXHJcbiAgICAgIGN1c3RvbVJlcXVlc3RJZFxyXG4gICAgKTtcclxuICAgIHJldHVybiB0aGlzLmluc2VydEV2ZW50U291cmNpbmdRdWV1ZShldmVudFNvdXJjaW5nSXRlbSk7XHJcbiAgfVxyXG5cclxuICByZW1vdmVFdmVudFNvdXJjaW5nSXRlbShpZEV2ZW50U291cmNpbmdJdGVtKSB7XHJcbiAgICByZXR1cm4gdGhpcy5wb1N0b3JhZ2UucmVtb3ZlSXRlbUZyb21BcnJheShQb0V2ZW50U291cmNpbmdTZXJ2aWNlLmV2ZW50X3NvdXJjaW5nX25hbWUsICdpZCcsIGlkRXZlbnRTb3VyY2luZ0l0ZW0pO1xyXG4gIH1cclxuXHJcbiAgc3luY0dldCgpOiBQcm9taXNlPGFueT4ge1xyXG4gICAgY29uc3Qgc3luY0dldEZ1bmN0aW9uID0gYXN5bmMgKCkgPT5cclxuICAgICAgdGhpcy5wb1NjaGVtYURlZmluaXRpb24uZ2V0QWxsKCkudGhlbihzY2hlbWFzID0+IHtcclxuICAgICAgICBjb25zdCBzY2hlbWFQcm9taXNlcyA9IHRoaXMudXBkYXRlU3RvcmFnZVNjaGVtYXMoc2NoZW1hcyk7XHJcblxyXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChzY2hlbWFQcm9taXNlcyk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgIHJldHVybiB0aGlzLnBvU2NoZW1hU2VydmljZS5saW1pdGVkQ2FsbFdyYXAoc3luY0dldEZ1bmN0aW9uKTtcclxuICB9XHJcblxyXG4gIGFzeW5jIHN5bmNTZW5kKCk6IFByb21pc2U8YW55PiB7XHJcbiAgICBjb25zdCBzeW5jU2VuZEZ1bmN0aW9uID0gYXN5bmMgKCk6IFByb21pc2U8YW55PiA9PiB7XHJcbiAgICAgIGNvbnN0IGl0ZW1PZlF1ZXVlID0gYXdhaXQgdGhpcy5wb1N0b3JhZ2UuZ2V0Rmlyc3RJdGVtKFBvRXZlbnRTb3VyY2luZ1NlcnZpY2UuZXZlbnRfc291cmNpbmdfbmFtZSk7XHJcblxyXG4gICAgICBpZiAoaXRlbU9mUXVldWUpIHtcclxuICAgICAgICBhd2FpdCB0aGlzLnNlbGVjdE9wZXJhdGlvbihpdGVtT2ZRdWV1ZSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmICh0aGlzLnN0b3BwZWRRdWV1ZUV2ZW50U291cmNpbmcgfHwgIWl0ZW1PZlF1ZXVlKSB7XHJcbiAgICAgICAgdGhpcy5zdG9wcGVkUXVldWVFdmVudFNvdXJjaW5nID0gZmFsc2U7XHJcbiAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gc3luY1NlbmRGdW5jdGlvbigpO1xyXG4gICAgfTtcclxuXHJcbiAgICByZXR1cm4gdGhpcy5wb1NjaGVtYVNlcnZpY2UubGltaXRlZENhbGxXcmFwKHN5bmNTZW5kRnVuY3Rpb24pO1xyXG4gIH1cclxuXHJcbiAgdXBkYXRlKHNjaGVtYU5hbWU6IHN0cmluZywgaXRlbVVwZGF0ZWQ6IGFueSwgY3VzdG9tUmVxdWVzdElkPzogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHtcclxuICAgIGNvbnN0IGV2ZW50U291cmNpbmdJdGVtID0gdGhpcy5jcmVhdGVFdmVudFNvdXJjaW5nSXRlbShcclxuICAgICAgUG9FdmVudFNvdXJjaW5nT3BlcmF0aW9uLlVwZGF0ZSxcclxuICAgICAgaXRlbVVwZGF0ZWQsXHJcbiAgICAgIHNjaGVtYU5hbWUsXHJcbiAgICAgIGN1c3RvbVJlcXVlc3RJZFxyXG4gICAgKTtcclxuICAgIHJldHVybiB0aGlzLmluc2VydEV2ZW50U291cmNpbmdRdWV1ZShldmVudFNvdXJjaW5nSXRlbSk7XHJcbiAgfVxyXG5cclxuICAvKiBBdmFsaWEgc2UgbyBib2R5IMOpIGRvIHRpcG8gRmlsZSBlIHNlIGZvciBjb252ZXJ0ZSBwYXJhIGJhc2U2NCAqL1xyXG4gIHByaXZhdGUgYXN5bmMgc2VyaWFsaXplQm9keShyZXF1ZXN0RGF0YTogUG9IdHRwUmVxdWVzdERhdGEpOiBQcm9taXNlPFBvSHR0cFJlcXVlc3REYXRhPiB7XHJcbiAgICBsZXQgeyBib2R5LCBtaW1lVHlwZSwgYm9keVR5cGUsIGZpbGVOYW1lIH0gPSByZXF1ZXN0RGF0YTtcclxuXHJcbiAgICBpZiAoYm9keSBpbnN0YW5jZW9mIEZpbGUpIHtcclxuICAgICAgYm9keVR5cGUgPSAnRmlsZSc7XHJcbiAgICAgIG1pbWVUeXBlID0gYm9keS50eXBlO1xyXG4gICAgICBmaWxlTmFtZSA9IGJvZHkubmFtZTtcclxuICAgICAgYm9keSA9IGF3YWl0IHRvQmFzZTY0KGJvZHkpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB7IC4uLnJlcXVlc3REYXRhLCBib2R5LCBtaW1lVHlwZSwgYm9keVR5cGUsIGZpbGVOYW1lIH07XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGJ1aWxkVXJsUGFyYW1zKHNjaGVtYTogUG9TeW5jU2NoZW1hLCBiYXNlVXJsOiBzdHJpbmcsIHBhZ2VOdW1iZXI6IG51bWJlcik6IHN0cmluZyB7XHJcbiAgICBjb25zdCBwYXJhbXMgPSBbXTtcclxuICAgIHBhcmFtcy5wdXNoKGAke3RoaXMuY29uZmlnLmRhdGFUcmFuc2Zvcm0uZ2V0UGFnZVNpemVQYXJhbU5hbWUoKX09JHtzY2hlbWEucGFnZVNpemV9YCk7XHJcbiAgICBwYXJhbXMucHVzaChgJHt0aGlzLmNvbmZpZy5kYXRhVHJhbnNmb3JtLmdldFBhZ2VQYXJhbU5hbWUoKX09JHtwYWdlTnVtYmVyfWApO1xyXG4gICAgcmV0dXJuIGAke2Jhc2VVcmx9PyR7cGFyYW1zLmpvaW4oJyYnKX1gO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBjaGVja1JlY29yZElkRXhpc3RzKHJlY29yZElkLCBvcGVyYXRpb24pIHtcclxuICAgIGlmICghcmVjb3JkSWQpIHtcclxuICAgICAgY29uc3QgZXJyb3IgPSB7XHJcbiAgICAgICAgbWVzc2FnZTogJ0lkZW50aWZpZXIgbm90IGRlZmluZWQnLFxyXG4gICAgICAgIG9wZXJhdGlvbjogb3BlcmF0aW9uXHJcbiAgICAgIH07XHJcblxyXG4gICAgICB0aHJvdyBuZXcgUG9FdmVudFNvdXJjaW5nRXJyb3JSZXNwb25zZShlcnJvcik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGNvbmNhdFBhZ2VJdGVtcyhwYWdlQWN1bXVsYXRvciwgcmVxdWVzdEJvZHkpOiB7IGVudGl0eTogc3RyaW5nOyBkYXRhOiBBcnJheTxhbnk+IH0ge1xyXG4gICAgaWYgKHJlcXVlc3RCb2R5W3RoaXMuY29uZmlnLmRhdGFUcmFuc2Zvcm0uZ2V0SXRlbXNGaWVsZE5hbWUoKV0pIHtcclxuICAgICAgcGFnZUFjdW11bGF0b3IuZGF0YSA9IFsuLi5wYWdlQWN1bXVsYXRvci5kYXRhLCAuLi5yZXF1ZXN0Qm9keVt0aGlzLmNvbmZpZy5kYXRhVHJhbnNmb3JtLmdldEl0ZW1zRmllbGROYW1lKCldXTtcclxuICAgIH1cclxuICAgIHJldHVybiBwYWdlQWN1bXVsYXRvcjtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgY3JlYXRlRXZlbnRTb3VyY2luZ0l0ZW0oXHJcbiAgICBvcGVyYXRpb246IFBvRXZlbnRTb3VyY2luZ09wZXJhdGlvbixcclxuICAgIG5ld0l0ZW06IGFueSB8IFBvSHR0cFJlcXVlc3REYXRhLFxyXG4gICAgc2NoZW1hTmFtZT86IHN0cmluZyxcclxuICAgIGN1c3RvbVJlcXVlc3RJZD86IHN0cmluZyxcclxuICAgIGlkPzogbnVtYmVyXHJcbiAgKTogUG9FdmVudFNvdXJjaW5nSXRlbSB7XHJcbiAgICBpZiAoIXNjaGVtYU5hbWUgJiYgb3BlcmF0aW9uICE9PSBQb0V2ZW50U291cmNpbmdPcGVyYXRpb24uSHR0cCkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1BvU3luY1NjaGVtYSBpcyBub3QgZGVmaW5lZC4nKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4ge1xyXG4gICAgICBpZDogaWQgPyBpZCA6IG5ldyBEYXRlKCkuZ2V0VGltZSgpLFxyXG4gICAgICBkYXRlVGltZTogbmV3IERhdGUoKS5nZXRUaW1lKCksXHJcbiAgICAgIHNjaGVtYTogc2NoZW1hTmFtZSxcclxuICAgICAgb3BlcmF0aW9uOiBvcGVyYXRpb24sXHJcbiAgICAgIHJlY29yZDogbmV3SXRlbSxcclxuICAgICAgY3VzdG9tUmVxdWVzdElkOiBjdXN0b21SZXF1ZXN0SWRcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGNyZWF0ZUV2ZW50U291cmNpbmdMaXN0KFxyXG4gICAgc2NoZW1hTmFtZTogc3RyaW5nLFxyXG4gICAgZXZlbnRMaXN0OiBBcnJheTxQb0V2ZW50U291cmNpbmdTdW1tYXJ5SXRlbT5cclxuICApOiBBcnJheTxQb0V2ZW50U291cmNpbmdJdGVtPiB7XHJcbiAgICByZXR1cm4gZXZlbnRMaXN0Lm1hcCgoZXZlbnRJdGVtLCBpbmRleCkgPT4ge1xyXG4gICAgICBjb25zdCBpZCA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpICsgaW5kZXg7XHJcblxyXG4gICAgICByZXR1cm4gdGhpcy5jcmVhdGVFdmVudFNvdXJjaW5nSXRlbShcclxuICAgICAgICBldmVudEl0ZW0ub3BlcmF0aW9uLFxyXG4gICAgICAgIGV2ZW50SXRlbS5yZWNvcmQsXHJcbiAgICAgICAgc2NoZW1hTmFtZSxcclxuICAgICAgICBldmVudEl0ZW0uY3VzdG9tUmVxdWVzdElkLFxyXG4gICAgICAgIGlkXHJcbiAgICAgICk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgY3JlYXRlU2NoZW1hU3luY0NvbmZpZyhzY2hlbWFOYW1lKSB7XHJcbiAgICB0aGlzLnNjaGVtYXNTeW5jQ29uZmlnW3NjaGVtYU5hbWVdID0ge1xyXG4gICAgICBwYWdlOiB1bmRlZmluZWQsXHJcbiAgICAgIGN1cnJlbnRVcmxEaWZmOiB1bmRlZmluZWQsXHJcbiAgICAgIHJlc3BvbnNlRGF0ZTogdW5kZWZpbmVkXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhc3luYyBkZWxldGVPcGVyYXRpb24oZXZlbnRTb3VyY2luZ0l0ZW06IFBvRXZlbnRTb3VyY2luZ0l0ZW0pOiBQcm9taXNlPGFueT4ge1xyXG4gICAgdHJ5IHtcclxuICAgICAgY29uc3Qgc2NoZW1hID0gYXdhaXQgdGhpcy5wb1NjaGVtYURlZmluaXRpb24uZ2V0KGV2ZW50U291cmNpbmdJdGVtLnNjaGVtYSk7XHJcblxyXG4gICAgICBjb25zdCByZWNvcmRJZCA9IGV2ZW50U291cmNpbmdJdGVtLnJlY29yZFtzY2hlbWEuaWRGaWVsZF07XHJcbiAgICAgIHRoaXMuY2hlY2tSZWNvcmRJZEV4aXN0cyhyZWNvcmRJZCwgUG9FdmVudFNvdXJjaW5nT3BlcmF0aW9uLkRlbGV0ZSk7XHJcblxyXG4gICAgICBjb25zdCB1cmwgPSBQb0V2ZW50U291cmNpbmdTZXJ2aWNlLmdldFVybChldmVudFNvdXJjaW5nSXRlbSwgc2NoZW1hLCBQb1JlcXVlc3RUeXBlLkRFTEVURSk7XHJcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5zZW5kU2VydmVySXRlbSh1cmwsIFBvSHR0cFJlcXVlc3RUeXBlLkRFTEVURSk7XHJcblxyXG4gICAgICBhd2FpdCB0aGlzLnJlbW92ZUV2ZW50U291cmNpbmdWYWxpZEl0ZW0ocmVzcG9uc2Uuc3RhdHVzLCBldmVudFNvdXJjaW5nSXRlbSk7XHJcblxyXG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kUmVzcG9uc2VTdWJqZWN0KGV2ZW50U291cmNpbmdJdGVtLCByZXNwb25zZSk7XHJcbiAgICB9IGNhdGNoIChlcnJvclJlc3BvbnNlKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLnNlbmRSZXNwb25zZVN1YmplY3QoZXZlbnRTb3VyY2luZ0l0ZW0sIGVycm9yUmVzcG9uc2UsIHRydWUpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBkaWZmU2VydmVySXRlbXMoY3VycmVudFVybERpZmYpOiBPYnNlcnZhYmxlPEh0dHBSZXNwb25zZTxPYmplY3Q+PiB7XHJcbiAgICByZXR1cm4gdGhpcy5wb0h0dHBDbGllbnQuZ2V0KGN1cnJlbnRVcmxEaWZmKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZ2V0Qm9keUFuZERhdGUoc2NoZW1hTmFtZSwgcmVzcG9uc2UpOiBhbnkge1xyXG4gICAgY29uc3QgZ2V0RGF0ZUZpZWxkTmFtZSA9IHRoaXMuY29uZmlnLmRhdGFUcmFuc2Zvcm0uZ2V0RGF0ZUZpZWxkTmFtZSgpO1xyXG5cclxuICAgIGNvbnN0IHJlc3BvbnNlU3luY0RhdGUgPSByZXNwb25zZS5ib2R5W2dldERhdGVGaWVsZE5hbWVdO1xyXG5cclxuICAgIHRoaXMuc2NoZW1hc1N5bmNDb25maWdbc2NoZW1hTmFtZV1bJ3Jlc3BvbnNlRGF0ZSddID0gcmVzcG9uc2VTeW5jRGF0ZTtcclxuICAgIHJldHVybiByZXNwb25zZS5ib2R5O1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhc3luYyBnZXRTZXJ2ZXJEaWZmUmVjb3JkcyhzY2hlbWE6IFBvU3luY1NjaGVtYSwgYmFzZVVybDogc3RyaW5nKTogUHJvbWlzZTxhbnk+IHtcclxuICAgIGNvbnN0IGluaXRpYWxBY3VtdWxhdG9yUGFnZSA9IHsgZW50aXR5OiBzY2hlbWEubmFtZSwgZGF0YTogW10gfTtcclxuICAgIGNvbnN0IGRpZmZVcmwgPSB0aGlzLnNjaGVtYXNTeW5jQ29uZmlnW3NjaGVtYS5uYW1lXVsnY3VycmVudFVybERpZmYnXTtcclxuXHJcbiAgICBjb25zdCBzZXJ2ZXJSZXNwb25zZSA9IGF3YWl0IHRoaXMuZGlmZlNlcnZlckl0ZW1zKGRpZmZVcmwpXHJcbiAgICAgIC5waXBlKFxyXG4gICAgICAgIG1hcChyZXNwb25zZSA9PiB0aGlzLmdldEJvZHlBbmREYXRlKHNjaGVtYS5uYW1lLCByZXNwb25zZSkpLFxyXG4gICAgICAgIGV4cGFuZChkYXRhID0+IHRoaXMucGFnaW5hdGVTY2hlbWFEYXRhKGRhdGEsIHNjaGVtYSwgYmFzZVVybCkpLFxyXG4gICAgICAgIHJlZHVjZShcclxuICAgICAgICAgIChwYWdlQWN1bXVsYXRvciwgcmVxdWVzdEJvZHkpID0+IHRoaXMuY29uY2F0UGFnZUl0ZW1zKHBhZ2VBY3VtdWxhdG9yLCByZXF1ZXN0Qm9keSksXHJcbiAgICAgICAgICBpbml0aWFsQWN1bXVsYXRvclBhZ2VcclxuICAgICAgICApXHJcbiAgICAgIClcclxuICAgICAgLnRvUHJvbWlzZSgpO1xyXG5cclxuICAgIHJldHVybiBzZXJ2ZXJSZXNwb25zZS5kYXRhO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhc3luYyBodHRwT3BlcmF0aW9uKGV2ZW50U291cmNpbmdJdGVtOiBQb0V2ZW50U291cmNpbmdJdGVtKTogUHJvbWlzZTxBcnJheTxQb0V2ZW50U291cmNpbmdJdGVtPiB8IG51bWJlcj4ge1xyXG4gICAgdHJ5IHtcclxuICAgICAgY29uc3QgcmVxdWVzdERhdGE6IFBvSHR0cFJlcXVlc3REYXRhID0gYXdhaXQgdGhpcy5jcmVhdGVQb0h0dHBSZXF1ZXN0RGF0YShcclxuICAgICAgICBldmVudFNvdXJjaW5nSXRlbS5yZWNvcmQudXJsLFxyXG4gICAgICAgIGV2ZW50U291cmNpbmdJdGVtLnJlY29yZC5tZXRob2QsXHJcbiAgICAgICAgZXZlbnRTb3VyY2luZ0l0ZW0ucmVjb3JkLFxyXG4gICAgICAgIGV2ZW50U291cmNpbmdJdGVtLnJlY29yZC5oZWFkZXJzXHJcbiAgICAgICk7XHJcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5wb0h0dHBDbGllbnQuY3JlYXRlUmVxdWVzdChyZXF1ZXN0RGF0YSkudG9Qcm9taXNlKCk7XHJcbiAgICAgIGNvbnN0IHBvSHR0cENvbW1hbmRSZXNwb25zZTogUG9TeW5jUmVzcG9uc2UgPSB7XHJcbiAgICAgICAgaWQ6IGV2ZW50U291cmNpbmdJdGVtLmlkLFxyXG4gICAgICAgIGN1c3RvbVJlcXVlc3RJZDogZXZlbnRTb3VyY2luZ0l0ZW0uY3VzdG9tUmVxdWVzdElkLFxyXG4gICAgICAgIHJlcXVlc3Q6IGV2ZW50U291cmNpbmdJdGVtLnJlY29yZCxcclxuICAgICAgICByZXNwb25zZTogcmVzcG9uc2VcclxuICAgICAgfTtcclxuXHJcbiAgICAgIHRoaXMucmVzcG9uc2VTdWJqZWN0Lm5leHQocG9IdHRwQ29tbWFuZFJlc3BvbnNlKTtcclxuXHJcbiAgICAgIHJldHVybiB0aGlzLnJlbW92ZUV2ZW50U291cmNpbmdWYWxpZEl0ZW0ocmVzcG9uc2Uuc3RhdHVzLCBldmVudFNvdXJjaW5nSXRlbSk7XHJcbiAgICB9IGNhdGNoIChlcnJvckh0dHBDbGllbnQpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuc2VuZFJlc3BvbnNlU3ViamVjdChldmVudFNvdXJjaW5nSXRlbSwgZXJyb3JIdHRwQ2xpZW50LCB0cnVlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgYXN5bmMgaW5zZXJ0RXZlbnRTb3VyY2luZ1F1ZXVlKGV2ZW50U291cmNpbmdJdGVtKTogUHJvbWlzZTxBcnJheTxQb0V2ZW50U291cmNpbmdJdGVtPj4ge1xyXG4gICAgY29uc3QgZXZlbnRTb3VyY2luZ1VwZGF0ZWRRdWV1ZSA9IGF3YWl0IHRoaXMucG9TdG9yYWdlLmFwcGVuZEl0ZW1Ub0FycmF5KFxyXG4gICAgICBQb0V2ZW50U291cmNpbmdTZXJ2aWNlLmV2ZW50X3NvdXJjaW5nX25hbWUsXHJcbiAgICAgIGV2ZW50U291cmNpbmdJdGVtXHJcbiAgICApO1xyXG5cclxuICAgIHRoaXMubm90aWZ5RXZlbnRDcmVhdGlvbigpO1xyXG5cclxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoZXZlbnRTb3VyY2luZ1VwZGF0ZWRRdWV1ZSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFzeW5jIGluc2VydE9wZXJhdGlvbihjdXJyZW50RXZlbnRTb3VyY2luZ0l0ZW06IFBvRXZlbnRTb3VyY2luZ0l0ZW0pOiBQcm9taXNlPGFueT4ge1xyXG4gICAgY29uc3Qgc2NoZW1hID0gYXdhaXQgdGhpcy5wb1NjaGVtYURlZmluaXRpb24uZ2V0KGN1cnJlbnRFdmVudFNvdXJjaW5nSXRlbS5zY2hlbWEpO1xyXG4gICAgY29uc3QgdXJsID0gUG9FdmVudFNvdXJjaW5nU2VydmljZS5nZXRVcmwoY3VycmVudEV2ZW50U291cmNpbmdJdGVtLCBzY2hlbWEsIFBvUmVxdWVzdFR5cGUuUE9TVCk7XHJcblxyXG4gICAgdHJ5IHtcclxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnNlbmRTZXJ2ZXJJdGVtKHVybCwgUG9IdHRwUmVxdWVzdFR5cGUuUE9TVCwgY3VycmVudEV2ZW50U291cmNpbmdJdGVtLnJlY29yZCk7XHJcbiAgICAgIGNvbnN0IHJlY29yZFVwZGF0ZWRCeVNlcnZlciA9IHJlc3BvbnNlLmJvZHk7XHJcblxyXG4gICAgICBhd2FpdCB0aGlzLnJlbW92ZUV2ZW50U291cmNpbmdWYWxpZEl0ZW0ocmVzcG9uc2Uuc3RhdHVzLCBjdXJyZW50RXZlbnRTb3VyY2luZ0l0ZW0pO1xyXG5cclxuICAgICAgY29uc3QgaWQgPSBjdXJyZW50RXZlbnRTb3VyY2luZ0l0ZW0ucmVjb3JkW1BvU2NoZW1hVXRpbC5zeW5jSW50ZXJuYWxJZEZpZWxkTmFtZV07XHJcbiAgICAgIGF3YWl0IHRoaXMucG9TY2hlbWFTZXJ2aWNlLnVwZGF0ZShzY2hlbWEsIHJlY29yZFVwZGF0ZWRCeVNlcnZlciwgaWQpO1xyXG5cclxuICAgICAgY29uc3QgZXZlbnRTb3VyY2luZ0l0ZW1zOiBBcnJheTxQb0V2ZW50U291cmNpbmdJdGVtPiA9IGF3YWl0IHRoaXMucG9TdG9yYWdlLmdldChcclxuICAgICAgICBQb0V2ZW50U291cmNpbmdTZXJ2aWNlLmV2ZW50X3NvdXJjaW5nX25hbWVcclxuICAgICAgKTtcclxuICAgICAgYXdhaXQgdGhpcy51cGRhdGVQZW5kaW5nRXZlbnRTb3VyY2luZyhcclxuICAgICAgICBjdXJyZW50RXZlbnRTb3VyY2luZ0l0ZW0sXHJcbiAgICAgICAgc2NoZW1hLmlkRmllbGQsXHJcbiAgICAgICAgcmVjb3JkVXBkYXRlZEJ5U2VydmVyLFxyXG4gICAgICAgIGV2ZW50U291cmNpbmdJdGVtc1xyXG4gICAgICApO1xyXG5cclxuICAgICAgcmV0dXJuIHRoaXMuc2VuZFJlc3BvbnNlU3ViamVjdChjdXJyZW50RXZlbnRTb3VyY2luZ0l0ZW0sIHJlc3BvbnNlKTtcclxuICAgIH0gY2F0Y2ggKGVycm9ySHR0cENsaWVudCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5zZW5kUmVzcG9uc2VTdWJqZWN0KGN1cnJlbnRFdmVudFNvdXJjaW5nSXRlbSwgZXJyb3JIdHRwQ2xpZW50LCB0cnVlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgaXNWYWxpZFN0YXR1cyhzdGF0dXM6IG51bWJlcik6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIFBvRXZlbnRTb3VyY2luZ1NlcnZpY2UuVkFMSURfSFRUUF9TVEFUVVNfQ09ERVMuaW5jbHVkZXMoc3RhdHVzKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgbm90aWZ5RXZlbnRDcmVhdGlvbigpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLmVtaXR0ZXIpIHtcclxuICAgICAgdGhpcy5lbWl0dGVyLm5leHQoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgcGFnaW5hdGVTY2hlbWFEYXRhKGRhdGEsIHNjaGVtYSwgYmFzZVVybCk6IE9ic2VydmFibGU8bnVsbD4ge1xyXG4gICAgdGhpcy5jb25maWcuZGF0YVRyYW5zZm9ybS50cmFuc2Zvcm0oZGF0YSk7XHJcblxyXG4gICAgaWYgKHRoaXMuY29uZmlnLmRhdGFUcmFuc2Zvcm0uaGFzTmV4dCgpKSB7XHJcbiAgICAgIHRoaXMuc2NoZW1hc1N5bmNDb25maWdbc2NoZW1hLm5hbWVdWydjdXJyZW50VXJsRGlmZiddID0gdGhpcy5idWlsZFVybFBhcmFtcyhcclxuICAgICAgICBzY2hlbWEsXHJcbiAgICAgICAgYmFzZVVybCxcclxuICAgICAgICArK3RoaXMuc2NoZW1hc1N5bmNDb25maWdbc2NoZW1hLm5hbWVdWydwYWdlJ11cclxuICAgICAgKTtcclxuXHJcbiAgICAgIHJldHVybiB0aGlzLmRpZmZTZXJ2ZXJJdGVtcyh0aGlzLnNjaGVtYXNTeW5jQ29uZmlnW3NjaGVtYS5uYW1lXVsnY3VycmVudFVybERpZmYnXSkucGlwZShcclxuICAgICAgICBtYXAocmVzcG9uc2UgPT4gdGhpcy5nZXRCb2R5QW5kRGF0ZShzY2hlbWEubmFtZSwgcmVzcG9uc2UpKVxyXG4gICAgICApO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBvZigpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSByZW1vdmVFdmVudFNvdXJjaW5nVmFsaWRJdGVtKFxyXG4gICAgc3RhdHVzLFxyXG4gICAgZXZlbnRTb3VyY2luZ0l0ZW06IFBvRXZlbnRTb3VyY2luZ0l0ZW1cclxuICApOiBQcm9taXNlPEFycmF5PFBvRXZlbnRTb3VyY2luZ0l0ZW0+PiB7XHJcbiAgICBpZiAodGhpcy5pc1ZhbGlkU3RhdHVzKHN0YXR1cykgfHwgZXZlbnRTb3VyY2luZ0l0ZW0ub3BlcmF0aW9uID09PSBQb0V2ZW50U291cmNpbmdPcGVyYXRpb24uSHR0cCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5yZW1vdmVFdmVudFNvdXJjaW5nSXRlbShldmVudFNvdXJjaW5nSXRlbS5pZCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHNlbGVjdE9wZXJhdGlvbihldmVudFNvdXJjaW5nSXRlbTogUG9FdmVudFNvdXJjaW5nSXRlbSk6IFByb21pc2U8YW55PiB7XHJcbiAgICBzd2l0Y2ggKGV2ZW50U291cmNpbmdJdGVtLm9wZXJhdGlvbikge1xyXG4gICAgICBjYXNlIFBvRXZlbnRTb3VyY2luZ09wZXJhdGlvbi5JbnNlcnQ6XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaW5zZXJ0T3BlcmF0aW9uKGV2ZW50U291cmNpbmdJdGVtKTtcclxuXHJcbiAgICAgIGNhc2UgUG9FdmVudFNvdXJjaW5nT3BlcmF0aW9uLlVwZGF0ZTpcclxuICAgICAgICByZXR1cm4gdGhpcy51cGRhdGVPcGVyYXRpb24oZXZlbnRTb3VyY2luZ0l0ZW0pO1xyXG5cclxuICAgICAgY2FzZSBQb0V2ZW50U291cmNpbmdPcGVyYXRpb24uRGVsZXRlOlxyXG4gICAgICAgIHJldHVybiB0aGlzLmRlbGV0ZU9wZXJhdGlvbihldmVudFNvdXJjaW5nSXRlbSk7XHJcblxyXG4gICAgICBjYXNlIFBvRXZlbnRTb3VyY2luZ09wZXJhdGlvbi5IdHRwOlxyXG4gICAgICAgIHJldHVybiB0aGlzLmh0dHBPcGVyYXRpb24oZXZlbnRTb3VyY2luZ0l0ZW0pO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBzZW5kUmVzcG9uc2VTdWJqZWN0KFxyXG4gICAgZXZlbnRTb3VyY2luZ0l0ZW06IFBvRXZlbnRTb3VyY2luZ0l0ZW0sXHJcbiAgICByZXNwb25zZTogSHR0cFJlc3BvbnNlPE9iamVjdD4gfCBIdHRwRXJyb3JSZXNwb25zZSB8IFBvRXZlbnRTb3VyY2luZ0Vycm9yUmVzcG9uc2UsXHJcbiAgICBpc1N1YmplY3RFcnJvcjogYm9vbGVhbiA9IGZhbHNlXHJcbiAgKTogUHJvbWlzZTxhbnk+IHtcclxuICAgIGNvbnN0IHBvU3luY1Jlc3BvbnNlOiBQb1N5bmNSZXNwb25zZSA9IHtcclxuICAgICAgaWQ6IGV2ZW50U291cmNpbmdJdGVtLmlkLFxyXG4gICAgICBjdXN0b21SZXF1ZXN0SWQ6IGV2ZW50U291cmNpbmdJdGVtLmN1c3RvbVJlcXVlc3RJZCxcclxuICAgICAgcmVxdWVzdDogZXZlbnRTb3VyY2luZ0l0ZW0ucmVjb3JkLFxyXG4gICAgICByZXNwb25zZTogcmVzcG9uc2VcclxuICAgIH07XHJcblxyXG4gICAgdGhpcy5zdG9wcGVkUXVldWVFdmVudFNvdXJjaW5nID0gaXNTdWJqZWN0RXJyb3I7XHJcbiAgICB0aGlzLnJlc3BvbnNlU3ViamVjdC5uZXh0KHBvU3luY1Jlc3BvbnNlKTtcclxuXHJcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFzeW5jIHNlbmRTZXJ2ZXJJdGVtKHVybDogc3RyaW5nLCBtZXRob2Q6IFBvSHR0cFJlcXVlc3RUeXBlLCBib2R5PzogUG9FdmVudFNvdXJjaW5nSXRlbVsncmVjb3JkJ10pIHtcclxuICAgIGNvbnN0IHJlcXVlc3REYXRhOiBQb0h0dHBSZXF1ZXN0RGF0YSA9IGF3YWl0IHRoaXMuY3JlYXRlUG9IdHRwUmVxdWVzdERhdGEodXJsLCBtZXRob2QsIGJvZHkpO1xyXG5cclxuICAgIHJldHVybiB0aGlzLnBvSHR0cENsaWVudC5jcmVhdGVSZXF1ZXN0KHJlcXVlc3REYXRhKS50b1Byb21pc2UoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYXN5bmMgY3JlYXRlUG9IdHRwUmVxdWVzdERhdGEoXHJcbiAgICB1cmw6IHN0cmluZyxcclxuICAgIG1ldGhvZDogUG9IdHRwUmVxdWVzdFR5cGUsXHJcbiAgICByZWNvcmQ/OiBQb0V2ZW50U291cmNpbmdJdGVtWydyZWNvcmQnXSxcclxuICAgIGhlYWRlcnM/OiBBcnJheTxQb0h0dHBIZWFkZXJPcHRpb24+XHJcbiAgKTogUHJvbWlzZTxQb0h0dHBSZXF1ZXN0RGF0YT4ge1xyXG4gICAgbGV0IGJvZHkgPSByZWNvcmQuYm9keSA/PyByZWNvcmQ7XHJcblxyXG4gICAgaWYgKHJlY29yZC5ib2R5VHlwZSA9PT0gJ0ZpbGUnKSB7XHJcbiAgICAgIGJvZHkgPSBhd2FpdCB0aGlzLmNyZWF0ZUZvcm1EYXRhKGJvZHksIHJlY29yZC5maWxlTmFtZSwgcmVjb3JkLm1pbWVUeXBlLCByZWNvcmQuZm9ybUZpZWxkKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4geyB1cmwsIG1ldGhvZCwgYm9keSwgaGVhZGVycyB9O1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhc3luYyBjcmVhdGVGb3JtRGF0YShcclxuICAgIGJvZHk6IHN0cmluZyxcclxuICAgIGZpbGVOYW1lOiBzdHJpbmcsXHJcbiAgICBtaW1lVHlwZTogc3RyaW5nLFxyXG4gICAgZm9ybUZpZWxkOiBzdHJpbmcgPSAnZmlsZSdcclxuICApOiBQcm9taXNlPEZvcm1EYXRhPiB7XHJcbiAgICBjb25zdCBmaWxlID0gYXdhaXQgdG9GaWxlKGJvZHksIGZpbGVOYW1lLCBtaW1lVHlwZSk7XHJcbiAgICBjb25zdCBmb3JtRGF0YTogRm9ybURhdGEgPSBuZXcgRm9ybURhdGEoKTtcclxuXHJcbiAgICBmb3JtRGF0YS5hcHBlbmQoZm9ybUZpZWxkLCBmaWxlLCBmaWxlTmFtZSk7XHJcbiAgICByZXR1cm4gZm9ybURhdGE7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGFzeW5jIHVwZGF0ZU9wZXJhdGlvbihldmVudFNvdXJjaW5nSXRlbTogUG9FdmVudFNvdXJjaW5nSXRlbSk6IFByb21pc2U8QXJyYXk8YW55PiB8IG51bWJlcj4ge1xyXG4gICAgY29uc3Qgc2NoZW1hID0gYXdhaXQgdGhpcy5wb1NjaGVtYURlZmluaXRpb24uZ2V0KGV2ZW50U291cmNpbmdJdGVtLnNjaGVtYSk7XHJcbiAgICBjb25zdCB1cmwgPSBQb0V2ZW50U291cmNpbmdTZXJ2aWNlLmdldFVybChldmVudFNvdXJjaW5nSXRlbSwgc2NoZW1hLCBQb1JlcXVlc3RUeXBlLlBBVENIKTtcclxuXHJcbiAgICB0cnkge1xyXG4gICAgICBjb25zdCByZWNvcmRJZCA9IGV2ZW50U291cmNpbmdJdGVtLnJlY29yZFtzY2hlbWEuaWRGaWVsZF07XHJcbiAgICAgIHRoaXMuY2hlY2tSZWNvcmRJZEV4aXN0cyhyZWNvcmRJZCwgUG9FdmVudFNvdXJjaW5nT3BlcmF0aW9uLlVwZGF0ZSk7XHJcblxyXG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuc2VuZFNlcnZlckl0ZW0odXJsLCBQb0h0dHBSZXF1ZXN0VHlwZS5QVVQsIGV2ZW50U291cmNpbmdJdGVtLnJlY29yZCk7XHJcbiAgICAgIGF3YWl0IHRoaXMucmVtb3ZlRXZlbnRTb3VyY2luZ1ZhbGlkSXRlbShyZXNwb25zZS5zdGF0dXMsIGV2ZW50U291cmNpbmdJdGVtKTtcclxuXHJcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnNlbmRSZXNwb25zZVN1YmplY3QoZXZlbnRTb3VyY2luZ0l0ZW0sIHJlc3BvbnNlKTtcclxuICAgIH0gY2F0Y2ggKGVycm9ySHR0cENsaWVudCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5zZW5kUmVzcG9uc2VTdWJqZWN0KGV2ZW50U291cmNpbmdJdGVtLCBlcnJvckh0dHBDbGllbnQsIHRydWUpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSB1cGRhdGVQZW5kaW5nRXZlbnRTb3VyY2luZyhcclxuICAgIGN1cnJlbnRFdmVudFNvdXJjaW5nSXRlbTogUG9FdmVudFNvdXJjaW5nSXRlbSxcclxuICAgIGlkRmllbGRTY2hlbWE6IHN0cmluZyxcclxuICAgIGluc2VydGVkOiBvYmplY3QsXHJcbiAgICBldmVudFNvdXJjaW5nSXRlbXM6IEFycmF5PFBvRXZlbnRTb3VyY2luZ0l0ZW0+XHJcbiAgKSB7XHJcbiAgICBpZiAoY3VycmVudEV2ZW50U291cmNpbmdJdGVtLnJlY29yZFtQb1NjaGVtYVV0aWwuc3luY0ludGVybmFsSWRGaWVsZE5hbWVdKSB7XHJcbiAgICAgIGV2ZW50U291cmNpbmdJdGVtcy5mb3JFYWNoKChldmVudFNvdXJjaW5nSXRlbSwgcG9zaXRpb24pID0+IHtcclxuICAgICAgICBjb25zdCBpc0N1cnJlbnRFdmVudFNvdXJjaW5nSXRlbSA9XHJcbiAgICAgICAgICAhZXZlbnRTb3VyY2luZ0l0ZW0ucmVjb3JkW2lkRmllbGRTY2hlbWFdICYmXHJcbiAgICAgICAgICBldmVudFNvdXJjaW5nSXRlbS5yZWNvcmRbUG9TY2hlbWFVdGlsLnN5bmNJbnRlcm5hbElkRmllbGROYW1lXSA9PT1cclxuICAgICAgICAgICAgY3VycmVudEV2ZW50U291cmNpbmdJdGVtLnJlY29yZFtQb1NjaGVtYVV0aWwuc3luY0ludGVybmFsSWRGaWVsZE5hbWVdO1xyXG5cclxuICAgICAgICBpZiAoaXNDdXJyZW50RXZlbnRTb3VyY2luZ0l0ZW0pIHtcclxuICAgICAgICAgIGV2ZW50U291cmNpbmdJdGVtc1twb3NpdGlvbl0ucmVjb3JkW2lkRmllbGRTY2hlbWFdID0gaW5zZXJ0ZWRbaWRGaWVsZFNjaGVtYV07XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIHJldHVybiB0aGlzLnBvU3RvcmFnZS5zZXQoUG9FdmVudFNvdXJjaW5nU2VydmljZS5ldmVudF9zb3VyY2luZ19uYW1lLCBldmVudFNvdXJjaW5nSXRlbXMpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhc3luYyB1cGRhdGVSZWNvcmRzKHNlcnZlclJlY29yZHM6IEFycmF5PGFueT4sIHNjaGVtYTogUG9TeW5jU2NoZW1hKSB7XHJcbiAgICBmb3IgKGNvbnN0IHNlcnZlclJlY29yZCBvZiBzZXJ2ZXJSZWNvcmRzKSB7XHJcbiAgICAgIGF3YWl0IHRoaXMudXBkYXRlUmVjb3JkQnlTZXJ2ZXJSZWNvcmQoc2VydmVyUmVjb3JkLCBzY2hlbWEpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhc3luYyB1cGRhdGVSZWNvcmRCeVNlcnZlclJlY29yZChzZXJ2ZXJSZWNvcmQsIHNjaGVtYSkge1xyXG4gICAgY29uc3QgcmVjb3JkSWQgPSBzZXJ2ZXJSZWNvcmRbc2NoZW1hLmlkRmllbGRdO1xyXG4gICAgY29uc3Qgc3RvcmFnZVJlY29yZCA9IGF3YWl0IHRoaXMucG9TY2hlbWFTZXJ2aWNlLmdldChzY2hlbWEubmFtZSwgcmVjb3JkSWQpO1xyXG4gICAgY29uc3QgZXhpc3RzU3RvcmFnZVJlY29yZCA9ICEhT2JqZWN0LmtleXMoc3RvcmFnZVJlY29yZCkubGVuZ3RoO1xyXG5cclxuICAgIGlmIChleGlzdHNTdG9yYWdlUmVjb3JkICYmIHNlcnZlclJlY29yZFtzY2hlbWEuZGVsZXRlZEZpZWxkXSkge1xyXG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5wb1NjaGVtYVNlcnZpY2UucmVtb3ZlKHNjaGVtYS5uYW1lLCBzZXJ2ZXJSZWNvcmRbc2NoZW1hLmlkRmllbGRdKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoZXhpc3RzU3RvcmFnZVJlY29yZCAmJiAhc2VydmVyUmVjb3JkW3NjaGVtYS5kZWxldGVkRmllbGRdKSB7XHJcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnBvU2NoZW1hU2VydmljZS51cGRhdGUoc2NoZW1hLCBzZXJ2ZXJSZWNvcmQpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghZXhpc3RzU3RvcmFnZVJlY29yZCAmJiAhc2VydmVyUmVjb3JkW3NjaGVtYS5kZWxldGVkRmllbGRdKSB7XHJcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnBvU2NoZW1hU2VydmljZS5jcmVhdGUoc2NoZW1hLCBzZXJ2ZXJSZWNvcmQpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBhc3luYyB1cGRhdGVTdG9yYWdlQnlTY2hlbWEoc2NoZW1hOiBQb1N5bmNTY2hlbWEpOiBQcm9taXNlPGFueT4ge1xyXG4gICAgdGhpcy5jcmVhdGVTY2hlbWFTeW5jQ29uZmlnKHNjaGVtYS5uYW1lKTtcclxuXHJcbiAgICB0aGlzLnNjaGVtYXNTeW5jQ29uZmlnW3NjaGVtYS5uYW1lXVsncGFnZSddID0gMTtcclxuICAgIGNvbnN0IGJhc2VVcmwgPSBgJHtQb1NjaGVtYVV0aWwuZ2V0VXJsKHNjaGVtYSwgUG9SZXF1ZXN0VHlwZS5ESUZGKX0vJHtzY2hlbWEubGFzdFN5bmN9YDtcclxuICAgIHRoaXMuc2NoZW1hc1N5bmNDb25maWdbc2NoZW1hLm5hbWVdWydjdXJyZW50VXJsRGlmZiddID0gdGhpcy5idWlsZFVybFBhcmFtcyhcclxuICAgICAgc2NoZW1hLFxyXG4gICAgICBiYXNlVXJsLFxyXG4gICAgICB0aGlzLnNjaGVtYXNTeW5jQ29uZmlnW3NjaGVtYS5uYW1lXVsncGFnZSddXHJcbiAgICApO1xyXG5cclxuICAgIGNvbnN0IHNlcnZlclJlY29yZHMgPSBhd2FpdCB0aGlzLmdldFNlcnZlckRpZmZSZWNvcmRzKHNjaGVtYSwgYmFzZVVybCk7XHJcblxyXG4gICAgYXdhaXQgdGhpcy51cGRhdGVSZWNvcmRzKHNlcnZlclJlY29yZHMsIHNjaGVtYSk7XHJcblxyXG4gICAgc2NoZW1hLmxhc3RTeW5jID0gdGhpcy5zY2hlbWFzU3luY0NvbmZpZ1tzY2hlbWEubmFtZV1bJ3Jlc3BvbnNlRGF0ZSddO1xyXG4gICAgYXdhaXQgdGhpcy5wb1NjaGVtYURlZmluaXRpb24udXBkYXRlKHNjaGVtYSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHVwZGF0ZVN0b3JhZ2VTY2hlbWFzKHNjaGVtYXMpOiBBcnJheTxQcm9taXNlPEFycmF5PGFueT4+PiB7XHJcbiAgICByZXR1cm4gc2NoZW1hcy5tYXAoKHNjaGVtYTogUG9TeW5jU2NoZW1hKSA9PiB0aGlzLnVwZGF0ZVN0b3JhZ2VCeVNjaGVtYShzY2hlbWEpKTtcclxuICB9XHJcbn1cclxuIl19
|
|
1
|
+
import { __awaiter } from "tslib";
|
|
2
|
+
import { Injectable } from '@angular/core';
|
|
3
|
+
import * as HttpStatus from 'http-status-codes';
|
|
4
|
+
import { Observable, of, Subject } from 'rxjs';
|
|
5
|
+
import { expand, map, reduce } from 'rxjs/operators';
|
|
6
|
+
import { PoStorageService } from '@po-ui/ng-storage';
|
|
7
|
+
import { toBase64, toFile } from '../../utils/utils';
|
|
8
|
+
import { PoEventSourcingErrorResponse } from '../../models/po-event-sourcing-error-response.model';
|
|
9
|
+
import { PoEventSourcingOperation } from './enums/po-event-sourcing-operation.enum';
|
|
10
|
+
import { PoHttpClientService } from './../po-http-client/po-http-client.service';
|
|
11
|
+
import { PoHttpRequestType } from '../po-http-client/po-http-request-type.enum';
|
|
12
|
+
import { PoRequestType } from '../../models/po-request-type.enum';
|
|
13
|
+
import { PoSchemaDefinitionService } from './../po-schema/po-schema-definition/po-schema-definition.service';
|
|
14
|
+
import { PoSchemaService } from './../po-schema/po-schema.service';
|
|
15
|
+
import { PoSchemaUtil } from './../po-schema/po-schema-util/po-schema-util.model';
|
|
16
|
+
export class PoEventSourcingService {
|
|
17
|
+
constructor(poSchemaDefinition, poSchemaService, poStorage, poHttpClient) {
|
|
18
|
+
this.poSchemaDefinition = poSchemaDefinition;
|
|
19
|
+
this.poSchemaService = poSchemaService;
|
|
20
|
+
this.poStorage = poStorage;
|
|
21
|
+
this.poHttpClient = poHttpClient;
|
|
22
|
+
this.stoppedQueueEventSourcing = false;
|
|
23
|
+
this.responseSubject = new Subject();
|
|
24
|
+
this.schemasSyncConfig = {};
|
|
25
|
+
}
|
|
26
|
+
static getUrl(eventSourcingItem, schema, requestType) {
|
|
27
|
+
const schemaUrl = PoSchemaUtil.getUrl(schema, requestType);
|
|
28
|
+
const schemaId = eventSourcingItem.record[schema.idField];
|
|
29
|
+
if (requestType === PoRequestType.GET) {
|
|
30
|
+
return schemaUrl;
|
|
31
|
+
}
|
|
32
|
+
if ([PoRequestType.DELETE, PoRequestType.PATCH].includes(requestType)) {
|
|
33
|
+
return schemaUrl ? `${schemaUrl}/${schemaId}` : `${PoSchemaUtil.getUrl(schema, PoRequestType.GET)}/${schemaId}`;
|
|
34
|
+
}
|
|
35
|
+
if (requestType === PoRequestType.POST) {
|
|
36
|
+
return schemaUrl ? schemaUrl : PoSchemaUtil.getUrl(schema, PoRequestType.GET);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
create(schemaName, newItem, customRequestId) {
|
|
40
|
+
const eventSourcingItem = this.createEventSourcingItem(PoEventSourcingOperation.Insert, newItem, schemaName, customRequestId);
|
|
41
|
+
return this.insertEventSourcingQueue(eventSourcingItem);
|
|
42
|
+
}
|
|
43
|
+
createBatchEvents(schemaName, eventList) {
|
|
44
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
45
|
+
const eventSourcingList = this.createEventSourcingList(schemaName, eventList);
|
|
46
|
+
yield this.poStorage.appendArrayToArray(PoEventSourcingService.event_sourcing_name, eventSourcingList);
|
|
47
|
+
this.notifyEventCreation();
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Destrói a chave do *storage* que contém a fila de dados que estão esperando para serem enviados ao
|
|
52
|
+
* servidor *(EventSourcing)*.
|
|
53
|
+
*
|
|
54
|
+
* @returns {Promise<void>} Promessa que é resolvida quando a chave referente a fila de *EventSourcing* for destruída.
|
|
55
|
+
*/
|
|
56
|
+
destroyEventSourcingQueue() {
|
|
57
|
+
return this.poStorage.remove(PoEventSourcingService.event_sourcing_name);
|
|
58
|
+
}
|
|
59
|
+
httpCommand(httpOperationData, customRequestId) {
|
|
60
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
61
|
+
httpOperationData = yield this.serializeBody(httpOperationData);
|
|
62
|
+
const eventSourcingItem = this.createEventSourcingItem(PoEventSourcingOperation.Http, httpOperationData, undefined, customRequestId);
|
|
63
|
+
yield this.insertEventSourcingQueue(eventSourcingItem);
|
|
64
|
+
return eventSourcingItem.id;
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
responsesSubject() {
|
|
68
|
+
return this.responseSubject.asObservable();
|
|
69
|
+
}
|
|
70
|
+
onSaveData() {
|
|
71
|
+
if (!this.eventSub) {
|
|
72
|
+
this.eventSub = Observable.create(subscriber => (this.emitter = subscriber));
|
|
73
|
+
}
|
|
74
|
+
return this.eventSub;
|
|
75
|
+
}
|
|
76
|
+
remove(schemaName, itemToDelete, customRequestId) {
|
|
77
|
+
const eventSourcingItem = this.createEventSourcingItem(PoEventSourcingOperation.Delete, itemToDelete, schemaName, customRequestId);
|
|
78
|
+
return this.insertEventSourcingQueue(eventSourcingItem);
|
|
79
|
+
}
|
|
80
|
+
removeEventSourcingItem(idEventSourcingItem) {
|
|
81
|
+
return this.poStorage.removeItemFromArray(PoEventSourcingService.event_sourcing_name, 'id', idEventSourcingItem);
|
|
82
|
+
}
|
|
83
|
+
syncGet() {
|
|
84
|
+
const syncGetFunction = () => __awaiter(this, void 0, void 0, function* () {
|
|
85
|
+
return this.poSchemaDefinition.getAll().then(schemas => {
|
|
86
|
+
const schemaPromises = this.updateStorageSchemas(schemas);
|
|
87
|
+
return Promise.all(schemaPromises);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
return this.poSchemaService.limitedCallWrap(syncGetFunction);
|
|
91
|
+
}
|
|
92
|
+
syncSend() {
|
|
93
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
94
|
+
const syncSendFunction = () => __awaiter(this, void 0, void 0, function* () {
|
|
95
|
+
const itemOfQueue = yield this.poStorage.getFirstItem(PoEventSourcingService.event_sourcing_name);
|
|
96
|
+
if (itemOfQueue) {
|
|
97
|
+
yield this.selectOperation(itemOfQueue);
|
|
98
|
+
}
|
|
99
|
+
if (this.stoppedQueueEventSourcing || !itemOfQueue) {
|
|
100
|
+
this.stoppedQueueEventSourcing = false;
|
|
101
|
+
return Promise.resolve();
|
|
102
|
+
}
|
|
103
|
+
return syncSendFunction();
|
|
104
|
+
});
|
|
105
|
+
return this.poSchemaService.limitedCallWrap(syncSendFunction);
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
update(schemaName, itemUpdated, customRequestId) {
|
|
109
|
+
const eventSourcingItem = this.createEventSourcingItem(PoEventSourcingOperation.Update, itemUpdated, schemaName, customRequestId);
|
|
110
|
+
return this.insertEventSourcingQueue(eventSourcingItem);
|
|
111
|
+
}
|
|
112
|
+
/* Avalia se o body é do tipo File e se for converte para base64 */
|
|
113
|
+
serializeBody(requestData) {
|
|
114
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
115
|
+
let { body, mimeType, bodyType, fileName } = requestData;
|
|
116
|
+
if (body instanceof File) {
|
|
117
|
+
bodyType = 'File';
|
|
118
|
+
mimeType = body.type;
|
|
119
|
+
fileName = body.name;
|
|
120
|
+
body = yield toBase64(body);
|
|
121
|
+
}
|
|
122
|
+
return Object.assign(Object.assign({}, requestData), { body, mimeType, bodyType, fileName });
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
buildUrlParams(schema, baseUrl, pageNumber) {
|
|
126
|
+
const params = [];
|
|
127
|
+
params.push(`${this.config.dataTransform.getPageSizeParamName()}=${schema.pageSize}`);
|
|
128
|
+
params.push(`${this.config.dataTransform.getPageParamName()}=${pageNumber}`);
|
|
129
|
+
return `${baseUrl}?${params.join('&')}`;
|
|
130
|
+
}
|
|
131
|
+
checkRecordIdExists(recordId, operation) {
|
|
132
|
+
if (!recordId) {
|
|
133
|
+
const error = {
|
|
134
|
+
message: 'Identifier not defined',
|
|
135
|
+
operation: operation
|
|
136
|
+
};
|
|
137
|
+
throw new PoEventSourcingErrorResponse(error);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
concatPageItems(pageAcumulator, requestBody) {
|
|
141
|
+
if (requestBody[this.config.dataTransform.getItemsFieldName()]) {
|
|
142
|
+
pageAcumulator.data = [...pageAcumulator.data, ...requestBody[this.config.dataTransform.getItemsFieldName()]];
|
|
143
|
+
}
|
|
144
|
+
return pageAcumulator;
|
|
145
|
+
}
|
|
146
|
+
createEventSourcingItem(operation, newItem, schemaName, customRequestId, id) {
|
|
147
|
+
if (!schemaName && operation !== PoEventSourcingOperation.Http) {
|
|
148
|
+
throw new Error('PoSyncSchema is not defined.');
|
|
149
|
+
}
|
|
150
|
+
return {
|
|
151
|
+
id: id ? id : new Date().getTime(),
|
|
152
|
+
dateTime: new Date().getTime(),
|
|
153
|
+
schema: schemaName,
|
|
154
|
+
operation: operation,
|
|
155
|
+
record: newItem,
|
|
156
|
+
customRequestId: customRequestId
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
createEventSourcingList(schemaName, eventList) {
|
|
160
|
+
return eventList.map((eventItem, index) => {
|
|
161
|
+
const id = new Date().getTime() + index;
|
|
162
|
+
return this.createEventSourcingItem(eventItem.operation, eventItem.record, schemaName, eventItem.customRequestId, id);
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
createSchemaSyncConfig(schemaName) {
|
|
166
|
+
this.schemasSyncConfig[schemaName] = {
|
|
167
|
+
page: undefined,
|
|
168
|
+
currentUrlDiff: undefined,
|
|
169
|
+
responseDate: undefined
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
deleteOperation(eventSourcingItem) {
|
|
173
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
174
|
+
try {
|
|
175
|
+
const schema = yield this.poSchemaDefinition.get(eventSourcingItem.schema);
|
|
176
|
+
const recordId = eventSourcingItem.record[schema.idField];
|
|
177
|
+
this.checkRecordIdExists(recordId, PoEventSourcingOperation.Delete);
|
|
178
|
+
const url = PoEventSourcingService.getUrl(eventSourcingItem, schema, PoRequestType.DELETE);
|
|
179
|
+
const response = yield this.sendServerItem(url, PoHttpRequestType.DELETE);
|
|
180
|
+
yield this.removeEventSourcingValidItem(response.status, eventSourcingItem);
|
|
181
|
+
return yield this.sendResponseSubject(eventSourcingItem, response);
|
|
182
|
+
}
|
|
183
|
+
catch (errorResponse) {
|
|
184
|
+
return this.sendResponseSubject(eventSourcingItem, errorResponse, true);
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
diffServerItems(currentUrlDiff) {
|
|
189
|
+
return this.poHttpClient.get(currentUrlDiff);
|
|
190
|
+
}
|
|
191
|
+
getBodyAndDate(schemaName, response) {
|
|
192
|
+
const getDateFieldName = this.config.dataTransform.getDateFieldName();
|
|
193
|
+
const responseSyncDate = response.body[getDateFieldName];
|
|
194
|
+
this.schemasSyncConfig[schemaName]['responseDate'] = responseSyncDate;
|
|
195
|
+
return response.body;
|
|
196
|
+
}
|
|
197
|
+
getServerDiffRecords(schema, baseUrl) {
|
|
198
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
199
|
+
const initialAcumulatorPage = { entity: schema.name, data: [] };
|
|
200
|
+
const diffUrl = this.schemasSyncConfig[schema.name]['currentUrlDiff'];
|
|
201
|
+
const serverResponse = yield this.diffServerItems(diffUrl)
|
|
202
|
+
.pipe(map(response => this.getBodyAndDate(schema.name, response)), expand(data => this.paginateSchemaData(data, schema, baseUrl)), reduce((pageAcumulator, requestBody) => this.concatPageItems(pageAcumulator, requestBody), initialAcumulatorPage))
|
|
203
|
+
.toPromise();
|
|
204
|
+
return serverResponse.data;
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
httpOperation(eventSourcingItem) {
|
|
208
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
209
|
+
try {
|
|
210
|
+
const requestData = yield this.createPoHttpRequestData(eventSourcingItem.record.url, eventSourcingItem.record.method, eventSourcingItem.record, eventSourcingItem.record.headers);
|
|
211
|
+
const response = yield this.poHttpClient.createRequest(requestData).toPromise();
|
|
212
|
+
const poHttpCommandResponse = {
|
|
213
|
+
id: eventSourcingItem.id,
|
|
214
|
+
customRequestId: eventSourcingItem.customRequestId,
|
|
215
|
+
request: eventSourcingItem.record,
|
|
216
|
+
response: response
|
|
217
|
+
};
|
|
218
|
+
this.responseSubject.next(poHttpCommandResponse);
|
|
219
|
+
return this.removeEventSourcingValidItem(response.status, eventSourcingItem);
|
|
220
|
+
}
|
|
221
|
+
catch (errorHttpClient) {
|
|
222
|
+
return this.sendResponseSubject(eventSourcingItem, errorHttpClient, true);
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
insertEventSourcingQueue(eventSourcingItem) {
|
|
227
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
228
|
+
const eventSourcingUpdatedQueue = yield this.poStorage.appendItemToArray(PoEventSourcingService.event_sourcing_name, eventSourcingItem);
|
|
229
|
+
this.notifyEventCreation();
|
|
230
|
+
return Promise.resolve(eventSourcingUpdatedQueue);
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
insertOperation(currentEventSourcingItem) {
|
|
234
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
235
|
+
const schema = yield this.poSchemaDefinition.get(currentEventSourcingItem.schema);
|
|
236
|
+
const url = PoEventSourcingService.getUrl(currentEventSourcingItem, schema, PoRequestType.POST);
|
|
237
|
+
try {
|
|
238
|
+
const response = yield this.sendServerItem(url, PoHttpRequestType.POST, currentEventSourcingItem.record);
|
|
239
|
+
const recordUpdatedByServer = response.body;
|
|
240
|
+
yield this.removeEventSourcingValidItem(response.status, currentEventSourcingItem);
|
|
241
|
+
const id = currentEventSourcingItem.record[PoSchemaUtil.syncInternalIdFieldName];
|
|
242
|
+
yield this.poSchemaService.update(schema, recordUpdatedByServer, id);
|
|
243
|
+
const eventSourcingItems = yield this.poStorage.get(PoEventSourcingService.event_sourcing_name);
|
|
244
|
+
yield this.updatePendingEventSourcing(currentEventSourcingItem, schema.idField, recordUpdatedByServer, eventSourcingItems);
|
|
245
|
+
return this.sendResponseSubject(currentEventSourcingItem, response);
|
|
246
|
+
}
|
|
247
|
+
catch (errorHttpClient) {
|
|
248
|
+
return this.sendResponseSubject(currentEventSourcingItem, errorHttpClient, true);
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
isValidStatus(status) {
|
|
253
|
+
return PoEventSourcingService.VALID_HTTP_STATUS_CODES.includes(status);
|
|
254
|
+
}
|
|
255
|
+
notifyEventCreation() {
|
|
256
|
+
if (this.emitter) {
|
|
257
|
+
this.emitter.next();
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
paginateSchemaData(data, schema, baseUrl) {
|
|
261
|
+
this.config.dataTransform.transform(data);
|
|
262
|
+
if (this.config.dataTransform.hasNext()) {
|
|
263
|
+
this.schemasSyncConfig[schema.name]['currentUrlDiff'] = this.buildUrlParams(schema, baseUrl, ++this.schemasSyncConfig[schema.name]['page']);
|
|
264
|
+
return this.diffServerItems(this.schemasSyncConfig[schema.name]['currentUrlDiff']).pipe(map(response => this.getBodyAndDate(schema.name, response)));
|
|
265
|
+
}
|
|
266
|
+
return of();
|
|
267
|
+
}
|
|
268
|
+
removeEventSourcingValidItem(status, eventSourcingItem) {
|
|
269
|
+
if (this.isValidStatus(status) || eventSourcingItem.operation === PoEventSourcingOperation.Http) {
|
|
270
|
+
return this.removeEventSourcingItem(eventSourcingItem.id);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
selectOperation(eventSourcingItem) {
|
|
274
|
+
switch (eventSourcingItem.operation) {
|
|
275
|
+
case PoEventSourcingOperation.Insert:
|
|
276
|
+
return this.insertOperation(eventSourcingItem);
|
|
277
|
+
case PoEventSourcingOperation.Update:
|
|
278
|
+
return this.updateOperation(eventSourcingItem);
|
|
279
|
+
case PoEventSourcingOperation.Delete:
|
|
280
|
+
return this.deleteOperation(eventSourcingItem);
|
|
281
|
+
case PoEventSourcingOperation.Http:
|
|
282
|
+
return this.httpOperation(eventSourcingItem);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
sendResponseSubject(eventSourcingItem, response, isSubjectError = false) {
|
|
286
|
+
const poSyncResponse = {
|
|
287
|
+
id: eventSourcingItem.id,
|
|
288
|
+
customRequestId: eventSourcingItem.customRequestId,
|
|
289
|
+
request: eventSourcingItem.record,
|
|
290
|
+
response: response
|
|
291
|
+
};
|
|
292
|
+
this.stoppedQueueEventSourcing = isSubjectError;
|
|
293
|
+
this.responseSubject.next(poSyncResponse);
|
|
294
|
+
return Promise.resolve();
|
|
295
|
+
}
|
|
296
|
+
sendServerItem(url, method, body) {
|
|
297
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
298
|
+
const requestData = yield this.createPoHttpRequestData(url, method, body);
|
|
299
|
+
return this.poHttpClient.createRequest(requestData).toPromise();
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
createPoHttpRequestData(url, method, record, headers) {
|
|
303
|
+
var _a;
|
|
304
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
305
|
+
let body = (_a = record.body) !== null && _a !== void 0 ? _a : record;
|
|
306
|
+
if (record.bodyType === 'File') {
|
|
307
|
+
body = yield this.createFormData(body, record.fileName, record.mimeType, record.formField);
|
|
308
|
+
}
|
|
309
|
+
return { url, method, body, headers };
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
createFormData(body, fileName, mimeType, formField = 'file') {
|
|
313
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
314
|
+
const file = yield toFile(body, fileName, mimeType);
|
|
315
|
+
const formData = new FormData();
|
|
316
|
+
formData.append(formField, file, fileName);
|
|
317
|
+
return formData;
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
updateOperation(eventSourcingItem) {
|
|
321
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
322
|
+
const schema = yield this.poSchemaDefinition.get(eventSourcingItem.schema);
|
|
323
|
+
const url = PoEventSourcingService.getUrl(eventSourcingItem, schema, PoRequestType.PATCH);
|
|
324
|
+
try {
|
|
325
|
+
const recordId = eventSourcingItem.record[schema.idField];
|
|
326
|
+
this.checkRecordIdExists(recordId, PoEventSourcingOperation.Update);
|
|
327
|
+
const response = yield this.sendServerItem(url, PoHttpRequestType.PUT, eventSourcingItem.record);
|
|
328
|
+
yield this.removeEventSourcingValidItem(response.status, eventSourcingItem);
|
|
329
|
+
return yield this.sendResponseSubject(eventSourcingItem, response);
|
|
330
|
+
}
|
|
331
|
+
catch (errorHttpClient) {
|
|
332
|
+
return this.sendResponseSubject(eventSourcingItem, errorHttpClient, true);
|
|
333
|
+
}
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
updatePendingEventSourcing(currentEventSourcingItem, idFieldSchema, inserted, eventSourcingItems) {
|
|
337
|
+
if (currentEventSourcingItem.record[PoSchemaUtil.syncInternalIdFieldName]) {
|
|
338
|
+
eventSourcingItems.forEach((eventSourcingItem, position) => {
|
|
339
|
+
const isCurrentEventSourcingItem = !eventSourcingItem.record[idFieldSchema] &&
|
|
340
|
+
eventSourcingItem.record[PoSchemaUtil.syncInternalIdFieldName] ===
|
|
341
|
+
currentEventSourcingItem.record[PoSchemaUtil.syncInternalIdFieldName];
|
|
342
|
+
if (isCurrentEventSourcingItem) {
|
|
343
|
+
eventSourcingItems[position].record[idFieldSchema] = inserted[idFieldSchema];
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
return this.poStorage.set(PoEventSourcingService.event_sourcing_name, eventSourcingItems);
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
return Promise.resolve();
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
updateRecords(serverRecords, schema) {
|
|
353
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
354
|
+
for (const serverRecord of serverRecords) {
|
|
355
|
+
yield this.updateRecordByServerRecord(serverRecord, schema);
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
updateRecordByServerRecord(serverRecord, schema) {
|
|
360
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
361
|
+
const recordId = serverRecord[schema.idField];
|
|
362
|
+
const storageRecord = yield this.poSchemaService.get(schema.name, recordId);
|
|
363
|
+
const existsStorageRecord = !!Object.keys(storageRecord).length;
|
|
364
|
+
if (existsStorageRecord && serverRecord[schema.deletedField]) {
|
|
365
|
+
return yield this.poSchemaService.remove(schema.name, serverRecord[schema.idField]);
|
|
366
|
+
}
|
|
367
|
+
if (existsStorageRecord && !serverRecord[schema.deletedField]) {
|
|
368
|
+
return yield this.poSchemaService.update(schema, serverRecord);
|
|
369
|
+
}
|
|
370
|
+
if (!existsStorageRecord && !serverRecord[schema.deletedField]) {
|
|
371
|
+
return yield this.poSchemaService.create(schema, serverRecord);
|
|
372
|
+
}
|
|
373
|
+
});
|
|
374
|
+
}
|
|
375
|
+
updateStorageBySchema(schema) {
|
|
376
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
377
|
+
this.createSchemaSyncConfig(schema.name);
|
|
378
|
+
this.schemasSyncConfig[schema.name]['page'] = 1;
|
|
379
|
+
const baseUrl = `${PoSchemaUtil.getUrl(schema, PoRequestType.DIFF)}/${schema.lastSync}`;
|
|
380
|
+
this.schemasSyncConfig[schema.name]['currentUrlDiff'] = this.buildUrlParams(schema, baseUrl, this.schemasSyncConfig[schema.name]['page']);
|
|
381
|
+
const serverRecords = yield this.getServerDiffRecords(schema, baseUrl);
|
|
382
|
+
yield this.updateRecords(serverRecords, schema);
|
|
383
|
+
schema.lastSync = this.schemasSyncConfig[schema.name]['responseDate'];
|
|
384
|
+
yield this.poSchemaDefinition.update(schema);
|
|
385
|
+
});
|
|
386
|
+
}
|
|
387
|
+
updateStorageSchemas(schemas) {
|
|
388
|
+
return schemas.map((schema) => this.updateStorageBySchema(schema));
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
PoEventSourcingService.event_sourcing_name = 'EventSourcing';
|
|
392
|
+
PoEventSourcingService.VALID_HTTP_STATUS_CODES = [
|
|
393
|
+
HttpStatus.OK,
|
|
394
|
+
HttpStatus.CREATED,
|
|
395
|
+
HttpStatus.ACCEPTED,
|
|
396
|
+
HttpStatus.NON_AUTHORITATIVE_INFORMATION,
|
|
397
|
+
HttpStatus.NO_CONTENT,
|
|
398
|
+
HttpStatus.RESET_CONTENT,
|
|
399
|
+
HttpStatus.PARTIAL_CONTENT,
|
|
400
|
+
HttpStatus.MULTI_STATUS // 207
|
|
401
|
+
];
|
|
402
|
+
PoEventSourcingService.decorators = [
|
|
403
|
+
{ type: Injectable }
|
|
404
|
+
];
|
|
405
|
+
PoEventSourcingService.ctorParameters = () => [
|
|
406
|
+
{ type: PoSchemaDefinitionService },
|
|
407
|
+
{ type: PoSchemaService },
|
|
408
|
+
{ type: PoStorageService },
|
|
409
|
+
{ type: PoHttpClientService }
|
|
410
|
+
];
|
|
411
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG8tZXZlbnQtc291cmNpbmcuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3N5bmMvc3JjL2xpYi9zZXJ2aWNlcy9wby1ldmVudC1zb3VyY2luZy9wby1ldmVudC1zb3VyY2luZy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFDQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTNDLE9BQU8sS0FBSyxVQUFVLE1BQU0sbUJBQW1CLENBQUM7QUFDaEQsT0FBTyxFQUFFLFVBQVUsRUFBRSxFQUFFLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9DLE9BQU8sRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLE1BQU0sRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXJELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBRXJELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFFckQsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0scURBQXFELENBQUM7QUFFbkcsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0sMENBQTBDLENBQUM7QUFHcEYsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFFakYsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sNkNBQTZDLENBQUM7QUFDaEYsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBQ2xFLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLGtFQUFrRSxDQUFDO0FBQzdHLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUNuRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0RBQW9ELENBQUM7QUFNbEYsTUFBTSxPQUFPLHNCQUFzQjtJQXVCakMsWUFDVSxrQkFBNkMsRUFDN0MsZUFBZ0MsRUFDaEMsU0FBMkIsRUFDM0IsWUFBaUM7UUFIakMsdUJBQWtCLEdBQWxCLGtCQUFrQixDQUEyQjtRQUM3QyxvQkFBZSxHQUFmLGVBQWUsQ0FBaUI7UUFDaEMsY0FBUyxHQUFULFNBQVMsQ0FBa0I7UUFDM0IsaUJBQVksR0FBWixZQUFZLENBQXFCO1FBWjNDLDhCQUF5QixHQUFZLEtBQUssQ0FBQztRQUluQyxvQkFBZSxHQUFHLElBQUksT0FBTyxFQUFrQixDQUFDO1FBRWhELHNCQUFpQixHQUFHLEVBQUUsQ0FBQztJQU81QixDQUFDO0lBRUksTUFBTSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsRUFBRSxNQUFNLEVBQUUsV0FBVztRQUMxRCxNQUFNLFNBQVMsR0FBRyxZQUFZLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxXQUFXLENBQUMsQ0FBQztRQUMzRCxNQUFNLFFBQVEsR0FBRyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRTFELElBQUksV0FBVyxLQUFLLGFBQWEsQ0FBQyxHQUFHLEVBQUU7WUFDckMsT0FBTyxTQUFTLENBQUM7U0FDbEI7UUFFRCxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sRUFBRSxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxFQUFFO1lBQ3JFLE9BQU8sU0FBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLFNBQVMsSUFBSSxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxZQUFZLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxhQUFhLENBQUMsR0FBRyxDQUFDLElBQUksUUFBUSxFQUFFLENBQUM7U0FDakg7UUFFRCxJQUFJLFdBQVcsS0FBSyxhQUFhLENBQUMsSUFBSSxFQUFFO1lBQ3RDLE9BQU8sU0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLGFBQWEsQ0FBQyxHQUFHLENBQUMsQ0FBQztTQUMvRTtJQUNILENBQUM7SUFFRCxNQUFNLENBQUMsVUFBa0IsRUFBRSxPQUFZLEVBQUUsZUFBd0I7UUFDL0QsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQ3BELHdCQUF3QixDQUFDLE1BQU0sRUFDL0IsT0FBTyxFQUNQLFVBQVUsRUFDVixlQUFlLENBQ2hCLENBQUM7UUFDRixPQUFPLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0lBQzFELENBQUM7SUFFSyxpQkFBaUIsQ0FBQyxVQUFrQixFQUFFLFNBQTRDOztZQUN0RixNQUFNLGlCQUFpQixHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxVQUFVLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFFOUUsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFDLGtCQUFrQixDQUFDLHNCQUFzQixDQUFDLG1CQUFtQixFQUFFLGlCQUFpQixDQUFDLENBQUM7WUFFdkcsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7UUFDN0IsQ0FBQztLQUFBO0lBRUQ7Ozs7O09BS0c7SUFDSCx5QkFBeUI7UUFDdkIsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxzQkFBc0IsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBQzNFLENBQUM7SUFFSyxXQUFXLENBQUMsaUJBQW9DLEVBQUUsZUFBd0I7O1lBQzlFLGlCQUFpQixHQUFHLE1BQU0sSUFBSSxDQUFDLGFBQWEsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1lBRWhFLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxDQUFDLHVCQUF1QixDQUNwRCx3QkFBd0IsQ0FBQyxJQUFJLEVBQzdCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsZUFBZSxDQUNoQixDQUFDO1lBRUYsTUFBTSxJQUFJLENBQUMsd0JBQXdCLENBQUMsaUJBQWlCLENBQUMsQ0FBQztZQUN2RCxPQUFPLGlCQUFpQixDQUFDLEVBQUUsQ0FBQztRQUM5QixDQUFDO0tBQUE7SUFFRCxnQkFBZ0I7UUFDZCxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxFQUFFLENBQUM7SUFDN0MsQ0FBQztJQUVELFVBQVU7UUFDUixJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNsQixJQUFJLENBQUMsUUFBUSxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLEdBQUcsVUFBVSxDQUFDLENBQUMsQ0FBQztTQUM5RTtRQUNELE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUN2QixDQUFDO0lBRUQsTUFBTSxDQUFDLFVBQWtCLEVBQUUsWUFBaUIsRUFBRSxlQUF3QjtRQUNwRSxNQUFNLGlCQUFpQixHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FDcEQsd0JBQXdCLENBQUMsTUFBTSxFQUMvQixZQUFZLEVBQ1osVUFBVSxFQUNWLGVBQWUsQ0FDaEIsQ0FBQztRQUNGLE9BQU8sSUFBSSxDQUFDLHdCQUF3QixDQUFDLGlCQUFpQixDQUFDLENBQUM7SUFDMUQsQ0FBQztJQUVELHVCQUF1QixDQUFDLG1CQUFtQjtRQUN6QyxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsbUJBQW1CLENBQUMsc0JBQXNCLENBQUMsbUJBQW1CLEVBQUUsSUFBSSxFQUFFLG1CQUFtQixDQUFDLENBQUM7SUFDbkgsQ0FBQztJQUVELE9BQU87UUFDTCxNQUFNLGVBQWUsR0FBRyxHQUFTLEVBQUU7WUFDakMsT0FBQSxJQUFJLENBQUMsa0JBQWtCLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFO2dCQUM5QyxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsb0JBQW9CLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBRTFELE9BQU8sT0FBTyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQztZQUNyQyxDQUFDLENBQUMsQ0FBQTtVQUFBLENBQUM7UUFFTCxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsZUFBZSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQy9ELENBQUM7SUFFSyxRQUFROztZQUNaLE1BQU0sZ0JBQWdCLEdBQUcsR0FBdUIsRUFBRTtnQkFDaEQsTUFBTSxXQUFXLEdBQUcsTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxzQkFBc0IsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO2dCQUVsRyxJQUFJLFdBQVcsRUFBRTtvQkFDZixNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsV0FBVyxDQUFDLENBQUM7aUJBQ3pDO2dCQUVELElBQUksSUFBSSxDQUFDLHlCQUF5QixJQUFJLENBQUMsV0FBVyxFQUFFO29CQUNsRCxJQUFJLENBQUMseUJBQXlCLEdBQUcsS0FBSyxDQUFDO29CQUN2QyxPQUFPLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztpQkFDMUI7Z0JBRUQsT0FBTyxnQkFBZ0IsRUFBRSxDQUFDO1lBQzVCLENBQUMsQ0FBQSxDQUFDO1lBRUYsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLGVBQWUsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBQ2hFLENBQUM7S0FBQTtJQUVELE1BQU0sQ0FBQyxVQUFrQixFQUFFLFdBQWdCLEVBQUUsZUFBd0I7UUFDbkUsTUFBTSxpQkFBaUIsR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQ3BELHdCQUF3QixDQUFDLE1BQU0sRUFDL0IsV0FBVyxFQUNYLFVBQVUsRUFDVixlQUFlLENBQ2hCLENBQUM7UUFDRixPQUFPLElBQUksQ0FBQyx3QkFBd0IsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0lBQzFELENBQUM7SUFFRCxtRUFBbUU7SUFDckQsYUFBYSxDQUFDLFdBQThCOztZQUN4RCxJQUFJLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLEdBQUcsV0FBVyxDQUFDO1lBRXpELElBQUksSUFBSSxZQUFZLElBQUksRUFBRTtnQkFDeEIsUUFBUSxHQUFHLE1BQU0sQ0FBQztnQkFDbEIsUUFBUSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7Z0JBQ3JCLFFBQVEsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDO2dCQUNyQixJQUFJLEdBQUcsTUFBTSxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7YUFDN0I7WUFFRCx1Q0FBWSxXQUFXLEtBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsUUFBUSxJQUFHO1FBQ2hFLENBQUM7S0FBQTtJQUVPLGNBQWMsQ0FBQyxNQUFvQixFQUFFLE9BQWUsRUFBRSxVQUFrQjtRQUM5RSxNQUFNLE1BQU0sR0FBRyxFQUFFLENBQUM7UUFDbEIsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLG9CQUFvQixFQUFFLElBQUksTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDdEYsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLGdCQUFnQixFQUFFLElBQUksVUFBVSxFQUFFLENBQUMsQ0FBQztRQUM3RSxPQUFPLEdBQUcsT0FBTyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztJQUMxQyxDQUFDO0lBRU8sbUJBQW1CLENBQUMsUUFBUSxFQUFFLFNBQVM7UUFDN0MsSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNiLE1BQU0sS0FBSyxHQUFHO2dCQUNaLE9BQU8sRUFBRSx3QkFBd0I7Z0JBQ2pDLFNBQVMsRUFBRSxTQUFTO2FBQ3JCLENBQUM7WUFFRixNQUFNLElBQUksNEJBQTRCLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDL0M7SUFDSCxDQUFDO0lBRU8sZUFBZSxDQUFDLGNBQWMsRUFBRSxXQUFXO1FBQ2pELElBQUksV0FBVyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLGlCQUFpQixFQUFFLENBQUMsRUFBRTtZQUM5RCxjQUFjLENBQUMsSUFBSSxHQUFHLENBQUMsR0FBRyxjQUFjLENBQUMsSUFBSSxFQUFFLEdBQUcsV0FBVyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLGlCQUFpQixFQUFFLENBQUMsQ0FBQyxDQUFDO1NBQy9HO1FBQ0QsT0FBTyxjQUFjLENBQUM7SUFDeEIsQ0FBQztJQUVPLHVCQUF1QixDQUM3QixTQUFtQyxFQUNuQyxPQUFnQyxFQUNoQyxVQUFtQixFQUNuQixlQUF3QixFQUN4QixFQUFXO1FBRVgsSUFBSSxDQUFDLFVBQVUsSUFBSSxTQUFTLEtBQUssd0JBQXdCLENBQUMsSUFBSSxFQUFFO1lBQzlELE1BQU0sSUFBSSxLQUFLLENBQUMsOEJBQThCLENBQUMsQ0FBQztTQUNqRDtRQUVELE9BQU87WUFDTCxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxFQUFFLENBQUMsT0FBTyxFQUFFO1lBQ2xDLFFBQVEsRUFBRSxJQUFJLElBQUksRUFBRSxDQUFDLE9BQU8sRUFBRTtZQUM5QixNQUFNLEVBQUUsVUFBVTtZQUNsQixTQUFTLEVBQUUsU0FBUztZQUNwQixNQUFNLEVBQUUsT0FBTztZQUNmLGVBQWUsRUFBRSxlQUFlO1NBQ2pDLENBQUM7SUFDSixDQUFDO0lBRU8sdUJBQXVCLENBQzdCLFVBQWtCLEVBQ2xCLFNBQTRDO1FBRTVDLE9BQU8sU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFNBQVMsRUFBRSxLQUFLLEVBQUUsRUFBRTtZQUN4QyxNQUFNLEVBQUUsR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDLE9BQU8sRUFBRSxHQUFHLEtBQUssQ0FBQztZQUV4QyxPQUFPLElBQUksQ0FBQyx1QkFBdUIsQ0FDakMsU0FBUyxDQUFDLFNBQVMsRUFDbkIsU0FBUyxDQUFDLE1BQU0sRUFDaEIsVUFBVSxFQUNWLFNBQVMsQ0FBQyxlQUFlLEVBQ3pCLEVBQUUsQ0FDSCxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU8sc0JBQXNCLENBQUMsVUFBVTtRQUN2QyxJQUFJLENBQUMsaUJBQWlCLENBQUMsVUFBVSxDQUFDLEdBQUc7WUFDbkMsSUFBSSxFQUFFLFNBQVM7WUFDZixjQUFjLEVBQUUsU0FBUztZQUN6QixZQUFZLEVBQUUsU0FBUztTQUN4QixDQUFDO0lBQ0osQ0FBQztJQUVhLGVBQWUsQ0FBQyxpQkFBc0M7O1lBQ2xFLElBQUk7Z0JBQ0YsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUUzRSxNQUFNLFFBQVEsR0FBRyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDO2dCQUMxRCxJQUFJLENBQUMsbUJBQW1CLENBQUMsUUFBUSxFQUFFLHdCQUF3QixDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUVwRSxNQUFNLEdBQUcsR0FBRyxzQkFBc0IsQ0FBQyxNQUFNLENBQUMsaUJBQWlCLEVBQUUsTUFBTSxFQUFFLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDM0YsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsRUFBRSxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFFMUUsTUFBTSxJQUFJLENBQUMsNEJBQTRCLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO2dCQUU1RSxPQUFPLE1BQU0sSUFBSSxDQUFDLG1CQUFtQixDQUFDLGlCQUFpQixFQUFFLFFBQVEsQ0FBQyxDQUFDO2FBQ3BFO1lBQUMsT0FBTyxhQUFhLEVBQUU7Z0JBQ3RCLE9BQU8sSUFBSSxDQUFDLG1CQUFtQixDQUFDLGlCQUFpQixFQUFFLGFBQWEsRUFBRSxJQUFJLENBQUMsQ0FBQzthQUN6RTtRQUNILENBQUM7S0FBQTtJQUVPLGVBQWUsQ0FBQyxjQUFjO1FBQ3BDLE9BQU8sSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsY0FBYyxDQUFDLENBQUM7SUFDL0MsQ0FBQztJQUVPLGNBQWMsQ0FBQyxVQUFVLEVBQUUsUUFBUTtRQUN6QyxNQUFNLGdCQUFnQixHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFFdEUsTUFBTSxnQkFBZ0IsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUM7UUFFekQsSUFBSSxDQUFDLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxHQUFHLGdCQUFnQixDQUFDO1FBQ3RFLE9BQU8sUUFBUSxDQUFDLElBQUksQ0FBQztJQUN2QixDQUFDO0lBRWEsb0JBQW9CLENBQUMsTUFBb0IsRUFBRSxPQUFlOztZQUN0RSxNQUFNLHFCQUFxQixHQUFHLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxDQUFDO1lBQ2hFLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUV0RSxNQUFNLGNBQWMsR0FBRyxNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDO2lCQUN2RCxJQUFJLENBQ0gsR0FBRyxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDLEVBQzNELE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDLEVBQzlELE1BQU0sQ0FDSixDQUFDLGNBQWMsRUFBRSxXQUFXLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsY0FBYyxFQUFFLFdBQVcsQ0FBQyxFQUNsRixxQkFBcUIsQ0FDdEIsQ0FDRjtpQkFDQSxTQUFTLEVBQUUsQ0FBQztZQUVmLE9BQU8sY0FBYyxDQUFDLElBQUksQ0FBQztRQUM3QixDQUFDO0tBQUE7SUFFYSxhQUFhLENBQUMsaUJBQXNDOztZQUNoRSxJQUFJO2dCQUNGLE1BQU0sV0FBVyxHQUFzQixNQUFNLElBQUksQ0FBQyx1QkFBdUIsQ0FDdkUsaUJBQWlCLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFDNUIsaUJBQWlCLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFDL0IsaUJBQWlCLENBQUMsTUFBTSxFQUN4QixpQkFBaUIsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUNqQyxDQUFDO2dCQUNGLE1BQU0sUUFBUSxHQUFHLE1BQU0sSUFBSSxDQUFDLFlBQVksQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQ2hGLE1BQU0scUJBQXFCLEdBQW1CO29CQUM1QyxFQUFFLEVBQUUsaUJBQWlCLENBQUMsRUFBRTtvQkFDeEIsZUFBZSxFQUFFLGlCQUFpQixDQUFDLGVBQWU7b0JBQ2xELE9BQU8sRUFBRSxpQkFBaUIsQ0FBQyxNQUFNO29CQUNqQyxRQUFRLEVBQUUsUUFBUTtpQkFDbkIsQ0FBQztnQkFFRixJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO2dCQUVqRCxPQUFPLElBQUksQ0FBQyw0QkFBNEIsQ0FBQyxRQUFRLENBQUMsTUFBTSxFQUFFLGlCQUFpQixDQUFDLENBQUM7YUFDOUU7WUFBQyxPQUFPLGVBQWUsRUFBRTtnQkFDeEIsT0FBTyxJQUFJLENBQUMsbUJBQW1CLENBQUMsaUJBQWlCLEVBQUUsZUFBZSxFQUFFLElBQUksQ0FBQyxDQUFDO2FBQzNFO1FBQ0gsQ0FBQztLQUFBO0lBRWEsd0JBQXdCLENBQUMsaUJBQWlCOztZQUN0RCxNQUFNLHlCQUF5QixHQUFHLE1BQU0sSUFBSSxDQUFDLFNBQVMsQ0FBQyxpQkFBaUIsQ0FDdEUsc0JBQXNCLENBQUMsbUJBQW1CLEVBQzFDLGlCQUFpQixDQUNsQixDQUFDO1lBRUYsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7WUFFM0IsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDLHlCQUF5QixDQUFDLENBQUM7UUFDcEQsQ0FBQztLQUFBO0lBRWEsZUFBZSxDQUFDLHdCQUE2Qzs7WUFDekUsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLHdCQUF3QixDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQ2xGLE1BQU0sR0FBRyxHQUFHLHNCQUFzQixDQUFDLE1BQU0sQ0FBQyx3QkFBd0IsRUFBRSxNQUFNLEVBQUUsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBRWhHLElBQUk7Z0JBQ0YsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsRUFBRSxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsd0JBQXdCLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQ3pHLE1BQU0scUJBQXFCLEdBQUcsUUFBUSxDQUFDLElBQUksQ0FBQztnQkFFNUMsTUFBTSxJQUFJLENBQUMsNEJBQTRCLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSx3QkFBd0IsQ0FBQyxDQUFDO2dCQUVuRixNQUFNLEVBQUUsR0FBRyx3QkFBd0IsQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLHVCQUF1QixDQUFDLENBQUM7Z0JBQ2pGLE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLHFCQUFxQixFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUVyRSxNQUFNLGtCQUFrQixHQUErQixNQUFNLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUM3RSxzQkFBc0IsQ0FBQyxtQkFBbUIsQ0FDM0MsQ0FBQztnQkFDRixNQUFNLElBQUksQ0FBQywwQkFBMEIsQ0FDbkMsd0JBQXdCLEVBQ3hCLE1BQU0sQ0FBQyxPQUFPLEVBQ2QscUJBQXFCLEVBQ3JCLGtCQUFrQixDQUNuQixDQUFDO2dCQUVGLE9BQU8sSUFBSSxDQUFDLG1CQUFtQixDQUFDLHdCQUF3QixFQUFFLFFBQVEsQ0FBQyxDQUFDO2FBQ3JFO1lBQUMsT0FBTyxlQUFlLEVBQUU7Z0JBQ3hCLE9BQU8sSUFBSSxDQUFDLG1CQUFtQixDQUFDLHdCQUF3QixFQUFFLGVBQWUsRUFBRSxJQUFJLENBQUMsQ0FBQzthQUNsRjtRQUNILENBQUM7S0FBQTtJQUVPLGFBQWEsQ0FBQyxNQUFjO1FBQ2xDLE9BQU8sc0JBQXNCLENBQUMsdUJBQXVCLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3pFLENBQUM7SUFFTyxtQkFBbUI7UUFDekIsSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFO1lBQ2hCLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUM7U0FDckI7SUFDSCxDQUFDO0lBRU8sa0JBQWtCLENBQUMsSUFBSSxFQUFFLE1BQU0sRUFBRSxPQUFPO1FBQzlDLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUUxQyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQ3ZDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUN6RSxNQUFNLEVBQ04sT0FBTyxFQUNQLEVBQUUsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FDOUMsQ0FBQztZQUVGLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQ3JGLEdBQUcsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQyxDQUM1RCxDQUFDO1NBQ0g7UUFFRCxPQUFPLEVBQUUsRUFBRSxDQUFDO0lBQ2QsQ0FBQztJQUVPLDRCQUE0QixDQUNsQyxNQUFNLEVBQ04saUJBQXNDO1FBRXRDLElBQUksSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsSUFBSSxpQkFBaUIsQ0FBQyxTQUFTLEtBQUssd0JBQXdCLENBQUMsSUFBSSxFQUFFO1lBQy9GLE9BQU8sSUFBSSxDQUFDLHVCQUF1QixDQUFDLGlCQUFpQixDQUFDLEVBQUUsQ0FBQyxDQUFDO1NBQzNEO0lBQ0gsQ0FBQztJQUVPLGVBQWUsQ0FBQyxpQkFBc0M7UUFDNUQsUUFBUSxpQkFBaUIsQ0FBQyxTQUFTLEVBQUU7WUFDbkMsS0FBSyx3QkFBd0IsQ0FBQyxNQUFNO2dCQUNsQyxPQUFPLElBQUksQ0FBQyxlQUFlLENBQUMsaUJBQWlCLENBQUMsQ0FBQztZQUVqRCxLQUFLLHdCQUF3QixDQUFDLE1BQU07Z0JBQ2xDLE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1lBRWpELEtBQUssd0JBQXdCLENBQUMsTUFBTTtnQkFDbEMsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDLGlCQUFpQixDQUFDLENBQUM7WUFFakQsS0FBSyx3QkFBd0IsQ0FBQyxJQUFJO2dCQUNoQyxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsaUJBQWlCLENBQUMsQ0FBQztTQUNoRDtJQUNILENBQUM7SUFFTyxtQkFBbUIsQ0FDekIsaUJBQXNDLEVBQ3RDLFFBQWlGLEVBQ2pGLGlCQUEwQixLQUFLO1FBRS9CLE1BQU0sY0FBYyxHQUFtQjtZQUNyQyxFQUFFLEVBQUUsaUJBQWlCLENBQUMsRUFBRTtZQUN4QixlQUFlLEVBQUUsaUJBQWlCLENBQUMsZUFBZTtZQUNsRCxPQUFPLEVBQUUsaUJBQWlCLENBQUMsTUFBTTtZQUNqQyxRQUFRLEVBQUUsUUFBUTtTQUNuQixDQUFDO1FBRUYsSUFBSSxDQUFDLHlCQUF5QixHQUFHLGNBQWMsQ0FBQztRQUNoRCxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQztRQUUxQyxPQUFPLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRWEsY0FBYyxDQUFDLEdBQVcsRUFBRSxNQUF5QixFQUFFLElBQW9DOztZQUN2RyxNQUFNLFdBQVcsR0FBc0IsTUFBTSxJQUFJLENBQUMsdUJBQXVCLENBQUMsR0FBRyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQztZQUU3RixPQUFPLElBQUksQ0FBQyxZQUFZLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUFDO1FBQ2xFLENBQUM7S0FBQTtJQUVhLHVCQUF1QixDQUNuQyxHQUFXLEVBQ1gsTUFBeUIsRUFDekIsTUFBc0MsRUFDdEMsT0FBbUM7OztZQUVuQyxJQUFJLElBQUksR0FBRyxNQUFBLE1BQU0sQ0FBQyxJQUFJLG1DQUFJLE1BQU0sQ0FBQztZQUVqQyxJQUFJLE1BQU0sQ0FBQyxRQUFRLEtBQUssTUFBTSxFQUFFO2dCQUM5QixJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDO2FBQzVGO1lBRUQsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxDQUFDOztLQUN2QztJQUVhLGNBQWMsQ0FDMUIsSUFBWSxFQUNaLFFBQWdCLEVBQ2hCLFFBQWdCLEVBQ2hCLFlBQW9CLE1BQU07O1lBRTFCLE1BQU0sSUFBSSxHQUFHLE1BQU0sTUFBTSxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFDcEQsTUFBTSxRQUFRLEdBQWEsSUFBSSxRQUFRLEVBQUUsQ0FBQztZQUUxQyxRQUFRLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFDM0MsT0FBTyxRQUFRLENBQUM7UUFDbEIsQ0FBQztLQUFBO0lBRWEsZUFBZSxDQUFDLGlCQUFzQzs7WUFDbEUsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsa0JBQWtCLENBQUMsR0FBRyxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzNFLE1BQU0sR0FBRyxHQUFHLHNCQUFzQixDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsRUFBRSxNQUFNLEVBQUUsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBRTFGLElBQUk7Z0JBQ0YsTUFBTSxRQUFRLEdBQUcsaUJBQWlCLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFDMUQsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFFBQVEsRUFBRSx3QkFBd0IsQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFFcEUsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsY0FBYyxDQUFDLEdBQUcsRUFBRSxpQkFBaUIsQ0FBQyxHQUFHLEVBQUUsaUJBQWlCLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQ2pHLE1BQU0sSUFBSSxDQUFDLDRCQUE0QixDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztnQkFFNUUsT0FBTyxNQUFNLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxpQkFBaUIsRUFBRSxRQUFRLENBQUMsQ0FBQzthQUNwRTtZQUFDLE9BQU8sZUFBZSxFQUFFO2dCQUN4QixPQUFPLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxpQkFBaUIsRUFBRSxlQUFlLEVBQUUsSUFBSSxDQUFDLENBQUM7YUFDM0U7UUFDSCxDQUFDO0tBQUE7SUFFTywwQkFBMEIsQ0FDaEMsd0JBQTZDLEVBQzdDLGFBQXFCLEVBQ3JCLFFBQWdCLEVBQ2hCLGtCQUE4QztRQUU5QyxJQUFJLHdCQUF3QixDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsdUJBQXVCLENBQUMsRUFBRTtZQUN6RSxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxpQkFBaUIsRUFBRSxRQUFRLEVBQUUsRUFBRTtnQkFDekQsTUFBTSwwQkFBMEIsR0FDOUIsQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDO29CQUN4QyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLHVCQUF1QixDQUFDO3dCQUM1RCx3QkFBd0IsQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLHVCQUF1QixDQUFDLENBQUM7Z0JBRTFFLElBQUksMEJBQTBCLEVBQUU7b0JBQzlCLGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsR0FBRyxRQUFRLENBQUMsYUFBYSxDQUFDLENBQUM7aUJBQzlFO1lBQ0gsQ0FBQyxDQUFDLENBQUM7WUFFSCxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLHNCQUFzQixDQUFDLG1CQUFtQixFQUFFLGtCQUFrQixDQUFDLENBQUM7U0FDM0Y7YUFBTTtZQUNMLE9BQU8sT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO1NBQzFCO0lBQ0gsQ0FBQztJQUVhLGFBQWEsQ0FBQyxhQUF5QixFQUFFLE1BQW9COztZQUN6RSxLQUFLLE1BQU0sWUFBWSxJQUFJLGFBQWEsRUFBRTtnQkFDeEMsTUFBTSxJQUFJLENBQUMsMEJBQTBCLENBQUMsWUFBWSxFQUFFLE1BQU0sQ0FBQyxDQUFDO2FBQzdEO1FBQ0gsQ0FBQztLQUFBO0lBRWEsMEJBQTBCLENBQUMsWUFBWSxFQUFFLE1BQU07O1lBQzNELE1BQU0sUUFBUSxHQUFHLFlBQVksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDOUMsTUFBTSxhQUFhLEdBQUcsTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQzVFLE1BQU0sbUJBQW1CLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsTUFBTSxDQUFDO1lBRWhFLElBQUksbUJBQW1CLElBQUksWUFBWSxDQUFDLE1BQU0sQ0FBQyxZQUFZLENBQUMsRUFBRTtnQkFDNUQsT0FBTyxNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsWUFBWSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO2FBQ3JGO1lBRUQsSUFBSSxtQkFBbUIsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLEVBQUU7Z0JBQzdELE9BQU8sTUFBTSxJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsWUFBWSxDQUFDLENBQUM7YUFDaEU7WUFFRCxJQUFJLENBQUMsbUJBQW1CLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxFQUFFO2dCQUM5RCxPQUFPLE1BQU0sSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLFlBQVksQ0FBQyxDQUFDO2FBQ2hFO1FBQ0gsQ0FBQztLQUFBO0lBRWEscUJBQXFCLENBQUMsTUFBb0I7O1lBQ3RELElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUM7WUFFekMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDaEQsTUFBTSxPQUFPLEdBQUcsR0FBRyxZQUFZLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxhQUFhLENBQUMsSUFBSSxDQUFDLElBQUksTUFBTSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ3hGLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUN6RSxNQUFNLEVBQ04sT0FBTyxFQUNQLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQzVDLENBQUM7WUFFRixNQUFNLGFBQWEsR0FBRyxNQUFNLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFFdkUsTUFBTSxJQUFJLENBQUMsYUFBYSxDQUFDLGFBQWEsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUVoRCxNQUFNLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsY0FBYyxDQUFDLENBQUM7WUFDdEUsTUFBTSxJQUFJLENBQUMsa0JBQWtCLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQy9DLENBQUM7S0FBQTtJQUVPLG9CQUFvQixDQUFDLE9BQU87UUFDbEMsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBb0IsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFDbkYsQ0FBQzs7QUE5aEJlLDBDQUFtQixHQUFXLGVBQWUsQ0FBQztBQUV0Qyw4Q0FBdUIsR0FBRztJQUNoRCxVQUFVLENBQUMsRUFBRTtJQUNiLFVBQVUsQ0FBQyxPQUFPO0lBQ2xCLFVBQVUsQ0FBQyxRQUFRO0lBQ25CLFVBQVUsQ0FBQyw2QkFBNkI7SUFDeEMsVUFBVSxDQUFDLFVBQVU7SUFDckIsVUFBVSxDQUFDLGFBQWE7SUFDeEIsVUFBVSxDQUFDLGVBQWU7SUFDMUIsVUFBVSxDQUFDLFlBQVksQ0FBQyxNQUFNO0NBQy9CLENBQUM7O1lBYkgsVUFBVTs7O1lBUEYseUJBQXlCO1lBQ3pCLGVBQWU7WUFkZixnQkFBZ0I7WUFTaEIsbUJBQW1CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSHR0cFJlc3BvbnNlLCBIdHRwRXJyb3JSZXNwb25zZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0ICogYXMgSHR0cFN0YXR1cyBmcm9tICdodHRwLXN0YXR1cy1jb2Rlcyc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBvZiwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZXhwYW5kLCBtYXAsIHJlZHVjZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgUG9TdG9yYWdlU2VydmljZSB9IGZyb20gJ0Bwby11aS9uZy1zdG9yYWdlJztcblxuaW1wb3J0IHsgdG9CYXNlNjQsIHRvRmlsZSB9IGZyb20gJy4uLy4uL3V0aWxzL3V0aWxzJztcblxuaW1wb3J0IHsgUG9FdmVudFNvdXJjaW5nRXJyb3JSZXNwb25zZSB9IGZyb20gJy4uLy4uL21vZGVscy9wby1ldmVudC1zb3VyY2luZy1lcnJvci1yZXNwb25zZS5tb2RlbCc7XG5pbXBvcnQgeyBQb0V2ZW50U291cmNpbmdJdGVtIH0gZnJvbSAnLi9pbnRlcmZhY2VzL3BvLWV2ZW50LXNvdXJjaW5nLWl0ZW0uaW50ZXJmYWNlJztcbmltcG9ydCB7IFBvRXZlbnRTb3VyY2luZ09wZXJhdGlvbiB9IGZyb20gJy4vZW51bXMvcG8tZXZlbnQtc291cmNpbmctb3BlcmF0aW9uLmVudW0nO1xuaW1wb3J0IHsgUG9FdmVudFNvdXJjaW5nU3VtbWFyeUl0ZW0gfSBmcm9tICcuL2ludGVyZmFjZXMvcG8tZXZlbnQtc291cmNpbmctc3VtbWFyeS1pdGVtLmludGVyZmFjZSc7XG5pbXBvcnQgeyBQb0h0dHBIZWFkZXJPcHRpb24gfSBmcm9tICcuLy4uL3BvLWh0dHAtY2xpZW50L2ludGVyZmFjZXMvcG8taHR0cC1oZWFkZXItb3B0aW9uLmludGVyZmFjZSc7XG5pbXBvcnQgeyBQb0h0dHBDbGllbnRTZXJ2aWNlIH0gZnJvbSAnLi8uLi9wby1odHRwLWNsaWVudC9wby1odHRwLWNsaWVudC5zZXJ2aWNlJztcbmltcG9ydCB7IFBvSHR0cFJlcXVlc3REYXRhIH0gZnJvbSAnLi4vcG8taHR0cC1jbGllbnQvaW50ZXJmYWNlcy9wby1odHRwLXJlcXVlc3QtZGF0YS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgUG9IdHRwUmVxdWVzdFR5cGUgfSBmcm9tICcuLi9wby1odHRwLWNsaWVudC9wby1odHRwLXJlcXVlc3QtdHlwZS5lbnVtJztcbmltcG9ydCB7IFBvUmVxdWVzdFR5cGUgfSBmcm9tICcuLi8uLi9tb2RlbHMvcG8tcmVxdWVzdC10eXBlLmVudW0nO1xuaW1wb3J0IHsgUG9TY2hlbWFEZWZpbml0aW9uU2VydmljZSB9IGZyb20gJy4vLi4vcG8tc2NoZW1hL3BvLXNjaGVtYS1kZWZpbml0aW9uL3BvLXNjaGVtYS1kZWZpbml0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHsgUG9TY2hlbWFTZXJ2aWNlIH0gZnJvbSAnLi8uLi9wby1zY2hlbWEvcG8tc2NoZW1hLnNlcnZpY2UnO1xuaW1wb3J0IHsgUG9TY2hlbWFVdGlsIH0gZnJvbSAnLi8uLi9wby1zY2hlbWEvcG8tc2NoZW1hLXV0aWwvcG8tc2NoZW1hLXV0aWwubW9kZWwnO1xuaW1wb3J0IHsgUG9TeW5jQ29uZmlnIH0gZnJvbSAnLi4vcG8tc3luYy9pbnRlcmZhY2VzL3BvLXN5bmMtY29uZmlnLmludGVyZmFjZSc7XG5pbXBvcnQgeyBQb1N5bmNSZXNwb25zZSB9IGZyb20gJy4uL3BvLXN5bmMvaW50ZXJmYWNlcy9wby1zeW5jLXJlc3BvbnNlLmludGVyZmFjZSc7XG5pbXBvcnQgeyBQb1N5bmNTY2hlbWEgfSBmcm9tICcuLy4uL3BvLXN5bmMvaW50ZXJmYWNlcy9wby1zeW5jLXNjaGVtYS5pbnRlcmZhY2UnO1xuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgUG9FdmVudFNvdXJjaW5nU2VydmljZSB7XG4gIHN0YXRpYyByZWFkb25seSBldmVudF9zb3VyY2luZ19uYW1lOiBzdHJpbmcgPSAnRXZlbnRTb3VyY2luZyc7XG5cbiAgcHJpdmF0ZSBzdGF0aWMgcmVhZG9ubHkgVkFMSURfSFRUUF9TVEFUVVNfQ09ERVMgPSBbXG4gICAgSHR0cFN0YXR1cy5PSywgLy8gMjAwXG4gICAgSHR0cFN0YXR1cy5DUkVBVEVELCAvLyAyMDFcbiAgICBIdHRwU3RhdHVzLkFDQ0VQVEVELCAvLyAyMDJcbiAgICBIdHRwU3RhdHVzLk5PTl9BVVRIT1JJVEFUSVZFX0lORk9STUFUSU9OLCAvLyAyMDNcbiAgICBIdHRwU3RhdHVzLk5PX0NPTlRFTlQsIC8vIDIwNFxuICAgIEh0dHBTdGF0dXMuUkVTRVRfQ09OVEVOVCwgLy8gMjA1XG4gICAgSHR0cFN0YXR1cy5QQVJUSUFMX0NPTlRFTlQsIC8vIDIwNlxuICAgIEh0dHBTdGF0dXMuTVVMVElfU1RBVFVTIC8vIDIwN1xuICBdO1xuXG4gIGNvbmZpZzogUG9TeW5jQ29uZmlnO1xuICBzdG9wcGVkUXVldWVFdmVudFNvdXJjaW5nOiBib29sZWFuID0gZmFsc2U7XG5cbiAgcHJpdmF0ZSBlbWl0dGVyOiBhbnk7XG4gIHByaXZhdGUgZXZlbnRTdWI6IE9ic2VydmFibGU8bnVsbD47XG4gIHByaXZhdGUgcmVzcG9uc2VTdWJqZWN0ID0gbmV3IFN1YmplY3Q8UG9TeW5jUmVzcG9uc2U+KCk7XG5cbiAgcHJpdmF0ZSBzY2hlbWFzU3luY0NvbmZpZyA9IHt9O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcG9TY2hlbWFEZWZpbml0aW9uOiBQb1NjaGVtYURlZmluaXRpb25TZXJ2aWNlLFxuICAgIHByaXZhdGUgcG9TY2hlbWFTZXJ2aWNlOiBQb1NjaGVtYVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBwb1N0b3JhZ2U6IFBvU3RvcmFnZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBwb0h0dHBDbGllbnQ6IFBvSHR0cENsaWVudFNlcnZpY2VcbiAgKSB7fVxuXG4gIHByaXZhdGUgc3RhdGljIGdldFVybChldmVudFNvdXJjaW5nSXRlbSwgc2NoZW1hLCByZXF1ZXN0VHlwZSk6IHN0cmluZyB7XG4gICAgY29uc3Qgc2NoZW1hVXJsID0gUG9TY2hlbWFVdGlsLmdldFVybChzY2hlbWEsIHJlcXVlc3RUeXBlKTtcbiAgICBjb25zdCBzY2hlbWFJZCA9IGV2ZW50U291cmNpbmdJdGVtLnJlY29yZFtzY2hlbWEuaWRGaWVsZF07XG5cbiAgICBpZiAocmVxdWVzdFR5cGUgPT09IFBvUmVxdWVzdFR5cGUuR0VUKSB7XG4gICAgICByZXR1cm4gc2NoZW1hVXJsO1xuICAgIH1cblxuICAgIGlmIChbUG9SZXF1ZXN0VHlwZS5ERUxFVEUsIFBvUmVxdWVzdFR5cGUuUEFUQ0hdLmluY2x1ZGVzKHJlcXVlc3RUeXBlKSkge1xuICAgICAgcmV0dXJuIHNjaGVtYVVybCA/IGAke3NjaGVtYVVybH0vJHtzY2hlbWFJZH1gIDogYCR7UG9TY2hlbWFVdGlsLmdldFVybChzY2hlbWEsIFBvUmVxdWVzdFR5cGUuR0VUKX0vJHtzY2hlbWFJZH1gO1xuICAgIH1cblxuICAgIGlmIChyZXF1ZXN0VHlwZSA9PT0gUG9SZXF1ZXN0VHlwZS5QT1NUKSB7XG4gICAgICByZXR1cm4gc2NoZW1hVXJsID8gc2NoZW1hVXJsIDogUG9TY2hlbWFVdGlsLmdldFVybChzY2hlbWEsIFBvUmVxdWVzdFR5cGUuR0VUKTtcbiAgICB9XG4gIH1cblxuICBjcmVhdGUoc2NoZW1hTmFtZTogc3RyaW5nLCBuZXdJdGVtOiBhbnksIGN1c3RvbVJlcXVlc3RJZD86IHN0cmluZyk6IFByb21pc2U8YW55PiB7XG4gICAgY29uc3QgZXZlbnRTb3VyY2luZ0l0ZW0gPSB0aGlzLmNyZWF0ZUV2ZW50U291cmNpbmdJdGVtKFxuICAgICAgUG9FdmVudFNvdXJjaW5nT3BlcmF0aW9uLkluc2VydCxcbiAgICAgIG5ld0l0ZW0sXG4gICAgICBzY2hlbWFOYW1lLFxuICAgICAgY3VzdG9tUmVxdWVzdElkXG4gICAgKTtcbiAgICByZXR1cm4gdGhpcy5pbnNlcnRFdmVudFNvdXJjaW5nUXVldWUoZXZlbnRTb3VyY2luZ0l0ZW0pO1xuICB9XG5cbiAgYXN5bmMgY3JlYXRlQmF0Y2hFdmVudHMoc2NoZW1hTmFtZTogc3RyaW5nLCBldmVudExpc3Q6IEFycmF5PFBvRXZlbnRTb3VyY2luZ1N1bW1hcnlJdGVtPikge1xuICAgIGNvbnN0IGV2ZW50U291cmNpbmdMaXN0ID0gdGhpcy5jcmVhdGVFdmVudFNvdXJjaW5nTGlzdChzY2hlbWFOYW1lLCBldmVudExpc3QpO1xuXG4gICAgYXdhaXQgdGhpcy5wb1N0b3JhZ2UuYXBwZW5kQXJyYXlUb0FycmF5KFBvRXZlbnRTb3VyY2luZ1NlcnZpY2UuZXZlbnRfc291cmNpbmdfbmFtZSwgZXZlbnRTb3VyY2luZ0xpc3QpO1xuXG4gICAgdGhpcy5ub3RpZnlFdmVudENyZWF0aW9uKCk7XG4gIH1cblxuICAvKipcbiAgICogRGVzdHLDs2kgYSBjaGF2ZSBkbyAqc3RvcmFnZSogcXVlIGNvbnTDqW0gYSBmaWxhIGRlIGRhZG9zIHF1ZSBlc3TDo28gZXNwZXJhbmRvIHBhcmEgc2VyZW0gZW52aWFkb3MgYW9cbiAgICogc2Vydmlkb3IgKihFdmVudFNvdXJjaW5nKSouXG4gICAqXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSBQcm9tZXNzYSBxdWUgw6kgcmVzb2x2aWRhIHF1YW5kbyBhIGNoYXZlIHJlZmVyZW50ZSBhIGZpbGEgZGUgKkV2ZW50U291cmNpbmcqIGZvciBkZXN0cnXDrWRhLlxuICAgKi9cbiAgZGVzdHJveUV2ZW50U291cmNpbmdRdWV1ZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5wb1N0b3JhZ2UucmVtb3ZlKFBvRXZlbnRTb3VyY2luZ1NlcnZpY2UuZXZlbnRfc291cmNpbmdfbmFtZSk7XG4gIH1cblxuICBhc3luYyBodHRwQ29tbWFuZChodHRwT3BlcmF0aW9uRGF0YTogUG9IdHRwUmVxdWVzdERhdGEsIGN1c3RvbVJlcXVlc3RJZD86IHN0cmluZyk6IFByb21pc2U8bnVtYmVyPiB7XG4gICAgaHR0cE9wZXJhdGlvbkRhdGEgPSBhd2FpdCB0aGlzLnNlcmlhbGl6ZUJvZHkoaHR0cE9wZXJhdGlvbkRhdGEpO1xuXG4gICAgY29uc3QgZXZlbnRTb3VyY2luZ0l0ZW0gPSB0aGlzLmNyZWF0ZUV2ZW50U291cmNpbmdJdGVtKFxuICAgICAgUG9FdmVudFNvdXJjaW5nT3BlcmF0aW9uLkh0dHAsXG4gICAgICBodHRwT3BlcmF0aW9uRGF0YSxcbiAgICAgIHVuZGVmaW5lZCxcbiAgICAgIGN1c3RvbVJlcXVlc3RJZFxuICAgICk7XG5cbiAgICBhd2FpdCB0aGlzLmluc2VydEV2ZW50U291cmNpbmdRdWV1ZShldmVudFNvdXJjaW5nSXRlbSk7XG4gICAgcmV0dXJuIGV2ZW50U291cmNpbmdJdGVtLmlkO1xuICB9XG5cbiAgcmVzcG9uc2VzU3ViamVjdCgpOiBPYnNlcnZhYmxlPFBvU3luY1Jlc3BvbnNlPiB7XG4gICAgcmV0dXJuIHRoaXMucmVzcG9uc2VTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICB9XG5cbiAgb25TYXZlRGF0YSgpOiBPYnNlcnZhYmxlPG51bGw+IHtcbiAgICBpZiAoIXRoaXMuZXZlbnRTdWIpIHtcbiAgICAgIHRoaXMuZXZlbnRTdWIgPSBPYnNlcnZhYmxlLmNyZWF0ZShzdWJzY3JpYmVyID0+ICh0aGlzLmVtaXR0ZXIgPSBzdWJzY3JpYmVyKSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmV2ZW50U3ViO1xuICB9XG5cbiAgcmVtb3ZlKHNjaGVtYU5hbWU6IHN0cmluZywgaXRlbVRvRGVsZXRlOiBhbnksIGN1c3RvbVJlcXVlc3RJZD86IHN0cmluZyk6IFByb21pc2U8YW55PiB7XG4gICAgY29uc3QgZXZlbnRTb3VyY2luZ0l0ZW0gPSB0aGlzLmNyZWF0ZUV2ZW50U291cmNpbmdJdGVtKFxuICAgICAgUG9FdmVudFNvdXJjaW5nT3BlcmF0aW9uLkRlbGV0ZSxcbiAgICAgIGl0ZW1Ub0RlbGV0ZSxcbiAgICAgIHNjaGVtYU5hbWUsXG4gICAgICBjdXN0b21SZXF1ZXN0SWRcbiAgICApO1xuICAgIHJldHVybiB0aGlzLmluc2VydEV2ZW50U291cmNpbmdRdWV1ZShldmVudFNvdXJjaW5nSXRlbSk7XG4gIH1cblxuICByZW1vdmVFdmVudFNvdXJjaW5nSXRlbShpZEV2ZW50U291cmNpbmdJdGVtKSB7XG4gICAgcmV0dXJuIHRoaXMucG9TdG9yYWdlLnJlbW92ZUl0ZW1Gcm9tQXJyYXkoUG9FdmVudFNvdXJjaW5nU2VydmljZS5ldmVudF9zb3VyY2luZ19uYW1lLCAnaWQnLCBpZEV2ZW50U291cmNpbmdJdGVtKTtcbiAgfVxuXG4gIHN5bmNHZXQoKTogUHJvbWlzZTxhbnk+IHtcbiAgICBjb25zdCBzeW5jR2V0RnVuY3Rpb24gPSBhc3luYyAoKSA9PlxuICAgICAgdGhpcy5wb1NjaGVtYURlZmluaXRpb24uZ2V0QWxsKCkudGhlbihzY2hlbWFzID0+IHtcbiAgICAgICAgY29uc3Qgc2NoZW1hUHJvbWlzZXMgPSB0aGlzLnVwZGF0ZVN0b3JhZ2VTY2hlbWFzKHNjaGVtYXMpO1xuXG4gICAgICAgIHJldHVybiBQcm9taXNlLmFsbChzY2hlbWFQcm9taXNlcyk7XG4gICAgICB9KTtcblxuICAgIHJldHVybiB0aGlzLnBvU2NoZW1hU2VydmljZS5saW1pdGVkQ2FsbFdyYXAoc3luY0dldEZ1bmN0aW9uKTtcbiAgfVxuXG4gIGFzeW5jIHN5bmNTZW5kKCk6IFByb21pc2U8YW55PiB7XG4gICAgY29uc3Qgc3luY1NlbmRGdW5jdGlvbiA9IGFzeW5jICgpOiBQcm9taXNlPGFueT4gPT4ge1xuICAgICAgY29uc3QgaXRlbU9mUXVldWUgPSBhd2FpdCB0aGlzLnBvU3RvcmFnZS5nZXRGaXJzdEl0ZW0oUG9FdmVudFNvdXJjaW5nU2VydmljZS5ldmVudF9zb3VyY2luZ19uYW1lKTtcblxuICAgICAgaWYgKGl0ZW1PZlF1ZXVlKSB7XG4gICAgICAgIGF3YWl0IHRoaXMuc2VsZWN0T3BlcmF0aW9uKGl0ZW1PZlF1ZXVlKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRoaXMuc3RvcHBlZFF1ZXVlRXZlbnRTb3VyY2luZyB8fCAhaXRlbU9mUXVldWUpIHtcbiAgICAgICAgdGhpcy5zdG9wcGVkUXVldWVFdmVudFNvdXJjaW5nID0gZmFsc2U7XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHN5bmNTZW5kRnVuY3Rpb24oKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIHRoaXMucG9TY2hlbWFTZXJ2aWNlLmxpbWl0ZWRDYWxsV3JhcChzeW5jU2VuZEZ1bmN0aW9uKTtcbiAgfVxuXG4gIHVwZGF0ZShzY2hlbWFOYW1lOiBzdHJpbmcsIGl0ZW1VcGRhdGVkOiBhbnksIGN1c3RvbVJlcXVlc3RJZD86IHN0cmluZyk6IFByb21pc2U8YW55PiB7XG4gICAgY29uc3QgZXZlbnRTb3VyY2luZ0l0ZW0gPSB0aGlzLmNyZWF0ZUV2ZW50U291cmNpbmdJdGVtKFxuICAgICAgUG9FdmVudFNvdXJjaW5nT3BlcmF0aW9uLlVwZGF0ZSxcbiAgICAgIGl0ZW1VcGRhdGVkLFxuICAgICAgc2NoZW1hTmFtZSxcbiAgICAgIGN1c3RvbVJlcXVlc3RJZFxuICAgICk7XG4gICAgcmV0dXJuIHRoaXMuaW5zZXJ0RXZlbnRTb3VyY2luZ1F1ZXVlKGV2ZW50U291cmNpbmdJdGVtKTtcbiAgfVxuXG4gIC8qIEF2YWxpYSBzZSBvIGJvZHkgw6kgZG8gdGlwbyBGaWxlIGUgc2UgZm9yIGNvbnZlcnRlIHBhcmEgYmFzZTY0ICovXG4gIHByaXZhdGUgYXN5bmMgc2VyaWFsaXplQm9keShyZXF1ZXN0RGF0YTogUG9IdHRwUmVxdWVzdERhdGEpOiBQcm9taXNlPFBvSHR0cFJlcXVlc3REYXRhPiB7XG4gICAgbGV0IHsgYm9keSwgbWltZVR5cGUsIGJvZHlUeXBlLCBmaWxlTmFtZSB9ID0gcmVxdWVzdERhdGE7XG5cbiAgICBpZiAoYm9keSBpbnN0YW5jZW9mIEZpbGUpIHtcbiAgICAgIGJvZHlUeXBlID0gJ0ZpbGUnO1xuICAgICAgbWltZVR5cGUgPSBib2R5LnR5cGU7XG4gICAgICBmaWxlTmFtZSA9IGJvZHkubmFtZTtcbiAgICAgIGJvZHkgPSBhd2FpdCB0b0Jhc2U2NChib2R5KTtcbiAgICB9XG5cbiAgICByZXR1cm4geyAuLi5yZXF1ZXN0RGF0YSwgYm9keSwgbWltZVR5cGUsIGJvZHlUeXBlLCBmaWxlTmFtZSB9O1xuICB9XG5cbiAgcHJpdmF0ZSBidWlsZFVybFBhcmFtcyhzY2hlbWE6IFBvU3luY1NjaGVtYSwgYmFzZVVybDogc3RyaW5nLCBwYWdlTnVtYmVyOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIGNvbnN0IHBhcmFtcyA9IFtdO1xuICAgIHBhcmFtcy5wdXNoKGAke3RoaXMuY29uZmlnLmRhdGFUcmFuc2Zvcm0uZ2V0UGFnZVNpemVQYXJhbU5hbWUoKX09JHtzY2hlbWEucGFnZVNpemV9YCk7XG4gICAgcGFyYW1zLnB1c2goYCR7dGhpcy5jb25maWcuZGF0YVRyYW5zZm9ybS5nZXRQYWdlUGFyYW1OYW1lKCl9PSR7cGFnZU51bWJlcn1gKTtcbiAgICByZXR1cm4gYCR7YmFzZVVybH0/JHtwYXJhbXMuam9pbignJicpfWA7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrUmVjb3JkSWRFeGlzdHMocmVjb3JkSWQsIG9wZXJhdGlvbikge1xuICAgIGlmICghcmVjb3JkSWQpIHtcbiAgICAgIGNvbnN0IGVycm9yID0ge1xuICAgICAgICBtZXNzYWdlOiAnSWRlbnRpZmllciBub3QgZGVmaW5lZCcsXG4gICAgICAgIG9wZXJhdGlvbjogb3BlcmF0aW9uXG4gICAgICB9O1xuXG4gICAgICB0aHJvdyBuZXcgUG9FdmVudFNvdXJjaW5nRXJyb3JSZXNwb25zZShlcnJvcik7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjb25jYXRQYWdlSXRlbXMocGFnZUFjdW11bGF0b3IsIHJlcXVlc3RCb2R5KTogeyBlbnRpdHk6IHN0cmluZzsgZGF0YTogQXJyYXk8YW55PiB9IHtcbiAgICBpZiAocmVxdWVzdEJvZHlbdGhpcy5jb25maWcuZGF0YVRyYW5zZm9ybS5nZXRJdGVtc0ZpZWxkTmFtZSgpXSkge1xuICAgICAgcGFnZUFjdW11bGF0b3IuZGF0YSA9IFsuLi5wYWdlQWN1bXVsYXRvci5kYXRhLCAuLi5yZXF1ZXN0Qm9keVt0aGlzLmNvbmZpZy5kYXRhVHJhbnNmb3JtLmdldEl0ZW1zRmllbGROYW1lKCldXTtcbiAgICB9XG4gICAgcmV0dXJuIHBhZ2VBY3VtdWxhdG9yO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVFdmVudFNvdXJjaW5nSXRlbShcbiAgICBvcGVyYXRpb246IFBvRXZlbnRTb3VyY2luZ09wZXJhdGlvbixcbiAgICBuZXdJdGVtOiBhbnkgfCBQb0h0dHBSZXF1ZXN0RGF0YSxcbiAgICBzY2hlbWFOYW1lPzogc3RyaW5nLFxuICAgIGN1c3RvbVJlcXVlc3RJZD86IHN0cmluZyxcbiAgICBpZD86IG51bWJlclxuICApOiBQb0V2ZW50U291cmNpbmdJdGVtIHtcbiAgICBpZiAoIXNjaGVtYU5hbWUgJiYgb3BlcmF0aW9uICE9PSBQb0V2ZW50U291cmNpbmdPcGVyYXRpb24uSHR0cCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdQb1N5bmNTY2hlbWEgaXMgbm90IGRlZmluZWQuJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGlkOiBpZCA/IGlkIDogbmV3IERhdGUoKS5nZXRUaW1lKCksXG4gICAgICBkYXRlVGltZTogbmV3IERhdGUoKS5nZXRUaW1lKCksXG4gICAgICBzY2hlbWE6IHNjaGVtYU5hbWUsXG4gICAgICBvcGVyYXRpb246IG9wZXJhdGlvbixcbiAgICAgIHJlY29yZDogbmV3SXRlbSxcbiAgICAgIGN1c3RvbVJlcXVlc3RJZDogY3VzdG9tUmVxdWVzdElkXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlRXZlbnRTb3VyY2luZ0xpc3QoXG4gICAgc2NoZW1hTmFtZTogc3RyaW5nLFxuICAgIGV2ZW50TGlzdDogQXJyYXk8UG9FdmVudFNvdXJjaW5nU3VtbWFyeUl0ZW0+XG4gICk6IEFycmF5PFBvRXZlbnRTb3VyY2luZ0l0ZW0+IHtcbiAgICByZXR1cm4gZXZlbnRMaXN0Lm1hcCgoZXZlbnRJdGVtLCBpbmRleCkgPT4ge1xuICAgICAgY29uc3QgaWQgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKSArIGluZGV4O1xuXG4gICAgICByZXR1cm4gdGhpcy5jcmVhdGVFdmVudFNvdXJjaW5nSXRlbShcbiAgICAgICAgZXZlbnRJdGVtLm9wZXJhdGlvbixcbiAgICAgICAgZXZlbnRJdGVtLnJlY29yZCxcbiAgICAgICAgc2NoZW1hTmFtZSxcbiAgICAgICAgZXZlbnRJdGVtLmN1c3RvbVJlcXVlc3RJZCxcbiAgICAgICAgaWRcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZVNjaGVtYVN5bmNDb25maWcoc2NoZW1hTmFtZSkge1xuICAgIHRoaXMuc2NoZW1hc1N5bmNDb25maWdbc2NoZW1hTmFtZV0gPSB7XG4gICAgICBwYWdlOiB1bmRlZmluZWQsXG4gICAgICBjdXJyZW50VXJsRGlmZjogdW5kZWZpbmVkLFxuICAgICAgcmVzcG9uc2VEYXRlOiB1bmRlZmluZWRcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBkZWxldGVPcGVyYXRpb24oZXZlbnRTb3VyY2luZ0l0ZW06IFBvRXZlbnRTb3VyY2luZ0l0ZW0pOiBQcm9taXNlPGFueT4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCBzY2hlbWEgPSBhd2FpdCB0aGlzLnBvU2NoZW1hRGVmaW5pdGlvbi5nZXQoZXZlbnRTb3VyY2luZ0l0ZW0uc2NoZW1hKTtcblxuICAgICAgY29uc3QgcmVjb3JkSWQgPSBldmVudFNvdXJjaW5nSXRlbS5yZWNvcmRbc2NoZW1hLmlkRmllbGRdO1xuICAgICAgdGhpcy5jaGVja1JlY29yZElkRXhpc3RzKHJlY29yZElkLCBQb0V2ZW50U291cmNpbmdPcGVyYXRpb24uRGVsZXRlKTtcblxuICAgICAgY29uc3QgdXJsID0gUG9FdmVudFNvdXJjaW5nU2VydmljZS5nZXRVcmwoZXZlbnRTb3VyY2luZ0l0ZW0sIHNjaGVtYSwgUG9SZXF1ZXN0VHlwZS5ERUxFVEUpO1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnNlbmRTZXJ2ZXJJdGVtKHVybCwgUG9IdHRwUmVxdWVzdFR5cGUuREVMRVRFKTtcblxuICAgICAgYXdhaXQgdGhpcy5yZW1vdmVFdmVudFNvdXJjaW5nVmFsaWRJdGVtKHJlc3BvbnNlLnN0YXR1cywgZXZlbnRTb3VyY2luZ0l0ZW0pO1xuXG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kUmVzcG9uc2VTdWJqZWN0KGV2ZW50U291cmNpbmdJdGVtLCByZXNwb25zZSk7XG4gICAgfSBjYXRjaCAoZXJyb3JSZXNwb25zZSkge1xuICAgICAgcmV0dXJuIHRoaXMuc2VuZFJlc3BvbnNlU3ViamVjdChldmVudFNvdXJjaW5nSXRlbSwgZXJyb3JSZXNwb25zZSwgdHJ1ZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBkaWZmU2VydmVySXRlbXMoY3VycmVudFVybERpZmYpOiBPYnNlcnZhYmxlPEh0dHBSZXNwb25zZTxPYmplY3Q+PiB7XG4gICAgcmV0dXJuIHRoaXMucG9IdHRwQ2xpZW50LmdldChjdXJyZW50VXJsRGlmZik7XG4gIH1cblxuICBwcml2YXRlIGdldEJvZHlBbmREYXRlKHNjaGVtYU5hbWUsIHJlc3BvbnNlKTogYW55IHtcbiAgICBjb25zdCBnZXREYXRlRmllbGROYW1lID0gdGhpcy5jb25maWcuZGF0YVRyYW5zZm9ybS5nZXREYXRlRmllbGROYW1lKCk7XG5cbiAgICBjb25zdCByZXNwb25zZVN5bmNEYXRlID0gcmVzcG9uc2UuYm9keVtnZXREYXRlRmllbGROYW1lXTtcblxuICAgIHRoaXMuc2NoZW1hc1N5bmNDb25maWdbc2NoZW1hTmFtZV1bJ3Jlc3BvbnNlRGF0ZSddID0gcmVzcG9uc2VTeW5jRGF0ZTtcbiAgICByZXR1cm4gcmVzcG9uc2UuYm9keTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZ2V0U2VydmVyRGlmZlJlY29yZHMoc2NoZW1hOiBQb1N5bmNTY2hlbWEsIGJhc2VVcmw6IHN0cmluZyk6IFByb21pc2U8YW55PiB7XG4gICAgY29uc3QgaW5pdGlhbEFjdW11bGF0b3JQYWdlID0geyBlbnRpdHk6IHNjaGVtYS5uYW1lLCBkYXRhOiBbXSB9O1xuICAgIGNvbnN0IGRpZmZVcmwgPSB0aGlzLnNjaGVtYXNTeW5jQ29uZmlnW3NjaGVtYS5uYW1lXVsnY3VycmVudFVybERpZmYnXTtcblxuICAgIGNvbnN0IHNlcnZlclJlc3BvbnNlID0gYXdhaXQgdGhpcy5kaWZmU2VydmVySXRlbXMoZGlmZlVybClcbiAgICAgIC5waXBlKFxuICAgICAgICBtYXAocmVzcG9uc2UgPT4gdGhpcy5nZXRCb2R5QW5kRGF0ZShzY2hlbWEubmFtZSwgcmVzcG9uc2UpKSxcbiAgICAgICAgZXhwYW5kKGRhdGEgPT4gdGhpcy5wYWdpbmF0ZVNjaGVtYURhdGEoZGF0YSwgc2NoZW1hLCBiYXNlVXJsKSksXG4gICAgICAgIHJlZHVjZShcbiAgICAgICAgICAocGFnZUFjdW11bGF0b3IsIHJlcXVlc3RCb2R5KSA9PiB0aGlzLmNvbmNhdFBhZ2VJdGVtcyhwYWdlQWN1bXVsYXRvciwgcmVxdWVzdEJvZHkpLFxuICAgICAgICAgIGluaXRpYWxBY3VtdWxhdG9yUGFnZVxuICAgICAgICApXG4gICAgICApXG4gICAgICAudG9Qcm9taXNlKCk7XG5cbiAgICByZXR1cm4gc2VydmVyUmVzcG9uc2UuZGF0YTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgaHR0cE9wZXJhdGlvbihldmVudFNvdXJjaW5nSXRlbTogUG9FdmVudFNvdXJjaW5nSXRlbSk6IFByb21pc2U8QXJyYXk8UG9FdmVudFNvdXJjaW5nSXRlbT4gfCBudW1iZXI+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVxdWVzdERhdGE6IFBvSHR0cFJlcXVlc3REYXRhID0gYXdhaXQgdGhpcy5jcmVhdGVQb0h0dHBSZXF1ZXN0RGF0YShcbiAgICAgICAgZXZlbnRTb3VyY2luZ0l0ZW0ucmVjb3JkLnVybCxcbiAgICAgICAgZXZlbnRTb3VyY2luZ0l0ZW0ucmVjb3JkLm1ldGhvZCxcbiAgICAgICAgZXZlbnRTb3VyY2luZ0l0ZW0ucmVjb3JkLFxuICAgICAgICBldmVudFNvdXJjaW5nSXRlbS5yZWNvcmQuaGVhZGVyc1xuICAgICAgKTtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5wb0h0dHBDbGllbnQuY3JlYXRlUmVxdWVzdChyZXF1ZXN0RGF0YSkudG9Qcm9taXNlKCk7XG4gICAgICBjb25zdCBwb0h0dHBDb21tYW5kUmVzcG9uc2U6IFBvU3luY1Jlc3BvbnNlID0ge1xuICAgICAgICBpZDogZXZlbnRTb3VyY2luZ0l0ZW0uaWQsXG4gICAgICAgIGN1c3RvbVJlcXVlc3RJZDogZXZlbnRTb3VyY2luZ0l0ZW0uY3VzdG9tUmVxdWVzdElkLFxuICAgICAgICByZXF1ZXN0OiBldmVudFNvdXJjaW5nSXRlbS5yZWNvcmQsXG4gICAgICAgIHJlc3BvbnNlOiByZXNwb25zZVxuICAgICAgfTtcblxuICAgICAgdGhpcy5yZXNwb25zZVN1YmplY3QubmV4dChwb0h0dHBDb21tYW5kUmVzcG9uc2UpO1xuXG4gICAgICByZXR1cm4gdGhpcy5yZW1vdmVFdmVudFNvdXJjaW5nVmFsaWRJdGVtKHJlc3BvbnNlLnN0YXR1cywgZXZlbnRTb3VyY2luZ0l0ZW0pO1xuICAgIH0gY2F0Y2ggKGVycm9ySHR0cENsaWVudCkge1xuICAgICAgcmV0dXJuIHRoaXMuc2VuZFJlc3BvbnNlU3ViamVjdChldmVudFNvdXJjaW5nSXRlbSwgZXJyb3JIdHRwQ2xpZW50LCB0cnVlKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGluc2VydEV2ZW50U291cmNpbmdRdWV1ZShldmVudFNvdXJjaW5nSXRlbSk6IFByb21pc2U8QXJyYXk8UG9FdmVudFNvdXJjaW5nSXRlbT4+IHtcbiAgICBjb25zdCBldmVudFNvdXJjaW5nVXBkYXRlZFF1ZXVlID0gYXdhaXQgdGhpcy5wb1N0b3JhZ2UuYXBwZW5kSXRlbVRvQXJyYXkoXG4gICAgICBQb0V2ZW50U291cmNpbmdTZXJ2aWNlLmV2ZW50X3NvdXJjaW5nX25hbWUsXG4gICAgICBldmVudFNvdXJjaW5nSXRlbVxuICAgICk7XG5cbiAgICB0aGlzLm5vdGlmeUV2ZW50Q3JlYXRpb24oKTtcblxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoZXZlbnRTb3VyY2luZ1VwZGF0ZWRRdWV1ZSk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGluc2VydE9wZXJhdGlvbihjdXJyZW50RXZlbnRTb3VyY2luZ0l0ZW06IFBvRXZlbnRTb3VyY2luZ0l0ZW0pOiBQcm9taXNlPGFueT4ge1xuICAgIGNvbnN0IHNjaGVtYSA9IGF3YWl0IHRoaXMucG9TY2hlbWFEZWZpbml0aW9uLmdldChjdXJyZW50RXZlbnRTb3VyY2luZ0l0ZW0uc2NoZW1hKTtcbiAgICBjb25zdCB1cmwgPSBQb0V2ZW50U291cmNpbmdTZXJ2aWNlLmdldFVybChjdXJyZW50RXZlbnRTb3VyY2luZ0l0ZW0sIHNjaGVtYSwgUG9SZXF1ZXN0VHlwZS5QT1NUKTtcblxuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuc2VuZFNlcnZlckl0ZW0odXJsLCBQb0h0dHBSZXF1ZXN0VHlwZS5QT1NULCBjdXJyZW50RXZlbnRTb3VyY2luZ0l0ZW0ucmVjb3JkKTtcbiAgICAgIGNvbnN0IHJlY29yZFVwZGF0ZWRCeVNlcnZlciA9IHJlc3BvbnNlLmJvZHk7XG5cbiAgICAgIGF3YWl0IHRoaXMucmVtb3ZlRXZlbnRTb3VyY2luZ1ZhbGlkSXRlbShyZXNwb25zZS5zdGF0dXMsIGN1cnJlbnRFdmVudFNvdXJjaW5nSXRlbSk7XG5cbiAgICAgIGNvbnN0IGlkID0gY3VycmVudEV2ZW50U291cmNpbmdJdGVtLnJlY29yZFtQb1NjaGVtYVV0aWwuc3luY0ludGVybmFsSWRGaWVsZE5hbWVdO1xuICAgICAgYXdhaXQgdGhpcy5wb1NjaGVtYVNlcnZpY2UudXBkYXRlKHNjaGVtYSwgcmVjb3JkVXBkYXRlZEJ5U2VydmVyLCBpZCk7XG5cbiAgICAgIGNvbnN0IGV2ZW50U291cmNpbmdJdGVtczogQXJyYXk8UG9FdmVudFNvdXJjaW5nSXRlbT4gPSBhd2FpdCB0aGlzLnBvU3RvcmFnZS5nZXQoXG4gICAgICAgIFBvRXZlbnRTb3VyY2luZ1NlcnZpY2UuZXZlbnRfc291cmNpbmdfbmFtZVxuICAgICAgKTtcbiAgICAgIGF3YWl0IHRoaXMudXBkYXRlUGVuZGluZ0V2ZW50U291cmNpbmcoXG4gICAgICAgIGN1cnJlbnRFdmVudFNvdXJjaW5nSXRlbSxcbiAgICAgICAgc2NoZW1hLmlkRmllbGQsXG4gICAgICAgIHJlY29yZFVwZGF0ZWRCeVNlcnZlcixcbiAgICAgICAgZXZlbnRTb3VyY2luZ0l0ZW1zXG4gICAgICApO1xuXG4gICAgICByZXR1cm4gdGhpcy5zZW5kUmVzcG9uc2VTdWJqZWN0KGN1cnJlbnRFdmVudFNvdXJjaW5nSXRlbSwgcmVzcG9uc2UpO1xuICAgIH0gY2F0Y2ggKGVycm9ySHR0cENsaWVudCkge1xuICAgICAgcmV0dXJuIHRoaXMuc2VuZFJlc3BvbnNlU3ViamVjdChjdXJyZW50RXZlbnRTb3VyY2luZ0l0ZW0sIGVycm9ySHR0cENsaWVudCwgdHJ1ZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBpc1ZhbGlkU3RhdHVzKHN0YXR1czogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIFBvRXZlbnRTb3VyY2luZ1NlcnZpY2UuVkFMSURfSFRUUF9TVEFUVVNfQ09ERVMuaW5jbHVkZXMoc3RhdHVzKTtcbiAgfVxuXG4gIHByaXZhdGUgbm90aWZ5RXZlbnRDcmVhdGlvbigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5lbWl0dGVyKSB7XG4gICAgICB0aGlzLmVtaXR0ZXIubmV4dCgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcGFnaW5hdGVTY2hlbWFEYXRhKGRhdGEsIHNjaGVtYSwgYmFzZVVybCk6IE9ic2VydmFibGU8bnVsbD4ge1xuICAgIHRoaXMuY29uZmlnLmRhdGFUcmFuc2Zvcm0udHJhbnNmb3JtKGRhdGEpO1xuXG4gICAgaWYgKHRoaXMuY29uZmlnLmRhdGFUcmFuc2Zvcm0uaGFzTmV4dCgpKSB7XG4gICAgICB0aGlzLnNjaGVtYXNTeW5jQ29uZmlnW3NjaGVtYS5uYW1lXVsnY3VycmVudFVybERpZmYnXSA9IHRoaXMuYnVpbGRVcmxQYXJhbXMoXG4gICAgICAgIHNjaGVtYSxcbiAgICAgICAgYmFzZVVybCxcbiAgICAgICAgKyt0aGlzLnNjaGVtYXNTeW5jQ29uZmlnW3NjaGVtYS5uYW1lXVsncGFnZSddXG4gICAgICApO1xuXG4gICAgICByZXR1cm4gdGhpcy5kaWZmU2VydmVySXRlbXModGhpcy5zY2hlbWFzU3luY0NvbmZpZ1tzY2hlbWEubmFtZV1bJ2N1cnJlbnRVcmxEaWZmJ10pLnBpcGUoXG4gICAgICAgIG1hcChyZXNwb25zZSA9PiB0aGlzLmdldEJvZHlBbmREYXRlKHNjaGVtYS5uYW1lLCByZXNwb25zZSkpXG4gICAgICApO1xuICAgIH1cblxuICAgIHJldHVybiBvZigpO1xuICB9XG5cbiAgcHJpdmF0ZSByZW1vdmVFdmVudFNvdXJjaW5nVmFsaWRJdGVtKFxuICAgIHN0YXR1cyxcbiAgICBldmVudFNvdXJjaW5nSXRlbTogUG9FdmVudFNvdXJjaW5nSXRlbVxuICApOiBQcm9taXNlPEFycmF5PFBvRXZlbnRTb3VyY2luZ0l0ZW0+PiB7XG4gICAgaWYgKHRoaXMuaXNWYWxpZFN0YXR1cyhzdGF0dXMpIHx8IGV2ZW50U291cmNpbmdJdGVtLm9wZXJhdGlvbiA9PT0gUG9FdmVudFNvdXJjaW5nT3BlcmF0aW9uLkh0dHApIHtcbiAgICAgIHJldHVybiB0aGlzLnJlbW92ZUV2ZW50U291cmNpbmdJdGVtKGV2ZW50U291cmNpbmdJdGVtLmlkKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNlbGVjdE9wZXJhdGlvbihldmVudFNvdXJjaW5nSXRlbTogUG9FdmVudFNvdXJjaW5nSXRlbSk6IFByb21pc2U8YW55PiB7XG4gICAgc3dpdGNoIChldmVudFNvdXJjaW5nSXRlbS5vcGVyYXRpb24pIHtcbiAgICAgIGNhc2UgUG9FdmVudFNvdXJjaW5nT3BlcmF0aW9uLkluc2VydDpcbiAgICAgICAgcmV0dXJuIHRoaXMuaW5zZXJ0T3BlcmF0aW9uKGV2ZW50U291cmNpbmdJdGVtKTtcblxuICAgICAgY2FzZSBQb0V2ZW50U291cmNpbmdPcGVyYXRpb24uVXBkYXRlOlxuICAgICAgICByZXR1cm4gdGhpcy51cGRhdGVPcGVyYXRpb24oZXZlbnRTb3VyY2luZ0l0ZW0pO1xuXG4gICAgICBjYXNlIFBvRXZlbnRTb3VyY2luZ09wZXJhdGlvbi5EZWxldGU6XG4gICAgICAgIHJldHVybiB0aGlzLmRlbGV0ZU9wZXJhdGlvbihldmVudFNvdXJjaW5nSXRlbSk7XG5cbiAgICAgIGNhc2UgUG9FdmVudFNvdXJjaW5nT3BlcmF0aW9uLkh0dHA6XG4gICAgICAgIHJldHVybiB0aGlzLmh0dHBPcGVyYXRpb24oZXZlbnRTb3VyY2luZ0l0ZW0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc2VuZFJlc3BvbnNlU3ViamVjdChcbiAgICBldmVudFNvdXJjaW5nSXRlbTogUG9FdmVudFNvdXJjaW5nSXRlbSxcbiAgICByZXNwb25zZTogSHR0cFJlc3BvbnNlPE9iamVjdD4gfCBIdHRwRXJyb3JSZXNwb25zZSB8IFBvRXZlbnRTb3VyY2luZ0Vycm9yUmVzcG9uc2UsXG4gICAgaXNTdWJqZWN0RXJyb3I6IGJvb2xlYW4gPSBmYWxzZVxuICApOiBQcm9taXNlPGFueT4ge1xuICAgIGNvbnN0IHBvU3luY1Jlc3BvbnNlOiBQb1N5bmNSZXNwb25zZSA9IHtcbiAgICAgIGlkOiBldmVudFNvdXJjaW5nSXRlbS5pZCxcbiAgICAgIGN1c3RvbVJlcXVlc3RJZDogZXZlbnRTb3VyY2luZ0l0ZW0uY3VzdG9tUmVxdWVzdElkLFxuICAgICAgcmVxdWVzdDogZXZlbnRTb3VyY2luZ0l0ZW0ucmVjb3JkLFxuICAgICAgcmVzcG9uc2U6IHJlc3BvbnNlXG4gICAgfTtcblxuICAgIHRoaXMuc3RvcHBlZFF1ZXVlRXZlbnRTb3VyY2luZyA9IGlzU3ViamVjdEVycm9yO1xuICAgIHRoaXMucmVzcG9uc2VTdWJqZWN0Lm5leHQocG9TeW5jUmVzcG9uc2UpO1xuXG4gICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBzZW5kU2VydmVySXRlbSh1cmw6IHN0cmluZywgbWV0aG9kOiBQb0h0dHBSZXF1ZXN0VHlwZSwgYm9keT86IFBvRXZlbnRTb3VyY2luZ0l0ZW1bJ3JlY29yZCddKSB7XG4gICAgY29uc3QgcmVxdWVzdERhdGE6IFBvSHR0cFJlcXVlc3REYXRhID0gYXdhaXQgdGhpcy5jcmVhdGVQb0h0dHBSZXF1ZXN0RGF0YSh1cmwsIG1ldGhvZCwgYm9keSk7XG5cbiAgICByZXR1cm4gdGhpcy5wb0h0dHBDbGllbnQuY3JlYXRlUmVxdWVzdChyZXF1ZXN0RGF0YSkudG9Qcm9taXNlKCk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGNyZWF0ZVBvSHR0cFJlcXVlc3REYXRhKFxuICAgIHVybDogc3RyaW5nLFxuICAgIG1ldGhvZDogUG9IdHRwUmVxdWVzdFR5cGUsXG4gICAgcmVjb3JkPzogUG9FdmVudFNvdXJjaW5nSXRlbVsncmVjb3JkJ10sXG4gICAgaGVhZGVycz86IEFycmF5PFBvSHR0cEhlYWRlck9wdGlvbj5cbiAgKTogUHJvbWlzZTxQb0h0dHBSZXF1ZXN0RGF0YT4ge1xuICAgIGxldCBib2R5ID0gcmVjb3JkLmJvZHkgPz8gcmVjb3JkO1xuXG4gICAgaWYgKHJlY29yZC5ib2R5VHlwZSA9PT0gJ0ZpbGUnKSB7XG4gICAgICBib2R5ID0gYXdhaXQgdGhpcy5jcmVhdGVGb3JtRGF0YShib2R5LCByZWNvcmQuZmlsZU5hbWUsIHJlY29yZC5taW1lVHlwZSwgcmVjb3JkLmZvcm1GaWVsZCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgdXJsLCBtZXRob2QsIGJvZHksIGhlYWRlcnMgfTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgY3JlYXRlRm9ybURhdGEoXG4gICAgYm9keTogc3RyaW5nLFxuICAgIGZpbGVOYW1lOiBzdHJpbmcsXG4gICAgbWltZVR5cGU6IHN0cmluZyxcbiAgICBmb3JtRmllbGQ6IHN0cmluZyA9ICdmaWxlJ1xuICApOiBQcm9taXNlPEZvcm1EYXRhPiB7XG4gICAgY29uc3QgZmlsZSA9IGF3YWl0IHRvRmlsZShib2R5LCBmaWxlTmFtZSwgbWltZVR5cGUpO1xuICAgIGNvbnN0IGZvcm1EYXRhOiBGb3JtRGF0YSA9IG5ldyBGb3JtRGF0YSgpO1xuXG4gICAgZm9ybURhdGEuYXBwZW5kKGZvcm1GaWVsZCwgZmlsZSwgZmlsZU5hbWUpO1xuICAgIHJldHVybiBmb3JtRGF0YTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgdXBkYXRlT3BlcmF0aW9uKGV2ZW50U291cmNpbmdJdGVtOiBQb0V2ZW50U291cmNpbmdJdGVtKTogUHJvbWlzZTxBcnJheTxhbnk+IHwgbnVtYmVyPiB7XG4gICAgY29uc3Qgc2NoZW1hID0gYXdhaXQgdGhpcy5wb1NjaGVtYURlZmluaXRpb24uZ2V0KGV2ZW50U291cmNpbmdJdGVtLnNjaGVtYSk7XG4gICAgY29uc3QgdXJsID0gUG9FdmVudFNvdXJjaW5nU2VydmljZS5nZXRVcmwoZXZlbnRTb3VyY2luZ0l0ZW0sIHNjaGVtYSwgUG9SZXF1ZXN0VHlwZS5QQVRDSCk7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVjb3JkSWQgPSBldmVudFNvdXJjaW5nSXRlbS5yZWNvcmRbc2NoZW1hLmlkRmllbGRdO1xuICAgICAgdGhpcy5jaGVja1JlY29yZElkRXhpc3RzKHJlY29yZElkLCBQb0V2ZW50U291cmNpbmdPcGVyYXRpb24uVXBkYXRlKTtcblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLnNlbmRTZXJ2ZXJJdGVtKHVybCwgUG9IdHRwUmVxdWVzdFR5cGUuUFVULCBldmVudFNvdXJjaW5nSXRlbS5yZWNvcmQpO1xuICAgICAgYXdhaXQgdGhpcy5yZW1vdmVFdmVudFNvdXJjaW5nVmFsaWRJdGVtKHJlc3BvbnNlLnN0YXR1cywgZXZlbnRTb3VyY2luZ0l0ZW0pO1xuXG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5zZW5kUmVzcG9uc2VTdWJqZWN0KGV2ZW50U291cmNpbmdJdGVtLCByZXNwb25zZSk7XG4gICAgfSBjYXRjaCAoZXJyb3JIdHRwQ2xpZW50KSB7XG4gICAgICByZXR1cm4gdGhpcy5zZW5kUmVzcG9uc2VTdWJqZWN0KGV2ZW50U291cmNpbmdJdGVtLCBlcnJvckh0dHBDbGllbnQsIHRydWUpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlUGVuZGluZ0V2ZW50U291cmNpbmcoXG4gICAgY3VycmVudEV2ZW50U291cmNpbmdJdGVtOiBQb0V2ZW50U291cmNpbmdJdGVtLFxuICAgIGlkRmllbGRTY2hlbWE6IHN0cmluZyxcbiAgICBpbnNlcnRlZDogb2JqZWN0LFxuICAgIGV2ZW50U291cmNpbmdJdGVtczogQXJyYXk8UG9FdmVudFNvdXJjaW5nSXRlbT5cbiAgKSB7XG4gICAgaWYgKGN1cnJlbnRFdmVudFNvdXJjaW5nSXRlbS5yZWNvcmRbUG9TY2hlbWFVdGlsLnN5bmNJbnRlcm5hbElkRmllbGROYW1lXSkge1xuICAgICAgZXZlbnRTb3VyY2luZ0l0ZW1zLmZvckVhY2goKGV2ZW50U291cmNpbmdJdGVtLCBwb3NpdGlvbikgPT4ge1xuICAgICAgICBjb25zdCBpc0N1cnJlbnRFdmVudFNvdXJjaW5nSXRlbSA9XG4gICAgICAgICAgIWV2ZW50U291cmNpbmdJdGVtLnJlY29yZFtpZEZpZWxkU2NoZW1hXSAmJlxuICAgICAgICAgIGV2ZW50U291cmNpbmdJdGVtLnJlY29yZFtQb1NjaGVtYVV0aWwuc3luY0ludGVybmFsSWRGaWVsZE5hbWVdID09PVxuICAgICAgICAgICAgY3VycmVudEV2ZW50U291cmNpbmdJdGVtLnJlY29yZFtQb1NjaGVtYVV0aWwuc3luY0ludGVybmFsSWRGaWVsZE5hbWVdO1xuXG4gICAgICAgIGlmIChpc0N1cnJlbnRFdmVudFNvdXJjaW5nSXRlbSkge1xuICAgICAgICAgIGV2ZW50U291cmNpbmdJdGVtc1twb3NpdGlvbl0ucmVjb3JkW2lkRmllbGRTY2hlbWFdID0gaW5zZXJ0ZWRbaWRGaWVsZFNjaGVtYV07XG4gICAgICAgIH1cbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4gdGhpcy5wb1N0b3JhZ2Uuc2V0KFBvRXZlbnRTb3VyY2luZ1NlcnZpY2UuZXZlbnRfc291cmNpbmdfbmFtZSwgZXZlbnRTb3VyY2luZ0l0ZW1zKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgdXBkYXRlUmVjb3JkcyhzZXJ2ZXJSZWNvcmRzOiBBcnJheTxhbnk+LCBzY2hlbWE6IFBvU3luY1NjaGVtYSkge1xuICAgIGZvciAoY29uc3Qgc2VydmVyUmVjb3JkIG9mIHNlcnZlclJlY29yZHMpIHtcbiAgICAgIGF3YWl0IHRoaXMudXBkYXRlUmVjb3JkQnlTZXJ2ZXJSZWNvcmQoc2VydmVyUmVjb3JkLCBzY2hlbWEpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgdXBkYXRlUmVjb3JkQnlTZXJ2ZXJSZWNvcmQoc2VydmVyUmVjb3JkLCBzY2hlbWEpIHtcbiAgICBjb25zdCByZWNvcmRJZCA9IHNlcnZlclJlY29yZFtzY2hlbWEuaWRGaWVsZF07XG4gICAgY29uc3Qgc3RvcmFnZVJlY29yZCA9IGF3YWl0IHRoaXMucG9TY2hlbWFTZXJ2aWNlLmdldChzY2hlbWEubmFtZSwgcmVjb3JkSWQpO1xuICAgIGNvbnN0IGV4aXN0c1N0b3JhZ2VSZWNvcmQgPSAhIU9iamVjdC5rZXlzKHN0b3JhZ2VSZWNvcmQpLmxlbmd0aDtcblxuICAgIGlmIChleGlzdHNTdG9yYWdlUmVjb3JkICYmIHNlcnZlclJlY29yZFtzY2hlbWEuZGVsZXRlZEZpZWxkXSkge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucG9TY2hlbWFTZXJ2aWNlLnJlbW92ZShzY2hlbWEubmFtZSwgc2VydmVyUmVjb3JkW3NjaGVtYS5pZEZpZWxkXSk7XG4gICAgfVxuXG4gICAgaWYgKGV4aXN0c1N0b3JhZ2VSZWNvcmQgJiYgIXNlcnZlclJlY29yZFtzY2hlbWEuZGVsZXRlZEZpZWxkXSkge1xuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucG9TY2hlbWFTZXJ2aWNlLnVwZGF0ZShzY2hlbWEsIHNlcnZlclJlY29yZCk7XG4gICAgfVxuXG4gICAgaWYgKCFleGlzdHNTdG9yYWdlUmVjb3JkICYmICFzZXJ2ZXJSZWNvcmRbc2NoZW1hLmRlbGV0ZWRGaWVsZF0pIHtcbiAgICAgIHJldHVybiBhd2FpdCB0aGlzLnBvU2NoZW1hU2VydmljZS5jcmVhdGUoc2NoZW1hLCBzZXJ2ZXJSZWNvcmQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgdXBkYXRlU3RvcmFnZUJ5U2NoZW1hKHNjaGVtYTogUG9TeW5jU2NoZW1hKTogUHJvbWlzZTxhbnk+IHtcbiAgICB0aGlzLmNyZWF0ZVNjaGVtYVN5bmNDb25maWcoc2NoZW1hLm5hbWUpO1xuXG4gICAgdGhpcy5zY2hlbWFzU3luY0NvbmZpZ1tzY2hlbWEubmFtZV1bJ3BhZ2UnXSA9IDE7XG4gICAgY29uc3QgYmFzZVVybCA9IGAke1BvU2NoZW1hVXRpbC5nZXRVcmwoc2NoZW1hLCBQb1JlcXVlc3RUeXBlLkRJRkYpfS8ke3NjaGVtYS5sYXN0U3luY31gO1xuICAgIHRoaXMuc2NoZW1hc1N5bmNDb25maWdbc2NoZW1hLm5hbWVdWydjdXJyZW50VXJsRGlmZiddID0gdGhpcy5idWlsZFVybFBhcmFtcyhcbiAgICAgIHNjaGVtYSxcbiAgICAgIGJhc2VVcmwsXG4gICAgICB0aGlzLnNjaGVtYXNTeW5jQ29uZmlnW3NjaGVtYS5uYW1lXVsncGFnZSddXG4gICAgKTtcblxuICAgIGNvbnN0IHNlcnZlclJlY29yZHMgPSBhd2FpdCB0aGlzLmdldFNlcnZlckRpZmZSZWNvcmRzKHNjaGVtYSwgYmFzZVVybCk7XG5cbiAgICBhd2FpdCB0aGlzLnVwZGF0ZVJlY29yZHMoc2VydmVyUmVjb3Jkcywgc2NoZW1hKTtcblxuICAgIHNjaGVtYS5sYXN0U3luYyA9IHRoaXMuc2NoZW1hc1N5bmNDb25maWdbc2NoZW1hLm5hbWVdWydyZXNwb25zZURhdGUnXTtcbiAgICBhd2FpdCB0aGlzLnBvU2NoZW1hRGVmaW5pdGlvbi51cGRhdGUoc2NoZW1hKTtcbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlU3RvcmFnZVNjaGVtYXMoc2NoZW1hcyk6IEFycmF5PFByb21pc2U8QXJyYXk8YW55Pj4+IHtcbiAgICByZXR1cm4gc2NoZW1hcy5tYXAoKHNjaGVtYTogUG9TeW5jU2NoZW1hKSA9PiB0aGlzLnVwZGF0ZVN0b3JhZ2VCeVNjaGVtYShzY2hlbWEpKTtcbiAgfVxufVxuIl19
|