@sentry/node 8.0.0-rc.1 → 8.0.0-rc.2
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/cjs/index.js +184 -91
- package/cjs/index.js.map +1 -1
- package/esm/index.js +183 -91
- package/esm/index.js.map +1 -1
- package/esm/integrations/anr/worker-script.js +1 -1
- package/esm/integrations/local-variables/worker-script.js +1 -1
- package/import-hook.mjs +2 -0
- package/package.json +8 -8
- package/types/cron/cron.d.ts.map +1 -1
- package/types/cron/node-cron.d.ts +1 -1
- package/types/cron/node-cron.d.ts.map +1 -1
- package/types/cron/node-schedule.d.ts.map +1 -1
- package/types/integrations/tracing/connect.d.ts.map +1 -1
- package/types/integrations/tracing/express.d.ts.map +1 -1
- package/types/integrations/tracing/fastify.d.ts.map +1 -1
- package/types/integrations/tracing/hapi/index.d.ts.map +1 -1
- package/types/integrations/tracing/koa.d.ts.map +1 -1
- package/types/sdk/init.d.ts.map +1 -1
- package/types-ts3.8/cron/node-cron.d.ts +1 -1
package/cjs/index.js
CHANGED
|
@@ -19,6 +19,7 @@ const path = require('path');
|
|
|
19
19
|
const worker_threads = require('worker_threads');
|
|
20
20
|
const inspector = require('inspector');
|
|
21
21
|
const instrumentationExpress = require('@opentelemetry/instrumentation-express');
|
|
22
|
+
const core$1 = require('@opentelemetry/core');
|
|
22
23
|
const instrumentationFastify = require('@opentelemetry/instrumentation-fastify');
|
|
23
24
|
const instrumentationGraphql = require('@opentelemetry/instrumentation-graphql');
|
|
24
25
|
const instrumentationMongodb = require('@opentelemetry/instrumentation-mongodb');
|
|
@@ -34,6 +35,7 @@ const instrumentationKoa = require('@opentelemetry/instrumentation-koa');
|
|
|
34
35
|
const semanticConventions = require('@opentelemetry/semantic-conventions');
|
|
35
36
|
const instrumentationConnect = require('@opentelemetry/instrumentation-connect');
|
|
36
37
|
const http = require('http');
|
|
38
|
+
const moduleModule = require('module');
|
|
37
39
|
const http$1 = require('node:http');
|
|
38
40
|
const https = require('node:https');
|
|
39
41
|
const stream = require('stream');
|
|
@@ -44,6 +46,7 @@ const resources = require('@opentelemetry/resources');
|
|
|
44
46
|
const sdkTraceBase = require('@opentelemetry/sdk-trace-base');
|
|
45
47
|
const contextAsyncHooks = require('@opentelemetry/context-async-hooks');
|
|
46
48
|
|
|
49
|
+
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
47
50
|
/**
|
|
48
51
|
* Update the active isolation scope.
|
|
49
52
|
* Should be used with caution!
|
|
@@ -74,7 +77,7 @@ function getRequestUrl(requestOptions) {
|
|
|
74
77
|
return `${protocol}//${hostname}${port}${path}`;
|
|
75
78
|
}
|
|
76
79
|
|
|
77
|
-
function _optionalChain$
|
|
80
|
+
function _optionalChain$e(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
78
81
|
|
|
79
82
|
const _httpIntegration = ((options = {}) => {
|
|
80
83
|
const _breadcrumbs = typeof options.breadcrumbs === 'undefined' ? true : options.breadcrumbs;
|
|
@@ -108,7 +111,7 @@ const _httpIntegration = ((options = {}) => {
|
|
|
108
111
|
ignoreIncomingRequestHook: request => {
|
|
109
112
|
const url = getRequestUrl(request);
|
|
110
113
|
|
|
111
|
-
const method = _optionalChain$
|
|
114
|
+
const method = _optionalChain$e([request, 'access', _ => _.method, 'optionalAccess', _2 => _2.toUpperCase, 'call', _3 => _3()]);
|
|
112
115
|
// We do not capture OPTIONS/HEAD requests as transactions
|
|
113
116
|
if (method === 'OPTIONS' || method === 'HEAD') {
|
|
114
117
|
return true;
|
|
@@ -331,7 +334,7 @@ const _consoleIntegration = (() => {
|
|
|
331
334
|
*/
|
|
332
335
|
const consoleIntegration = core.defineIntegration(_consoleIntegration);
|
|
333
336
|
|
|
334
|
-
function _optionalChain$
|
|
337
|
+
function _optionalChain$d(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
335
338
|
const readFileAsync$1 = util.promisify(fs.readFile);
|
|
336
339
|
const readDirAsync = util.promisify(fs.readdir);
|
|
337
340
|
|
|
@@ -359,11 +362,11 @@ const _nodeContextIntegration = ((options = {}) => {
|
|
|
359
362
|
|
|
360
363
|
event.contexts = {
|
|
361
364
|
...event.contexts,
|
|
362
|
-
app: { ...updatedContext.app, ..._optionalChain$
|
|
363
|
-
os: { ...updatedContext.os, ..._optionalChain$
|
|
364
|
-
device: { ...updatedContext.device, ..._optionalChain$
|
|
365
|
-
culture: { ...updatedContext.culture, ..._optionalChain$
|
|
366
|
-
cloud_resource: { ...updatedContext.cloud_resource, ..._optionalChain$
|
|
365
|
+
app: { ...updatedContext.app, ..._optionalChain$d([event, 'access', _ => _.contexts, 'optionalAccess', _2 => _2.app]) },
|
|
366
|
+
os: { ...updatedContext.os, ..._optionalChain$d([event, 'access', _3 => _3.contexts, 'optionalAccess', _4 => _4.os]) },
|
|
367
|
+
device: { ...updatedContext.device, ..._optionalChain$d([event, 'access', _5 => _5.contexts, 'optionalAccess', _6 => _6.device]) },
|
|
368
|
+
culture: { ...updatedContext.culture, ..._optionalChain$d([event, 'access', _7 => _7.contexts, 'optionalAccess', _8 => _8.culture]) },
|
|
369
|
+
cloud_resource: { ...updatedContext.cloud_resource, ..._optionalChain$d([event, 'access', _9 => _9.contexts, 'optionalAccess', _10 => _10.cloud_resource]) },
|
|
367
370
|
};
|
|
368
371
|
|
|
369
372
|
return event;
|
|
@@ -418,11 +421,11 @@ const nodeContextIntegration = core.defineIntegration(_nodeContextIntegration);
|
|
|
418
421
|
*/
|
|
419
422
|
function _updateContext(contexts) {
|
|
420
423
|
// Only update properties if they exist
|
|
421
|
-
if (_optionalChain$
|
|
424
|
+
if (_optionalChain$d([contexts, 'optionalAccess', _11 => _11.app, 'optionalAccess', _12 => _12.app_memory])) {
|
|
422
425
|
contexts.app.app_memory = process.memoryUsage().rss;
|
|
423
426
|
}
|
|
424
427
|
|
|
425
|
-
if (_optionalChain$
|
|
428
|
+
if (_optionalChain$d([contexts, 'optionalAccess', _13 => _13.device, 'optionalAccess', _14 => _14.free_memory])) {
|
|
426
429
|
contexts.device.free_memory = os.freemem();
|
|
427
430
|
}
|
|
428
431
|
|
|
@@ -749,7 +752,7 @@ function getCloudResourceContext() {
|
|
|
749
752
|
}
|
|
750
753
|
}
|
|
751
754
|
|
|
752
|
-
function _optionalChain$
|
|
755
|
+
function _optionalChain$c(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
753
756
|
const FILE_CONTENT_CACHE = new utils.LRUMap(100);
|
|
754
757
|
const DEFAULT_LINES_OF_CONTEXT = 7;
|
|
755
758
|
const INTEGRATION_NAME$6 = 'ContextLines';
|
|
@@ -779,9 +782,9 @@ async function addSourceContext(event, contextLines) {
|
|
|
779
782
|
const enqueuedReadSourceFileTasks = {};
|
|
780
783
|
const readSourceFileTasks = [];
|
|
781
784
|
|
|
782
|
-
if (contextLines > 0 && _optionalChain$
|
|
785
|
+
if (contextLines > 0 && _optionalChain$c([event, 'access', _2 => _2.exception, 'optionalAccess', _3 => _3.values])) {
|
|
783
786
|
for (const exception of event.exception.values) {
|
|
784
|
-
if (!_optionalChain$
|
|
787
|
+
if (!_optionalChain$c([exception, 'access', _4 => _4.stacktrace, 'optionalAccess', _5 => _5.frames])) {
|
|
785
788
|
continue;
|
|
786
789
|
}
|
|
787
790
|
|
|
@@ -808,7 +811,7 @@ async function addSourceContext(event, contextLines) {
|
|
|
808
811
|
|
|
809
812
|
// Perform the same loop as above, but this time we can assume all files are in the cache
|
|
810
813
|
// and attempt to add source context to frames.
|
|
811
|
-
if (contextLines > 0 && _optionalChain$
|
|
814
|
+
if (contextLines > 0 && _optionalChain$c([event, 'access', _6 => _6.exception, 'optionalAccess', _7 => _7.values])) {
|
|
812
815
|
for (const exception of event.exception.values) {
|
|
813
816
|
if (exception.stacktrace && exception.stacktrace.frames) {
|
|
814
817
|
await addSourceContextToFrames(exception.stacktrace.frames, contextLines);
|
|
@@ -953,9 +956,9 @@ function hashFromStack(stackParser, stack) {
|
|
|
953
956
|
return hashFrames(stackParser(stack, 1));
|
|
954
957
|
}
|
|
955
958
|
|
|
956
|
-
function _optionalChain$
|
|
959
|
+
function _optionalChain$b(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
957
960
|
// This string is a placeholder that gets overwritten with the worker code.
|
|
958
|
-
const base64WorkerScript$1 = '
|
|
961
|
+
const base64WorkerScript$1 = 'LyohIEBzZW50cnkvbm9kZSA4LjAuMC1yYy4yICg3YTNlMTZjKSB8IGh0dHBzOi8vZ2l0aHViLmNvbS9nZXRzZW50cnkvc2VudHJ5LWphdmFzY3JpcHQgKi8KaW1wb3J0e1Nlc3Npb24gYXMgZX1mcm9tIm5vZGU6aW5zcGVjdG9yL3Byb21pc2VzIjtpbXBvcnR7d29ya2VyRGF0YSBhcyBuLHBhcmVudFBvcnQgYXMgdH1mcm9tIndvcmtlcl90aHJlYWRzIjtpbXBvcnR7cG9zaXggYXMgbyxzZXAgYXMgcn1mcm9tInBhdGgiO2NvbnN0IGk9NTAscz0iPyIsYz0vXChlcnJvcjogKC4qKVwpLyxhPS9jYXB0dXJlTWVzc2FnZXxjYXB0dXJlRXhjZXB0aW9uLztjb25zdCB1PS9eKFxTKzpcXHxcLz8pKFtcc1xTXSo/KSgoPzpcLnsxLDJ9fFteL1xcXSs/fCkoXC5bXi4vXFxdKnwpKSg/OlsvXFxdKikkLztmdW5jdGlvbiBmKGUpe2NvbnN0IG49ZnVuY3Rpb24oZSl7Y29uc3Qgbj1lLmxlbmd0aD4xMDI0P2A8dHJ1bmNhdGVkPiR7ZS5zbGljZSgtMTAyNCl9YDplLHQ9dS5leGVjKG4pO3JldHVybiB0P3Quc2xpY2UoMSk6W119KGUpLHQ9blswXTtsZXQgbz1uWzFdO3JldHVybiB0fHxvPyhvJiYobz1vLnNsaWNlKDAsby5sZW5ndGgtMSkpLHQrbyk6Ii4ifWZ1bmN0aW9uIGwoZSxuPSExKXtyZXR1cm4hKG58fGUmJiFlLnN0YXJ0c1dpdGgoIi8iKSYmIWUubWF0Y2goL15bQS1aXTovKSYmIWUuc3RhcnRzV2l0aCgiLiIpJiYhZS5tYXRjaCgvXlthLXpBLVpdKFthLXpBLVowLTkuXC0rXSkqOlwvXC8vKSkmJnZvaWQgMCE9PWUmJiFlLmluY2x1ZGVzKCJub2RlX21vZHVsZXMvIil9ZnVuY3Rpb24gZChlKXtjb25zdCBuPS9eXHMqWy1dezQsfSQvLHQ9L2F0ICg/OmFzeW5jICk/KD86KC4rPylccytcKCk/KD86KC4rKTooXGQrKTooXGQrKT98KFteKV0rKSlcKT8vO3JldHVybiBvPT57Y29uc3Qgcj1vLm1hdGNoKHQpO2lmKHIpe2xldCBuLHQsbyxpLGM7aWYoclsxXSl7bz1yWzFdO2xldCBlPW8ubGFzdEluZGV4T2YoIi4iKTtpZigiLiI9PT1vW2UtMV0mJmUtLSxlPjApe249by5zbGljZSgwLGUpLHQ9by5zbGljZShlKzEpO2NvbnN0IHI9bi5pbmRleE9mKCIuTW9kdWxlIik7cj4wJiYobz1vLnNsaWNlKHIrMSksbj1uLnNsaWNlKDAscikpfWk9dm9pZCAwfXQmJihpPW4sYz10KSwiPGFub255bW91cz4iPT09dCYmKGM9dm9pZCAwLG89dm9pZCAwKSx2b2lkIDA9PT1vJiYoYz1jfHxzLG89aT9gJHtpfS4ke2N9YDpjKTtsZXQgYT1yWzJdJiZyWzJdLnN0YXJ0c1dpdGgoImZpbGU6Ly8iKT9yWzJdLnNsaWNlKDcpOnJbMl07Y29uc3QgdT0ibmF0aXZlIj09PXJbNV07cmV0dXJuIGEmJmEubWF0Y2goL1wvW0EtWl06LykmJihhPWEuc2xpY2UoMSkpLGF8fCFyWzVdfHx1fHwoYT1yWzVdKSx7ZmlsZW5hbWU6YSxtb2R1bGU6ZT9lKGEpOnZvaWQgMCxmdW5jdGlvbjpvLGxpbmVubzpwYXJzZUludChyWzNdLDEwKXx8dm9pZCAwLGNvbG5vOnBhcnNlSW50KHJbNF0sMTApfHx2b2lkIDAsaW5fYXBwOmwoYSx1KX19aWYoby5tYXRjaChuKSlyZXR1cm57ZmlsZW5hbWU6b319fWZ1bmN0aW9uIHAoZSl7cmV0dXJuIGUucmVwbGFjZSgvXltBLVpdOi8sIiIpLnJlcGxhY2UoL1xcL2csIi8iKX1jb25zdCBnPW4sbT1mdW5jdGlvbiguLi5lKXtjb25zdCBuPWUuc29ydCgoKGUsbik9PmVbMF0tblswXSkpLm1hcCgoZT0+ZVsxXSkpO3JldHVybihlLHQ9MCxvPTApPT57Y29uc3Qgcj1bXSx1PWUuc3BsaXQoIlxuIik7Zm9yKGxldCBlPXQ7ZTx1Lmxlbmd0aDtlKyspe2NvbnN0IHQ9dVtlXTtpZih0Lmxlbmd0aD4xMDI0KWNvbnRpbnVlO2NvbnN0IHM9Yy50ZXN0KHQpP3QucmVwbGFjZShjLCIkMSIpOnQ7aWYoIXMubWF0Y2goL1xTKkVycm9yOiAvKSl7Zm9yKGNvbnN0IGUgb2Ygbil7Y29uc3Qgbj1lKHMpO2lmKG4pe3IucHVzaChuKTticmVha319aWYoci5sZW5ndGg+PWkrbylicmVha319cmV0dXJuIGZ1bmN0aW9uKGUpe2lmKCFlLmxlbmd0aClyZXR1cm5bXTtjb25zdCBuPUFycmF5LmZyb20oZSk7L3NlbnRyeVdyYXBwZWQvLnRlc3QobltuLmxlbmd0aC0xXS5mdW5jdGlvbnx8IiIpJiZuLnBvcCgpO24ucmV2ZXJzZSgpLGEudGVzdChuW24ubGVuZ3RoLTFdLmZ1bmN0aW9ufHwiIikmJihuLnBvcCgpLGEudGVzdChuW24ubGVuZ3RoLTFdLmZ1bmN0aW9ufHwiIikmJm4ucG9wKCkpO3JldHVybiBuLnNsaWNlKDAsaSkubWFwKChlPT4oey4uLmUsZmlsZW5hbWU6ZS5maWxlbmFtZXx8bltuLmxlbmd0aC0xXS5maWxlbmFtZSxmdW5jdGlvbjplLmZ1bmN0aW9ufHxzfSkpKX0oci5zbGljZShvKSl9fShbOTAsZChmdW5jdGlvbihlPShwcm9jZXNzLmFyZ3ZbMV0/Zihwcm9jZXNzLmFyZ3ZbMV0pOnByb2Nlc3MuY3dkKCkpLG49IlxcIj09PXIpe2NvbnN0IHQ9bj9wKGUpOmU7cmV0dXJuIGU9PntpZighZSlyZXR1cm47Y29uc3Qgcj1uP3AoZSk6ZTtsZXR7ZGlyOmksYmFzZTpzLGV4dDpjfT1vLnBhcnNlKHIpOyIuanMiIT09YyYmIi5tanMiIT09YyYmIi5janMiIT09Y3x8KHM9cy5zbGljZSgwLC0xKmMubGVuZ3RoKSksaXx8KGk9Ii4iKTtjb25zdCBhPWkubGFzdEluZGV4T2YoIi9ub2RlX21vZHVsZXMiKTtpZihhPi0xKXJldHVybmAke2kuc2xpY2UoYSsxNCkucmVwbGFjZSgvXC8vZywiLiIpfToke3N9YDtpZihpLnN0YXJ0c1dpdGgodCkpe2xldCBlPWkuc2xpY2UodC5sZW5ndGgrMSkucmVwbGFjZSgvXC8vZywiLiIpO3JldHVybiBlJiYoZSs9IjoiKSxlKz1zLGV9cmV0dXJuIHN9fShnLmJhc2VQYXRoKSldKTtmdW5jdGlvbiBiKC4uLmUpe2cuZGVidWcmJmNvbnNvbGUubG9nKCJbTG9jYWxWYXJpYWJsZXMgV29ya2VyXSIsLi4uZSl9YXN5bmMgZnVuY3Rpb24gdihlLG4sdCxvKXtjb25zdCByPWF3YWl0IGUucG9zdCgiUnVudGltZS5nZXRQcm9wZXJ0aWVzIix7b2JqZWN0SWQ6bixvd25Qcm9wZXJ0aWVzOiEwfSk7b1t0XT1yLnJlc3VsdC5maWx0ZXIoKGU9PiJsZW5ndGgiIT09ZS5uYW1lJiYhaXNOYU4ocGFyc2VJbnQoZS5uYW1lLDEwKSkpKS5zb3J0KCgoZSxuKT0+cGFyc2VJbnQoZS5uYW1lLDEwKS1wYXJzZUludChuLm5hbWUsMTApKSkubWFwKChlPT5lLnZhbHVlPy52YWx1ZSkpfWFzeW5jIGZ1bmN0aW9uICQoZSxuLHQsbyl7Y29uc3Qgcj1hd2FpdCBlLnBvc3QoIlJ1bnRpbWUuZ2V0UHJvcGVydGllcyIse29iamVjdElkOm4sb3duUHJvcGVydGllczohMH0pO29bdF09ci5yZXN1bHQubWFwKChlPT5bZS5uYW1lLGUudmFsdWU/LnZhbHVlXSkpLnJlZHVjZSgoKGUsW24sdF0pPT4oZVtuXT10LGUpKSx7fSl9ZnVuY3Rpb24gdyhlLG4pe2UudmFsdWUmJigidmFsdWUiaW4gZS52YWx1ZT92b2lkIDA9PT1lLnZhbHVlLnZhbHVlfHxudWxsPT09ZS52YWx1ZS52YWx1ZT9uW2UubmFtZV09YDwke2UudmFsdWUudmFsdWV9PmA6bltlLm5hbWVdPWUudmFsdWUudmFsdWU6ImRlc2NyaXB0aW9uImluIGUudmFsdWUmJiJmdW5jdGlvbiIhPT1lLnZhbHVlLnR5cGU/bltlLm5hbWVdPWA8JHtlLnZhbHVlLmRlc2NyaXB0aW9ufT5gOiJ1bmRlZmluZWQiPT09ZS52YWx1ZS50eXBlJiYobltlLm5hbWVdPSI8dW5kZWZpbmVkPiIpKX1hc3luYyBmdW5jdGlvbiB5KGUsbil7Y29uc3QgdD1hd2FpdCBlLnBvc3QoIlJ1bnRpbWUuZ2V0UHJvcGVydGllcyIse29iamVjdElkOm4sb3duUHJvcGVydGllczohMH0pLG89e307Zm9yKGNvbnN0IG4gb2YgdC5yZXN1bHQpaWYobj8udmFsdWU/Lm9iamVjdElkJiYiQXJyYXkiPT09bj8udmFsdWUuY2xhc3NOYW1lKXtjb25zdCB0PW4udmFsdWUub2JqZWN0SWQ7YXdhaXQgdihlLHQsbi5uYW1lLG8pfWVsc2UgaWYobj8udmFsdWU/Lm9iamVjdElkJiYiT2JqZWN0Ij09PW4/LnZhbHVlPy5jbGFzc05hbWUpe2NvbnN0IHQ9bi52YWx1ZS5vYmplY3RJZDthd2FpdCAkKGUsdCxuLm5hbWUsbyl9ZWxzZSBuPy52YWx1ZSYmdyhuLG8pO3JldHVybiBvfWxldCBoOyhhc3luYyBmdW5jdGlvbigpe2NvbnN0IG49bmV3IGU7bi5jb25uZWN0VG9NYWluVGhyZWFkKCksYigiQ29ubmVjdGVkIHRvIG1haW4gdGhyZWFkIik7bGV0IG89ITE7bi5vbigiRGVidWdnZXIucmVzdW1lZCIsKCgpPT57bz0hMX0pKSxuLm9uKCJEZWJ1Z2dlci5wYXVzZWQiLChlPT57bz0hMCxhc3luYyBmdW5jdGlvbihlLG4se3JlYXNvbjpvLGRhdGE6cixjYWxsRnJhbWVzOml9KXtpZigiZXhjZXB0aW9uIiE9PW8mJiJwcm9taXNlUmVqZWN0aW9uIiE9PW8pcmV0dXJuO2g/LigpO2NvbnN0IHM9ZnVuY3Rpb24oZSxuKXtpZih2b2lkIDAhPT1uKXJldHVybiBmdW5jdGlvbihlKXtpZih2b2lkIDAhPT1lKXJldHVybiBlLnNsaWNlKC0xMCkucmVkdWNlKCgoZSxuKT0+YCR7ZX0sJHtuLmZ1bmN0aW9ufSwke24ubGluZW5vfSwke24uY29sbm99YCksIiIpfShlKG4sMSkpfShuLHI/LmRlc2NyaXB0aW9uKTtpZihudWxsPT1zKXJldHVybjtjb25zdCBjPVtdO2ZvcihsZXQgbj0wO248aS5sZW5ndGg7bisrKXtjb25zdHtzY29wZUNoYWluOnQsZnVuY3Rpb25OYW1lOm8sdGhpczpyfT1pW25dLHM9dC5maW5kKChlPT4ibG9jYWwiPT09ZS50eXBlKSksYT0iZ2xvYmFsIiE9PXIuY2xhc3NOYW1lJiZyLmNsYXNzTmFtZT9gJHtyLmNsYXNzTmFtZX0uJHtvfWA6bztpZih2b2lkIDA9PT1zPy5vYmplY3Qub2JqZWN0SWQpY1tuXT17ZnVuY3Rpb246YX07ZWxzZXtjb25zdCB0PWF3YWl0IHkoZSxzLm9iamVjdC5vYmplY3RJZCk7Y1tuXT17ZnVuY3Rpb246YSx2YXJzOnR9fX10Py5wb3N0TWVzc2FnZSh7ZXhjZXB0aW9uSGFzaDpzLGZyYW1lczpjfSl9KG4sbSxlLnBhcmFtcykudGhlbigoKCk9Pm8/bi5wb3N0KCJEZWJ1Z2dlci5yZXN1bWUiKTpQcm9taXNlLnJlc29sdmUoKSksKGU9Pnt9KSl9KSksYXdhaXQgbi5wb3N0KCJEZWJ1Z2dlci5lbmFibGUiKTtjb25zdCByPSExIT09Zy5jYXB0dXJlQWxsRXhjZXB0aW9ucztpZihhd2FpdCBuLnBvc3QoIkRlYnVnZ2VyLnNldFBhdXNlT25FeGNlcHRpb25zIix7c3RhdGU6cj8iYWxsIjoidW5jYXVnaHQifSkscil7Y29uc3QgZT1nLm1heEV4Y2VwdGlvbnNQZXJTZWNvbmR8fDUwO2g9ZnVuY3Rpb24oZSxuLHQpe2xldCBvPTAscj01LGk9MDtyZXR1cm4gc2V0SW50ZXJ2YWwoKCgpPT57MD09PWk/bz5lJiYocio9Mix0KHIpLHI+ODY0MDAmJihyPTg2NDAwKSxpPXIpOihpLT0xLDA9PT1pJiZuKCkpLG89MH0pLDFlMykudW5yZWYoKSwoKT0+e28rPTF9fShlLChhc3luYygpPT57YigiUmF0ZS1saW1pdCBsaWZ0ZWQuIiksYXdhaXQgbi5wb3N0KCJEZWJ1Z2dlci5zZXRQYXVzZU9uRXhjZXB0aW9ucyIse3N0YXRlOiJhbGwifSl9KSwoYXN5bmMgZT0+e2IoYFJhdGUtbGltaXQgZXhjZWVkZWQuIERpc2FibGluZyBjYXB0dXJpbmcgb2YgY2F1Z2h0IGV4Y2VwdGlvbnMgZm9yICR7ZX0gc2Vjb25kcy5gKSxhd2FpdCBuLnBvc3QoIkRlYnVnZ2VyLnNldFBhdXNlT25FeGNlcHRpb25zIix7c3RhdGU6InVuY2F1Z2h0In0pfSkpfX0pKCkuY2F0Y2goKGU9PntiKCJGYWlsZWQgdG8gc3RhcnQgZGVidWdnZXIiLGUpfSkpLHNldEludGVydmFsKCgoKT0+e30pLDFlNCk7';
|
|
959
962
|
|
|
960
963
|
function log$1(...args) {
|
|
961
964
|
utils.logger.log('[LocalVariables]', ...args);
|
|
@@ -970,7 +973,7 @@ const localVariablesAsyncIntegration = core.defineIntegration(((
|
|
|
970
973
|
const cachedFrames = new utils.LRUMap(20);
|
|
971
974
|
|
|
972
975
|
function addLocalVariablesToException(exception) {
|
|
973
|
-
const hash = hashFrames(_optionalChain$
|
|
976
|
+
const hash = hashFrames(_optionalChain$b([exception, 'optionalAccess', _ => _.stacktrace, 'optionalAccess', _2 => _2.frames]));
|
|
974
977
|
|
|
975
978
|
if (hash === undefined) {
|
|
976
979
|
return;
|
|
@@ -986,7 +989,7 @@ const localVariablesAsyncIntegration = core.defineIntegration(((
|
|
|
986
989
|
|
|
987
990
|
// Filter out frames where the function name is `new Promise` since these are in the error.stack frames
|
|
988
991
|
// but do not appear in the debugger call frames
|
|
989
|
-
const frames = (_optionalChain$
|
|
992
|
+
const frames = (_optionalChain$b([exception, 'access', _3 => _3.stacktrace, 'optionalAccess', _4 => _4.frames]) || []).filter(frame => frame.function !== 'new Promise');
|
|
990
993
|
|
|
991
994
|
for (let i = 0; i < frames.length; i++) {
|
|
992
995
|
// Sentry frames are in reverse order
|
|
@@ -1013,7 +1016,7 @@ const localVariablesAsyncIntegration = core.defineIntegration(((
|
|
|
1013
1016
|
}
|
|
1014
1017
|
|
|
1015
1018
|
function addLocalVariablesToEvent(event) {
|
|
1016
|
-
for (const exception of _optionalChain$
|
|
1019
|
+
for (const exception of _optionalChain$b([event, 'access', _5 => _5.exception, 'optionalAccess', _6 => _6.values]) || []) {
|
|
1017
1020
|
addLocalVariablesToException(exception);
|
|
1018
1021
|
}
|
|
1019
1022
|
|
|
@@ -1087,7 +1090,7 @@ const localVariablesAsyncIntegration = core.defineIntegration(((
|
|
|
1087
1090
|
};
|
|
1088
1091
|
}) );
|
|
1089
1092
|
|
|
1090
|
-
function _optionalChain$
|
|
1093
|
+
function _optionalChain$a(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
1091
1094
|
/** Creates a container for callbacks to be called sequentially */
|
|
1092
1095
|
function createCallbackList(complete) {
|
|
1093
1096
|
// A collection of callbacks to be executed last to first
|
|
@@ -1165,13 +1168,13 @@ class AsyncSession {
|
|
|
1165
1168
|
const { add, next } = createCallbackList(complete);
|
|
1166
1169
|
|
|
1167
1170
|
for (const prop of props) {
|
|
1168
|
-
if (_optionalChain$
|
|
1171
|
+
if (_optionalChain$a([prop, 'optionalAccess', _2 => _2.value, 'optionalAccess', _3 => _3.objectId]) && _optionalChain$a([prop, 'optionalAccess', _4 => _4.value, 'access', _5 => _5.className]) === 'Array') {
|
|
1169
1172
|
const id = prop.value.objectId;
|
|
1170
1173
|
add(vars => this._unrollArray(id, prop.name, vars, next));
|
|
1171
|
-
} else if (_optionalChain$
|
|
1174
|
+
} else if (_optionalChain$a([prop, 'optionalAccess', _6 => _6.value, 'optionalAccess', _7 => _7.objectId]) && _optionalChain$a([prop, 'optionalAccess', _8 => _8.value, 'optionalAccess', _9 => _9.className]) === 'Object') {
|
|
1172
1175
|
const id = prop.value.objectId;
|
|
1173
1176
|
add(vars => this._unrollObject(id, prop.name, vars, next));
|
|
1174
|
-
} else if (_optionalChain$
|
|
1177
|
+
} else if (_optionalChain$a([prop, 'optionalAccess', _10 => _10.value])) {
|
|
1175
1178
|
add(vars => this._unrollOther(prop, vars, next));
|
|
1176
1179
|
}
|
|
1177
1180
|
}
|
|
@@ -1208,7 +1211,7 @@ class AsyncSession {
|
|
|
1208
1211
|
vars[name] = props
|
|
1209
1212
|
.filter(v => v.name !== 'length' && !isNaN(parseInt(v.name, 10)))
|
|
1210
1213
|
.sort((a, b) => parseInt(a.name, 10) - parseInt(b.name, 10))
|
|
1211
|
-
.map(v => _optionalChain$
|
|
1214
|
+
.map(v => _optionalChain$a([v, 'optionalAccess', _11 => _11.value, 'optionalAccess', _12 => _12.value]));
|
|
1212
1215
|
|
|
1213
1216
|
next(vars);
|
|
1214
1217
|
});
|
|
@@ -1220,7 +1223,7 @@ class AsyncSession {
|
|
|
1220
1223
|
_unrollObject(objectId, name, vars, next) {
|
|
1221
1224
|
this._getProperties(objectId, props => {
|
|
1222
1225
|
vars[name] = props
|
|
1223
|
-
.map(v => [v.name, _optionalChain$
|
|
1226
|
+
.map(v => [v.name, _optionalChain$a([v, 'optionalAccess', _13 => _13.value, 'optionalAccess', _14 => _14.value])])
|
|
1224
1227
|
.reduce((obj, [key, val]) => {
|
|
1225
1228
|
obj[key] = val;
|
|
1226
1229
|
return obj;
|
|
@@ -1287,10 +1290,10 @@ const _localVariablesSyncIntegration = ((
|
|
|
1287
1290
|
return;
|
|
1288
1291
|
}
|
|
1289
1292
|
|
|
1290
|
-
_optionalChain$
|
|
1293
|
+
_optionalChain$a([rateLimiter, 'optionalCall', _15 => _15()]);
|
|
1291
1294
|
|
|
1292
1295
|
// data.description contains the original error.stack
|
|
1293
|
-
const exceptionHash = hashFromStack(stackParser, _optionalChain$
|
|
1296
|
+
const exceptionHash = hashFromStack(stackParser, _optionalChain$a([data, 'optionalAccess', _16 => _16.description]));
|
|
1294
1297
|
|
|
1295
1298
|
if (exceptionHash == undefined) {
|
|
1296
1299
|
complete();
|
|
@@ -1312,7 +1315,7 @@ const _localVariablesSyncIntegration = ((
|
|
|
1312
1315
|
// obj.className is undefined in ESM modules
|
|
1313
1316
|
const fn = obj.className === 'global' || !obj.className ? functionName : `${obj.className}.${functionName}`;
|
|
1314
1317
|
|
|
1315
|
-
if (_optionalChain$
|
|
1318
|
+
if (_optionalChain$a([localScope, 'optionalAccess', _17 => _17.object, 'access', _18 => _18.objectId]) === undefined) {
|
|
1316
1319
|
add(frames => {
|
|
1317
1320
|
frames[i] = { function: fn };
|
|
1318
1321
|
next(frames);
|
|
@@ -1320,7 +1323,7 @@ const _localVariablesSyncIntegration = ((
|
|
|
1320
1323
|
} else {
|
|
1321
1324
|
const id = localScope.object.objectId;
|
|
1322
1325
|
add(frames =>
|
|
1323
|
-
_optionalChain$
|
|
1326
|
+
_optionalChain$a([session, 'optionalAccess', _19 => _19.getLocalVariables, 'call', _20 => _20(id, vars => {
|
|
1324
1327
|
frames[i] = { function: fn, vars };
|
|
1325
1328
|
next(frames);
|
|
1326
1329
|
})]),
|
|
@@ -1332,7 +1335,7 @@ const _localVariablesSyncIntegration = ((
|
|
|
1332
1335
|
}
|
|
1333
1336
|
|
|
1334
1337
|
function addLocalVariablesToException(exception) {
|
|
1335
|
-
const hash = hashFrames(_optionalChain$
|
|
1338
|
+
const hash = hashFrames(_optionalChain$a([exception, 'optionalAccess', _21 => _21.stacktrace, 'optionalAccess', _22 => _22.frames]));
|
|
1336
1339
|
|
|
1337
1340
|
if (hash === undefined) {
|
|
1338
1341
|
return;
|
|
@@ -1348,7 +1351,7 @@ const _localVariablesSyncIntegration = ((
|
|
|
1348
1351
|
|
|
1349
1352
|
// Filter out frames where the function name is `new Promise` since these are in the error.stack frames
|
|
1350
1353
|
// but do not appear in the debugger call frames
|
|
1351
|
-
const frames = (_optionalChain$
|
|
1354
|
+
const frames = (_optionalChain$a([exception, 'access', _23 => _23.stacktrace, 'optionalAccess', _24 => _24.frames]) || []).filter(frame => frame.function !== 'new Promise');
|
|
1352
1355
|
|
|
1353
1356
|
for (let i = 0; i < frames.length; i++) {
|
|
1354
1357
|
// Sentry frames are in reverse order
|
|
@@ -1375,7 +1378,7 @@ const _localVariablesSyncIntegration = ((
|
|
|
1375
1378
|
}
|
|
1376
1379
|
|
|
1377
1380
|
function addLocalVariablesToEvent(event) {
|
|
1378
|
-
for (const exception of _optionalChain$
|
|
1381
|
+
for (const exception of _optionalChain$a([event, 'optionalAccess', _25 => _25.exception, 'optionalAccess', _26 => _26.values]) || []) {
|
|
1379
1382
|
addLocalVariablesToException(exception);
|
|
1380
1383
|
}
|
|
1381
1384
|
|
|
@@ -1386,9 +1389,9 @@ const _localVariablesSyncIntegration = ((
|
|
|
1386
1389
|
name: INTEGRATION_NAME$5,
|
|
1387
1390
|
setupOnce() {
|
|
1388
1391
|
const client = core.getClient();
|
|
1389
|
-
const clientOptions = _optionalChain$
|
|
1392
|
+
const clientOptions = _optionalChain$a([client, 'optionalAccess', _27 => _27.getOptions, 'call', _28 => _28()]);
|
|
1390
1393
|
|
|
1391
|
-
if (session && _optionalChain$
|
|
1394
|
+
if (session && _optionalChain$a([clientOptions, 'optionalAccess', _29 => _29.includeLocalVariables])) {
|
|
1392
1395
|
// Only setup this integration if the Node version is >= v18
|
|
1393
1396
|
// https://github.com/getsentry/sentry-javascript/issues/7697
|
|
1394
1397
|
const unsupportedNodeVersion = NODE_MAJOR < 18;
|
|
@@ -1413,13 +1416,13 @@ const _localVariablesSyncIntegration = ((
|
|
|
1413
1416
|
max,
|
|
1414
1417
|
() => {
|
|
1415
1418
|
utils.logger.log('Local variables rate-limit lifted.');
|
|
1416
|
-
_optionalChain$
|
|
1419
|
+
_optionalChain$a([session, 'optionalAccess', _30 => _30.setPauseOnExceptions, 'call', _31 => _31(true)]);
|
|
1417
1420
|
},
|
|
1418
1421
|
seconds => {
|
|
1419
1422
|
utils.logger.log(
|
|
1420
1423
|
`Local variables rate-limit exceeded. Disabling capturing of caught exceptions for ${seconds} seconds.`,
|
|
1421
1424
|
);
|
|
1422
|
-
_optionalChain$
|
|
1425
|
+
_optionalChain$a([session, 'optionalAccess', _32 => _32.setPauseOnExceptions, 'call', _33 => _33(false)]);
|
|
1423
1426
|
},
|
|
1424
1427
|
);
|
|
1425
1428
|
}
|
|
@@ -1786,9 +1789,9 @@ function handleRejection(
|
|
|
1786
1789
|
/* eslint-enable no-console */
|
|
1787
1790
|
}
|
|
1788
1791
|
|
|
1789
|
-
function _optionalChain$
|
|
1792
|
+
function _optionalChain$9(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
1790
1793
|
// This string is a placeholder that gets overwritten with the worker code.
|
|
1791
|
-
const base64WorkerScript = 'LyohIEBzZW50cnkvbm9kZSA4LjAuMC1yYy4xICgyYzU2N2ZmKSB8IGh0dHBzOi8vZ2l0aHViLmNvbS9nZXRzZW50cnkvc2VudHJ5LWphdmFzY3JpcHQgKi8KaW1wb3J0e1Nlc3Npb24gYXMgdH1mcm9tImluc3BlY3RvciI7aW1wb3J0e3BhcmVudFBvcnQgYXMgZSx3b3JrZXJEYXRhIGFzIG59ZnJvbSJ3b3JrZXJfdGhyZWFkcyI7aW1wb3J0e3Bvc2l4IGFzIHIsc2VwIGFzIG99ZnJvbSJwYXRoIjtpbXBvcnQqYXMgcyBmcm9tIm5vZGU6aHR0cCI7aW1wb3J0KmFzIGkgZnJvbSJub2RlOmh0dHBzIjtpbXBvcnR7UmVhZGFibGUgYXMgY31mcm9tInN0cmVhbSI7aW1wb3J0e2NyZWF0ZUd6aXAgYXMgdX1mcm9tInpsaWIiO2ltcG9ydCphcyBhIGZyb20ibmV0IjtpbXBvcnQqYXMgZiBmcm9tInRscyI7aW1wb3J0KmFzIGggZnJvbSJodHRwIjtjb25zdCBwPU9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7ZnVuY3Rpb24gbCh0LGUpe3JldHVybiBwLmNhbGwodCk9PT1gW29iamVjdCAke2V9XWB9ZnVuY3Rpb24gZCh0KXtyZXR1cm4gbCh0LCJPYmplY3QiKX1mdW5jdGlvbiBtKHQpe3JldHVybiBCb29sZWFuKHQmJnQudGhlbiYmImZ1bmN0aW9uIj09dHlwZW9mIHQudGhlbil9ZnVuY3Rpb24gZyh0LGUpe3RyeXtyZXR1cm4gdCBpbnN0YW5jZW9mIGV9Y2F0Y2godCl7cmV0dXJuITF9fWNvbnN0IHk9Z2xvYmFsVGhpcztmdW5jdGlvbiBiKHQsZSxuKXtjb25zdCByPW58fHksbz1yLl9fU0VOVFJZX189ci5fX1NFTlRSWV9ffHx7fTtyZXR1cm4gb1t0XXx8KG9bdF09ZSgpKX1jb25zdCB2PXksXz04MDtmdW5jdGlvbiB3KHQsZSl7Y29uc3Qgbj10LHI9W107bGV0IG8scyxpLGMsdTtpZighbnx8IW4udGFnTmFtZSlyZXR1cm4iIjtpZih2LkhUTUxFbGVtZW50JiZuIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQmJm4uZGF0YXNldCl7aWYobi5kYXRhc2V0LnNlbnRyeUNvbXBvbmVudClyZXR1cm4gbi5kYXRhc2V0LnNlbnRyeUNvbXBvbmVudDtpZihuLmRhdGFzZXQuc2VudHJ5RWxlbWVudClyZXR1cm4gbi5kYXRhc2V0LnNlbnRyeUVsZW1lbnR9ci5wdXNoKG4udGFnTmFtZS50b0xvd2VyQ2FzZSgpKTtjb25zdCBhPWUmJmUubGVuZ3RoP2UuZmlsdGVyKCh0PT5uLmdldEF0dHJpYnV0ZSh0KSkpLm1hcCgodD0+W3Qsbi5nZXRBdHRyaWJ1dGUodCldKSk6bnVsbDtpZihhJiZhLmxlbmd0aClhLmZvckVhY2goKHQ9PntyLnB1c2goYFske3RbMF19PSIke3RbMV19Il1gKX0pKTtlbHNlIGlmKG4uaWQmJnIucHVzaChgIyR7bi5pZH1gKSxvPW4uY2xhc3NOYW1lLG8mJmwobywiU3RyaW5nIikpZm9yKHM9by5zcGxpdCgvXHMrLyksdT0wO3U8cy5sZW5ndGg7dSsrKXIucHVzaChgLiR7c1t1XX1gKTtjb25zdCBmPVsiYXJpYS1sYWJlbCIsInR5cGUiLCJuYW1lIiwidGl0bGUiLCJhbHQiXTtmb3IodT0wO3U8Zi5sZW5ndGg7dSsrKWk9Zlt1XSxjPW4uZ2V0QXR0cmlidXRlKGkpLGMmJnIucHVzaChgWyR7aX09IiR7Y30iXWApO3JldHVybiByLmpvaW4oIiIpfWNvbnN0IFM9InVuZGVmaW5lZCI9PXR5cGVvZiBfX1NFTlRSWV9ERUJVR19ffHxfX1NFTlRSWV9ERUJVR19fLCQ9WyJkZWJ1ZyIsImluZm8iLCJ3YXJuIiwiZXJyb3IiLCJsb2ciLCJhc3NlcnQiLCJ0cmFjZSJdLEU9e307ZnVuY3Rpb24geCh0KXtpZighKCJjb25zb2xlImluIHkpKXJldHVybiB0KCk7Y29uc3QgZT15LmNvbnNvbGUsbj17fSxyPU9iamVjdC5rZXlzKEUpO3IuZm9yRWFjaCgodD0+e2NvbnN0IHI9RVt0XTtuW3RdPWVbdF0sZVt0XT1yfSkpO3RyeXtyZXR1cm4gdCgpfWZpbmFsbHl7ci5mb3JFYWNoKCh0PT57ZVt0XT1uW3RdfSkpfX1jb25zdCBOPWZ1bmN0aW9uKCl7bGV0IHQ9ITE7Y29uc3QgZT17ZW5hYmxlOigpPT57dD0hMH0sZGlzYWJsZTooKT0+e3Q9ITF9LGlzRW5hYmxlZDooKT0+dH07cmV0dXJuIFM/JC5mb3JFYWNoKChuPT57ZVtuXT0oLi4uZSk9Pnt0JiZ4KCgoKT0+e3kuY29uc29sZVtuXShgU2VudHJ5IExvZ2dlciBbJHtufV06YCwuLi5lKX0pKX19KSk6JC5mb3JFYWNoKCh0PT57ZVt0XT0oKT0+e319KSksZX0oKTtmdW5jdGlvbiBrKHQsZT0hMSl7Y29uc3R7aG9zdDpuLHBhdGg6cixwYXNzOm8scG9ydDpzLHByb2plY3RJZDppLHByb3RvY29sOmMscHVibGljS2V5OnV9PXQ7cmV0dXJuYCR7Y306Ly8ke3V9JHtlJiZvP2A6JHtvfWA6IiJ9QCR7bn0ke3M/YDoke3N9YDoiIn0vJHtyP2Ake3J9L2A6cn0ke2l9YH1jbGFzcyBDIGV4dGVuZHMgRXJyb3J7Y29uc3RydWN0b3IodCxlPSJ3YXJuIil7c3VwZXIodCksdGhpcy5tZXNzYWdlPXQsdGhpcy5uYW1lPW5ldy50YXJnZXQucHJvdG90eXBlLmNvbnN0cnVjdG9yLm5hbWUsT2JqZWN0LnNldFByb3RvdHlwZU9mKHRoaXMsbmV3LnRhcmdldC5wcm90b3R5cGUpLHRoaXMubG9nTGV2ZWw9ZX19ZnVuY3Rpb24gRCh0KXtpZihmdW5jdGlvbih0KXtzd2l0Y2gocC5jYWxsKHQpKXtjYXNlIltvYmplY3QgRXJyb3JdIjpjYXNlIltvYmplY3QgRXhjZXB0aW9uXSI6Y2FzZSJbb2JqZWN0IERPTUV4Y2VwdGlvbl0iOnJldHVybiEwO2RlZmF1bHQ6cmV0dXJuIGcodCxFcnJvcil9fSh0KSlyZXR1cm57bWVzc2FnZTp0Lm1lc3NhZ2UsbmFtZTp0Lm5hbWUsc3RhY2s6dC5zdGFjaywuLi5PKHQpfTtpZihlPXQsInVuZGVmaW5lZCIhPXR5cGVvZiBFdmVudCYmZyhlLEV2ZW50KSl7Y29uc3QgZT17dHlwZTp0LnR5cGUsdGFyZ2V0OlQodC50YXJnZXQpLGN1cnJlbnRUYXJnZXQ6VCh0LmN1cnJlbnRUYXJnZXQpLC4uLk8odCl9O3JldHVybiJ1bmRlZmluZWQiIT10eXBlb2YgQ3VzdG9tRXZlbnQmJmcodCxDdXN0b21FdmVudCkmJihlLmRldGFpbD10LmRldGFpbCksZX1yZXR1cm4gdDt2YXIgZX1mdW5jdGlvbiBUKHQpe3RyeXtyZXR1cm4gZT10LCJ1bmRlZmluZWQiIT10eXBlb2YgRWxlbWVudCYmZyhlLEVsZW1lbnQpP2Z1bmN0aW9uKHQsZT17fSl7aWYoIXQpcmV0dXJuIjx1bmtub3duPiI7dHJ5e2xldCBuPXQ7Y29uc3Qgcj01LG89W107bGV0IHM9MCxpPTA7Y29uc3QgYz0iID4gIix1PWMubGVuZ3RoO2xldCBhO2NvbnN0IGY9QXJyYXkuaXNBcnJheShlKT9lOmUua2V5QXR0cnMsaD0hQXJyYXkuaXNBcnJheShlKSYmZS5tYXhTdHJpbmdMZW5ndGh8fF87Zm9yKDtuJiZzKys8ciYmKGE9dyhuLGYpLCEoImh0bWwiPT09YXx8cz4xJiZpK28ubGVuZ3RoKnUrYS5sZW5ndGg+PWgpKTspby5wdXNoKGEpLGkrPWEubGVuZ3RoLG49bi5wYXJlbnROb2RlO3JldHVybiBvLnJldmVyc2UoKS5qb2luKGMpfWNhdGNoKHQpe3JldHVybiI8dW5rbm93bj4ifX0odCk6T2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHQpfWNhdGNoKHQpe3JldHVybiI8dW5rbm93bj4ifXZhciBlfWZ1bmN0aW9uIE8odCl7aWYoIm9iamVjdCI9PXR5cGVvZiB0JiZudWxsIT09dCl7Y29uc3QgZT17fTtmb3IoY29uc3QgbiBpbiB0KU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0LG4pJiYoZVtuXT10W25dKTtyZXR1cm4gZX1yZXR1cm57fX1mdW5jdGlvbiBqKHQpe3JldHVybiBSKHQsbmV3IE1hcCl9ZnVuY3Rpb24gUih0LGUpe2lmKGZ1bmN0aW9uKHQpe2lmKCFkKHQpKXJldHVybiExO3RyeXtjb25zdCBlPU9iamVjdC5nZXRQcm90b3R5cGVPZih0KS5jb25zdHJ1Y3Rvci5uYW1lO3JldHVybiFlfHwiT2JqZWN0Ij09PWV9Y2F0Y2godCl7cmV0dXJuITB9fSh0KSl7Y29uc3Qgbj1lLmdldCh0KTtpZih2b2lkIDAhPT1uKXJldHVybiBuO2NvbnN0IHI9e307ZS5zZXQodCxyKTtmb3IoY29uc3QgbiBvZiBPYmplY3Qua2V5cyh0KSl2b2lkIDAhPT10W25dJiYocltuXT1SKHRbbl0sZSkpO3JldHVybiByfWlmKEFycmF5LmlzQXJyYXkodCkpe2NvbnN0IG49ZS5nZXQodCk7aWYodm9pZCAwIT09bilyZXR1cm4gbjtjb25zdCByPVtdO3JldHVybiBlLnNldCh0LHIpLHQuZm9yRWFjaCgodD0+e3IucHVzaChSKHQsZSkpfSkpLHJ9cmV0dXJuIHR9Y29uc3QgQT01MCxJPSI/IixQPS9jYXB0dXJlTWVzc2FnZXxjYXB0dXJlRXhjZXB0aW9uLztjb25zdCBVPSI8YW5vbnltb3VzPiI7ZnVuY3Rpb24gTSgpe2NvbnN0IHQ9eSxlPXQuY3J5cHRvfHx0Lm1zQ3J5cHRvO2xldCBuPSgpPT4xNipNYXRoLnJhbmRvbSgpO3RyeXtpZihlJiZlLnJhbmRvbVVVSUQpcmV0dXJuIGUucmFuZG9tVVVJRCgpLnJlcGxhY2UoLy0vZywiIik7ZSYmZS5nZXRSYW5kb21WYWx1ZXMmJihuPSgpPT57Y29uc3QgdD1uZXcgVWludDhBcnJheSgxKTtyZXR1cm4gZS5nZXRSYW5kb21WYWx1ZXModCksdFswXX0pfWNhdGNoKHQpe31yZXR1cm4oWzFlN10rMWUzKzRlMys4ZTMrMWUxMSkucmVwbGFjZSgvWzAxOF0vZywodD0+KHReKDE1Jm4oKSk+PnQvNCkudG9TdHJpbmcoMTYpKSl9ZnVuY3Rpb24gTCh0LGU9MTAwLG49MS8wKXt0cnl7cmV0dXJuIEIoIiIsdCxlLG4pfWNhdGNoKHQpe3JldHVybntFUlJPUjpgKipub24tc2VyaWFsaXphYmxlKiogKCR7dH0pYH19fWZ1bmN0aW9uIEIodCxlLG49MS8wLHI9MS8wLG89ZnVuY3Rpb24oKXtjb25zdCB0PSJmdW5jdGlvbiI9PXR5cGVvZiBXZWFrU2V0LGU9dD9uZXcgV2Vha1NldDpbXTtyZXR1cm5bZnVuY3Rpb24obil7aWYodClyZXR1cm4hIWUuaGFzKG4pfHwoZS5hZGQobiksITEpO2ZvcihsZXQgdD0wO3Q8ZS5sZW5ndGg7dCsrKWlmKGVbdF09PT1uKXJldHVybiEwO3JldHVybiBlLnB1c2gobiksITF9LGZ1bmN0aW9uKG4pe2lmKHQpZS5kZWxldGUobik7ZWxzZSBmb3IobGV0IHQ9MDt0PGUubGVuZ3RoO3QrKylpZihlW3RdPT09bil7ZS5zcGxpY2UodCwxKTticmVha319XX0oKSl7Y29uc3RbcyxpXT1vO2lmKG51bGw9PWV8fFsibnVtYmVyIiwiYm9vbGVhbiIsInN0cmluZyJdLmluY2x1ZGVzKHR5cGVvZiBlKSYmIU51bWJlci5pc05hTihlKSlyZXR1cm4gZTtjb25zdCBjPWZ1bmN0aW9uKHQsZSl7dHJ5e2lmKCJkb21haW4iPT09dCYmZSYmIm9iamVjdCI9PXR5cGVvZiBlJiZlLnQpcmV0dXJuIltEb21haW5dIjtpZigiZG9tYWluRW1pdHRlciI9PT10KXJldHVybiJbRG9tYWluRW1pdHRlcl0iO2lmKCJ1bmRlZmluZWQiIT10eXBlb2YgZ2xvYmFsJiZlPT09Z2xvYmFsKXJldHVybiJbR2xvYmFsXSI7aWYoInVuZGVmaW5lZCIhPXR5cGVvZiB3aW5kb3cmJmU9PT13aW5kb3cpcmV0dXJuIltXaW5kb3ddIjtpZigidW5kZWZpbmVkIiE9dHlwZW9mIGRvY3VtZW50JiZlPT09ZG9jdW1lbnQpcmV0dXJuIltEb2N1bWVudF0iO2lmKCJvYmplY3QiPT10eXBlb2Yobj1lKSYmbnVsbCE9PW4mJihuLl9faXNWdWV8fG4ubykpcmV0dXJuIltWdWVWaWV3TW9kZWxdIjtpZihmdW5jdGlvbih0KXtyZXR1cm4gZCh0KSYmIm5hdGl2ZUV2ZW50ImluIHQmJiJwcmV2ZW50RGVmYXVsdCJpbiB0JiYic3RvcFByb3BhZ2F0aW9uImluIHR9KGUpKXJldHVybiJbU3ludGhldGljRXZlbnRdIjtpZigibnVtYmVyIj09dHlwZW9mIGUmJmUhPWUpcmV0dXJuIltOYU5dIjtpZigiZnVuY3Rpb24iPT10eXBlb2YgZSlyZXR1cm5gW0Z1bmN0aW9uOiAke2Z1bmN0aW9uKHQpe3RyeXtyZXR1cm4gdCYmImZ1bmN0aW9uIj09dHlwZW9mIHQmJnQubmFtZXx8VX1jYXRjaCh0KXtyZXR1cm4gVX19KGUpfV1gO2lmKCJzeW1ib2wiPT10eXBlb2YgZSlyZXR1cm5gWyR7U3RyaW5nKGUpfV1gO2lmKCJiaWdpbnQiPT10eXBlb2YgZSlyZXR1cm5gW0JpZ0ludDogJHtTdHJpbmcoZSl9XWA7Y29uc3Qgcj1mdW5jdGlvbih0KXtjb25zdCBlPU9iamVjdC5nZXRQcm90b3R5cGVPZih0KTtyZXR1cm4gZT9lLmNvbnN0cnVjdG9yLm5hbWU6Im51bGwgcHJvdG90eXBlIn0oZSk7cmV0dXJuL15IVE1MKFx3KilFbGVtZW50JC8udGVzdChyKT9gW0hUTUxFbGVtZW50OiAke3J9XWA6YFtvYmplY3QgJHtyfV1gfWNhdGNoKHQpe3JldHVybmAqKm5vbi1zZXJpYWxpemFibGUqKiAoJHt0fSlgfXZhciBufSh0LGUpO2lmKCFjLnN0YXJ0c1dpdGgoIltvYmplY3QgIikpcmV0dXJuIGM7aWYoZS5fX3NlbnRyeV9za2lwX25vcm1hbGl6YXRpb25fXylyZXR1cm4gZTtjb25zdCB1PSJudW1iZXIiPT10eXBlb2YgZS5fX3NlbnRyeV9vdmVycmlkZV9ub3JtYWxpemF0aW9uX2RlcHRoX18/ZS5fX3NlbnRyeV9vdmVycmlkZV9ub3JtYWxpemF0aW9uX2RlcHRoX186bjtpZigwPT09dSlyZXR1cm4gYy5yZXBsYWNlKCJvYmplY3QgIiwiIik7aWYocyhlKSlyZXR1cm4iW0NpcmN1bGFyIH5dIjtjb25zdCBhPWU7aWYoYSYmImZ1bmN0aW9uIj09dHlwZW9mIGEudG9KU09OKXRyeXtyZXR1cm4gQigiIixhLnRvSlNPTigpLHUtMSxyLG8pfWNhdGNoKHQpe31jb25zdCBmPUFycmF5LmlzQXJyYXkoZSk/W106e307bGV0IGg9MDtjb25zdCBwPUQoZSk7Zm9yKGNvbnN0IHQgaW4gcCl7aWYoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChwLHQpKWNvbnRpbnVlO2lmKGg+PXIpe2ZbdF09IltNYXhQcm9wZXJ0aWVzIH5dIjticmVha31jb25zdCBlPXBbdF07Zlt0XT1CKHQsZSx1LTEscixvKSxoKyt9cmV0dXJuIGkoZSksZn1mdW5jdGlvbiBHKHQsZSl7Y29uc3Qgbj1lLnJlcGxhY2UoL1xcL2csIi8iKS5yZXBsYWNlKC9bfFxce30oKVtcXV4kKyo/Ll0vZywiXFwkJiIpO2xldCByPXQ7dHJ5e3I9ZGVjb2RlVVJJKHQpfWNhdGNoKHQpe31yZXR1cm4gci5yZXBsYWNlKC9cXC9nLCIvIikucmVwbGFjZSgvd2VicGFjazpcLz8vZywiIikucmVwbGFjZShuZXcgUmVnRXhwKGAoZmlsZTovLyk/Lyoke259LypgLCJpZyIpLCJhcHA6Ly8vIil9Y29uc3QgSj0vXihcUys6XFx8XC8/KShbXHNcU10qPykoKD86XC57MSwyfXxbXi9cXF0rP3wpKFwuW14uL1xcXSp8KSkoPzpbL1xcXSopJC87ZnVuY3Rpb24geih0KXtjb25zdCBlPWZ1bmN0aW9uKHQpe2NvbnN0IGU9dC5sZW5ndGg+MTAyND9gPHRydW5jYXRlZD4ke3Quc2xpY2UoLTEwMjQpfWA6dCxuPUouZXhlYyhlKTtyZXR1cm4gbj9uLnNsaWNlKDEpOltdfSh0KSxuPWVbMF07bGV0IHI9ZVsxXTtyZXR1cm4gbnx8cj8ociYmKHI9ci5zbGljZSgwLHIubGVuZ3RoLTEpKSxuK3IpOiIuIn12YXIgSDtmdW5jdGlvbiBXKHQpe3JldHVybiBuZXcgWSgoZT0+e2UodCl9KSl9IWZ1bmN0aW9uKHQpe3RbdC5QRU5ESU5HPTBdPSJQRU5ESU5HIjt0W3QuUkVTT0xWRUQ9MV09IlJFU09MVkVEIjt0W3QuUkVKRUNURUQ9Ml09IlJFSkVDVEVEIn0oSHx8KEg9e30pKTtjbGFzcyBZe2NvbnN0cnVjdG9yKHQpe1kucHJvdG90eXBlLl9faW5pdC5jYWxsKHRoaXMpLFkucHJvdG90eXBlLl9faW5pdDIuY2FsbCh0aGlzKSxZLnByb3RvdHlwZS5fX2luaXQzLmNhbGwodGhpcyksWS5wcm90b3R5cGUuX19pbml0NC5jYWxsKHRoaXMpLHRoaXMuaT1ILlBFTkRJTkcsdGhpcy51PVtdO3RyeXt0KHRoaXMuaCx0aGlzLnApfWNhdGNoKHQpe3RoaXMucCh0KX19dGhlbih0LGUpe3JldHVybiBuZXcgWSgoKG4scik9Pnt0aGlzLnUucHVzaChbITEsZT0+e2lmKHQpdHJ5e24odChlKSl9Y2F0Y2godCl7cih0KX1lbHNlIG4oZSl9LHQ9PntpZihlKXRyeXtuKGUodCkpfWNhdGNoKHQpe3IodCl9ZWxzZSByKHQpfV0pLHRoaXMubCgpfSkpfWNhdGNoKHQpe3JldHVybiB0aGlzLnRoZW4oKHQ9PnQpLHQpfWZpbmFsbHkodCl7cmV0dXJuIG5ldyBZKCgoZSxuKT0+e2xldCByLG87cmV0dXJuIHRoaXMudGhlbigoZT0+e289ITEscj1lLHQmJnQoKX0pLChlPT57bz0hMCxyPWUsdCYmdCgpfSkpLnRoZW4oKCgpPT57bz9uKHIpOmUocil9KSl9KSl9X19pbml0KCl7dGhpcy5oPXQ9Pnt0aGlzLm0oSC5SRVNPTFZFRCx0KX19X19pbml0Migpe3RoaXMucD10PT57dGhpcy5tKEguUkVKRUNURUQsdCl9fV9faW5pdDMoKXt0aGlzLm09KHQsZSk9Pnt0aGlzLmk9PT1ILlBFTkRJTkcmJihtKGUpP2UudGhlbih0aGlzLmgsdGhpcy5wKToodGhpcy5pPXQsdGhpcy52PWUsdGhpcy5sKCkpKX19X19pbml0NCgpe3RoaXMubD0oKT0+e2lmKHRoaXMuaT09PUguUEVORElORylyZXR1cm47Y29uc3QgdD10aGlzLnUuc2xpY2UoKTt0aGlzLnU9W10sdC5mb3JFYWNoKCh0PT57dFswXXx8KHRoaXMuaT09PUguUkVTT0xWRUQmJnRbMV0odGhpcy52KSx0aGlzLmk9PT1ILlJFSkVDVEVEJiZ0WzJdKHRoaXMudiksdFswXT0hMCl9KSl9fX1mdW5jdGlvbiBxKHQpe2NvbnN0IGU9W107ZnVuY3Rpb24gbih0KXtyZXR1cm4gZS5zcGxpY2UoZS5pbmRleE9mKHQpLDEpWzBdfXJldHVybnskOmUsYWRkOmZ1bmN0aW9uKHIpe2lmKCEodm9pZCAwPT09dHx8ZS5sZW5ndGg8dCkpcmV0dXJuIG89bmV3IEMoIk5vdCBhZGRpbmcgUHJvbWlzZSBiZWNhdXNlIGJ1ZmZlciBsaW1pdCB3YXMgcmVhY2hlZC4iKSxuZXcgWSgoKHQsZSk9PntlKG8pfSkpO3ZhciBvO2NvbnN0IHM9cigpO3JldHVybi0xPT09ZS5pbmRleE9mKHMpJiZlLnB1c2gocykscy50aGVuKCgoKT0+bihzKSkpLnRoZW4obnVsbCwoKCk9Pm4ocykudGhlbihudWxsLCgoKT0+e30pKSkpLHN9LGRyYWluOmZ1bmN0aW9uKHQpe3JldHVybiBuZXcgWSgoKG4scik9PntsZXQgbz1lLmxlbmd0aDtpZighbylyZXR1cm4gbighMCk7Y29uc3Qgcz1zZXRUaW1lb3V0KCgoKT0+e3QmJnQ+MCYmbighMSl9KSx0KTtlLmZvckVhY2goKHQ9PntXKHQpLnRoZW4oKCgpPT57LS1vfHwoY2xlYXJUaW1lb3V0KHMpLG4oITApKX0pLHIpfSkpfSkpfX19ZnVuY3Rpb24gRih0LGU9ITEpe3JldHVybiEoZXx8dCYmIXQuc3RhcnRzV2l0aCgiLyIpJiYhdC5tYXRjaCgvXltBLVpdOi8pJiYhdC5zdGFydHNXaXRoKCIuIikmJiF0Lm1hdGNoKC9eW2EtekEtWl0oW2EtekEtWjAtOS5cLStdKSo6XC9cLy8pKSYmdm9pZCAwIT09dCYmIXQuaW5jbHVkZXMoIm5vZGVfbW9kdWxlcy8iKX1jb25zdCBLPTFlMztmdW5jdGlvbiBWKCl7cmV0dXJuIERhdGUubm93KCkvS31jb25zdCBaPWZ1bmN0aW9uKCl7Y29uc3R7cGVyZm9ybWFuY2U6dH09eTtpZighdHx8IXQubm93KXJldHVybiBWO2NvbnN0IGU9RGF0ZS5ub3coKS10Lm5vdygpLG49bnVsbD09dC50aW1lT3JpZ2luP2U6dC50aW1lT3JpZ2luO3JldHVybigpPT4obit0Lm5vdygpKS9LfSgpO2Z1bmN0aW9uIFEodCxlPVtdKXtyZXR1cm5bdCxlXX1mdW5jdGlvbiBYKHQsZSl7Y29uc3Qgbj10WzFdO2Zvcihjb25zdCB0IG9mIG4pe2lmKGUodCx0WzBdLnR5cGUpKXJldHVybiEwfXJldHVybiExfWZ1bmN0aW9uIHR0KHQpe3JldHVybiB5Ll9fU0VOVFJZX18mJnkuX19TRU5UUllfXy5lbmNvZGVQb2x5ZmlsbD95Ll9fU0VOVFJZX18uZW5jb2RlUG9seWZpbGwodCk6KG5ldyBUZXh0RW5jb2RlcikuZW5jb2RlKHQpfWZ1bmN0aW9uIGV0KHQpe2NvbnN0W2Usbl09dDtsZXQgcj1KU09OLnN0cmluZ2lmeShlKTtmdW5jdGlvbiBvKHQpeyJzdHJpbmciPT10eXBlb2Ygcj9yPSJzdHJpbmciPT10eXBlb2YgdD9yK3Q6W3R0KHIpLHRdOnIucHVzaCgic3RyaW5nIj09dHlwZW9mIHQ/dHQodCk6dCl9Zm9yKGNvbnN0IHQgb2Ygbil7Y29uc3RbZSxuXT10O2lmKG8oYFxuJHtKU09OLnN0cmluZ2lmeShlKX1cbmApLCJzdHJpbmciPT10eXBlb2Ygbnx8biBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpbyhuKTtlbHNle2xldCB0O3RyeXt0PUpTT04uc3RyaW5naWZ5KG4pfWNhdGNoKGUpe3Q9SlNPTi5zdHJpbmdpZnkoTChuKSl9byh0KX19cmV0dXJuInN0cmluZyI9PXR5cGVvZiByP3I6ZnVuY3Rpb24odCl7Y29uc3QgZT10LnJlZHVjZSgoKHQsZSk9PnQrZS5sZW5ndGgpLDApLG49bmV3IFVpbnQ4QXJyYXkoZSk7bGV0IHI9MDtmb3IoY29uc3QgZSBvZiB0KW4uc2V0KGUscikscis9ZS5sZW5ndGg7cmV0dXJuIG59KHIpfSgoKT0+e2NvbnN0e3BlcmZvcm1hbmNlOnR9PXk7aWYoIXR8fCF0Lm5vdylyZXR1cm47Y29uc3QgZT0zNmU1LG49dC5ub3coKSxyPURhdGUubm93KCksbz10LnRpbWVPcmlnaW4/TWF0aC5hYnModC50aW1lT3JpZ2luK24tcik6ZSxzPW88ZSxpPXQudGltaW5nJiZ0LnRpbWluZy5uYXZpZ2F0aW9uU3RhcnQsYz0ibnVtYmVyIj09dHlwZW9mIGk/TWF0aC5hYnMoaStuLXIpOmU7KHN8fGM8ZSkmJihvPD1jJiZ0LnRpbWVPcmlnaW4pfSkoKTtjb25zdCBudD17c2Vzc2lvbjoic2Vzc2lvbiIsc2Vzc2lvbnM6InNlc3Npb24iLGF0dGFjaG1lbnQ6ImF0dGFjaG1lbnQiLHRyYW5zYWN0aW9uOiJ0cmFuc2FjdGlvbiIsZXZlbnQ6ImVycm9yIixjbGllbnRfcmVwb3J0OiJpbnRlcm5hbCIsdXNlcl9yZXBvcnQ6ImRlZmF1bHQiLHByb2ZpbGU6InByb2ZpbGUiLHJlcGxheV9ldmVudDoicmVwbGF5IixyZXBsYXlfcmVjb3JkaW5nOiJyZXBsYXkiLGNoZWNrX2luOiJtb25pdG9yIixmZWVkYmFjazoiZmVlZGJhY2siLHNwYW46InNwYW4iLHN0YXRzZDoibWV0cmljX2J1Y2tldCJ9O2Z1bmN0aW9uIHJ0KHQpe3JldHVybiBudFt0XX1mdW5jdGlvbiBvdCh0KXtpZighdHx8IXQuc2RrKXJldHVybjtjb25zdHtuYW1lOmUsdmVyc2lvbjpufT10LnNkaztyZXR1cm57bmFtZTplLHZlcnNpb246bn19Y29uc3Qgc3Q9NmU0O2Z1bmN0aW9uIGl0KHQse3N0YXR1c0NvZGU6ZSxoZWFkZXJzOm59LHI9RGF0ZS5ub3coKSl7Y29uc3Qgbz17Li4udH0scz1uJiZuWyJ4LXNlbnRyeS1yYXRlLWxpbWl0cyJdLGk9biYmblsicmV0cnktYWZ0ZXIiXTtpZihzKWZvcihjb25zdCB0IG9mIHMudHJpbSgpLnNwbGl0KCIsIikpe2NvbnN0W2UsbiwsLHNdPXQuc3BsaXQoIjoiLDUpLGk9cGFyc2VJbnQoZSwxMCksYz0xZTMqKGlzTmFOKGkpPzYwOmkpO2lmKG4pZm9yKGNvbnN0IHQgb2Ygbi5zcGxpdCgiOyIpKSJtZXRyaWNfYnVja2V0Ij09PXQmJnMmJiFzLnNwbGl0KCI7IikuaW5jbHVkZXMoImN1c3RvbSIpfHwob1t0XT1yK2MpO2Vsc2Ugby5hbGw9citjfWVsc2UgaT9vLmFsbD1yK2Z1bmN0aW9uKHQsZT1EYXRlLm5vdygpKXtjb25zdCBuPXBhcnNlSW50KGAke3R9YCwxMCk7aWYoIWlzTmFOKG4pKXJldHVybiAxZTMqbjtjb25zdCByPURhdGUucGFyc2UoYCR7dH1gKTtyZXR1cm4gaXNOYU4ocik/c3Q6ci1lfShpLHIpOjQyOT09PWUmJihvLmFsbD1yKzZlNCk7cmV0dXJuIG99Y29uc3QgY3Q9InVuZGVmaW5lZCI9PXR5cGVvZiBfX1NFTlRSWV9ERUJVR19ffHxfX1NFTlRSWV9ERUJVR19fO2Z1bmN0aW9uIHV0KCl7cmV0dXJuIGF0KHkpLHl9ZnVuY3Rpb24gYXQodCl7cmV0dXJuIHQuX19TRU5UUllfX3x8KHQuX19TRU5UUllfXz17ZXh0ZW5zaW9uczp7fX0pLHQuX19TRU5UUllfX31mdW5jdGlvbiBmdCh0KXtjb25zdCBlPVooKSxuPXtzaWQ6TSgpLGluaXQ6ITAsdGltZXN0YW1wOmUsc3RhcnRlZDplLGR1cmF0aW9uOjAsc3RhdHVzOiJvayIsZXJyb3JzOjAsaWdub3JlRHVyYXRpb246ITEsdG9KU09OOigpPT5mdW5jdGlvbih0KXtyZXR1cm4gaih7c2lkOmAke3Quc2lkfWAsaW5pdDp0LmluaXQsc3RhcnRlZDpuZXcgRGF0ZSgxZTMqdC5zdGFydGVkKS50b0lTT1N0cmluZygpLHRpbWVzdGFtcDpuZXcgRGF0ZSgxZTMqdC50aW1lc3RhbXApLnRvSVNPU3RyaW5nKCksc3RhdHVzOnQuc3RhdHVzLGVycm9yczp0LmVycm9ycyxkaWQ6Im51bWJlciI9PXR5cGVvZiB0LmRpZHx8InN0cmluZyI9PXR5cGVvZiB0LmRpZD9gJHt0LmRpZH1gOnZvaWQgMCxkdXJhdGlvbjp0LmR1cmF0aW9uLGFibm9ybWFsX21lY2hhbmlzbTp0LmFibm9ybWFsX21lY2hhbmlzbSxhdHRyczp7cmVsZWFzZTp0LnJlbGVhc2UsZW52aXJvbm1lbnQ6dC5lbnZpcm9ubWVudCxpcF9hZGRyZXNzOnQuaXBBZGRyZXNzLHVzZXJfYWdlbnQ6dC51c2VyQWdlbnR9fSl9KG4pfTtyZXR1cm4gdCYmaHQobix0KSxufWZ1bmN0aW9uIGh0KHQsZT17fSl7aWYoZS51c2VyJiYoIXQuaXBBZGRyZXNzJiZlLnVzZXIuaXBfYWRkcmVzcyYmKHQuaXBBZGRyZXNzPWUudXNlci5pcF9hZGRyZXNzKSx0LmRpZHx8ZS5kaWR8fCh0LmRpZD1lLnVzZXIuaWR8fGUudXNlci5lbWFpbHx8ZS51c2VyLnVzZXJuYW1lKSksdC50aW1lc3RhbXA9ZS50aW1lc3RhbXB8fFooKSxlLmFibm9ybWFsX21lY2hhbmlzbSYmKHQuYWJub3JtYWxfbWVjaGFuaXNtPWUuYWJub3JtYWxfbWVjaGFuaXNtKSxlLmlnbm9yZUR1cmF0aW9uJiYodC5pZ25vcmVEdXJhdGlvbj1lLmlnbm9yZUR1cmF0aW9uKSxlLnNpZCYmKHQuc2lkPTMyPT09ZS5zaWQubGVuZ3RoP2Uuc2lkOk0oKSksdm9pZCAwIT09ZS5pbml0JiYodC5pbml0PWUuaW5pdCksIXQuZGlkJiZlLmRpZCYmKHQuZGlkPWAke2UuZGlkfWApLCJudW1iZXIiPT10eXBlb2YgZS5zdGFydGVkJiYodC5zdGFydGVkPWUuc3RhcnRlZCksdC5pZ25vcmVEdXJhdGlvbil0LmR1cmF0aW9uPXZvaWQgMDtlbHNlIGlmKCJudW1iZXIiPT10eXBlb2YgZS5kdXJhdGlvbil0LmR1cmF0aW9uPWUuZHVyYXRpb247ZWxzZXtjb25zdCBlPXQudGltZXN0YW1wLXQuc3RhcnRlZDt0LmR1cmF0aW9uPWU+PTA/ZTowfWUucmVsZWFzZSYmKHQucmVsZWFzZT1lLnJlbGVhc2UpLGUuZW52aXJvbm1lbnQmJih0LmVudmlyb25tZW50PWUuZW52aXJvbm1lbnQpLCF0LmlwQWRkcmVzcyYmZS5pcEFkZHJlc3MmJih0LmlwQWRkcmVzcz1lLmlwQWRkcmVzcyksIXQudXNlckFnZW50JiZlLnVzZXJBZ2VudCYmKHQudXNlckFnZW50PWUudXNlckFnZW50KSwibnVtYmVyIj09dHlwZW9mIGUuZXJyb3JzJiYodC5lcnJvcnM9ZS5lcnJvcnMpLGUuc3RhdHVzJiYodC5zdGF0dXM9ZS5zdGF0dXMpfWNvbnN0IHB0PSJfc2VudHJ5U3BhbiI7ZnVuY3Rpb24gbHQodCxlKXtlP2Z1bmN0aW9uKHQsZSxuKXt0cnl7T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsZSx7dmFsdWU6bix3cml0YWJsZTohMCxjb25maWd1cmFibGU6ITB9KX1jYXRjaChuKXtTJiZOLmxvZyhgRmFpbGVkIHRvIGFkZCBub24tZW51bWVyYWJsZSBwcm9wZXJ0eSAiJHtlfSIgdG8gb2JqZWN0YCx0KX19KHQscHQsZSk6ZGVsZXRlIHRbcHRdfWZ1bmN0aW9uIGR0KHQpe3JldHVybiB0W3B0XX1jbGFzcyBtdHtjb25zdHJ1Y3Rvcigpe3RoaXMuXz0hMSx0aGlzLlM9W10sdGhpcy5OPVtdLHRoaXMuaz1bXSx0aGlzLkM9W10sdGhpcy5EPXt9LHRoaXMuVD17fSx0aGlzLk89e30sdGhpcy5qPXt9LHRoaXMuUj17fSx0aGlzLkE9Z3QoKX1jbG9uZSgpe2NvbnN0IHQ9bmV3IG10O3JldHVybiB0Lms9Wy4uLnRoaXMua10sdC5UPXsuLi50aGlzLlR9LHQuTz17Li4udGhpcy5PfSx0Lmo9ey4uLnRoaXMuan0sdC5EPXRoaXMuRCx0Lkk9dGhpcy5JLHQuUD10aGlzLlAsdC5VPXRoaXMuVSx0Lk09dGhpcy5NLHQuTj1bLi4udGhpcy5OXSx0Lkw9dGhpcy5MLHQuQz1bLi4udGhpcy5DXSx0LlI9ey4uLnRoaXMuUn0sdC5BPXsuLi50aGlzLkF9LHQuQj10aGlzLkIsbHQodCxkdCh0aGlzKSksdH1zZXRDbGllbnQodCl7dGhpcy5CPXR9Z2V0Q2xpZW50KCl7cmV0dXJuIHRoaXMuQn1hZGRTY29wZUxpc3RlbmVyKHQpe3RoaXMuUy5wdXNoKHQpfWFkZEV2ZW50UHJvY2Vzc29yKHQpe3JldHVybiB0aGlzLk4ucHVzaCh0KSx0aGlzfXNldFVzZXIodCl7cmV0dXJuIHRoaXMuRD10fHx7ZW1haWw6dm9pZCAwLGlkOnZvaWQgMCxpcF9hZGRyZXNzOnZvaWQgMCx1c2VybmFtZTp2b2lkIDB9LHRoaXMuUCYmaHQodGhpcy5QLHt1c2VyOnR9KSx0aGlzLkcoKSx0aGlzfWdldFVzZXIoKXtyZXR1cm4gdGhpcy5EfWdldFJlcXVlc3RTZXNzaW9uKCl7cmV0dXJuIHRoaXMuTH1zZXRSZXF1ZXN0U2Vzc2lvbih0KXtyZXR1cm4gdGhpcy5MPXQsdGhpc31zZXRUYWdzKHQpe3JldHVybiB0aGlzLlQ9ey4uLnRoaXMuVCwuLi50fSx0aGlzLkcoKSx0aGlzfXNldFRhZyh0LGUpe3JldHVybiB0aGlzLlQ9ey4uLnRoaXMuVCxbdF06ZX0sdGhpcy5HKCksdGhpc31zZXRFeHRyYXModCl7cmV0dXJuIHRoaXMuTz17Li4udGhpcy5PLC4uLnR9LHRoaXMuRygpLHRoaXN9c2V0RXh0cmEodCxlKXtyZXR1cm4gdGhpcy5PPXsuLi50aGlzLk8sW3RdOmV9LHRoaXMuRygpLHRoaXN9c2V0RmluZ2VycHJpbnQodCl7cmV0dXJuIHRoaXMuTT10LHRoaXMuRygpLHRoaXN9c2V0TGV2ZWwodCl7cmV0dXJuIHRoaXMuST10LHRoaXMuRygpLHRoaXN9c2V0VHJhbnNhY3Rpb25OYW1lKHQpe3JldHVybiB0aGlzLlU9dCx0aGlzLkcoKSx0aGlzfXNldENvbnRleHQodCxlKXtyZXR1cm4gbnVsbD09PWU/ZGVsZXRlIHRoaXMualt0XTp0aGlzLmpbdF09ZSx0aGlzLkcoKSx0aGlzfXNldFNlc3Npb24odCl7cmV0dXJuIHQ/dGhpcy5QPXQ6ZGVsZXRlIHRoaXMuUCx0aGlzLkcoKSx0aGlzfWdldFNlc3Npb24oKXtyZXR1cm4gdGhpcy5QfXVwZGF0ZSh0KXtpZighdClyZXR1cm4gdGhpcztjb25zdCBlPSJmdW5jdGlvbiI9PXR5cGVvZiB0P3QodGhpcyk6dCxbbixyXT1lIGluc3RhbmNlb2YgbXQ/W2UuZ2V0U2NvcGVEYXRhKCksZS5nZXRSZXF1ZXN0U2Vzc2lvbigpXTpkKGUpP1t0LHQucmVxdWVzdFNlc3Npb25dOltdLHt0YWdzOm8sZXh0cmE6cyx1c2VyOmksY29udGV4dHM6YyxsZXZlbDp1LGZpbmdlcnByaW50OmE9W10scHJvcGFnYXRpb25Db250ZXh0OmZ9PW58fHt9O3JldHVybiB0aGlzLlQ9ey4uLnRoaXMuVCwuLi5vfSx0aGlzLk89ey4uLnRoaXMuTywuLi5zfSx0aGlzLmo9ey4uLnRoaXMuaiwuLi5jfSxpJiZPYmplY3Qua2V5cyhpKS5sZW5ndGgmJih0aGlzLkQ9aSksdSYmKHRoaXMuST11KSxhLmxlbmd0aCYmKHRoaXMuTT1hKSxmJiYodGhpcy5BPWYpLHImJih0aGlzLkw9ciksdGhpc31jbGVhcigpe3JldHVybiB0aGlzLms9W10sdGhpcy5UPXt9LHRoaXMuTz17fSx0aGlzLkQ9e30sdGhpcy5qPXt9LHRoaXMuST12b2lkIDAsdGhpcy5VPXZvaWQgMCx0aGlzLk09dm9pZCAwLHRoaXMuTD12b2lkIDAsdGhpcy5QPXZvaWQgMCxsdCh0aGlzLHZvaWQgMCksdGhpcy5DPVtdLHRoaXMuQT1ndCgpLHRoaXMuRygpLHRoaXN9YWRkQnJlYWRjcnVtYih0LGUpe2NvbnN0IG49Im51bWJlciI9PXR5cGVvZiBlP2U6MTAwO2lmKG48PTApcmV0dXJuIHRoaXM7Y29uc3Qgcj17dGltZXN0YW1wOlYoKSwuLi50fSxvPXRoaXMuaztyZXR1cm4gby5wdXNoKHIpLHRoaXMuaz1vLmxlbmd0aD5uP28uc2xpY2UoLW4pOm8sdGhpcy5HKCksdGhpc31nZXRMYXN0QnJlYWRjcnVtYigpe3JldHVybiB0aGlzLmtbdGhpcy5rLmxlbmd0aC0xXX1jbGVhckJyZWFkY3J1bWJzKCl7cmV0dXJuIHRoaXMuaz1bXSx0aGlzLkcoKSx0aGlzfWFkZEF0dGFjaG1lbnQodCl7cmV0dXJuIHRoaXMuQy5wdXNoKHQpLHRoaXN9Y2xlYXJBdHRhY2htZW50cygpe3JldHVybiB0aGlzLkM9W10sdGhpc31nZXRTY29wZURhdGEoKXtyZXR1cm57YnJlYWRjcnVtYnM6dGhpcy5rLGF0dGFjaG1lbnRzOnRoaXMuQyxjb250ZXh0czp0aGlzLmosdGFnczp0aGlzLlQsZXh0cmE6dGhpcy5PLHVzZXI6dGhpcy5ELGxldmVsOnRoaXMuSSxmaW5nZXJwcmludDp0aGlzLk18fFtdLGV2ZW50UHJvY2Vzc29yczp0aGlzLk4scHJvcGFnYXRpb25Db250ZXh0OnRoaXMuQSxzZGtQcm9jZXNzaW5nTWV0YWRhdGE6dGhpcy5SLHRyYW5zYWN0aW9uTmFtZTp0aGlzLlUsc3BhbjpkdCh0aGlzKX19c2V0U0RLUHJvY2Vzc2luZ01ldGFkYXRhKHQpe3JldHVybiB0aGlzLlI9ey4uLnRoaXMuUiwuLi50fSx0aGlzfXNldFByb3BhZ2F0aW9uQ29udGV4dCh0KXtyZXR1cm4gdGhpcy5BPXQsdGhpc31nZXRQcm9wYWdhdGlvbkNvbnRleHQoKXtyZXR1cm4gdGhpcy5BfWNhcHR1cmVFeGNlcHRpb24odCxlKXtjb25zdCBuPWUmJmUuZXZlbnRfaWQ/ZS5ldmVudF9pZDpNKCk7aWYoIXRoaXMuQilyZXR1cm4gTi53YXJuKCJObyBjbGllbnQgY29uZmlndXJlZCBvbiBzY29wZSAtIHdpbGwgbm90IGNhcHR1cmUgZXhjZXB0aW9uISIpLG47Y29uc3Qgcj1uZXcgRXJyb3IoIlNlbnRyeSBzeW50aGV0aWNFeGNlcHRpb24iKTtyZXR1cm4gdGhpcy5CLmNhcHR1cmVFeGNlcHRpb24odCx7b3JpZ2luYWxFeGNlcHRpb246dCxzeW50aGV0aWNFeGNlcHRpb246ciwuLi5lLGV2ZW50X2lkOm59LHRoaXMpLG59Y2FwdHVyZU1lc3NhZ2UodCxlLG4pe2NvbnN0IHI9biYmbi5ldmVudF9pZD9uLmV2ZW50X2lkOk0oKTtpZighdGhpcy5CKXJldHVybiBOLndhcm4oIk5vIGNsaWVudCBjb25maWd1cmVkIG9uIHNjb3BlIC0gd2lsbCBub3QgY2FwdHVyZSBtZXNzYWdlISIpLHI7Y29uc3Qgbz1uZXcgRXJyb3IodCk7cmV0dXJuIHRoaXMuQi5jYXB0dXJlTWVzc2FnZSh0LGUse29yaWdpbmFsRXhjZXB0aW9uOnQsc3ludGhldGljRXhjZXB0aW9uOm8sLi4ubixldmVudF9pZDpyfSx0aGlzKSxyfWNhcHR1cmVFdmVudCh0LGUpe2NvbnN0IG49ZSYmZS5ldmVudF9pZD9lLmV2ZW50X2lkOk0oKTtyZXR1cm4gdGhpcy5CPyh0aGlzLkIuY2FwdHVyZUV2ZW50KHQsey4uLmUsZXZlbnRfaWQ6bn0sdGhpcyksbik6KE4ud2FybigiTm8gY2xpZW50IGNvbmZpZ3VyZWQgb24gc2NvcGUgLSB3aWxsIG5vdCBjYXB0dXJlIGV2ZW50ISIpLG4pfUcoKXt0aGlzLl98fCh0aGlzLl89ITAsdGhpcy5TLmZvckVhY2goKHQ9Pnt0KHRoaXMpfSkpLHRoaXMuXz0hMSl9fWZ1bmN0aW9uIGd0KCl7cmV0dXJue3RyYWNlSWQ6TSgpLHNwYW5JZDpNKCkuc3Vic3RyaW5nKDE2KX19ZnVuY3Rpb24geXQoKXtyZXR1cm4gJHQodXQoKSkuZ2V0Q3VycmVudFNjb3BlKCkuZ2V0Q2xpZW50KCl9Y2xhc3MgYnR7Y29uc3RydWN0b3IodCxlKXtsZXQgbixyO249dHx8bmV3IG10LHI9ZXx8bmV3IG10LHRoaXMuSj1be3Njb3BlOm59XSx0aGlzLkg9cn13aXRoU2NvcGUodCl7Y29uc3QgZT10aGlzLlcoKTtsZXQgbjt0cnl7bj10KGUpfWNhdGNoKHQpe3Rocm93IHRoaXMuWSgpLHR9cmV0dXJuIG0obik/bi50aGVuKCh0PT4odGhpcy5ZKCksdCkpLCh0PT57dGhyb3cgdGhpcy5ZKCksdH0pKToodGhpcy5ZKCksbil9Z2V0Q2xpZW50KCl7cmV0dXJuIHRoaXMuZ2V0U3RhY2tUb3AoKS5jbGllbnR9Z2V0U2NvcGUoKXtyZXR1cm4gdGhpcy5nZXRTdGFja1RvcCgpLnNjb3BlfWdldElzb2xhdGlvblNjb3BlKCl7cmV0dXJuIHRoaXMuSH1nZXRTdGFjaygpe3JldHVybiB0aGlzLkp9Z2V0U3RhY2tUb3AoKXtyZXR1cm4gdGhpcy5KW3RoaXMuSi5sZW5ndGgtMV19Vygpe2NvbnN0IHQ9dGhpcy5nZXRTY29wZSgpLmNsb25lKCk7cmV0dXJuIHRoaXMuZ2V0U3RhY2soKS5wdXNoKHtjbGllbnQ6dGhpcy5nZXRDbGllbnQoKSxzY29wZTp0fSksdH1ZKCl7cmV0dXJuISh0aGlzLmdldFN0YWNrKCkubGVuZ3RoPD0xKSYmISF0aGlzLmdldFN0YWNrKCkucG9wKCl9fWZ1bmN0aW9uIHZ0KCl7Y29uc3QgdD1hdCh1dCgpKTtyZXR1cm4gdC5odWJ8fCh0Lmh1Yj1uZXcgYnQoYigiZGVmYXVsdEN1cnJlbnRTY29wZSIsKCgpPT5uZXcgbXQpKSxiKCJkZWZhdWx0SXNvbGF0aW9uU2NvcGUiLCgoKT0+bmV3IG10KSkpKSx0Lmh1Yn1mdW5jdGlvbiBfdCh0KXtyZXR1cm4gdnQoKS53aXRoU2NvcGUodCl9ZnVuY3Rpb24gd3QodCxlKXtjb25zdCBuPXZ0KCk7cmV0dXJuIG4ud2l0aFNjb3BlKCgoKT0+KG4uZ2V0U3RhY2tUb3AoKS5zY29wZT10LGUodCkpKSl9ZnVuY3Rpb24gU3QodCl7cmV0dXJuIHZ0KCkud2l0aFNjb3BlKCgoKT0+dCh2dCgpLmdldElzb2xhdGlvblNjb3BlKCkpKSl9ZnVuY3Rpb24gJHQodCl7Y29uc3QgZT1hdCh0KTtyZXR1cm4gZS5hY3M/ZS5hY3M6e3dpdGhJc29sYXRpb25TY29wZTpTdCx3aXRoU2NvcGU6X3Qsd2l0aFNldFNjb3BlOnd0LHdpdGhTZXRJc29sYXRpb25TY29wZToodCxlKT0+U3QoZSksZ2V0Q3VycmVudFNjb3BlOigpPT52dCgpLmdldFNjb3BlKCksZ2V0SXNvbGF0aW9uU2NvcGU6KCk9PnZ0KCkuZ2V0SXNvbGF0aW9uU2NvcGUoKX19Y29uc3QgRXQ9InNlbnRyeS5zb3VyY2UiLHh0PSJzZW50cnkuc2FtcGxlX3JhdGUiLE50PSJzZW50cnkub3AiLGt0PSJzZW50cnkub3JpZ2luIixDdD0wLER0PTEsVHQ9InByb2R1Y3Rpb24iLE90PSJfZnJvemVuRHNjIjtmdW5jdGlvbiBqdCh0KXtjb25zdCBlPXl0KCk7aWYoIWUpcmV0dXJue307Y29uc3Qgbj1mdW5jdGlvbih0LGUpe2NvbnN0IG49ZS5nZXRPcHRpb25zKCkse3B1YmxpY0tleTpyfT1lLmdldERzbigpfHx7fSxvPWooe2Vudmlyb25tZW50Om4uZW52aXJvbm1lbnR8fFR0LHJlbGVhc2U6bi5yZWxlYXNlLHB1YmxpY19rZXk6cix0cmFjZV9pZDp0fSk7cmV0dXJuIGUuZW1pdCgiY3JlYXRlRHNjIixvKSxvfShVdCh0KS50cmFjZV9pZHx8IiIsZSkscj1CdCh0KTtpZighcilyZXR1cm4gbjtjb25zdCBvPXJbT3RdO2lmKG8pcmV0dXJuIG87Y29uc3Qgcz1VdChyKSxpPXMuZGF0YXx8e30sYz1pW3h0XTtudWxsIT1jJiYobi5zYW1wbGVfcmF0ZT1gJHtjfWApO2NvbnN0IHU9aVtFdF07cmV0dXJuIHUmJiJ1cmwiIT09dSYmKG4udHJhbnNhY3Rpb249cy5kZXNjcmlwdGlvbiksbi5zYW1wbGVkPVN0cmluZyhmdW5jdGlvbih0KXtjb25zdHt0cmFjZUZsYWdzOmV9PXQuc3BhbkNvbnRleHQoKTtyZXR1cm4gZT09PVJ0fShyKSksZS5lbWl0KCJjcmVhdGVEc2MiLG4pLG59Y29uc3QgUnQ9MTtmdW5jdGlvbiBBdCh0KXtjb25zdHtzcGFuSWQ6ZSx0cmFjZUlkOm59PXQuc3BhbkNvbnRleHQoKSx7cGFyZW50X3NwYW5faWQ6cn09VXQodCk7cmV0dXJuIGooe3BhcmVudF9zcGFuX2lkOnIsc3Bhbl9pZDplLHRyYWNlX2lkOm59KX1mdW5jdGlvbiBJdCh0KXtyZXR1cm4ibnVtYmVyIj09dHlwZW9mIHQ/UHQodCk6QXJyYXkuaXNBcnJheSh0KT90WzBdK3RbMV0vMWU5OnQgaW5zdGFuY2VvZiBEYXRlP1B0KHQuZ2V0VGltZSgpKTpaKCl9ZnVuY3Rpb24gUHQodCl7cmV0dXJuIHQ+OTk5OTk5OTk5OT90LzFlMzp0fWZ1bmN0aW9uIFV0KHQpe2lmKGZ1bmN0aW9uKHQpe3JldHVybiJmdW5jdGlvbiI9PXR5cGVvZiB0LmdldFNwYW5KU09OfSh0KSlyZXR1cm4gdC5nZXRTcGFuSlNPTigpO3RyeXtjb25zdHtzcGFuSWQ6ZSx0cmFjZUlkOm59PXQuc3BhbkNvbnRleHQoKTtpZihmdW5jdGlvbih0KXtjb25zdCBlPXQ7cmV0dXJuISEoZS5hdHRyaWJ1dGVzJiZlLnN0YXJ0VGltZSYmZS5uYW1lJiZlLmVuZFRpbWUmJmUuc3RhdHVzKX0odCkpe2NvbnN0e2F0dHJpYnV0ZXM6cixzdGFydFRpbWU6byxuYW1lOnMsZW5kVGltZTppLHBhcmVudFNwYW5JZDpjLHN0YXR1czp1fT10O3JldHVybiBqKHtzcGFuX2lkOmUsdHJhY2VfaWQ6bixkYXRhOnIsZGVzY3JpcHRpb246cyxwYXJlbnRfc3Bhbl9pZDpjLHN0YXJ0X3RpbWVzdGFtcDpJdChvKSx0aW1lc3RhbXA6SXQoaSl8fHZvaWQgMCxzdGF0dXM6TXQodSksb3A6cltOdF0sb3JpZ2luOnJba3RdLHE6dm9pZCAwfSl9cmV0dXJue3NwYW5faWQ6ZSx0cmFjZV9pZDpufX1jYXRjaCh0KXtyZXR1cm57fX19ZnVuY3Rpb24gTXQodCl7aWYodCYmdC5jb2RlIT09Q3QpcmV0dXJuIHQuY29kZT09PUR0PyJvayI6dC5tZXNzYWdlfHwidW5rbm93bl9lcnJvciJ9Y29uc3QgTHQ9Il9zZW50cnlSb290U3BhbiI7ZnVuY3Rpb24gQnQodCl7cmV0dXJuIHRbTHRdfHx0fWZ1bmN0aW9uIEd0KHQsZSxuLHIpe2NvbnN0IG89b3Qobikscz10LnR5cGUmJiJyZXBsYXlfZXZlbnQiIT09dC50eXBlP3QudHlwZToiZXZlbnQiOyFmdW5jdGlvbih0LGUpe2UmJih0LnNkaz10LnNka3x8e30sdC5zZGsubmFtZT10LnNkay5uYW1lfHxlLm5hbWUsdC5zZGsudmVyc2lvbj10LnNkay52ZXJzaW9ufHxlLnZlcnNpb24sdC5zZGsuaW50ZWdyYXRpb25zPVsuLi50LnNkay5pbnRlZ3JhdGlvbnN8fFtdLC4uLmUuaW50ZWdyYXRpb25zfHxbXV0sdC5zZGsucGFja2FnZXM9Wy4uLnQuc2RrLnBhY2thZ2VzfHxbXSwuLi5lLnBhY2thZ2VzfHxbXV0pfSh0LG4mJm4uc2RrKTtjb25zdCBpPWZ1bmN0aW9uKHQsZSxuLHIpe2NvbnN0IG89dC5zZGtQcm9jZXNzaW5nTWV0YWRhdGEmJnQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhLmR5bmFtaWNTYW1wbGluZ0NvbnRleHQ7cmV0dXJue2V2ZW50X2lkOnQuZXZlbnRfaWQsc2VudF9hdDoobmV3IERhdGUpLnRvSVNPU3RyaW5nKCksLi4uZSYme3NkazplfSwuLi4hIW4mJnImJntkc246ayhyKX0sLi4ubyYme3RyYWNlOmooey4uLm99KX19fSh0LG8scixlKTtkZWxldGUgdC5zZGtQcm9jZXNzaW5nTWV0YWRhdGE7cmV0dXJuIFEoaSxbW3t0eXBlOnN9LHRdXSl9Y29uc3QgSnQ9Il9fU0VOVFJZX1NVUFBSRVNTX1RSQUNJTkdfXyI7ZnVuY3Rpb24genQodCl7Y29uc3QgZT0kdCh1dCgpKTtyZXR1cm4gZS5zdXBwcmVzc1RyYWNpbmc/ZS5zdXBwcmVzc1RyYWNpbmcodCk6ZnVuY3Rpb24oLi4udCl7Y29uc3QgZT0kdCh1dCgpKTtpZigyPT09dC5sZW5ndGgpe2NvbnN0W24scl09dDtyZXR1cm4gbj9lLndpdGhTZXRTY29wZShuLHIpOmUud2l0aFNjb3BlKHIpfXJldHVybiBlLndpdGhTY29wZSh0WzBdKX0oKGU9PihlLnNldFNES1Byb2Nlc3NpbmdNZXRhZGF0YSh7W0p0XTohMH0pLHQoKSkpKX1mdW5jdGlvbiBIdCh0LGUpe2NvbnN0e2ZpbmdlcnByaW50Om4sc3BhbjpyLGJyZWFkY3J1bWJzOm8sc2RrUHJvY2Vzc2luZ01ldGFkYXRhOnN9PWU7IWZ1bmN0aW9uKHQsZSl7Y29uc3R7ZXh0cmE6bix0YWdzOnIsdXNlcjpvLGNvbnRleHRzOnMsbGV2ZWw6aSx0cmFuc2FjdGlvbk5hbWU6Y309ZSx1PWoobik7dSYmT2JqZWN0LmtleXModSkubGVuZ3RoJiYodC5leHRyYT17Li4udSwuLi50LmV4dHJhfSk7Y29uc3QgYT1qKHIpO2EmJk9iamVjdC5rZXlzKGEpLmxlbmd0aCYmKHQudGFncz17Li4uYSwuLi50LnRhZ3N9KTtjb25zdCBmPWoobyk7ZiYmT2JqZWN0LmtleXMoZikubGVuZ3RoJiYodC51c2VyPXsuLi5mLC4uLnQudXNlcn0pO2NvbnN0IGg9aihzKTtoJiZPYmplY3Qua2V5cyhoKS5sZW5ndGgmJih0LmNvbnRleHRzPXsuLi5oLC4uLnQuY29udGV4dHN9KTtpJiYodC5sZXZlbD1pKTtjJiYidHJhbnNhY3Rpb24iIT09dC50eXBlJiYodC50cmFuc2FjdGlvbj1jKX0odCxlKSxyJiZmdW5jdGlvbih0LGUpe3QuY29udGV4dHM9e3RyYWNlOkF0KGUpLC4uLnQuY29udGV4dHN9LHQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhPXtkeW5hbWljU2FtcGxpbmdDb250ZXh0Omp0KGUpLC4uLnQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhfTtjb25zdCBuPUJ0KGUpLHI9VXQobikuZGVzY3JpcHRpb247ciYmIXQudHJhbnNhY3Rpb24mJiJ0cmFuc2FjdGlvbiI9PT10LnR5cGUmJih0LnRyYW5zYWN0aW9uPXIpfSh0LHIpLGZ1bmN0aW9uKHQsZSl7dC5maW5nZXJwcmludD10LmZpbmdlcnByaW50P2Z1bmN0aW9uKHQpe3JldHVybiBBcnJheS5pc0FycmF5KHQpP3Q6W3RdfSh0LmZpbmdlcnByaW50KTpbXSxlJiYodC5maW5nZXJwcmludD10LmZpbmdlcnByaW50LmNvbmNhdChlKSk7dC5maW5nZXJwcmludCYmIXQuZmluZ2VycHJpbnQubGVuZ3RoJiZkZWxldGUgdC5maW5nZXJwcmludH0odCxuKSxmdW5jdGlvbih0LGUpe2NvbnN0IG49Wy4uLnQuYnJlYWRjcnVtYnN8fFtdLC4uLmVdO3QuYnJlYWRjcnVtYnM9bi5sZW5ndGg/bjp2b2lkIDB9KHQsbyksZnVuY3Rpb24odCxlKXt0LnNka1Byb2Nlc3NpbmdNZXRhZGF0YT17Li4udC5zZGtQcm9jZXNzaW5nTWV0YWRhdGEsLi4uZX19KHQscyl9Y29uc3QgV3Q9IjciO2Z1bmN0aW9uIFl0KHQsZSl7cmV0dXJuIG49e3NlbnRyeV9rZXk6dC5wdWJsaWNLZXksc2VudHJ5X3ZlcnNpb246V3QsLi4uZSYme3NlbnRyeV9jbGllbnQ6YCR7ZS5uYW1lfS8ke2UudmVyc2lvbn1gfX0sT2JqZWN0LmtleXMobikubWFwKCh0PT5gJHtlbmNvZGVVUklDb21wb25lbnQodCl9PSR7ZW5jb2RlVVJJQ29tcG9uZW50KG5bdF0pfWApKS5qb2luKCImIik7dmFyIG59Y29uc3QgcXQ9NjQ7ZnVuY3Rpb24gRnQodCxlLG49cSh0LmJ1ZmZlclNpemV8fHF0KSl7bGV0IHI9e307cmV0dXJue3NlbmQ6ZnVuY3Rpb24obyl7Y29uc3Qgcz1bXTtpZihYKG8sKChlLG4pPT57Y29uc3Qgbz1ydChuKTtpZihmdW5jdGlvbih0LGUsbj1EYXRlLm5vdygpKXtyZXR1cm4gZnVuY3Rpb24odCxlKXtyZXR1cm4gdFtlXXx8dC5hbGx8fDB9KHQsZSk+bn0ocixvKSl7Y29uc3Qgcj1LdChlLG4pO3QucmVjb3JkRHJvcHBlZEV2ZW50KCJyYXRlbGltaXRfYmFja29mZiIsbyxyKX1lbHNlIHMucHVzaChlKX0pKSwwPT09cy5sZW5ndGgpcmV0dXJuIFcoe30pO2NvbnN0IGk9UShvWzBdLHMpLGM9ZT0+e1goaSwoKG4scik9Pntjb25zdCBvPUt0KG4scik7dC5yZWNvcmREcm9wcGVkRXZlbnQoZSxydChyKSxvKX0pKX07cmV0dXJuIG4uYWRkKCgoKT0+ZSh7Ym9keTpldChpKX0pLnRoZW4oKHQ9Pih2b2lkIDAhPT10LnN0YXR1c0NvZGUmJih0LnN0YXR1c0NvZGU8MjAwfHx0LnN0YXR1c0NvZGU+PTMwMCkmJmN0JiZOLndhcm4oYFNlbnRyeSByZXNwb25kZWQgd2l0aCBzdGF0dXMgY29kZSAke3Quc3RhdHVzQ29kZX0gdG8gc2VudCBldmVudC5gKSxyPWl0KHIsdCksdCkpLCh0PT57dGhyb3cgYygibmV0d29ya19lcnJvciIpLHR9KSkpKS50aGVuKCh0PT50KSwodD0+e2lmKHQgaW5zdGFuY2VvZiBDKXJldHVybiBjdCYmTi5lcnJvcigiU2tpcHBlZCBzZW5kaW5nIGV2ZW50IGJlY2F1c2UgYnVmZmVyIGlzIGZ1bGwuIiksYygicXVldWVfb3ZlcmZsb3ciKSxXKHt9KTt0aHJvdyB0fSkpfSxmbHVzaDp0PT5uLmRyYWluKHQpfX1mdW5jdGlvbiBLdCh0LGUpe2lmKCJldmVudCI9PT1lfHwidHJhbnNhY3Rpb24iPT09ZSlyZXR1cm4gQXJyYXkuaXNBcnJheSh0KT90WzFdOnZvaWQgMH1jb25zdCBWdD1TeW1ib2woIkFnZW50QmFzZUludGVybmFsU3RhdGUiKTtjbGFzcyBadCBleHRlbmRzIGguQWdlbnR7W1Z0XTtvcHRpb25zO2tlZXBBbGl2ZTtjb25zdHJ1Y3Rvcih0KXtzdXBlcih0KSx0aGlzW1Z0XT17fX1pc1NlY3VyZUVuZHBvaW50KHQpe2lmKHQpe2lmKCJib29sZWFuIj09dHlwZW9mIHQuc2VjdXJlRW5kcG9pbnQpcmV0dXJuIHQuc2VjdXJlRW5kcG9pbnQ7aWYoInN0cmluZyI9PXR5cGVvZiB0LnByb3RvY29sKXJldHVybiJodHRwczoiPT09dC5wcm90b2NvbH1jb25zdHtzdGFjazplfT1uZXcgRXJyb3I7cmV0dXJuInN0cmluZyI9PXR5cGVvZiBlJiZlLnNwbGl0KCJcbiIpLnNvbWUoKHQ9Pi0xIT09dC5pbmRleE9mKCIoaHR0cHMuanM6Iil8fC0xIT09dC5pbmRleE9mKCJub2RlOmh0dHBzOiIpKSl9Y3JlYXRlU29ja2V0KHQsZSxuKXtjb25zdCByPXsuLi5lLHNlY3VyZUVuZHBvaW50OnRoaXMuaXNTZWN1cmVFbmRwb2ludChlKX07UHJvbWlzZS5yZXNvbHZlKCkudGhlbigoKCk9PnRoaXMuY29ubmVjdCh0LHIpKSkudGhlbigobz0+e2lmKG8gaW5zdGFuY2VvZiBoLkFnZW50KXJldHVybiBvLmFkZFJlcXVlc3QodCxyKTt0aGlzW1Z0XS5jdXJyZW50U29ja2V0PW8sc3VwZXIuY3JlYXRlU29ja2V0KHQsZSxuKX0pLG4pfWNyZWF0ZUNvbm5lY3Rpb24oKXtjb25zdCB0PXRoaXNbVnRdLmN1cnJlbnRTb2NrZXQ7aWYodGhpc1tWdF0uY3VycmVudFNvY2tldD12b2lkIDAsIXQpdGhyb3cgbmV3IEVycm9yKCJObyBzb2NrZXQgd2FzIHJldHVybmVkIGluIHRoZSBgY29ubmVjdCgpYCBmdW5jdGlvbiIpO3JldHVybiB0fWdldCBkZWZhdWx0UG9ydCgpe3JldHVybiB0aGlzW1Z0XS5kZWZhdWx0UG9ydD8/KCJodHRwczoiPT09dGhpcy5wcm90b2NvbD80NDM6ODApfXNldCBkZWZhdWx0UG9ydCh0KXt0aGlzW1Z0XSYmKHRoaXNbVnRdLmRlZmF1bHRQb3J0PXQpfWdldCBwcm90b2NvbCgpe3JldHVybiB0aGlzW1Z0XS5wcm90b2NvbD8/KHRoaXMuaXNTZWN1cmVFbmRwb2ludCgpPyJodHRwczoiOiJodHRwOiIpfXNldCBwcm90b2NvbCh0KXt0aGlzW1Z0XSYmKHRoaXNbVnRdLnByb3RvY29sPXQpfX1mdW5jdGlvbiBRdCguLi50KXtOLmxvZygiW2h0dHBzLXByb3h5LWFnZW50OnBhcnNlLXByb3h5LXJlc3BvbnNlXSIsLi4udCl9ZnVuY3Rpb24gWHQodCl7cmV0dXJuIG5ldyBQcm9taXNlKCgoZSxuKT0+e2xldCByPTA7Y29uc3Qgbz1bXTtmdW5jdGlvbiBzKCl7Y29uc3QgYz10LnJlYWQoKTtjP2Z1bmN0aW9uKGMpe28ucHVzaChjKSxyKz1jLmxlbmd0aDtjb25zdCB1PUJ1ZmZlci5jb25jYXQobyxyKSxhPXUuaW5kZXhPZigiXHJcblxyXG4iKTtpZigtMT09PWEpcmV0dXJuIFF0KCJoYXZlIG5vdCByZWNlaXZlZCBlbmQgb2YgSFRUUCBoZWFkZXJzIHlldC4uLiIpLHZvaWQgcygpO2NvbnN0IGY9dS5zbGljZSgwLGEpLnRvU3RyaW5nKCJhc2NpaSIpLnNwbGl0KCJcclxuIiksaD1mLnNoaWZ0KCk7aWYoIWgpcmV0dXJuIHQuZGVzdHJveSgpLG4obmV3IEVycm9yKCJObyBoZWFkZXIgcmVjZWl2ZWQgZnJvbSBwcm94eSBDT05ORUNUIHJlc3BvbnNlIikpO2NvbnN0IHA9aC5zcGxpdCgiICIpLGw9K3BbMV0sZD1wLnNsaWNlKDIpLmpvaW4oIiAiKSxtPXt9O2Zvcihjb25zdCBlIG9mIGYpe2lmKCFlKWNvbnRpbnVlO2NvbnN0IHI9ZS5pbmRleE9mKCI6Iik7aWYoLTE9PT1yKXJldHVybiB0LmRlc3Ryb3koKSxuKG5ldyBFcnJvcihgSW52YWxpZCBoZWFkZXIgZnJvbSBwcm94eSBDT05ORUNUIHJlc3BvbnNlOiAiJHtlfSJgKSk7Y29uc3Qgbz1lLnNsaWNlKDAscikudG9Mb3dlckNhc2UoKSxzPWUuc2xpY2UocisxKS50cmltU3RhcnQoKSxpPW1bb107InN0cmluZyI9PXR5cGVvZiBpP21bb109W2ksc106QXJyYXkuaXNBcnJheShpKT9pLnB1c2gocyk6bVtvXT1zfVF0KCJnb3QgcHJveHkgc2VydmVyIHJlc3BvbnNlOiAlbyAlbyIsaCxtKSxpKCksZSh7Y29ubmVjdDp7c3RhdHVzQ29kZTpsLHN0YXR1c1RleHQ6ZCxoZWFkZXJzOm19LGJ1ZmZlcmVkOnV9KX0oYyk6dC5vbmNlKCJyZWFkYWJsZSIscyl9ZnVuY3Rpb24gaSgpe3QucmVtb3ZlTGlzdGVuZXIoImVuZCIsYyksdC5yZW1vdmVMaXN0ZW5lcigiZXJyb3IiLHUpLHQucmVtb3ZlTGlzdGVuZXIoInJlYWRhYmxlIixzKX1mdW5jdGlvbiBjKCl7aSgpLFF0KCJvbmVuZCIpLG4obmV3IEVycm9yKCJQcm94eSBjb25uZWN0aW9uIGVuZGVkIGJlZm9yZSByZWNlaXZpbmcgQ09OTkVDVCByZXNwb25zZSIpKX1mdW5jdGlvbiB1KHQpe2koKSxRdCgib25lcnJvciAlbyIsdCksbih0KX10Lm9uKCJlcnJvciIsdSksdC5vbigiZW5kIixjKSxzKCl9KSl9ZnVuY3Rpb24gdGUoLi4udCl7Ti5sb2coIltodHRwcy1wcm94eS1hZ2VudF0iLC4uLnQpfWNsYXNzIGVlIGV4dGVuZHMgWnR7c3RhdGljIHByb3RvY29scz1bImh0dHAiLCJodHRwcyJdO3Byb3h5O3Byb3h5SGVhZGVycztjb25uZWN0T3B0cztjb25zdHJ1Y3Rvcih0LGUpe3N1cGVyKGUpLHRoaXMub3B0aW9ucz17fSx0aGlzLnByb3h5PSJzdHJpbmciPT10eXBlb2YgdD9uZXcgVVJMKHQpOnQsdGhpcy5wcm94eUhlYWRlcnM9ZT8uaGVhZGVycz8/e30sdGUoIkNyZWF0aW5nIG5ldyBIdHRwc1Byb3h5QWdlbnQgaW5zdGFuY2U6ICVvIix0aGlzLnByb3h5LmhyZWYpO2NvbnN0IG49KHRoaXMucHJveHkuaG9zdG5hbWV8fHRoaXMucHJveHkuaG9zdCkucmVwbGFjZSgvXlxbfFxdJC9nLCIiKSxyPXRoaXMucHJveHkucG9ydD9wYXJzZUludCh0aGlzLnByb3h5LnBvcnQsMTApOiJodHRwczoiPT09dGhpcy5wcm94eS5wcm90b2NvbD80NDM6ODA7dGhpcy5jb25uZWN0T3B0cz17QUxQTlByb3RvY29sczpbImh0dHAvMS4xIl0sLi4uZT9yZShlLCJoZWFkZXJzIik6bnVsbCxob3N0Om4scG9ydDpyfX1hc3luYyBjb25uZWN0KHQsZSl7Y29uc3R7cHJveHk6bn09dGhpcztpZighZS5ob3N0KXRocm93IG5ldyBUeXBlRXJyb3IoJ05vICJob3N0IiBwcm92aWRlZCcpO2xldCByO2lmKCJodHRwczoiPT09bi5wcm90b2NvbCl7dGUoIkNyZWF0aW5nIGB0bHMuU29ja2V0YDogJW8iLHRoaXMuY29ubmVjdE9wdHMpO2NvbnN0IHQ9dGhpcy5jb25uZWN0T3B0cy5zZXJ2ZXJuYW1lfHx0aGlzLmNvbm5lY3RPcHRzLmhvc3Q7cj1mLmNvbm5lY3Qoey4uLnRoaXMuY29ubmVjdE9wdHMsc2VydmVybmFtZTp0JiZhLmlzSVAodCk/dm9pZCAwOnR9KX1lbHNlIHRlKCJDcmVhdGluZyBgbmV0LlNvY2tldGA6ICVvIix0aGlzLmNvbm5lY3RPcHRzKSxyPWEuY29ubmVjdCh0aGlzLmNvbm5lY3RPcHRzKTtjb25zdCBvPSJmdW5jdGlvbiI9PXR5cGVvZiB0aGlzLnByb3h5SGVhZGVycz90aGlzLnByb3h5SGVhZGVycygpOnsuLi50aGlzLnByb3h5SGVhZGVyc30scz1hLmlzSVB2NihlLmhvc3QpP2BbJHtlLmhvc3R9XWA6ZS5ob3N0O2xldCBpPWBDT05ORUNUICR7c306JHtlLnBvcnR9IEhUVFAvMS4xXHJcbmA7aWYobi51c2VybmFtZXx8bi5wYXNzd29yZCl7Y29uc3QgdD1gJHtkZWNvZGVVUklDb21wb25lbnQobi51c2VybmFtZSl9OiR7ZGVjb2RlVVJJQ29tcG9uZW50KG4ucGFzc3dvcmQpfWA7b1siUHJveHktQXV0aG9yaXphdGlvbiJdPWBCYXNpYyAke0J1ZmZlci5mcm9tKHQpLnRvU3RyaW5nKCJiYXNlNjQiKX1gfW8uSG9zdD1gJHtzfToke2UucG9ydH1gLG9bIlByb3h5LUNvbm5lY3Rpb24iXXx8KG9bIlByb3h5LUNvbm5lY3Rpb24iXT10aGlzLmtlZXBBbGl2ZT8iS2VlcC1BbGl2ZSI6ImNsb3NlIik7Zm9yKGNvbnN0IHQgb2YgT2JqZWN0LmtleXMobykpaSs9YCR7dH06ICR7b1t0XX1cclxuYDtjb25zdCBjPVh0KHIpO3Iud3JpdGUoYCR7aX1cclxuYCk7Y29uc3R7Y29ubmVjdDp1LGJ1ZmZlcmVkOmh9PWF3YWl0IGM7aWYodC5lbWl0KCJwcm94eUNvbm5lY3QiLHUpLHRoaXMuZW1pdCgicHJveHlDb25uZWN0Iix1LHQpLDIwMD09PXUuc3RhdHVzQ29kZSl7aWYodC5vbmNlKCJzb2NrZXQiLG5lKSxlLnNlY3VyZUVuZHBvaW50KXt0ZSgiVXBncmFkaW5nIHNvY2tldCBjb25uZWN0aW9uIHRvIFRMUyIpO2NvbnN0IHQ9ZS5zZXJ2ZXJuYW1lfHxlLmhvc3Q7cmV0dXJuIGYuY29ubmVjdCh7Li4ucmUoZSwiaG9zdCIsInBhdGgiLCJwb3J0Iiksc29ja2V0OnIsc2VydmVybmFtZTphLmlzSVAodCk/dm9pZCAwOnR9KX1yZXR1cm4gcn1yLmRlc3Ryb3koKTtjb25zdCBwPW5ldyBhLlNvY2tldCh7d3JpdGFibGU6ITF9KTtyZXR1cm4gcC5yZWFkYWJsZT0hMCx0Lm9uY2UoInNvY2tldCIsKHQ9Pnt0ZSgiUmVwbGF5aW5nIHByb3h5IGJ1ZmZlciBmb3IgZmFpbGVkIHJlcXVlc3QiKSx0LnB1c2goaCksdC5wdXNoKG51bGwpfSkpLHB9fWZ1bmN0aW9uIG5lKHQpe3QucmVzdW1lKCl9ZnVuY3Rpb24gcmUodCwuLi5lKXtjb25zdCBuPXt9O2xldCByO2ZvcihyIGluIHQpZS5pbmNsdWRlcyhyKXx8KG5bcl09dFtyXSk7cmV0dXJuIG59Y29uc3Qgb2U9MzI3Njg7ZnVuY3Rpb24gc2UodCl7cmV0dXJuIHQucmVwbGFjZSgvXltBLVpdOi8sIiIpLnJlcGxhY2UoL1xcL2csIi8iKX1jb25zdCBpZT1uO2xldCBjZSx1ZT0hMTtmdW5jdGlvbiBhZSh0KXtpZS5kZWJ1ZyYmY29uc29sZS5sb2coYFtBTlIgV29ya2VyXSAke3R9YCl9dmFyIGZlLGhlLHBlO2NvbnN0IGxlPWZ1bmN0aW9uKHQpe2xldCBlO3RyeXtlPW5ldyBVUkwodC51cmwpfWNhdGNoKGUpe3JldHVybiB4KCgoKT0+e2NvbnNvbGUud2FybigiW0BzZW50cnkvbm9kZV06IEludmFsaWQgZHNuIG9yIHR1bm5lbCBvcHRpb24sIHdpbGwgbm90IHNlbmQgYW55IGV2ZW50cy4gVGhlIHR1bm5lbCBvcHRpb24gbXVzdCBiZSBhIGZ1bGwgVVJMIHdoZW4gdXNlZC4iKX0pKSxGdCh0LCgoKT0+UHJvbWlzZS5yZXNvbHZlKHt9KSkpfWNvbnN0IG49Imh0dHBzOiI9PT1lLnByb3RvY29sLHI9ZnVuY3Rpb24odCxlKXtjb25zdHtub19wcm94eTpufT1wcm9jZXNzLmVudjtyZXR1cm4gbiYmbi5zcGxpdCgiLCIpLnNvbWUoKGU9PnQuaG9zdC5lbmRzV2l0aChlKXx8dC5ob3N0bmFtZS5lbmRzV2l0aChlKSkpP3ZvaWQgMDplfShlLHQucHJveHl8fChuP3Byb2Nlc3MuZW52Lmh0dHBzX3Byb3h5OnZvaWQgMCl8fHByb2Nlc3MuZW52Lmh0dHBfcHJveHkpLG89bj9pOnMsYT12b2lkIDAhPT10LmtlZXBBbGl2ZSYmdC5rZWVwQWxpdmUsZj1yP25ldyBlZShyKTpuZXcgby5BZ2VudCh7a2VlcEFsaXZlOmEsbWF4U29ja2V0czozMCx0aW1lb3V0OjJlM30pO3JldHVybiB6dCgoKCk9Pntjb25zdCBlPWZ1bmN0aW9uKHQsZSxuKXtjb25zdHtob3N0bmFtZTpyLHBhdGhuYW1lOm8scG9ydDpzLHByb3RvY29sOmksc2VhcmNoOmF9PW5ldyBVUkwodC51cmwpO3JldHVybiBmdW5jdGlvbihmKXtyZXR1cm4gbmV3IFByb21pc2UoKChoLHApPT57bGV0IGw9ZnVuY3Rpb24odCl7cmV0dXJuIG5ldyBjKHtyZWFkKCl7dGhpcy5wdXNoKHQpLHRoaXMucHVzaChudWxsKX19KX0oZi5ib2R5KTtjb25zdCBkPXsuLi50LmhlYWRlcnN9O2YuYm9keS5sZW5ndGg+b2UmJihkWyJjb250ZW50LWVuY29kaW5nIl09Imd6aXAiLGw9bC5waXBlKHUoKSkpO2NvbnN0IG09ZS5yZXF1ZXN0KHttZXRob2Q6IlBPU1QiLGFnZW50Om4saGVhZGVyczpkLGhvc3RuYW1lOnIscGF0aDpgJHtvfSR7YX1gLHBvcnQ6cyxwcm90b2NvbDppLGNhOnQuY2FDZXJ0c30sKHQ9Pnt0Lm9uKCJkYXRhIiwoKCk9Pnt9KSksdC5vbigiZW5kIiwoKCk9Pnt9KSksdC5zZXRFbmNvZGluZygidXRmOCIpO2NvbnN0IGU9dC5oZWFkZXJzWyJyZXRyeS1hZnRlciJdPz9udWxsLG49dC5oZWFkZXJzWyJ4LXNlbnRyeS1yYXRlLWxpbWl0cyJdPz9udWxsO2goe3N0YXR1c0NvZGU6dC5zdGF0dXNDb2RlLGhlYWRlcnM6eyJyZXRyeS1hZnRlciI6ZSwieC1zZW50cnktcmF0ZS1saW1pdHMiOkFycmF5LmlzQXJyYXkobik/blswXTpufX0pfSkpO20ub24oImVycm9yIixwKSxsLnBpcGUobSl9KSl9fSh0LHQuaHR0cE1vZHVsZT8/byxmKTtyZXR1cm4gRnQodCxlKX0pKX0oe3VybDooZmU9aWUuZHNuLGhlPWllLnR1bm5lbCxwZT1pZS5zZGtNZXRhZGF0YS5zZGssaGV8fGAke2Z1bmN0aW9uKHQpe3JldHVybmAke2Z1bmN0aW9uKHQpe2NvbnN0IGU9dC5wcm90b2NvbD9gJHt0LnByb3RvY29sfTpgOiIiLG49dC5wb3J0P2A6JHt0LnBvcnR9YDoiIjtyZXR1cm5gJHtlfS8vJHt0Lmhvc3R9JHtufSR7dC5wYXRoP2AvJHt0LnBhdGh9YDoiIn0vYXBpL2B9KHQpfSR7dC5wcm9qZWN0SWR9L2VudmVsb3BlL2B9KGZlKX0/JHtZdChmZSxwZSl9YCkscmVjb3JkRHJvcHBlZEV2ZW50OigpPT57fX0pO2FzeW5jIGZ1bmN0aW9uIGRlKCl7aWYoY2Upe2FlKCJTZW5kaW5nIGFibm9ybWFsIHNlc3Npb24iKSxodChjZSx7c3RhdHVzOiJhYm5vcm1hbCIsYWJub3JtYWxfbWVjaGFuaXNtOiJhbnJfZm9yZWdyb3VuZCJ9KTtjb25zdCB0PWZ1bmN0aW9uKHQsZSxuLHIpe2NvbnN0IG89b3Qobik7cmV0dXJuIFEoe3NlbnRfYXQ6KG5ldyBEYXRlKS50b0lTT1N0cmluZygpLC4uLm8mJntzZGs6b30sLi4uISFyJiZlJiZ7ZHNuOmsoZSl9fSxbImFnZ3JlZ2F0ZXMiaW4gdD9be3R5cGU6InNlc3Npb25zIn0sdF06W3t0eXBlOiJzZXNzaW9uIn0sdC50b0pTT04oKV1dKX0oY2UsaWUuZHNuLGllLnNka01ldGFkYXRhLGllLnR1bm5lbCk7YWUoSlNPTi5zdHJpbmdpZnkodCkpLGF3YWl0IGxlLnNlbmQodCk7dHJ5e2U/LnBvc3RNZXNzYWdlKCJzZXNzaW9uLWVuZGVkIil9Y2F0Y2godCl7fX19ZnVuY3Rpb24gbWUodCl7aWYoIXQpcmV0dXJuO2NvbnN0IGU9ZnVuY3Rpb24odCl7aWYoIXQubGVuZ3RoKXJldHVybltdO2NvbnN0IGU9QXJyYXkuZnJvbSh0KTtyZXR1cm4vc2VudHJ5V3JhcHBlZC8udGVzdChlW2UubGVuZ3RoLTFdLmZ1bmN0aW9ufHwiIikmJmUucG9wKCksZS5yZXZlcnNlKCksUC50ZXN0KGVbZS5sZW5ndGgtMV0uZnVuY3Rpb258fCIiKSYmKGUucG9wKCksUC50ZXN0KGVbZS5sZW5ndGgtMV0uZnVuY3Rpb258fCIiKSYmZS5wb3AoKSksZS5zbGljZSgwLEEpLm1hcCgodD0+KHsuLi50LGZpbGVuYW1lOnQuZmlsZW5hbWV8fGVbZS5sZW5ndGgtMV0uZmlsZW5hbWUsZnVuY3Rpb246dC5mdW5jdGlvbnx8SX0pKSl9KHQpO2lmKGllLmFwcFJvb3RQYXRoKWZvcihjb25zdCB0IG9mIGUpdC5maWxlbmFtZSYmKHQuZmlsZW5hbWU9Ryh0LmZpbGVuYW1lLGllLmFwcFJvb3RQYXRoKSk7cmV0dXJuIGV9YXN5bmMgZnVuY3Rpb24gZ2UodCxlKXtpZih1ZSlyZXR1cm47dWU9ITAsYXdhaXQgZGUoKSxhZSgiU2VuZGluZyBldmVudCIpO2NvbnN0IG49e2V2ZW50X2lkOk0oKSxjb250ZXh0czppZS5jb250ZXh0cyxyZWxlYXNlOmllLnJlbGVhc2UsZW52aXJvbm1lbnQ6aWUuZW52aXJvbm1lbnQsZGlzdDppZS5kaXN0LHBsYXRmb3JtOiJub2RlIixsZXZlbDoiZXJyb3IiLGV4Y2VwdGlvbjp7dmFsdWVzOlt7dHlwZToiQXBwbGljYXRpb25Ob3RSZXNwb25kaW5nIix2YWx1ZTpgQXBwbGljYXRpb24gTm90IFJlc3BvbmRpbmcgZm9yIGF0IGxlYXN0ICR7aWUuYW5yVGhyZXNob2xkfSBtc2Asc3RhY2t0cmFjZTp7ZnJhbWVzOm1lKHQpfSxtZWNoYW5pc206e3R5cGU6IkFOUiJ9fV19LHRhZ3M6aWUuc3RhdGljVGFnc307ZSYmZnVuY3Rpb24odCxlKXtpZihIdCh0LGUpLCF0LmNvbnRleHRzPy50cmFjZSl7Y29uc3R7dHJhY2VJZDpuLHNwYW5JZDpyLHBhcmVudFNwYW5JZDpvfT1lLnByb3BhZ2F0aW9uQ29udGV4dDt0LmNvbnRleHRzPXt0cmFjZTp7dHJhY2VfaWQ6bixzcGFuX2lkOnIscGFyZW50X3NwYW5faWQ6b30sLi4udC5jb250ZXh0c319fShuLGUpO2NvbnN0IHI9R3QobixpZS5kc24saWUuc2RrTWV0YWRhdGEsaWUudHVubmVsKTthZShKU09OLnN0cmluZ2lmeShyKSksYXdhaXQgbGUuc2VuZChyKSxhd2FpdCBsZS5mbHVzaCgyZTMpLHNldFRpbWVvdXQoKCgpPT57cHJvY2Vzcy5leGl0KDApfSksNWUzKX1sZXQgeWU7aWYoYWUoIlN0YXJ0ZWQiKSxpZS5jYXB0dXJlU3RhY2tUcmFjZSl7YWUoIkNvbm5lY3RpbmcgdG8gZGVidWdnZXIiKTtjb25zdCBlPW5ldyB0O2UuY29ubmVjdFRvTWFpblRocmVhZCgpLGFlKCJDb25uZWN0ZWQgdG8gZGVidWdnZXIiKTtjb25zdCBuPW5ldyBNYXA7ZS5vbigiRGVidWdnZXIuc2NyaXB0UGFyc2VkIiwodD0+e24uc2V0KHQucGFyYW1zLnNjcmlwdElkLHQucGFyYW1zLnVybCl9KSksZS5vbigiRGVidWdnZXIucGF1c2VkIiwodD0+e2lmKCJvdGhlciI9PT10LnBhcmFtcy5yZWFzb24pdHJ5e2FlKCJEZWJ1Z2dlciBwYXVzZWQiKTtjb25zdCBzPVsuLi50LnBhcmFtcy5jYWxsRnJhbWVzXSxpPWllLmFwcFJvb3RQYXRoP2Z1bmN0aW9uKHQ9KHByb2Nlc3MuYXJndlsxXT96KHByb2Nlc3MuYXJndlsxXSk6cHJvY2Vzcy5jd2QoKSksZT0iXFwiPT09byl7Y29uc3Qgbj1lP3NlKHQpOnQ7cmV0dXJuIHQ9PntpZighdClyZXR1cm47Y29uc3Qgbz1lP3NlKHQpOnQ7bGV0e2RpcjpzLGJhc2U6aSxleHQ6Y309ci5wYXJzZShvKTsiLmpzIiE9PWMmJiIubWpzIiE9PWMmJiIuY2pzIiE9PWN8fChpPWkuc2xpY2UoMCwtMSpjLmxlbmd0aCkpLHN8fChzPSIuIik7Y29uc3QgdT1zLmxhc3RJbmRleE9mKCIvbm9kZV9tb2R1bGVzIik7aWYodT4tMSlyZXR1cm5gJHtzLnNsaWNlKHUrMTQpLnJlcGxhY2UoL1wvL2csIi4iKX06JHtpfWA7aWYocy5zdGFydHNXaXRoKG4pKXtsZXQgdD1zLnNsaWNlKG4ubGVuZ3RoKzEpLnJlcGxhY2UoL1wvL2csIi4iKTtyZXR1cm4gdCYmKHQrPSI6IiksdCs9aSx0fXJldHVybiBpfX0oaWUuYXBwUm9vdFBhdGgpOigpPT57fSxjPXMubWFwKCh0PT5mdW5jdGlvbih0LGUsbil7Y29uc3Qgcj1lP2UucmVwbGFjZSgvXmZpbGU6XC9cLy8sIiIpOnZvaWQgMCxvPXQubG9jYXRpb24uY29sdW1uTnVtYmVyP3QubG9jYXRpb24uY29sdW1uTnVtYmVyKzE6dm9pZCAwLHM9dC5sb2NhdGlvbi5saW5lTnVtYmVyP3QubG9jYXRpb24ubGluZU51bWJlcisxOnZvaWQgMDtyZXR1cm4gaih7ZmlsZW5hbWU6cixtb2R1bGU6bihyKSxmdW5jdGlvbjp0LmZ1bmN0aW9uTmFtZXx8SSxjb2xubzpvLGxpbmVubzpzLGluX2FwcDpyP0Yocik6dm9pZCAwfSl9KHQsbi5nZXQodC5sb2NhdGlvbi5zY3JpcHRJZCksaSkpKSx1PXNldFRpbWVvdXQoKCgpPT57Z2UoYykudGhlbihudWxsLCgoKT0+e2FlKCJTZW5kaW5nIEFOUiBldmVudCBmYWlsZWQuIil9KSl9KSw1ZTMpO2UucG9zdCgiUnVudGltZS5ldmFsdWF0ZSIse2V4cHJlc3Npb246Imdsb2JhbC5fX1NFTlRSWV9HRVRfU0NPUEVTX18oKTsiLHNpbGVudDohMCxyZXR1cm5CeVZhbHVlOiEwfSwoKHQsbik9Pnt0JiZhZShgRXJyb3IgZXhlY3V0aW5nIHNjcmlwdDogJyR7dC5tZXNzYWdlfSdgKSxjbGVhclRpbWVvdXQodSk7Y29uc3Qgcj1uJiZuLnJlc3VsdD9uLnJlc3VsdC52YWx1ZTp2b2lkIDA7ZS5wb3N0KCJEZWJ1Z2dlci5yZXN1bWUiKSxlLnBvc3QoIkRlYnVnZ2VyLmRpc2FibGUiKSxnZShjLHIpLnRoZW4obnVsbCwoKCk9PnthZSgiU2VuZGluZyBBTlIgZXZlbnQgZmFpbGVkLiIpfSkpfSkpfWNhdGNoKHQpe3Rocm93IGUucG9zdCgiRGVidWdnZXIucmVzdW1lIiksZS5wb3N0KCJEZWJ1Z2dlci5kaXNhYmxlIiksdH19KSkseWU9KCk9Pnt0cnl7ZS5wb3N0KCJEZWJ1Z2dlci5lbmFibGUiLCgoKT0+e2UucG9zdCgiRGVidWdnZXIucGF1c2UiKX0pKX1jYXRjaCh0KXt9fX1jb25zdHtwb2xsOmJlfT1mdW5jdGlvbih0LGUsbixyKXtjb25zdCBvPXQoKTtsZXQgcz0hMSxpPSEwO3JldHVybiBzZXRJbnRlcnZhbCgoKCk9Pntjb25zdCB0PW8uZ2V0VGltZU1zKCk7ITE9PT1zJiZ0PmUrbiYmKHM9ITAsaSYmcigpKSx0PGUrbiYmKHM9ITEpfSksMjApLHtwb2xsOigpPT57by5yZXNldCgpfSxlbmFibGVkOnQ9PntpPXR9fX0oKGZ1bmN0aW9uKCl7bGV0IHQ9cHJvY2Vzcy5ocnRpbWUoKTtyZXR1cm57Z2V0VGltZU1zOigpPT57Y29uc3RbZSxuXT1wcm9jZXNzLmhydGltZSh0KTtyZXR1cm4gTWF0aC5mbG9vcigxZTMqZStuLzFlNil9LHJlc2V0OigpPT57dD1wcm9jZXNzLmhydGltZSgpfX19KSxpZS5wb2xsSW50ZXJ2YWwsaWUuYW5yVGhyZXNob2xkLChmdW5jdGlvbigpe2FlKCJXYXRjaGRvZyB0aW1lb3V0IikseWU/KGFlKCJQYXVzaW5nIGRlYnVnZ2VyIHRvIGNhcHR1cmUgc3RhY2sgdHJhY2UiKSx5ZSgpKTooYWUoIkNhcHR1cmluZyBldmVudCB3aXRob3V0IGEgc3RhY2sgdHJhY2UiKSxnZSgpLnRoZW4obnVsbCwoKCk9PnthZSgiU2VuZGluZyBBTlIgZXZlbnQgZmFpbGVkIG9uIHdhdGNoZG9nIHRpbWVvdXQuIil9KSkpfSkpO2U/Lm9uKCJtZXNzYWdlIiwodD0+e3Quc2Vzc2lvbiYmKGNlPWZ0KHQuc2Vzc2lvbikpLGJlKCl9KSk7';
|
|
1794
|
+
const base64WorkerScript = 'LyohIEBzZW50cnkvbm9kZSA4LjAuMC1yYy4yICg3YTNlMTZjKSB8IGh0dHBzOi8vZ2l0aHViLmNvbS9nZXRzZW50cnkvc2VudHJ5LWphdmFzY3JpcHQgKi8KaW1wb3J0e1Nlc3Npb24gYXMgdH1mcm9tImluc3BlY3RvciI7aW1wb3J0e3BhcmVudFBvcnQgYXMgZSx3b3JrZXJEYXRhIGFzIG59ZnJvbSJ3b3JrZXJfdGhyZWFkcyI7aW1wb3J0e3Bvc2l4IGFzIHIsc2VwIGFzIG99ZnJvbSJwYXRoIjtpbXBvcnQqYXMgcyBmcm9tIm5vZGU6aHR0cCI7aW1wb3J0KmFzIGkgZnJvbSJub2RlOmh0dHBzIjtpbXBvcnR7UmVhZGFibGUgYXMgY31mcm9tInN0cmVhbSI7aW1wb3J0e2NyZWF0ZUd6aXAgYXMgdX1mcm9tInpsaWIiO2ltcG9ydCphcyBhIGZyb20ibmV0IjtpbXBvcnQqYXMgZiBmcm9tInRscyI7aW1wb3J0KmFzIGggZnJvbSJodHRwIjtjb25zdCBwPU9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7ZnVuY3Rpb24gbCh0LGUpe3JldHVybiBwLmNhbGwodCk9PT1gW29iamVjdCAke2V9XWB9ZnVuY3Rpb24gZCh0KXtyZXR1cm4gbCh0LCJPYmplY3QiKX1mdW5jdGlvbiBtKHQpe3JldHVybiBCb29sZWFuKHQmJnQudGhlbiYmImZ1bmN0aW9uIj09dHlwZW9mIHQudGhlbil9ZnVuY3Rpb24gZyh0LGUpe3RyeXtyZXR1cm4gdCBpbnN0YW5jZW9mIGV9Y2F0Y2godCl7cmV0dXJuITF9fWNvbnN0IHk9Z2xvYmFsVGhpcztmdW5jdGlvbiBiKHQsZSxuKXtjb25zdCByPW58fHksbz1yLl9fU0VOVFJZX189ci5fX1NFTlRSWV9ffHx7fTtyZXR1cm4gb1t0XXx8KG9bdF09ZSgpKX1jb25zdCB2PXksXz04MDtmdW5jdGlvbiB3KHQsZSl7Y29uc3Qgbj10LHI9W107bGV0IG8scyxpLGMsdTtpZighbnx8IW4udGFnTmFtZSlyZXR1cm4iIjtpZih2LkhUTUxFbGVtZW50JiZuIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQmJm4uZGF0YXNldCl7aWYobi5kYXRhc2V0LnNlbnRyeUNvbXBvbmVudClyZXR1cm4gbi5kYXRhc2V0LnNlbnRyeUNvbXBvbmVudDtpZihuLmRhdGFzZXQuc2VudHJ5RWxlbWVudClyZXR1cm4gbi5kYXRhc2V0LnNlbnRyeUVsZW1lbnR9ci5wdXNoKG4udGFnTmFtZS50b0xvd2VyQ2FzZSgpKTtjb25zdCBhPWUmJmUubGVuZ3RoP2UuZmlsdGVyKCh0PT5uLmdldEF0dHJpYnV0ZSh0KSkpLm1hcCgodD0+W3Qsbi5nZXRBdHRyaWJ1dGUodCldKSk6bnVsbDtpZihhJiZhLmxlbmd0aClhLmZvckVhY2goKHQ9PntyLnB1c2goYFske3RbMF19PSIke3RbMV19Il1gKX0pKTtlbHNlIGlmKG4uaWQmJnIucHVzaChgIyR7bi5pZH1gKSxvPW4uY2xhc3NOYW1lLG8mJmwobywiU3RyaW5nIikpZm9yKHM9by5zcGxpdCgvXHMrLyksdT0wO3U8cy5sZW5ndGg7dSsrKXIucHVzaChgLiR7c1t1XX1gKTtjb25zdCBmPVsiYXJpYS1sYWJlbCIsInR5cGUiLCJuYW1lIiwidGl0bGUiLCJhbHQiXTtmb3IodT0wO3U8Zi5sZW5ndGg7dSsrKWk9Zlt1XSxjPW4uZ2V0QXR0cmlidXRlKGkpLGMmJnIucHVzaChgWyR7aX09IiR7Y30iXWApO3JldHVybiByLmpvaW4oIiIpfWNvbnN0IFM9InVuZGVmaW5lZCI9PXR5cGVvZiBfX1NFTlRSWV9ERUJVR19ffHxfX1NFTlRSWV9ERUJVR19fLCQ9WyJkZWJ1ZyIsImluZm8iLCJ3YXJuIiwiZXJyb3IiLCJsb2ciLCJhc3NlcnQiLCJ0cmFjZSJdLEU9e307ZnVuY3Rpb24geCh0KXtpZighKCJjb25zb2xlImluIHkpKXJldHVybiB0KCk7Y29uc3QgZT15LmNvbnNvbGUsbj17fSxyPU9iamVjdC5rZXlzKEUpO3IuZm9yRWFjaCgodD0+e2NvbnN0IHI9RVt0XTtuW3RdPWVbdF0sZVt0XT1yfSkpO3RyeXtyZXR1cm4gdCgpfWZpbmFsbHl7ci5mb3JFYWNoKCh0PT57ZVt0XT1uW3RdfSkpfX1jb25zdCBOPWZ1bmN0aW9uKCl7bGV0IHQ9ITE7Y29uc3QgZT17ZW5hYmxlOigpPT57dD0hMH0sZGlzYWJsZTooKT0+e3Q9ITF9LGlzRW5hYmxlZDooKT0+dH07cmV0dXJuIFM/JC5mb3JFYWNoKChuPT57ZVtuXT0oLi4uZSk9Pnt0JiZ4KCgoKT0+e3kuY29uc29sZVtuXShgU2VudHJ5IExvZ2dlciBbJHtufV06YCwuLi5lKX0pKX19KSk6JC5mb3JFYWNoKCh0PT57ZVt0XT0oKT0+e319KSksZX0oKTtmdW5jdGlvbiBrKHQsZT0hMSl7Y29uc3R7aG9zdDpuLHBhdGg6cixwYXNzOm8scG9ydDpzLHByb2plY3RJZDppLHByb3RvY29sOmMscHVibGljS2V5OnV9PXQ7cmV0dXJuYCR7Y306Ly8ke3V9JHtlJiZvP2A6JHtvfWA6IiJ9QCR7bn0ke3M/YDoke3N9YDoiIn0vJHtyP2Ake3J9L2A6cn0ke2l9YH1jbGFzcyBDIGV4dGVuZHMgRXJyb3J7Y29uc3RydWN0b3IodCxlPSJ3YXJuIil7c3VwZXIodCksdGhpcy5tZXNzYWdlPXQsdGhpcy5uYW1lPW5ldy50YXJnZXQucHJvdG90eXBlLmNvbnN0cnVjdG9yLm5hbWUsT2JqZWN0LnNldFByb3RvdHlwZU9mKHRoaXMsbmV3LnRhcmdldC5wcm90b3R5cGUpLHRoaXMubG9nTGV2ZWw9ZX19ZnVuY3Rpb24gRCh0KXtpZihmdW5jdGlvbih0KXtzd2l0Y2gocC5jYWxsKHQpKXtjYXNlIltvYmplY3QgRXJyb3JdIjpjYXNlIltvYmplY3QgRXhjZXB0aW9uXSI6Y2FzZSJbb2JqZWN0IERPTUV4Y2VwdGlvbl0iOnJldHVybiEwO2RlZmF1bHQ6cmV0dXJuIGcodCxFcnJvcil9fSh0KSlyZXR1cm57bWVzc2FnZTp0Lm1lc3NhZ2UsbmFtZTp0Lm5hbWUsc3RhY2s6dC5zdGFjaywuLi5PKHQpfTtpZihlPXQsInVuZGVmaW5lZCIhPXR5cGVvZiBFdmVudCYmZyhlLEV2ZW50KSl7Y29uc3QgZT17dHlwZTp0LnR5cGUsdGFyZ2V0OlQodC50YXJnZXQpLGN1cnJlbnRUYXJnZXQ6VCh0LmN1cnJlbnRUYXJnZXQpLC4uLk8odCl9O3JldHVybiJ1bmRlZmluZWQiIT10eXBlb2YgQ3VzdG9tRXZlbnQmJmcodCxDdXN0b21FdmVudCkmJihlLmRldGFpbD10LmRldGFpbCksZX1yZXR1cm4gdDt2YXIgZX1mdW5jdGlvbiBUKHQpe3RyeXtyZXR1cm4gZT10LCJ1bmRlZmluZWQiIT10eXBlb2YgRWxlbWVudCYmZyhlLEVsZW1lbnQpP2Z1bmN0aW9uKHQsZT17fSl7aWYoIXQpcmV0dXJuIjx1bmtub3duPiI7dHJ5e2xldCBuPXQ7Y29uc3Qgcj01LG89W107bGV0IHM9MCxpPTA7Y29uc3QgYz0iID4gIix1PWMubGVuZ3RoO2xldCBhO2NvbnN0IGY9QXJyYXkuaXNBcnJheShlKT9lOmUua2V5QXR0cnMsaD0hQXJyYXkuaXNBcnJheShlKSYmZS5tYXhTdHJpbmdMZW5ndGh8fF87Zm9yKDtuJiZzKys8ciYmKGE9dyhuLGYpLCEoImh0bWwiPT09YXx8cz4xJiZpK28ubGVuZ3RoKnUrYS5sZW5ndGg+PWgpKTspby5wdXNoKGEpLGkrPWEubGVuZ3RoLG49bi5wYXJlbnROb2RlO3JldHVybiBvLnJldmVyc2UoKS5qb2luKGMpfWNhdGNoKHQpe3JldHVybiI8dW5rbm93bj4ifX0odCk6T2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHQpfWNhdGNoKHQpe3JldHVybiI8dW5rbm93bj4ifXZhciBlfWZ1bmN0aW9uIE8odCl7aWYoIm9iamVjdCI9PXR5cGVvZiB0JiZudWxsIT09dCl7Y29uc3QgZT17fTtmb3IoY29uc3QgbiBpbiB0KU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0LG4pJiYoZVtuXT10W25dKTtyZXR1cm4gZX1yZXR1cm57fX1mdW5jdGlvbiBqKHQpe3JldHVybiBSKHQsbmV3IE1hcCl9ZnVuY3Rpb24gUih0LGUpe2lmKGZ1bmN0aW9uKHQpe2lmKCFkKHQpKXJldHVybiExO3RyeXtjb25zdCBlPU9iamVjdC5nZXRQcm90b3R5cGVPZih0KS5jb25zdHJ1Y3Rvci5uYW1lO3JldHVybiFlfHwiT2JqZWN0Ij09PWV9Y2F0Y2godCl7cmV0dXJuITB9fSh0KSl7Y29uc3Qgbj1lLmdldCh0KTtpZih2b2lkIDAhPT1uKXJldHVybiBuO2NvbnN0IHI9e307ZS5zZXQodCxyKTtmb3IoY29uc3QgbiBvZiBPYmplY3Qua2V5cyh0KSl2b2lkIDAhPT10W25dJiYocltuXT1SKHRbbl0sZSkpO3JldHVybiByfWlmKEFycmF5LmlzQXJyYXkodCkpe2NvbnN0IG49ZS5nZXQodCk7aWYodm9pZCAwIT09bilyZXR1cm4gbjtjb25zdCByPVtdO3JldHVybiBlLnNldCh0LHIpLHQuZm9yRWFjaCgodD0+e3IucHVzaChSKHQsZSkpfSkpLHJ9cmV0dXJuIHR9Y29uc3QgQT01MCxJPSI/IixQPS9jYXB0dXJlTWVzc2FnZXxjYXB0dXJlRXhjZXB0aW9uLztjb25zdCBVPSI8YW5vbnltb3VzPiI7ZnVuY3Rpb24gTSgpe2NvbnN0IHQ9eSxlPXQuY3J5cHRvfHx0Lm1zQ3J5cHRvO2xldCBuPSgpPT4xNipNYXRoLnJhbmRvbSgpO3RyeXtpZihlJiZlLnJhbmRvbVVVSUQpcmV0dXJuIGUucmFuZG9tVVVJRCgpLnJlcGxhY2UoLy0vZywiIik7ZSYmZS5nZXRSYW5kb21WYWx1ZXMmJihuPSgpPT57Y29uc3QgdD1uZXcgVWludDhBcnJheSgxKTtyZXR1cm4gZS5nZXRSYW5kb21WYWx1ZXModCksdFswXX0pfWNhdGNoKHQpe31yZXR1cm4oWzFlN10rMWUzKzRlMys4ZTMrMWUxMSkucmVwbGFjZSgvWzAxOF0vZywodD0+KHReKDE1Jm4oKSk+PnQvNCkudG9TdHJpbmcoMTYpKSl9ZnVuY3Rpb24gTCh0LGU9MTAwLG49MS8wKXt0cnl7cmV0dXJuIEIoIiIsdCxlLG4pfWNhdGNoKHQpe3JldHVybntFUlJPUjpgKipub24tc2VyaWFsaXphYmxlKiogKCR7dH0pYH19fWZ1bmN0aW9uIEIodCxlLG49MS8wLHI9MS8wLG89ZnVuY3Rpb24oKXtjb25zdCB0PSJmdW5jdGlvbiI9PXR5cGVvZiBXZWFrU2V0LGU9dD9uZXcgV2Vha1NldDpbXTtyZXR1cm5bZnVuY3Rpb24obil7aWYodClyZXR1cm4hIWUuaGFzKG4pfHwoZS5hZGQobiksITEpO2ZvcihsZXQgdD0wO3Q8ZS5sZW5ndGg7dCsrKWlmKGVbdF09PT1uKXJldHVybiEwO3JldHVybiBlLnB1c2gobiksITF9LGZ1bmN0aW9uKG4pe2lmKHQpZS5kZWxldGUobik7ZWxzZSBmb3IobGV0IHQ9MDt0PGUubGVuZ3RoO3QrKylpZihlW3RdPT09bil7ZS5zcGxpY2UodCwxKTticmVha319XX0oKSl7Y29uc3RbcyxpXT1vO2lmKG51bGw9PWV8fFsibnVtYmVyIiwiYm9vbGVhbiIsInN0cmluZyJdLmluY2x1ZGVzKHR5cGVvZiBlKSYmIU51bWJlci5pc05hTihlKSlyZXR1cm4gZTtjb25zdCBjPWZ1bmN0aW9uKHQsZSl7dHJ5e2lmKCJkb21haW4iPT09dCYmZSYmIm9iamVjdCI9PXR5cGVvZiBlJiZlLnQpcmV0dXJuIltEb21haW5dIjtpZigiZG9tYWluRW1pdHRlciI9PT10KXJldHVybiJbRG9tYWluRW1pdHRlcl0iO2lmKCJ1bmRlZmluZWQiIT10eXBlb2YgZ2xvYmFsJiZlPT09Z2xvYmFsKXJldHVybiJbR2xvYmFsXSI7aWYoInVuZGVmaW5lZCIhPXR5cGVvZiB3aW5kb3cmJmU9PT13aW5kb3cpcmV0dXJuIltXaW5kb3ddIjtpZigidW5kZWZpbmVkIiE9dHlwZW9mIGRvY3VtZW50JiZlPT09ZG9jdW1lbnQpcmV0dXJuIltEb2N1bWVudF0iO2lmKCJvYmplY3QiPT10eXBlb2Yobj1lKSYmbnVsbCE9PW4mJihuLl9faXNWdWV8fG4ubykpcmV0dXJuIltWdWVWaWV3TW9kZWxdIjtpZihmdW5jdGlvbih0KXtyZXR1cm4gZCh0KSYmIm5hdGl2ZUV2ZW50ImluIHQmJiJwcmV2ZW50RGVmYXVsdCJpbiB0JiYic3RvcFByb3BhZ2F0aW9uImluIHR9KGUpKXJldHVybiJbU3ludGhldGljRXZlbnRdIjtpZigibnVtYmVyIj09dHlwZW9mIGUmJmUhPWUpcmV0dXJuIltOYU5dIjtpZigiZnVuY3Rpb24iPT10eXBlb2YgZSlyZXR1cm5gW0Z1bmN0aW9uOiAke2Z1bmN0aW9uKHQpe3RyeXtyZXR1cm4gdCYmImZ1bmN0aW9uIj09dHlwZW9mIHQmJnQubmFtZXx8VX1jYXRjaCh0KXtyZXR1cm4gVX19KGUpfV1gO2lmKCJzeW1ib2wiPT10eXBlb2YgZSlyZXR1cm5gWyR7U3RyaW5nKGUpfV1gO2lmKCJiaWdpbnQiPT10eXBlb2YgZSlyZXR1cm5gW0JpZ0ludDogJHtTdHJpbmcoZSl9XWA7Y29uc3Qgcj1mdW5jdGlvbih0KXtjb25zdCBlPU9iamVjdC5nZXRQcm90b3R5cGVPZih0KTtyZXR1cm4gZT9lLmNvbnN0cnVjdG9yLm5hbWU6Im51bGwgcHJvdG90eXBlIn0oZSk7cmV0dXJuL15IVE1MKFx3KilFbGVtZW50JC8udGVzdChyKT9gW0hUTUxFbGVtZW50OiAke3J9XWA6YFtvYmplY3QgJHtyfV1gfWNhdGNoKHQpe3JldHVybmAqKm5vbi1zZXJpYWxpemFibGUqKiAoJHt0fSlgfXZhciBufSh0LGUpO2lmKCFjLnN0YXJ0c1dpdGgoIltvYmplY3QgIikpcmV0dXJuIGM7aWYoZS5fX3NlbnRyeV9za2lwX25vcm1hbGl6YXRpb25fXylyZXR1cm4gZTtjb25zdCB1PSJudW1iZXIiPT10eXBlb2YgZS5fX3NlbnRyeV9vdmVycmlkZV9ub3JtYWxpemF0aW9uX2RlcHRoX18/ZS5fX3NlbnRyeV9vdmVycmlkZV9ub3JtYWxpemF0aW9uX2RlcHRoX186bjtpZigwPT09dSlyZXR1cm4gYy5yZXBsYWNlKCJvYmplY3QgIiwiIik7aWYocyhlKSlyZXR1cm4iW0NpcmN1bGFyIH5dIjtjb25zdCBhPWU7aWYoYSYmImZ1bmN0aW9uIj09dHlwZW9mIGEudG9KU09OKXRyeXtyZXR1cm4gQigiIixhLnRvSlNPTigpLHUtMSxyLG8pfWNhdGNoKHQpe31jb25zdCBmPUFycmF5LmlzQXJyYXkoZSk/W106e307bGV0IGg9MDtjb25zdCBwPUQoZSk7Zm9yKGNvbnN0IHQgaW4gcCl7aWYoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChwLHQpKWNvbnRpbnVlO2lmKGg+PXIpe2ZbdF09IltNYXhQcm9wZXJ0aWVzIH5dIjticmVha31jb25zdCBlPXBbdF07Zlt0XT1CKHQsZSx1LTEscixvKSxoKyt9cmV0dXJuIGkoZSksZn1mdW5jdGlvbiBHKHQsZSl7Y29uc3Qgbj1lLnJlcGxhY2UoL1xcL2csIi8iKS5yZXBsYWNlKC9bfFxce30oKVtcXV4kKyo/Ll0vZywiXFwkJiIpO2xldCByPXQ7dHJ5e3I9ZGVjb2RlVVJJKHQpfWNhdGNoKHQpe31yZXR1cm4gci5yZXBsYWNlKC9cXC9nLCIvIikucmVwbGFjZSgvd2VicGFjazpcLz8vZywiIikucmVwbGFjZShuZXcgUmVnRXhwKGAoZmlsZTovLyk/Lyoke259LypgLCJpZyIpLCJhcHA6Ly8vIil9Y29uc3QgSj0vXihcUys6XFx8XC8/KShbXHNcU10qPykoKD86XC57MSwyfXxbXi9cXF0rP3wpKFwuW14uL1xcXSp8KSkoPzpbL1xcXSopJC87ZnVuY3Rpb24geih0KXtjb25zdCBlPWZ1bmN0aW9uKHQpe2NvbnN0IGU9dC5sZW5ndGg+MTAyND9gPHRydW5jYXRlZD4ke3Quc2xpY2UoLTEwMjQpfWA6dCxuPUouZXhlYyhlKTtyZXR1cm4gbj9uLnNsaWNlKDEpOltdfSh0KSxuPWVbMF07bGV0IHI9ZVsxXTtyZXR1cm4gbnx8cj8ociYmKHI9ci5zbGljZSgwLHIubGVuZ3RoLTEpKSxuK3IpOiIuIn12YXIgSDtmdW5jdGlvbiBXKHQpe3JldHVybiBuZXcgWSgoZT0+e2UodCl9KSl9IWZ1bmN0aW9uKHQpe3RbdC5QRU5ESU5HPTBdPSJQRU5ESU5HIjt0W3QuUkVTT0xWRUQ9MV09IlJFU09MVkVEIjt0W3QuUkVKRUNURUQ9Ml09IlJFSkVDVEVEIn0oSHx8KEg9e30pKTtjbGFzcyBZe2NvbnN0cnVjdG9yKHQpe1kucHJvdG90eXBlLl9faW5pdC5jYWxsKHRoaXMpLFkucHJvdG90eXBlLl9faW5pdDIuY2FsbCh0aGlzKSxZLnByb3RvdHlwZS5fX2luaXQzLmNhbGwodGhpcyksWS5wcm90b3R5cGUuX19pbml0NC5jYWxsKHRoaXMpLHRoaXMuaT1ILlBFTkRJTkcsdGhpcy51PVtdO3RyeXt0KHRoaXMuaCx0aGlzLnApfWNhdGNoKHQpe3RoaXMucCh0KX19dGhlbih0LGUpe3JldHVybiBuZXcgWSgoKG4scik9Pnt0aGlzLnUucHVzaChbITEsZT0+e2lmKHQpdHJ5e24odChlKSl9Y2F0Y2godCl7cih0KX1lbHNlIG4oZSl9LHQ9PntpZihlKXRyeXtuKGUodCkpfWNhdGNoKHQpe3IodCl9ZWxzZSByKHQpfV0pLHRoaXMubCgpfSkpfWNhdGNoKHQpe3JldHVybiB0aGlzLnRoZW4oKHQ9PnQpLHQpfWZpbmFsbHkodCl7cmV0dXJuIG5ldyBZKCgoZSxuKT0+e2xldCByLG87cmV0dXJuIHRoaXMudGhlbigoZT0+e289ITEscj1lLHQmJnQoKX0pLChlPT57bz0hMCxyPWUsdCYmdCgpfSkpLnRoZW4oKCgpPT57bz9uKHIpOmUocil9KSl9KSl9X19pbml0KCl7dGhpcy5oPXQ9Pnt0aGlzLm0oSC5SRVNPTFZFRCx0KX19X19pbml0Migpe3RoaXMucD10PT57dGhpcy5tKEguUkVKRUNURUQsdCl9fV9faW5pdDMoKXt0aGlzLm09KHQsZSk9Pnt0aGlzLmk9PT1ILlBFTkRJTkcmJihtKGUpP2UudGhlbih0aGlzLmgsdGhpcy5wKToodGhpcy5pPXQsdGhpcy52PWUsdGhpcy5sKCkpKX19X19pbml0NCgpe3RoaXMubD0oKT0+e2lmKHRoaXMuaT09PUguUEVORElORylyZXR1cm47Y29uc3QgdD10aGlzLnUuc2xpY2UoKTt0aGlzLnU9W10sdC5mb3JFYWNoKCh0PT57dFswXXx8KHRoaXMuaT09PUguUkVTT0xWRUQmJnRbMV0odGhpcy52KSx0aGlzLmk9PT1ILlJFSkVDVEVEJiZ0WzJdKHRoaXMudiksdFswXT0hMCl9KSl9fX1mdW5jdGlvbiBxKHQpe2NvbnN0IGU9W107ZnVuY3Rpb24gbih0KXtyZXR1cm4gZS5zcGxpY2UoZS5pbmRleE9mKHQpLDEpWzBdfXJldHVybnskOmUsYWRkOmZ1bmN0aW9uKHIpe2lmKCEodm9pZCAwPT09dHx8ZS5sZW5ndGg8dCkpcmV0dXJuIG89bmV3IEMoIk5vdCBhZGRpbmcgUHJvbWlzZSBiZWNhdXNlIGJ1ZmZlciBsaW1pdCB3YXMgcmVhY2hlZC4iKSxuZXcgWSgoKHQsZSk9PntlKG8pfSkpO3ZhciBvO2NvbnN0IHM9cigpO3JldHVybi0xPT09ZS5pbmRleE9mKHMpJiZlLnB1c2gocykscy50aGVuKCgoKT0+bihzKSkpLnRoZW4obnVsbCwoKCk9Pm4ocykudGhlbihudWxsLCgoKT0+e30pKSkpLHN9LGRyYWluOmZ1bmN0aW9uKHQpe3JldHVybiBuZXcgWSgoKG4scik9PntsZXQgbz1lLmxlbmd0aDtpZighbylyZXR1cm4gbighMCk7Y29uc3Qgcz1zZXRUaW1lb3V0KCgoKT0+e3QmJnQ+MCYmbighMSl9KSx0KTtlLmZvckVhY2goKHQ9PntXKHQpLnRoZW4oKCgpPT57LS1vfHwoY2xlYXJUaW1lb3V0KHMpLG4oITApKX0pLHIpfSkpfSkpfX19ZnVuY3Rpb24gRih0LGU9ITEpe3JldHVybiEoZXx8dCYmIXQuc3RhcnRzV2l0aCgiLyIpJiYhdC5tYXRjaCgvXltBLVpdOi8pJiYhdC5zdGFydHNXaXRoKCIuIikmJiF0Lm1hdGNoKC9eW2EtekEtWl0oW2EtekEtWjAtOS5cLStdKSo6XC9cLy8pKSYmdm9pZCAwIT09dCYmIXQuaW5jbHVkZXMoIm5vZGVfbW9kdWxlcy8iKX1jb25zdCBLPTFlMztmdW5jdGlvbiBWKCl7cmV0dXJuIERhdGUubm93KCkvS31jb25zdCBaPWZ1bmN0aW9uKCl7Y29uc3R7cGVyZm9ybWFuY2U6dH09eTtpZighdHx8IXQubm93KXJldHVybiBWO2NvbnN0IGU9RGF0ZS5ub3coKS10Lm5vdygpLG49bnVsbD09dC50aW1lT3JpZ2luP2U6dC50aW1lT3JpZ2luO3JldHVybigpPT4obit0Lm5vdygpKS9LfSgpO2Z1bmN0aW9uIFEodCxlPVtdKXtyZXR1cm5bdCxlXX1mdW5jdGlvbiBYKHQsZSl7Y29uc3Qgbj10WzFdO2Zvcihjb25zdCB0IG9mIG4pe2lmKGUodCx0WzBdLnR5cGUpKXJldHVybiEwfXJldHVybiExfWZ1bmN0aW9uIHR0KHQpe3JldHVybiB5Ll9fU0VOVFJZX18mJnkuX19TRU5UUllfXy5lbmNvZGVQb2x5ZmlsbD95Ll9fU0VOVFJZX18uZW5jb2RlUG9seWZpbGwodCk6KG5ldyBUZXh0RW5jb2RlcikuZW5jb2RlKHQpfWZ1bmN0aW9uIGV0KHQpe2NvbnN0W2Usbl09dDtsZXQgcj1KU09OLnN0cmluZ2lmeShlKTtmdW5jdGlvbiBvKHQpeyJzdHJpbmciPT10eXBlb2Ygcj9yPSJzdHJpbmciPT10eXBlb2YgdD9yK3Q6W3R0KHIpLHRdOnIucHVzaCgic3RyaW5nIj09dHlwZW9mIHQ/dHQodCk6dCl9Zm9yKGNvbnN0IHQgb2Ygbil7Y29uc3RbZSxuXT10O2lmKG8oYFxuJHtKU09OLnN0cmluZ2lmeShlKX1cbmApLCJzdHJpbmciPT10eXBlb2Ygbnx8biBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpbyhuKTtlbHNle2xldCB0O3RyeXt0PUpTT04uc3RyaW5naWZ5KG4pfWNhdGNoKGUpe3Q9SlNPTi5zdHJpbmdpZnkoTChuKSl9byh0KX19cmV0dXJuInN0cmluZyI9PXR5cGVvZiByP3I6ZnVuY3Rpb24odCl7Y29uc3QgZT10LnJlZHVjZSgoKHQsZSk9PnQrZS5sZW5ndGgpLDApLG49bmV3IFVpbnQ4QXJyYXkoZSk7bGV0IHI9MDtmb3IoY29uc3QgZSBvZiB0KW4uc2V0KGUscikscis9ZS5sZW5ndGg7cmV0dXJuIG59KHIpfSgoKT0+e2NvbnN0e3BlcmZvcm1hbmNlOnR9PXk7aWYoIXR8fCF0Lm5vdylyZXR1cm47Y29uc3QgZT0zNmU1LG49dC5ub3coKSxyPURhdGUubm93KCksbz10LnRpbWVPcmlnaW4/TWF0aC5hYnModC50aW1lT3JpZ2luK24tcik6ZSxzPW88ZSxpPXQudGltaW5nJiZ0LnRpbWluZy5uYXZpZ2F0aW9uU3RhcnQsYz0ibnVtYmVyIj09dHlwZW9mIGk/TWF0aC5hYnMoaStuLXIpOmU7KHN8fGM8ZSkmJihvPD1jJiZ0LnRpbWVPcmlnaW4pfSkoKTtjb25zdCBudD17c2Vzc2lvbjoic2Vzc2lvbiIsc2Vzc2lvbnM6InNlc3Npb24iLGF0dGFjaG1lbnQ6ImF0dGFjaG1lbnQiLHRyYW5zYWN0aW9uOiJ0cmFuc2FjdGlvbiIsZXZlbnQ6ImVycm9yIixjbGllbnRfcmVwb3J0OiJpbnRlcm5hbCIsdXNlcl9yZXBvcnQ6ImRlZmF1bHQiLHByb2ZpbGU6InByb2ZpbGUiLHJlcGxheV9ldmVudDoicmVwbGF5IixyZXBsYXlfcmVjb3JkaW5nOiJyZXBsYXkiLGNoZWNrX2luOiJtb25pdG9yIixmZWVkYmFjazoiZmVlZGJhY2siLHNwYW46InNwYW4iLHN0YXRzZDoibWV0cmljX2J1Y2tldCJ9O2Z1bmN0aW9uIHJ0KHQpe3JldHVybiBudFt0XX1mdW5jdGlvbiBvdCh0KXtpZighdHx8IXQuc2RrKXJldHVybjtjb25zdHtuYW1lOmUsdmVyc2lvbjpufT10LnNkaztyZXR1cm57bmFtZTplLHZlcnNpb246bn19Y29uc3Qgc3Q9NmU0O2Z1bmN0aW9uIGl0KHQse3N0YXR1c0NvZGU6ZSxoZWFkZXJzOm59LHI9RGF0ZS5ub3coKSl7Y29uc3Qgbz17Li4udH0scz1uJiZuWyJ4LXNlbnRyeS1yYXRlLWxpbWl0cyJdLGk9biYmblsicmV0cnktYWZ0ZXIiXTtpZihzKWZvcihjb25zdCB0IG9mIHMudHJpbSgpLnNwbGl0KCIsIikpe2NvbnN0W2UsbiwsLHNdPXQuc3BsaXQoIjoiLDUpLGk9cGFyc2VJbnQoZSwxMCksYz0xZTMqKGlzTmFOKGkpPzYwOmkpO2lmKG4pZm9yKGNvbnN0IHQgb2Ygbi5zcGxpdCgiOyIpKSJtZXRyaWNfYnVja2V0Ij09PXQmJnMmJiFzLnNwbGl0KCI7IikuaW5jbHVkZXMoImN1c3RvbSIpfHwob1t0XT1yK2MpO2Vsc2Ugby5hbGw9citjfWVsc2UgaT9vLmFsbD1yK2Z1bmN0aW9uKHQsZT1EYXRlLm5vdygpKXtjb25zdCBuPXBhcnNlSW50KGAke3R9YCwxMCk7aWYoIWlzTmFOKG4pKXJldHVybiAxZTMqbjtjb25zdCByPURhdGUucGFyc2UoYCR7dH1gKTtyZXR1cm4gaXNOYU4ocik/c3Q6ci1lfShpLHIpOjQyOT09PWUmJihvLmFsbD1yKzZlNCk7cmV0dXJuIG99Y29uc3QgY3Q9InVuZGVmaW5lZCI9PXR5cGVvZiBfX1NFTlRSWV9ERUJVR19ffHxfX1NFTlRSWV9ERUJVR19fO2Z1bmN0aW9uIHV0KCl7cmV0dXJuIGF0KHkpLHl9ZnVuY3Rpb24gYXQodCl7cmV0dXJuIHQuX19TRU5UUllfX3x8KHQuX19TRU5UUllfXz17ZXh0ZW5zaW9uczp7fX0pLHQuX19TRU5UUllfX31mdW5jdGlvbiBmdCh0KXtjb25zdCBlPVooKSxuPXtzaWQ6TSgpLGluaXQ6ITAsdGltZXN0YW1wOmUsc3RhcnRlZDplLGR1cmF0aW9uOjAsc3RhdHVzOiJvayIsZXJyb3JzOjAsaWdub3JlRHVyYXRpb246ITEsdG9KU09OOigpPT5mdW5jdGlvbih0KXtyZXR1cm4gaih7c2lkOmAke3Quc2lkfWAsaW5pdDp0LmluaXQsc3RhcnRlZDpuZXcgRGF0ZSgxZTMqdC5zdGFydGVkKS50b0lTT1N0cmluZygpLHRpbWVzdGFtcDpuZXcgRGF0ZSgxZTMqdC50aW1lc3RhbXApLnRvSVNPU3RyaW5nKCksc3RhdHVzOnQuc3RhdHVzLGVycm9yczp0LmVycm9ycyxkaWQ6Im51bWJlciI9PXR5cGVvZiB0LmRpZHx8InN0cmluZyI9PXR5cGVvZiB0LmRpZD9gJHt0LmRpZH1gOnZvaWQgMCxkdXJhdGlvbjp0LmR1cmF0aW9uLGFibm9ybWFsX21lY2hhbmlzbTp0LmFibm9ybWFsX21lY2hhbmlzbSxhdHRyczp7cmVsZWFzZTp0LnJlbGVhc2UsZW52aXJvbm1lbnQ6dC5lbnZpcm9ubWVudCxpcF9hZGRyZXNzOnQuaXBBZGRyZXNzLHVzZXJfYWdlbnQ6dC51c2VyQWdlbnR9fSl9KG4pfTtyZXR1cm4gdCYmaHQobix0KSxufWZ1bmN0aW9uIGh0KHQsZT17fSl7aWYoZS51c2VyJiYoIXQuaXBBZGRyZXNzJiZlLnVzZXIuaXBfYWRkcmVzcyYmKHQuaXBBZGRyZXNzPWUudXNlci5pcF9hZGRyZXNzKSx0LmRpZHx8ZS5kaWR8fCh0LmRpZD1lLnVzZXIuaWR8fGUudXNlci5lbWFpbHx8ZS51c2VyLnVzZXJuYW1lKSksdC50aW1lc3RhbXA9ZS50aW1lc3RhbXB8fFooKSxlLmFibm9ybWFsX21lY2hhbmlzbSYmKHQuYWJub3JtYWxfbWVjaGFuaXNtPWUuYWJub3JtYWxfbWVjaGFuaXNtKSxlLmlnbm9yZUR1cmF0aW9uJiYodC5pZ25vcmVEdXJhdGlvbj1lLmlnbm9yZUR1cmF0aW9uKSxlLnNpZCYmKHQuc2lkPTMyPT09ZS5zaWQubGVuZ3RoP2Uuc2lkOk0oKSksdm9pZCAwIT09ZS5pbml0JiYodC5pbml0PWUuaW5pdCksIXQuZGlkJiZlLmRpZCYmKHQuZGlkPWAke2UuZGlkfWApLCJudW1iZXIiPT10eXBlb2YgZS5zdGFydGVkJiYodC5zdGFydGVkPWUuc3RhcnRlZCksdC5pZ25vcmVEdXJhdGlvbil0LmR1cmF0aW9uPXZvaWQgMDtlbHNlIGlmKCJudW1iZXIiPT10eXBlb2YgZS5kdXJhdGlvbil0LmR1cmF0aW9uPWUuZHVyYXRpb247ZWxzZXtjb25zdCBlPXQudGltZXN0YW1wLXQuc3RhcnRlZDt0LmR1cmF0aW9uPWU+PTA/ZTowfWUucmVsZWFzZSYmKHQucmVsZWFzZT1lLnJlbGVhc2UpLGUuZW52aXJvbm1lbnQmJih0LmVudmlyb25tZW50PWUuZW52aXJvbm1lbnQpLCF0LmlwQWRkcmVzcyYmZS5pcEFkZHJlc3MmJih0LmlwQWRkcmVzcz1lLmlwQWRkcmVzcyksIXQudXNlckFnZW50JiZlLnVzZXJBZ2VudCYmKHQudXNlckFnZW50PWUudXNlckFnZW50KSwibnVtYmVyIj09dHlwZW9mIGUuZXJyb3JzJiYodC5lcnJvcnM9ZS5lcnJvcnMpLGUuc3RhdHVzJiYodC5zdGF0dXM9ZS5zdGF0dXMpfWNvbnN0IHB0PSJfc2VudHJ5U3BhbiI7ZnVuY3Rpb24gbHQodCxlKXtlP2Z1bmN0aW9uKHQsZSxuKXt0cnl7T2JqZWN0LmRlZmluZVByb3BlcnR5KHQsZSx7dmFsdWU6bix3cml0YWJsZTohMCxjb25maWd1cmFibGU6ITB9KX1jYXRjaChuKXtTJiZOLmxvZyhgRmFpbGVkIHRvIGFkZCBub24tZW51bWVyYWJsZSBwcm9wZXJ0eSAiJHtlfSIgdG8gb2JqZWN0YCx0KX19KHQscHQsZSk6ZGVsZXRlIHRbcHRdfWZ1bmN0aW9uIGR0KHQpe3JldHVybiB0W3B0XX1jbGFzcyBtdHtjb25zdHJ1Y3Rvcigpe3RoaXMuXz0hMSx0aGlzLlM9W10sdGhpcy5OPVtdLHRoaXMuaz1bXSx0aGlzLkM9W10sdGhpcy5EPXt9LHRoaXMuVD17fSx0aGlzLk89e30sdGhpcy5qPXt9LHRoaXMuUj17fSx0aGlzLkE9Z3QoKX1jbG9uZSgpe2NvbnN0IHQ9bmV3IG10O3JldHVybiB0Lms9Wy4uLnRoaXMua10sdC5UPXsuLi50aGlzLlR9LHQuTz17Li4udGhpcy5PfSx0Lmo9ey4uLnRoaXMuan0sdC5EPXRoaXMuRCx0Lkk9dGhpcy5JLHQuUD10aGlzLlAsdC5VPXRoaXMuVSx0Lk09dGhpcy5NLHQuTj1bLi4udGhpcy5OXSx0Lkw9dGhpcy5MLHQuQz1bLi4udGhpcy5DXSx0LlI9ey4uLnRoaXMuUn0sdC5BPXsuLi50aGlzLkF9LHQuQj10aGlzLkIsbHQodCxkdCh0aGlzKSksdH1zZXRDbGllbnQodCl7dGhpcy5CPXR9Z2V0Q2xpZW50KCl7cmV0dXJuIHRoaXMuQn1hZGRTY29wZUxpc3RlbmVyKHQpe3RoaXMuUy5wdXNoKHQpfWFkZEV2ZW50UHJvY2Vzc29yKHQpe3JldHVybiB0aGlzLk4ucHVzaCh0KSx0aGlzfXNldFVzZXIodCl7cmV0dXJuIHRoaXMuRD10fHx7ZW1haWw6dm9pZCAwLGlkOnZvaWQgMCxpcF9hZGRyZXNzOnZvaWQgMCx1c2VybmFtZTp2b2lkIDB9LHRoaXMuUCYmaHQodGhpcy5QLHt1c2VyOnR9KSx0aGlzLkcoKSx0aGlzfWdldFVzZXIoKXtyZXR1cm4gdGhpcy5EfWdldFJlcXVlc3RTZXNzaW9uKCl7cmV0dXJuIHRoaXMuTH1zZXRSZXF1ZXN0U2Vzc2lvbih0KXtyZXR1cm4gdGhpcy5MPXQsdGhpc31zZXRUYWdzKHQpe3JldHVybiB0aGlzLlQ9ey4uLnRoaXMuVCwuLi50fSx0aGlzLkcoKSx0aGlzfXNldFRhZyh0LGUpe3JldHVybiB0aGlzLlQ9ey4uLnRoaXMuVCxbdF06ZX0sdGhpcy5HKCksdGhpc31zZXRFeHRyYXModCl7cmV0dXJuIHRoaXMuTz17Li4udGhpcy5PLC4uLnR9LHRoaXMuRygpLHRoaXN9c2V0RXh0cmEodCxlKXtyZXR1cm4gdGhpcy5PPXsuLi50aGlzLk8sW3RdOmV9LHRoaXMuRygpLHRoaXN9c2V0RmluZ2VycHJpbnQodCl7cmV0dXJuIHRoaXMuTT10LHRoaXMuRygpLHRoaXN9c2V0TGV2ZWwodCl7cmV0dXJuIHRoaXMuST10LHRoaXMuRygpLHRoaXN9c2V0VHJhbnNhY3Rpb25OYW1lKHQpe3JldHVybiB0aGlzLlU9dCx0aGlzLkcoKSx0aGlzfXNldENvbnRleHQodCxlKXtyZXR1cm4gbnVsbD09PWU/ZGVsZXRlIHRoaXMualt0XTp0aGlzLmpbdF09ZSx0aGlzLkcoKSx0aGlzfXNldFNlc3Npb24odCl7cmV0dXJuIHQ/dGhpcy5QPXQ6ZGVsZXRlIHRoaXMuUCx0aGlzLkcoKSx0aGlzfWdldFNlc3Npb24oKXtyZXR1cm4gdGhpcy5QfXVwZGF0ZSh0KXtpZighdClyZXR1cm4gdGhpcztjb25zdCBlPSJmdW5jdGlvbiI9PXR5cGVvZiB0P3QodGhpcyk6dCxbbixyXT1lIGluc3RhbmNlb2YgbXQ/W2UuZ2V0U2NvcGVEYXRhKCksZS5nZXRSZXF1ZXN0U2Vzc2lvbigpXTpkKGUpP1t0LHQucmVxdWVzdFNlc3Npb25dOltdLHt0YWdzOm8sZXh0cmE6cyx1c2VyOmksY29udGV4dHM6YyxsZXZlbDp1LGZpbmdlcnByaW50OmE9W10scHJvcGFnYXRpb25Db250ZXh0OmZ9PW58fHt9O3JldHVybiB0aGlzLlQ9ey4uLnRoaXMuVCwuLi5vfSx0aGlzLk89ey4uLnRoaXMuTywuLi5zfSx0aGlzLmo9ey4uLnRoaXMuaiwuLi5jfSxpJiZPYmplY3Qua2V5cyhpKS5sZW5ndGgmJih0aGlzLkQ9aSksdSYmKHRoaXMuST11KSxhLmxlbmd0aCYmKHRoaXMuTT1hKSxmJiYodGhpcy5BPWYpLHImJih0aGlzLkw9ciksdGhpc31jbGVhcigpe3JldHVybiB0aGlzLms9W10sdGhpcy5UPXt9LHRoaXMuTz17fSx0aGlzLkQ9e30sdGhpcy5qPXt9LHRoaXMuST12b2lkIDAsdGhpcy5VPXZvaWQgMCx0aGlzLk09dm9pZCAwLHRoaXMuTD12b2lkIDAsdGhpcy5QPXZvaWQgMCxsdCh0aGlzLHZvaWQgMCksdGhpcy5DPVtdLHRoaXMuQT1ndCgpLHRoaXMuRygpLHRoaXN9YWRkQnJlYWRjcnVtYih0LGUpe2NvbnN0IG49Im51bWJlciI9PXR5cGVvZiBlP2U6MTAwO2lmKG48PTApcmV0dXJuIHRoaXM7Y29uc3Qgcj17dGltZXN0YW1wOlYoKSwuLi50fSxvPXRoaXMuaztyZXR1cm4gby5wdXNoKHIpLHRoaXMuaz1vLmxlbmd0aD5uP28uc2xpY2UoLW4pOm8sdGhpcy5HKCksdGhpc31nZXRMYXN0QnJlYWRjcnVtYigpe3JldHVybiB0aGlzLmtbdGhpcy5rLmxlbmd0aC0xXX1jbGVhckJyZWFkY3J1bWJzKCl7cmV0dXJuIHRoaXMuaz1bXSx0aGlzLkcoKSx0aGlzfWFkZEF0dGFjaG1lbnQodCl7cmV0dXJuIHRoaXMuQy5wdXNoKHQpLHRoaXN9Y2xlYXJBdHRhY2htZW50cygpe3JldHVybiB0aGlzLkM9W10sdGhpc31nZXRTY29wZURhdGEoKXtyZXR1cm57YnJlYWRjcnVtYnM6dGhpcy5rLGF0dGFjaG1lbnRzOnRoaXMuQyxjb250ZXh0czp0aGlzLmosdGFnczp0aGlzLlQsZXh0cmE6dGhpcy5PLHVzZXI6dGhpcy5ELGxldmVsOnRoaXMuSSxmaW5nZXJwcmludDp0aGlzLk18fFtdLGV2ZW50UHJvY2Vzc29yczp0aGlzLk4scHJvcGFnYXRpb25Db250ZXh0OnRoaXMuQSxzZGtQcm9jZXNzaW5nTWV0YWRhdGE6dGhpcy5SLHRyYW5zYWN0aW9uTmFtZTp0aGlzLlUsc3BhbjpkdCh0aGlzKX19c2V0U0RLUHJvY2Vzc2luZ01ldGFkYXRhKHQpe3JldHVybiB0aGlzLlI9ey4uLnRoaXMuUiwuLi50fSx0aGlzfXNldFByb3BhZ2F0aW9uQ29udGV4dCh0KXtyZXR1cm4gdGhpcy5BPXQsdGhpc31nZXRQcm9wYWdhdGlvbkNvbnRleHQoKXtyZXR1cm4gdGhpcy5BfWNhcHR1cmVFeGNlcHRpb24odCxlKXtjb25zdCBuPWUmJmUuZXZlbnRfaWQ/ZS5ldmVudF9pZDpNKCk7aWYoIXRoaXMuQilyZXR1cm4gTi53YXJuKCJObyBjbGllbnQgY29uZmlndXJlZCBvbiBzY29wZSAtIHdpbGwgbm90IGNhcHR1cmUgZXhjZXB0aW9uISIpLG47Y29uc3Qgcj1uZXcgRXJyb3IoIlNlbnRyeSBzeW50aGV0aWNFeGNlcHRpb24iKTtyZXR1cm4gdGhpcy5CLmNhcHR1cmVFeGNlcHRpb24odCx7b3JpZ2luYWxFeGNlcHRpb246dCxzeW50aGV0aWNFeGNlcHRpb246ciwuLi5lLGV2ZW50X2lkOm59LHRoaXMpLG59Y2FwdHVyZU1lc3NhZ2UodCxlLG4pe2NvbnN0IHI9biYmbi5ldmVudF9pZD9uLmV2ZW50X2lkOk0oKTtpZighdGhpcy5CKXJldHVybiBOLndhcm4oIk5vIGNsaWVudCBjb25maWd1cmVkIG9uIHNjb3BlIC0gd2lsbCBub3QgY2FwdHVyZSBtZXNzYWdlISIpLHI7Y29uc3Qgbz1uZXcgRXJyb3IodCk7cmV0dXJuIHRoaXMuQi5jYXB0dXJlTWVzc2FnZSh0LGUse29yaWdpbmFsRXhjZXB0aW9uOnQsc3ludGhldGljRXhjZXB0aW9uOm8sLi4ubixldmVudF9pZDpyfSx0aGlzKSxyfWNhcHR1cmVFdmVudCh0LGUpe2NvbnN0IG49ZSYmZS5ldmVudF9pZD9lLmV2ZW50X2lkOk0oKTtyZXR1cm4gdGhpcy5CPyh0aGlzLkIuY2FwdHVyZUV2ZW50KHQsey4uLmUsZXZlbnRfaWQ6bn0sdGhpcyksbik6KE4ud2FybigiTm8gY2xpZW50IGNvbmZpZ3VyZWQgb24gc2NvcGUgLSB3aWxsIG5vdCBjYXB0dXJlIGV2ZW50ISIpLG4pfUcoKXt0aGlzLl98fCh0aGlzLl89ITAsdGhpcy5TLmZvckVhY2goKHQ9Pnt0KHRoaXMpfSkpLHRoaXMuXz0hMSl9fWZ1bmN0aW9uIGd0KCl7cmV0dXJue3RyYWNlSWQ6TSgpLHNwYW5JZDpNKCkuc3Vic3RyaW5nKDE2KX19ZnVuY3Rpb24geXQoKXtyZXR1cm4gJHQodXQoKSkuZ2V0Q3VycmVudFNjb3BlKCkuZ2V0Q2xpZW50KCl9Y2xhc3MgYnR7Y29uc3RydWN0b3IodCxlKXtsZXQgbixyO249dHx8bmV3IG10LHI9ZXx8bmV3IG10LHRoaXMuSj1be3Njb3BlOm59XSx0aGlzLkg9cn13aXRoU2NvcGUodCl7Y29uc3QgZT10aGlzLlcoKTtsZXQgbjt0cnl7bj10KGUpfWNhdGNoKHQpe3Rocm93IHRoaXMuWSgpLHR9cmV0dXJuIG0obik/bi50aGVuKCh0PT4odGhpcy5ZKCksdCkpLCh0PT57dGhyb3cgdGhpcy5ZKCksdH0pKToodGhpcy5ZKCksbil9Z2V0Q2xpZW50KCl7cmV0dXJuIHRoaXMuZ2V0U3RhY2tUb3AoKS5jbGllbnR9Z2V0U2NvcGUoKXtyZXR1cm4gdGhpcy5nZXRTdGFja1RvcCgpLnNjb3BlfWdldElzb2xhdGlvblNjb3BlKCl7cmV0dXJuIHRoaXMuSH1nZXRTdGFjaygpe3JldHVybiB0aGlzLkp9Z2V0U3RhY2tUb3AoKXtyZXR1cm4gdGhpcy5KW3RoaXMuSi5sZW5ndGgtMV19Vygpe2NvbnN0IHQ9dGhpcy5nZXRTY29wZSgpLmNsb25lKCk7cmV0dXJuIHRoaXMuZ2V0U3RhY2soKS5wdXNoKHtjbGllbnQ6dGhpcy5nZXRDbGllbnQoKSxzY29wZTp0fSksdH1ZKCl7cmV0dXJuISh0aGlzLmdldFN0YWNrKCkubGVuZ3RoPD0xKSYmISF0aGlzLmdldFN0YWNrKCkucG9wKCl9fWZ1bmN0aW9uIHZ0KCl7Y29uc3QgdD1hdCh1dCgpKTtyZXR1cm4gdC5odWJ8fCh0Lmh1Yj1uZXcgYnQoYigiZGVmYXVsdEN1cnJlbnRTY29wZSIsKCgpPT5uZXcgbXQpKSxiKCJkZWZhdWx0SXNvbGF0aW9uU2NvcGUiLCgoKT0+bmV3IG10KSkpKSx0Lmh1Yn1mdW5jdGlvbiBfdCh0KXtyZXR1cm4gdnQoKS53aXRoU2NvcGUodCl9ZnVuY3Rpb24gd3QodCxlKXtjb25zdCBuPXZ0KCk7cmV0dXJuIG4ud2l0aFNjb3BlKCgoKT0+KG4uZ2V0U3RhY2tUb3AoKS5zY29wZT10LGUodCkpKSl9ZnVuY3Rpb24gU3QodCl7cmV0dXJuIHZ0KCkud2l0aFNjb3BlKCgoKT0+dCh2dCgpLmdldElzb2xhdGlvblNjb3BlKCkpKSl9ZnVuY3Rpb24gJHQodCl7Y29uc3QgZT1hdCh0KTtyZXR1cm4gZS5hY3M/ZS5hY3M6e3dpdGhJc29sYXRpb25TY29wZTpTdCx3aXRoU2NvcGU6X3Qsd2l0aFNldFNjb3BlOnd0LHdpdGhTZXRJc29sYXRpb25TY29wZToodCxlKT0+U3QoZSksZ2V0Q3VycmVudFNjb3BlOigpPT52dCgpLmdldFNjb3BlKCksZ2V0SXNvbGF0aW9uU2NvcGU6KCk9PnZ0KCkuZ2V0SXNvbGF0aW9uU2NvcGUoKX19Y29uc3QgRXQ9InNlbnRyeS5zb3VyY2UiLHh0PSJzZW50cnkuc2FtcGxlX3JhdGUiLE50PSJzZW50cnkub3AiLGt0PSJzZW50cnkub3JpZ2luIixDdD0wLER0PTEsVHQ9InByb2R1Y3Rpb24iLE90PSJfZnJvemVuRHNjIjtmdW5jdGlvbiBqdCh0KXtjb25zdCBlPXl0KCk7aWYoIWUpcmV0dXJue307Y29uc3Qgbj1mdW5jdGlvbih0LGUpe2NvbnN0IG49ZS5nZXRPcHRpb25zKCkse3B1YmxpY0tleTpyfT1lLmdldERzbigpfHx7fSxvPWooe2Vudmlyb25tZW50Om4uZW52aXJvbm1lbnR8fFR0LHJlbGVhc2U6bi5yZWxlYXNlLHB1YmxpY19rZXk6cix0cmFjZV9pZDp0fSk7cmV0dXJuIGUuZW1pdCgiY3JlYXRlRHNjIixvKSxvfShVdCh0KS50cmFjZV9pZHx8IiIsZSkscj1CdCh0KTtpZighcilyZXR1cm4gbjtjb25zdCBvPXJbT3RdO2lmKG8pcmV0dXJuIG87Y29uc3Qgcz1VdChyKSxpPXMuZGF0YXx8e30sYz1pW3h0XTtudWxsIT1jJiYobi5zYW1wbGVfcmF0ZT1gJHtjfWApO2NvbnN0IHU9aVtFdF07cmV0dXJuIHUmJiJ1cmwiIT09dSYmKG4udHJhbnNhY3Rpb249cy5kZXNjcmlwdGlvbiksbi5zYW1wbGVkPVN0cmluZyhmdW5jdGlvbih0KXtjb25zdHt0cmFjZUZsYWdzOmV9PXQuc3BhbkNvbnRleHQoKTtyZXR1cm4gZT09PVJ0fShyKSksZS5lbWl0KCJjcmVhdGVEc2MiLG4pLG59Y29uc3QgUnQ9MTtmdW5jdGlvbiBBdCh0KXtjb25zdHtzcGFuSWQ6ZSx0cmFjZUlkOm59PXQuc3BhbkNvbnRleHQoKSx7cGFyZW50X3NwYW5faWQ6cn09VXQodCk7cmV0dXJuIGooe3BhcmVudF9zcGFuX2lkOnIsc3Bhbl9pZDplLHRyYWNlX2lkOm59KX1mdW5jdGlvbiBJdCh0KXtyZXR1cm4ibnVtYmVyIj09dHlwZW9mIHQ/UHQodCk6QXJyYXkuaXNBcnJheSh0KT90WzBdK3RbMV0vMWU5OnQgaW5zdGFuY2VvZiBEYXRlP1B0KHQuZ2V0VGltZSgpKTpaKCl9ZnVuY3Rpb24gUHQodCl7cmV0dXJuIHQ+OTk5OTk5OTk5OT90LzFlMzp0fWZ1bmN0aW9uIFV0KHQpe2lmKGZ1bmN0aW9uKHQpe3JldHVybiJmdW5jdGlvbiI9PXR5cGVvZiB0LmdldFNwYW5KU09OfSh0KSlyZXR1cm4gdC5nZXRTcGFuSlNPTigpO3RyeXtjb25zdHtzcGFuSWQ6ZSx0cmFjZUlkOm59PXQuc3BhbkNvbnRleHQoKTtpZihmdW5jdGlvbih0KXtjb25zdCBlPXQ7cmV0dXJuISEoZS5hdHRyaWJ1dGVzJiZlLnN0YXJ0VGltZSYmZS5uYW1lJiZlLmVuZFRpbWUmJmUuc3RhdHVzKX0odCkpe2NvbnN0e2F0dHJpYnV0ZXM6cixzdGFydFRpbWU6byxuYW1lOnMsZW5kVGltZTppLHBhcmVudFNwYW5JZDpjLHN0YXR1czp1fT10O3JldHVybiBqKHtzcGFuX2lkOmUsdHJhY2VfaWQ6bixkYXRhOnIsZGVzY3JpcHRpb246cyxwYXJlbnRfc3Bhbl9pZDpjLHN0YXJ0X3RpbWVzdGFtcDpJdChvKSx0aW1lc3RhbXA6SXQoaSl8fHZvaWQgMCxzdGF0dXM6TXQodSksb3A6cltOdF0sb3JpZ2luOnJba3RdLHE6dm9pZCAwfSl9cmV0dXJue3NwYW5faWQ6ZSx0cmFjZV9pZDpufX1jYXRjaCh0KXtyZXR1cm57fX19ZnVuY3Rpb24gTXQodCl7aWYodCYmdC5jb2RlIT09Q3QpcmV0dXJuIHQuY29kZT09PUR0PyJvayI6dC5tZXNzYWdlfHwidW5rbm93bl9lcnJvciJ9Y29uc3QgTHQ9Il9zZW50cnlSb290U3BhbiI7ZnVuY3Rpb24gQnQodCl7cmV0dXJuIHRbTHRdfHx0fWZ1bmN0aW9uIEd0KHQsZSxuLHIpe2NvbnN0IG89b3Qobikscz10LnR5cGUmJiJyZXBsYXlfZXZlbnQiIT09dC50eXBlP3QudHlwZToiZXZlbnQiOyFmdW5jdGlvbih0LGUpe2UmJih0LnNkaz10LnNka3x8e30sdC5zZGsubmFtZT10LnNkay5uYW1lfHxlLm5hbWUsdC5zZGsudmVyc2lvbj10LnNkay52ZXJzaW9ufHxlLnZlcnNpb24sdC5zZGsuaW50ZWdyYXRpb25zPVsuLi50LnNkay5pbnRlZ3JhdGlvbnN8fFtdLC4uLmUuaW50ZWdyYXRpb25zfHxbXV0sdC5zZGsucGFja2FnZXM9Wy4uLnQuc2RrLnBhY2thZ2VzfHxbXSwuLi5lLnBhY2thZ2VzfHxbXV0pfSh0LG4mJm4uc2RrKTtjb25zdCBpPWZ1bmN0aW9uKHQsZSxuLHIpe2NvbnN0IG89dC5zZGtQcm9jZXNzaW5nTWV0YWRhdGEmJnQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhLmR5bmFtaWNTYW1wbGluZ0NvbnRleHQ7cmV0dXJue2V2ZW50X2lkOnQuZXZlbnRfaWQsc2VudF9hdDoobmV3IERhdGUpLnRvSVNPU3RyaW5nKCksLi4uZSYme3NkazplfSwuLi4hIW4mJnImJntkc246ayhyKX0sLi4ubyYme3RyYWNlOmooey4uLm99KX19fSh0LG8scixlKTtkZWxldGUgdC5zZGtQcm9jZXNzaW5nTWV0YWRhdGE7cmV0dXJuIFEoaSxbW3t0eXBlOnN9LHRdXSl9Y29uc3QgSnQ9Il9fU0VOVFJZX1NVUFBSRVNTX1RSQUNJTkdfXyI7ZnVuY3Rpb24genQodCl7Y29uc3QgZT0kdCh1dCgpKTtyZXR1cm4gZS5zdXBwcmVzc1RyYWNpbmc/ZS5zdXBwcmVzc1RyYWNpbmcodCk6ZnVuY3Rpb24oLi4udCl7Y29uc3QgZT0kdCh1dCgpKTtpZigyPT09dC5sZW5ndGgpe2NvbnN0W24scl09dDtyZXR1cm4gbj9lLndpdGhTZXRTY29wZShuLHIpOmUud2l0aFNjb3BlKHIpfXJldHVybiBlLndpdGhTY29wZSh0WzBdKX0oKGU9PihlLnNldFNES1Byb2Nlc3NpbmdNZXRhZGF0YSh7W0p0XTohMH0pLHQoKSkpKX1mdW5jdGlvbiBIdCh0LGUpe2NvbnN0e2ZpbmdlcnByaW50Om4sc3BhbjpyLGJyZWFkY3J1bWJzOm8sc2RrUHJvY2Vzc2luZ01ldGFkYXRhOnN9PWU7IWZ1bmN0aW9uKHQsZSl7Y29uc3R7ZXh0cmE6bix0YWdzOnIsdXNlcjpvLGNvbnRleHRzOnMsbGV2ZWw6aSx0cmFuc2FjdGlvbk5hbWU6Y309ZSx1PWoobik7dSYmT2JqZWN0LmtleXModSkubGVuZ3RoJiYodC5leHRyYT17Li4udSwuLi50LmV4dHJhfSk7Y29uc3QgYT1qKHIpO2EmJk9iamVjdC5rZXlzKGEpLmxlbmd0aCYmKHQudGFncz17Li4uYSwuLi50LnRhZ3N9KTtjb25zdCBmPWoobyk7ZiYmT2JqZWN0LmtleXMoZikubGVuZ3RoJiYodC51c2VyPXsuLi5mLC4uLnQudXNlcn0pO2NvbnN0IGg9aihzKTtoJiZPYmplY3Qua2V5cyhoKS5sZW5ndGgmJih0LmNvbnRleHRzPXsuLi5oLC4uLnQuY29udGV4dHN9KTtpJiYodC5sZXZlbD1pKTtjJiYidHJhbnNhY3Rpb24iIT09dC50eXBlJiYodC50cmFuc2FjdGlvbj1jKX0odCxlKSxyJiZmdW5jdGlvbih0LGUpe3QuY29udGV4dHM9e3RyYWNlOkF0KGUpLC4uLnQuY29udGV4dHN9LHQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhPXtkeW5hbWljU2FtcGxpbmdDb250ZXh0Omp0KGUpLC4uLnQuc2RrUHJvY2Vzc2luZ01ldGFkYXRhfTtjb25zdCBuPUJ0KGUpLHI9VXQobikuZGVzY3JpcHRpb247ciYmIXQudHJhbnNhY3Rpb24mJiJ0cmFuc2FjdGlvbiI9PT10LnR5cGUmJih0LnRyYW5zYWN0aW9uPXIpfSh0LHIpLGZ1bmN0aW9uKHQsZSl7dC5maW5nZXJwcmludD10LmZpbmdlcnByaW50P2Z1bmN0aW9uKHQpe3JldHVybiBBcnJheS5pc0FycmF5KHQpP3Q6W3RdfSh0LmZpbmdlcnByaW50KTpbXSxlJiYodC5maW5nZXJwcmludD10LmZpbmdlcnByaW50LmNvbmNhdChlKSk7dC5maW5nZXJwcmludCYmIXQuZmluZ2VycHJpbnQubGVuZ3RoJiZkZWxldGUgdC5maW5nZXJwcmludH0odCxuKSxmdW5jdGlvbih0LGUpe2NvbnN0IG49Wy4uLnQuYnJlYWRjcnVtYnN8fFtdLC4uLmVdO3QuYnJlYWRjcnVtYnM9bi5sZW5ndGg/bjp2b2lkIDB9KHQsbyksZnVuY3Rpb24odCxlKXt0LnNka1Byb2Nlc3NpbmdNZXRhZGF0YT17Li4udC5zZGtQcm9jZXNzaW5nTWV0YWRhdGEsLi4uZX19KHQscyl9Y29uc3QgV3Q9IjciO2Z1bmN0aW9uIFl0KHQsZSl7cmV0dXJuIG49e3NlbnRyeV9rZXk6dC5wdWJsaWNLZXksc2VudHJ5X3ZlcnNpb246V3QsLi4uZSYme3NlbnRyeV9jbGllbnQ6YCR7ZS5uYW1lfS8ke2UudmVyc2lvbn1gfX0sT2JqZWN0LmtleXMobikubWFwKCh0PT5gJHtlbmNvZGVVUklDb21wb25lbnQodCl9PSR7ZW5jb2RlVVJJQ29tcG9uZW50KG5bdF0pfWApKS5qb2luKCImIik7dmFyIG59Y29uc3QgcXQ9NjQ7ZnVuY3Rpb24gRnQodCxlLG49cSh0LmJ1ZmZlclNpemV8fHF0KSl7bGV0IHI9e307cmV0dXJue3NlbmQ6ZnVuY3Rpb24obyl7Y29uc3Qgcz1bXTtpZihYKG8sKChlLG4pPT57Y29uc3Qgbz1ydChuKTtpZihmdW5jdGlvbih0LGUsbj1EYXRlLm5vdygpKXtyZXR1cm4gZnVuY3Rpb24odCxlKXtyZXR1cm4gdFtlXXx8dC5hbGx8fDB9KHQsZSk+bn0ocixvKSl7Y29uc3Qgcj1LdChlLG4pO3QucmVjb3JkRHJvcHBlZEV2ZW50KCJyYXRlbGltaXRfYmFja29mZiIsbyxyKX1lbHNlIHMucHVzaChlKX0pKSwwPT09cy5sZW5ndGgpcmV0dXJuIFcoe30pO2NvbnN0IGk9UShvWzBdLHMpLGM9ZT0+e1goaSwoKG4scik9Pntjb25zdCBvPUt0KG4scik7dC5yZWNvcmREcm9wcGVkRXZlbnQoZSxydChyKSxvKX0pKX07cmV0dXJuIG4uYWRkKCgoKT0+ZSh7Ym9keTpldChpKX0pLnRoZW4oKHQ9Pih2b2lkIDAhPT10LnN0YXR1c0NvZGUmJih0LnN0YXR1c0NvZGU8MjAwfHx0LnN0YXR1c0NvZGU+PTMwMCkmJmN0JiZOLndhcm4oYFNlbnRyeSByZXNwb25kZWQgd2l0aCBzdGF0dXMgY29kZSAke3Quc3RhdHVzQ29kZX0gdG8gc2VudCBldmVudC5gKSxyPWl0KHIsdCksdCkpLCh0PT57dGhyb3cgYygibmV0d29ya19lcnJvciIpLHR9KSkpKS50aGVuKCh0PT50KSwodD0+e2lmKHQgaW5zdGFuY2VvZiBDKXJldHVybiBjdCYmTi5lcnJvcigiU2tpcHBlZCBzZW5kaW5nIGV2ZW50IGJlY2F1c2UgYnVmZmVyIGlzIGZ1bGwuIiksYygicXVldWVfb3ZlcmZsb3ciKSxXKHt9KTt0aHJvdyB0fSkpfSxmbHVzaDp0PT5uLmRyYWluKHQpfX1mdW5jdGlvbiBLdCh0LGUpe2lmKCJldmVudCI9PT1lfHwidHJhbnNhY3Rpb24iPT09ZSlyZXR1cm4gQXJyYXkuaXNBcnJheSh0KT90WzFdOnZvaWQgMH1jb25zdCBWdD1TeW1ib2woIkFnZW50QmFzZUludGVybmFsU3RhdGUiKTtjbGFzcyBadCBleHRlbmRzIGguQWdlbnR7W1Z0XTtvcHRpb25zO2tlZXBBbGl2ZTtjb25zdHJ1Y3Rvcih0KXtzdXBlcih0KSx0aGlzW1Z0XT17fX1pc1NlY3VyZUVuZHBvaW50KHQpe2lmKHQpe2lmKCJib29sZWFuIj09dHlwZW9mIHQuc2VjdXJlRW5kcG9pbnQpcmV0dXJuIHQuc2VjdXJlRW5kcG9pbnQ7aWYoInN0cmluZyI9PXR5cGVvZiB0LnByb3RvY29sKXJldHVybiJodHRwczoiPT09dC5wcm90b2NvbH1jb25zdHtzdGFjazplfT1uZXcgRXJyb3I7cmV0dXJuInN0cmluZyI9PXR5cGVvZiBlJiZlLnNwbGl0KCJcbiIpLnNvbWUoKHQ9Pi0xIT09dC5pbmRleE9mKCIoaHR0cHMuanM6Iil8fC0xIT09dC5pbmRleE9mKCJub2RlOmh0dHBzOiIpKSl9Y3JlYXRlU29ja2V0KHQsZSxuKXtjb25zdCByPXsuLi5lLHNlY3VyZUVuZHBvaW50OnRoaXMuaXNTZWN1cmVFbmRwb2ludChlKX07UHJvbWlzZS5yZXNvbHZlKCkudGhlbigoKCk9PnRoaXMuY29ubmVjdCh0LHIpKSkudGhlbigobz0+e2lmKG8gaW5zdGFuY2VvZiBoLkFnZW50KXJldHVybiBvLmFkZFJlcXVlc3QodCxyKTt0aGlzW1Z0XS5jdXJyZW50U29ja2V0PW8sc3VwZXIuY3JlYXRlU29ja2V0KHQsZSxuKX0pLG4pfWNyZWF0ZUNvbm5lY3Rpb24oKXtjb25zdCB0PXRoaXNbVnRdLmN1cnJlbnRTb2NrZXQ7aWYodGhpc1tWdF0uY3VycmVudFNvY2tldD12b2lkIDAsIXQpdGhyb3cgbmV3IEVycm9yKCJObyBzb2NrZXQgd2FzIHJldHVybmVkIGluIHRoZSBgY29ubmVjdCgpYCBmdW5jdGlvbiIpO3JldHVybiB0fWdldCBkZWZhdWx0UG9ydCgpe3JldHVybiB0aGlzW1Z0XS5kZWZhdWx0UG9ydD8/KCJodHRwczoiPT09dGhpcy5wcm90b2NvbD80NDM6ODApfXNldCBkZWZhdWx0UG9ydCh0KXt0aGlzW1Z0XSYmKHRoaXNbVnRdLmRlZmF1bHRQb3J0PXQpfWdldCBwcm90b2NvbCgpe3JldHVybiB0aGlzW1Z0XS5wcm90b2NvbD8/KHRoaXMuaXNTZWN1cmVFbmRwb2ludCgpPyJodHRwczoiOiJodHRwOiIpfXNldCBwcm90b2NvbCh0KXt0aGlzW1Z0XSYmKHRoaXNbVnRdLnByb3RvY29sPXQpfX1mdW5jdGlvbiBRdCguLi50KXtOLmxvZygiW2h0dHBzLXByb3h5LWFnZW50OnBhcnNlLXByb3h5LXJlc3BvbnNlXSIsLi4udCl9ZnVuY3Rpb24gWHQodCl7cmV0dXJuIG5ldyBQcm9taXNlKCgoZSxuKT0+e2xldCByPTA7Y29uc3Qgbz1bXTtmdW5jdGlvbiBzKCl7Y29uc3QgYz10LnJlYWQoKTtjP2Z1bmN0aW9uKGMpe28ucHVzaChjKSxyKz1jLmxlbmd0aDtjb25zdCB1PUJ1ZmZlci5jb25jYXQobyxyKSxhPXUuaW5kZXhPZigiXHJcblxyXG4iKTtpZigtMT09PWEpcmV0dXJuIFF0KCJoYXZlIG5vdCByZWNlaXZlZCBlbmQgb2YgSFRUUCBoZWFkZXJzIHlldC4uLiIpLHZvaWQgcygpO2NvbnN0IGY9dS5zbGljZSgwLGEpLnRvU3RyaW5nKCJhc2NpaSIpLnNwbGl0KCJcclxuIiksaD1mLnNoaWZ0KCk7aWYoIWgpcmV0dXJuIHQuZGVzdHJveSgpLG4obmV3IEVycm9yKCJObyBoZWFkZXIgcmVjZWl2ZWQgZnJvbSBwcm94eSBDT05ORUNUIHJlc3BvbnNlIikpO2NvbnN0IHA9aC5zcGxpdCgiICIpLGw9K3BbMV0sZD1wLnNsaWNlKDIpLmpvaW4oIiAiKSxtPXt9O2Zvcihjb25zdCBlIG9mIGYpe2lmKCFlKWNvbnRpbnVlO2NvbnN0IHI9ZS5pbmRleE9mKCI6Iik7aWYoLTE9PT1yKXJldHVybiB0LmRlc3Ryb3koKSxuKG5ldyBFcnJvcihgSW52YWxpZCBoZWFkZXIgZnJvbSBwcm94eSBDT05ORUNUIHJlc3BvbnNlOiAiJHtlfSJgKSk7Y29uc3Qgbz1lLnNsaWNlKDAscikudG9Mb3dlckNhc2UoKSxzPWUuc2xpY2UocisxKS50cmltU3RhcnQoKSxpPW1bb107InN0cmluZyI9PXR5cGVvZiBpP21bb109W2ksc106QXJyYXkuaXNBcnJheShpKT9pLnB1c2gocyk6bVtvXT1zfVF0KCJnb3QgcHJveHkgc2VydmVyIHJlc3BvbnNlOiAlbyAlbyIsaCxtKSxpKCksZSh7Y29ubmVjdDp7c3RhdHVzQ29kZTpsLHN0YXR1c1RleHQ6ZCxoZWFkZXJzOm19LGJ1ZmZlcmVkOnV9KX0oYyk6dC5vbmNlKCJyZWFkYWJsZSIscyl9ZnVuY3Rpb24gaSgpe3QucmVtb3ZlTGlzdGVuZXIoImVuZCIsYyksdC5yZW1vdmVMaXN0ZW5lcigiZXJyb3IiLHUpLHQucmVtb3ZlTGlzdGVuZXIoInJlYWRhYmxlIixzKX1mdW5jdGlvbiBjKCl7aSgpLFF0KCJvbmVuZCIpLG4obmV3IEVycm9yKCJQcm94eSBjb25uZWN0aW9uIGVuZGVkIGJlZm9yZSByZWNlaXZpbmcgQ09OTkVDVCByZXNwb25zZSIpKX1mdW5jdGlvbiB1KHQpe2koKSxRdCgib25lcnJvciAlbyIsdCksbih0KX10Lm9uKCJlcnJvciIsdSksdC5vbigiZW5kIixjKSxzKCl9KSl9ZnVuY3Rpb24gdGUoLi4udCl7Ti5sb2coIltodHRwcy1wcm94eS1hZ2VudF0iLC4uLnQpfWNsYXNzIGVlIGV4dGVuZHMgWnR7c3RhdGljIHByb3RvY29scz1bImh0dHAiLCJodHRwcyJdO3Byb3h5O3Byb3h5SGVhZGVycztjb25uZWN0T3B0cztjb25zdHJ1Y3Rvcih0LGUpe3N1cGVyKGUpLHRoaXMub3B0aW9ucz17fSx0aGlzLnByb3h5PSJzdHJpbmciPT10eXBlb2YgdD9uZXcgVVJMKHQpOnQsdGhpcy5wcm94eUhlYWRlcnM9ZT8uaGVhZGVycz8/e30sdGUoIkNyZWF0aW5nIG5ldyBIdHRwc1Byb3h5QWdlbnQgaW5zdGFuY2U6ICVvIix0aGlzLnByb3h5LmhyZWYpO2NvbnN0IG49KHRoaXMucHJveHkuaG9zdG5hbWV8fHRoaXMucHJveHkuaG9zdCkucmVwbGFjZSgvXlxbfFxdJC9nLCIiKSxyPXRoaXMucHJveHkucG9ydD9wYXJzZUludCh0aGlzLnByb3h5LnBvcnQsMTApOiJodHRwczoiPT09dGhpcy5wcm94eS5wcm90b2NvbD80NDM6ODA7dGhpcy5jb25uZWN0T3B0cz17QUxQTlByb3RvY29sczpbImh0dHAvMS4xIl0sLi4uZT9yZShlLCJoZWFkZXJzIik6bnVsbCxob3N0Om4scG9ydDpyfX1hc3luYyBjb25uZWN0KHQsZSl7Y29uc3R7cHJveHk6bn09dGhpcztpZighZS5ob3N0KXRocm93IG5ldyBUeXBlRXJyb3IoJ05vICJob3N0IiBwcm92aWRlZCcpO2xldCByO2lmKCJodHRwczoiPT09bi5wcm90b2NvbCl7dGUoIkNyZWF0aW5nIGB0bHMuU29ja2V0YDogJW8iLHRoaXMuY29ubmVjdE9wdHMpO2NvbnN0IHQ9dGhpcy5jb25uZWN0T3B0cy5zZXJ2ZXJuYW1lfHx0aGlzLmNvbm5lY3RPcHRzLmhvc3Q7cj1mLmNvbm5lY3Qoey4uLnRoaXMuY29ubmVjdE9wdHMsc2VydmVybmFtZTp0JiZhLmlzSVAodCk/dm9pZCAwOnR9KX1lbHNlIHRlKCJDcmVhdGluZyBgbmV0LlNvY2tldGA6ICVvIix0aGlzLmNvbm5lY3RPcHRzKSxyPWEuY29ubmVjdCh0aGlzLmNvbm5lY3RPcHRzKTtjb25zdCBvPSJmdW5jdGlvbiI9PXR5cGVvZiB0aGlzLnByb3h5SGVhZGVycz90aGlzLnByb3h5SGVhZGVycygpOnsuLi50aGlzLnByb3h5SGVhZGVyc30scz1hLmlzSVB2NihlLmhvc3QpP2BbJHtlLmhvc3R9XWA6ZS5ob3N0O2xldCBpPWBDT05ORUNUICR7c306JHtlLnBvcnR9IEhUVFAvMS4xXHJcbmA7aWYobi51c2VybmFtZXx8bi5wYXNzd29yZCl7Y29uc3QgdD1gJHtkZWNvZGVVUklDb21wb25lbnQobi51c2VybmFtZSl9OiR7ZGVjb2RlVVJJQ29tcG9uZW50KG4ucGFzc3dvcmQpfWA7b1siUHJveHktQXV0aG9yaXphdGlvbiJdPWBCYXNpYyAke0J1ZmZlci5mcm9tKHQpLnRvU3RyaW5nKCJiYXNlNjQiKX1gfW8uSG9zdD1gJHtzfToke2UucG9ydH1gLG9bIlByb3h5LUNvbm5lY3Rpb24iXXx8KG9bIlByb3h5LUNvbm5lY3Rpb24iXT10aGlzLmtlZXBBbGl2ZT8iS2VlcC1BbGl2ZSI6ImNsb3NlIik7Zm9yKGNvbnN0IHQgb2YgT2JqZWN0LmtleXMobykpaSs9YCR7dH06ICR7b1t0XX1cclxuYDtjb25zdCBjPVh0KHIpO3Iud3JpdGUoYCR7aX1cclxuYCk7Y29uc3R7Y29ubmVjdDp1LGJ1ZmZlcmVkOmh9PWF3YWl0IGM7aWYodC5lbWl0KCJwcm94eUNvbm5lY3QiLHUpLHRoaXMuZW1pdCgicHJveHlDb25uZWN0Iix1LHQpLDIwMD09PXUuc3RhdHVzQ29kZSl7aWYodC5vbmNlKCJzb2NrZXQiLG5lKSxlLnNlY3VyZUVuZHBvaW50KXt0ZSgiVXBncmFkaW5nIHNvY2tldCBjb25uZWN0aW9uIHRvIFRMUyIpO2NvbnN0IHQ9ZS5zZXJ2ZXJuYW1lfHxlLmhvc3Q7cmV0dXJuIGYuY29ubmVjdCh7Li4ucmUoZSwiaG9zdCIsInBhdGgiLCJwb3J0Iiksc29ja2V0OnIsc2VydmVybmFtZTphLmlzSVAodCk/dm9pZCAwOnR9KX1yZXR1cm4gcn1yLmRlc3Ryb3koKTtjb25zdCBwPW5ldyBhLlNvY2tldCh7d3JpdGFibGU6ITF9KTtyZXR1cm4gcC5yZWFkYWJsZT0hMCx0Lm9uY2UoInNvY2tldCIsKHQ9Pnt0ZSgiUmVwbGF5aW5nIHByb3h5IGJ1ZmZlciBmb3IgZmFpbGVkIHJlcXVlc3QiKSx0LnB1c2goaCksdC5wdXNoKG51bGwpfSkpLHB9fWZ1bmN0aW9uIG5lKHQpe3QucmVzdW1lKCl9ZnVuY3Rpb24gcmUodCwuLi5lKXtjb25zdCBuPXt9O2xldCByO2ZvcihyIGluIHQpZS5pbmNsdWRlcyhyKXx8KG5bcl09dFtyXSk7cmV0dXJuIG59Y29uc3Qgb2U9MzI3Njg7ZnVuY3Rpb24gc2UodCl7cmV0dXJuIHQucmVwbGFjZSgvXltBLVpdOi8sIiIpLnJlcGxhY2UoL1xcL2csIi8iKX1jb25zdCBpZT1uO2xldCBjZSx1ZT0hMTtmdW5jdGlvbiBhZSh0KXtpZS5kZWJ1ZyYmY29uc29sZS5sb2coYFtBTlIgV29ya2VyXSAke3R9YCl9dmFyIGZlLGhlLHBlO2NvbnN0IGxlPWZ1bmN0aW9uKHQpe2xldCBlO3RyeXtlPW5ldyBVUkwodC51cmwpfWNhdGNoKGUpe3JldHVybiB4KCgoKT0+e2NvbnNvbGUud2FybigiW0BzZW50cnkvbm9kZV06IEludmFsaWQgZHNuIG9yIHR1bm5lbCBvcHRpb24sIHdpbGwgbm90IHNlbmQgYW55IGV2ZW50cy4gVGhlIHR1bm5lbCBvcHRpb24gbXVzdCBiZSBhIGZ1bGwgVVJMIHdoZW4gdXNlZC4iKX0pKSxGdCh0LCgoKT0+UHJvbWlzZS5yZXNvbHZlKHt9KSkpfWNvbnN0IG49Imh0dHBzOiI9PT1lLnByb3RvY29sLHI9ZnVuY3Rpb24odCxlKXtjb25zdHtub19wcm94eTpufT1wcm9jZXNzLmVudjtyZXR1cm4gbiYmbi5zcGxpdCgiLCIpLnNvbWUoKGU9PnQuaG9zdC5lbmRzV2l0aChlKXx8dC5ob3N0bmFtZS5lbmRzV2l0aChlKSkpP3ZvaWQgMDplfShlLHQucHJveHl8fChuP3Byb2Nlc3MuZW52Lmh0dHBzX3Byb3h5OnZvaWQgMCl8fHByb2Nlc3MuZW52Lmh0dHBfcHJveHkpLG89bj9pOnMsYT12b2lkIDAhPT10LmtlZXBBbGl2ZSYmdC5rZWVwQWxpdmUsZj1yP25ldyBlZShyKTpuZXcgby5BZ2VudCh7a2VlcEFsaXZlOmEsbWF4U29ja2V0czozMCx0aW1lb3V0OjJlM30pO3JldHVybiB6dCgoKCk9Pntjb25zdCBlPWZ1bmN0aW9uKHQsZSxuKXtjb25zdHtob3N0bmFtZTpyLHBhdGhuYW1lOm8scG9ydDpzLHByb3RvY29sOmksc2VhcmNoOmF9PW5ldyBVUkwodC51cmwpO3JldHVybiBmdW5jdGlvbihmKXtyZXR1cm4gbmV3IFByb21pc2UoKChoLHApPT57bGV0IGw9ZnVuY3Rpb24odCl7cmV0dXJuIG5ldyBjKHtyZWFkKCl7dGhpcy5wdXNoKHQpLHRoaXMucHVzaChudWxsKX19KX0oZi5ib2R5KTtjb25zdCBkPXsuLi50LmhlYWRlcnN9O2YuYm9keS5sZW5ndGg+b2UmJihkWyJjb250ZW50LWVuY29kaW5nIl09Imd6aXAiLGw9bC5waXBlKHUoKSkpO2NvbnN0IG09ZS5yZXF1ZXN0KHttZXRob2Q6IlBPU1QiLGFnZW50Om4saGVhZGVyczpkLGhvc3RuYW1lOnIscGF0aDpgJHtvfSR7YX1gLHBvcnQ6cyxwcm90b2NvbDppLGNhOnQuY2FDZXJ0c30sKHQ9Pnt0Lm9uKCJkYXRhIiwoKCk9Pnt9KSksdC5vbigiZW5kIiwoKCk9Pnt9KSksdC5zZXRFbmNvZGluZygidXRmOCIpO2NvbnN0IGU9dC5oZWFkZXJzWyJyZXRyeS1hZnRlciJdPz9udWxsLG49dC5oZWFkZXJzWyJ4LXNlbnRyeS1yYXRlLWxpbWl0cyJdPz9udWxsO2goe3N0YXR1c0NvZGU6dC5zdGF0dXNDb2RlLGhlYWRlcnM6eyJyZXRyeS1hZnRlciI6ZSwieC1zZW50cnktcmF0ZS1saW1pdHMiOkFycmF5LmlzQXJyYXkobik/blswXTpufX0pfSkpO20ub24oImVycm9yIixwKSxsLnBpcGUobSl9KSl9fSh0LHQuaHR0cE1vZHVsZT8/byxmKTtyZXR1cm4gRnQodCxlKX0pKX0oe3VybDooZmU9aWUuZHNuLGhlPWllLnR1bm5lbCxwZT1pZS5zZGtNZXRhZGF0YS5zZGssaGV8fGAke2Z1bmN0aW9uKHQpe3JldHVybmAke2Z1bmN0aW9uKHQpe2NvbnN0IGU9dC5wcm90b2NvbD9gJHt0LnByb3RvY29sfTpgOiIiLG49dC5wb3J0P2A6JHt0LnBvcnR9YDoiIjtyZXR1cm5gJHtlfS8vJHt0Lmhvc3R9JHtufSR7dC5wYXRoP2AvJHt0LnBhdGh9YDoiIn0vYXBpL2B9KHQpfSR7dC5wcm9qZWN0SWR9L2VudmVsb3BlL2B9KGZlKX0/JHtZdChmZSxwZSl9YCkscmVjb3JkRHJvcHBlZEV2ZW50OigpPT57fX0pO2FzeW5jIGZ1bmN0aW9uIGRlKCl7aWYoY2Upe2FlKCJTZW5kaW5nIGFibm9ybWFsIHNlc3Npb24iKSxodChjZSx7c3RhdHVzOiJhYm5vcm1hbCIsYWJub3JtYWxfbWVjaGFuaXNtOiJhbnJfZm9yZWdyb3VuZCJ9KTtjb25zdCB0PWZ1bmN0aW9uKHQsZSxuLHIpe2NvbnN0IG89b3Qobik7cmV0dXJuIFEoe3NlbnRfYXQ6KG5ldyBEYXRlKS50b0lTT1N0cmluZygpLC4uLm8mJntzZGs6b30sLi4uISFyJiZlJiZ7ZHNuOmsoZSl9fSxbImFnZ3JlZ2F0ZXMiaW4gdD9be3R5cGU6InNlc3Npb25zIn0sdF06W3t0eXBlOiJzZXNzaW9uIn0sdC50b0pTT04oKV1dKX0oY2UsaWUuZHNuLGllLnNka01ldGFkYXRhLGllLnR1bm5lbCk7YWUoSlNPTi5zdHJpbmdpZnkodCkpLGF3YWl0IGxlLnNlbmQodCk7dHJ5e2U/LnBvc3RNZXNzYWdlKCJzZXNzaW9uLWVuZGVkIil9Y2F0Y2godCl7fX19ZnVuY3Rpb24gbWUodCl7aWYoIXQpcmV0dXJuO2NvbnN0IGU9ZnVuY3Rpb24odCl7aWYoIXQubGVuZ3RoKXJldHVybltdO2NvbnN0IGU9QXJyYXkuZnJvbSh0KTtyZXR1cm4vc2VudHJ5V3JhcHBlZC8udGVzdChlW2UubGVuZ3RoLTFdLmZ1bmN0aW9ufHwiIikmJmUucG9wKCksZS5yZXZlcnNlKCksUC50ZXN0KGVbZS5sZW5ndGgtMV0uZnVuY3Rpb258fCIiKSYmKGUucG9wKCksUC50ZXN0KGVbZS5sZW5ndGgtMV0uZnVuY3Rpb258fCIiKSYmZS5wb3AoKSksZS5zbGljZSgwLEEpLm1hcCgodD0+KHsuLi50LGZpbGVuYW1lOnQuZmlsZW5hbWV8fGVbZS5sZW5ndGgtMV0uZmlsZW5hbWUsZnVuY3Rpb246dC5mdW5jdGlvbnx8SX0pKSl9KHQpO2lmKGllLmFwcFJvb3RQYXRoKWZvcihjb25zdCB0IG9mIGUpdC5maWxlbmFtZSYmKHQuZmlsZW5hbWU9Ryh0LmZpbGVuYW1lLGllLmFwcFJvb3RQYXRoKSk7cmV0dXJuIGV9YXN5bmMgZnVuY3Rpb24gZ2UodCxlKXtpZih1ZSlyZXR1cm47dWU9ITAsYXdhaXQgZGUoKSxhZSgiU2VuZGluZyBldmVudCIpO2NvbnN0IG49e2V2ZW50X2lkOk0oKSxjb250ZXh0czppZS5jb250ZXh0cyxyZWxlYXNlOmllLnJlbGVhc2UsZW52aXJvbm1lbnQ6aWUuZW52aXJvbm1lbnQsZGlzdDppZS5kaXN0LHBsYXRmb3JtOiJub2RlIixsZXZlbDoiZXJyb3IiLGV4Y2VwdGlvbjp7dmFsdWVzOlt7dHlwZToiQXBwbGljYXRpb25Ob3RSZXNwb25kaW5nIix2YWx1ZTpgQXBwbGljYXRpb24gTm90IFJlc3BvbmRpbmcgZm9yIGF0IGxlYXN0ICR7aWUuYW5yVGhyZXNob2xkfSBtc2Asc3RhY2t0cmFjZTp7ZnJhbWVzOm1lKHQpfSxtZWNoYW5pc206e3R5cGU6IkFOUiJ9fV19LHRhZ3M6aWUuc3RhdGljVGFnc307ZSYmZnVuY3Rpb24odCxlKXtpZihIdCh0LGUpLCF0LmNvbnRleHRzPy50cmFjZSl7Y29uc3R7dHJhY2VJZDpuLHNwYW5JZDpyLHBhcmVudFNwYW5JZDpvfT1lLnByb3BhZ2F0aW9uQ29udGV4dDt0LmNvbnRleHRzPXt0cmFjZTp7dHJhY2VfaWQ6bixzcGFuX2lkOnIscGFyZW50X3NwYW5faWQ6b30sLi4udC5jb250ZXh0c319fShuLGUpO2NvbnN0IHI9R3QobixpZS5kc24saWUuc2RrTWV0YWRhdGEsaWUudHVubmVsKTthZShKU09OLnN0cmluZ2lmeShyKSksYXdhaXQgbGUuc2VuZChyKSxhd2FpdCBsZS5mbHVzaCgyZTMpLHNldFRpbWVvdXQoKCgpPT57cHJvY2Vzcy5leGl0KDApfSksNWUzKX1sZXQgeWU7aWYoYWUoIlN0YXJ0ZWQiKSxpZS5jYXB0dXJlU3RhY2tUcmFjZSl7YWUoIkNvbm5lY3RpbmcgdG8gZGVidWdnZXIiKTtjb25zdCBlPW5ldyB0O2UuY29ubmVjdFRvTWFpblRocmVhZCgpLGFlKCJDb25uZWN0ZWQgdG8gZGVidWdnZXIiKTtjb25zdCBuPW5ldyBNYXA7ZS5vbigiRGVidWdnZXIuc2NyaXB0UGFyc2VkIiwodD0+e24uc2V0KHQucGFyYW1zLnNjcmlwdElkLHQucGFyYW1zLnVybCl9KSksZS5vbigiRGVidWdnZXIucGF1c2VkIiwodD0+e2lmKCJvdGhlciI9PT10LnBhcmFtcy5yZWFzb24pdHJ5e2FlKCJEZWJ1Z2dlciBwYXVzZWQiKTtjb25zdCBzPVsuLi50LnBhcmFtcy5jYWxsRnJhbWVzXSxpPWllLmFwcFJvb3RQYXRoP2Z1bmN0aW9uKHQ9KHByb2Nlc3MuYXJndlsxXT96KHByb2Nlc3MuYXJndlsxXSk6cHJvY2Vzcy5jd2QoKSksZT0iXFwiPT09byl7Y29uc3Qgbj1lP3NlKHQpOnQ7cmV0dXJuIHQ9PntpZighdClyZXR1cm47Y29uc3Qgbz1lP3NlKHQpOnQ7bGV0e2RpcjpzLGJhc2U6aSxleHQ6Y309ci5wYXJzZShvKTsiLmpzIiE9PWMmJiIubWpzIiE9PWMmJiIuY2pzIiE9PWN8fChpPWkuc2xpY2UoMCwtMSpjLmxlbmd0aCkpLHN8fChzPSIuIik7Y29uc3QgdT1zLmxhc3RJbmRleE9mKCIvbm9kZV9tb2R1bGVzIik7aWYodT4tMSlyZXR1cm5gJHtzLnNsaWNlKHUrMTQpLnJlcGxhY2UoL1wvL2csIi4iKX06JHtpfWA7aWYocy5zdGFydHNXaXRoKG4pKXtsZXQgdD1zLnNsaWNlKG4ubGVuZ3RoKzEpLnJlcGxhY2UoL1wvL2csIi4iKTtyZXR1cm4gdCYmKHQrPSI6IiksdCs9aSx0fXJldHVybiBpfX0oaWUuYXBwUm9vdFBhdGgpOigpPT57fSxjPXMubWFwKCh0PT5mdW5jdGlvbih0LGUsbil7Y29uc3Qgcj1lP2UucmVwbGFjZSgvXmZpbGU6XC9cLy8sIiIpOnZvaWQgMCxvPXQubG9jYXRpb24uY29sdW1uTnVtYmVyP3QubG9jYXRpb24uY29sdW1uTnVtYmVyKzE6dm9pZCAwLHM9dC5sb2NhdGlvbi5saW5lTnVtYmVyP3QubG9jYXRpb24ubGluZU51bWJlcisxOnZvaWQgMDtyZXR1cm4gaih7ZmlsZW5hbWU6cixtb2R1bGU6bihyKSxmdW5jdGlvbjp0LmZ1bmN0aW9uTmFtZXx8SSxjb2xubzpvLGxpbmVubzpzLGluX2FwcDpyP0Yocik6dm9pZCAwfSl9KHQsbi5nZXQodC5sb2NhdGlvbi5zY3JpcHRJZCksaSkpKSx1PXNldFRpbWVvdXQoKCgpPT57Z2UoYykudGhlbihudWxsLCgoKT0+e2FlKCJTZW5kaW5nIEFOUiBldmVudCBmYWlsZWQuIil9KSl9KSw1ZTMpO2UucG9zdCgiUnVudGltZS5ldmFsdWF0ZSIse2V4cHJlc3Npb246Imdsb2JhbC5fX1NFTlRSWV9HRVRfU0NPUEVTX18oKTsiLHNpbGVudDohMCxyZXR1cm5CeVZhbHVlOiEwfSwoKHQsbik9Pnt0JiZhZShgRXJyb3IgZXhlY3V0aW5nIHNjcmlwdDogJyR7dC5tZXNzYWdlfSdgKSxjbGVhclRpbWVvdXQodSk7Y29uc3Qgcj1uJiZuLnJlc3VsdD9uLnJlc3VsdC52YWx1ZTp2b2lkIDA7ZS5wb3N0KCJEZWJ1Z2dlci5yZXN1bWUiKSxlLnBvc3QoIkRlYnVnZ2VyLmRpc2FibGUiKSxnZShjLHIpLnRoZW4obnVsbCwoKCk9PnthZSgiU2VuZGluZyBBTlIgZXZlbnQgZmFpbGVkLiIpfSkpfSkpfWNhdGNoKHQpe3Rocm93IGUucG9zdCgiRGVidWdnZXIucmVzdW1lIiksZS5wb3N0KCJEZWJ1Z2dlci5kaXNhYmxlIiksdH19KSkseWU9KCk9Pnt0cnl7ZS5wb3N0KCJEZWJ1Z2dlci5lbmFibGUiLCgoKT0+e2UucG9zdCgiRGVidWdnZXIucGF1c2UiKX0pKX1jYXRjaCh0KXt9fX1jb25zdHtwb2xsOmJlfT1mdW5jdGlvbih0LGUsbixyKXtjb25zdCBvPXQoKTtsZXQgcz0hMSxpPSEwO3JldHVybiBzZXRJbnRlcnZhbCgoKCk9Pntjb25zdCB0PW8uZ2V0VGltZU1zKCk7ITE9PT1zJiZ0PmUrbiYmKHM9ITAsaSYmcigpKSx0PGUrbiYmKHM9ITEpfSksMjApLHtwb2xsOigpPT57by5yZXNldCgpfSxlbmFibGVkOnQ9PntpPXR9fX0oKGZ1bmN0aW9uKCl7bGV0IHQ9cHJvY2Vzcy5ocnRpbWUoKTtyZXR1cm57Z2V0VGltZU1zOigpPT57Y29uc3RbZSxuXT1wcm9jZXNzLmhydGltZSh0KTtyZXR1cm4gTWF0aC5mbG9vcigxZTMqZStuLzFlNil9LHJlc2V0OigpPT57dD1wcm9jZXNzLmhydGltZSgpfX19KSxpZS5wb2xsSW50ZXJ2YWwsaWUuYW5yVGhyZXNob2xkLChmdW5jdGlvbigpe2FlKCJXYXRjaGRvZyB0aW1lb3V0IikseWU/KGFlKCJQYXVzaW5nIGRlYnVnZ2VyIHRvIGNhcHR1cmUgc3RhY2sgdHJhY2UiKSx5ZSgpKTooYWUoIkNhcHR1cmluZyBldmVudCB3aXRob3V0IGEgc3RhY2sgdHJhY2UiKSxnZSgpLnRoZW4obnVsbCwoKCk9PnthZSgiU2VuZGluZyBBTlIgZXZlbnQgZmFpbGVkIG9uIHdhdGNoZG9nIHRpbWVvdXQuIil9KSkpfSkpO2U/Lm9uKCJtZXNzYWdlIiwodD0+e3Quc2Vzc2lvbiYmKGNlPWZ0KHQuc2Vzc2lvbikpLGJlKCl9KSk7';
|
|
1792
1795
|
|
|
1793
1796
|
const DEFAULT_INTERVAL = 50;
|
|
1794
1797
|
const DEFAULT_HANG_THRESHOLD = 5000;
|
|
@@ -1827,7 +1830,7 @@ async function getContexts(client) {
|
|
|
1827
1830
|
event = await processor(event, eventHint);
|
|
1828
1831
|
}
|
|
1829
1832
|
|
|
1830
|
-
return _optionalChain$
|
|
1833
|
+
return _optionalChain$9([event, 'optionalAccess', _2 => _2.contexts]) || {};
|
|
1831
1834
|
}
|
|
1832
1835
|
|
|
1833
1836
|
const INTEGRATION_NAME$1 = 'Anr';
|
|
@@ -1980,7 +1983,7 @@ async function _startWorker(
|
|
|
1980
1983
|
};
|
|
1981
1984
|
}
|
|
1982
1985
|
|
|
1983
|
-
function _optionalChain$
|
|
1986
|
+
function _optionalChain$8(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
1984
1987
|
|
|
1985
1988
|
const _expressIntegration = (() => {
|
|
1986
1989
|
return {
|
|
@@ -2031,7 +2034,7 @@ function expressErrorHandler(options
|
|
|
2031
2034
|
res,
|
|
2032
2035
|
next,
|
|
2033
2036
|
) {
|
|
2034
|
-
const shouldHandleError = _optionalChain$
|
|
2037
|
+
const shouldHandleError = _optionalChain$8([options, 'optionalAccess', _ => _.shouldHandleError]) || defaultShouldHandleError;
|
|
2035
2038
|
|
|
2036
2039
|
if (shouldHandleError(error)) {
|
|
2037
2040
|
const client = core.getClient();
|
|
@@ -2069,6 +2072,15 @@ function expressErrorHandler(options
|
|
|
2069
2072
|
*/
|
|
2070
2073
|
function setupExpressErrorHandler(app) {
|
|
2071
2074
|
app.use(expressErrorHandler());
|
|
2075
|
+
|
|
2076
|
+
if (!core$1.isWrapped(app.use)) {
|
|
2077
|
+
utils.consoleSandbox(() => {
|
|
2078
|
+
// eslint-disable-next-line no-console
|
|
2079
|
+
console.warn(
|
|
2080
|
+
'[Sentry] Express is not instrumented. This is likely because you required/imported express before calling `Sentry.init()`.',
|
|
2081
|
+
);
|
|
2082
|
+
});
|
|
2083
|
+
}
|
|
2072
2084
|
}
|
|
2073
2085
|
|
|
2074
2086
|
function getStatusCodeFromResponse(error) {
|
|
@@ -2082,7 +2094,7 @@ function defaultShouldHandleError(error) {
|
|
|
2082
2094
|
return status >= 500;
|
|
2083
2095
|
}
|
|
2084
2096
|
|
|
2085
|
-
function _optionalChain$
|
|
2097
|
+
function _optionalChain$7(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2086
2098
|
const _fastifyIntegration = (() => {
|
|
2087
2099
|
return {
|
|
2088
2100
|
name: 'Fastify',
|
|
@@ -2125,8 +2137,8 @@ function setupFastifyErrorHandler(fastify) {
|
|
|
2125
2137
|
|
|
2126
2138
|
// Taken from Otel Fastify instrumentation:
|
|
2127
2139
|
// https://github.com/open-telemetry/opentelemetry-js-contrib/blob/main/plugins/node/opentelemetry-instrumentation-fastify/src/instrumentation.ts#L94-L96
|
|
2128
|
-
const routeName = _optionalChain$
|
|
2129
|
-
const method = _optionalChain$
|
|
2140
|
+
const routeName = _optionalChain$7([reqWithRouteInfo, 'access', _ => _.routeOptions, 'optionalAccess', _2 => _2.url]) || reqWithRouteInfo.routerPath;
|
|
2141
|
+
const method = _optionalChain$7([reqWithRouteInfo, 'access', _3 => _3.routeOptions, 'optionalAccess', _4 => _4.method]) || 'GET';
|
|
2130
2142
|
|
|
2131
2143
|
core.getIsolationScope().setTransactionName(`${method} ${routeName}`);
|
|
2132
2144
|
});
|
|
@@ -2140,6 +2152,15 @@ function setupFastifyErrorHandler(fastify) {
|
|
|
2140
2152
|
);
|
|
2141
2153
|
|
|
2142
2154
|
fastify.register(plugin);
|
|
2155
|
+
|
|
2156
|
+
if (!core$1.isWrapped(fastify.addHook)) {
|
|
2157
|
+
utils.consoleSandbox(() => {
|
|
2158
|
+
// eslint-disable-next-line no-console
|
|
2159
|
+
console.warn(
|
|
2160
|
+
'[Sentry] Fastify is not instrumented. This is likely because you required/imported fastify before calling `Sentry.init()`.',
|
|
2161
|
+
);
|
|
2162
|
+
});
|
|
2163
|
+
}
|
|
2143
2164
|
}
|
|
2144
2165
|
|
|
2145
2166
|
const _graphqlIntegration = (() => {
|
|
@@ -2268,7 +2289,7 @@ const _redisIntegration = (() => {
|
|
|
2268
2289
|
*/
|
|
2269
2290
|
const redisIntegration = core.defineIntegration(_redisIntegration);
|
|
2270
2291
|
|
|
2271
|
-
function _optionalChain$
|
|
2292
|
+
function _optionalChain$6(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2272
2293
|
const _nestIntegration = (() => {
|
|
2273
2294
|
return {
|
|
2274
2295
|
name: 'Nest',
|
|
@@ -2299,7 +2320,7 @@ function setupNestErrorHandler(app, baseFilter) {
|
|
|
2299
2320
|
if (context.getType() === 'http') {
|
|
2300
2321
|
const req = context.switchToHttp().getRequest();
|
|
2301
2322
|
if (req.route) {
|
|
2302
|
-
core.getIsolationScope().setTransactionName(`${_optionalChain$
|
|
2323
|
+
core.getIsolationScope().setTransactionName(`${_optionalChain$6([req, 'access', _ => _.method, 'optionalAccess', _2 => _2.toUpperCase, 'call', _3 => _3()]) || 'GET'} ${req.route.path}`);
|
|
2303
2324
|
}
|
|
2304
2325
|
}
|
|
2305
2326
|
|
|
@@ -2347,7 +2368,7 @@ const _postgresIntegration = (() => {
|
|
|
2347
2368
|
*/
|
|
2348
2369
|
const postgresIntegration = core.defineIntegration(_postgresIntegration);
|
|
2349
2370
|
|
|
2350
|
-
function _optionalChain$
|
|
2371
|
+
function _optionalChain$5(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }// When importing CJS modules into an ESM module, we cannot import the named exports directly.
|
|
2351
2372
|
|
|
2352
2373
|
const _prismaIntegration = (() => {
|
|
2353
2374
|
return {
|
|
@@ -2362,7 +2383,7 @@ const _prismaIntegration = (() => {
|
|
|
2362
2383
|
setup(client) {
|
|
2363
2384
|
client.on('spanStart', span => {
|
|
2364
2385
|
const spanJSON = core.spanToJSON(span);
|
|
2365
|
-
if (_optionalChain$
|
|
2386
|
+
if (_optionalChain$5([spanJSON, 'access', _ => _.description, 'optionalAccess', _2 => _2.startsWith, 'call', _3 => _3('prisma:')])) {
|
|
2366
2387
|
span.setAttribute(core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.otel.prisma');
|
|
2367
2388
|
}
|
|
2368
2389
|
|
|
@@ -2385,7 +2406,7 @@ const _prismaIntegration = (() => {
|
|
|
2385
2406
|
*/
|
|
2386
2407
|
const prismaIntegration = core.defineIntegration(_prismaIntegration);
|
|
2387
2408
|
|
|
2388
|
-
function _optionalChain$
|
|
2409
|
+
function _optionalChain$4(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2389
2410
|
const _hapiIntegration = (() => {
|
|
2390
2411
|
return {
|
|
2391
2412
|
name: 'Hapi',
|
|
@@ -2434,7 +2455,7 @@ const hapiErrorPlugin = {
|
|
|
2434
2455
|
if (core.getIsolationScope() !== core.getDefaultIsolationScope()) {
|
|
2435
2456
|
const route = request.route;
|
|
2436
2457
|
if (route && route.path) {
|
|
2437
|
-
core.getIsolationScope().setTransactionName(`${_optionalChain$
|
|
2458
|
+
core.getIsolationScope().setTransactionName(`${_optionalChain$4([route, 'access', _ => _.method, 'optionalAccess', _2 => _2.toUpperCase, 'call', _3 => _3()]) || 'GET'} ${route.path}`);
|
|
2438
2459
|
}
|
|
2439
2460
|
} else {
|
|
2440
2461
|
DEBUG_BUILD &&
|
|
@@ -2463,6 +2484,16 @@ const hapiErrorPlugin = {
|
|
|
2463
2484
|
*/
|
|
2464
2485
|
async function setupHapiErrorHandler(server) {
|
|
2465
2486
|
await server.register(hapiErrorPlugin);
|
|
2487
|
+
|
|
2488
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
2489
|
+
if (!core$1.isWrapped(server.register)) {
|
|
2490
|
+
utils.consoleSandbox(() => {
|
|
2491
|
+
// eslint-disable-next-line no-console
|
|
2492
|
+
console.warn(
|
|
2493
|
+
'[Sentry] Hapi is not instrumented. This is likely because you required/imported hapi before calling `Sentry.init()`.',
|
|
2494
|
+
);
|
|
2495
|
+
});
|
|
2496
|
+
}
|
|
2466
2497
|
}
|
|
2467
2498
|
|
|
2468
2499
|
const _koaIntegration = (() => {
|
|
@@ -2501,6 +2532,15 @@ const setupKoaErrorHandler = (app) => {
|
|
|
2501
2532
|
core.captureException(error);
|
|
2502
2533
|
}
|
|
2503
2534
|
});
|
|
2535
|
+
|
|
2536
|
+
if (!core$1.isWrapped(app.use)) {
|
|
2537
|
+
utils.consoleSandbox(() => {
|
|
2538
|
+
// eslint-disable-next-line no-console
|
|
2539
|
+
console.warn(
|
|
2540
|
+
'[Sentry] Koa is not instrumented. This is likely because you required/imported koa before calling `Sentry.init()`.',
|
|
2541
|
+
);
|
|
2542
|
+
});
|
|
2543
|
+
}
|
|
2504
2544
|
};
|
|
2505
2545
|
|
|
2506
2546
|
const _connectIntegration = (() => {
|
|
@@ -2522,6 +2562,15 @@ function connectErrorMiddleware(err, req, res, next) {
|
|
|
2522
2562
|
|
|
2523
2563
|
const setupConnectErrorHandler = (app) => {
|
|
2524
2564
|
app.use(connectErrorMiddleware);
|
|
2565
|
+
|
|
2566
|
+
if (!core$1.isWrapped(app.use)) {
|
|
2567
|
+
utils.consoleSandbox(() => {
|
|
2568
|
+
// eslint-disable-next-line no-console
|
|
2569
|
+
console.warn(
|
|
2570
|
+
'[Sentry] Connect is not instrumented. This is likely because you required/imported connect before calling `Sentry.init()`.',
|
|
2571
|
+
);
|
|
2572
|
+
});
|
|
2573
|
+
}
|
|
2525
2574
|
};
|
|
2526
2575
|
|
|
2527
2576
|
const INTEGRATION_NAME = 'Spotlight';
|
|
@@ -2862,7 +2911,7 @@ function parseProxyResponse(socket) {
|
|
|
2862
2911
|
});
|
|
2863
2912
|
}
|
|
2864
2913
|
|
|
2865
|
-
function _nullishCoalesce$1(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }function _optionalChain$
|
|
2914
|
+
function _nullishCoalesce$1(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }function _optionalChain$3(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
2866
2915
|
|
|
2867
2916
|
function debug(...args) {
|
|
2868
2917
|
utils.logger.log('[https-proxy-agent]', ...args);
|
|
@@ -2887,7 +2936,7 @@ class HttpsProxyAgent extends Agent {
|
|
|
2887
2936
|
super(opts);
|
|
2888
2937
|
this.options = {};
|
|
2889
2938
|
this.proxy = typeof proxy === 'string' ? new URL(proxy) : proxy;
|
|
2890
|
-
this.proxyHeaders = _nullishCoalesce$1(_optionalChain$
|
|
2939
|
+
this.proxyHeaders = _nullishCoalesce$1(_optionalChain$3([opts, 'optionalAccess', _2 => _2.headers]), () => ( {}));
|
|
2891
2940
|
debug('Creating new HttpsProxyAgent instance: %o', this.proxy.href);
|
|
2892
2941
|
|
|
2893
2942
|
// Trim off the brackets from IPv6 addresses
|
|
@@ -3266,7 +3315,7 @@ function getSentryRelease(fallback) {
|
|
|
3266
3315
|
/** Node.js stack parser */
|
|
3267
3316
|
const defaultStackParser = utils.createStackParser(utils.nodeStackLineParser(createGetModuleFromFilename()));
|
|
3268
3317
|
|
|
3269
|
-
function _optionalChain$
|
|
3318
|
+
function _optionalChain$2(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
3270
3319
|
/** A client for using Sentry with Node & OpenTelemetry. */
|
|
3271
3320
|
class NodeClient extends core.ServerRuntimeClient {
|
|
3272
3321
|
|
|
@@ -3302,7 +3351,7 @@ class NodeClient extends core.ServerRuntimeClient {
|
|
|
3302
3351
|
*/
|
|
3303
3352
|
async flush(timeout) {
|
|
3304
3353
|
const provider = this.traceProvider;
|
|
3305
|
-
const spanProcessor = _optionalChain$
|
|
3354
|
+
const spanProcessor = _optionalChain$2([provider, 'optionalAccess', _ => _.activeSpanProcessor]);
|
|
3306
3355
|
|
|
3307
3356
|
if (spanProcessor) {
|
|
3308
3357
|
await spanProcessor.forceFlush();
|
|
@@ -3416,13 +3465,27 @@ function init(options = {}) {
|
|
|
3416
3465
|
}
|
|
3417
3466
|
|
|
3418
3467
|
if (!isCjs()) {
|
|
3419
|
-
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3468
|
+
const [nodeMajor, nodeMinor] = process.versions.node.split('.').map(Number);
|
|
3469
|
+
|
|
3470
|
+
// Register hook was added in v20.6.0 and v18.19.0
|
|
3471
|
+
if (nodeMajor >= 22 || (nodeMajor === 20 && nodeMinor >= 6) || (nodeMajor === 18 && nodeMinor >= 19)) {
|
|
3472
|
+
// We need to work around using import.meta.url directly because jest complains about it.
|
|
3473
|
+
const importMetaUrl =
|
|
3474
|
+
typeof (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)) !== 'undefined' ? (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)) : undefined;
|
|
3475
|
+
|
|
3476
|
+
if (!utils.GLOBAL_OBJ._sentryEsmLoaderHookRegistered && importMetaUrl) {
|
|
3477
|
+
// @ts-expect-error register is available in these versions
|
|
3478
|
+
moduleModule.default.register('@opentelemetry/instrumentation/hook.mjs', importMetaUrl);
|
|
3479
|
+
utils.GLOBAL_OBJ._sentryEsmLoaderHookRegistered = true;
|
|
3480
|
+
}
|
|
3481
|
+
} else {
|
|
3482
|
+
utils.consoleSandbox(() => {
|
|
3483
|
+
// eslint-disable-next-line no-console
|
|
3484
|
+
console.warn(
|
|
3485
|
+
'[Sentry] You are using Node.js in ESM mode ("import syntax"). The Sentry Node.js SDK is not compatible with ESM in Node.js versions before 18.19.0 or before 20.6.0. Please either build your application with CommonJS ("require() syntax"), or use version 7.x of the Sentry Node.js SDK.',
|
|
3486
|
+
);
|
|
3487
|
+
});
|
|
3488
|
+
}
|
|
3426
3489
|
}
|
|
3427
3490
|
|
|
3428
3491
|
opentelemetry.setOpenTelemetryContextAsyncContextStrategy();
|
|
@@ -3700,11 +3763,16 @@ function instrumentCron(lib, monitorSlug) {
|
|
|
3700
3763
|
|
|
3701
3764
|
const cronString = replaceCronNames(cronTime);
|
|
3702
3765
|
|
|
3703
|
-
function monitoredTick(context, onComplete) {
|
|
3766
|
+
async function monitoredTick(context, onComplete) {
|
|
3704
3767
|
return core.withMonitor(
|
|
3705
3768
|
monitorSlug,
|
|
3706
|
-
() => {
|
|
3707
|
-
|
|
3769
|
+
async () => {
|
|
3770
|
+
try {
|
|
3771
|
+
await onTick(context, onComplete);
|
|
3772
|
+
} catch (e) {
|
|
3773
|
+
core.captureException(e);
|
|
3774
|
+
throw e;
|
|
3775
|
+
}
|
|
3708
3776
|
},
|
|
3709
3777
|
{
|
|
3710
3778
|
schedule: { type: 'crontab', value: cronString },
|
|
@@ -3732,11 +3800,16 @@ function instrumentCron(lib, monitorSlug) {
|
|
|
3732
3800
|
|
|
3733
3801
|
const cronString = replaceCronNames(cronTime);
|
|
3734
3802
|
|
|
3735
|
-
param.onTick = (context, onComplete) => {
|
|
3803
|
+
param.onTick = async (context, onComplete) => {
|
|
3736
3804
|
return core.withMonitor(
|
|
3737
3805
|
monitorSlug,
|
|
3738
|
-
() => {
|
|
3739
|
-
|
|
3806
|
+
async () => {
|
|
3807
|
+
try {
|
|
3808
|
+
await onTick(context, onComplete);
|
|
3809
|
+
} catch (e) {
|
|
3810
|
+
core.captureException(e);
|
|
3811
|
+
throw e;
|
|
3812
|
+
}
|
|
3740
3813
|
},
|
|
3741
3814
|
{
|
|
3742
3815
|
schedule: { type: 'crontab', value: cronString },
|
|
@@ -3754,12 +3827,13 @@ function instrumentCron(lib, monitorSlug) {
|
|
|
3754
3827
|
});
|
|
3755
3828
|
}
|
|
3756
3829
|
|
|
3830
|
+
function _optionalChain$1(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
|
|
3757
3831
|
/**
|
|
3758
3832
|
* Wraps the `node-cron` library with check-in monitoring.
|
|
3759
3833
|
*
|
|
3760
3834
|
* ```ts
|
|
3761
3835
|
* import * as Sentry from "@sentry/node";
|
|
3762
|
-
* import cron from "node-cron";
|
|
3836
|
+
* import * as cron from "node-cron";
|
|
3763
3837
|
*
|
|
3764
3838
|
* const cronWithCheckIn = Sentry.cron.instrumentNodeCron(cron);
|
|
3765
3839
|
*
|
|
@@ -3779,22 +3853,33 @@ function instrumentNodeCron(lib) {
|
|
|
3779
3853
|
// When 'get' is called for schedule, return a proxied version of the schedule function
|
|
3780
3854
|
return new Proxy(target.schedule, {
|
|
3781
3855
|
apply(target, thisArg, argArray) {
|
|
3782
|
-
const [expression, , options] = argArray;
|
|
3856
|
+
const [expression, callback, options] = argArray;
|
|
3783
3857
|
|
|
3784
|
-
if (!_optionalChain([options, 'optionalAccess', _ => _.name])) {
|
|
3858
|
+
if (!_optionalChain$1([options, 'optionalAccess', _ => _.name])) {
|
|
3785
3859
|
throw new Error('Missing "name" for scheduled job. A name is required for Sentry check-in monitoring.');
|
|
3786
3860
|
}
|
|
3787
3861
|
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
|
|
3795
|
-
|
|
3796
|
-
|
|
3797
|
-
|
|
3862
|
+
async function monitoredCallback() {
|
|
3863
|
+
return core.withMonitor(
|
|
3864
|
+
options.name,
|
|
3865
|
+
async () => {
|
|
3866
|
+
// We have to manually catch here and capture the exception because node-cron swallows errors
|
|
3867
|
+
// https://github.com/node-cron/node-cron/issues/399
|
|
3868
|
+
try {
|
|
3869
|
+
return await callback();
|
|
3870
|
+
} catch (e) {
|
|
3871
|
+
core.captureException(e);
|
|
3872
|
+
throw e;
|
|
3873
|
+
}
|
|
3874
|
+
},
|
|
3875
|
+
{
|
|
3876
|
+
schedule: { type: 'crontab', value: replaceCronNames(expression) },
|
|
3877
|
+
timezone: _optionalChain$1([options, 'optionalAccess', _2 => _2.timezone]),
|
|
3878
|
+
},
|
|
3879
|
+
);
|
|
3880
|
+
}
|
|
3881
|
+
|
|
3882
|
+
return target.apply(thisArg, [expression, monitoredCallback, options]);
|
|
3798
3883
|
},
|
|
3799
3884
|
});
|
|
3800
3885
|
} else {
|
|
@@ -3825,9 +3910,13 @@ function instrumentNodeSchedule(lib) {
|
|
|
3825
3910
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
3826
3911
|
return new Proxy(target.scheduleJob, {
|
|
3827
3912
|
apply(target, thisArg, argArray) {
|
|
3828
|
-
const [nameOrExpression, expressionOrCallback] = argArray;
|
|
3913
|
+
const [nameOrExpression, expressionOrCallback, callback] = argArray;
|
|
3829
3914
|
|
|
3830
|
-
if (
|
|
3915
|
+
if (
|
|
3916
|
+
typeof nameOrExpression !== 'string' ||
|
|
3917
|
+
typeof expressionOrCallback !== 'string' ||
|
|
3918
|
+
typeof callback !== 'function'
|
|
3919
|
+
) {
|
|
3831
3920
|
throw new Error(
|
|
3832
3921
|
"Automatic instrumentation of 'node-schedule' requires the first parameter of 'scheduleJob' to be a job name string and the second parameter to be a crontab string",
|
|
3833
3922
|
);
|
|
@@ -3836,15 +3925,19 @@ function instrumentNodeSchedule(lib) {
|
|
|
3836
3925
|
const monitorSlug = nameOrExpression;
|
|
3837
3926
|
const expression = expressionOrCallback;
|
|
3838
3927
|
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3928
|
+
async function monitoredCallback() {
|
|
3929
|
+
return core.withMonitor(
|
|
3930
|
+
monitorSlug,
|
|
3931
|
+
async () => {
|
|
3932
|
+
await _optionalChain([callback, 'optionalCall', _ => _()]);
|
|
3933
|
+
},
|
|
3934
|
+
{
|
|
3935
|
+
schedule: { type: 'crontab', value: replaceCronNames(expression) },
|
|
3936
|
+
},
|
|
3937
|
+
);
|
|
3938
|
+
}
|
|
3939
|
+
|
|
3940
|
+
return target.apply(thisArg, [monitorSlug, expression, monitoredCallback]);
|
|
3848
3941
|
},
|
|
3849
3942
|
});
|
|
3850
3943
|
}
|