UNPKG

71.7 kBJavaScriptView Raw
1"use strict";
2
3var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
4
5var querystring = require("querystring");
6
7var msgpath = {
8 host: "rest.nexmo.com",
9 path: "/sms/json"
10};
11var shortcodePath = {
12 host: "rest.nexmo.com",
13 path: "/sc/us/${type}/json"
14};
15var ttsEndpoint = {
16 host: "api.nexmo.com",
17 path: "/tts/json"
18};
19var ttsPromptEndpoint = {
20 host: "api.nexmo.com",
21 path: "/tts-prompt/json"
22};
23var callEndpoint = {
24 host: "rest.nexmo.com",
25 path: "/call/json"
26};
27var verifyEndpoint = {
28 host: "api.nexmo.com",
29 path: "/verify/json"
30};
31var checkVerifyEndpoint = {
32 host: "api.nexmo.com",
33 path: "/verify/check/json"
34};
35var controlVerifyEndpoint = {
36 host: "api.nexmo.com",
37 path: "/verify/control/json"
38};
39var searchVerifyEndpoint = {
40 host: "api.nexmo.com",
41 path: "/verify/search/json"
42};
43var niEndpoint = {
44 host: "api.nexmo.com",
45 path: "/ni/advanced/async/json"
46};
47var niBasicEndpoint = {
48 host: "api.nexmo.com",
49 path: "/ni/basic/json"
50};
51var niStandardEndpoint = {
52 host: "api.nexmo.com",
53 path: "/ni/standard/json"
54};
55var niAdvancedEndpoint = {
56 host: "api.nexmo.com",
57 path: "/ni/advanced/json"
58};
59var up = {};
60var numberPattern = new RegExp("^[0-9 +()-]*$");
61
62var _options = null;
63
64// Error message resources are maintained globally in one place for easy management
65var ERROR_MESSAGES = {
66 sender: "Invalid from address",
67 to: "Invalid to address",
68 msg: "Invalid Text Message",
69 msgParams: "Invalid shortcode message parameters",
70 countrycode: "Invalid Country Code",
71 msisdn: "Invalid MSISDN passed",
72 body: "Invalid Body value in Binary Message",
73 udh: "Invalid udh value in Binary Message",
74 title: "Invalid title in WAP Push message",
75 url: "Invalid url in WAP Push message",
76 maxDigits: "Invalid max digits for TTS prompt",
77 byeText: "Invalid bye text for TTS prompt",
78 pinCode: "Invalid pin code for TTS confirm",
79 failedText: "Invalid failed text for TTS confirm",
80 answerUrl: "Invalid answer URL for call",
81 verifyValidation: "Missing Mandatory fields (number and/or brand)",
82 checkVerifyValidation: "Missing Mandatory fields (request_id and/or code)",
83 controlVerifyValidation: "Missing Mandatory fields (request_id and/or cmd-command)",
84 searchVerifyValidation: "Missing Mandatory fields (request_id or request_ids)",
85 numberInsightAdvancedValidation: "Missing Mandatory fields (number and/or callback url)",
86 numberInsightValidation: "Missing Mandatory field - number",
87 numberInsightPatternFailure: "Number can contain digits and may include any or all of the following: white space, -,+, (, ).",
88 optionsNotAnObject: "Options parameter should be a dictionary. Check the docs for valid properties for options",
89 product: "Invalid product. Should be one of [voice, sms]"
90};
91
92exports.initialize = function (pkey, psecret, options, hosts) {
93 if (!pkey || !psecret) {
94 throw "key and secret cannot be empty, set valid values";
95 }
96 up = {
97 api_key: pkey,
98 api_secret: psecret
99 };
100 _options = options;
101
102 if (_options.restHost) {
103 msgpath.host = _options.restHost;
104 shortcodePath.host = _options.restHost;
105 callEndpoint.host = _options.restHost;
106 }
107
108 if (_options.apiHost) {
109 ttsEndpoint.host = _options.apiHost;
110 ttsPromptEndpoint.host = _options.apiHost;
111 verifyEndpoint.host = _options.apiHost;
112 checkVerifyEndpoint.host = _options.apiHost;
113 controlVerifyEndpoint.host = _options.apiHost;
114 searchVerifyEndpoint.host = _options.apiHost;
115 niEndpoint.host = _options.apiHost;
116 niBasicEndpoint.host = _options.apiHost;
117 niStandardEndpoint.host = _options.apiHost;
118 niAdvancedEndpoint.host = _options.apiHost;
119 }
120};
121
122exports.sendBinaryMessage = function (sender, recipient, body, udh, callback) {
123 if (!body) {
124 sendError(callback, new Error(ERROR_MESSAGES.body));
125 } else if (!udh) {
126 sendError(callback, new Error(ERROR_MESSAGES.udh));
127 } else {
128 sendMessage({
129 from: sender,
130 to: recipient,
131 type: "binary",
132 body: body,
133 udh: udh
134 }, callback);
135 }
136};
137
138exports.sendWapPushMessage = function (sender, recipient, title, url, validity, callback) {
139 if (!title) {
140 sendError(callback, new Error(ERROR_MESSAGES.title));
141 } else if (!url) {
142 sendError(callback, new Error(ERROR_MESSAGES.url));
143 } else {
144 if (typeof validity === "function") {
145 callback = validity;
146 validity = 86400000;
147 }
148 sendMessage({
149 from: sender,
150 to: recipient,
151 type: "wappush",
152 title: title,
153 validity: validity,
154 url: url
155 }, callback);
156 }
157};
158
159exports.sendTextMessage = function (sender, recipient, message, opts, callback) {
160 if (!message) {
161 sendError(callback, new Error(ERROR_MESSAGES.msg));
162 } else {
163 if (!callback) {
164 callback = opts;
165 opts = {};
166 }
167 opts["from"] = sender;
168 opts["to"] = recipient;
169 opts["text"] = message;
170 sendMessage(opts, callback);
171 }
172};
173
174exports.sendMessage = function (opts, callback) {
175 sendMessage(opts, callback);
176};
177function sendMessage(data, callback) {
178 if (!data.from) {
179 sendError(callback, new Error(ERROR_MESSAGES.sender));
180 } else if (!data.to) {
181 sendError(callback, new Error(ERROR_MESSAGES.to));
182 } else {
183 var path = clone(msgpath);
184 path.path += "?" + querystring.stringify(data);
185 _options.logger.info("sending message from " + data.from + " to " + data.to + " with message " + data.text);
186 sendRequest(path, "POST", function (err, apiResponse) {
187 if (!err && apiResponse.status && apiResponse.messages[0].status > 0) {
188 sendError(callback, new Error(apiResponse.messages[0]["error-text"]), apiResponse);
189 } else {
190 if (callback) callback(err, apiResponse);
191 }
192 });
193 }
194}
195
196function sendViaShortcode(type, recipient, messageParams, opts, callback) {
197 if (!recipient) {
198 sendError(callback, new Error(ERROR_MESSAGES.to));
199 }
200 if (!messageParams || !Object.keys(messageParams)) {
201 sendError(callback, new Error(ERROR_MESSAGES.msgParams));
202 }
203 opts = opts || {};
204 var path = clone(shortcodePath);
205 path.path = path.path.replace("${type}", type);
206 Object.keys(messageParams).forEach(function (key) {
207 opts[key] = messageParams[key];
208 });
209 opts.to = recipient;
210 path.path += "?" + querystring.stringify(opts);
211 _options.logger.info("sending message from shortcode " + type + " to " + recipient + " with parameters " + JSON.stringify(messageParams));
212 sendRequest(path, "POST", function (err, apiResponse) {
213 if (!err && apiResponse.status && apiResponse.messages[0].status > 0) {
214 sendError(callback, new Error(apiResponse.messages[0]["error-text"]), apiResponse);
215 } else {
216 if (callback) callback(err, apiResponse);
217 }
218 });
219}
220exports.shortcodeAlert = function (recipient, messageParams, opts, callback) {
221 sendViaShortcode("alert", recipient, messageParams, opts, callback);
222};
223exports.shortcode2FA = function (recipient, messageParams, opts, callback) {
224 sendViaShortcode("2fa", recipient, messageParams, opts, callback);
225};
226exports.shortcodeMarketing = function (recipient, messageParams, opts, callback) {
227 sendViaShortcode("marketing", recipient, messageParams, opts, callback);
228};
229
230function clone(a) {
231 return JSON.parse(JSON.stringify(a));
232}
233
234function getEndpoint(action) {
235 return { path: action };
236}
237
238function sendRequest(endpoint, method, callback) {
239 endpoint.path = endpoint.path + (endpoint.path.indexOf("?") > 0 ? "&" : "?") + querystring.stringify(up);
240 _options.httpClient.request(endpoint, method, callback);
241}
242
243exports.checkBalance = function (callback) {
244 var balanceEndpoint = getEndpoint("/account/get-balance");
245 sendRequest(balanceEndpoint, callback);
246};
247
248exports.getNumbers = function (options, callback) {
249 var numbersEndpoint = getEndpoint("/account/numbers");
250 if (typeof options === "function") {
251 callback = options;
252 } else if ((typeof options === "undefined" ? "undefined" : _typeof(options)) === "object") {
253 numbersEndpoint.path = numbersEndpoint.path + "?";
254 for (var key in options) {
255 numbersEndpoint.path = numbersEndpoint.path + key + "=" + options[key] + "&";
256 }
257 } else {
258 sendError(callback, new Error(ERROR_MESSAGES.optionsNotAnObject));
259 return;
260 }
261 sendRequest(numbersEndpoint, callback);
262};
263
264exports.searchNumbers = function (countryCode, pattern, callback) {
265 if (!countryCode || countryCode.length !== 2) {
266 sendError(callback, new Error(ERROR_MESSAGES.countrycode));
267 } else {
268 var searchEndpoint = getEndpoint("/number/search");
269 searchEndpoint.path += "?country=" + countryCode;
270 if (typeof pattern === "function") {
271 callback = pattern;
272 } else if ((typeof pattern === "undefined" ? "undefined" : _typeof(pattern)) === "object") {
273 searchEndpoint.path = searchEndpoint.path + "&";
274 for (var arg in pattern) {
275 searchEndpoint.path = searchEndpoint.path + arg + "=" + pattern[arg] + "&";
276 }
277 } else {
278 searchEndpoint.path = searchEndpoint.path + "&pattern=" + pattern;
279 }
280 sendRequest(searchEndpoint, callback);
281 }
282};
283
284exports.buyNumber = function (countryCode, msisdn, callback) {
285 if (!countryCode || countryCode.length !== 2) {
286 sendError(callback, new Error(ERROR_MESSAGES.countrycode));
287 } else if (!msisdn) {
288 sendError(callback, new Error(ERROR_MESSAGES.msisdn));
289 } else {
290 var buyEndpoint = getEndpoint("/number/buy");
291 buyEndpoint.path += "?country=" + countryCode + "&msisdn=" + msisdn;
292 sendRequest(buyEndpoint, "POST", callback);
293 }
294};
295
296exports.cancelNumber = function (countryCode, msisdn, callback) {
297 if (!countryCode || countryCode.length !== 2) {
298 sendError(callback, new Error(ERROR_MESSAGES.countrycode));
299 } else if (!msisdn) {
300 sendError(callback, new Error(ERROR_MESSAGES.msisdn));
301 } else {
302 var cancelEndpoint = getEndpoint("/number/cancel");
303 cancelEndpoint.path += "?country=" + countryCode + "&msisdn=" + msisdn;
304 sendRequest(cancelEndpoint, "POST", callback);
305 }
306};
307
308exports.cancelNumber = function (countryCode, msisdn, callback) {
309 if (!countryCode || countryCode.length !== 2) {
310 sendError(callback, new Error(ERROR_MESSAGES.countrycode));
311 } else if (!msisdn) {
312 sendError(callback, new Error(ERROR_MESSAGES.msisdn));
313 } else {
314 var cancelEndpoint = getEndpoint("/number/cancel");
315 cancelEndpoint.path += "?country=" + countryCode + "&msisdn=" + msisdn;
316 sendRequest(cancelEndpoint, "POST", callback);
317 }
318};
319
320exports.updateNumber = function (countryCode, msisdn, params, callback) {
321 if (!countryCode || countryCode.length !== 2) {
322 sendError(callback, new Error(ERROR_MESSAGES.countrycode));
323 } else if (!msisdn) {
324 sendError(callback, new Error(ERROR_MESSAGES.msisdn));
325 } else {
326 var updateEndpoint = getEndpoint("/number/update");
327 updateEndpoint.path += "?country=" + countryCode + "&msisdn=" + msisdn;
328 updateEndpoint.path = updateEndpoint.path + "&";
329 for (var arg in params) {
330 updateEndpoint.path = updateEndpoint.path + arg + "=" + encodeURIComponent(params[arg]) + "&";
331 }
332 sendRequest(updateEndpoint, "POST", callback);
333 }
334};
335
336exports.changePassword = function (newSecret, callback) {
337 var settingsEndpoint = getEndpoint("/account/settings");
338 settingsEndpoint.path += "?newSecret=" + encodeURIComponent(newSecret);
339 sendRequest(settingsEndpoint, "POST", callback);
340};
341
342exports.changeMoCallbackUrl = function (newUrl, callback) {
343 var settingsEndpoint = getEndpoint("/account/settings");
344 settingsEndpoint.path += "?moCallBackUrl=" + encodeURIComponent(newUrl);
345 sendRequest(settingsEndpoint, "POST", callback);
346};
347
348exports.changeDrCallbackUrl = function (newUrl, callback) {
349 var settingsEndpoint = getEndpoint("/account/settings");
350 settingsEndpoint.path += "?drCallBackUrl=" + encodeURIComponent(newUrl);
351 sendRequest(settingsEndpoint, "POST", callback);
352};
353
354exports.verifyNumber = function (inputParams, callback) {
355 if (!inputParams.number || !inputParams.brand) {
356 sendError(callback, new Error(ERROR_MESSAGES.verifyValidation));
357 } else {
358 var vEndpoint = clone(verifyEndpoint);
359 vEndpoint.path += "?" + querystring.stringify(inputParams);
360 sendRequest(vEndpoint, callback);
361 }
362};
363
364exports.checkVerifyRequest = function (inputParams, callback) {
365 if (!inputParams.request_id || !inputParams.code) {
366 sendError(callback, new Error(ERROR_MESSAGES.checkVerifyValidation));
367 } else {
368 var vEndpoint = clone(checkVerifyEndpoint);
369 vEndpoint.path += "?" + querystring.stringify(inputParams);
370 sendRequest(vEndpoint, callback);
371 }
372};
373
374exports.controlVerifyRequest = function (inputParams, callback) {
375 if (!inputParams.request_id || !inputParams.cmd) {
376 sendError(callback, new Error(ERROR_MESSAGES.controlVerifyValidation));
377 } else {
378 var vEndpoint = clone(controlVerifyEndpoint);
379 vEndpoint.path += "?" + querystring.stringify(inputParams);
380 sendRequest(vEndpoint, callback);
381 }
382};
383
384exports.searchVerifyRequest = function (requestIds, callback) {
385 var requestIdParam = {};
386 if (!requestIds) {
387 sendError(callback, new Error(ERROR_MESSAGES.searchVerifyValidation));
388 } else {
389 if (Array.isArray(requestIds)) {
390 if (requestIds.length === 1) {
391 requestIdParam.request_id = requestIds;
392 } else {
393 requestIdParam.request_ids = requestIds;
394 }
395 } else {
396 requestIdParam.request_id = requestIds;
397 }
398 var vEndpoint = clone(searchVerifyEndpoint);
399 vEndpoint.path += "?" + querystring.stringify(requestIdParam);
400 sendRequest(vEndpoint, callback);
401 }
402};
403
404exports.numberInsight = function (inputParams, callback) {
405 numberInsightAsync(inputParams, callback);
406};
407
408exports.numberInsightBasic = function (inputParams, callback) {
409 numberInsightCommon(niBasicEndpoint, inputParams, callback);
410};
411
412exports.numberInsightStandard = function (inputParams, callback) {
413 numberInsightCommon(niStandardEndpoint, inputParams, callback);
414};
415
416exports.numberInsightAdvanced = function (inputParams, callback) {
417 numberInsightCommon(niAdvancedEndpoint, inputParams, callback);
418};
419
420exports.numberInsightAdvancedAsync = function (inputParams, callback) {
421 numberInsightAsync(inputParams, callback);
422};
423
424function numberInsightAsync(inputParams, callback) {
425 if (!inputParams.number || !inputParams.callback) {
426 sendError(callback, new Error(ERROR_MESSAGES.numberInsightAdvancedValidation));
427 } else {
428 var nEndpoint = clone(niEndpoint);
429 nEndpoint.path += "?" + querystring.stringify(inputParams);
430 sendRequest(nEndpoint, callback);
431 }
432}
433
434function numberInsightCommon(endpoint, inputParams, callback) {
435 if (validateNumber(inputParams, callback)) {
436 var inputObj;
437 if ((typeof inputParams === "undefined" ? "undefined" : _typeof(inputParams)) !== "object") {
438 inputObj = { number: inputParams };
439 } else {
440 inputObj = inputParams;
441 }
442 var nEndpoint = clone(endpoint);
443 nEndpoint.path += "?" + querystring.stringify(inputObj);
444 sendRequest(nEndpoint, callback);
445 }
446}
447function validateNumber(inputParams, callback) {
448 if ((typeof inputParams === "undefined" ? "undefined" : _typeof(inputParams)) === "object" && !inputParams.number) {
449 sendError(callback, new Error(ERROR_MESSAGES.numberInsightValidation));
450 return false;
451 } else if ((typeof inputParams === "undefined" ? "undefined" : _typeof(inputParams)) === "object" && !numberPattern.test(inputParams.number)) {
452 sendError(callback, new Error(ERROR_MESSAGES.numberInsightPatternFailure));
453 return false;
454 } else if ((typeof inputParams === "undefined" ? "undefined" : _typeof(inputParams)) !== "object" && (!inputParams || !numberPattern.test(inputParams))) {
455 sendError(callback, new Error(ERROR_MESSAGES.numberInsightPatternFailure));
456 return false;
457 }
458 return true;
459}
460
461function sendVoiceMessage(voiceEndpoint, data, callback) {
462 if (!data.to) {
463 sendError(callback, new Error(ERROR_MESSAGES.to));
464 } else {
465 var endpoint = clone(voiceEndpoint);
466 endpoint.path += "?" + querystring.stringify(data);
467 _options.logger.info("sending TTS message to " + data.to + " with message " + data.text);
468 sendRequest(endpoint, "POST", function (err, apiResponse) {
469 if (!err && apiResponse.status && apiResponse.status > 0) {
470 sendError(callback, new Error(apiResponse["error-text"]), apiResponse);
471 } else {
472 if (callback) callback(err, apiResponse);
473 }
474 });
475 }
476}
477
478exports.sendTTSMessage = function (recipient, message, opts, callback) {
479 if (!message) {
480 sendError(callback, new Error(ERROR_MESSAGES.msg));
481 } else {
482 if (!opts) {
483 opts = {};
484 }
485 opts["to"] = recipient;
486 opts["text"] = message;
487 sendVoiceMessage(ttsEndpoint, opts, callback);
488 }
489};
490
491exports.sendTTSPromptWithCapture = function (recipient, message, maxDigits, byeText, opts, callback) {
492 if (!message) {
493 sendError(callback, new Error(ERROR_MESSAGES.msg));
494 } else if (!maxDigits || isNaN(maxDigits) || maxDigits.length > 16) {
495 sendError(callback, new Error(ERROR_MESSAGES.maxDigits));
496 } else if (!byeText) {
497 sendError(callback, new Error(ERROR_MESSAGES.byeText));
498 } else {
499 if (!opts) {
500 opts = {};
501 }
502 opts["to"] = recipient;
503 opts["text"] = message;
504 opts["max_digits"] = maxDigits;
505 opts["bye_text"] = byeText;
506 sendVoiceMessage(ttsPromptEndpoint, opts, callback);
507 }
508};
509
510exports.sendTTSPromptWithConfirm = function (recipient, message, maxDigits, pinCode, byeText, failedText, opts, callback) {
511 if (!message) {
512 sendError(callback, new Error(ERROR_MESSAGES.msg));
513 } else if (!maxDigits || isNaN(maxDigits) || maxDigits.length > 16) {
514 sendError(callback, new Error(ERROR_MESSAGES.maxDigits));
515 } else if (!pinCode || pinCode.length !== maxDigits) {
516 sendError(callback, new Error(ERROR_MESSAGES.pinCode));
517 } else if (!byeText) {
518 sendError(callback, new Error(ERROR_MESSAGES.byeText));
519 } else if (!failedText) {
520 sendError(callback, new Error(ERROR_MESSAGES.failedText));
521 } else {
522 if (!opts) {
523 opts = {};
524 }
525 opts["to"] = recipient;
526 opts["text"] = message;
527 opts["max_digits"] = maxDigits;
528 opts["pin_code"] = pinCode;
529 opts["bye_text"] = byeText;
530 opts["failed_text"] = failedText;
531 sendVoiceMessage(ttsPromptEndpoint, opts, callback);
532 }
533};
534
535exports.call = function (recipient, answerUrl, opts, callback) {
536 if (!answerUrl) {
537 sendError(callback, new Error(ERROR_MESSAGES.answerUrl));
538 } else {
539 if (!opts) {
540 opts = {};
541 }
542 opts["to"] = recipient;
543 opts["answer_url"] = answerUrl;
544 sendVoiceMessage(callEndpoint, opts, callback);
545 }
546};
547
548function sendError(callback, err, returnData) {
549 // Throw the error in case if there is no callback passed
550 if (callback) {
551 callback(err, returnData);
552 } else {
553 throw err;
554 }
555}
556//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9pbmRleC5qcyJdLCJuYW1lcyI6WyJxdWVyeXN0cmluZyIsInJlcXVpcmUiLCJtc2dwYXRoIiwiaG9zdCIsInBhdGgiLCJzaG9ydGNvZGVQYXRoIiwidHRzRW5kcG9pbnQiLCJ0dHNQcm9tcHRFbmRwb2ludCIsImNhbGxFbmRwb2ludCIsInZlcmlmeUVuZHBvaW50IiwiY2hlY2tWZXJpZnlFbmRwb2ludCIsImNvbnRyb2xWZXJpZnlFbmRwb2ludCIsInNlYXJjaFZlcmlmeUVuZHBvaW50IiwibmlFbmRwb2ludCIsIm5pQmFzaWNFbmRwb2ludCIsIm5pU3RhbmRhcmRFbmRwb2ludCIsIm5pQWR2YW5jZWRFbmRwb2ludCIsInVwIiwibnVtYmVyUGF0dGVybiIsIlJlZ0V4cCIsIl9vcHRpb25zIiwiRVJST1JfTUVTU0FHRVMiLCJzZW5kZXIiLCJ0byIsIm1zZyIsIm1zZ1BhcmFtcyIsImNvdW50cnljb2RlIiwibXNpc2RuIiwiYm9keSIsInVkaCIsInRpdGxlIiwidXJsIiwibWF4RGlnaXRzIiwiYnllVGV4dCIsInBpbkNvZGUiLCJmYWlsZWRUZXh0IiwiYW5zd2VyVXJsIiwidmVyaWZ5VmFsaWRhdGlvbiIsImNoZWNrVmVyaWZ5VmFsaWRhdGlvbiIsImNvbnRyb2xWZXJpZnlWYWxpZGF0aW9uIiwic2VhcmNoVmVyaWZ5VmFsaWRhdGlvbiIsIm51bWJlckluc2lnaHRBZHZhbmNlZFZhbGlkYXRpb24iLCJudW1iZXJJbnNpZ2h0VmFsaWRhdGlvbiIsIm51bWJlckluc2lnaHRQYXR0ZXJuRmFpbHVyZSIsIm9wdGlvbnNOb3RBbk9iamVjdCIsInByb2R1Y3QiLCJleHBvcnRzIiwiaW5pdGlhbGl6ZSIsInBrZXkiLCJwc2VjcmV0Iiwib3B0aW9ucyIsImhvc3RzIiwiYXBpX2tleSIsImFwaV9zZWNyZXQiLCJyZXN0SG9zdCIsImFwaUhvc3QiLCJzZW5kQmluYXJ5TWVzc2FnZSIsInJlY2lwaWVudCIsImNhbGxiYWNrIiwic2VuZEVycm9yIiwiRXJyb3IiLCJzZW5kTWVzc2FnZSIsImZyb20iLCJ0eXBlIiwic2VuZFdhcFB1c2hNZXNzYWdlIiwidmFsaWRpdHkiLCJzZW5kVGV4dE1lc3NhZ2UiLCJtZXNzYWdlIiwib3B0cyIsImRhdGEiLCJjbG9uZSIsInN0cmluZ2lmeSIsImxvZ2dlciIsImluZm8iLCJ0ZXh0Iiwic2VuZFJlcXVlc3QiLCJlcnIiLCJhcGlSZXNwb25zZSIsInN0YXR1cyIsIm1lc3NhZ2VzIiwic2VuZFZpYVNob3J0Y29kZSIsIm1lc3NhZ2VQYXJhbXMiLCJPYmplY3QiLCJrZXlzIiwicmVwbGFjZSIsImZvckVhY2giLCJrZXkiLCJKU09OIiwic2hvcnRjb2RlQWxlcnQiLCJzaG9ydGNvZGUyRkEiLCJzaG9ydGNvZGVNYXJrZXRpbmciLCJhIiwicGFyc2UiLCJnZXRFbmRwb2ludCIsImFjdGlvbiIsImVuZHBvaW50IiwibWV0aG9kIiwiaW5kZXhPZiIsImh0dHBDbGllbnQiLCJyZXF1ZXN0IiwiY2hlY2tCYWxhbmNlIiwiYmFsYW5jZUVuZHBvaW50IiwiZ2V0TnVtYmVycyIsIm51bWJlcnNFbmRwb2ludCIsInNlYXJjaE51bWJlcnMiLCJjb3VudHJ5Q29kZSIsInBhdHRlcm4iLCJsZW5ndGgiLCJzZWFyY2hFbmRwb2ludCIsImFyZyIsImJ1eU51bWJlciIsImJ1eUVuZHBvaW50IiwiY2FuY2VsTnVtYmVyIiwiY2FuY2VsRW5kcG9pbnQiLCJ1cGRhdGVOdW1iZXIiLCJwYXJhbXMiLCJ1cGRhdGVFbmRwb2ludCIsImVuY29kZVVSSUNvbXBvbmVudCIsImNoYW5nZVBhc3N3b3JkIiwibmV3U2VjcmV0Iiwic2V0dGluZ3NFbmRwb2ludCIsImNoYW5nZU1vQ2FsbGJhY2tVcmwiLCJuZXdVcmwiLCJjaGFuZ2VEckNhbGxiYWNrVXJsIiwidmVyaWZ5TnVtYmVyIiwiaW5wdXRQYXJhbXMiLCJudW1iZXIiLCJicmFuZCIsInZFbmRwb2ludCIsImNoZWNrVmVyaWZ5UmVxdWVzdCIsInJlcXVlc3RfaWQiLCJjb2RlIiwiY29udHJvbFZlcmlmeVJlcXVlc3QiLCJjbWQiLCJzZWFyY2hWZXJpZnlSZXF1ZXN0IiwicmVxdWVzdElkcyIsInJlcXVlc3RJZFBhcmFtIiwiQXJyYXkiLCJpc0FycmF5IiwicmVxdWVzdF9pZHMiLCJudW1iZXJJbnNpZ2h0IiwibnVtYmVySW5zaWdodEFzeW5jIiwibnVtYmVySW5zaWdodEJhc2ljIiwibnVtYmVySW5zaWdodENvbW1vbiIsIm51bWJlckluc2lnaHRTdGFuZGFyZCIsIm51bWJlckluc2lnaHRBZHZhbmNlZCIsIm51bWJlckluc2lnaHRBZHZhbmNlZEFzeW5jIiwibkVuZHBvaW50IiwidmFsaWRhdGVOdW1iZXIiLCJpbnB1dE9iaiIsInRlc3QiLCJzZW5kVm9pY2VNZXNzYWdlIiwidm9pY2VFbmRwb2ludCIsInNlbmRUVFNNZXNzYWdlIiwic2VuZFRUU1Byb21wdFdpdGhDYXB0dXJlIiwiaXNOYU4iLCJzZW5kVFRTUHJvbXB0V2l0aENvbmZpcm0iLCJjYWxsIiwicmV0dXJuRGF0YSJdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7QUFFQSxJQUFJQSxjQUFjQyxRQUFRLGFBQVIsQ0FBbEI7O0FBRUEsSUFBSUMsVUFBVTtBQUNaQyxRQUFNLGdCQURNO0FBRVpDLFFBQU07QUFGTSxDQUFkO0FBSUEsSUFBSUMsZ0JBQWdCO0FBQ2xCRixRQUFNLGdCQURZO0FBRWxCQyxRQUFNO0FBRlksQ0FBcEI7QUFJQSxJQUFJRSxjQUFjO0FBQ2hCSCxRQUFNLGVBRFU7QUFFaEJDLFFBQU07QUFGVSxDQUFsQjtBQUlBLElBQUlHLG9CQUFvQjtBQUN0QkosUUFBTSxlQURnQjtBQUV0QkMsUUFBTTtBQUZnQixDQUF4QjtBQUlBLElBQUlJLGVBQWU7QUFDakJMLFFBQU0sZ0JBRFc7QUFFakJDLFFBQU07QUFGVyxDQUFuQjtBQUlBLElBQUlLLGlCQUFpQjtBQUNuQk4sUUFBTSxlQURhO0FBRW5CQyxRQUFNO0FBRmEsQ0FBckI7QUFJQSxJQUFJTSxzQkFBc0I7QUFDeEJQLFFBQU0sZUFEa0I7QUFFeEJDLFFBQU07QUFGa0IsQ0FBMUI7QUFJQSxJQUFJ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cmluZyA9IHJlcXVpcmUoXCJxdWVyeXN0cmluZ1wiKTtcblxudmFyIG1zZ3BhdGggPSB7XG4gIGhvc3Q6IFwicmVzdC5uZXhtby5jb21cIixcbiAgcGF0aDogXCIvc21zL2pzb25cIlxufTtcbnZhciBzaG9ydGNvZGVQYXRoID0ge1xuICBob3N0OiBcInJlc3QubmV4bW8uY29tXCIsXG4gIHBhdGg6IFwiL3NjL3VzLyR7dHlwZX0vanNvblwiXG59O1xudmFyIHR0c0VuZHBvaW50ID0ge1xuICBob3N0OiBcImFwaS5uZXhtby5jb21cIixcbiAgcGF0aDogXCIvdHRzL2pzb25cIlxufTtcbnZhciB0dHNQcm9tcHRFbmRwb2ludCA9IHtcbiAgaG9zdDogXCJhcGkubmV4bW8uY29tXCIsXG4gIHBhdGg6IFwiL3R0cy1wcm9tcHQvanNvblwiXG59O1xudmFyIGNhbGxFbmRwb2ludCA9IHtcbiAgaG9zdDogXCJyZXN0Lm5leG1vLmNvbVwiLFxuICBwYXRoOiBcIi9jYWxsL2pzb25cIlxufTtcbnZhciB2ZXJpZnlFbmRwb2ludCA9IHtcbiAgaG9zdDogXCJhcGkubmV4bW8uY29tXCIsXG4gIHBhdGg6IFwiL3ZlcmlmeS9qc29uXCJcbn07XG52YXIgY2hlY2tWZXJpZnlFbmRwb2ludCA9IHtcbiAgaG9zdDogXCJhcGkubmV4bW8uY29tXCIsXG4gIHBhdGg6IFwiL3ZlcmlmeS9jaGVjay9qc29uXCJcbn07XG52YXIgY29udHJvbFZlcmlmeUVuZHBvaW50ID0ge1xuICBob3N0OiBcImFwaS5uZXhtby5jb21cIixcbiAgcGF0aDogXCIvdmVyaWZ5L2NvbnRyb2wvanNvblwiXG59O1xudmFyIHNlYXJjaFZlcmlmeUVuZHBvaW50ID0ge1xuICBob3N0OiBcImFwaS5uZXhtby5jb21cIixcbiAgcGF0aDogXCIvdmVyaWZ5L3NlYXJjaC9qc29uXCJcbn07XG52YXIgbmlFbmRwb2ludCA9IHtcbiAgaG9zdDogXCJhcGkubmV4bW8uY29tXCIsXG4gIHBhdGg6IFwiL25pL2FkdmFuY2VkL2FzeW5jL2pzb25cIlxufTtcbnZhciBuaUJhc2ljRW5kcG9pbnQgPSB7XG4gIGhvc3Q6IFwiYXBpLm5leG1vLmNvbVwiLFxuICBwYXRoOiBcIi9uaS9iYXNpYy9qc29uXCJcbn07XG52YXIgbmlTdGFuZGFyZEVuZHBvaW50ID0ge1xuICBob3N0OiBcImFwaS5uZXhtby5jb21cIixcbiAgcGF0aDogXCIvbmkvc3RhbmRhcmQvanNvblwiXG59O1xudmFyIG5pQWR2YW5jZWRFbmRwb2ludCA9IHtcbiAgaG9zdDogXCJhcGkubmV4bW8uY29tXCIsXG4gIHBhdGg6IFwiL25pL2FkdmFuY2VkL2pzb25cIlxufTtcbnZhciB1cCA9IHt9O1xudmFyIG51bWJlclBhdHRlcm4gPSBuZXcgUmVnRXhwKFwiXlswLTkgKygpLV0qJFwiKTtcblxudmFyIF9vcHRpb25zID0gbnVsbDtcblxuLy8gRXJyb3IgbWVzc2FnZSByZXNvdXJjZXMgYXJlIG1haW50YWluZWQgZ2xvYmFsbHkgaW4gb25lIHBsYWNlIGZvciBlYXN5IG1hbmFnZW1lbnRcbnZhciBFUlJPUl9NRVNTQUdFUyA9IHtcbiAgc2VuZGVyOiBcIkludmFsaWQgZnJvbSBhZGRyZXNzXCIsXG4gIHRvOiBcIkludmFsaWQgdG8gYWRkcmVzc1wiLFxuICBtc2c6IFwiSW52YWxpZCBUZXh0IE1lc3NhZ2VcIixcbiAgbXNnUGFyYW1zOiBcIkludmFsaWQgc2hvcnRjb2RlIG1lc3NhZ2UgcGFyYW1ldGVyc1wiLFxuICBjb3VudHJ5Y29kZTogXCJJbnZhbGlkIENvdW50cnkgQ29kZVwiLFxuICBtc2lzZG46IFwiSW52YWxpZCBNU0lTRE4gcGFzc2VkXCIsXG4gIGJvZHk6IFwiSW52YWxpZCBCb2R5IHZhbHVlIGluIEJpbmFyeSBNZXNzYWdlXCIsXG4gIHVkaDogXCJJbnZhbGlkIHVkaCB2YWx1ZSBpbiBCaW5hcnkgTWVzc2FnZVwiLFxuICB0aXRsZTogXCJJbnZhbGlkIHRpdGxlIGluIFdBUCBQdXNoIG1lc3NhZ2VcIixcbiAgdXJsOiBcIkludmFsaWQgdXJsIGluIFdBUCBQdXNoIG1lc3NhZ2VcIixcbiAgbWF4RGlnaXRzOiBcIkludmFsaWQgbWF4IGRpZ2l0cyBmb3IgVFRTIHByb21wdFwiLFxuICBieWVUZXh0OiBcIkludmFsaWQgYnllIHRleHQgZm9yIFRUUyBwcm9tcHRcIixcbiAgcGluQ29kZTogXCJJbnZhbGlkIHBpbiBjb2RlIGZvciBUVFMgY29uZmlybVwiLFxuICBmYWlsZWRUZXh0OiBcIkludmFsaWQgZmFpbGVkIHRleHQgZm9yIFRUUyBjb25maXJtXCIsXG4gIGFuc3dlclVybDogXCJJbnZhbGlkIGFuc3dlciBVUkwgZm9yIGNhbGxcIixcbiAgdmVyaWZ5VmFsaWRhdGlvbjogXCJNaXNzaW5nIE1hbmRhdG9yeSBmaWVsZHMgKG51bWJlciBhbmQvb3IgYnJhbmQpXCIsXG4gIGNoZWNrVmVyaWZ5VmFsaWRhdGlvbjogXCJNaXNzaW5nIE1hbmRhdG9yeSBmaWVsZHMgKHJlcXVlc3RfaWQgYW5kL29yIGNvZGUpXCIsXG4gIGNvbnRyb2xWZXJpZnlWYWxpZGF0aW9uOlxuICAgIFwiTWlzc2luZyBNYW5kYXRvcnkgZmllbGRzIChyZXF1ZXN0X2lkIGFuZC9vciBjbWQtY29tbWFuZClcIixcbiAgc2VhcmNoVmVyaWZ5VmFsaWRhdGlvbjpcbiAgICBcIk1pc3NpbmcgTWFuZGF0b3J5IGZpZWxkcyAocmVxdWVzdF9pZCBvciByZXF1ZXN0X2lkcylcIixcbiAgbnVtYmVySW5zaWdodEFkdmFuY2VkVmFsaWRhdGlvbjpcbiAgICBcIk1pc3NpbmcgTWFuZGF0b3J5IGZpZWxkcyAobnVtYmVyIGFuZC9vciBjYWxsYmFjayB1cmwpXCIsXG4gIG51bWJlckluc2lnaHRWYWxpZGF0aW9uOiBcIk1pc3NpbmcgTWFuZGF0b3J5IGZpZWxkIC0gbnVtYmVyXCIsXG4gIG51bWJlckluc2lnaHRQYXR0ZXJuRmFpbHVyZTpcbiAgICBcIk51bWJlciBjYW4gY29udGFpbiBkaWdpdHMgYW5kIG1heSBpbmNsdWRlIGFueSBvciBhbGwgb2YgdGhlIGZvbGxvd2luZzogd2hpdGUgc3BhY2UsIC0sKywgKCwgKS5cIixcbiAgb3B0aW9uc05vdEFuT2JqZWN0OlxuICAgIFwiT3B0aW9ucyBwYXJhbWV0ZXIgc2hvdWxkIGJlIGEgZGljdGlvbmFyeS4gQ2hlY2sgdGhlIGRvY3MgZm9yIHZhbGlkIHByb3BlcnRpZXMgZm9yIG9wdGlvbnNcIixcbiAgcHJvZHVjdDogXCJJbnZhbGlkIHByb2R1Y3QuIFNob3VsZCBiZSBvbmUgb2YgW3ZvaWNlLCBzbXNdXCJcbn07XG5cbmV4cG9ydHMuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uKHBrZXksIHBzZWNyZXQsIG9wdGlvbnMsIGhvc3RzKSB7XG4gIGlmICghcGtleSB8fCAhcHNlY3JldCkge1xuICAgIHRocm93IFwia2V5IGFuZCBzZWNyZXQgY2Fubm90IGJlIGVtcHR5LCBzZXQgdmFsaWQgdmFsdWVzXCI7XG4gIH1cbiAgdXAgPSB7XG4gICAgYXBpX2tleTogcGtleSxcbiAgICBhcGlfc2VjcmV0OiBwc2VjcmV0XG4gIH07XG4gIF9vcHRpb25zID0gb3B0aW9ucztcblxuICBpZiAoX29wdGlvbnMucmVzdEhvc3QpIHtcbiAgICBtc2dwYXRoLmhvc3QgPSBfb3B0aW9ucy5yZXN0SG9zdDtcbiAgICBzaG9ydGNvZGVQYXRoLmhvc3QgPSBfb3B0aW9ucy5yZXN0SG9zdDtcbiAgICBjYWxsRW5kcG9pbnQuaG9zdCA9IF9vcHRpb25zLnJlc3RIb3N0O1xuICB9XG5cbiAgaWYgKF9vcHRpb25zLmFwaUhvc3QpIHtcbiAgICB0dHNFbmRwb2ludC5ob3N0ID0gX29wdGlvbnMuYXBpSG9zdDtcbiAgICB0dHNQcm9tcHRFbmRwb2ludC5ob3N0ID0gX29wdGlvbnMuYXBpSG9zdDtcbiAgICB2ZXJpZnlFbmRwb2ludC5ob3N0ID0gX29wdGlvbnMuYXBpSG9zdDtcbiAgICBjaGVja1ZlcmlmeUVuZHBvaW50Lmhvc3QgPSBfb3B0aW9ucy5hcGlIb3N0O1xuICAgIGNvbnRyb2xWZXJpZnlFbmRwb2ludC5ob3N0ID0gX29wdGlvbnMuYXBpSG9zdDtcbiAgICBzZWFyY2hWZXJpZnlFbmRwb2ludC5ob3N0ID0gX29wdGlvbnMuYXBpSG9zdDtcbiAgICBuaUVuZHBvaW50Lmhvc3QgPSBfb3B0aW9ucy5hcGlIb3N0O1xuICAgIG5pQmFzaWNFbmRwb2ludC5ob3N0ID0gX29wdGlvbnMuYXBpSG9zdDtcbiAgICBuaVN0YW5kYXJkRW5kcG9pbnQuaG9zdCA9IF9vcHRpb25zLmFwaUhvc3Q7XG4gICAgbmlBZHZhbmNlZEVuZHBvaW50Lmhvc3QgPSBfb3B0aW9ucy5hcGlIb3N0O1xuICB9XG59O1xuXG5leHBvcnRzLnNlbmRCaW5hcnlNZXNzYWdlID0gZnVuY3Rpb24oc2VuZGVyLCByZWNpcGllbnQsIGJvZHksIHVkaCwgY2FsbGJhY2spIHtcbiAgaWYgKCFib2R5KSB7XG4gICAgc2VuZEVycm9yKGNhbGxiYWNrLCBuZXcgRXJyb3IoRVJST1JfTUVTU0FHRVMuYm9keSkpO1xuICB9IGVsc2UgaWYgKCF1ZGgpIHtcbiAgICBzZW5kRXJyb3IoY2FsbGJhY2ssIG5ldyBFcnJvcihFUlJPUl9NRVNTQUdFUy51ZGgpKTtcbiAgfSBlbHNlIHtcbiAgICBzZW5kTWVzc2FnZShcbiAgICAgIHtcbiAgICAgICAgZnJvbTogc2VuZGVyLFxuICAgICAgICB0bzogcmVjaXBpZW50LFxuICAgICAgICB0eXBlOiBcImJpbmFyeVwiLFxuICAgICAgICBib2R5OiBib2R5LFxuICAgICAgICB1ZGg6IHVkaFxuICAgICAgfSxcbiAgICAgIGNhbGxiYWNrXG4gICAgKTtcbiAgfVxufTtcblxuZXhwb3J0cy5zZW5kV2FwUHVzaE1lc3NhZ2UgPSBmdW5jdGlvbihcbiAgc2VuZGVyLFxuICByZWNpcGllbnQsXG4gIHRpdGxlLFxuICB1cmwsXG4gIHZhbGlkaXR5LFxuICBjYWxsYmFja1xuKSB7XG4gIGlmICghdGl0bGUpIHtcbiAgICBzZW5kRXJyb3IoY2FsbGJhY2ssIG5ldyBFcnJvcihFUlJPUl9NRVNTQUdFUy50aXRsZSkpO1xuICB9IGVsc2UgaWYgKCF1cmwpIHtcbiAgICBzZW5kRXJyb3IoY2FsbGJhY2ssIG5ldyBFcnJvcihFUlJPUl9NRVNTQUdFUy51cmwpKTtcbiAgfSBlbHNlIHtcbiAgICBpZiAodHlwZW9mIHZhbGlkaXR5ID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIGNhbGxiYWNrID0gdmFsaWRpdHk7XG4gICAgICB2YWxpZGl0eSA9IDg2NDAwMDAwO1xuICAgIH1cbiAgICBzZW5kTWVzc2FnZShcbiAgICAgIHtcbiAgICAgICAgZnJvbTogc2VuZGVyLFxuICAgICAgICB0bzogcmVjaXBpZW50LFxuICAgICAgICB0eXBlOiBcIndhcHB1c2hcIixcbiAgICAgICAgdGl0bGU6IHRpdGxlLFxuICAgICAgICB2YWxpZGl0eTogdmFsaWRpdHksXG4gICAgICAgIHVybDogdXJsXG4gICAgICB9LFxuICAgICAgY2FsbGJhY2tcbiAgICApO1xuICB9XG59O1xuXG5leHBvcnRzLnNlbmRUZXh0TWVzc2FnZSA9IGZ1bmN0aW9uKHNlbmRlciwgcmVjaXBpZW50LCBtZXNzYWdlLCBvcHRzLCBjYWxsYmFjaykge1xuICBpZiAoIW1lc3NhZ2UpIHtcbiAgICBzZW5kRXJyb3IoY2FsbGJhY2ssIG5ldyBFcnJvcihFUlJPUl9NRVNTQUdFUy5tc2cpKTtcbiAgfSBlbHNlIHtcbiAgICBpZiAoIWNhbGxiYWNrKSB7XG4gICAgICBjYWxsYmFjayA9IG9wdHM7XG4gICAgICBvcHRzID0ge307XG4gICAgfVxuICAgIG9wdHNbXCJmcm9tXCJdID0gc2VuZGVyO1xuICAgIG9wdHNbXCJ0b1wiXSA9IHJlY2lwaWVudDtcbiAgICBvcHRzW1widGV4dFwiXSA9IG1lc3NhZ2U7XG4gICAgc2VuZE1lc3NhZ2Uob3B0cywgY2FsbGJhY2spO1xuICB9XG59O1xuXG5leHBvcnRzLnNlbmRNZXNzYWdlID0gZnVuY3Rpb24ob3B0cywgY2FsbGJhY2spIHtcbiAgc2VuZE1lc3NhZ2Uob3B0cywgY2FsbGJhY2spO1xufTtcbmZ1bmN0aW9uIHNlbmRNZXNzYWdlKGRhdGEsIGNhbGxiYWNrKSB7XG4gIGlmICghZGF0YS5mcm9tKSB7XG4gICAgc2VuZEVycm9yKGNhbGxiYWNrLCBuZXcgRXJyb3IoRVJST1JfTUVTU0FHRVMuc2VuZGVyKSk7XG4gIH0gZWxzZSBpZiAoIWRhdGEudG8pIHtcbiAgICBzZW5kRXJyb3IoY2FsbGJhY2ssIG5ldyBFcnJvcihFUlJPUl9NRVNTQUdFUy50bykpO1xuICB9IGVsc2Uge1xuICAgIHZhciBwYXRoID0gY2xvbmUobXNncGF0aCk7XG4gICAgcGF0aC5wYXRoICs9IFwiP1wiICsgcXVlcnlzdHJpbmcuc3RyaW5naWZ5KGRhdGEpO1xuICAgIF9vcHRpb25zLmxvZ2dlci5pbmZvKFxuICAgICAgXCJzZW5kaW5nIG1lc3NhZ2UgZnJvbSBcIiArXG4gICAgICAgIGRhdGEuZnJvbSArXG4gICAgICAgIFwiIHRvIFwiICtcbiAgICAgICAgZGF0YS50byArXG4gICAgICAgIFwiIHdpdGggbWVzc2FnZSBcIiArXG4gICAgICAgIGRhdGEudGV4dFxuICAgICk7XG4gICAgc2VuZFJlcXVlc3QocGF0aCwgXCJQT1NUXCIsIGZ1bmN0aW9uKGVyciwgYXBpUmVzcG9uc2UpIHtcbiAgICAgIGlmICghZXJyICYmIGFwaVJlc3BvbnNlLnN0YXR1cyAmJiBhcGlSZXNwb25zZS5tZXNzYWdlc1swXS5zdGF0dXMgPiAwKSB7XG4gICAgICAgIHNlbmRFcnJvcihcbiAgICAgICAgICBjYWxsYmFjayxcbiAgICAgICAgICBuZXcgRXJyb3IoYXBpUmVzcG9uc2UubWVzc2FnZXNbMF1bXCJlcnJvci10ZXh0XCJdKSxcbiAgICAgICAgICBhcGlSZXNwb25zZVxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGNhbGxiYWNrKSBjYWxsYmFjayhlcnIsIGFwaVJlc3BvbnNlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBzZW5kVmlhU2hvcnRjb2RlKHR5cGUsIHJlY2lwaWVudCwgbWVzc2FnZVBhcmFtcywgb3B0cywgY2FsbGJhY2spIHtcbiAgaWYgKCFyZWNpcGllbnQpIHtcbiAgICBzZW5kRXJyb3IoY2FsbGJhY2ssIG5ldyBFcnJvcihFUlJPUl9NRVNTQUdFUy50bykpO1xuICB9XG4gIGlmICghbWVzc2FnZVBhcmFtcyB8fCAhT2JqZWN0LmtleXMobWVzc2FnZVBhcmFtcykpIHtcbiAgICBzZW5kRXJyb3IoY2FsbGJhY2ssIG5ldyBFcnJvcihFUlJPUl9NRVNTQUdFUy5tc2dQYXJhbXMpKTtcbiAgfVxuICBvcHRzID0gb3B0cyB8fCB7fTtcbiAgdmFyIHBhdGggPSBjbG9uZShzaG9ydGNvZGVQYXRoKTtcbiAgcGF0aC5wYXRoID0gcGF0aC5wYXRoLnJlcGxhY2UoXCIke3R5cGV9XCIsIHR5cGUpO1xuICBPYmplY3Qua2V5cyhtZXNzYWdlUGFyYW1zKS5mb3JFYWNoKGZ1bmN0aW9uKGtleSkge1xuICAgIG9wdHNba2V5XSA9IG1lc3NhZ2VQYXJhbXNba2V5XTtcbiAgfSk7XG4gIG9wdHMudG8gPSByZWNpcGllbnQ7XG4gIHBhdGgucGF0aCArPSBcIj9cIiArIHF1ZXJ5c3RyaW5nLnN0cmluZ2lmeShvcHRzKTtcbiAgX29wdGlvbnMubG9nZ2VyLmluZm8oXG4gICAgXCJzZW5kaW5nIG1lc3NhZ2UgZnJvbSBzaG9ydGNvZGUgXCIgK1xuICAgICAgdHlwZSArXG4gICAgICBcIiB0byBcIiArXG4gICAgICByZWNpcGllbnQgK1xuICAgICAgXCIgd2l0aCBwYXJhbWV0ZXJzIFwiICtcbiAgICAgIEpTT04uc3RyaW5naWZ5KG1lc3NhZ2VQYXJhbXMpXG4gICk7XG4gIHNlbmRSZXF1ZXN0KHBhdGgsIFwiUE9TVFwiLCBmdW5jdGlvbihlcnIsIGFwaVJlc3BvbnNlKSB7XG4gICAgaWYgKCFlcnIgJiYgYXBpUmVzcG9uc2Uuc3RhdHVzICYmIGFwaVJlc3BvbnNlLm1lc3NhZ2VzWzBdLnN0YXR1cyA+IDApIHtcbiAgICAgIHNlbmRFcnJvcihcbiAgICAgICAgY2FsbGJhY2ssXG4gICAgICAgIG5ldyBFcnJvcihhcGlSZXNwb25zZS5tZXNzYWdlc1swXVtcImVycm9yLXRleHRcIl0pLFxuICAgICAgICBhcGlSZXNwb25zZVxuICAgICAgKTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGNhbGxiYWNrKSBjYWxsYmFjayhlcnIsIGFwaVJlc3BvbnNlKTtcbiAgICB9XG4gIH0pO1xufVxuZXhwb3J0cy5zaG9ydGNvZGVBbGVydCA9IGZ1bmN0aW9uKHJlY2lwaWVudCwgbWVzc2FnZVBhcmFtcywgb3B0cywgY2FsbGJhY2spIHtcbiAgc2VuZFZpYVNob3J0Y29kZShcImFsZXJ0XCIsIHJlY2lwaWVudCwgbWVzc2FnZVBhcmFtcywgb3B0cywgY2FsbGJhY2spO1xufTtcbmV4cG9ydHMuc2hvcnRjb2RlMkZBID0gZnVuY3Rpb24ocmVjaXBpZW50LCBtZXNzYWdlUGFyYW1zLCBvcHRzLCBjYWxsYmFjaykge1xuICBzZW5kVmlhU2hvcnRjb2RlKFwiMmZhXCIsIHJlY2lwaWVudCwgbWVzc2FnZVBhcmFtcywgb3B0cywgY2FsbGJhY2spO1xufTtcbmV4cG9ydHMuc2hvcnRjb2RlTWFya2V0aW5nID0gZnVuY3Rpb24oXG4gIHJlY2lwaWVudCxcbiAgbWVzc2FnZVBhcmFtcyxcbiAgb3B0cyxcbiAgY2FsbGJhY2tcbikge1xuICBzZW5kVmlhU2hvcnRjb2RlKFwibWFya2V0aW5nXCIsIHJlY2lwaWVudCwgbWVzc2FnZVBhcmFtcywgb3B0cywgY2FsbGJhY2spO1xufTtcblxuZnVuY3Rpb24gY2xvbmUoYSkge1xuICByZXR1cm4gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShhKSk7XG59XG5cbmZ1bmN0aW9uIGdldEVuZHBvaW50KGFjdGlvbikge1xuICByZXR1cm4geyBwYXRoOiBhY3Rpb24gfTtcbn1cblxuZnVuY3Rpb24gc2VuZFJlcXVlc3QoZW5kcG9pbnQsIG1ldGhvZCwgY2FsbGJhY2spIHtcbiAgZW5kcG9pbnQucGF0aCA9XG4gICAgZW5kcG9pbnQucGF0aCArXG4gICAgKGVuZHBvaW50LnBhdGguaW5kZXhPZihcIj9cIikgPiAwID8gXCImXCIgOiBcIj9cIikgK1xuICAgIHF1ZXJ5c3RyaW5nLnN0cmluZ2lmeSh1cCk7XG4gIF9vcHRpb25zLmh0dHBDbGllbnQucmVxdWVzdChlbmRwb2ludCwgbWV0aG9kLCBjYWxsYmFjayk7XG59XG5cbmV4cG9ydHMuY2hlY2tCYWxhbmNlID0gZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAgdmFyIGJhbGFuY2VFbmRwb2ludCA9IGdldEVuZHBvaW50KFwiL2FjY291bnQvZ2V0LWJhbGFuY2VcIik7XG4gIHNlbmRSZXF1ZXN0KGJhbGFuY2VFbmRwb2ludCwgY2FsbGJhY2spO1xufTtcblxuZXhwb3J0cy5nZXROdW1iZXJzID0gZnVuY3Rpb24ob3B0aW9ucywgY2FsbGJhY2spIHtcbiAgdmFyIG51bWJlcnNFbmRwb2ludCA9IGdldEVuZHBvaW50KFwiL2FjY291bnQvbnVtYmVyc1wiKTtcbiAgaWYgKHR5cGVvZiBvcHRpb25zID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICBjYWxsYmFjayA9IG9wdGlvbnM7XG4gIH0gZWxzZSBpZiAodHlwZW9mIG9wdGlvbnMgPT09IFwib2JqZWN0XCIpIHtcbiAgICBudW1iZXJzRW5kcG9pbnQucGF0aCA9IG51bWJlcnNFbmRwb2ludC5wYXRoICsgXCI/XCI7XG4gICAgZm9yICh2YXIga2V5IGluIG9wdGlvbnMpIHtcbiAgICAgIG51bWJlcnNFbmRwb2ludC5wYXRoID1cbiAgICAgICAgbnVtYmVyc0VuZHBvaW50LnBhdGggKyBrZXkgKyBcIj1cIiArIG9wdGlvbnNba2V5XSArIFwiJlwiO1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBzZW5kRXJyb3IoY2FsbGJhY2ssIG5ldyBFcnJvcihFUlJPUl9NRVNTQUdFUy5vcHRpb25zTm90QW5PYmplY3QpKTtcbiAgICByZXR1cm47XG4gIH1cbiAgc2VuZFJlcXVlc3QobnVtYmVyc0VuZHBvaW50LCBjYWxsYmFjayk7XG59O1xuXG5leHBvcnRzLnNlYXJjaE51bWJlcnMgPSBmdW5jdGlvbihjb3VudHJ5Q29kZSwgcGF0dGVybiwgY2FsbGJhY2spIHtcbiAgaWYgKCFjb3VudHJ5Q29kZSB8fCBjb3VudHJ5Q29kZS5sZW5ndGggIT09IDIpIHtcbiAgICBzZW5kRXJyb3IoY2FsbGJhY2ssIG5ldyBFcnJvcihFUlJPUl9NRVNTQUdFUy5jb3VudHJ5Y29kZSkpO1xuICB9IGVsc2Uge1xuICAgIHZhciBzZWFyY2hFbmRwb2ludCA9IGdldEVuZHBvaW50KFwiL251bWJlci9zZWFyY2hcIik7XG4gICAgc2VhcmNoRW5kcG9pbnQucGF0aCArPSBcIj9jb3VudHJ5PVwiICsgY291bnRyeUNvZGU7XG4gICAgaWYgKHR5cGVvZiBwYXR0ZXJuID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIGNhbGxiYWNrID0gcGF0dGVybjtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBwYXR0ZXJuID09PSBcIm9iamVjdFwiKSB7XG4gICAgICBzZWFyY2hFbmRwb2ludC5wYXRoID0gc2VhcmNoRW5kcG9pbnQucGF0aCArIFwiJlwiO1xuICAgICAgZm9yICh2YXIgYXJnIGluIHBhdHRlcm4pIHtcbiAgICAgICAgc2VhcmNoRW5kcG9pbnQucGF0aCA9XG4gICAgICAgICAgc2VhcmNoRW5kcG9pbnQucGF0aCArIGFyZyArIFwiPVwiICsgcGF0dGVyblthcmddICsgXCImXCI7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHNlYXJjaEVuZHBvaW50LnBhdGggPSBzZWFyY2hFbmRwb2ludC5wYXRoICsgXCImcGF0dGVybj1cIiArIHBhdHRlcm47XG4gICAgfVxuICAgIHNlbmRSZXF1ZXN0KHNlYXJjaEVuZHBvaW50LCBjYWxsYmFjayk7XG4gIH1cbn07XG5cbmV4cG9ydHMuYnV5TnVtYmVyID0gZnVuY3Rpb24oY291bnRyeUNvZGUsIG1zaXNkbiwgY2FsbGJhY2spIHtcbiAgaWYgKCFjb3VudHJ5Q29kZSB8fCBjb3VudHJ5Q29kZS5sZW5ndGggIT09IDIpIHtcbiAgICBzZW5kRXJyb3IoY2FsbGJhY2ssIG5ldyBFcnJvcihFUlJPUl9NRVNTQUdFUy5jb3VudHJ5Y29kZSkpO1xuICB9IGVsc2UgaWYgKCFtc2lzZG4pIHtcbiAgICBzZW5kRXJyb3IoY2FsbGJhY2ssIG5ldyBFcnJvcihFUlJPUl9NRVNTQUdFUy5tc2lzZG4pKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgYnV5RW5kcG9pbnQgPSBnZXRFbmRwb2ludChcIi9udW1iZXIvYnV5XCIpO1xuICAgIGJ1eUVuZHBvaW50LnBhdGggKz0gXCI/Y291bnRyeT1cIiArIGNvdW50cnlDb2RlICsgXCImbXNpc2RuPVwiICsgbXNpc2RuO1xuICAgIHNlbmRSZXF1ZXN0KGJ1eUVuZHBvaW50LCBcIlBPU1RcIiwgY2FsbGJhY2spO1xuICB9XG59O1xuXG5leHBvcnRzLmNhbmNlbE51bWJlciA9IGZ1bmN0aW9uKGNvdW50cnlDb2RlLCBtc2lzZG4sIGNhbGxiYWNrKSB7XG4gIGlmICghY291bnRyeUNvZGUgfHwgY291bnRyeUNvZGUubGVuZ3RoICE9PSAyKSB7XG4gICAgc2VuZEVycm9yKGNhbGxiYWNrLCBuZXcgRXJyb3IoRVJST1JfTUVTU0FHRVMuY291bnRyeWNvZGUpKTtcbiAgfSBlbHNlIGlmICghbXNpc2RuKSB7XG4gICAgc2VuZEVycm9yKGNhbGxiYWNrLCBuZXcgRXJyb3IoRVJST1JfTUVTU0FHRVMubXNpc2RuKSk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGNhbmNlbEVuZHBvaW50ID0gZ2V0RW5kcG9pbnQoXCIvbnVtYmVyL2NhbmNlbFwiKTtcbiAgICBjYW5jZWxFbmRwb2ludC5wYXRoICs9IFwiP2NvdW50cnk9XCIgKyBjb3VudHJ5Q29kZSArIFwiJm1zaXNkbj1cIiArIG1zaXNkbjtcbiAgICBzZW5kUmVxdWVzdChjYW5jZWxFbmRwb2ludCwgXCJQT1NUXCIsIGNhbGxiYWNrKTtcbiAgfVxufTtcblxuZXhwb3J0cy5jYW5jZWxOdW1iZXIgPSBmdW5jdGlvbihjb3VudHJ5Q29kZSwgbXNpc2RuLCBjYWxsYmFjaykge1xuICBpZiAoIWNvdW50cnlDb2RlIHx8IGNvdW50cnlDb2RlLmxlbmd0aCAhPT0gMikge1xuICAgIHNlbmRFcnJvcihjYWxsYmFjaywgbmV3IEVycm9yKEVSUk9SX01FU1NBR0VTLmNvdW50cnljb2RlKSk7XG4gIH0gZWxzZSBpZiAoIW1zaXNkbikge1xuICAgIHNlbmRFcnJvcihjYWxsYmFjaywgbmV3IEVycm9yKEVSUk9SX01FU1NBR0VTLm1zaXNkbikpO1xuICB9IGVsc2Uge1xuICAgIHZhciBjYW5jZWxFbmRwb2ludCA9IGdldEVuZHBvaW50KFwiL251bWJlci9jYW5jZWxcIik7XG4gICAgY2FuY2VsRW5kcG9pbnQucGF0aCArPSBcIj9jb3VudHJ5PVwiICsgY291bnRyeUNvZGUgKyBcIiZtc2lzZG49XCIgKyBtc2lzZG47XG4gICAgc2VuZFJlcXVlc3QoY2FuY2VsRW5kcG9pbnQsIFwiUE9TVFwiLCBjYWxsYmFjayk7XG4gIH1cbn07XG5cbmV4cG9ydHMudXBkYXRlTnVtYmVyID0gZnVuY3Rpb24oY291bnRyeUNvZGUsIG1zaXNkbiwgcGFyYW1zLCBjYWxsYmFjaykge1xuICBpZiAoIWNvdW50cnlDb2RlIHx8IGNvdW50cnlDb2RlLmxlbmd0aCAhPT0gMikge1xuICAgIHNlbmRFcnJvcihjYWxsYmFjaywgbmV3IEVycm9yKEVSUk9SX01FU1NBR0VTLmNvdW50cnljb2RlKSk7XG4gIH0gZWxzZSBpZiAoIW1zaXNkbikge1xuICAgIHNlbmRFcnJvcihjYWxsYmFjaywgbmV3IEVycm9yKEVSUk9SX01FU1NBR0VTLm1zaXNkbikpO1xuICB9IGVsc2Uge1xuICAgIHZhciB1cGRhdGVFbmRwb2ludCA9IGdldEVuZHBvaW50KFwiL251bWJlci91cGRhdGVcIik7XG4gICAgdXBkYXRlRW5kcG9pbnQucGF0aCArPSBcIj9jb3VudHJ5PVwiICsgY291bnRyeUNvZGUgKyBcIiZtc2lzZG49XCIgKyBtc2lzZG47XG4gICAgdXBkYXRlRW5kcG9pbnQucGF0aCA9IHVwZGF0ZUVuZHBvaW50LnBhdGggKyBcIiZcIjtcbiAgICBmb3IgKHZhciBhcmcgaW4gcGFyYW1zKSB7XG4gICAgICB1cGRhdGVFbmRwb2ludC5wYXRoID1cbiAgICAgICAgdXBkYXRlRW5kcG9pbnQucGF0aCArIGFyZyArIFwiPVwiICsgZW5jb2RlVVJJQ29tcG9uZW50KHBhcmFtc1thcmddKSArIFwiJlwiO1xuICAgIH1cbiAgICBzZW5kUmVxdWVzdCh1cGRhdGVFbmRwb2ludCwgXCJQT1NUXCIsIGNhbGxiYWNrKTtcbiAgfVxufTtcblxuZXhwb3J0cy5jaGFuZ2VQYXNzd29yZCA9IGZ1bmN0aW9uKG5ld1NlY3JldCwgY2FsbGJhY2spIHtcbiAgdmFyIHNldHRpbmdzRW5kcG9pbnQgPSBnZXRFbmRwb2ludChcIi9hY2NvdW50L3NldHRpbmdzXCIpO1xuICBzZXR0aW5nc0VuZHBvaW50LnBhdGggKz0gXCI/bmV3U2VjcmV0PVwiICsgZW5jb2RlVVJJQ29tcG9uZW50KG5ld1NlY3JldCk7XG4gIHNlbmRSZXF1ZXN0KHNldHRpbmdzRW5kcG9pbnQsIFwiUE9TVFwiLCBjYWxsYmFjayk7XG59O1xuXG5leHBvcnRzLmNoYW5nZU1vQ2FsbGJhY2tVcmwgPSBmdW5jdGlvbihuZXdVcmwsIGNhbGxiYWNrKSB7XG4gIHZhciBzZXR0aW5nc0VuZHBvaW50ID0gZ2V0RW5kcG9pbnQoXCIvYWNjb3VudC9zZXR0aW5nc1wiKTtcbiAgc2V0dGluZ3NFbmRwb2ludC5wYXRoICs9IFwiP21vQ2FsbEJhY2tVcmw9XCIgKyBlbmNvZGVVUklDb21wb25lbnQobmV3VXJsKTtcbiAgc2VuZFJlcXVlc3Qoc2V0dGluZ3NFbmRwb2ludCwgXCJQT1NUXCIsIGNhbGxiYWNrKTtcbn07XG5cbmV4cG9ydHMuY2hhbmdlRHJDYWxsYmFja1VybCA9IGZ1bmN0aW9uKG5ld1VybCwgY2FsbGJhY2spIHtcbiAgdmFyIHNldHRpbmdzRW5kcG9pbnQgPSBnZXRFbmRwb2ludChcIi9hY2NvdW50L3NldHRpbmdzXCIpO1xuICBzZXR0aW5nc0VuZHBvaW50LnBhdGggKz0gXCI/ZHJDYWxsQmFja1VybD1cIiArIGVuY29kZVVSSUNvbXBvbmVudChuZXdVcmwpO1xuICBzZW5kUmVxdWVzdChzZXR0aW5nc0VuZHBvaW50LCBcIlBPU1RcIiwgY2FsbGJhY2spO1xufTtcblxuZXhwb3J0cy52ZXJpZnlOdW1iZXIgPSBmdW5jdGlvbihpbnB1dFBhcmFtcywgY2FsbGJhY2spIHtcbiAgaWYgKCFpbnB1dFBhcmFtcy5udW1iZXIgfHwgIWlucHV0UGFyYW1zLmJyYW5kKSB7XG4gICAgc2VuZEVycm9yKGNhbGxiYWNrLCBuZXcgRXJyb3IoRVJST1JfTUVTU0FHRVMudmVyaWZ5VmFsaWRhdGlvbikpO1xuICB9IGVsc2Uge1xuICAgIHZhciB2RW5kcG9pbnQgPSBjbG9uZSh2ZXJpZnlFbmRwb2ludCk7XG4gICAgdkVuZHBvaW50LnBhdGggKz0gXCI/XCIgKyBxdWVyeXN0cmluZy5zdHJpbmdpZnkoaW5wdXRQYXJhbXMpO1xuICAgIHNlbmRSZXF1ZXN0KHZFbmRwb2ludCwgY2FsbGJhY2spO1xuICB9XG59O1xuXG5leHBvcnRzLmNoZWNrVmVyaWZ5UmVxdWVzdCA9IGZ1bmN0aW9uKGlucHV0UGFyYW1zLCBjYWxsYmFjaykge1xuICBpZiAoIWlucHV0UGFyYW1zLnJlcXVlc3RfaWQgfHwgIWlucHV0UGFyYW1zLmNvZGUpIHtcbiAgICBzZW5kRXJyb3IoY2FsbGJhY2ssIG5ldyBFcnJvcihFUlJPUl9NRVNTQUdFUy5jaGVja1ZlcmlmeVZhbGlkYXRpb24pKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgdkVuZHBvaW50ID0gY2xvbmUoY2hlY2tWZXJpZnlFbmRwb2ludCk7XG4gICAgdkVuZHBvaW50LnBhdGggKz0gXCI/XCIgKyBxdWVyeXN0cmluZy5zdHJpbmdpZnkoaW5wdXRQYXJhbXMpO1xuICAgIHNlbmRSZXF1ZXN0KHZFbmRwb2ludCwgY2FsbGJhY2spO1xuICB9XG59O1xuXG5leHBvcnRzLmNvbnRyb2xWZXJpZnlSZXF1ZXN0ID0gZnVuY3Rpb24oaW5wdXRQYXJhbXMsIGNhbGxiYWNrKSB7XG4gIGlmICghaW5wdXRQYXJhbXMucmVxdWVzdF9pZCB8fCAhaW5wdXRQYXJhbXMuY21kKSB7XG4gICAgc2VuZEVycm9yKGNhbGxiYWNrLCBuZXcgRXJyb3IoRVJST1JfTUVTU0FHRVMuY29udHJvbFZlcmlmeVZhbGlkYXRpb24pKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgdkVuZHBvaW50ID0gY2xvbmUoY29udHJvbFZlcmlmeUVuZHBvaW50KTtcbiAgICB2RW5kcG9pbnQucGF0aCArPSBcIj9cIiArIHF1ZXJ5c3RyaW5nLnN0cmluZ2lmeShpbnB1dFBhcmFtcyk7XG4gICAgc2VuZFJlcXVlc3QodkVuZHBvaW50LCBjYWxsYmFjayk7XG4gIH1cbn07XG5cbmV4cG9ydHMuc2VhcmNoVmVyaWZ5UmVxdWVzdCA9IGZ1bmN0aW9uKHJlcXVlc3RJZHMsIGNhbGxiYWNrKSB7XG4gIHZhciByZXF1ZXN0SWRQYXJhbSA9IHt9O1xuICBpZiAoIXJlcXVlc3RJZHMpIHtcbiAgICBzZW5kRXJyb3IoY2FsbGJhY2ssIG5ldyBFcnJvcihFUlJPUl9NRVNTQUdFUy5zZWFyY2hWZXJpZnlWYWxpZGF0aW9uKSk7XG4gIH0gZWxzZSB7XG4gICAgaWYgKEFycmF5LmlzQXJyYXkocmVxdWVzdElkcykpIHtcbiAgICAgIGlmIChyZXF1ZXN0SWRzLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICByZXF1ZXN0SWRQYXJhbS5yZXF1ZXN0X2lkID0gcmVxdWVzdElkcztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlcXVlc3RJZFBhcmFtLnJlcXVlc3RfaWRzID0gcmVxdWVzdElkcztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgcmVxdWVzdElkUGFyYW0ucmVxdWVzdF9pZCA9IHJlcXVlc3RJZHM7XG4gICAgfVxuICAgIHZhciB2RW5kcG9pbnQgPSBjbG9uZShzZWFyY2hWZXJpZnlFbmRwb2ludCk7XG4gICAgdkVuZHBvaW50LnBhdGggKz0gXCI/XCIgKyBxdWVyeXN0cmluZy5zdHJpbmdpZnkocmVxdWVzdElkUGFyYW0pO1xuICAgIHNlbmRSZXF1ZXN0KHZFbmRwb2ludCwgY2FsbGJhY2spO1xuICB9XG59O1xuXG5leHBvcnRzLm51bWJlckluc2lnaHQgPSBmdW5jdGlvbihpbnB1dFBhcmFtcywgY2FsbGJhY2spIHtcbiAgbnVtYmVySW5zaWdodEFzeW5jKGlucHV0UGFyYW1zLCBjYWxsYmFjayk7XG59O1xuXG5leHBvcnRzLm51bWJlckluc2lnaHRCYXNpYyA9IGZ1bmN0aW9uKGlucHV0UGFyYW1zLCBjYWxsYmFjaykge1xuICBudW1iZXJJbnNpZ2h0Q29tbW9uKG5pQmFzaWNFbmRwb2ludCwgaW5wdXRQYXJhbXMsIGNhbGxiYWNrKTtcbn07XG5cbmV4cG9ydHMubnVtYmVySW5zaWdodFN0YW5kYXJkID0gZnVuY3Rpb24oaW5wdXRQYXJhbXMsIGNhbGxiYWNrKSB7XG4gIG51bWJlckluc2lnaHRDb21tb24obmlTdGFuZGFyZEVuZHBvaW50LCBpbnB1dFBhcmFtcywgY2FsbGJhY2spO1xufTtcblxuZXhwb3J0cy5udW1iZXJJbnNpZ2h0QWR2YW5jZWQgPSBmdW5jdGlvbihpbnB1dFBhcmFtcywgY2FsbGJhY2spIHtcbiAgbnVtYmVySW5zaWdodENvbW1vbihuaUFkdmFuY2VkRW5kcG9pbnQsIGlucHV0UGFyYW1zLCBjYWxsYmFjayk7XG59O1xuXG5leHBvcnRzLm51bWJlckluc2lnaHRBZHZhbmNlZEFzeW5jID0gZnVuY3Rpb24oaW5wdXRQYXJhbXMsIGNhbGxiYWNrKSB7XG4gIG51bWJlckluc2lnaHRBc3luYyhpbnB1dFBhcmFtcywgY2FsbGJhY2spO1xufTtcblxuZnVuY3Rpb24gbnVtYmVySW5zaWdodEFzeW5jKGlucHV0UGFyYW1zLCBjYWxsYmFjaykge1xuICBpZiAoIWlucHV0UGFyYW1zLm51bWJlciB8fCAhaW5wdXRQYXJhbXMuY2FsbGJhY2spIHtcbiAgICBzZW5kRXJyb3IoXG4gICAgICBjYWxsYmFjayxcbiAgICAgIG5ldyBFcnJvcihFUlJPUl9NRVNTQUdFUy5udW1iZXJJbnNpZ2h0QWR2YW5jZWRWYWxpZGF0aW9uKVxuICAgICk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIG5FbmRwb2ludCA9IGNsb25lKG5pRW5kcG9pbnQpO1xuICAgIG5FbmRwb2ludC5wYXRoICs9IFwiP1wiICsgcXVlcnlzdHJpbmcuc3RyaW5naWZ5KGlucHV0UGFyYW1zKTtcbiAgICBzZW5kUmVxdWVzdChuRW5kcG9pbnQsIGNhbGxiYWNrKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBudW1iZXJJbnNpZ2h0Q29tbW9uKGVuZHBvaW50LCBpbnB1dFBhcmFtcywgY2FsbGJhY2spIHtcbiAgaWYgKHZhbGlkYXRlTnVtYmVyKGlucHV0UGFyYW1zLCBjYWxsYmFjaykpIHtcbiAgICB2YXIgaW5wdXRPYmo7XG4gICAgaWYgKHR5cGVvZiBpbnB1dFBhcmFtcyAhPT0gXCJvYmplY3RcIikge1xuICAgICAgaW5wdXRPYmogPSB7IG51bWJlcjogaW5wdXRQYXJhbXMgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgaW5wdXRPYmogPSBpbnB1dFBhcmFtcztcbiAgICB9XG4gICAgdmFyIG5FbmRwb2ludCA9IGNsb25lKGVuZHBvaW50KTtcbiAgICBuRW5kcG9pbnQucGF0aCArPSBcIj9cIiArIHF1ZXJ5c3RyaW5nLnN0cmluZ2lmeShpbnB1dE9iaik7XG4gICAgc2VuZFJlcXVlc3QobkVuZHBvaW50LCBjYWxsYmFjayk7XG4gIH1cbn1cbmZ1bmN0aW9uIHZhbGlkYXRlTnVtYmVyKGlucHV0UGFyYW1zLCBjYWxsYmFjaykge1xuICBpZiAodHlwZW9mIGlucHV0UGFyYW1zID09PSBcIm9iamVjdFwiICYmICFpbnB1dFBhcmFtcy5udW1iZXIpIHtcbiAgICBzZW5kRXJyb3IoY2FsbGJhY2ssIG5ldyBFcnJvcihFUlJPUl9NRVNTQUdFUy5udW1iZXJJbnNpZ2h0VmFsaWRhdGlvbikpO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfSBlbHNlIGlmIChcbiAgICB0eXBlb2YgaW5wdXRQYXJhbXMgPT09IFwib2JqZWN0XCIgJiZcbiAgICAhbnVtYmVyUGF0dGVybi50ZXN0KGlucHV0UGFyYW1zLm51bWJlcilcbiAgKSB7XG4gICAgc2VuZEVycm9yKGNhbGxiYWNrLCBuZXcgRXJyb3IoRVJST1JfTUVTU0FHRVMubnVtYmVySW5zaWdodFBhdHRlcm5GYWlsdXJlKSk7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9IGVsc2UgaWYgKFxuICAgIHR5cGVvZiBpbnB1dFBhcmFtcyAhPT0gXCJvYmplY3RcIiAmJlxuICAgICghaW5wdXRQYXJhbXMgfHwgIW51bWJlclBhdHRlcm4udGVzdChpbnB1dFBhcmFtcykpXG4gICkge1xuICAgIHNlbmRFcnJvcihjYWxsYmFjaywgbmV3IEVycm9yKEVSUk9SX01FU1NBR0VTLm51bWJlckluc2lnaHRQYXR0ZXJuRmFpbHVyZSkpO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cblxuZnVuY3Rpb24gc2VuZFZvaWNlTWVzc2FnZSh2b2ljZUVuZHBvaW50LCBkYXRhLCBjYWxsYmFjaykge1xuICBpZiAoIWRhdGEudG8pIHtcbiAgICBzZW5kRXJyb3IoY2FsbGJhY2ssIG5ldyBFcnJvcihFUlJPUl9NRVNTQUdFUy50bykpO1xuICB9IGVsc2Uge1xuICAgIHZhciBlbmRwb2ludCA9IGNsb25lKHZvaWNlRW5kcG9pbnQpO1xuICAgIGVuZHBvaW50LnBhdGggKz0gXCI/XCIgKyBxdWVyeXN0cmluZy5zdHJpbmdpZnkoZGF0YSk7XG4gICAgX29wdGlvbnMubG9nZ2VyLmluZm8oXG4gICAgICBcInNlbmRpbmcgVFRTIG1lc3NhZ2UgdG8gXCIgKyBkYXRhLnRvICsgXCIgd2l0aCBtZXNzYWdlIFwiICsgZGF0YS50ZXh0XG4gICAgKTtcbiAgICBzZW5kUmVxdWVzdChlbmRwb2ludCwgXCJQT1NUXCIsIGZ1bmN0aW9uKGVyciwgYXBpUmVzcG9uc2UpIHtcbiAgICAgIGlmICghZXJyICYmIGFwaVJlc3BvbnNlLnN0YXR1cyAmJiBhcGlSZXNwb25zZS5zdGF0dXMgPiAwKSB7XG4gICAgICAgIHNlbmRFcnJvcihjYWxsYmFjaywgbmV3IEVycm9yKGFwaVJlc3BvbnNlW1wiZXJyb3ItdGV4dFwiXSksIGFwaVJlc3BvbnNlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChjYWxsYmFjaykgY2FsbGJhY2soZXJyLCBhcGlSZXNwb25zZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn1cblxuZXhwb3J0cy5zZW5kVFRTTWVzc2FnZSA9IGZ1bmN0aW9uKHJlY2lwaWVudCwgbWVzc2FnZSwgb3B0cywgY2FsbGJhY2spIHtcbiAgaWYgKCFtZXNzYWdlKSB7XG4gICAgc2VuZEVycm9yKGNhbGxiYWNrLCBuZXcgRXJyb3IoRVJST1JfTUVTU0FHRVMubXNnKSk7XG4gIH0gZWxzZSB7XG4gICAgaWYgKCFvcHRzKSB7XG4gICAgICBvcHRzID0ge307XG4gICAgfVxuICAgIG9wdHNbXCJ0b1wiXSA9IHJlY2lwaWVudDtcbiAgICBvcHRzW1widGV4dFwiXSA9IG1lc3NhZ2U7XG4gICAgc2VuZFZvaWNlTWVzc2FnZSh0dHNFbmRwb2ludCwgb3B0cywgY2FsbGJhY2spO1xuICB9XG59O1xuXG5leHBvcnRzLnNlbmRUVFNQcm9tcHRXaXRoQ2FwdHVyZSA9IGZ1bmN0aW9uKFxuICByZWNpcGllbnQsXG4gIG1lc3NhZ2UsXG4gIG1heERpZ2l0cyxcbiAgYnllVGV4dCxcbiAgb3B0cyxcbiAgY2FsbGJhY2tcbikge1xuICBpZiAoIW1lc3NhZ2UpIHtcbiAgICBzZW5kRXJyb3IoY2FsbGJhY2ssIG5ldyBFcnJvcihFUlJPUl9NRVNTQUdFUy5tc2cpKTtcbiAgfSBlbHNlIGlmICghbWF4RGlnaXRzIHx8IGlzTmFOKG1heERpZ2l0cykgfHwgbWF4RGlnaXRzLmxlbmd0aCA+IDE2KSB7XG4gICAgc2VuZEVycm9yKGNhbGxiYWNrLCBuZXcgRXJyb3IoRVJST1JfTUVTU0FHRVMubWF4RGlnaXRzKSk7XG4gIH0gZWxzZSBpZiAoIWJ5ZVRleHQpIHtcbiAgICBzZW5kRXJyb3IoY2FsbGJhY2ssIG5ldyBFcnJvcihFUlJPUl9NRVNTQUdFUy5ieWVUZXh0KSk7XG4gIH0gZWxzZSB7XG4gICAgaWYgKCFvcHRzKSB7XG4gICAgICBvcHRzID0ge307XG4gICAgfVxuICAgIG9wdHNbXCJ0b1wiXSA9IHJlY2lwaWVudDtcbiAgICBvcHRzW1widGV4dFwiXSA9IG1lc3NhZ2U7XG4gICAgb3B0c1tcIm1heF9kaWdpdHNcIl0gPSBtYXhEaWdpdHM7XG4gICAgb3B0c1tcImJ5ZV90ZXh0XCJdID0gYnllVGV4dDtcbiAgICBzZW5kVm9pY2VNZXNzYWdlKHR0c1Byb21wdEVuZHBvaW50LCBvcHRzLCBjYWxsYmFjayk7XG4gIH1cbn07XG5cbmV4cG9ydHMuc2VuZFRUU1Byb21wdFdpdGhDb25maXJtID0gZnVuY3Rpb24oXG4gIHJlY2lwaWVudCxcbiAgbWVzc2FnZSxcbiAgbWF4RGlnaXRzLFxuICBwaW5Db2RlLFxuICBieWVUZXh0LFxuICBmYWlsZWRUZXh0LFxuICBvcHRzLFxuICBjYWxsYmFja1xuKSB7XG4gIGlmICghbWVzc2FnZSkge1xuICAgIHNlbmRFcnJvcihjYWxsYmFjaywgbmV3IEVycm9yKEVSUk9SX01FU1NBR0VTLm1zZykpO1xuICB9IGVsc2UgaWYgKCFtYXhEaWdpdHMgfHwgaXNOYU4obWF4RGlnaXRzKSB8fCBtYXhEaWdpdHMubGVuZ3RoID4gMTYpIHtcbiAgICBzZW5kRXJyb3IoY2FsbGJhY2ssIG5ldyBFcnJvcihFUlJPUl9NRVNTQUdFUy5tYXhEaWdpdHMpKTtcbiAgfSBlbHNlIGlmICghcGluQ29kZSB8fCBwaW5Db2RlLmxlbmd0aCAhPT0gbWF4RGlnaXRzKSB7XG4gICAgc2VuZEVycm9yKGNhbGxiYWNrLCBuZXcgRXJyb3IoRVJST1JfTUVTU0FHRVMucGluQ29kZSkpO1xuICB9IGVsc2UgaWYgKCFieWVUZXh0KSB7XG4gICAgc2VuZEVycm9yKGNhbGxiYWNrLCBuZXcgRXJyb3IoRVJST1JfTUVTU0FHRVMuYnllVGV4dCkpO1xuICB9IGVsc2UgaWYgKCFmYWlsZWRUZXh0KSB7XG4gICAgc2VuZEVycm9yKGNhbGxiYWNrLCBuZXcgRXJyb3IoRVJST1JfTUVTU0FHRVMuZmFpbGVkVGV4dCkpO1xuICB9IGVsc2Uge1xuICAgIGlmICghb3B0cykge1xuICAgICAgb3B0cyA9IHt9O1xuICAgIH1cbiAgICBvcHRzW1widG9cIl0gPSByZWNpcGllbnQ7XG4gICAgb3B0c1tcInRleHRcIl0gPSBtZXNzYWdlO1xuICAgIG9wdHNbXCJtYXhfZGlnaXRzXCJdID0gbWF4RGlnaXRzO1xuICAgIG9wdHNbXCJwaW5fY29kZVwiXSA9IHBpbkNvZGU7XG4gICAgb3B0c1tcImJ5ZV90ZXh0XCJdID0gYnllVGV4dDtcbiAgICBvcHRzW1wiZmFpbGVkX3RleHRcIl0gPSBmYWlsZWRUZXh0O1xuICAgIHNlbmRWb2ljZU1lc3NhZ2UodHRzUHJvbXB0RW5kcG9pbnQsIG9wdHMsIGNhbGxiYWNrKTtcbiAgfVxufTtcblxuZXhwb3J0cy5jYWxsID0gZnVuY3Rpb24ocmVjaXBpZW50LCBhbnN3ZXJVcmwsIG9wdHMsIGNhbGxiYWNrKSB7XG4gIGlmICghYW5zd2VyVXJsKSB7XG4gICAgc2VuZEVycm9yKGNhbGxiYWNrLCBuZXcgRXJyb3IoRVJST1JfTUVTU0FHRVMuYW5zd2VyVXJsKSk7XG4gIH0gZWxzZSB7XG4gICAgaWYgKCFvcHRzKSB7XG4gICAgICBvcHRzID0ge307XG4gICAgfVxuICAgIG9wdHNbXCJ0b1wiXSA9IHJlY2lwaWVudDtcbiAgICBvcHRzW1wiYW5zd2VyX3VybFwiXSA9IGFuc3dlclVybDtcbiAgICBzZW5kVm9pY2VNZXNzYWdlKGNhbGxFbmRwb2ludCwgb3B0cywgY2FsbGJhY2spO1xuICB9XG59O1xuXG5mdW5jdGlvbiBzZW5kRXJyb3IoY2FsbGJhY2ssIGVyciwgcmV0dXJuRGF0YSkge1xuICAvLyBUaHJvdyB0aGUgZXJyb3IgaW4gY2FzZSBpZiB0aGVyZSBpcyBubyBjYWxsYmFjayBwYXNzZWRcbiAgaWYgKGNhbGxiYWNrKSB7XG4gICAgY2FsbGJhY2soZXJyLCByZXR1cm5EYXRhKTtcbiAgfSBlbHNlIHtcbiAgICB0aHJvdyBlcnI7XG4gIH1cbn1cbiJdfQ==
\No newline at end of file