@metigan/angular 1.0.2 → 1.0.3
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/.gitattributes +31 -0
- package/README.md +313 -64
- package/package.json +1 -1
- package/dist/LICENSE +0 -22
- package/dist/README.md +0 -584
- package/dist/esm2022/metigan-angular.mjs +0 -5
- package/dist/esm2022/public-api.mjs +0 -21
- package/dist/esm2022/src/lib/audiences.service.mjs +0 -157
- package/dist/esm2022/src/lib/config.mjs +0 -30
- package/dist/esm2022/src/lib/contacts.service.mjs +0 -267
- package/dist/esm2022/src/lib/email.service.mjs +0 -267
- package/dist/esm2022/src/lib/errors.mjs +0 -40
- package/dist/esm2022/src/lib/forms.service.mjs +0 -180
- package/dist/esm2022/src/lib/http-client.service.mjs +0 -111
- package/dist/esm2022/src/lib/metigan.module.mjs +0 -67
- package/dist/esm2022/src/lib/metigan.service.mjs +0 -72
- package/dist/esm2022/src/lib/templates.service.mjs +0 -85
- package/dist/esm2022/src/lib/types.mjs +0 -6
- package/dist/fesm2022/metigan-angular.mjs +0 -1241
- package/dist/fesm2022/metigan-angular.mjs.map +0 -1
- package/dist/index.d.ts +0 -5
- package/dist/public-api.d.ts +0 -15
- package/dist/src/lib/audiences.service.d.ts +0 -62
- package/dist/src/lib/config.d.ts +0 -28
- package/dist/src/lib/contacts.service.d.ts +0 -80
- package/dist/src/lib/email.service.d.ts +0 -44
- package/dist/src/lib/errors.d.ts +0 -24
- package/dist/src/lib/forms.service.d.ts +0 -67
- package/dist/src/lib/http-client.service.d.ts +0 -46
- package/dist/src/lib/metigan.module.d.ts +0 -27
- package/dist/src/lib/metigan.service.d.ts +0 -27
- package/dist/src/lib/templates.service.d.ts +0 -36
- package/dist/src/lib/types.d.ts +0 -329
|
@@ -1,267 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Metigan Email Service
|
|
3
|
-
* Service for sending emails through the Metigan API
|
|
4
|
-
*/
|
|
5
|
-
import { Injectable } from '@angular/core';
|
|
6
|
-
import { Observable, throwError } from 'rxjs';
|
|
7
|
-
import { map } from 'rxjs/operators';
|
|
8
|
-
import { API_URL, DEFAULT_TIMEOUT, DEFAULT_RETRY_COUNT, DEFAULT_RETRY_DELAY, MAX_FILE_SIZE } from './config';
|
|
9
|
-
import { ValidationError, MetiganError } from './errors';
|
|
10
|
-
import * as i0 from "@angular/core";
|
|
11
|
-
import * as i1 from "./http-client.service";
|
|
12
|
-
export class MetiganEmailService {
|
|
13
|
-
http;
|
|
14
|
-
apiKey = '';
|
|
15
|
-
apiUrl = API_URL;
|
|
16
|
-
timeout = DEFAULT_TIMEOUT;
|
|
17
|
-
retryCount = DEFAULT_RETRY_COUNT;
|
|
18
|
-
retryDelay = DEFAULT_RETRY_DELAY;
|
|
19
|
-
constructor(http) {
|
|
20
|
-
this.http = http;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Initialize the service with API key and options
|
|
24
|
-
*/
|
|
25
|
-
initialize(apiKey, options) {
|
|
26
|
-
if (!apiKey) {
|
|
27
|
-
throw new MetiganError('API key is required');
|
|
28
|
-
}
|
|
29
|
-
this.apiKey = apiKey;
|
|
30
|
-
this.apiUrl = options?.apiUrl || API_URL;
|
|
31
|
-
this.timeout = options?.timeout || DEFAULT_TIMEOUT;
|
|
32
|
-
this.retryCount = options?.retryCount || DEFAULT_RETRY_COUNT;
|
|
33
|
-
this.retryDelay = options?.retryDelay || DEFAULT_RETRY_DELAY;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Validate email address format
|
|
37
|
-
*/
|
|
38
|
-
validateEmail(email) {
|
|
39
|
-
if (!email || typeof email !== 'string')
|
|
40
|
-
return false;
|
|
41
|
-
const parts = email.split('@');
|
|
42
|
-
if (parts.length !== 2)
|
|
43
|
-
return false;
|
|
44
|
-
if (parts[0].length === 0)
|
|
45
|
-
return false;
|
|
46
|
-
const domainParts = parts[1].split('.');
|
|
47
|
-
if (domainParts.length < 2)
|
|
48
|
-
return false;
|
|
49
|
-
if (domainParts.some(part => part.length === 0))
|
|
50
|
-
return false;
|
|
51
|
-
return true;
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Extract email address from "Name <email>" format
|
|
55
|
-
*/
|
|
56
|
-
extractEmailAddress(from) {
|
|
57
|
-
if (!from)
|
|
58
|
-
return '';
|
|
59
|
-
const angleMatch = from.match(/<([^>]+)>/);
|
|
60
|
-
if (angleMatch) {
|
|
61
|
-
return angleMatch[1].trim();
|
|
62
|
-
}
|
|
63
|
-
return from.trim();
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Validate email options
|
|
67
|
-
*/
|
|
68
|
-
validateOptions(options) {
|
|
69
|
-
if (!options.from) {
|
|
70
|
-
throw new ValidationError('Sender email (from) is required');
|
|
71
|
-
}
|
|
72
|
-
if (!options.recipients || !Array.isArray(options.recipients) || options.recipients.length === 0) {
|
|
73
|
-
throw new ValidationError('Recipients must be a non-empty array');
|
|
74
|
-
}
|
|
75
|
-
if (!options.subject) {
|
|
76
|
-
throw new ValidationError('Subject is required');
|
|
77
|
-
}
|
|
78
|
-
if (!options.content && !options.templateId) {
|
|
79
|
-
throw new ValidationError('Either content or templateId is required');
|
|
80
|
-
}
|
|
81
|
-
const fromEmail = this.extractEmailAddress(options.from);
|
|
82
|
-
if (!this.validateEmail(fromEmail)) {
|
|
83
|
-
throw new ValidationError(`Invalid sender email format: ${fromEmail}`);
|
|
84
|
-
}
|
|
85
|
-
for (const recipient of options.recipients) {
|
|
86
|
-
const recipientEmail = this.extractEmailAddress(recipient);
|
|
87
|
-
if (!this.validateEmail(recipientEmail)) {
|
|
88
|
-
throw new ValidationError(`Invalid recipient email format: ${recipientEmail}`);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
if (options.cc) {
|
|
92
|
-
for (const cc of options.cc) {
|
|
93
|
-
const ccEmail = this.extractEmailAddress(cc);
|
|
94
|
-
if (!this.validateEmail(ccEmail)) {
|
|
95
|
-
throw new ValidationError(`Invalid CC email format: ${ccEmail}`);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
if (options.bcc) {
|
|
100
|
-
for (const bcc of options.bcc) {
|
|
101
|
-
const bccEmail = this.extractEmailAddress(bcc);
|
|
102
|
-
if (!this.validateEmail(bccEmail)) {
|
|
103
|
-
throw new ValidationError(`Invalid BCC email format: ${bccEmail}`);
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
if (options.replyTo) {
|
|
108
|
-
const replyToEmail = this.extractEmailAddress(options.replyTo);
|
|
109
|
-
if (!this.validateEmail(replyToEmail)) {
|
|
110
|
-
throw new ValidationError(`Invalid reply-to email format: ${replyToEmail}`);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
/**
|
|
115
|
-
* Process attachments for FormData
|
|
116
|
-
*/
|
|
117
|
-
async processAttachments(attachments) {
|
|
118
|
-
const formData = new FormData();
|
|
119
|
-
for (const file of attachments) {
|
|
120
|
-
if (file instanceof File) {
|
|
121
|
-
if (file.size > MAX_FILE_SIZE) {
|
|
122
|
-
throw new MetiganError(`File ${file.name} exceeds the maximum size of 7MB`);
|
|
123
|
-
}
|
|
124
|
-
formData.append('files', file);
|
|
125
|
-
}
|
|
126
|
-
else {
|
|
127
|
-
const attachment = file;
|
|
128
|
-
// Convert content to Blob
|
|
129
|
-
let blob;
|
|
130
|
-
if (attachment.content instanceof ArrayBuffer) {
|
|
131
|
-
blob = new Blob([attachment.content], { type: attachment.contentType });
|
|
132
|
-
}
|
|
133
|
-
else if (attachment.content instanceof Uint8Array) {
|
|
134
|
-
blob = new Blob([attachment.content], { type: attachment.contentType });
|
|
135
|
-
}
|
|
136
|
-
else if (typeof attachment.content === 'string') {
|
|
137
|
-
// Base64 string
|
|
138
|
-
const byteCharacters = atob(attachment.content);
|
|
139
|
-
const byteNumbers = new Array(byteCharacters.length);
|
|
140
|
-
for (let i = 0; i < byteCharacters.length; i++) {
|
|
141
|
-
byteNumbers[i] = byteCharacters.charCodeAt(i);
|
|
142
|
-
}
|
|
143
|
-
const byteArray = new Uint8Array(byteNumbers);
|
|
144
|
-
blob = new Blob([byteArray], { type: attachment.contentType });
|
|
145
|
-
}
|
|
146
|
-
else {
|
|
147
|
-
throw new MetiganError('Invalid attachment content type');
|
|
148
|
-
}
|
|
149
|
-
if (blob.size > MAX_FILE_SIZE) {
|
|
150
|
-
throw new MetiganError(`File ${attachment.filename} exceeds the maximum size of 7MB`);
|
|
151
|
-
}
|
|
152
|
-
const fileObj = new File([blob], attachment.filename, { type: attachment.contentType });
|
|
153
|
-
formData.append('files', fileObj);
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
return formData;
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* Send an email
|
|
160
|
-
*/
|
|
161
|
-
sendEmail(options) {
|
|
162
|
-
if (!this.apiKey) {
|
|
163
|
-
return throwError(() => new MetiganError('Service not initialized. Call initialize() first.'));
|
|
164
|
-
}
|
|
165
|
-
try {
|
|
166
|
-
this.validateOptions(options);
|
|
167
|
-
}
|
|
168
|
-
catch (error) {
|
|
169
|
-
return throwError(() => error);
|
|
170
|
-
}
|
|
171
|
-
const headers = {
|
|
172
|
-
'x-api-key': this.apiKey,
|
|
173
|
-
'User-Agent': 'AngularSDK/1.0'
|
|
174
|
-
};
|
|
175
|
-
// If attachments, use FormData
|
|
176
|
-
if (options.attachments && options.attachments.length > 0) {
|
|
177
|
-
return new Observable(observer => {
|
|
178
|
-
this.processAttachments(options.attachments).then(formData => {
|
|
179
|
-
formData.append('from', options.from);
|
|
180
|
-
formData.append('recipients', JSON.stringify(options.recipients));
|
|
181
|
-
formData.append('subject', options.subject);
|
|
182
|
-
if (options.templateId) {
|
|
183
|
-
formData.append('useTemplate', 'true');
|
|
184
|
-
formData.append('templateId', options.templateId);
|
|
185
|
-
}
|
|
186
|
-
else if (options.content) {
|
|
187
|
-
formData.append('content', options.content);
|
|
188
|
-
}
|
|
189
|
-
if (options.cc && options.cc.length > 0) {
|
|
190
|
-
formData.append('cc', JSON.stringify(options.cc));
|
|
191
|
-
}
|
|
192
|
-
if (options.bcc && options.bcc.length > 0) {
|
|
193
|
-
formData.append('bcc', JSON.stringify(options.bcc));
|
|
194
|
-
}
|
|
195
|
-
if (options.replyTo) {
|
|
196
|
-
formData.append('replyTo', options.replyTo);
|
|
197
|
-
}
|
|
198
|
-
const httpOptions = {
|
|
199
|
-
headers: headers
|
|
200
|
-
};
|
|
201
|
-
this.http.post(`${this.apiUrl}/api/email/send`, formData, httpOptions, this.retryCount, this.retryDelay)
|
|
202
|
-
.pipe(map(response => {
|
|
203
|
-
if ('success' in response && response.success) {
|
|
204
|
-
return response;
|
|
205
|
-
}
|
|
206
|
-
else {
|
|
207
|
-
throw new MetiganError(response.message || 'Failed to send email');
|
|
208
|
-
}
|
|
209
|
-
}))
|
|
210
|
-
.subscribe({
|
|
211
|
-
next: (response) => observer.next(response),
|
|
212
|
-
error: (error) => observer.error(error),
|
|
213
|
-
complete: () => observer.complete()
|
|
214
|
-
});
|
|
215
|
-
}).catch(error => observer.error(error));
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
else {
|
|
219
|
-
// No attachments, use JSON
|
|
220
|
-
const body = {
|
|
221
|
-
from: options.from,
|
|
222
|
-
recipients: options.recipients,
|
|
223
|
-
subject: options.subject
|
|
224
|
-
};
|
|
225
|
-
if (options.templateId) {
|
|
226
|
-
body.useTemplate = 'true';
|
|
227
|
-
body.templateId = options.templateId;
|
|
228
|
-
}
|
|
229
|
-
else if (options.content) {
|
|
230
|
-
body.content = options.content;
|
|
231
|
-
}
|
|
232
|
-
if (options.cc && options.cc.length > 0) {
|
|
233
|
-
body.cc = options.cc;
|
|
234
|
-
}
|
|
235
|
-
if (options.bcc && options.bcc.length > 0) {
|
|
236
|
-
body.bcc = options.bcc;
|
|
237
|
-
}
|
|
238
|
-
if (options.replyTo) {
|
|
239
|
-
body.replyTo = options.replyTo;
|
|
240
|
-
}
|
|
241
|
-
const httpOptions = {
|
|
242
|
-
headers: {
|
|
243
|
-
...headers,
|
|
244
|
-
'Content-Type': 'application/json'
|
|
245
|
-
}
|
|
246
|
-
};
|
|
247
|
-
return this.http.post(`${this.apiUrl}/api/email/send`, body, httpOptions, this.retryCount, this.retryDelay)
|
|
248
|
-
.pipe(map(response => {
|
|
249
|
-
if ('success' in response && response.success) {
|
|
250
|
-
return response;
|
|
251
|
-
}
|
|
252
|
-
else {
|
|
253
|
-
throw new MetiganError(response.message || 'Failed to send email');
|
|
254
|
-
}
|
|
255
|
-
}));
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MetiganEmailService, deps: [{ token: i1.MetiganHttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
259
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MetiganEmailService, providedIn: 'root' });
|
|
260
|
-
}
|
|
261
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MetiganEmailService, decorators: [{
|
|
262
|
-
type: Injectable,
|
|
263
|
-
args: [{
|
|
264
|
-
providedIn: 'root'
|
|
265
|
-
}]
|
|
266
|
-
}], ctorParameters: () => [{ type: i1.MetiganHttpClient }] });
|
|
267
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW1haWwuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvZW1haWwuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFFSCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzlDLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUVyQyxPQUFPLEVBQUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxtQkFBbUIsRUFBRSxtQkFBbUIsRUFBRSxhQUFhLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDN0csT0FBTyxFQUFFLGVBQWUsRUFBRSxZQUFZLEVBQUUsTUFBTSxVQUFVLENBQUM7OztBQU16RCxNQUFNLE9BQU8sbUJBQW1CO0lBT1Y7SUFOWixNQUFNLEdBQVcsRUFBRSxDQUFDO0lBQ3BCLE1BQU0sR0FBVyxPQUFPLENBQUM7SUFDekIsT0FBTyxHQUFXLGVBQWUsQ0FBQztJQUNsQyxVQUFVLEdBQVcsbUJBQW1CLENBQUM7SUFDekMsVUFBVSxHQUFXLG1CQUFtQixDQUFDO0lBRWpELFlBQW9CLElBQXVCO1FBQXZCLFNBQUksR0FBSixJQUFJLENBQW1CO0lBQUcsQ0FBQztJQUUvQzs7T0FFRztJQUNILFVBQVUsQ0FBQyxNQUFjLEVBQUUsT0FBeUY7UUFDbEgsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ1osTUFBTSxJQUFJLFlBQVksQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1FBQ2hELENBQUM7UUFFRCxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixJQUFJLENBQUMsTUFBTSxHQUFHLE9BQU8sRUFBRSxNQUFNLElBQUksT0FBTyxDQUFDO1FBQ3pDLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxFQUFFLE9BQU8sSUFBSSxlQUFlLENB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LENBQUM7WUFFRCxJQUFJLE9BQU8sQ0FBQyxHQUFHLElBQUksT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ3pDLElBQVksQ0FBQyxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQztZQUNsQyxDQUFDO1lBRUQsSUFBSSxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQ25CLElBQVksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQztZQUMxQyxDQUFDO1lBRUQsTUFBTSxXQUFXLEdBQUc7Z0JBQ2xCLE9BQU8sRUFBRTtvQkFDUCxHQUFHLE9BQU87b0JBQ1YsY0FBYyxFQUFFLGtCQUFrQjtpQkFDbkM7YUFDRixDQUFDO1lBRUYsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBbUIsR0FBRyxJQUFJLENBQUMsTUFBTSxpQkFBaUIsRUFBRSxJQUFJLEVBQUUsV0FBVyxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQztpQkFDMUgsSUFBSSxDQUNILEdBQUcsQ0FBQyxRQUFRLENBQUMsRUFBRTtnQkFDYixJQUFJLFNBQVMsSUFBSSxRQUFRLElBQUksUUFBUSxDQUFDLE9BQU8sRUFBRSxDQUFDO29CQUM5QyxPQUFPLFFBQWdDLENBQUM7Z0JBQzFDLENBQUM7cUJBQU0sQ0FBQztvQkFDTixNQUFNLElBQUksWUFBWSxDQUFFLFFBQWdCLENBQUMsT0FBTyxJQUFJLHNCQUFzQixDQUFDLENBQUM7Z0JBQzlFLENBQUM7WUFDSCxDQUFDLENBQUMsQ0FDSCxDQUFDO1FBQ04sQ0FBQztJQUNILENBQUM7d0dBMVFVLG1CQUFtQjs0R0FBbkIsbUJBQW1CLGNBRmxCLE1BQU07OzRGQUVQLG1CQUFtQjtrQkFIL0IsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcclxuICogTWV0aWdhbiBFbWFpbCBTZXJ2aWNlXHJcbiAqIFNlcnZpY2UgZm9yIHNlbmRpbmcgZW1haWxzIHRocm91Z2ggdGhlIE1ldGlnYW4gQVBJXHJcbiAqL1xyXG5cclxuaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBPYnNlcnZhYmxlLCB0aHJvd0Vycm9yIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuaW1wb3J0IHsgTWV0aWdhbkh0dHBDbGllbnQgfSBmcm9tICcuL2h0dHAtY2xpZW50LnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBBUElfVVJMLCBERUZBVUxUX1RJTUVPVVQsIERFRkFVTFRfUkVUUllfQ09VTlQsIERFRkFVTFRfUkVUUllfREVMQVksIE1BWF9GSUxFX1NJWkUgfSBmcm9tICcuL2NvbmZpZyc7XHJcbmltcG9ydCB7IFZhbGlkYXRpb25FcnJvciwgTWV0aWdhbkVycm9yIH0gZnJvbSAnLi9lcnJvcnMnO1xyXG5pbXBvcnQgeyBFbWFpbE9wdGlvbnMsIEVtYWlsQXBpUmVzcG9uc2UsIEVtYWlsU3VjY2Vzc1Jlc3BvbnNlLCBFbWFpbEF0dGFjaG1lbnQgfSBmcm9tICcuL3R5cGVzJztcclxuXHJcbkBJbmplY3RhYmxlKHtcclxuICBwcm92aWRlZEluOiAncm9vdCdcclxufSlcclxuZXhwb3J0IGNsYXNzIE1ldGlnYW5FbWFpbFNlcnZpY2Uge1xyXG4gIHByaXZhdGUgYXBpS2V5OiBzdHJpbmcgPSAnJztcclxuICBwcml2YXRlIGFwaVVybDogc3RyaW5nID0gQVBJX1VSTDtcclxuICBwcml2YXRlIHRpbWVvdXQ6IG51bWJlciA9IERFRkFVTFRfVElNRU9VVDtcclxuICBwcml2YXRlIHJldHJ5Q291bnQ6IG51bWJlciA9IERFRkFVTFRfUkVUUllfQ09VTlQ7XHJcbiAgcHJpdmF0ZSByZXRyeURlbGF5OiBudW1iZXIgPSBERUZBVUxUX1JFVFJZX0RFTEFZO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGh0dHA6IE1ldGlnYW5IdHRwQ2xpZW50KSB7fVxyXG5cclxuICAvKipcclxuICAgKiBJbml0aWFsaXplIHRoZSBzZXJ2aWNlIHdpdGggQVBJIGtleSBhbmQgb3B0aW9uc1xyXG4gICAqL1xyXG4gIGluaXRpYWxpemUoYXBpS2V5OiBzdHJpbmcsIG9wdGlvbnM/OiB7IGFwaVVybD86IHN0cmluZzsgdGltZW91dD86IG51bWJlcjsgcmV0cnlDb3VudD86IG51bWJlcjsgcmV0cnlEZWxheT86IG51bWJlciB9KTogdm9pZCB7XHJcbiAgICBpZiAoIWFwaUtleSkge1xyXG4gICAgICB0aHJvdyBuZXcgTWV0aWdhbkVycm9yKCdBUEkga2V5IGlzIHJlcXVpcmVkJyk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5hcGlLZXkgPSBhcGlLZXk7XHJcbiAgICB0aGlzLmFwaVVybCA9IG9wdGlvbnM/LmFwaVVybCB8fCBBUElfVVJMO1xyXG4gICAgdGhpcy50aW1lb3V0ID0gb3B0aW9ucz8udGltZW91dCB8fCBERUZBVUxUX1RJTUVPVVQ7XHJcbiAgICB0aGlzLnJldHJ5Q291bnQgPSBvcHRpb25zPy5yZXRyeUNvdW50IHx8IERFRkFVTFRfUkVUUllfQ09VTlQ7XHJcbiAgICB0aGlzLnJldHJ5RGVsYXkgPSBvcHRpb25zPy5yZXRyeURlbGF5IHx8IERFRkFVTFRfUkVUUllfREVMQVk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBWYWxpZGF0ZSBlbWFpbCBhZGRyZXNzIGZvcm1hdFxyXG4gICAqL1xyXG4gIHByaXZhdGUgdmFsaWRhdGVFbWFpbChlbWFpbDogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICBpZiAoIWVtYWlsIHx8IHR5cGVvZiBlbWFpbCAhPT0gJ3N0cmluZycpIHJldHVybiBmYWxzZTtcclxuICAgIGNvbnN0IHBhcnRzID0gZW1haWwuc3BsaXQoJ0AnKTtcclxuICAgIGlmIChwYXJ0cy5sZW5ndGggIT09IDIpIHJldHVybiBmYWxzZTtcclxuICAgIGlmIChwYXJ0c1swXS5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcclxuICAgIGNvbnN0IGRvbWFpblBhcnRzID0gcGFydHNbMV0uc3BsaXQoJy4nKTtcclxuICAgIGlmIChkb21haW5QYXJ0cy5sZW5ndGggPCAyKSByZXR1cm4gZmFsc2U7XHJcbiAgICBpZiAoZG9tYWluUGFydHMuc29tZShwYXJ0ID0+IHBhcnQubGVuZ3RoID09PSAwKSkgcmV0dXJuIGZhbHNlO1xyXG4gICAgcmV0dXJuIHRydWU7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBFeHRyYWN0IGVtYWlsIGFkZHJlc3MgZnJvbSBcIk5hbWUgPGVtYWlsPlwiIGZvcm1hdFxyXG4gICAqL1xyXG4gIHByaXZhdGUgZXh0cmFjdEVtYWlsQWRkcmVzcyhmcm9tOiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgaWYgKCFmcm9tKSByZXR1cm4gJyc7XHJcbiAgICBjb25zdCBhbmdsZU1hdGNoID0gZnJvbS5tYXRjaCgvPChbXj5dKyk+Lyk7XHJcbiAgICBpZiAoYW5nbGVNYXRjaCkge1xyXG4gICAgICByZXR1cm4gYW5nbGVNYXRjaFsxXS50cmltKCk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gZnJvbS50cmltKCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBWYWxpZGF0ZSBlbWFpbCBvcHRpb25zXHJcbiAgICovXHJcbiAgcHJpdmF0ZSB2YWxpZGF0ZU9wdGlvbnMob3B0aW9uczogRW1haWxPcHRpb25zKTogdm9pZCB7XHJcbiAgICBpZiAoIW9wdGlvbnMuZnJvbSkge1xyXG4gICAgICB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKCdTZW5kZXIgZW1haWwgKGZyb20pIGlzIHJlcXVpcmVkJyk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCFvcHRpb25zLnJlY2lwaWVudHMgfHwgIUFycmF5LmlzQXJyYXkob3B0aW9ucy5yZWNpcGllbnRzKSB8fCBvcHRpb25zLnJlY2lwaWVudHMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoJ1JlY2lwaWVudHMgbXVzdCBiZSBhIG5vbi1lbXB0eSBhcnJheScpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghb3B0aW9ucy5zdWJqZWN0KSB7XHJcbiAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoJ1N1YmplY3QgaXMgcmVxdWlyZWQnKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIW9wdGlvbnMuY29udGVudCAmJiAhb3B0aW9ucy50ZW1wbGF0ZUlkKSB7XHJcbiAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoJ0VpdGhlciBjb250ZW50IG9yIHRlbXBsYXRlSWQgaXMgcmVxdWlyZWQnKTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBmcm9tRW1haWwgPSB0aGlzLmV4dHJhY3RFbWFpbEFkZHJlc3Mob3B0aW9ucy5mcm9tKTtcclxuICAgIGlmICghdGhpcy52YWxpZGF0ZUVtYWlsKGZyb21FbWFpbCkpIHtcclxuICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihgSW52YWxpZCBzZW5kZXIgZW1haWwgZm9ybWF0OiAke2Zyb21FbWFpbH1gKTtcclxuICAgIH1cclxuXHJcbiAgICBmb3IgKGNvbnN0IHJlY2lwaWVudCBvZiBvcHRpb25zLnJlY2lwaWVudHMpIHtcclxuICAgICAgY29uc3QgcmVjaXBpZW50RW1haWwgPSB0aGlzLmV4dHJhY3RFbWFpbEFkZHJlc3MocmVjaXBpZW50KTtcclxuICAgICAgaWYgKCF0aGlzLnZhbGlkYXRlRW1haWwocmVjaXBpZW50RW1haWwpKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihgSW52YWxpZCByZWNpcGllbnQgZW1haWwgZm9ybWF0OiAke3JlY2lwaWVudEVtYWlsfWApO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKG9wdGlvbnMuY2MpIHtcclxuICAgICAgZm9yIChjb25zdCBjYyBvZiBvcHRpb25zLmNjKSB7XHJcbiAgICAgICAgY29uc3QgY2NFbWFpbCA9IHRoaXMuZXh0cmFjdEVtYWlsQWRkcmVzcyhjYyk7XHJcbiAgICAgICAgaWYgKCF0aGlzLnZhbGlkYXRlRW1haWwoY2NFbWFpbCkpIHtcclxuICAgICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoYEludmFsaWQgQ0MgZW1haWwgZm9ybWF0OiAke2NjRW1haWx9YCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKG9wdGlvbnMuYmNjKSB7XHJcbiAgICAgIGZvciAoY29uc3QgYmNjIG9mIG9wdGlvbnMuYmNjKSB7XHJcbiAgICAgICAgY29uc3QgYmNjRW1haWwgPSB0aGlzLmV4dHJhY3RFbWFpbEFkZHJlc3MoYmNjKTtcclxuICAgICAgICBpZiAoIXRoaXMudmFsaWRhdGVFbWFpbChiY2NFbWFpbCkpIHtcclxuICAgICAgICAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoYEludmFsaWQgQkNDIGVtYWlsIGZvcm1hdDogJHtiY2NFbWFpbH1gKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpZiAob3B0aW9ucy5yZXBseVRvKSB7XHJcbiAgICAgIGNvbnN0IHJlcGx5VG9FbWFpbCA9IHRoaXMuZXh0cmFjdEVtYWlsQWRkcmVzcyhvcHRpb25zLnJlcGx5VG8pO1xyXG4gICAgICBpZiAoIXRoaXMudmFsaWRhdGVFbWFpbChyZXBseVRvRW1haWwpKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihgSW52YWxpZCByZXBseS10byBlbWFpbCBmb3JtYXQ6ICR7cmVwbHlUb0VtYWlsfWApO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBQcm9jZXNzIGF0dGFjaG1lbnRzIGZvciBGb3JtRGF0YVxyXG4gICAqL1xyXG4gIHByaXZhdGUgYXN5bmMgcHJvY2Vzc0F0dGFjaG1lbnRzKGF0dGFjaG1lbnRzOiBGaWxlW10gfCBFbWFpbEF0dGFjaG1lbnRbXSk6IFByb21pc2U8Rm9ybURhdGE+IHtcclxuICAgIGNvbnN0IGZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKCk7XHJcblxyXG4gICAgZm9yIChjb25zdCBmaWxlIG9mIGF0dGFjaG1lbnRzKSB7XHJcbiAgICAgIGlmIChmaWxlIGluc3RhbmNlb2YgRmlsZSkge1xyXG4gICAgICAgIGlmIChmaWxlLnNpemUgPiBNQVhfRklMRV9TSVpFKSB7XHJcbiAgICAgICAgICB0aHJvdyBuZXcgTWV0aWdhbkVycm9yKGBGaWxlICR7ZmlsZS5uYW1lfSBleGNlZWRzIHRoZSBtYXhpbXVtIHNpemUgb2YgN01CYCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZvcm1EYXRhLmFwcGVuZCgnZmlsZXMnLCBmaWxlKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBjb25zdCBhdHRhY2htZW50ID0gZmlsZSBhcyBFbWFpbEF0dGFjaG1lbnQ7XHJcbiAgICAgICAgXHJcbiAgICAgICAgLy8gQ29udmVydCBjb250ZW50IHRvIEJsb2JcclxuICAgICAgICBsZXQgYmxvYjogQmxvYjtcclxuICAgICAgICBpZiAoYXR0YWNobWVudC5jb250ZW50IGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcclxuICAgICAgICAgIGJsb2IgPSBuZXcgQmxvYihbYXR0YWNobWVudC5jb250ZW50XSwgeyB0eXBlOiBhdHRhY2htZW50LmNvbnRlbnRUeXBlIH0pO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoYXR0YWNobWVudC5jb250ZW50IGluc3RhbmNlb2YgVWludDhBcnJheSkge1xyXG4gICAgICAgICAgYmxvYiA9IG5ldyBCbG9iKFthdHRhY2htZW50LmNvbnRlbnRdLCB7IHR5cGU6IGF0dGFjaG1lbnQuY29udGVudFR5cGUgfSk7XHJcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgYXR0YWNobWVudC5jb250ZW50ID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgLy8gQmFzZTY0IHN0cmluZ1xyXG4gICAgICAgICAgY29uc3QgYnl0ZUNoYXJhY3RlcnMgPSBhdG9iKGF0dGFjaG1lbnQuY29udGVudCk7XHJcbiAgICAgICAgICBjb25zdCBieXRlTnVtYmVycyA9IG5ldyBBcnJheShieXRlQ2hhcmFjdGVycy5sZW5ndGgpO1xyXG4gICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBieXRlQ2hhcmFjdGVycy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBieXRlTnVtYmVyc1tpXSA9IGJ5dGVDaGFyYWN0ZXJzLmNoYXJDb2RlQXQoaSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBjb25zdCBieXRlQXJyYXkgPSBuZXcgVWludDhBcnJheShieXRlTnVtYmVycyk7XHJcbiAgICAgICAgICBibG9iID0gbmV3IEJsb2IoW2J5dGVBcnJheV0sIHsgdHlwZTogYXR0YWNobWVudC5jb250ZW50VHlwZSB9KTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdGhyb3cgbmV3IE1ldGlnYW5FcnJvcignSW52YWxpZCBhdHRhY2htZW50IGNvbnRlbnQgdHlwZScpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGJsb2Iuc2l6ZSA+IE1BWF9GSUxFX1NJWkUpIHtcclxuICAgICAgICAgIHRocm93IG5ldyBNZXRpZ2FuRXJyb3IoYEZpbGUgJHthdHRhY2htZW50LmZpbGVuYW1lfSBleGNlZWRzIHRoZSBtYXhpbXVtIHNpemUgb2YgN01CYCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBmaWxlT2JqID0gbmV3IEZpbGUoW2Jsb2JdLCBhdHRhY2htZW50LmZpbGVuYW1lLCB7IHR5cGU6IGF0dGFjaG1lbnQuY29udGVudFR5cGUgfSk7XHJcbiAgICAgICAgZm9ybURhdGEuYXBwZW5kKCdmaWxlcycsIGZpbGVPYmopO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGZvcm1EYXRhO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU2VuZCBhbiBlbWFpbFxyXG4gICAqL1xyXG4gIHNlbmRFbWFpbChvcHRpb25zOiBFbWFpbE9wdGlvbnMpOiBPYnNlcnZhYmxlPEVtYWlsU3VjY2Vzc1Jlc3BvbnNlPiB7XHJcbiAgICBpZiAoIXRoaXMuYXBpS2V5KSB7XHJcbiAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IG5ldyBNZXRpZ2FuRXJyb3IoJ1NlcnZpY2Ugbm90IGluaXRpYWxpemVkLiBDYWxsIGluaXRpYWxpemUoKSBmaXJzdC4nKSk7XHJcbiAgICB9XHJcblxyXG4gICAgdHJ5IHtcclxuICAgICAgdGhpcy52YWxpZGF0ZU9wdGlvbnMob3B0aW9ucyk7XHJcbiAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBlcnJvcik7XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3QgaGVhZGVycyA9IHtcclxuICAgICAgJ3gtYXBpLWtleSc6IHRoaXMuYXBpS2V5LFxyXG4gICAgICAnVXNlci1BZ2VudCc6ICdBbmd1bGFyU0RLLzEuMCdcclxuICAgIH07XHJcblxyXG4gICAgLy8gSWYgYXR0YWNobWVudHMsIHVzZSBGb3JtRGF0YVxyXG4gICAgaWYgKG9wdGlvbnMuYXR0YWNobWVudHMgJiYgb3B0aW9ucy5hdHRhY2htZW50cy5sZW5ndGggPiAwKSB7XHJcbiAgICAgIHJldHVybiBuZXcgT2JzZXJ2YWJsZShvYnNlcnZlciA9PiB7XHJcbiAgICAgICAgdGhpcy5wcm9jZXNzQXR0YWNobWVudHMob3B0aW9ucy5hdHRhY2htZW50cyEpLnRoZW4oZm9ybURhdGEgPT4ge1xyXG4gICAgICAgICAgZm9ybURhdGEuYXBwZW5kKCdmcm9tJywgb3B0aW9ucy5mcm9tKTtcclxuICAgICAgICAgIGZvcm1EYXRhLmFwcGVuZCgncmVjaXBpZW50cycsIEpTT04uc3RyaW5naWZ5KG9wdGlvbnMucmVjaXBpZW50cykpO1xyXG4gICAgICAgICAgZm9ybURhdGEuYXBwZW5kKCdzdWJqZWN0Jywgb3B0aW9ucy5zdWJqZWN0KTtcclxuICAgICAgICAgIFxyXG4gICAgICAgICAgaWYgKG9wdGlvbnMudGVtcGxhdGVJZCkge1xyXG4gICAgICAgICAgICBmb3JtRGF0YS5hcHBlbmQoJ3VzZVRlbXBsYXRlJywgJ3RydWUnKTtcclxuICAgICAgICAgICAgZm9ybURhdGEuYXBwZW5kKCd0ZW1wbGF0ZUlkJywgb3B0aW9ucy50ZW1wbGF0ZUlkKTtcclxuICAgICAgICAgIH0gZWxzZSBpZiAob3B0aW9ucy5jb250ZW50KSB7XHJcbiAgICAgICAgICAgIGZvcm1EYXRhLmFwcGVuZCgnY29udGVudCcsIG9wdGlvbnMuY29udGVudCk7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgaWYgKG9wdGlvbnMuY2MgJiYgb3B0aW9ucy5jYy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIGZvcm1EYXRhLmFwcGVuZCgnY2MnLCBKU09OLnN0cmluZ2lmeShvcHRpb25zLmNjKSk7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgaWYgKG9wdGlvbnMuYmNjICYmIG9wdGlvbnMuYmNjLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgZm9ybURhdGEuYXBwZW5kKCdiY2MnLCBKU09OLnN0cmluZ2lmeShvcHRpb25zLmJjYykpO1xyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIGlmIChvcHRpb25zLnJlcGx5VG8pIHtcclxuICAgICAgICAgICAgZm9ybURhdGEuYXBwZW5kKCdyZXBseVRvJywgb3B0aW9ucy5yZXBseVRvKTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBjb25zdCBodHRwT3B0aW9ucyA9IHtcclxuICAgICAgICAgICAgaGVhZGVyczogaGVhZGVyc1xyXG4gICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICB0aGlzLmh0dHAucG9zdDxFbWFpbEFwaVJlc3BvbnNlPihgJHt0aGlzLmFwaVVybH0vYXBpL2VtYWlsL3NlbmRgLCBmb3JtRGF0YSwgaHR0cE9wdGlvbnMsIHRoaXMucmV0cnlDb3VudCwgdGhpcy5yZXRyeURlbGF5KVxyXG4gICAgICAgICAgICAucGlwZShcclxuICAgICAgICAgICAgICBtYXAocmVzcG9uc2UgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKCdzdWNjZXNzJyBpbiByZXNwb25zZSAmJiByZXNwb25zZS5zdWNjZXNzKSB7XHJcbiAgICAgICAgICAgICAgICAgIHJldHVybiByZXNwb25zZSBhcyBFbWFpbFN1Y2Nlc3NSZXNwb25zZTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBNZXRpZ2FuRXJyb3IoKHJlc3BvbnNlIGFzIGFueSkubWVzc2FnZSB8fCAnRmFpbGVkIHRvIHNlbmQgZW1haWwnKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICApXHJcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoe1xyXG4gICAgICAgICAgICAgIG5leHQ6IChyZXNwb25zZSkgPT4gb2JzZXJ2ZXIubmV4dChyZXNwb25zZSksXHJcbiAgICAgICAgICAgICAgZXJyb3I6IChlcnJvcikgPT4gb2JzZXJ2ZXIuZXJyb3IoZXJyb3IpLFxyXG4gICAgICAgICAgICAgIGNvbXBsZXRlOiAoKSA9PiBvYnNlcnZlci5jb21wbGV0ZSgpXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pLmNhdGNoKGVycm9yID0+IG9ic2VydmVyLmVycm9yKGVycm9yKSk7XHJcbiAgICAgIH0pO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgLy8gTm8gYXR0YWNobWVudHMsIHVzZSBKU09OXHJcbiAgICAgIGNvbnN0IGJvZHkgPSB7XHJcbiAgICAgICAgZnJvbTogb3B0aW9ucy5mcm9tLFxyXG4gICAgICAgIHJlY2lwaWVudHM6IG9wdGlvbnMucmVjaXBpZW50cyxcclxuICAgICAgICBzdWJqZWN0OiBvcHRpb25zLnN1YmplY3RcclxuICAgICAgfTtcclxuXHJcbiAgICAgIGlmIChvcHRpb25zLnRlbXBsYXRlSWQpIHtcclxuICAgICAgICAoYm9keSBhcyBhbnkpLnVzZVRlbXBsYXRlID0gJ3RydWUnO1xyXG4gICAgICAgIChib2R5IGFzIGFueSkudGVtcGxhdGVJZCA9IG9wdGlvbnMudGVtcGxhdGVJZDtcclxuICAgICAgfSBlbHNlIGlmIChvcHRpb25zLmNvbnRlbnQpIHtcclxuICAgICAgICAoYm9keSBhcyBhbnkpLmNvbnRlbnQgPSBvcHRpb25zLmNvbnRlbnQ7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChvcHRpb25zLmNjICYmIG9wdGlvbnMuY2MubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIChib2R5IGFzIGFueSkuY2MgPSBvcHRpb25zLmNjO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAob3B0aW9ucy5iY2MgJiYgb3B0aW9ucy5iY2MubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIChib2R5IGFzIGFueSkuYmNjID0gb3B0aW9ucy5iY2M7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChvcHRpb25zLnJlcGx5VG8pIHtcclxuICAgICAgICAoYm9keSBhcyBhbnkpLnJlcGx5VG8gPSBvcHRpb25zLnJlcGx5VG87XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGNvbnN0IGh0dHBPcHRpb25zID0ge1xyXG4gICAgICAgIGhlYWRlcnM6IHtcclxuICAgICAgICAgIC4uLmhlYWRlcnMsXHJcbiAgICAgICAgICAnQ29udGVudC1UeXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nXHJcbiAgICAgICAgfVxyXG4gICAgICB9O1xyXG5cclxuICAgICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0PEVtYWlsQXBpUmVzcG9uc2U+KGAke3RoaXMuYXBpVXJsfS9hcGkvZW1haWwvc2VuZGAsIGJvZHksIGh0dHBPcHRpb25zLCB0aGlzLnJldHJ5Q291bnQsIHRoaXMucmV0cnlEZWxheSlcclxuICAgICAgICAucGlwZShcclxuICAgICAgICAgIG1hcChyZXNwb25zZSA9PiB7XHJcbiAgICAgICAgICAgIGlmICgnc3VjY2VzcycgaW4gcmVzcG9uc2UgJiYgcmVzcG9uc2Uuc3VjY2Vzcykge1xyXG4gICAgICAgICAgICAgIHJldHVybiByZXNwb25zZSBhcyBFbWFpbFN1Y2Nlc3NSZXNwb25zZTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICB0aHJvdyBuZXcgTWV0aWdhbkVycm9yKChyZXNwb25zZSBhcyBhbnkpLm1lc3NhZ2UgfHwgJ0ZhaWxlZCB0byBzZW5kIGVtYWlsJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0pXHJcbiAgICAgICAgKTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuXHJcblxyXG4iXX0=
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Custom error classes for Metigan SDK
|
|
3
|
-
*/
|
|
4
|
-
/**
|
|
5
|
-
* Base error class for all Metigan errors
|
|
6
|
-
*/
|
|
7
|
-
export class MetiganError extends Error {
|
|
8
|
-
constructor(message) {
|
|
9
|
-
super(message);
|
|
10
|
-
this.name = 'MetiganError';
|
|
11
|
-
Object.setPrototypeOf(this, MetiganError.prototype);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Validation error - thrown when input validation fails
|
|
16
|
-
*/
|
|
17
|
-
export class ValidationError extends MetiganError {
|
|
18
|
-
field;
|
|
19
|
-
constructor(message, field) {
|
|
20
|
-
super(message);
|
|
21
|
-
this.name = 'ValidationError';
|
|
22
|
-
this.field = field;
|
|
23
|
-
Object.setPrototypeOf(this, ValidationError.prototype);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* API error - thrown when API request fails
|
|
28
|
-
*/
|
|
29
|
-
export class ApiError extends MetiganError {
|
|
30
|
-
statusCode;
|
|
31
|
-
status;
|
|
32
|
-
constructor(message, statusCode) {
|
|
33
|
-
super(message);
|
|
34
|
-
this.name = 'ApiError';
|
|
35
|
-
this.statusCode = statusCode || statusCode;
|
|
36
|
-
this.status = statusCode;
|
|
37
|
-
Object.setPrototypeOf(this, ApiError.prototype);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXJyb3JzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9lcnJvcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFFSDs7R0FFRztBQUNILE1BQU0sT0FBTyxZQUFhLFNBQVEsS0FBSztJQUNyQyxZQUFZLE9BQWU7UUFDekIsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2YsSUFBSSxDQUFDLElBQUksR0FBRyxjQUFjLENBQUM7UUFDM0IsTUFBTSxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBQ3RELENBQUM7Q0FDRjtBQUVEOztHQUVHO0FBQ0gsTUFBTSxPQUFPLGVBQWdCLFNBQVEsWUFBWTtJQUN4QyxLQUFLLENBQVU7SUFFdEIsWUFBWSxPQUFlLEVBQUUsS0FBYztRQUN6QyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDZixJQUFJLENBQUMsSUFBSSxHQUFHLGlCQUFpQixDQUFDO1FBQzlCLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ25CLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLGVBQWUsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN6RCxDQUFDO0NBQ0Y7QUFFRDs7R0FFRztBQUNILE1BQU0sT0FBTyxRQUFTLFNBQVEsWUFBWTtJQUNqQyxVQUFVLENBQVU7SUFDcEIsTUFBTSxDQUFVO0lBRXZCLFlBQVksT0FBZSxFQUFFLFVBQW1CO1FBQzlDLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNmLElBQUksQ0FBQyxJQUFJLEdBQUcsVUFBVSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxJQUFJLFVBQVUsQ0FBQztRQUMzQyxJQUFJLENBQUMsTUFBTSxHQUFHLFVBQVUsQ0FBQztRQUN6QixNQUFNLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDbEQsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXHJcbiAqIEN1c3RvbSBlcnJvciBjbGFzc2VzIGZvciBNZXRpZ2FuIFNES1xyXG4gKi9cclxuXHJcbi8qKlxyXG4gKiBCYXNlIGVycm9yIGNsYXNzIGZvciBhbGwgTWV0aWdhbiBlcnJvcnNcclxuICovXHJcbmV4cG9ydCBjbGFzcyBNZXRpZ2FuRXJyb3IgZXh0ZW5kcyBFcnJvciB7XHJcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nKSB7XHJcbiAgICBzdXBlcihtZXNzYWdlKTtcclxuICAgIHRoaXMubmFtZSA9ICdNZXRpZ2FuRXJyb3InO1xyXG4gICAgT2JqZWN0LnNldFByb3RvdHlwZU9mKHRoaXMsIE1ldGlnYW5FcnJvci5wcm90b3R5cGUpO1xyXG4gIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFZhbGlkYXRpb24gZXJyb3IgLSB0aHJvd24gd2hlbiBpbnB1dCB2YWxpZGF0aW9uIGZhaWxzXHJcbiAqL1xyXG5leHBvcnQgY2xhc3MgVmFsaWRhdGlvbkVycm9yIGV4dGVuZHMgTWV0aWdhbkVycm9yIHtcclxuICBwdWJsaWMgZmllbGQ/OiBzdHJpbmc7XHJcblxyXG4gIGNvbnN0cnVjdG9yKG1lc3NhZ2U6IHN0cmluZywgZmllbGQ/OiBzdHJpbmcpIHtcclxuICAgIHN1cGVyKG1lc3NhZ2UpO1xyXG4gICAgdGhpcy5uYW1lID0gJ1ZhbGlkYXRpb25FcnJvcic7XHJcbiAgICB0aGlzLmZpZWxkID0gZmllbGQ7XHJcbiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgVmFsaWRhdGlvbkVycm9yLnByb3RvdHlwZSk7XHJcbiAgfVxyXG59XHJcblxyXG4vKipcclxuICogQVBJIGVycm9yIC0gdGhyb3duIHdoZW4gQVBJIHJlcXVlc3QgZmFpbHNcclxuICovXHJcbmV4cG9ydCBjbGFzcyBBcGlFcnJvciBleHRlbmRzIE1ldGlnYW5FcnJvciB7XHJcbiAgcHVibGljIHN0YXR1c0NvZGU/OiBudW1iZXI7XHJcbiAgcHVibGljIHN0YXR1cz86IG51bWJlcjtcclxuXHJcbiAgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nLCBzdGF0dXNDb2RlPzogbnVtYmVyKSB7XHJcbiAgICBzdXBlcihtZXNzYWdlKTtcclxuICAgIHRoaXMubmFtZSA9ICdBcGlFcnJvcic7XHJcbiAgICB0aGlzLnN0YXR1c0NvZGUgPSBzdGF0dXNDb2RlIHx8IHN0YXR1c0NvZGU7XHJcbiAgICB0aGlzLnN0YXR1cyA9IHN0YXR1c0NvZGU7XHJcbiAgICBPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcywgQXBpRXJyb3IucHJvdG90eXBlKTtcclxuICB9XHJcbn1cclxuXHJcbiJdfQ==
|
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Metigan Forms Service
|
|
3
|
-
* Service for form management and submissions
|
|
4
|
-
*/
|
|
5
|
-
import { Injectable } from '@angular/core';
|
|
6
|
-
import { throwError } from 'rxjs';
|
|
7
|
-
import { HttpParams } from '@angular/common/http';
|
|
8
|
-
import { API_URL, DEFAULT_TIMEOUT, DEFAULT_RETRY_COUNT, DEFAULT_RETRY_DELAY } from './config';
|
|
9
|
-
import { ValidationError, MetiganError } from './errors';
|
|
10
|
-
import * as i0 from "@angular/core";
|
|
11
|
-
import * as i1 from "./http-client.service";
|
|
12
|
-
export class MetiganFormsService {
|
|
13
|
-
http;
|
|
14
|
-
apiKey = '';
|
|
15
|
-
apiUrl = API_URL;
|
|
16
|
-
timeout = DEFAULT_TIMEOUT;
|
|
17
|
-
retryCount = DEFAULT_RETRY_COUNT;
|
|
18
|
-
retryDelay = DEFAULT_RETRY_DELAY;
|
|
19
|
-
constructor(http) {
|
|
20
|
-
this.http = http;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Initialize the service with API key and options
|
|
24
|
-
*/
|
|
25
|
-
initialize(apiKey, options) {
|
|
26
|
-
if (!apiKey) {
|
|
27
|
-
throw new MetiganError('API key is required');
|
|
28
|
-
}
|
|
29
|
-
this.apiKey = apiKey;
|
|
30
|
-
this.apiUrl = options?.apiUrl || API_URL;
|
|
31
|
-
this.timeout = options?.timeout || DEFAULT_TIMEOUT;
|
|
32
|
-
this.retryCount = options?.retryCount || DEFAULT_RETRY_COUNT;
|
|
33
|
-
this.retryDelay = options?.retryDelay || DEFAULT_RETRY_DELAY;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Get default headers
|
|
37
|
-
*/
|
|
38
|
-
getHeaders() {
|
|
39
|
-
return {
|
|
40
|
-
'Content-Type': 'application/json',
|
|
41
|
-
'x-api-key': this.apiKey,
|
|
42
|
-
'User-Agent': 'AngularSDK/1.0'
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Submit form data
|
|
47
|
-
*/
|
|
48
|
-
submit(options) {
|
|
49
|
-
if (!this.apiKey) {
|
|
50
|
-
return throwError(() => new MetiganError('Service not initialized. Call initialize() first.'));
|
|
51
|
-
}
|
|
52
|
-
if (!options.formId) {
|
|
53
|
-
return throwError(() => new ValidationError('Form ID is required'));
|
|
54
|
-
}
|
|
55
|
-
if (!options.data || Object.keys(options.data).length === 0) {
|
|
56
|
-
return throwError(() => new ValidationError('Submission data is required'));
|
|
57
|
-
}
|
|
58
|
-
const body = {
|
|
59
|
-
formId: options.formId,
|
|
60
|
-
data: options.data
|
|
61
|
-
};
|
|
62
|
-
return this.http.post(`${this.apiUrl}/api/submissions`, body, { headers: this.getHeaders() }, this.retryCount, this.retryDelay);
|
|
63
|
-
}
|
|
64
|
-
/**
|
|
65
|
-
* Get form by ID or slug
|
|
66
|
-
*/
|
|
67
|
-
getForm(formIdOrSlug) {
|
|
68
|
-
if (!this.apiKey) {
|
|
69
|
-
return throwError(() => new MetiganError('Service not initialized. Call initialize() first.'));
|
|
70
|
-
}
|
|
71
|
-
if (!formIdOrSlug) {
|
|
72
|
-
return throwError(() => new ValidationError('Form ID or slug is required'));
|
|
73
|
-
}
|
|
74
|
-
return this.http.get(`${this.apiUrl}/api/forms/${formIdOrSlug}`, { headers: this.getHeaders() }, this.retryCount, this.retryDelay);
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Get public form by slug
|
|
78
|
-
*/
|
|
79
|
-
getPublicForm(slug) {
|
|
80
|
-
if (!slug) {
|
|
81
|
-
return throwError(() => new ValidationError('Form slug is required'));
|
|
82
|
-
}
|
|
83
|
-
// Public forms don't require API key
|
|
84
|
-
return this.http.get(`${this.apiUrl}/f/${slug}/api`, {}, this.retryCount, this.retryDelay);
|
|
85
|
-
}
|
|
86
|
-
/**
|
|
87
|
-
* List all forms
|
|
88
|
-
*/
|
|
89
|
-
listForms(options) {
|
|
90
|
-
if (!this.apiKey) {
|
|
91
|
-
return throwError(() => new MetiganError('Service not initialized. Call initialize() first.'));
|
|
92
|
-
}
|
|
93
|
-
let params = new HttpParams();
|
|
94
|
-
if (options?.page) {
|
|
95
|
-
params = params.set('page', options.page.toString());
|
|
96
|
-
}
|
|
97
|
-
if (options?.limit) {
|
|
98
|
-
params = params.set('limit', options.limit.toString());
|
|
99
|
-
}
|
|
100
|
-
return this.http.get(`${this.apiUrl}/api/forms`, {
|
|
101
|
-
headers: this.getHeaders(),
|
|
102
|
-
params: params
|
|
103
|
-
}, this.retryCount, this.retryDelay);
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Create a new form
|
|
107
|
-
*/
|
|
108
|
-
createForm(config) {
|
|
109
|
-
if (!this.apiKey) {
|
|
110
|
-
return throwError(() => new MetiganError('Service not initialized. Call initialize() first.'));
|
|
111
|
-
}
|
|
112
|
-
if (!config.title) {
|
|
113
|
-
return throwError(() => new ValidationError('Form title is required'));
|
|
114
|
-
}
|
|
115
|
-
if (!config.fields || config.fields.length === 0) {
|
|
116
|
-
return throwError(() => new ValidationError('At least one field is required'));
|
|
117
|
-
}
|
|
118
|
-
return this.http.post(`${this.apiUrl}/api/forms`, config, { headers: this.getHeaders() }, this.retryCount, this.retryDelay);
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Update an existing form
|
|
122
|
-
*/
|
|
123
|
-
updateForm(formId, config) {
|
|
124
|
-
if (!this.apiKey) {
|
|
125
|
-
return throwError(() => new MetiganError('Service not initialized. Call initialize() first.'));
|
|
126
|
-
}
|
|
127
|
-
if (!formId) {
|
|
128
|
-
return throwError(() => new ValidationError('Form ID is required'));
|
|
129
|
-
}
|
|
130
|
-
return this.http.put(`${this.apiUrl}/api/forms/${formId}`, config, { headers: this.getHeaders() }, this.retryCount, this.retryDelay);
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Delete a form
|
|
134
|
-
*/
|
|
135
|
-
deleteForm(formId) {
|
|
136
|
-
if (!this.apiKey) {
|
|
137
|
-
return throwError(() => new MetiganError('Service not initialized. Call initialize() first.'));
|
|
138
|
-
}
|
|
139
|
-
if (!formId) {
|
|
140
|
-
return throwError(() => new ValidationError('Form ID is required'));
|
|
141
|
-
}
|
|
142
|
-
return this.http.delete(`${this.apiUrl}/api/forms/${formId}`, { headers: this.getHeaders() }, this.retryCount, this.retryDelay);
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Get form analytics
|
|
146
|
-
*/
|
|
147
|
-
getAnalytics(formId) {
|
|
148
|
-
if (!this.apiKey) {
|
|
149
|
-
return throwError(() => new MetiganError('Service not initialized. Call initialize() first.'));
|
|
150
|
-
}
|
|
151
|
-
if (!formId) {
|
|
152
|
-
return throwError(() => new ValidationError('Form ID is required'));
|
|
153
|
-
}
|
|
154
|
-
return this.http.get(`${this.apiUrl}/api/forms/${formId}/analytics`, { headers: this.getHeaders() }, this.retryCount, this.retryDelay);
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Publish a form
|
|
158
|
-
*/
|
|
159
|
-
publishForm(formId, slug) {
|
|
160
|
-
if (!this.apiKey) {
|
|
161
|
-
return throwError(() => new MetiganError('Service not initialized. Call initialize() first.'));
|
|
162
|
-
}
|
|
163
|
-
if (!formId) {
|
|
164
|
-
return throwError(() => new ValidationError('Form ID is required'));
|
|
165
|
-
}
|
|
166
|
-
if (!slug) {
|
|
167
|
-
return throwError(() => new ValidationError('Slug is required'));
|
|
168
|
-
}
|
|
169
|
-
return this.http.post(`${this.apiUrl}/api/forms/${formId}/publish`, { slug }, { headers: this.getHeaders() }, this.retryCount, this.retryDelay);
|
|
170
|
-
}
|
|
171
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MetiganFormsService, deps: [{ token: i1.MetiganHttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
172
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MetiganFormsService, providedIn: 'root' });
|
|
173
|
-
}
|
|
174
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: MetiganFormsService, decorators: [{
|
|
175
|
-
type: Injectable,
|
|
176
|
-
args: [{
|
|
177
|
-
providedIn: 'root'
|
|
178
|
-
}]
|
|
179
|
-
}], ctorParameters: () => [{ type: i1.MetiganHttpClient }] });
|
|
180
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybXMuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvZm9ybXMuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0dBR0c7QUFFSCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBYyxVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDOUMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRWxELE9BQU8sRUFBRSxPQUFPLEVBQUUsZUFBZSxFQUFFLG1CQUFtQixFQUFFLG1CQUFtQixFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQzlGLE9BQU8sRUFBRSxlQUFlLEVBQUUsWUFBWSxFQUFFLE1BQU0sVUFBVSxDQUFDOzs7QUFZekQsTUFBTSxPQUFPLG1CQUFtQjtJQU9WO0lBTlosTUFBTSxHQUFXLEVBQUUsQ0FBQztJQUNwQixNQUFNLEdBQVcsT0FBTyxDQUFDO0lBQ3pCLE9BQU8sR0FBVyxlQUFlLENBQUM7SUFDbEMsVUFBVSxHQUFXLG1CQUFtQixDQUFDO0lBQ3pDLFVBQVUsR0FBVyxtQkFBbUIsQ0FBQztJQUVqRCxZQUFvQixJQUF1QjtRQUF2QixTQUFJLEdBQUosSUFBSSxDQUFtQjtJQUFHLENBQUM7SUFFL0M7O09BRUc7SUFDSCxVQUFVLENBQUMsTUFBYyxFQUFFLE9BQXlGO1FBQ2xILElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNaLE1BQU0sSUFBSSxZQUFZLENBQUMscUJBQXFCLENBQUMsQ0FBQztRQUNoRCxDQUFDO1FBRUQsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsSUFBSSxDQUFDLE1BQU0sR0FBRyxPQUFPLEVBQUUsTUFBTSxJQUFJLE9BQU8sQ0FBQztRQUN6QyxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sRUFBRSxPQUFPLElBQUksZUFBZSxDQUFDO1FBQ25ELElBQUksQ0FBQyxV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LE9BQU8sVUFBVSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksWUFBWSxDQUFDLG1EQUFtRCxDQUFDLENBQUMsQ0FBQztRQUNqRyxDQUFDO1FBRUQsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ1osT0FBTyxVQUFVLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxlQUFlLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDO1FBQ3RFLENBQUM7UUFFRCxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDVixPQUFPLFVBQVUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxJQUFJLGVBQWUsQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDLENBQUM7UUFDbkUsQ0FBQztRQUVELE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQ25CLEdBQUcsSUFBSSxDQUFDLE1BQU0sY0FBYyxNQUFNLFVBQVUsRUFDNUMsRUFBRSxJQUFJLEVBQUUsRUFDUixFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLEVBQUUsRUFDOUIsSUFBSSxDQUFDLFVBQVUsRUFDZixJQUFJLENBQUMsVUFBVSxDQUNoQixDQUFDO0lBQ0osQ0FBQzt3R0E5T1UsbUJBQW1COzRHQUFuQixtQkFBbUIsY0FGbEIsTUFBTTs7NEZBRVAsbUJBQW1CO2tCQUgvQixVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxyXG4gKiBNZXRpZ2FuIEZvcm1zIFNlcnZpY2VcclxuICogU2VydmljZSBmb3IgZm9ybSBtYW5hZ2VtZW50IGFuZCBzdWJtaXNzaW9uc1xyXG4gKi9cclxuXHJcbmltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgdGhyb3dFcnJvciB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBIdHRwUGFyYW1zIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xyXG5pbXBvcnQgeyBNZXRpZ2FuSHR0cENsaWVudCB9IGZyb20gJy4vaHR0cC1jbGllbnQuc2VydmljZSc7XHJcbmltcG9ydCB7IEFQSV9VUkwsIERFRkFVTFRfVElNRU9VVCwgREVGQVVMVF9SRVRSWV9DT1VOVCwgREVGQVVMVF9SRVRSWV9ERUxBWSB9IGZyb20gJy4vY29uZmlnJztcclxuaW1wb3J0IHsgVmFsaWRhdGlvbkVycm9yLCBNZXRpZ2FuRXJyb3IgfSBmcm9tICcuL2Vycm9ycyc7XHJcbmltcG9ydCB7XHJcbiAgRm9ybUNvbmZpZyxcclxuICBGb3JtU3VibWlzc2lvbk9wdGlvbnMsXHJcbiAgRm9ybVN1Ym1pc3Npb25SZXNwb25zZSxcclxuICBGb3JtTGlzdFJlc3BvbnNlLFxyXG4gIFBhZ2luYXRpb25PcHRpb25zXHJcbn0gZnJvbSAnLi90eXBlcyc7XHJcblxyXG5ASW5qZWN0YWJsZSh7XHJcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBNZXRpZ2FuRm9ybXNTZXJ2aWNlIHtcclxuICBwcml2YXRlIGFwaUtleTogc3RyaW5nID0gJyc7XHJcbiAgcHJpdmF0ZSBhcGlVcmw6IHN0cmluZyA9IEFQSV9VUkw7XHJcbiAgcHJpdmF0ZSB0aW1lb3V0OiBudW1iZXIgPSBERUZBVUxUX1RJTUVPVVQ7XHJcbiAgcHJpdmF0ZSByZXRyeUNvdW50OiBudW1iZXIgPSBERUZBVUxUX1JFVFJZX0NPVU5UO1xyXG4gIHByaXZhdGUgcmV0cnlEZWxheTogbnVtYmVyID0gREVGQVVMVF9SRVRSWV9ERUxBWTtcclxuXHJcbiAgY29uc3RydWN0b3IocHJpdmF0ZSBodHRwOiBNZXRpZ2FuSHR0cENsaWVudCkge31cclxuXHJcbiAgLyoqXHJcbiAgICogSW5pdGlhbGl6ZSB0aGUgc2VydmljZSB3aXRoIEFQSSBrZXkgYW5kIG9wdGlvbnNcclxuICAgKi9cclxuICBpbml0aWFsaXplKGFwaUtleTogc3RyaW5nLCBvcHRpb25zPzogeyBhcGlVcmw/OiBzdHJpbmc7IHRpbWVvdXQ/OiBudW1iZXI7IHJldHJ5Q291bnQ/OiBudW1iZXI7IHJldHJ5RGVsYXk/OiBudW1iZXIgfSk6IHZvaWQge1xyXG4gICAgaWYgKCFhcGlLZXkpIHtcclxuICAgICAgdGhyb3cgbmV3IE1ldGlnYW5FcnJvcignQVBJIGtleSBpcyByZXF1aXJlZCcpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuYXBpS2V5ID0gYXBpS2V5O1xyXG4gICAgdGhpcy5hcGlVcmwgPSBvcHRpb25zPy5hcGlVcmwgfHwgQVBJX1VSTDtcclxuICAgIHRoaXMudGltZW91dCA9IG9wdGlvbnM/LnRpbWVvdXQgfHwgREVGQVVMVF9USU1FT1VUO1xyXG4gICAgdGhpcy5yZXRyeUNvdW50ID0gb3B0aW9ucz8ucmV0cnlDb3VudCB8fCBERUZBVUxUX1JFVFJZX0NPVU5UO1xyXG4gICAgdGhpcy5yZXRyeURlbGF5ID0gb3B0aW9ucz8ucmV0cnlEZWxheSB8fCBERUZBVUxUX1JFVFJZX0RFTEFZO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IGRlZmF1bHQgaGVhZGVyc1xyXG4gICAqL1xyXG4gIHByaXZhdGUgZ2V0SGVhZGVycygpIHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgICdDb250ZW50LVR5cGUnOiAnYXBwbGljYXRpb24vanNvbicsXHJcbiAgICAgICd4LWFwaS1rZXknOiB0aGlzLmFwaUtleSxcclxuICAgICAgJ1VzZXItQWdlbnQnOiAnQW5ndWxhclNESy8xLjAnXHJcbiAgICB9O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU3VibWl0IGZvcm0gZGF0YVxyXG4gICAqL1xyXG4gIHN1Ym1pdChvcHRpb25zOiBGb3JtU3VibWlzc2lvbk9wdGlvbnMpOiBPYnNlcnZhYmxlPEZvcm1TdWJtaXNzaW9uUmVzcG9uc2U+IHtcclxuICAgIGlmICghdGhpcy5hcGlLZXkpIHtcclxuICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gbmV3IE1ldGlnYW5FcnJvcignU2VydmljZSBub3QgaW5pdGlhbGl6ZWQuIENhbGwgaW5pdGlhbGl6ZSgpIGZpcnN0LicpKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIW9wdGlvbnMuZm9ybUlkKSB7XHJcbiAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IG5ldyBWYWxpZGF0aW9uRXJyb3IoJ0Zvcm0gSUQgaXMgcmVxdWlyZWQnKSk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCFvcHRpb25zLmRhdGEgfHwgT2JqZWN0LmtleXMob3B0aW9ucy5kYXRhKS5sZW5ndGggPT09IDApIHtcclxuICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gbmV3IFZhbGlkYXRpb25FcnJvcignU3VibWlzc2lvbiBkYXRhIGlzIHJlcXVpcmVkJykpO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGJvZHkgPSB7XHJcbiAgICAgIGZvcm1JZDogb3B0aW9ucy5mb3JtSWQsXHJcbiAgICAgIGRhdGE6IG9wdGlvbnMuZGF0YVxyXG4gICAgfTtcclxuXHJcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3Q8Rm9ybVN1Ym1pc3Npb25SZXNwb25zZT4oXHJcbiAgICAgIGAke3RoaXMuYXBpVXJsfS9hcGkvc3VibWlzc2lvbnNgLFxyXG4gICAgICBib2R5LFxyXG4gICAgICB7IGhlYWRlcnM6IHRoaXMuZ2V0SGVhZGVycygpIH0sXHJcbiAgICAgIHRoaXMucmV0cnlDb3VudCxcclxuICAgICAgdGhpcy5yZXRyeURlbGF5XHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IGZvcm0gYnkgSUQgb3Igc2x1Z1xyXG4gICAqL1xyXG4gIGdldEZvcm0oZm9ybUlkT3JTbHVnOiBzdHJpbmcpOiBPYnNlcnZhYmxlPEZvcm1Db25maWc+IHtcclxuICAgIGlmICghdGhpcy5hcGlLZXkpIHtcclxuICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gbmV3IE1ldGlnYW5FcnJvcignU2VydmljZSBub3QgaW5pdGlhbGl6ZWQuIENhbGwgaW5pdGlhbGl6ZSgpIGZpcnN0LicpKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIWZvcm1JZE9yU2x1Zykge1xyXG4gICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBuZXcgVmFsaWRhdGlvbkVycm9yKCdGb3JtIElEIG9yIHNsdWcgaXMgcmVxdWlyZWQnKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8Rm9ybUNvbmZpZz4oXHJcbiAgICAgIGAke3RoaXMuYXBpVXJsfS9hcGkvZm9ybXMvJHtmb3JtSWRPclNsdWd9YCxcclxuICAgICAgeyBoZWFkZXJzOiB0aGlzLmdldEhlYWRlcnMoKSB9LFxyXG4gICAgICB0aGlzLnJldHJ5Q291bnQsXHJcbiAgICAgIHRoaXMucmV0cnlEZWxheVxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCBwdWJsaWMgZm9ybSBieSBzbHVnXHJcbiAgICovXHJcbiAgZ2V0UHVibGljRm9ybShzbHVnOiBzdHJpbmcpOiBPYnNlcnZhYmxlPEZvcm1Db25maWc+IHtcclxuICAgIGlmICghc2x1Zykge1xyXG4gICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBuZXcgVmFsaWRhdGlvbkVycm9yKCdGb3JtIHNsdWcgaXMgcmVxdWlyZWQnKSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gUHVibGljIGZvcm1zIGRvbid0IHJlcXVpcmUgQVBJIGtleVxyXG4gICAgcmV0dXJuIHRoaXMuaHR0cC5nZXQ8Rm9ybUNvbmZpZz4oXHJcbiAgICAgIGAke3RoaXMuYXBpVXJsfS9mLyR7c2x1Z30vYXBpYCxcclxuICAgICAge30sXHJcbiAgICAgIHRoaXMucmV0cnlDb3VudCxcclxuICAgICAgdGhpcy5yZXRyeURlbGF5XHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogTGlzdCBhbGwgZm9ybXNcclxuICAgKi9cclxuICBsaXN0Rm9ybXMob3B0aW9ucz86IFBhZ2luYXRpb25PcHRpb25zKTogT2JzZXJ2YWJsZTxGb3JtTGlzdFJlc3BvbnNlPiB7XHJcbiAgICBpZiAoIXRoaXMuYXBpS2V5KSB7XHJcbiAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IG5ldyBNZXRpZ2FuRXJyb3IoJ1NlcnZpY2Ugbm90IGluaXRpYWxpemVkLiBDYWxsIGluaXRpYWxpemUoKSBmaXJzdC4nKSk7XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IHBhcmFtcyA9IG5ldyBIdHRwUGFyYW1zKCk7XHJcbiAgICBpZiAob3B0aW9ucz8ucGFnZSkge1xyXG4gICAgICBwYXJhbXMgPSBwYXJhbXMuc2V0KCdwYWdlJywgb3B0aW9ucy5wYWdlLnRvU3RyaW5nKCkpO1xyXG4gICAgfVxyXG4gICAgaWYgKG9wdGlvbnM/LmxpbWl0KSB7XHJcbiAgICAgIHBhcmFtcyA9IHBhcmFtcy5zZXQoJ2xpbWl0Jywgb3B0aW9ucy5saW1pdC50b1N0cmluZygpKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdGhpcy5odHRwLmdldDxGb3JtTGlzdFJlc3BvbnNlPihcclxuICAgICAgYCR7dGhpcy5hcGlVcmx9L2FwaS9mb3Jtc2AsXHJcbiAgICAgIHtcclxuICAgICAgICBoZWFkZXJzOiB0aGlzLmdldEhlYWRlcnMoKSxcclxuICAgICAgICBwYXJhbXM6IHBhcmFtc1xyXG4gICAgICB9LFxyXG4gICAgICB0aGlzLnJldHJ5Q291bnQsXHJcbiAgICAgIHRoaXMucmV0cnlEZWxheVxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENyZWF0ZSBhIG5ldyBmb3JtXHJcbiAgICovXHJcbiAgY3JlYXRlRm9ybShjb25maWc6IE9taXQ8Rm9ybUNvbmZpZywgJ2lkJz4pOiBPYnNlcnZhYmxlPEZvcm1Db25maWc+IHtcclxuICAgIGlmICghdGhpcy5hcGlLZXkpIHtcclxuICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gbmV3IE1ldGlnYW5FcnJvcignU2VydmljZSBub3QgaW5pdGlhbGl6ZWQuIENhbGwgaW5pdGlhbGl6ZSgpIGZpcnN0LicpKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIWNvbmZpZy50aXRsZSkge1xyXG4gICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBuZXcgVmFsaWRhdGlvbkVycm9yKCdGb3JtIHRpdGxlIGlzIHJlcXVpcmVkJykpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghY29uZmlnLmZpZWxkcyB8fCBjb25maWcuZmllbGRzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBuZXcgVmFsaWRhdGlvbkVycm9yKCdBdCBsZWFzdCBvbmUgZmllbGQgaXMgcmVxdWlyZWQnKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHRoaXMuaHR0cC5wb3N0PEZvcm1Db25maWc+KFxyXG4gICAgICBgJHt0aGlzLmFwaVVybH0vYXBpL2Zvcm1zYCxcclxuICAgICAgY29uZmlnLFxyXG4gICAgICB7IGhlYWRlcnM6IHRoaXMuZ2V0SGVhZGVycygpIH0sXHJcbiAgICAgIHRoaXMucmV0cnlDb3VudCxcclxuICAgICAgdGhpcy5yZXRyeURlbGF5XHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVXBkYXRlIGFuIGV4aXN0aW5nIGZvcm1cclxuICAgKi9cclxuICB1cGRhdGVGb3JtKGZvcm1JZDogc3RyaW5nLCBjb25maWc6IFBhcnRpYWw8Rm9ybUNvbmZpZz4pOiBPYnNlcnZhYmxlPEZvcm1Db25maWc+IHtcclxuICAgIGlmICghdGhpcy5hcGlLZXkpIHtcclxuICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gbmV3IE1ldGlnYW5FcnJvcignU2VydmljZSBub3QgaW5pdGlhbGl6ZWQuIENhbGwgaW5pdGlhbGl6ZSgpIGZpcnN0LicpKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIWZvcm1JZCkge1xyXG4gICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBuZXcgVmFsaWRhdGlvbkVycm9yKCdGb3JtIElEIGlzIHJlcXVpcmVkJykpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzLmh0dHAucHV0PEZvcm1Db25maWc+KFxyXG4gICAgICBgJHt0aGlzLmFwaVVybH0vYXBpL2Zvcm1zLyR7Zm9ybUlkfWAsXHJcbiAgICAgIGNvbmZpZyxcclxuICAgICAgeyBoZWFkZXJzOiB0aGlzLmdldEhlYWRlcnMoKSB9LFxyXG4gICAgICB0aGlzLnJldHJ5Q291bnQsXHJcbiAgICAgIHRoaXMucmV0cnlEZWxheVxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIERlbGV0ZSBhIGZvcm1cclxuICAgKi9cclxuICBkZWxldGVGb3JtKGZvcm1JZDogc3RyaW5nKTogT2JzZXJ2YWJsZTx2b2lkPiB7XHJcbiAgICBpZiAoIXRoaXMuYXBpS2V5KSB7XHJcbiAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IG5ldyBNZXRpZ2FuRXJyb3IoJ1NlcnZpY2Ugbm90IGluaXRpYWxpemVkLiBDYWxsIGluaXRpYWxpemUoKSBmaXJzdC4nKSk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCFmb3JtSWQpIHtcclxuICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gbmV3IFZhbGlkYXRpb25FcnJvcignRm9ybSBJRCBpcyByZXF1aXJlZCcpKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdGhpcy5odHRwLmRlbGV0ZTx2b2lkPihcclxuICAgICAgYCR7dGhpcy5hcGlVcmx9L2FwaS9mb3Jtcy8ke2Zvcm1JZH1gLFxyXG4gICAgICB7IGhlYWRlcnM6IHRoaXMuZ2V0SGVhZGVycygpIH0sXHJcbiAgICAgIHRoaXMucmV0cnlDb3VudCxcclxuICAgICAgdGhpcy5yZXRyeURlbGF5XHJcbiAgICApO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IGZvcm0gYW5hbHl0aWNzXHJcbiAgICovXHJcbiAgZ2V0QW5hbHl0aWNzKGZvcm1JZDogc3RyaW5nKTogT2JzZXJ2YWJsZTxhbnk+IHtcclxuICAgIGlmICghdGhpcy5hcGlLZXkpIHtcclxuICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gbmV3IE1ldGlnYW5FcnJvcignU2VydmljZSBub3QgaW5pdGlhbGl6ZWQuIENhbGwgaW5pdGlhbGl6ZSgpIGZpcnN0LicpKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIWZvcm1JZCkge1xyXG4gICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBuZXcgVmFsaWRhdGlvbkVycm9yKCdGb3JtIElEIGlzIHJlcXVpcmVkJykpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PGFueT4oXHJcbiAgICAgIGAke3RoaXMuYXBpVXJsfS9hcGkvZm9ybXMvJHtmb3JtSWR9L2FuYWx5dGljc2AsXHJcbiAgICAgIHsgaGVhZGVyczogdGhpcy5nZXRIZWFkZXJzKCkgfSxcclxuICAgICAgdGhpcy5yZXRyeUNvdW50LFxyXG4gICAgICB0aGlzLnJldHJ5RGVsYXlcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBQdWJsaXNoIGEgZm9ybVxyXG4gICAqL1xyXG4gIHB1Ymxpc2hGb3JtKGZvcm1JZDogc3RyaW5nLCBzbHVnOiBzdHJpbmcpOiBPYnNlcnZhYmxlPHsgcHVibGlzaGVkVXJsOiBzdHJpbmc7IHNsdWc6IHN0cmluZyB9PiB7XHJcbiAgICBpZiAoIXRoaXMuYXBpS2V5KSB7XHJcbiAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IG5ldyBNZXRpZ2FuRXJyb3IoJ1NlcnZpY2Ugbm90IGluaXRpYWxpemVkLiBDYWxsIGluaXRpYWxpemUoKSBmaXJzdC4nKSk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCFmb3JtSWQpIHtcclxuICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gbmV3IFZhbGlkYXRpb25FcnJvcignRm9ybSBJRCBpcyByZXF1aXJlZCcpKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIXNsdWcpIHtcclxuICAgICAgcmV0dXJuIHRocm93RXJyb3IoKCkgPT4gbmV3IFZhbGlkYXRpb25FcnJvcignU2x1ZyBpcyByZXF1aXJlZCcpKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdGhpcy5odHRwLnBvc3Q8eyBwdWJsaXNoZWRVcmw6IHN0cmluZzsgc2x1Zzogc3RyaW5nIH0+KFxyXG4gICAgICBgJHt0aGlzLmFwaVVybH0vYXBpL2Zvcm1zLyR7Zm9ybUlkfS9wdWJsaXNoYCxcclxuICAgICAgeyBzbHVnIH0sXHJcbiAgICAgIHsgaGVhZGVyczogdGhpcy5nZXRIZWFkZXJzKCkgfSxcclxuICAgICAgdGhpcy5yZXRyeUNvdW50LFxyXG4gICAgICB0aGlzLnJldHJ5RGVsYXlcclxuICAgICk7XHJcbiAgfVxyXG59XHJcblxyXG4iXX0=
|