@sentry/node 8.0.0-alpha.2 → 8.0.0-alpha.4

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.
Files changed (228) hide show
  1. package/README.md +14 -93
  2. package/cjs/index.js +3665 -77
  3. package/cjs/index.js.map +1 -1
  4. package/esm/index.js +3614 -31
  5. package/esm/index.js.map +1 -1
  6. package/esm/integrations/anr/worker-script.js +2 -2
  7. package/esm/package.json +1 -0
  8. package/package.json +21 -6
  9. package/types/index.d.ts +6 -5
  10. package/types/index.d.ts.map +1 -1
  11. package/types/integrations/anr/worker-script.d.ts +1 -1
  12. package/types/integrations/anr/worker-script.d.ts.map +1 -1
  13. package/types/integrations/http.d.ts +4 -0
  14. package/types/integrations/http.d.ts.map +1 -1
  15. package/types/integrations/tracing/fastify.d.ts +9 -0
  16. package/types/integrations/tracing/fastify.d.ts.map +1 -1
  17. package/types/integrations/tracing/prisma.d.ts.map +1 -1
  18. package/types/proxy/helpers.d.ts +2 -2
  19. package/types/proxy/helpers.d.ts.map +1 -1
  20. package/types/proxy/index.d.ts.map +1 -1
  21. package/types/sdk/hub.d.ts.map +1 -1
  22. package/types/sdk/init.d.ts.map +1 -1
  23. package/types/transports/http-module.d.ts +2 -2
  24. package/types/transports/http-module.d.ts.map +1 -1
  25. package/types/types.d.ts +3 -4
  26. package/types/types.d.ts.map +1 -1
  27. package/types-ts3.8/index.d.ts +6 -5
  28. package/types-ts3.8/integrations/anr/worker-script.d.ts +1 -1
  29. package/types-ts3.8/integrations/http.d.ts +4 -0
  30. package/types-ts3.8/integrations/tracing/fastify.d.ts +9 -0
  31. package/types-ts3.8/proxy/helpers.d.ts +2 -2
  32. package/types-ts3.8/transports/http-module.d.ts +2 -2
  33. package/types-ts3.8/types.d.ts +3 -4
  34. package/cjs/cron/common.js +0 -56
  35. package/cjs/cron/common.js.map +0 -1
  36. package/cjs/cron/cron.js +0 -102
  37. package/cjs/cron/cron.js.map +0 -1
  38. package/cjs/cron/index.js +0 -15
  39. package/cjs/cron/index.js.map +0 -1
  40. package/cjs/cron/node-cron.js +0 -61
  41. package/cjs/cron/node-cron.js.map +0 -1
  42. package/cjs/cron/node-schedule.js +0 -57
  43. package/cjs/cron/node-schedule.js.map +0 -1
  44. package/cjs/debug-build.js +0 -11
  45. package/cjs/debug-build.js.map +0 -1
  46. package/cjs/integrations/anr/index.js +0 -144
  47. package/cjs/integrations/anr/index.js.map +0 -1
  48. package/cjs/integrations/anr/worker-script.js +0 -2
  49. package/cjs/integrations/anr/worker-script.js.map +0 -1
  50. package/cjs/integrations/console.js +0 -40
  51. package/cjs/integrations/console.js.map +0 -1
  52. package/cjs/integrations/context.js +0 -435
  53. package/cjs/integrations/context.js.map +0 -1
  54. package/cjs/integrations/contextlines.js +0 -137
  55. package/cjs/integrations/contextlines.js.map +0 -1
  56. package/cjs/integrations/http.js +0 -137
  57. package/cjs/integrations/http.js.map +0 -1
  58. package/cjs/integrations/local-variables/common.js +0 -87
  59. package/cjs/integrations/local-variables/common.js.map +0 -1
  60. package/cjs/integrations/local-variables/index.js +0 -8
  61. package/cjs/integrations/local-variables/index.js.map +0 -1
  62. package/cjs/integrations/local-variables/local-variables-sync.js +0 -385
  63. package/cjs/integrations/local-variables/local-variables-sync.js.map +0 -1
  64. package/cjs/integrations/modules.js +0 -99
  65. package/cjs/integrations/modules.js.map +0 -1
  66. package/cjs/integrations/node-fetch.js +0 -82
  67. package/cjs/integrations/node-fetch.js.map +0 -1
  68. package/cjs/integrations/onuncaughtexception.js +0 -137
  69. package/cjs/integrations/onuncaughtexception.js.map +0 -1
  70. package/cjs/integrations/onunhandledrejection.js +0 -90
  71. package/cjs/integrations/onunhandledrejection.js.map +0 -1
  72. package/cjs/integrations/spotlight.js +0 -109
  73. package/cjs/integrations/spotlight.js.map +0 -1
  74. package/cjs/integrations/tracing/express.js +0 -103
  75. package/cjs/integrations/tracing/express.js.map +0 -1
  76. package/cjs/integrations/tracing/fastify.js +0 -33
  77. package/cjs/integrations/tracing/fastify.js.map +0 -1
  78. package/cjs/integrations/tracing/graphql.js +0 -34
  79. package/cjs/integrations/tracing/graphql.js.map +0 -1
  80. package/cjs/integrations/tracing/hapi/index.js +0 -81
  81. package/cjs/integrations/tracing/hapi/index.js.map +0 -1
  82. package/cjs/integrations/tracing/index.js +0 -37
  83. package/cjs/integrations/tracing/index.js.map +0 -1
  84. package/cjs/integrations/tracing/koa.js +0 -21
  85. package/cjs/integrations/tracing/koa.js.map +0 -1
  86. package/cjs/integrations/tracing/mongo.js +0 -33
  87. package/cjs/integrations/tracing/mongo.js.map +0 -1
  88. package/cjs/integrations/tracing/mongoose.js +0 -33
  89. package/cjs/integrations/tracing/mongoose.js.map +0 -1
  90. package/cjs/integrations/tracing/mysql.js +0 -26
  91. package/cjs/integrations/tracing/mysql.js.map +0 -1
  92. package/cjs/integrations/tracing/mysql2.js +0 -33
  93. package/cjs/integrations/tracing/mysql2.js.map +0 -1
  94. package/cjs/integrations/tracing/nest.js +0 -26
  95. package/cjs/integrations/tracing/nest.js.map +0 -1
  96. package/cjs/integrations/tracing/postgres.js +0 -34
  97. package/cjs/integrations/tracing/postgres.js.map +0 -1
  98. package/cjs/integrations/tracing/prisma.js +0 -33
  99. package/cjs/integrations/tracing/prisma.js.map +0 -1
  100. package/cjs/nodeVersion.js +0 -12
  101. package/cjs/nodeVersion.js.map +0 -1
  102. package/cjs/otel/contextManager.js +0 -16
  103. package/cjs/otel/contextManager.js.map +0 -1
  104. package/cjs/proxy/base.js +0 -126
  105. package/cjs/proxy/base.js.map +0 -1
  106. package/cjs/proxy/index.js +0 -209
  107. package/cjs/proxy/index.js.map +0 -1
  108. package/cjs/proxy/parse-proxy-response.js +0 -104
  109. package/cjs/proxy/parse-proxy-response.js.map +0 -1
  110. package/cjs/sdk/api.js +0 -74
  111. package/cjs/sdk/api.js.map +0 -1
  112. package/cjs/sdk/client.js +0 -57
  113. package/cjs/sdk/client.js.map +0 -1
  114. package/cjs/sdk/hub.js +0 -104
  115. package/cjs/sdk/hub.js.map +0 -1
  116. package/cjs/sdk/init.js +0 -252
  117. package/cjs/sdk/init.js.map +0 -1
  118. package/cjs/sdk/initOtel.js +0 -70
  119. package/cjs/sdk/initOtel.js.map +0 -1
  120. package/cjs/sdk/scope.js +0 -18
  121. package/cjs/sdk/scope.js.map +0 -1
  122. package/cjs/transports/http.js +0 -160
  123. package/cjs/transports/http.js.map +0 -1
  124. package/cjs/utils/addOriginToSpan.js +0 -11
  125. package/cjs/utils/addOriginToSpan.js.map +0 -1
  126. package/cjs/utils/errorhandling.js +0 -44
  127. package/cjs/utils/errorhandling.js.map +0 -1
  128. package/cjs/utils/getRequestUrl.js +0 -18
  129. package/cjs/utils/getRequestUrl.js.map +0 -1
  130. package/cjs/utils/module.js +0 -62
  131. package/cjs/utils/module.js.map +0 -1
  132. package/esm/cron/common.js +0 -54
  133. package/esm/cron/common.js.map +0 -1
  134. package/esm/cron/cron.js +0 -100
  135. package/esm/cron/cron.js.map +0 -1
  136. package/esm/cron/index.js +0 -13
  137. package/esm/cron/index.js.map +0 -1
  138. package/esm/cron/node-cron.js +0 -56
  139. package/esm/cron/node-cron.js.map +0 -1
  140. package/esm/cron/node-schedule.js +0 -55
  141. package/esm/cron/node-schedule.js.map +0 -1
  142. package/esm/debug-build.js +0 -9
  143. package/esm/debug-build.js.map +0 -1
  144. package/esm/integrations/anr/index.js +0 -138
  145. package/esm/integrations/anr/index.js.map +0 -1
  146. package/esm/integrations/anr/worker-script.js.map +0 -1
  147. package/esm/integrations/console.js +0 -38
  148. package/esm/integrations/console.js.map +0 -1
  149. package/esm/integrations/context.js +0 -427
  150. package/esm/integrations/context.js.map +0 -1
  151. package/esm/integrations/contextlines.js +0 -131
  152. package/esm/integrations/contextlines.js.map +0 -1
  153. package/esm/integrations/http.js +0 -132
  154. package/esm/integrations/http.js.map +0 -1
  155. package/esm/integrations/local-variables/common.js +0 -81
  156. package/esm/integrations/local-variables/common.js.map +0 -1
  157. package/esm/integrations/local-variables/index.js +0 -6
  158. package/esm/integrations/local-variables/index.js.map +0 -1
  159. package/esm/integrations/local-variables/local-variables-sync.js +0 -379
  160. package/esm/integrations/local-variables/local-variables-sync.js.map +0 -1
  161. package/esm/integrations/modules.js +0 -97
  162. package/esm/integrations/modules.js.map +0 -1
  163. package/esm/integrations/node-fetch.js +0 -80
  164. package/esm/integrations/node-fetch.js.map +0 -1
  165. package/esm/integrations/onuncaughtexception.js +0 -134
  166. package/esm/integrations/onuncaughtexception.js.map +0 -1
  167. package/esm/integrations/onunhandledrejection.js +0 -87
  168. package/esm/integrations/onunhandledrejection.js.map +0 -1
  169. package/esm/integrations/spotlight.js +0 -106
  170. package/esm/integrations/spotlight.js.map +0 -1
  171. package/esm/integrations/tracing/express.js +0 -96
  172. package/esm/integrations/tracing/express.js.map +0 -1
  173. package/esm/integrations/tracing/fastify.js +0 -31
  174. package/esm/integrations/tracing/fastify.js.map +0 -1
  175. package/esm/integrations/tracing/graphql.js +0 -32
  176. package/esm/integrations/tracing/graphql.js.map +0 -1
  177. package/esm/integrations/tracing/hapi/index.js +0 -77
  178. package/esm/integrations/tracing/hapi/index.js.map +0 -1
  179. package/esm/integrations/tracing/index.js +0 -35
  180. package/esm/integrations/tracing/index.js.map +0 -1
  181. package/esm/integrations/tracing/koa.js +0 -19
  182. package/esm/integrations/tracing/koa.js.map +0 -1
  183. package/esm/integrations/tracing/mongo.js +0 -31
  184. package/esm/integrations/tracing/mongo.js.map +0 -1
  185. package/esm/integrations/tracing/mongoose.js +0 -31
  186. package/esm/integrations/tracing/mongoose.js.map +0 -1
  187. package/esm/integrations/tracing/mysql.js +0 -24
  188. package/esm/integrations/tracing/mysql.js.map +0 -1
  189. package/esm/integrations/tracing/mysql2.js +0 -31
  190. package/esm/integrations/tracing/mysql2.js.map +0 -1
  191. package/esm/integrations/tracing/nest.js +0 -24
  192. package/esm/integrations/tracing/nest.js.map +0 -1
  193. package/esm/integrations/tracing/postgres.js +0 -32
  194. package/esm/integrations/tracing/postgres.js.map +0 -1
  195. package/esm/integrations/tracing/prisma.js +0 -31
  196. package/esm/integrations/tracing/prisma.js.map +0 -1
  197. package/esm/nodeVersion.js +0 -9
  198. package/esm/nodeVersion.js.map +0 -1
  199. package/esm/otel/contextManager.js +0 -14
  200. package/esm/otel/contextManager.js.map +0 -1
  201. package/esm/proxy/base.js +0 -121
  202. package/esm/proxy/base.js.map +0 -1
  203. package/esm/proxy/index.js +0 -203
  204. package/esm/proxy/index.js.map +0 -1
  205. package/esm/proxy/parse-proxy-response.js +0 -102
  206. package/esm/proxy/parse-proxy-response.js.map +0 -1
  207. package/esm/sdk/api.js +0 -69
  208. package/esm/sdk/api.js.map +0 -1
  209. package/esm/sdk/client.js +0 -52
  210. package/esm/sdk/client.js.map +0 -1
  211. package/esm/sdk/hub.js +0 -102
  212. package/esm/sdk/hub.js.map +0 -1
  213. package/esm/sdk/init.js +0 -249
  214. package/esm/sdk/init.js.map +0 -1
  215. package/esm/sdk/initOtel.js +0 -67
  216. package/esm/sdk/initOtel.js.map +0 -1
  217. package/esm/sdk/scope.js +0 -16
  218. package/esm/sdk/scope.js.map +0 -1
  219. package/esm/transports/http.js +0 -155
  220. package/esm/transports/http.js.map +0 -1
  221. package/esm/utils/addOriginToSpan.js +0 -9
  222. package/esm/utils/addOriginToSpan.js.map +0 -1
  223. package/esm/utils/errorhandling.js +0 -42
  224. package/esm/utils/errorhandling.js.map +0 -1
  225. package/esm/utils/getRequestUrl.js +0 -16
  226. package/esm/utils/getRequestUrl.js.map +0 -1
  227. package/esm/utils/module.js +0 -60
  228. package/esm/utils/module.js.map +0 -1
@@ -1,144 +0,0 @@
1
- var {
2
- _optionalChain,
3
- _optionalChainDelete
4
- } = require('@sentry/utils');
5
-
6
- Object.defineProperty(exports, '__esModule', { value: true });
7
-
8
- const core = require('@sentry/core');
9
- const utils = require('@sentry/utils');
10
- const inspector = require('inspector');
11
- const worker_threads = require('worker_threads');
12
- const nodeVersion = require('../../nodeVersion.js');
13
- const workerScript = require('./worker-script.js');
14
-
15
- const DEFAULT_INTERVAL = 50;
16
- const DEFAULT_HANG_THRESHOLD = 5000;
17
-
18
- function log(message, ...args) {
19
- utils.logger.log(`[ANR] ${message}`, ...args);
20
- }
21
-
22
- /**
23
- * Gets contexts by calling all event processors. This relies on being called after all integrations are setup
24
- */
25
- async function getContexts(client) {
26
- let event = { message: 'ANR' };
27
- const eventHint = {};
28
-
29
- for (const processor of client.getEventProcessors()) {
30
- if (event === null) break;
31
- event = await processor(event, eventHint);
32
- }
33
-
34
- return _optionalChain([event, 'optionalAccess', _2 => _2.contexts]) || {};
35
- }
36
-
37
- const INTEGRATION_NAME = 'Anr';
38
-
39
- const _anrIntegration = ((options = {}) => {
40
- return {
41
- name: INTEGRATION_NAME,
42
- setup(client) {
43
- if (nodeVersion.NODE_MAJOR < 16 || (nodeVersion.NODE_MAJOR === 16 && (nodeVersion.NODE_VERSION.minor || 0) < 17)) {
44
- throw new Error('ANR detection requires Node 16.17.0 or later');
45
- }
46
-
47
- // setImmediate is used to ensure that all other integrations have been setup
48
- setImmediate(() => _startWorker(client, options));
49
- },
50
- };
51
- }) ;
52
-
53
- const anrIntegration = core.defineIntegration(_anrIntegration);
54
-
55
- /**
56
- * Starts the ANR worker thread
57
- */
58
- async function _startWorker(client, _options) {
59
- const contexts = await getContexts(client);
60
- const dsn = client.getDsn();
61
-
62
- if (!dsn) {
63
- return;
64
- }
65
-
66
- // These will not be accurate if sent later from the worker thread
67
- _optionalChainDelete([contexts, 'access', _3 => _3.app, 'optionalAccess', _4 => delete _4.app_memory]);
68
- _optionalChainDelete([contexts, 'access', _5 => _5.device, 'optionalAccess', _6 => delete _6.free_memory]);
69
-
70
- const initOptions = client.getOptions();
71
-
72
- const sdkMetadata = client.getSdkMetadata() || {};
73
- if (sdkMetadata.sdk) {
74
- sdkMetadata.sdk.integrations = initOptions.integrations.map(i => i.name);
75
- }
76
-
77
- const options = {
78
- debug: utils.logger.isEnabled(),
79
- dsn,
80
- environment: initOptions.environment || 'production',
81
- release: initOptions.release,
82
- dist: initOptions.dist,
83
- sdkMetadata,
84
- appRootPath: _options.appRootPath,
85
- pollInterval: _options.pollInterval || DEFAULT_INTERVAL,
86
- anrThreshold: _options.anrThreshold || DEFAULT_HANG_THRESHOLD,
87
- captureStackTrace: !!_options.captureStackTrace,
88
- staticTags: _options.staticTags || {},
89
- contexts,
90
- };
91
-
92
- if (options.captureStackTrace) {
93
- if (!inspector.url()) {
94
- inspector.open(0);
95
- }
96
- }
97
-
98
- const worker = new worker_threads.Worker(new URL(`data:application/javascript;base64,${workerScript.base64WorkerScript}`), {
99
- workerData: options,
100
- });
101
-
102
- process.on('exit', () => {
103
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
104
- worker.terminate();
105
- });
106
-
107
- const timer = setInterval(() => {
108
- try {
109
- const currentSession = core.getCurrentScope().getSession();
110
- // We need to copy the session object and remove the toJSON method so it can be sent to the worker
111
- // serialized without making it a SerializedSession
112
- const session = currentSession ? { ...currentSession, toJSON: undefined } : undefined;
113
- // message the worker to tell it the main event loop is still running
114
- worker.postMessage({ session });
115
- } catch (_) {
116
- //
117
- }
118
- }, options.pollInterval);
119
- // Timer should not block exit
120
- timer.unref();
121
-
122
- worker.on('message', (msg) => {
123
- if (msg === 'session-ended') {
124
- log('ANR event sent from ANR worker. Clearing session in this thread.');
125
- core.getCurrentScope().setSession(undefined);
126
- }
127
- });
128
-
129
- worker.once('error', (err) => {
130
- clearInterval(timer);
131
- log('ANR worker error', err);
132
- });
133
-
134
- worker.once('exit', (code) => {
135
- clearInterval(timer);
136
- log('ANR worker exit', code);
137
- });
138
-
139
- // Ensure this thread can't block app exit
140
- worker.unref();
141
- }
142
-
143
- exports.anrIntegration = anrIntegration;
144
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sources":["../../../../src/integrations/anr/index.ts"],"sourcesContent":["import { defineIntegration, getCurrentScope } from '@sentry/core';\nimport type { Contexts, Event, EventHint, IntegrationFn } from '@sentry/types';\nimport { logger } from '@sentry/utils';\nimport * as inspector from 'inspector';\nimport { Worker } from 'worker_threads';\nimport { NODE_MAJOR, NODE_VERSION } from '../../nodeVersion';\nimport type { NodeClient } from '../../sdk/client';\nimport type { AnrIntegrationOptions, WorkerStartData } from './common';\nimport { base64WorkerScript } from './worker-script';\n\nconst DEFAULT_INTERVAL = 50;\nconst DEFAULT_HANG_THRESHOLD = 5000;\n\nfunction log(message: string, ...args: unknown[]): void {\n logger.log(`[ANR] ${message}`, ...args);\n}\n\n/**\n * Gets contexts by calling all event processors. This relies on being called after all integrations are setup\n */\nasync function getContexts(client: NodeClient): Promise<Contexts> {\n let event: Event | null = { message: 'ANR' };\n const eventHint: EventHint = {};\n\n for (const processor of client.getEventProcessors()) {\n if (event === null) break;\n event = await processor(event, eventHint);\n }\n\n return event?.contexts || {};\n}\n\nconst INTEGRATION_NAME = 'Anr';\n\nconst _anrIntegration = ((options: Partial<AnrIntegrationOptions> = {}) => {\n return {\n name: INTEGRATION_NAME,\n setup(client: NodeClient) {\n if (NODE_MAJOR < 16 || (NODE_MAJOR === 16 && (NODE_VERSION.minor || 0) < 17)) {\n throw new Error('ANR detection requires Node 16.17.0 or later');\n }\n\n // setImmediate is used to ensure that all other integrations have been setup\n setImmediate(() => _startWorker(client, options));\n },\n };\n}) satisfies IntegrationFn;\n\nexport const anrIntegration = defineIntegration(_anrIntegration);\n\n/**\n * Starts the ANR worker thread\n */\nasync function _startWorker(client: NodeClient, _options: Partial<AnrIntegrationOptions>): Promise<void> {\n const contexts = await getContexts(client);\n const dsn = client.getDsn();\n\n if (!dsn) {\n return;\n }\n\n // These will not be accurate if sent later from the worker thread\n delete contexts.app?.app_memory;\n delete contexts.device?.free_memory;\n\n const initOptions = client.getOptions();\n\n const sdkMetadata = client.getSdkMetadata() || {};\n if (sdkMetadata.sdk) {\n sdkMetadata.sdk.integrations = initOptions.integrations.map(i => i.name);\n }\n\n const options: WorkerStartData = {\n debug: logger.isEnabled(),\n dsn,\n environment: initOptions.environment || 'production',\n release: initOptions.release,\n dist: initOptions.dist,\n sdkMetadata,\n appRootPath: _options.appRootPath,\n pollInterval: _options.pollInterval || DEFAULT_INTERVAL,\n anrThreshold: _options.anrThreshold || DEFAULT_HANG_THRESHOLD,\n captureStackTrace: !!_options.captureStackTrace,\n staticTags: _options.staticTags || {},\n contexts,\n };\n\n if (options.captureStackTrace) {\n if (!inspector.url()) {\n inspector.open(0);\n }\n }\n\n const worker = new Worker(new URL(`data:application/javascript;base64,${base64WorkerScript}`), {\n workerData: options,\n });\n\n process.on('exit', () => {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n worker.terminate();\n });\n\n const timer = setInterval(() => {\n try {\n const currentSession = getCurrentScope().getSession();\n // We need to copy the session object and remove the toJSON method so it can be sent to the worker\n // serialized without making it a SerializedSession\n const session = currentSession ? { ...currentSession, toJSON: undefined } : undefined;\n // message the worker to tell it the main event loop is still running\n worker.postMessage({ session });\n } catch (_) {\n //\n }\n }, options.pollInterval);\n // Timer should not block exit\n timer.unref();\n\n worker.on('message', (msg: string) => {\n if (msg === 'session-ended') {\n log('ANR event sent from ANR worker. Clearing session in this thread.');\n getCurrentScope().setSession(undefined);\n }\n });\n\n worker.once('error', (err: Error) => {\n clearInterval(timer);\n log('ANR worker error', err);\n });\n\n worker.once('exit', (code: number) => {\n clearInterval(timer);\n log('ANR worker exit', code);\n });\n\n // Ensure this thread can't block app exit\n worker.unref();\n}\n"],"names":["logger","NODE_MAJOR","NODE_VERSION","defineIntegration","Worker","base64WorkerScript","getCurrentScope"],"mappings":"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A,MAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA;;EAEA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA;IACA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;EACA;;EAEA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,EAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,EAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA;GACA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,EAAA,CAAA,EAAA,CAAA,CAAA,CAAA,GAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,EAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;GACA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,EAAA,CAAA,EAAA,CAAA,CAAA,CAAA,MAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,EAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;;EAEA,MAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,EAAA,MAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA;;EAEA,CAAA,CAAA,CAAA,CAAA,EAAA,YAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,EAAA,CAAA,CAAA;EACA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA;IACA,WAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,EAAA,WAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;EACA;;EAEA,CAAA,CAAA,CAAA,CAAA,EAAA,QAAA,EAAA;IACA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAAH,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,SAAA,CAAA,CAAA;IACA,CAAA,CAAA,CAAA;IACA,WAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;IACA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;IACA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;IACA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;IACA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;IACA,YAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;IACA,YAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;IACA,iBAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;IACA,UAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,KAAA,CAAA,CAAA;IACA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;EACA,CAAA;;EAEA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA;IACA,IAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,EAAA;MACA,SAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;IACA;EACA;;EAEA,MAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,EAAA,CAAAI,CAAAA,EAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,mCAAA,CAAAC,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAA,CAAA,CAAA,CAAA,EAAA;IACA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;EACA,CAAA,CAAA;;EAEA,OAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,EAAA,CAAA,EAAA;IACA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;IACA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;EACA,CAAA,CAAA;;EAEA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,EAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,EAAA;IACA,CAAA,CAAA,EAAA;MACA,CAAA,CAAA,CAAA,CAAA,EAAA,eAAAC,EAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA;MACA,CAAA,EAAA,CAAA,EAAA,CAAA,CAAA,CAAA,EAAA,CAAA,EAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,EAAA,CAAA,EAAA,CAAA,CAAA,EAAA,CAAA,EAAA,CAAA,CAAA,CAAA,EAAA,CAAA,EAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA;MACA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,EAAA,CAAA,EAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA;MACA,CAAA,CAAA,CAAA,CAAA,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"}
@@ -1,2 +0,0 @@
1
- /*! @sentry/node 8.0.0-alpha.2 (894c151) | https://github.com/getsentry/sentry-javascript */
2
- exports.base64WorkerScript="aW1wb3J0IHsgU2Vzc2lvbiB9IGZyb20gJ2luc3BlY3Rvcic7CmltcG9ydCB7IHdvcmtlckRhdGEsIHBhcmVudFBvcnQgfSBmcm9tICd3b3JrZXJfdGhyZWFkcyc7CmltcG9ydCB7IHBvc2l4LCBzZXAgfSBmcm9tICdwYXRoJzsKaW1wb3J0ICogYXMgaHR0cCBmcm9tICdodHRwJzsKaW1wb3J0ICogYXMgaHR0cHMgZnJvbSAnaHR0cHMnOwppbXBvcnQgeyBSZWFkYWJsZSB9IGZyb20gJ3N0cmVhbSc7CmltcG9ydCB7IGNyZWF0ZUd6aXAgfSBmcm9tICd6bGliJzsKaW1wb3J0IGFzc2VydCBmcm9tICdhc3NlcnQnOwppbXBvcnQgKiBhcyBuZXQgZnJvbSAnbmV0JzsKaW1wb3J0ICogYXMgdGxzIGZyb20gJ3Rscyc7CgovLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L3VuYm91bmQtbWV0aG9kCmNvbnN0IG9iamVjdFRvU3RyaW5nID0gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZzsKCi8qKgogKiBDaGVja3Mgd2hldGhlciBnaXZlbiB2YWx1ZSdzIHR5cGUgaXMgb25lIG9mIGEgZmV3IEVycm9yIG9yIEVycm9yLWxpa2UKICoge0BsaW5rIGlzRXJyb3J9LgogKgogKiBAcGFyYW0gd2F0IEEgdmFsdWUgdG8gYmUgY2hlY2tlZC4KICogQHJldHVybnMgQSBib29sZWFuIHJlcHJlc2VudGluZyB0aGUgcmVzdWx0LgogKi8KZnVuY3Rpb24gaXNFcnJvcih3YXQpIHsKICBzd2l0Y2ggKG9iamVjdFRvU3RyaW5nLmNhbGwod2F0KSkgewogICAgY2FzZSAnW29iamVjdCBFcnJvcl0nOgogICAgY2FzZSAnW29iamVjdCBFeGNlcHRpb25dJzoKICAgIGNhc2UgJ1tvYmplY3QgRE9NRXhjZXB0aW9uXSc6CiAgICAgIHJldHVybiB0cnVlOwogICAgZGVmYXVsdDoKICAgICAgcmV0dXJuIGlzSW5zdGFuY2VPZih3YXQsIEVycm9yKTsKICB9Cn0KLyoqCiAqIENoZWNrcyB3aGV0aGVyIGdpdmVuIHZhbHVlIGlzIGFuIGluc3RhbmNlIG9mIHRoZSBnaXZlbiBidWlsdC1pbiBjbGFzcy4KICoKICogQHBhcmFtIHdhdCBUaGUgdmFsdWUgdG8gYmUgY2hlY2tlZAogKiBAcGFyYW0gY2xhc3NOYW1lCiAqIEByZXR1cm5zIEEgYm9vbGVhbiByZXByZXNlbnRpbmcgdGhlIHJlc3VsdC4KICovCmZ1bmN0aW9uIGlzQnVpbHRpbih3YXQsIGNsYXNzTmFtZSkgewogIHJldHVybiBvYmplY3RUb1N0cmluZy5jYWxsKHdhdCkgPT09IGBbb2JqZWN0ICR7Y2xhc3NOYW1lfV1gOwp9CgovKioKICogQ2hlY2tzIHdoZXRoZXIgZ2l2ZW4gdmFsdWUncyB0eXBlIGlzIGEgc3RyaW5nCiAqIHtAbGluayBpc1N0cmluZ30uCiAqCiAqIEBwYXJhbSB3YXQgQSB2YWx1ZSB0byBiZSBjaGVja2VkLgogKiBAcmV0dXJucyBBIGJvb2xlYW4gcmVwcmVzZW50aW5nIHRoZSByZXN1bHQuCiAqLwpmdW5jdGlvbiBpc1N0cmluZyh3YXQpIHsKICByZXR1cm4gaXNCdWlsdGluKHdhdCwgJ1N0cmluZycpOwp9CgovKioKICogQ2hlY2tzIHdoZXRoZXIgZ2l2ZW4gdmFsdWUncyB0eXBlIGlzIGFuIG9iamVjdCBsaXRlcmFsLCBvciBhIGNsYXNzIGluc3RhbmNlLgogKiB7QGxpbmsgaXNQbGFpbk9iamVjdH0uCiAqCiAqIEBwYXJhbSB3YXQgQSB2YWx1ZSB0byBiZSBjaGVja2VkLgogKiBAcmV0dXJucyBBIGJvb2xlYW4gcmVwcmVzZW50aW5nIHRoZSByZXN1bHQuCiAqLwpmdW5jdGlvbiBpc1BsYWluT2JqZWN0KHdhdCkgewogIHJldHVybiBpc0J1aWx0aW4od2F0LCAnT2JqZWN0Jyk7Cn0KCi8qKgogKiBDaGVja3Mgd2hldGhlciBnaXZlbiB2YWx1ZSdzIHR5cGUgaXMgYW4gRXZlbnQgaW5zdGFuY2UKICoge0BsaW5rIGlzRXZlbnR9LgogKgogKiBAcGFyYW0gd2F0IEEgdmFsdWUgdG8gYmUgY2hlY2tlZC4KICogQHJldHVybnMgQSBib29sZWFuIHJlcHJlc2VudGluZyB0aGUgcmVzdWx0LgogKi8KZnVuY3Rpb24gaXNFdmVudCh3YXQpIHsKICByZXR1cm4gdHlwZW9mIEV2ZW50ICE9PSAndW5kZWZpbmVkJyAmJiBpc0luc3RhbmNlT2Yod2F0LCBFdmVudCk7Cn0KCi8qKgogKiBDaGVja3Mgd2hldGhlciBnaXZlbiB2YWx1ZSdzIHR5cGUgaXMgYW4gRWxlbWVudCBpbnN0YW5jZQogKiB7QGxpbmsgaXNFbGVtZW50fS4KICoKICogQHBhcmFtIHdhdCBBIHZhbHVlIHRvIGJlIGNoZWNrZWQuCiAqIEByZXR1cm5zIEEgYm9vbGVhbiByZXByZXNlbnRpbmcgdGhlIHJlc3VsdC4KICovCmZ1bmN0aW9uIGlzRWxlbWVudCh3YXQpIHsKICByZXR1cm4gdHlwZW9mIEVsZW1lbnQgIT09ICd1bmRlZmluZWQnICYmIGlzSW5zdGFuY2VPZih3YXQsIEVsZW1lbnQpOwp9CgovKioKICogQ2hlY2tzIHdoZXRoZXIgZ2l2ZW4gdmFsdWUgaGFzIGEgdGhlbiBmdW5jdGlvbi4KICogQHBhcmFtIHdhdCBBIHZhbHVlIHRvIGJlIGNoZWNrZWQuCiAqLwpmdW5jdGlvbiBpc1RoZW5hYmxlKHdhdCkgewogIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLW1lbWJlci1hY2Nlc3MKICByZXR1cm4gQm9vbGVhbih3YXQgJiYgd2F0LnRoZW4gJiYgdHlwZW9mIHdhdC50aGVuID09PSAnZnVuY3Rpb24nKTsKfQoKLyoqCiAqIENoZWNrcyB3aGV0aGVyIGdpdmVuIHZhbHVlJ3MgdHlwZSBpcyBhIFN5bnRoZXRpY0V2ZW50CiAqIHtAbGluayBpc1N5bnRoZXRpY0V2ZW50fS4KICoKICogQHBhcmFtIHdhdCBBIHZhbHVlIHRvIGJlIGNoZWNrZWQuCiAqIEByZXR1cm5zIEEgYm9vbGVhbiByZXByZXNlbnRpbmcgdGhlIHJlc3VsdC4KICovCmZ1bmN0aW9uIGlzU3ludGhldGljRXZlbnQod2F0KSB7CiAgcmV0dXJuIGlzUGxhaW5PYmplY3Qod2F0KSAmJiAnbmF0aXZlRXZlbnQnIGluIHdhdCAmJiAncHJldmVudERlZmF1bHQnIGluIHdhdCAmJiAnc3RvcFByb3BhZ2F0aW9uJyBpbiB3YXQ7Cn0KCi8qKgogKiBDaGVja3Mgd2hldGhlciBnaXZlbiB2YWx1ZSBpcyBOYU4KICoge0BsaW5rIGlzTmFOfS4KICoKICogQHBhcmFtIHdhdCBBIHZhbHVlIHRvIGJlIGNoZWNrZWQuCiAqIEByZXR1cm5zIEEgYm9vbGVhbiByZXByZXNlbnRpbmcgdGhlIHJlc3VsdC4KICovCmZ1bmN0aW9uIGlzTmFOJDEod2F0KSB7CiAgcmV0dXJuIHR5cGVvZiB3YXQgPT09ICdudW1iZXInICYmIHdhdCAhPT0gd2F0Owp9CgovKioKICogQ2hlY2tzIHdoZXRoZXIgZ2l2ZW4gdmFsdWUncyB0eXBlIGlzIGFuIGluc3RhbmNlIG9mIHByb3ZpZGVkIGNvbnN0cnVjdG9yLgogKiB7QGxpbmsgaXNJbnN0YW5jZU9mfS4KICoKICogQHBhcmFtIHdhdCBBIHZhbHVlIHRvIGJlIGNoZWNrZWQuCiAqIEBwYXJhbSBiYXNlIEEgY29uc3RydWN0b3IgdG8gYmUgdXNlZCBpbiBhIGNoZWNrLgogKiBAcmV0dXJucyBBIGJvb2xlYW4gcmVwcmVzZW50aW5nIHRoZSByZXN1bHQuCiAqLwpmdW5jdGlvbiBpc0luc3RhbmNlT2Yod2F0LCBiYXNlKSB7CiAgdHJ5IHsKICAgIHJldHVybiB3YXQgaW5zdGFuY2VvZiBiYXNlOwogIH0gY2F0Y2ggKF9lKSB7CiAgICByZXR1cm4gZmFsc2U7CiAgfQp9CgovKioKICogQ2hlY2tzIHdoZXRoZXIgZ2l2ZW4gdmFsdWUncyB0eXBlIGlzIGEgVnVlIFZpZXdNb2RlbC4KICoKICogQHBhcmFtIHdhdCBBIHZhbHVlIHRvIGJlIGNoZWNrZWQuCiAqIEByZXR1cm5zIEEgYm9vbGVhbiByZXByZXNlbnRpbmcgdGhlIHJlc3VsdC4KICovCmZ1bmN0aW9uIGlzVnVlVmlld01vZGVsKHdhdCkgewogIC8vIE5vdCB1c2luZyBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nIGJlY2F1c2UgaW4gVnVlIDMgaXQgd291bGQgcmVhZCB0aGUgaW5zdGFuY2UncyBTeW1ib2woU3ltYm9sLnRvU3RyaW5nVGFnKSBwcm9wZXJ0eS4KICByZXR1cm4gISEodHlwZW9mIHdhdCA9PT0gJ29iamVjdCcgJiYgd2F0ICE9PSBudWxsICYmICgod2F0ICkuX19pc1Z1ZSB8fCAod2F0ICkuX2lzVnVlKSk7Cn0KCi8qKiBJbnRlcm5hbCBnbG9iYWwgd2l0aCBjb21tb24gcHJvcGVydGllcyBhbmQgU2VudHJ5IGV4dGVuc2lvbnMgICovCgovLyBUaGUgY29kZSBiZWxvdyBmb3IgJ2lzR2xvYmFsT2JqJyBhbmQgJ0dMT0JBTF9PQkonIHdhcyBjb3BpZWQgZnJvbSBjb3JlLWpzIGJlZm9yZSBtb2RpZmljYXRpb24KLy8gaHR0cHM6Ly9naXRodWIuY29tL3psb2lyb2NrL2NvcmUtanMvYmxvYi8xYjk0NGRmNTUyODJjZGM5OWM5MGRiNWY0OWViMGI2ZWRhMmNjMGEzL3BhY2thZ2VzL2NvcmUtanMvaW50ZXJuYWxzL2dsb2JhbC5qcwovLyBjb3JlLWpzIGhhcyB0aGUgZm9sbG93aW5nIGxpY2VuY2U6Ci8vCi8vIENvcHlyaWdodCAoYykgMjAxNC0yMDIyIERlbmlzIFB1c2hrYXJldgovLwovLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5Ci8vIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLCB0byBkZWFsCi8vIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMKLy8gdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbAovLyBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMKLy8gZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKLy8KLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4KLy8gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCi8vCi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCi8vIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLAovLyBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUKLy8gQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUgovLyBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLAovLyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOCi8vIFRIRSBTT0ZUV0FSRS4KCi8qKiBSZXR1cm5zICdvYmonIGlmIGl0J3MgdGhlIGdsb2JhbCBvYmplY3QsIG90aGVyd2lzZSByZXR1cm5zIHVuZGVmaW5lZCAqLwpmdW5jdGlvbiBpc0dsb2JhbE9iaihvYmopIHsKICByZXR1cm4gb2JqICYmIG9iai5NYXRoID09IE1hdGggPyBvYmogOiB1bmRlZmluZWQ7Cn0KCi8qKiBHZXQncyB0aGUgZ2xvYmFsIG9iamVjdCBmb3IgdGhlIGN1cnJlbnQgSmF2YVNjcmlwdCBydW50aW1lICovCmNvbnN0IEdMT0JBTF9PQkogPQogICh0eXBlb2YgZ2xvYmFsVGhpcyA9PSAnb2JqZWN0JyAmJiBpc0dsb2JhbE9iaihnbG9iYWxUaGlzKSkgfHwKICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tcmVzdHJpY3RlZC1nbG9iYWxzCiAgKHR5cGVvZiB3aW5kb3cgPT0gJ29iamVjdCcgJiYgaXNHbG9iYWxPYmood2luZG93KSkgfHwKICAodHlwZW9mIHNlbGYgPT0gJ29iamVjdCcgJiYgaXNHbG9iYWxPYmooc2VsZikpIHx8CiAgKHR5cGVvZiBnbG9iYWwgPT0gJ29iamVjdCcgJiYgaXNHbG9iYWxPYmooZ2xvYmFsKSkgfHwKICAoZnVuY3Rpb24gKCkgewogICAgcmV0dXJuIHRoaXM7CiAgfSkoKSB8fAogIHt9OwoKLyoqCiAqIEBkZXByZWNhdGVkIFVzZSBHTE9CQUxfT0JKIGluc3RlYWQgb3IgV0lORE9XIGZyb20gQHNlbnRyeS9icm93c2VyLiBUaGlzIHdpbGwgYmUgcmVtb3ZlZCBpbiB2OAogKi8KZnVuY3Rpb24gZ2V0R2xvYmFsT2JqZWN0KCkgewogIHJldHVybiBHTE9CQUxfT0JKIDsKfQoKLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCmNvbnN0IFdJTkRPVyA9IGdldEdsb2JhbE9iamVjdCgpOwoKY29uc3QgREVGQVVMVF9NQVhfU1RSSU5HX0xFTkdUSCA9IDgwOwoKLyoqCiAqIEdpdmVuIGEgY2hpbGQgRE9NIGVsZW1lbnQsIHJldHVybnMgYSBxdWVyeS1zZWxlY3RvciBzdGF0ZW1lbnQgZGVzY3JpYmluZyB0aGF0CiAqIGFuZCBpdHMgYW5jZXN0b3JzCiAqIGUuZy4gW0hUTUxFbGVtZW50XSA9PiBib2R5ID4gZGl2ID4gaW5wdXQjZm9vLmJ0bltuYW1lPWJhel0KICogQHJldHVybnMgZ2VuZXJhdGVkIERPTSBwYXRoCiAqLwpmdW5jdGlvbiBodG1sVHJlZUFzU3RyaW5nKAogIGVsZW0sCiAgb3B0aW9ucyA9IHt9LAopIHsKICBpZiAoIWVsZW0pIHsKICAgIHJldHVybiAnPHVua25vd24+JzsKICB9CgogIC8vIHRyeS9jYXRjaCBib3RoOgogIC8vIC0gYWNjZXNzaW5nIGV2ZW50LnRhcmdldCAoc2VlIGdldHNlbnRyeS9yYXZlbi1qcyM4MzgsICM3NjgpCiAgLy8gLSBgaHRtbFRyZWVBc1N0cmluZ2AgYmVjYXVzZSBpdCdzIGNvbXBsZXgsIGFuZCBqdXN0IGFjY2Vzc2luZyB0aGUgRE9NIGluY29ycmVjdGx5CiAgLy8gLSBjYW4gdGhyb3cgYW4gZXhjZXB0aW9uIGluIHNvbWUgY2lyY3Vtc3RhbmNlcy4KICB0cnkgewogICAgbGV0IGN1cnJlbnRFbGVtID0gZWxlbSA7CiAgICBjb25zdCBNQVhfVFJBVkVSU0VfSEVJR0hUID0gNTsKICAgIGNvbnN0IG91dCA9IFtdOwogICAgbGV0IGhlaWdodCA9IDA7CiAgICBsZXQgbGVuID0gMDsKICAgIGNvbnN0IHNlcGFyYXRvciA9ICcgPiAnOwogICAgY29uc3Qgc2VwTGVuZ3RoID0gc2VwYXJhdG9yLmxlbmd0aDsKICAgIGxldCBuZXh0U3RyOwogICAgY29uc3Qga2V5QXR0cnMgPSBBcnJheS5pc0FycmF5KG9wdGlvbnMpID8gb3B0aW9ucyA6IG9wdGlvbnMua2V5QXR0cnM7CiAgICBjb25zdCBtYXhTdHJpbmdMZW5ndGggPSAoIUFycmF5LmlzQXJyYXkob3B0aW9ucykgJiYgb3B0aW9ucy5tYXhTdHJpbmdMZW5ndGgpIHx8IERFRkFVTFRfTUFYX1NUUklOR19MRU5HVEg7CgogICAgd2hpbGUgKGN1cnJlbnRFbGVtICYmIGhlaWdodCsrIDwgTUFYX1RSQVZFUlNFX0hFSUdIVCkgewogICAgICBuZXh0U3RyID0gX2h0bWxFbGVtZW50QXNTdHJpbmcoY3VycmVudEVsZW0sIGtleUF0dHJzKTsKICAgICAgLy8gYmFpbCBvdXQgaWYKICAgICAgLy8gLSBuZXh0U3RyIGlzIHRoZSAnaHRtbCcgZWxlbWVudAogICAgICAvLyAtIHRoZSBsZW5ndGggb2YgdGhlIHN0cmluZyB0aGF0IHdvdWxkIGJlIGNyZWF0ZWQgZXhjZWVkcyBtYXhTdHJpbmdMZW5ndGgKICAgICAgLy8gICAoaWdub3JlIHRoaXMgbGltaXQgaWYgd2UgYXJlIG9uIHRoZSBmaXJzdCBpdGVyYXRpb24pCiAgICAgIGlmIChuZXh0U3RyID09PSAnaHRtbCcgfHwgKGhlaWdodCA+IDEgJiYgbGVuICsgb3V0Lmxlbmd0aCAqIHNlcExlbmd0aCArIG5leHRTdHIubGVuZ3RoID49IG1heFN0cmluZ0xlbmd0aCkpIHsKICAgICAgICBicmVhazsKICAgICAgfQoKICAgICAgb3V0LnB1c2gobmV4dFN0cik7CgogICAgICBsZW4gKz0gbmV4dFN0ci5sZW5ndGg7CiAgICAgIGN1cnJlbnRFbGVtID0gY3VycmVudEVsZW0ucGFyZW50Tm9kZTsKICAgIH0KCiAgICByZXR1cm4gb3V0LnJldmVyc2UoKS5qb2luKHNlcGFyYXRvcik7CiAgfSBjYXRjaCAoX29PKSB7CiAgICByZXR1cm4gJzx1bmtub3duPic7CiAgfQp9CgovKioKICogUmV0dXJucyBhIHNpbXBsZSwgcXVlcnktc2VsZWN0b3IgcmVwcmVzZW50YXRpb24gb2YgYSBET00gZWxlbWVudAogKiBlLmcuIFtIVE1MRWxlbWVudF0gPT4gaW5wdXQjZm9vLmJ0bltuYW1lPWJhel0KICogQHJldHVybnMgZ2VuZXJhdGVkIERPTSBwYXRoCiAqLwpmdW5jdGlvbiBfaHRtbEVsZW1lbnRBc1N0cmluZyhlbCwga2V5QXR0cnMpIHsKICBjb25zdCBlbGVtID0gZWwKCjsKCiAgY29uc3Qgb3V0ID0gW107CiAgbGV0IGNsYXNzTmFtZTsKICBsZXQgY2xhc3NlczsKICBsZXQga2V5OwogIGxldCBhdHRyOwogIGxldCBpOwoKICBpZiAoIWVsZW0gfHwgIWVsZW0udGFnTmFtZSkgewogICAgcmV0dXJuICcnOwogIH0KCiAgLy8gQHRzLWV4cGVjdC1lcnJvciBXSU5ET1cgaGFzIEhUTUxFbGVtZW50CiAgaWYgKFdJTkRPVy5IVE1MRWxlbWVudCkgewogICAgLy8gSWYgdXNpbmcgdGhlIGNvbXBvbmVudCBuYW1lIGFubm90YXRpb24gcGx1Z2luLCB0aGlzIHZhbHVlIG1heSBiZSBhdmFpbGFibGUgb24gdGhlIERPTSBub2RlCiAgICBpZiAoZWxlbSBpbnN0YW5jZW9mIEhUTUxFbGVtZW50ICYmIGVsZW0uZGF0YXNldCAmJiBlbGVtLmRhdGFzZXRbJ3NlbnRyeUNvbXBvbmVudCddKSB7CiAgICAgIHJldHVybiBlbGVtLmRhdGFzZXRbJ3NlbnRyeUNvbXBvbmVudCddOwogICAgfQogIH0KCiAgb3V0LnB1c2goZWxlbS50YWdOYW1lLnRvTG93ZXJDYXNlKCkpOwoKICAvLyBQYWlycyBvZiBhdHRyaWJ1dGUga2V5cyBkZWZpbmVkIGluIGBzZXJpYWxpemVBdHRyaWJ1dGVgIGFuZCB0aGVpciB2YWx1ZXMgb24gZWxlbWVudC4KICBjb25zdCBrZXlBdHRyUGFpcnMgPQogICAga2V5QXR0cnMgJiYga2V5QXR0cnMubGVuZ3RoCiAgICAgID8ga2V5QXR0cnMuZmlsdGVyKGtleUF0dHIgPT4gZWxlbS5nZXRBdHRyaWJ1dGUoa2V5QXR0cikpLm1hcChrZXlBdHRyID0+IFtrZXlBdHRyLCBlbGVtLmdldEF0dHJpYnV0ZShrZXlBdHRyKV0pCiAgICAgIDogbnVsbDsKCiAgaWYgKGtleUF0dHJQYWlycyAmJiBrZXlBdHRyUGFpcnMubGVuZ3RoKSB7CiAgICBrZXlBdHRyUGFpcnMuZm9yRWFjaChrZXlBdHRyUGFpciA9PiB7CiAgICAgIG91dC5wdXNoKGBbJHtrZXlBdHRyUGFpclswXX09IiR7a2V5QXR0clBhaXJbMV19Il1gKTsKICAgIH0pOwogIH0gZWxzZSB7CiAgICBpZiAoZWxlbS5pZCkgewogICAgICBvdXQucHVzaChgIyR7ZWxlbS5pZH1gKTsKICAgIH0KCiAgICBjbGFzc05hbWUgPSBlbGVtLmNsYXNzTmFtZTsKICAgIGlmIChjbGFzc05hbWUgJiYgaXNTdHJpbmcoY2xhc3NOYW1lKSkgewogICAgICBjbGFzc2VzID0gY2xhc3NOYW1lLnNwbGl0KC9ccysvKTsKICAgICAgZm9yIChpID0gMDsgaSA8IGNsYXNzZXMubGVuZ3RoOyBpKyspIHsKICAgICAgICBvdXQucHVzaChgLiR7Y2xhc3Nlc1tpXX1gKTsKICAgICAgfQogICAgfQogIH0KICBjb25zdCBhbGxvd2VkQXR0cnMgPSBbJ2FyaWEtbGFiZWwnLCAndHlwZScsICduYW1lJywgJ3RpdGxlJywgJ2FsdCddOwogIGZvciAoaSA9IDA7IGkgPCBhbGxvd2VkQXR0cnMubGVuZ3RoOyBpKyspIHsKICAgIGtleSA9IGFsbG93ZWRBdHRyc1tpXTsKICAgIGF0dHIgPSBlbGVtLmdldEF0dHJpYnV0ZShrZXkpOwogICAgaWYgKGF0dHIpIHsKICAgICAgb3V0LnB1c2goYFske2tleX09IiR7YXR0cn0iXWApOwogICAgfQogIH0KICByZXR1cm4gb3V0LmpvaW4oJycpOwp9CgovKioKICogVGhpcyBzZXJ2ZXMgYXMgYSBidWlsZCB0aW1lIGZsYWcgdGhhdCB3aWxsIGJlIHRydWUgYnkgZGVmYXVsdCwgYnV0IGZhbHNlIGluIG5vbi1kZWJ1ZyBidWlsZHMgb3IgaWYgdXNlcnMgcmVwbGFjZSBgX19TRU5UUllfREVCVUdfX2AgaW4gdGhlaXIgZ2VuZXJhdGVkIGNvZGUuCiAqCiAqIEFUVEVOVElPTjogVGhpcyBjb25zdGFudCBtdXN0IG5ldmVyIGNyb3NzIHBhY2thZ2UgYm91bmRhcmllcyAoaS5lLiBiZSBleHBvcnRlZCkgdG8gZ3VhcmFudGVlIHRoYXQgaXQgY2FuIGJlIHVzZWQgZm9yIHRyZWUgc2hha2luZy4KICovCmNvbnN0IERFQlVHX0JVSUxEJDEgPSAodHlwZW9mIF9fU0VOVFJZX0RFQlVHX18gPT09ICd1bmRlZmluZWQnIHx8IF9fU0VOVFJZX0RFQlVHX18pOwoKLyoqIFByZWZpeCBmb3IgbG9nZ2luZyBzdHJpbmdzICovCmNvbnN0IFBSRUZJWCA9ICdTZW50cnkgTG9nZ2VyICc7Cgpjb25zdCBDT05TT0xFX0xFVkVMUyA9IFsKICAnZGVidWcnLAogICdpbmZvJywKICAnd2FybicsCiAgJ2Vycm9yJywKICAnbG9nJywKICAnYXNzZXJ0JywKICAndHJhY2UnLApdIDsKCi8qKiBUaGlzIG1heSBiZSBtdXRhdGVkIGJ5IHRoZSBjb25zb2xlIGluc3RydW1lbnRhdGlvbi4gKi8KY29uc3Qgb3JpZ2luYWxDb25zb2xlTWV0aG9kcwoKID0ge307CgovKiogSlNEb2MgKi8KCi8qKgogKiBUZW1wb3JhcmlseSBkaXNhYmxlIHNlbnRyeSBjb25zb2xlIGluc3RydW1lbnRhdGlvbnMuCiAqCiAqIEBwYXJhbSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gdG8gcnVuIGFnYWluc3QgdGhlIG9yaWdpbmFsIGBjb25zb2xlYCBtZXNzYWdlcwogKiBAcmV0dXJucyBUaGUgcmVzdWx0cyBvZiB0aGUgY2FsbGJhY2sKICovCmZ1bmN0aW9uIGNvbnNvbGVTYW5kYm94KGNhbGxiYWNrKSB7CiAgaWYgKCEoJ2NvbnNvbGUnIGluIEdMT0JBTF9PQkopKSB7CiAgICByZXR1cm4gY2FsbGJhY2soKTsKICB9CgogIGNvbnN0IGNvbnNvbGUgPSBHTE9CQUxfT0JKLmNvbnNvbGUgOwogIGNvbnN0IHdyYXBwZWRGdW5jcyA9IHt9OwoKICBjb25zdCB3cmFwcGVkTGV2ZWxzID0gT2JqZWN0LmtleXMob3JpZ2luYWxDb25zb2xlTWV0aG9kcykgOwoKICAvLyBSZXN0b3JlIGFsbCB3cmFwcGVkIGNvbnNvbGUgbWV0aG9kcwogIHdyYXBwZWRMZXZlbHMuZm9yRWFjaChsZXZlbCA9PiB7CiAgICBjb25zdCBvcmlnaW5hbENvbnNvbGVNZXRob2QgPSBvcmlnaW5hbENvbnNvbGVNZXRob2RzW2xldmVsXSA7CiAgICB3cmFwcGVkRnVuY3NbbGV2ZWxdID0gY29uc29sZVtsZXZlbF0gOwogICAgY29uc29sZVtsZXZlbF0gPSBvcmlnaW5hbENvbnNvbGVNZXRob2Q7CiAgfSk7CgogIHRyeSB7CiAgICByZXR1cm4gY2FsbGJhY2soKTsKICB9IGZpbmFsbHkgewogICAgLy8gUmV2ZXJ0IHJlc3RvcmF0aW9uIHRvIHdyYXBwZWQgc3RhdGUKICAgIHdyYXBwZWRMZXZlbHMuZm9yRWFjaChsZXZlbCA9PiB7CiAgICAgIGNvbnNvbGVbbGV2ZWxdID0gd3JhcHBlZEZ1bmNzW2xldmVsXSA7CiAgICB9KTsKICB9Cn0KCmZ1bmN0aW9uIG1ha2VMb2dnZXIoKSB7CiAgbGV0IGVuYWJsZWQgPSBmYWxzZTsKICBjb25zdCBsb2dnZXIgPSB7CiAgICBlbmFibGU6ICgpID0+IHsKICAgICAgZW5hYmxlZCA9IHRydWU7CiAgICB9LAogICAgZGlzYWJsZTogKCkgPT4gewogICAgICBlbmFibGVkID0gZmFsc2U7CiAgICB9LAogICAgaXNFbmFibGVkOiAoKSA9PiBlbmFibGVkLAogIH07CgogIGlmIChERUJVR19CVUlMRCQxKSB7CiAgICBDT05TT0xFX0xFVkVMUy5mb3JFYWNoKG5hbWUgPT4gewogICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueQogICAgICBsb2dnZXJbbmFtZV0gPSAoLi4uYXJncykgPT4gewogICAgICAgIGlmIChlbmFibGVkKSB7CiAgICAgICAgICBjb25zb2xlU2FuZGJveCgoKSA9PiB7CiAgICAgICAgICAgIEdMT0JBTF9PQkouY29uc29sZVtuYW1lXShgJHtQUkVGSVh9WyR7bmFtZX1dOmAsIC4uLmFyZ3MpOwogICAgICAgICAgfSk7CiAgICAgICAgfQogICAgICB9OwogICAgfSk7CiAgfSBlbHNlIHsKICAgIENPTlNPTEVfTEVWRUxTLmZvckVhY2gobmFtZSA9PiB7CiAgICAgIGxvZ2dlcltuYW1lXSA9ICgpID0+IHVuZGVmaW5lZDsKICAgIH0pOwogIH0KCiAgcmV0dXJuIGxvZ2dlciA7Cn0KCmNvbnN0IGxvZ2dlciA9IG1ha2VMb2dnZXIoKTsKCi8qKgogKiBSZW5kZXJzIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhpcyBEc24uCiAqCiAqIEJ5IGRlZmF1bHQsIHRoaXMgd2lsbCByZW5kZXIgdGhlIHB1YmxpYyByZXByZXNlbnRhdGlvbiB3aXRob3V0IHRoZSBwYXNzd29yZAogKiBjb21wb25lbnQuIFRvIGdldCB0aGUgZGVwcmVjYXRlZCBwcml2YXRlIHJlcHJlc2VudGF0aW9uLCBzZXQgYHdpdGhQYXNzd29yZGAKICogdG8gdHJ1ZS4KICoKICogQHBhcmFtIHdpdGhQYXNzd29yZCBXaGVuIHNldCB0byB0cnVlLCB0aGUgcGFzc3dvcmQgd2lsbCBiZSBpbmNsdWRlZC4KICovCmZ1bmN0aW9uIGRzblRvU3RyaW5nKGRzbiwgd2l0aFBhc3N3b3JkID0gZmFsc2UpIHsKICBjb25zdCB7IGhvc3QsIHBhdGgsIHBhc3MsIHBvcnQsIHByb2plY3RJZCwgcHJvdG9jb2wsIHB1YmxpY0tleSB9ID0gZHNuOwogIHJldHVybiAoCiAgICBgJHtwcm90b2NvbH06Ly8ke3B1YmxpY0tleX0ke3dpdGhQYXNzd29yZCAmJiBwYXNzID8gYDoke3Bhc3N9YCA6ICcnfWAgKwogICAgYEAke2hvc3R9JHtwb3J0ID8gYDoke3BvcnR9YCA6ICcnfS8ke3BhdGggPyBgJHtwYXRofS9gIDogcGF0aH0ke3Byb2plY3RJZH1gCiAgKTsKfQoKLyoqIEFuIGVycm9yIGVtaXR0ZWQgYnkgU2VudHJ5IFNES3MgYW5kIHJlbGF0ZWQgdXRpbGl0aWVzLiAqLwpjbGFzcyBTZW50cnlFcnJvciBleHRlbmRzIEVycm9yIHsKICAvKiogRGlzcGxheSBuYW1lIG9mIHRoaXMgZXJyb3IgaW5zdGFuY2UuICovCgogICBjb25zdHJ1Y3RvciggbWVzc2FnZSwgbG9nTGV2ZWwgPSAnd2FybicpIHsKICAgIHN1cGVyKG1lc3NhZ2UpO3RoaXMubWVzc2FnZSA9IG1lc3NhZ2U7CiAgICB0aGlzLm5hbWUgPSBuZXcudGFyZ2V0LnByb3RvdHlwZS5jb25zdHJ1Y3Rvci5uYW1lOwogICAgLy8gVGhpcyBzZXRzIHRoZSBwcm90b3R5cGUgdG8gYmUgYEVycm9yYCwgbm90IGBTZW50cnlFcnJvcmAuIEl0J3MgdW5jbGVhciB3aHkgd2UgZG8gdGhpcywgYnV0IGNvbW1lbnRpbmcgdGhpcyBsaW5lCiAgICAvLyBvdXQgY2F1c2VzIHZhcmlvdXMgKHNlZW1pbmdseSB0b3RhbGx5IHVucmVsYXRlZCkgcGxheXdyaWdodCB0ZXN0cyBjb25zaXN0ZW50bHkgdGltZSBvdXQuIEZZSSwgdGhpcyBtYWtlcwogICAgLy8gaW5zdGFuY2VzIG9mIGBTZW50cnlFcnJvcmAgZmFpbCBgb2JqIGluc3RhbmNlb2YgU2VudHJ5RXJyb3JgIGNoZWNrcy4KICAgIE9iamVjdC5zZXRQcm90b3R5cGVPZih0aGlzLCBuZXcudGFyZ2V0LnByb3RvdHlwZSk7CiAgICB0aGlzLmxvZ0xldmVsID0gbG9nTGV2ZWw7CiAgfQp9Cgpjb25zdCBTVEFDS1RSQUNFX0ZSQU1FX0xJTUlUID0gNTA7CmNvbnN0IFVOS05PV05fRlVOQ1RJT04gPSAnPyc7CmNvbnN0IFNUUklQX0ZSQU1FX1JFR0VYUCA9IC9jYXB0dXJlTWVzc2FnZXxjYXB0dXJlRXhjZXB0aW9uLzsKCi8qKgogKiBSZW1vdmVzIFNlbnRyeSBmcmFtZXMgZnJvbSB0aGUgdG9wIGFuZCBib3R0b20gb2YgdGhlIHN0YWNrIGlmIHByZXNlbnQgYW5kIGVuZm9yY2VzIGEgbGltaXQgb2YgbWF4IG51bWJlciBvZiBmcmFtZXMuCiAqIEFzc3VtZXMgc3RhY2sgaW5wdXQgaXMgb3JkZXJlZCBmcm9tIHRvcCB0byBib3R0b20gYW5kIHJldHVybnMgdGhlIHJldmVyc2UgcmVwcmVzZW50YXRpb24gc28gY2FsbCBzaXRlIG9mIHRoZQogKiBmdW5jdGlvbiB0aGF0IGNhdXNlZCB0aGUgY3Jhc2ggaXMgdGhlIGxhc3QgZnJhbWUgaW4gdGhlIGFycmF5LgogKiBAaGlkZGVuCiAqLwpmdW5jdGlvbiBzdHJpcFNlbnRyeUZyYW1lc0FuZFJldmVyc2Uoc3RhY2spIHsKICBpZiAoIXN0YWNrLmxlbmd0aCkgewogICAgcmV0dXJuIFtdOwogIH0KCiAgY29uc3QgbG9jYWxTdGFjayA9IEFycmF5LmZyb20oc3RhY2spOwoKICAvLyBJZiBzdGFjayBzdGFydHMgd2l0aCBvbmUgb2Ygb3VyIEFQSSBjYWxscywgcmVtb3ZlIGl0IChzdGFydHMsIG1lYW5pbmcgaXQncyB0aGUgdG9wIG9mIHRoZSBzdGFjayAtIGFrYSBsYXN0IGNhbGwpCiAgaWYgKC9zZW50cnlXcmFwcGVkLy50ZXN0KGxvY2FsU3RhY2tbbG9jYWxTdGFjay5sZW5ndGggLSAxXS5mdW5jdGlvbiB8fCAnJykpIHsKICAgIGxvY2FsU3RhY2sucG9wKCk7CiAgfQoKICAvLyBSZXZlcnNpbmcgaW4gdGhlIG1pZGRsZSBvZiB0aGUgcHJvY2VkdXJlIGFsbG93cyB1cyB0byBqdXN0IHBvcCB0aGUgdmFsdWVzIG9mZiB0aGUgc3RhY2sKICBsb2NhbFN0YWNrLnJldmVyc2UoKTsKCiAgLy8gSWYgc3RhY2sgZW5kcyB3aXRoIG9uZSBvZiBvdXIgaW50ZXJuYWwgQVBJIGNhbGxzLCByZW1vdmUgaXQgKGVuZHMsIG1lYW5pbmcgaXQncyB0aGUgYm90dG9tIG9mIHRoZSBzdGFjayAtIGFrYSB0b3AtbW9zdCBjYWxsKQogIGlmIChTVFJJUF9GUkFNRV9SRUdFWFAudGVzdChsb2NhbFN0YWNrW2xvY2FsU3RhY2subGVuZ3RoIC0gMV0uZnVuY3Rpb24gfHwgJycpKSB7CiAgICBsb2NhbFN0YWNrLnBvcCgpOwoKICAgIC8vIFdoZW4gdXNpbmcgc3ludGhldGljIGV2ZW50cywgd2Ugd2lsbCBoYXZlIGEgMiBsZXZlbHMgZGVlcCBzdGFjaywgYXMgYG5ldyBFcnJvcignU2VudHJ5IHN5bnRoZXRpY0V4Y2VwdGlvbicpYAogICAgLy8gaXMgcHJvZHVjZWQgd2l0aGluIHRoZSBodWIgaXRzZWxmLCBtYWtpbmcgaXQ6CiAgICAvLwogICAgLy8gICBTZW50cnkuY2FwdHVyZUV4Y2VwdGlvbigpCiAgICAvLyAgIGdldEN1cnJlbnRIdWIoKS5jYXB0dXJlRXhjZXB0aW9uKCkKICAgIC8vCiAgICAvLyBpbnN0ZWFkIG9mIGp1c3QgdGhlIHRvcCBgU2VudHJ5YCBjYWxsIGl0c2VsZi4KICAgIC8vIFRoaXMgZm9yY2VzIHVzIHRvIHBvc3NpYmx5IHN0cmlwIGFuIGFkZGl0aW9uYWwgZnJhbWUgaW4gdGhlIGV4YWN0IHNhbWUgd2FzIGFzIGFib3ZlLgogICAgaWYgKFNUUklQX0ZSQU1FX1JFR0VYUC50ZXN0KGxvY2FsU3RhY2tbbG9jYWxTdGFjay5sZW5ndGggLSAxXS5mdW5jdGlvbiB8fCAnJykpIHsKICAgICAgbG9jYWxTdGFjay5wb3AoKTsKICAgIH0KICB9CgogIHJldHVybiBsb2NhbFN0YWNrLnNsaWNlKDAsIFNUQUNLVFJBQ0VfRlJBTUVfTElNSVQpLm1hcChmcmFtZSA9PiAoewogICAgLi4uZnJhbWUsCiAgICBmaWxlbmFtZTogZnJhbWUuZmlsZW5hbWUgfHwgbG9jYWxTdGFja1tsb2NhbFN0YWNrLmxlbmd0aCAtIDFdLmZpbGVuYW1lLAogICAgZnVuY3Rpb246IGZyYW1lLmZ1bmN0aW9uIHx8IFVOS05PV05fRlVOQ1RJT04sCiAgfSkpOwp9Cgpjb25zdCBkZWZhdWx0RnVuY3Rpb25OYW1lID0gJzxhbm9ueW1vdXM+JzsKCi8qKgogKiBTYWZlbHkgZXh0cmFjdCBmdW5jdGlvbiBuYW1lIGZyb20gaXRzZWxmCiAqLwpmdW5jdGlvbiBnZXRGdW5jdGlvbk5hbWUoZm4pIHsKICB0cnkgewogICAgaWYgKCFmbiB8fCB0eXBlb2YgZm4gIT09ICdmdW5jdGlvbicpIHsKICAgICAgcmV0dXJuIGRlZmF1bHRGdW5jdGlvbk5hbWU7CiAgICB9CiAgICByZXR1cm4gZm4ubmFtZSB8fCBkZWZhdWx0RnVuY3Rpb25OYW1lOwogIH0gY2F0Y2ggKGUpIHsKICAgIC8vIEp1c3QgYWNjZXNzaW5nIGN1c3RvbSBwcm9wcyBpbiBzb21lIFNlbGVuaXVtIGVudmlyb25tZW50cwogICAgLy8gY2FuIGNhdXNlIGEgIlBlcm1pc3Npb24gZGVuaWVkIiBleGNlcHRpb24gKHNlZSByYXZlbi1qcyM0OTUpLgogICAgcmV0dXJuIGRlZmF1bHRGdW5jdGlvbk5hbWU7CiAgfQp9CgovKioKICogRW5jb2RlcyBnaXZlbiBvYmplY3QgaW50byB1cmwtZnJpZW5kbHkgZm9ybWF0CiAqCiAqIEBwYXJhbSBvYmplY3QgQW4gb2JqZWN0IHRoYXQgY29udGFpbnMgc2VyaWFsaXphYmxlIHZhbHVlcwogKiBAcmV0dXJucyBzdHJpbmcgRW5jb2RlZAogKi8KZnVuY3Rpb24gdXJsRW5jb2RlKG9iamVjdCkgewogIHJldHVybiBPYmplY3Qua2V5cyhvYmplY3QpCiAgICAubWFwKGtleSA9PiBgJHtlbmNvZGVVUklDb21wb25lbnQoa2V5KX09JHtlbmNvZGVVUklDb21wb25lbnQob2JqZWN0W2tleV0pfWApCiAgICAuam9pbignJicpOwp9CgovKioKICogVHJhbnNmb3JtcyBhbnkgYEVycm9yYCBvciBgRXZlbnRgIGludG8gYSBwbGFpbiBvYmplY3Qgd2l0aCBhbGwgb2YgdGhlaXIgZW51bWVyYWJsZSBwcm9wZXJ0aWVzLCBhbmQgc29tZSBvZiB0aGVpcgogKiBub24tZW51bWVyYWJsZSBwcm9wZXJ0aWVzIGF0dGFjaGVkLgogKgogKiBAcGFyYW0gdmFsdWUgSW5pdGlhbCBzb3VyY2UgdGhhdCB3ZSBoYXZlIHRvIHRyYW5zZm9ybSBpbiBvcmRlciBmb3IgaXQgdG8gYmUgdXNhYmxlIGJ5IHRoZSBzZXJpYWxpemVyCiAqIEByZXR1cm5zIEFuIEV2ZW50IG9yIEVycm9yIHR1cm5lZCBpbnRvIGFuIG9iamVjdCAtIG9yIHRoZSB2YWx1ZSBhcmd1cm1lbnQgaXRzZWxmLCB3aGVuIHZhbHVlIGlzIG5laXRoZXIgYW4gRXZlbnQgbm9yCiAqICBhbiBFcnJvci4KICovCmZ1bmN0aW9uIGNvbnZlcnRUb1BsYWluT2JqZWN0KAogIHZhbHVlLAopCgogewogIGlmIChpc0Vycm9yKHZhbHVlKSkgewogICAgcmV0dXJuIHsKICAgICAgbWVzc2FnZTogdmFsdWUubWVzc2FnZSwKICAgICAgbmFtZTogdmFsdWUubmFtZSwKICAgICAgc3RhY2s6IHZhbHVlLnN0YWNrLAogICAgICAuLi5nZXRPd25Qcm9wZXJ0aWVzKHZhbHVlKSwKICAgIH07CiAgfSBlbHNlIGlmIChpc0V2ZW50KHZhbHVlKSkgewogICAgY29uc3QgbmV3T2JqCgogPSB7CiAgICAgIHR5cGU6IHZhbHVlLnR5cGUsCiAgICAgIHRhcmdldDogc2VyaWFsaXplRXZlbnRUYXJnZXQodmFsdWUudGFyZ2V0KSwKICAgICAgY3VycmVudFRhcmdldDogc2VyaWFsaXplRXZlbnRUYXJnZXQodmFsdWUuY3VycmVudFRhcmdldCksCiAgICAgIC4uLmdldE93blByb3BlcnRpZXModmFsdWUpLAogICAgfTsKCiAgICBpZiAodHlwZW9mIEN1c3RvbUV2ZW50ICE9PSAndW5kZWZpbmVkJyAmJiBpc0luc3RhbmNlT2YodmFsdWUsIEN1c3RvbUV2ZW50KSkgewogICAgICBuZXdPYmouZGV0YWlsID0gdmFsdWUuZGV0YWlsOwogICAgfQoKICAgIHJldHVybiBuZXdPYmo7CiAgfSBlbHNlIHsKICAgIHJldHVybiB2YWx1ZTsKICB9Cn0KCi8qKiBDcmVhdGVzIGEgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB0YXJnZXQgb2YgYW4gYEV2ZW50YCBvYmplY3QgKi8KZnVuY3Rpb24gc2VyaWFsaXplRXZlbnRUYXJnZXQodGFyZ2V0KSB7CiAgdHJ5IHsKICAgIHJldHVybiBpc0VsZW1lbnQodGFyZ2V0KSA/IGh0bWxUcmVlQXNTdHJpbmcodGFyZ2V0KSA6IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh0YXJnZXQpOwogIH0gY2F0Y2ggKF9vTykgewogICAgcmV0dXJuICc8dW5rbm93bj4nOwogIH0KfQoKLyoqIEZpbHRlcnMgb3V0IGFsbCBidXQgYW4gb2JqZWN0J3Mgb3duIHByb3BlcnRpZXMgKi8KZnVuY3Rpb24gZ2V0T3duUHJvcGVydGllcyhvYmopIHsKICBpZiAodHlwZW9mIG9iaiA9PT0gJ29iamVjdCcgJiYgb2JqICE9PSBudWxsKSB7CiAgICBjb25zdCBleHRyYWN0ZWRQcm9wcyA9IHt9OwogICAgZm9yIChjb25zdCBwcm9wZXJ0eSBpbiBvYmopIHsKICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3BlcnR5KSkgewogICAgICAgIGV4dHJhY3RlZFByb3BzW3Byb3BlcnR5XSA9IChvYmogKVtwcm9wZXJ0eV07CiAgICAgIH0KICAgIH0KICAgIHJldHVybiBleHRyYWN0ZWRQcm9wczsKICB9IGVsc2UgewogICAgcmV0dXJuIHt9OwogIH0KfQoKLyoqCiAqIEdpdmVuIGFueSBvYmplY3QsIHJldHVybiBhIG5ldyBvYmplY3QgaGF2aW5nIHJlbW92ZWQgYWxsIGZpZWxkcyB3aG9zZSB2YWx1ZSB3YXMgYHVuZGVmaW5lZGAuCiAqIFdvcmtzIHJlY3Vyc2l2ZWx5IG9uIG9iamVjdHMgYW5kIGFycmF5cy4KICoKICogQXR0ZW50aW9uOiBUaGlzIGZ1bmN0aW9uIGtlZXBzIGNpcmN1bGFyIHJlZmVyZW5jZXMgaW4gdGhlIHJldHVybmVkIG9iamVjdC4KICovCmZ1bmN0aW9uIGRyb3BVbmRlZmluZWRLZXlzKGlucHV0VmFsdWUpIHsKICAvLyBUaGlzIG1hcCBrZWVwcyB0cmFjayBvZiB3aGF0IGFscmVhZHkgdmlzaXRlZCBub2RlcyBtYXAgdG8uCiAgLy8gT3VyIFNldCAtIGJhc2VkIG1lbW9CdWlsZGVyIGRvZXNuJ3Qgd29yayBoZXJlIGJlY2F1c2Ugd2Ugd2FudCB0byB0aGUgb3V0cHV0IG9iamVjdCB0byBoYXZlIHRoZSBzYW1lIGNpcmN1bGFyCiAgLy8gcmVmZXJlbmNlcyBhcyB0aGUgaW5wdXQgb2JqZWN0LgogIGNvbnN0IG1lbW9pemF0aW9uTWFwID0gbmV3IE1hcCgpOwoKICAvLyBUaGlzIGZ1bmN0aW9uIGp1c3QgcHJveGllcyBgX2Ryb3BVbmRlZmluZWRLZXlzYCB0byBrZWVwIHRoZSBgbWVtb0J1aWxkZXJgIG91dCBvZiB0aGlzIGZ1bmN0aW9uJ3MgQVBJCiAgcmV0dXJuIF9kcm9wVW5kZWZpbmVkS2V5cyhpbnB1dFZhbHVlLCBtZW1vaXphdGlvbk1hcCk7Cn0KCmZ1bmN0aW9uIF9kcm9wVW5kZWZpbmVkS2V5cyhpbnB1dFZhbHVlLCBtZW1vaXphdGlvbk1hcCkgewogIGlmIChpc1Bvam8oaW5wdXRWYWx1ZSkpIHsKICAgIC8vIElmIHRoaXMgbm9kZSBoYXMgYWxyZWFkeSBiZWVuIHZpc2l0ZWQgZHVlIHRvIGEgY2lyY3VsYXIgcmVmZXJlbmNlLCByZXR1cm4gdGhlIG9iamVjdCBpdCB3YXMgbWFwcGVkIHRvIGluIHRoZSBuZXcgb2JqZWN0CiAgICBjb25zdCBtZW1vVmFsID0gbWVtb2l6YXRpb25NYXAuZ2V0KGlucHV0VmFsdWUpOwogICAgaWYgKG1lbW9WYWwgIT09IHVuZGVmaW5lZCkgewogICAgICByZXR1cm4gbWVtb1ZhbCA7CiAgICB9CgogICAgY29uc3QgcmV0dXJuVmFsdWUgPSB7fTsKICAgIC8vIFN0b3JlIHRoZSBtYXBwaW5nIG9mIHRoaXMgdmFsdWUgaW4gY2FzZSB3ZSB2aXNpdCBpdCBhZ2FpbiwgaW4gY2FzZSBvZiBjaXJjdWxhciBkYXRhCiAgICBtZW1vaXphdGlvbk1hcC5zZXQoaW5wdXRWYWx1ZSwgcmV0dXJuVmFsdWUpOwoKICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKGlucHV0VmFsdWUpKSB7CiAgICAgIGlmICh0eXBlb2YgaW5wdXRWYWx1ZVtrZXldICE9PSAndW5kZWZpbmVkJykgewogICAgICAgIHJldHVyblZhbHVlW2tleV0gPSBfZHJvcFVuZGVmaW5lZEtleXMoaW5wdXRWYWx1ZVtrZXldLCBtZW1vaXphdGlvbk1hcCk7CiAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gcmV0dXJuVmFsdWUgOwogIH0KCiAgaWYgKEFycmF5LmlzQXJyYXkoaW5wdXRWYWx1ZSkpIHsKICAgIC8vIElmIHRoaXMgbm9kZSBoYXMgYWxyZWFkeSBiZWVuIHZpc2l0ZWQgZHVlIHRvIGEgY2lyY3VsYXIgcmVmZXJlbmNlLCByZXR1cm4gdGhlIGFycmF5IGl0IHdhcyBtYXBwZWQgdG8gaW4gdGhlIG5ldyBvYmplY3QKICAgIGNvbnN0IG1lbW9WYWwgPSBtZW1vaXphdGlvbk1hcC5nZXQoaW5wdXRWYWx1ZSk7CiAgICBpZiAobWVtb1ZhbCAhPT0gdW5kZWZpbmVkKSB7CiAgICAgIHJldHVybiBtZW1vVmFsIDsKICAgIH0KCiAgICBjb25zdCByZXR1cm5WYWx1ZSA9IFtdOwogICAgLy8gU3RvcmUgdGhlIG1hcHBpbmcgb2YgdGhpcyB2YWx1ZSBpbiBjYXNlIHdlIHZpc2l0IGl0IGFnYWluLCBpbiBjYXNlIG9mIGNpcmN1bGFyIGRhdGEKICAgIG1lbW9pemF0aW9uTWFwLnNldChpbnB1dFZhbHVlLCByZXR1cm5WYWx1ZSk7CgogICAgaW5wdXRWYWx1ZS5mb3JFYWNoKChpdGVtKSA9PiB7CiAgICAgIHJldHVyblZhbHVlLnB1c2goX2Ryb3BVbmRlZmluZWRLZXlzKGl0ZW0sIG1lbW9pemF0aW9uTWFwKSk7CiAgICB9KTsKCiAgICByZXR1cm4gcmV0dXJuVmFsdWUgOwogIH0KCiAgcmV0dXJuIGlucHV0VmFsdWU7Cn0KCmZ1bmN0aW9uIGlzUG9qbyhpbnB1dCkgewogIGlmICghaXNQbGFpbk9iamVjdChpbnB1dCkpIHsKICAgIHJldHVybiBmYWxzZTsKICB9CgogIHRyeSB7CiAgICBjb25zdCBuYW1lID0gKE9iamVjdC5nZXRQcm90b3R5cGVPZihpbnB1dCkgKS5jb25zdHJ1Y3Rvci5uYW1lOwogICAgcmV0dXJuICFuYW1lIHx8IG5hbWUgPT09ICdPYmplY3QnOwogIH0gY2F0Y2ggKGUpIHsKICAgIHJldHVybiB0cnVlOwogIH0KfQoKLyoqCiAqIFVVSUQ0IGdlbmVyYXRvcgogKgogKiBAcmV0dXJucyBzdHJpbmcgR2VuZXJhdGVkIFVVSUQ0LgogKi8KZnVuY3Rpb24gdXVpZDQoKSB7CiAgY29uc3QgZ2JsID0gR0xPQkFMX09CSiA7CiAgY29uc3QgY3J5cHRvID0gZ2JsLmNyeXB0byB8fCBnYmwubXNDcnlwdG87CgogIGxldCBnZXRSYW5kb21CeXRlID0gKCkgPT4gTWF0aC5yYW5kb20oKSAqIDE2OwogIHRyeSB7CiAgICBpZiAoY3J5cHRvICYmIGNyeXB0by5yYW5kb21VVUlEKSB7CiAgICAgIHJldHVybiBjcnlwdG8ucmFuZG9tVVVJRCgpLnJlcGxhY2UoLy0vZywgJycpOwogICAgfQogICAgaWYgKGNyeXB0byAmJiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzKSB7CiAgICAgIGdldFJhbmRvbUJ5dGUgPSAoKSA9PiB7CiAgICAgICAgLy8gY3J5cHRvLmdldFJhbmRvbVZhbHVlcyBtaWdodCByZXR1cm4gdW5kZWZpbmVkIGluc3RlYWQgb2YgdGhlIHR5cGVkIGFycmF5CiAgICAgICAgLy8gaW4gb2xkIENocm9taXVtIHZlcnNpb25zIChlLmcuIDIzLjAuMTIzNS4wICgxNTE0MjIpKQogICAgICAgIC8vIEhvd2V2ZXIsIGB0eXBlZEFycmF5YCBpcyBzdGlsbCBmaWxsZWQgaW4tcGxhY2UuCiAgICAgICAgLy8gQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvQ3J5cHRvL2dldFJhbmRvbVZhbHVlcyN0eXBlZGFycmF5CiAgICAgICAgY29uc3QgdHlwZWRBcnJheSA9IG5ldyBVaW50OEFycmF5KDEpOwogICAgICAgIGNyeXB0by5nZXRSYW5kb21WYWx1ZXModHlwZWRBcnJheSk7CiAgICAgICAgcmV0dXJuIHR5cGVkQXJyYXlbMF07CiAgICAgIH07CiAgICB9CiAgfSBjYXRjaCAoXykgewogICAgLy8gc29tZSBydW50aW1lcyBjYW4gY3Jhc2ggaW52b2tpbmcgY3J5cHRvCiAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vZ2V0c2VudHJ5L3NlbnRyeS1qYXZhc2NyaXB0L2lzc3Vlcy84OTM1CiAgfQoKICAvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzEwNTAzNC9ob3ctdG8tY3JlYXRlLWEtZ3VpZC11dWlkLWluLWphdmFzY3JpcHQvMjExNzUyMyMyMTE3NTIzCiAgLy8gQ29uY2F0ZW5hdGluZyB0aGUgZm9sbG93aW5nIG51bWJlcnMgYXMgc3RyaW5ncyByZXN1bHRzIGluICcxMDAwMDAwMDEwMDA0MDAwODAwMDEwMDAwMDAwMDAwMCcKICByZXR1cm4gKChbMWU3XSApICsgMWUzICsgNGUzICsgOGUzICsgMWUxMSkucmVwbGFjZSgvWzAxOF0vZywgYyA9PgogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWJpdHdpc2UKICAgICgoYyApIF4gKChnZXRSYW5kb21CeXRlKCkgJiAxNSkgPj4gKChjICkgLyA0KSkpLnRvU3RyaW5nKDE2KSwKICApOwp9CgovKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLW1lbWJlci1hY2Nlc3MgKi8KLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWV4cGxpY2l0LWFueSAqLwoKLyoqCiAqIEhlbHBlciB0byBkZWN5Y2xlIGpzb24gb2JqZWN0cwogKi8KZnVuY3Rpb24gbWVtb0J1aWxkZXIoKSB7CiAgY29uc3QgaGFzV2Vha1NldCA9IHR5cGVvZiBXZWFrU2V0ID09PSAnZnVuY3Rpb24nOwogIGNvbnN0IGlubmVyID0gaGFzV2Vha1NldCA/IG5ldyBXZWFrU2V0KCkgOiBbXTsKICBmdW5jdGlvbiBtZW1vaXplKG9iaikgewogICAgaWYgKGhhc1dlYWtTZXQpIHsKICAgICAgaWYgKGlubmVyLmhhcyhvYmopKSB7CiAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgIH0KICAgICAgaW5uZXIuYWRkKG9iaik7CiAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvcHJlZmVyLWZvci1vZgogICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbm5lci5sZW5ndGg7IGkrKykgewogICAgICBjb25zdCB2YWx1ZSA9IGlubmVyW2ldOwogICAgICBpZiAodmFsdWUgPT09IG9iaikgewogICAgICAgIHJldHVybiB0cnVlOwogICAgICB9CiAgICB9CiAgICBpbm5lci5wdXNoKG9iaik7CiAgICByZXR1cm4gZmFsc2U7CiAgfQoKICBmdW5jdGlvbiB1bm1lbW9pemUob2JqKSB7CiAgICBpZiAoaGFzV2Vha1NldCkgewogICAgICBpbm5lci5kZWxldGUob2JqKTsKICAgIH0gZWxzZSB7CiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5uZXIubGVuZ3RoOyBpKyspIHsKICAgICAgICBpZiAoaW5uZXJbaV0gPT09IG9iaikgewogICAgICAgICAgaW5uZXIuc3BsaWNlKGksIDEpOwogICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgfQogIHJldHVybiBbbWVtb2l6ZSwgdW5tZW1vaXplXTsKfQoKLyoqCiAqIFJlY3Vyc2l2ZWx5IG5vcm1hbGl6ZXMgdGhlIGdpdmVuIG9iamVjdC4KICoKICogLSBDcmVhdGVzIGEgY29weSB0byBwcmV2ZW50IG9yaWdpbmFsIGlucHV0IG11dGF0aW9uCiAqIC0gU2tpcHMgbm9uLWVudW1lcmFibGUgcHJvcGVydGllcwogKiAtIFdoZW4gc3RyaW5naWZ5aW5nLCBjYWxscyBgdG9KU09OYCBpZiBpbXBsZW1lbnRlZAogKiAtIFJlbW92ZXMgY2lyY3VsYXIgcmVmZXJlbmNlcwogKiAtIFRyYW5zbGF0ZXMgbm9uLXNlcmlhbGl6YWJsZSB2YWx1ZXMgKGB1bmRlZmluZWRgL2BOYU5gL2Z1bmN0aW9ucykgdG8gc2VyaWFsaXphYmxlIGZvcm1hdAogKiAtIFRyYW5zbGF0ZXMga25vd24gZ2xvYmFsIG9iamVjdHMvY2xhc3NlcyB0byBhIHN0cmluZyByZXByZXNlbnRhdGlvbnMKICogLSBUYWtlcyBjYXJlIG9mIGBFcnJvcmAgb2JqZWN0IHNlcmlhbGl6YXRpb24KICogLSBPcHRpb25hbGx5IGxpbWl0cyBkZXB0aCBvZiBmaW5hbCBvdXRwdXQKICogLSBPcHRpb25hbGx5IGxpbWl0cyBudW1iZXIgb2YgcHJvcGVydGllcy9lbGVtZW50cyBpbmNsdWRlZCBpbiBhbnkgc2luZ2xlIG9iamVjdC9hcnJheQogKgogKiBAcGFyYW0gaW5wdXQgVGhlIG9iamVjdCB0byBiZSBub3JtYWxpemVkLgogKiBAcGFyYW0gZGVwdGggVGhlIG1heCBkZXB0aCB0byB3aGljaCB0byBub3JtYWxpemUgdGhlIG9iamVjdC4gKEFueXRoaW5nIGRlZXBlciBzdHJpbmdpZmllZCB3aG9sZS4pCiAqIEBwYXJhbSBtYXhQcm9wZXJ0aWVzIFRoZSBtYXggbnVtYmVyIG9mIGVsZW1lbnRzIG9yIHByb3BlcnRpZXMgdG8gYmUgaW5jbHVkZWQgaW4gYW55IHNpbmdsZSBhcnJheSBvcgogKiBvYmplY3QgaW4gdGhlIG5vcm1hbGxpemVkIG91dHB1dC4KICogQHJldHVybnMgQSBub3JtYWxpemVkIHZlcnNpb24gb2YgdGhlIG9iamVjdCwgb3IgYCIqKm5vbi1zZXJpYWxpemFibGUqKiJgIGlmIGFueSBlcnJvcnMgYXJlIHRocm93biBkdXJpbmcgbm9ybWFsaXphdGlvbi4KICovCi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55CmZ1bmN0aW9uIG5vcm1hbGl6ZShpbnB1dCwgZGVwdGggPSAxMDAsIG1heFByb3BlcnRpZXMgPSArSW5maW5pdHkpIHsKICB0cnkgewogICAgLy8gc2luY2Ugd2UncmUgYXQgdGhlIG91dGVybW9zdCBsZXZlbCwgd2UgZG9uJ3QgcHJvdmlkZSBhIGtleQogICAgcmV0dXJuIHZpc2l0KCcnLCBpbnB1dCwgZGVwdGgsIG1heFByb3BlcnRpZXMpOwogIH0gY2F0Y2ggKGVycikgewogICAgcmV0dXJuIHsgRVJST1I6IGAqKm5vbi1zZXJpYWxpemFibGUqKiAoJHtlcnJ9KWAgfTsKICB9Cn0KCi8qKgogKiBWaXNpdHMgYSBub2RlIHRvIHBlcmZvcm0gbm9ybWFsaXphdGlvbiBvbiBpdAogKgogKiBAcGFyYW0ga2V5IFRoZSBrZXkgY29ycmVzcG9uZGluZyB0byB0aGUgZ2l2ZW4gbm9kZQogKiBAcGFyYW0gdmFsdWUgVGhlIG5vZGUgdG8gYmUgdmlzaXRlZAogKiBAcGFyYW0gZGVwdGggT3B0aW9uYWwgbnVtYmVyIGluZGljYXRpbmcgdGhlIG1heGltdW0gcmVjdXJzaW9uIGRlcHRoCiAqIEBwYXJhbSBtYXhQcm9wZXJ0aWVzIE9wdGlvbmFsIG1heGltdW0gbnVtYmVyIG9mIHByb3BlcnRpZXMvZWxlbWVudHMgaW5jbHVkZWQgaW4gYW55IHNpbmdsZSBvYmplY3QvYXJyYXkKICogQHBhcmFtIG1lbW8gT3B0aW9uYWwgTWVtbyBjbGFzcyBoYW5kbGluZyBkZWN5Y2xpbmcKICovCmZ1bmN0aW9uIHZpc2l0KAogIGtleSwKICB2YWx1ZSwKICBkZXB0aCA9ICtJbmZpbml0eSwKICBtYXhQcm9wZXJ0aWVzID0gK0luZmluaXR5LAogIG1lbW8gPSBtZW1vQnVpbGRlcigpLAopIHsKICBjb25zdCBbbWVtb2l6ZSwgdW5tZW1vaXplXSA9IG1lbW87CgogIC8vIEdldCB0aGUgc2ltcGxlIGNhc2VzIG91dCBvZiB0aGUgd2F5IGZpcnN0CiAgaWYgKAogICAgdmFsdWUgPT0gbnVsbCB8fCAvLyB0aGlzIG1hdGNoZXMgbnVsbCBhbmQgdW5kZWZpbmVkIC0+IGVxZXEgbm90IGVxZXFlcQogICAgKFsnbnVtYmVyJywgJ2Jvb2xlYW4nLCAnc3RyaW5nJ10uaW5jbHVkZXModHlwZW9mIHZhbHVlKSAmJiAhaXNOYU4kMSh2YWx1ZSkpCiAgKSB7CiAgICByZXR1cm4gdmFsdWUgOwogIH0KCiAgY29uc3Qgc3RyaW5naWZpZWQgPSBzdHJpbmdpZnlWYWx1ZShrZXksIHZhbHVlKTsKCiAgLy8gQW55dGhpbmcgd2UgY291bGQgcG90ZW50aWFsbHkgZGlnIGludG8gbW9yZSAob2JqZWN0cyBvciBhcnJheXMpIHdpbGwgaGF2ZSBjb21lIGJhY2sgYXMgYCJbb2JqZWN0IFhYWFhdImAuCiAgLy8gRXZlcnl0aGluZyBlbHNlIHdpbGwgaGF2ZSBhbHJlYWR5IGJlZW4gc2VyaWFsaXplZCwgc28gaWYgd2UgZG9uJ3Qgc2VlIHRoYXQgcGF0dGVybiwgd2UncmUgZG9uZS4KICBpZiAoIXN0cmluZ2lmaWVkLnN0YXJ0c1dpdGgoJ1tvYmplY3QgJykpIHsKICAgIHJldHVybiBzdHJpbmdpZmllZDsKICB9CgogIC8vIEZyb20gaGVyZSBvbiwgd2UgY2FuIGFzc2VydCB0aGF0IGB2YWx1ZWAgaXMgZWl0aGVyIGFuIG9iamVjdCBvciBhbiBhcnJheS4KCiAgLy8gRG8gbm90IG5vcm1hbGl6ZSBvYmplY3RzIHRoYXQgd2Uga25vdyBoYXZlIGFscmVhZHkgYmVlbiBub3JtYWxpemVkLiBBcyBhIGdlbmVyYWwgcnVsZSwgdGhlCiAgLy8gIl9fc2VudHJ5X3NraXBfbm9ybWFsaXphdGlvbl9fIiBwcm9wZXJ0eSBzaG91bGQgb25seSBiZSB1c2VkIHNwYXJpbmdseSBhbmQgb25seSBzaG91bGQgb25seSBiZSBzZXQgb24gb2JqZWN0cyB0aGF0CiAgLy8gaGF2ZSBhbHJlYWR5IGJlZW4gbm9ybWFsaXplZC4KICBpZiAoKHZhbHVlIClbJ19fc2VudHJ5X3NraXBfbm9ybWFsaXphdGlvbl9fJ10pIHsKICAgIHJldHVybiB2YWx1ZSA7CiAgfQoKICAvLyBXZSBjYW4gc2V0IGBfX3NlbnRyeV9vdmVycmlkZV9ub3JtYWxpemF0aW9uX2RlcHRoX19gIG9uIGFuIG9iamVjdCB0byBlbnN1cmUgdGhhdCBmcm9tIHRoZXJlCiAgLy8gV2Uga2VlcCBhIGNlcnRhaW4gYW1vdW50IG9mIGRlcHRoLgogIC8vIFRoaXMgc2hvdWxkIGJlIHVzZWQgc3BhcmluZ2x5LCBlLmcuIHdlIHVzZSBpdCBmb3IgdGhlIHJlZHV4IGludGVncmF0aW9uIHRvIGVuc3VyZSB3ZSBnZXQgYSBjZXJ0YWluIGFtb3VudCBvZiBzdGF0ZS4KICBjb25zdCByZW1haW5pbmdEZXB0aCA9CiAgICB0eXBlb2YgKHZhbHVlIClbJ19fc2VudHJ5X292ZXJyaWRlX25vcm1hbGl6YXRpb25fZGVwdGhfXyddID09PSAnbnVtYmVyJwogICAgICA/ICgodmFsdWUgKVsnX19zZW50cnlfb3ZlcnJpZGVfbm9ybWFsaXphdGlvbl9kZXB0aF9fJ10gKQogICAgICA6IGRlcHRoOwoKICAvLyBXZSdyZSBhbHNvIGRvbmUgaWYgd2UndmUgcmVhY2hlZCB0aGUgbWF4IGRlcHRoCiAgaWYgKHJlbWFpbmluZ0RlcHRoID09PSAwKSB7CiAgICAvLyBBdCB0aGlzIHBvaW50IHdlIGtub3cgYHNlcmlhbGl6ZWRgIGlzIGEgc3RyaW5nIG9mIHRoZSBmb3JtIGAiW29iamVjdCBYWFhYXSJgLiBDbGVhbiBpdCB1cCBzbyBpdCdzIGp1c3QgYCJbWFhYWF0iYC4KICAgIHJldHVybiBzdHJpbmdpZmllZC5yZXBsYWNlKCdvYmplY3QgJywgJycpOwogIH0KCiAgLy8gSWYgd2UndmUgYWxyZWFkeSB2aXNpdGVkIHRoaXMgYnJhbmNoLCBiYWlsIG91dCwgYXMgaXQncyBjaXJjdWxhciByZWZlcmVuY2UuIElmIG5vdCwgbm90ZSB0aGF0IHdlJ3JlIHNlZWluZyBpdCBub3cuCiAgaWYgKG1lbW9pemUodmFsdWUpKSB7CiAgICByZXR1cm4gJ1tDaXJjdWxhciB+XSc7CiAgfQoKICAvLyBJZiB0aGUgdmFsdWUgaGFzIGEgYHRvSlNPTmAgbWV0aG9kLCB3ZSBjYWxsIGl0IHRvIGV4dHJhY3QgbW9yZSBpbmZvcm1hdGlvbgogIGNvbnN0IHZhbHVlV2l0aFRvSlNPTiA9IHZhbHVlIDsKICBpZiAodmFsdWVXaXRoVG9KU09OICYmIHR5cGVvZiB2YWx1ZVdpdGhUb0pTT04udG9KU09OID09PSAnZnVuY3Rpb24nKSB7CiAgICB0cnkgewogICAgICBjb25zdCBqc29uVmFsdWUgPSB2YWx1ZVdpdGhUb0pTT04udG9KU09OKCk7CiAgICAgIC8vIFdlIG5lZWQgdG8gbm9ybWFsaXplIHRoZSByZXR1cm4gdmFsdWUgb2YgYC50b0pTT04oKWAgaW4gY2FzZSBpdCBoYXMgY2lyY3VsYXIgcmVmZXJlbmNlcwogICAgICByZXR1cm4gdmlzaXQoJycsIGpzb25WYWx1ZSwgcmVtYWluaW5nRGVwdGggLSAxLCBtYXhQcm9wZXJ0aWVzLCBtZW1vKTsKICAgIH0gY2F0Y2ggKGVycikgewogICAgICAvLyBwYXNzIChUaGUgYnVpbHQtaW4gYHRvSlNPTmAgZmFpbGVkLCBidXQgd2UgY2FuIHN0aWxsIHRyeSB0byBkbyBpdCBvdXJzZWx2ZXMpCiAgICB9CiAgfQoKICAvLyBBdCB0aGlzIHBvaW50IHdlIGtub3cgd2UgZWl0aGVyIGhhdmUgYW4gb2JqZWN0IG9yIGFuIGFycmF5LCB3ZSBoYXZlbid0IHNlZW4gaXQgYmVmb3JlLCBhbmQgd2UncmUgZ29pbmcgdG8gcmVjdXJzZQogIC8vIGJlY2F1c2Ugd2UgaGF2ZW4ndCB5ZXQgcmVhY2hlZCB0aGUgbWF4IGRlcHRoLiBDcmVhdGUgYW4gYWNjdW11bGF0b3IgdG8gaG9sZCB0aGUgcmVzdWx0cyBvZiB2aXNpdGluZyBlYWNoCiAgLy8gcHJvcGVydHkvZW50cnksIGFuZCBrZWVwIHRyYWNrIG9mIHRoZSBudW1iZXIgb2YgaXRlbXMgd2UgYWRkIHRvIGl0LgogIGNvbnN0IG5vcm1hbGl6ZWQgPSAoQXJyYXkuaXNBcnJheSh2YWx1ZSkgPyBbXSA6IHt9KSA7CiAgbGV0IG51bUFkZGVkID0gMDsKCiAgLy8gQmVmb3JlIHdlIGJlZ2luLCBjb252ZXJ0YEVycm9yYCBhbmRgRXZlbnRgIGluc3RhbmNlcyBpbnRvIHBsYWluIG9iamVjdHMsIHNpbmNlIHNvbWUgb2YgZWFjaCBvZiB0aGVpciByZWxldmFudAogIC8vIHByb3BlcnRpZXMgYXJlIG5vbi1lbnVtZXJhYmxlIGFuZCBvdGhlcndpc2Ugd291bGQgZ2V0IG1pc3NlZC4KICBjb25zdCB2aXNpdGFibGUgPSBjb252ZXJ0VG9QbGFpbk9iamVjdCh2YWx1ZSApOwoKICBmb3IgKGNvbnN0IHZpc2l0S2V5IGluIHZpc2l0YWJsZSkgewogICAgLy8gQXZvaWQgaXRlcmF0aW5nIG92ZXIgZmllbGRzIGluIHRoZSBwcm90b3R5cGUgaWYgdGhleSd2ZSBzb21laG93IGJlZW4gZXhwb3NlZCB0byBlbnVtZXJhdGlvbi4KICAgIGlmICghT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHZpc2l0YWJsZSwgdmlzaXRLZXkpKSB7CiAgICAgIGNvbnRpbnVlOwogICAgfQoKICAgIGlmIChudW1BZGRlZCA+PSBtYXhQcm9wZXJ0aWVzKSB7CiAgICAgIG5vcm1hbGl6ZWRbdmlzaXRLZXldID0gJ1tNYXhQcm9wZXJ0aWVzIH5dJzsKICAgICAgYnJlYWs7CiAgICB9CgogICAgLy8gUmVjdXJzaXZlbHkgdmlzaXQgYWxsIHRoZSBjaGlsZCBub2RlcwogICAgY29uc3QgdmlzaXRWYWx1ZSA9IHZpc2l0YWJsZVt2aXNpdEtleV07CiAgICBub3JtYWxpemVkW3Zpc2l0S2V5XSA9IHZpc2l0KHZpc2l0S2V5LCB2aXNpdFZhbHVlLCByZW1haW5pbmdEZXB0aCAtIDEsIG1heFByb3BlcnRpZXMsIG1lbW8pOwoKICAgIG51bUFkZGVkKys7CiAgfQoKICAvLyBPbmNlIHdlJ3ZlIHZpc2l0ZWQgYWxsIHRoZSBicmFuY2hlcywgcmVtb3ZlIHRoZSBwYXJlbnQgZnJvbSBtZW1vIHN0b3JhZ2UKICB1bm1lbW9pemUodmFsdWUpOwoKICAvLyBSZXR1cm4gYWNjdW11bGF0ZWQgdmFsdWVzCiAgcmV0dXJuIG5vcm1hbGl6ZWQ7Cn0KCi8qIGVzbGludC1kaXNhYmxlIGNvbXBsZXhpdHkgKi8KLyoqCiAqIFN0cmluZ2lmeSB0aGUgZ2l2ZW4gdmFsdWUuIEhhbmRsZXMgdmFyaW91cyBrbm93biBzcGVjaWFsIHZhbHVlcyBhbmQgdHlwZXMuCiAqCiAqIE5vdCBtZWFudCB0byBiZSB1c2VkIG9uIHNpbXBsZSBwcmltaXRpdmVzIHdoaWNoIGFscmVhZHkgaGF2ZSBhIHN0cmluZyByZXByZXNlbnRhdGlvbiwgYXMgaXQgd2lsbCwgZm9yIGV4YW1wbGUsIHR1cm4KICogdGhlIG51bWJlciAxMjMxIGludG8gIltPYmplY3QgTnVtYmVyXSIsIG5vciBvbiBgbnVsbGAsIGFzIGl0IHdpbGwgdGhyb3cuCiAqCiAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gc3RyaW5naWZ5CiAqIEByZXR1cm5zIEEgc3RyaW5naWZpZWQgcmVwcmVzZW50YXRpb24gb2YgdGhlIGdpdmVuIHZhbHVlCiAqLwpmdW5jdGlvbiBzdHJpbmdpZnlWYWx1ZSgKICBrZXksCiAgLy8gdGhpcyB0eXBlIGlzIGEgdGlueSBiaXQgb2YgYSBjaGVhdCwgc2luY2UgdGhpcyBmdW5jdGlvbiBkb2VzIGhhbmRsZSBOYU4gKHdoaWNoIGlzIHRlY2huaWNhbGx5IGEgbnVtYmVyKSwgYnV0IGZvcgogIC8vIG91ciBpbnRlcm5hbCB1c2UsIGl0J2xsIGRvCiAgdmFsdWUsCikgewogIHRyeSB7CiAgICBpZiAoa2V5ID09PSAnZG9tYWluJyAmJiB2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmICh2YWx1ZSApLl9ldmVudHMpIHsKICAgICAgcmV0dXJuICdbRG9tYWluXSc7CiAgICB9CgogICAgaWYgKGtleSA9PT0gJ2RvbWFpbkVtaXR0ZXInKSB7CiAgICAgIHJldHVybiAnW0RvbWFpbkVtaXR0ZXJdJzsKICAgIH0KCiAgICAvLyBJdCdzIHNhZmUgdG8gdXNlIGBnbG9iYWxgLCBgd2luZG93YCwgYW5kIGBkb2N1bWVudGAgaGVyZSBpbiB0aGlzIG1hbm5lciwgYXMgd2UgYXJlIGFzc2VydGluZyB1c2luZyBgdHlwZW9mYCBmaXJzdAogICAgLy8gd2hpY2ggd29uJ3QgdGhyb3cgaWYgdGhleSBhcmUgbm90IHByZXNlbnQuCgogICAgaWYgKHR5cGVvZiBnbG9iYWwgIT09ICd1bmRlZmluZWQnICYmIHZhbHVlID09PSBnbG9iYWwpIHsKICAgICAgcmV0dXJuICdbR2xvYmFsXSc7CiAgICB9CgogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlc3RyaWN0ZWQtZ2xvYmFscwogICAgaWYgKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHZhbHVlID09PSB3aW5kb3cpIHsKICAgICAgcmV0dXJuICdbV2luZG93XSc7CiAgICB9CgogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLXJlc3RyaWN0ZWQtZ2xvYmFscwogICAgaWYgKHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcgJiYgdmFsdWUgPT09IGRvY3VtZW50KSB7CiAgICAgIHJldHVybiAnW0RvY3VtZW50XSc7CiAgICB9CgogICAgaWYgKGlzVnVlVmlld01vZGVsKHZhbHVlKSkgewogICAgICByZXR1cm4gJ1tWdWVWaWV3TW9kZWxdJzsKICAgIH0KCiAgICAvLyBSZWFjdCdzIFN5bnRoZXRpY0V2ZW50IHRoaW5neQogICAgaWYgKGlzU3ludGhldGljRXZlbnQodmFsdWUpKSB7CiAgICAgIHJldHVybiAnW1N5bnRoZXRpY0V2ZW50XSc7CiAgICB9CgogICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgJiYgdmFsdWUgIT09IHZhbHVlKSB7CiAgICAgIHJldHVybiAnW05hTl0nOwogICAgfQoKICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHsKICAgICAgcmV0dXJuIGBbRnVuY3Rpb246ICR7Z2V0RnVuY3Rpb25OYW1lKHZhbHVlKX1dYDsKICAgIH0KCiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3ltYm9sJykgewogICAgICByZXR1cm4gYFske1N0cmluZyh2YWx1ZSl9XWA7CiAgICB9CgogICAgLy8gc3RyaW5naWZpZWQgQmlnSW50cyBhcmUgaW5kaXN0aW5ndWlzaGFibGUgZnJvbSByZWd1bGFyIG51bWJlcnMsIHNvIHdlIG5lZWQgdG8gbGFiZWwgdGhlbSB0byBhdm9pZCBjb25mdXNpb24KICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdiaWdpbnQnKSB7CiAgICAgIHJldHVybiBgW0JpZ0ludDogJHtTdHJpbmcodmFsdWUpfV1gOwogICAgfQoKICAgIC8vIE5vdyB0aGF0IHdlJ3ZlIGtub2NrZWQgb3V0IGFsbCB0aGUgc3BlY2lhbCBjYXNlcyBhbmQgdGhlIHByaW1pdGl2ZXMsIGFsbCB3ZSBoYXZlIGxlZnQgYXJlIG9iamVjdHMuIFNpbXBseSBjYXN0aW5nCiAgICAvLyB0aGVtIHRvIHN0cmluZ3MgbWVhbnMgdGhhdCBpbnN0YW5jZXMgb2YgY2xhc3NlcyB3aGljaCBoYXZlbid0IGRlZmluZWQgdGhlaXIgYHRvU3RyaW5nVGFnYCB3aWxsIGp1c3QgY29tZSBvdXQgYXMKICAgIC8vIGAiW29iamVjdCBPYmplY3RdImAuIElmIHdlIGluc3RlYWQgbG9vayBhdCB0aGUgY29uc3RydWN0b3IncyBuYW1lICh3aGljaCBpcyB0aGUgc2FtZSBhcyB0aGUgbmFtZSBvZiB0aGUgY2xhc3MpLAogICAgLy8gd2UgY2FuIG1ha2Ugc3VyZSB0aGF0IG9ubHkgcGxhaW4gb2JqZWN0cyBjb21lIG91dCB0aGF0IHdheS4KICAgIGNvbnN0IG9iak5hbWUgPSBnZXRDb25zdHJ1Y3Rvck5hbWUodmFsdWUpOwoKICAgIC8vIEhhbmRsZSBIVE1MIEVsZW1lbnRzCiAgICBpZiAoL15IVE1MKFx3KilFbGVtZW50JC8udGVzdChvYmpOYW1lKSkgewogICAgICByZXR1cm4gYFtIVE1MRWxlbWVudDogJHtvYmpOYW1lfV1gOwogICAgfQoKICAgIHJldHVybiBgW29iamVjdCAke29iak5hbWV9XWA7CiAgfSBjYXRjaCAoZXJyKSB7CiAgICByZXR1cm4gYCoqbm9uLXNlcmlhbGl6YWJsZSoqICgke2Vycn0pYDsKICB9Cn0KLyogZXNsaW50LWVuYWJsZSBjb21wbGV4aXR5ICovCgpmdW5jdGlvbiBnZXRDb25zdHJ1Y3Rvck5hbWUodmFsdWUpIHsKICBjb25zdCBwcm90b3R5cGUgPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YodmFsdWUpOwoKICByZXR1cm4gcHJvdG90eXBlID8gcHJvdG90eXBlLmNvbnN0cnVjdG9yLm5hbWUgOiAnbnVsbCBwcm90b3R5cGUnOwp9CgovKioKICogTm9ybWFsaXplcyBVUkxzIGluIGV4Y2VwdGlvbnMgYW5kIHN0YWNrdHJhY2VzIHRvIGEgYmFzZSBwYXRoIHNvIFNlbnRyeSBjYW4gZmluZ2VycHJpbnQKICogYWNyb3NzIHBsYXRmb3JtcyBhbmQgd29ya2luZyBkaXJlY3RvcnkuCiAqCiAqIEBwYXJhbSB1cmwgVGhlIFVSTCB0byBiZSBub3JtYWxpemVkLgogKiBAcGFyYW0gYmFzZVBhdGggVGhlIGFwcGxpY2F0aW9uIGJhc2UgcGF0aC4KICogQHJldHVybnMgVGhlIG5vcm1hbGl6ZWQgVVJMLgogKi8KZnVuY3Rpb24gbm9ybWFsaXplVXJsVG9CYXNlKHVybCwgYmFzZVBhdGgpIHsKICBjb25zdCBlc2NhcGVkQmFzZSA9IGJhc2VQYXRoCiAgICAvLyBCYWNrc2xhc2ggdG8gZm9yd2FyZAogICAgLnJlcGxhY2UoL1xcL2csICcvJykKICAgIC8vIEVzY2FwZSBSZWdFeHAgc3BlY2lhbCBjaGFyYWN0ZXJzCiAgICAucmVwbGFjZSgvW3xcXHt9KClbXF1eJCsqPy5dL2csICdcXCQmJyk7CgogIGxldCBuZXdVcmwgPSB1cmw7CiAgdHJ5IHsKICAgIG5ld1VybCA9IGRlY29kZVVSSSh1cmwpOwogIH0gY2F0Y2ggKF9PbykgewogICAgLy8gU29tZXRpbWUgdGhpcyBicmVha3MKICB9CiAgcmV0dXJuICgKICAgIG5ld1VybAogICAgICAucmVwbGFjZSgvXFwvZywgJy8nKQogICAgICAucmVwbGFjZSgvd2VicGFjazpcLz8vZywgJycpIC8vIFJlbW92ZSBpbnRlcm1lZGlhdGUgYmFzZSBwYXRoCiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAc2VudHJ5LWludGVybmFsL3Nkay9uby1yZWdleHAtY29uc3RydWN0b3IKICAgICAgLnJlcGxhY2UobmV3IFJlZ0V4cChgKGZpbGU6Ly8pPy8qJHtlc2NhcGVkQmFzZX0vKmAsICdpZycpLCAnYXBwOi8vLycpCiAgKTsKfQoKLy8gU2xpZ2h0bHkgbW9kaWZpZWQgKG5vIElFOCBzdXBwb3J0LCBFUzYpIGFuZCB0cmFuc2NyaWJlZCB0byBUeXBlU2NyaXB0CgovLyBTcGxpdCBhIGZpbGVuYW1lIGludG8gW3Jvb3QsIGRpciwgYmFzZW5hbWUsIGV4dF0sIHVuaXggdmVyc2lvbgovLyAncm9vdCcgaXMganVzdCBhIHNsYXNoLCBvciBub3RoaW5nLgpjb25zdCBzcGxpdFBhdGhSZSA9IC9eKFxTKzpcXHxcLz8pKFtcc1xTXSo/KSgoPzpcLnsxLDJ9fFteL1xcXSs/fCkoXC5bXi4vXFxdKnwpKSg/OlsvXFxdKikkLzsKLyoqIEpTRG9jICovCmZ1bmN0aW9uIHNwbGl0UGF0aChmaWxlbmFtZSkgewogIC8vIFRydW5jYXRlIGZpbGVzIG5hbWVzIGdyZWF0ZXIgdGhhbiAxMDI0IGNoYXJhY3RlcnMgdG8gYXZvaWQgcmVnZXggZG9zCiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2dldHNlbnRyeS9zZW50cnktamF2YXNjcmlwdC9wdWxsLzg3MzcjZGlzY3Vzc2lvbl9yMTI4NTcxOTE3MgogIGNvbnN0IHRydW5jYXRlZCA9IGZpbGVuYW1lLmxlbmd0aCA+IDEwMjQgPyBgPHRydW5jYXRlZD4ke2ZpbGVuYW1lLnNsaWNlKC0xMDI0KX1gIDogZmlsZW5hbWU7CiAgY29uc3QgcGFydHMgPSBzcGxpdFBhdGhSZS5leGVjKHRydW5jYXRlZCk7CiAgcmV0dXJuIHBhcnRzID8gcGFydHMuc2xpY2UoMSkgOiBbXTsKfQoKLyoqIEpTRG9jICovCmZ1bmN0aW9uIGRpcm5hbWUocGF0aCkgewogIGNvbnN0IHJlc3VsdCA9IHNwbGl0UGF0aChwYXRoKTsKICBjb25zdCByb290ID0gcmVzdWx0WzBdOwogIGxldCBkaXIgPSByZXN1bHRbMV07CgogIGlmICghcm9vdCAmJiAhZGlyKSB7CiAgICAvLyBObyBkaXJuYW1lIHdoYXRzb2V2ZXIKICAgIHJldHVybiAnLic7CiAgfQoKICBpZiAoZGlyKSB7CiAgICAvLyBJdCBoYXMgYSBkaXJuYW1lLCBzdHJpcCB0cmFpbGluZyBzbGFzaAogICAgZGlyID0gZGlyLnNsaWNlKDAsIGRpci5sZW5ndGggLSAxKTsKICB9CgogIHJldHVybiByb290ICsgZGlyOwp9CgovKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvZXhwbGljaXQtZnVuY3Rpb24tcmV0dXJuLXR5cGUgKi8KCi8qKiBTeW5jUHJvbWlzZSBpbnRlcm5hbCBzdGF0ZXMgKi8KdmFyIFN0YXRlczsgKGZ1bmN0aW9uIChTdGF0ZXMpIHsKICAvKiogUGVuZGluZyAqLwogIGNvbnN0IFBFTkRJTkcgPSAwOyBTdGF0ZXNbU3RhdGVzWyJQRU5ESU5HIl0gPSBQRU5ESU5HXSA9ICJQRU5ESU5HIjsKICAvKiogUmVzb2x2ZWQgLyBPSyAqLwogIGNvbnN0IFJFU09MVkVEID0gMTsgU3RhdGVzW1N0YXRlc1siUkVTT0xWRUQiXSA9IFJFU09MVkVEXSA9ICJSRVNPTFZFRCI7CiAgLyoqIFJlamVjdGVkIC8gRXJyb3IgKi8KICBjb25zdCBSRUpFQ1RFRCA9IDI7IFN0YXRlc1tTdGF0ZXNbIlJFSkVDVEVEIl0gPSBSRUpFQ1RFRF0gPSAiUkVKRUNURUQiOwp9KShTdGF0ZXMgfHwgKFN0YXRlcyA9IHt9KSk7CgovLyBPdmVybG9hZHMgc28gd2UgY2FuIGNhbGwgcmVzb2x2ZWRTeW5jUHJvbWlzZSB3aXRob3V0IGFyZ3VtZW50cyBhbmQgZ2VuZXJpYyBhcmd1bWVudAoKLyoqCiAqIENyZWF0ZXMgYSByZXNvbHZlZCBzeW5jIHByb21pc2UuCiAqCiAqIEBwYXJhbSB2YWx1ZSB0aGUgdmFsdWUgdG8gcmVzb2x2ZSB0aGUgcHJvbWlzZSB3aXRoCiAqIEByZXR1cm5zIHRoZSByZXNvbHZlZCBzeW5jIHByb21pc2UKICovCmZ1bmN0aW9uIHJlc29sdmVkU3luY1Byb21pc2UodmFsdWUpIHsKICByZXR1cm4gbmV3IFN5bmNQcm9taXNlKHJlc29sdmUgPT4gewogICAgcmVzb2x2ZSh2YWx1ZSk7CiAgfSk7Cn0KCi8qKgogKiBDcmVhdGVzIGEgcmVqZWN0ZWQgc3luYyBwcm9taXNlLgogKgogKiBAcGFyYW0gdmFsdWUgdGhlIHZhbHVlIHRvIHJlamVjdCB0aGUgcHJvbWlzZSB3aXRoCiAqIEByZXR1cm5zIHRoZSByZWplY3RlZCBzeW5jIHByb21pc2UKICovCmZ1bmN0aW9uIHJlamVjdGVkU3luY1Byb21pc2UocmVhc29uKSB7CiAgcmV0dXJuIG5ldyBTeW5jUHJvbWlzZSgoXywgcmVqZWN0KSA9PiB7CiAgICByZWplY3QocmVhc29uKTsKICB9KTsKfQoKLyoqCiAqIFRoZW5hYmxlIGNsYXNzIHRoYXQgYmVoYXZlcyBsaWtlIGEgUHJvbWlzZSBhbmQgZm9sbG93cyBpdCdzIGludGVyZmFjZQogKiBidXQgaXMgbm90IGFzeW5jIGludGVybmFsbHkKICovCmNsYXNzIFN5bmNQcm9taXNlIHsKCiAgIGNvbnN0cnVjdG9yKAogICAgZXhlY3V0b3IsCiAgKSB7U3luY1Byb21pc2UucHJvdG90eXBlLl9faW5pdC5jYWxsKHRoaXMpO1N5bmNQcm9taXNlLnByb3RvdHlwZS5fX2luaXQyLmNhbGwodGhpcyk7U3luY1Byb21pc2UucHJvdG90eXBlLl9faW5pdDMuY2FsbCh0aGlzKTtTeW5jUHJvbWlzZS5wcm90b3R5cGUuX19pbml0NC5jYWxsKHRoaXMpOwogICAgdGhpcy5fc3RhdGUgPSBTdGF0ZXMuUEVORElORzsKICAgIHRoaXMuX2hhbmRsZXJzID0gW107CgogICAgdHJ5IHsKICAgICAgZXhlY3V0b3IodGhpcy5fcmVzb2x2ZSwgdGhpcy5fcmVqZWN0KTsKICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgdGhpcy5fcmVqZWN0KGUpOwogICAgfQogIH0KCiAgLyoqIEpTRG9jICovCiAgIHRoZW4oCiAgICBvbmZ1bGZpbGxlZCwKICAgIG9ucmVqZWN0ZWQsCiAgKSB7CiAgICByZXR1cm4gbmV3IFN5bmNQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHsKICAgICAgdGhpcy5faGFuZGxlcnMucHVzaChbCiAgICAgICAgZmFsc2UsCiAgICAgICAgcmVzdWx0ID0+IHsKICAgICAgICAgIGlmICghb25mdWxmaWxsZWQpIHsKICAgICAgICAgICAgLy8gVE9ETzogwq9cXyjjg4QpXy/CrwogICAgICAgICAgICAvLyBUT0RPOiBGSVhNRQogICAgICAgICAgICByZXNvbHZlKHJlc3VsdCApOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICByZXNvbHZlKG9uZnVsZmlsbGVkKHJlc3VsdCkpOwogICAgICAgICAgICB9IGNhdGNoIChlKSB7CiAgICAgICAgICAgICAgcmVqZWN0KGUpOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgICByZWFzb24gPT4gewogICAgICAgICAgaWYgKCFvbnJlamVjdGVkKSB7CiAgICAgICAgICAgIHJlamVjdChyZWFzb24pOwogICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdHJ5IHsKICAgICAgICAgICAgICByZXNvbHZlKG9ucmVqZWN0ZWQocmVhc29uKSk7CiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsKICAgICAgICAgICAgICByZWplY3QoZSk7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICB9LAogICAgICBdKTsKICAgICAgdGhpcy5fZXhlY3V0ZUhhbmRsZXJzKCk7CiAgICB9KTsKICB9CgogIC8qKiBKU0RvYyAqLwogICBjYXRjaCgKICAgIG9ucmVqZWN0ZWQsCiAgKSB7CiAgICByZXR1cm4gdGhpcy50aGVuKHZhbCA9PiB2YWwsIG9ucmVqZWN0ZWQpOwogIH0KCiAgLyoqIEpTRG9jICovCiAgIGZpbmFsbHkob25maW5hbGx5KSB7CiAgICByZXR1cm4gbmV3IFN5bmNQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHsKICAgICAgbGV0IHZhbDsKICAgICAgbGV0IGlzUmVqZWN0ZWQ7CgogICAgICByZXR1cm4gdGhpcy50aGVuKAogICAgICAgIHZhbHVlID0+IHsKICAgICAgICAgIGlzUmVqZWN0ZWQgPSBmYWxzZTsKICAgICAgICAgIHZhbCA9IHZhbHVlOwogICAgICAgICAgaWYgKG9uZmluYWxseSkgewogICAgICAgICAgICBvbmZpbmFsbHkoKTsKICAgICAgICAgIH0KICAgICAgICB9LAogICAgICAgIHJlYXNvbiA9PiB7CiAgICAgICAgICBpc1JlamVjdGVkID0gdHJ1ZTsKICAgICAgICAgIHZhbCA9IHJlYXNvbjsKICAgICAgICAgIGlmIChvbmZpbmFsbHkpIHsKICAgICAgICAgICAgb25maW5hbGx5KCk7CiAgICAgICAgICB9CiAgICAgICAgfSwKICAgICAgKS50aGVuKCgpID0+IHsKICAgICAgICBpZiAoaXNSZWplY3RlZCkgewogICAgICAgICAgcmVqZWN0KHZhbCk7CiAgICAgICAgICByZXR1cm47CiAgICAgICAgfQoKICAgICAgICByZXNvbHZlKHZhbCApOwogICAgICB9KTsKICAgIH0pOwogIH0KCiAgLyoqIEpTRG9jICovCiAgICBfX2luaXQoKSB7dGhpcy5fcmVzb2x2ZSA9ICh2YWx1ZSkgPT4gewogICAgdGhpcy5fc2V0UmVzdWx0KFN0YXRlcy5SRVNPTFZFRCwgdmFsdWUpOwogIH07fQoKICAvKiogSlNEb2MgKi8KICAgIF9faW5pdDIoKSB7dGhpcy5fcmVqZWN0ID0gKHJlYXNvbikgPT4gewogICAgdGhpcy5fc2V0UmVzdWx0KFN0YXRlcy5SRUpFQ1RFRCwgcmVhc29uKTsKICB9O30KCiAgLyoqIEpTRG9jICovCiAgICBfX2luaXQzKCkge3RoaXMuX3NldFJlc3VsdCA9IChzdGF0ZSwgdmFsdWUpID0+IHsKICAgIGlmICh0aGlzLl9zdGF0ZSAhPT0gU3RhdGVzLlBFTkRJTkcpIHsKICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmIChpc1RoZW5hYmxlKHZhbHVlKSkgewogICAgICB2b2lkICh2YWx1ZSApLnRoZW4odGhpcy5fcmVzb2x2ZSwgdGhpcy5fcmVqZWN0KTsKICAgICAgcmV0dXJuOwogICAgfQoKICAgIHRoaXMuX3N0YXRlID0gc3RhdGU7CiAgICB0aGlzLl92YWx1ZSA9IHZhbHVlOwoKICAgIHRoaXMuX2V4ZWN1dGVIYW5kbGVycygpOwogIH07fQoKICAvKiogSlNEb2MgKi8KICAgIF9faW5pdDQoKSB7dGhpcy5fZXhlY3V0ZUhhbmRsZXJzID0gKCkgPT4gewogICAgaWYgKHRoaXMuX3N0YXRlID09PSBTdGF0ZXMuUEVORElORykgewogICAgICByZXR1cm47CiAgICB9CgogICAgY29uc3QgY2FjaGVkSGFuZGxlcnMgPSB0aGlzLl9oYW5kbGVycy5zbGljZSgpOwogICAgdGhpcy5faGFuZGxlcnMgPSBbXTsKCiAgICBjYWNoZWRIYW5kbGVycy5mb3JFYWNoKGhhbmRsZXIgPT4gewogICAgICBpZiAoaGFuZGxlclswXSkgewogICAgICAgIHJldHVybjsKICAgICAgfQoKICAgICAgaWYgKHRoaXMuX3N0YXRlID09PSBTdGF0ZXMuUkVTT0xWRUQpIHsKICAgICAgICBoYW5kbGVyWzFdKHRoaXMuX3ZhbHVlICk7CiAgICAgIH0KCiAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gU3RhdGVzLlJFSkVDVEVEKSB7CiAgICAgICAgaGFuZGxlclsyXSh0aGlzLl92YWx1ZSk7CiAgICAgIH0KCiAgICAgIGhhbmRsZXJbMF0gPSB0cnVlOwogICAgfSk7CiAgfTt9Cn0KCi8qKgogKiBDcmVhdGVzIGFuIG5ldyBQcm9taXNlQnVmZmVyIG9iamVjdCB3aXRoIHRoZSBzcGVjaWZpZWQgbGltaXQKICogQHBhcmFtIGxpbWl0IG1heCBudW1iZXIgb2YgcHJvbWlzZXMgdGhhdCBjYW4gYmUgc3RvcmVkIGluIHRoZSBidWZmZXIKICovCmZ1bmN0aW9uIG1ha2VQcm9taXNlQnVmZmVyKGxpbWl0KSB7CiAgY29uc3QgYnVmZmVyID0gW107CgogIGZ1bmN0aW9uIGlzUmVhZHkoKSB7CiAgICByZXR1cm4gbGltaXQgPT09IHVuZGVmaW5lZCB8fCBidWZmZXIubGVuZ3RoIDwgbGltaXQ7CiAgfQoKICAvKioKICAgKiBSZW1vdmUgYSBwcm9taXNlIGZyb20gdGhlIHF1ZXVlLgogICAqCiAgICogQHBhcmFtIHRhc2sgQ2FuIGJlIGFueSBQcm9taXNlTGlrZTxUPgogICAqIEByZXR1cm5zIFJlbW92ZWQgcHJvbWlzZS4KICAgKi8KICBmdW5jdGlvbiByZW1vdmUodGFzaykgewogICAgcmV0dXJuIGJ1ZmZlci5zcGxpY2UoYnVmZmVyLmluZGV4T2YodGFzayksIDEpWzBdOwogIH0KCiAgLyoqCiAgICogQWRkIGEgcHJvbWlzZSAocmVwcmVzZW50aW5nIGFuIGluLWZsaWdodCBhY3Rpb24pIHRvIHRoZSBxdWV1ZSwgYW5kIHNldCBpdCB0byByZW1vdmUgaXRzZWxmIG9uIGZ1bGZpbGxtZW50LgogICAqCiAgICogQHBhcmFtIHRhc2tQcm9kdWNlciBBIGZ1bmN0aW9uIHByb2R1Y2luZyBhbnkgUHJvbWlzZUxpa2U8VD47IEluIHByZXZpb3VzIHZlcnNpb25zIHRoaXMgdXNlZCB0byBiZSBgdGFzazoKICAgKiAgICAgICAgUHJvbWlzZUxpa2U8VD5gLCBidXQgdW5kZXIgdGhhdCBtb2RlbCwgUHJvbWlzZXMgd2VyZSBpbnN0YW50bHkgY3JlYXRlZCBvbiB0aGUgY2FsbC1zaXRlIGFuZCB0aGVpciBleGVjdXRvcgogICAqICAgICAgICBmdW5jdGlvbnMgdGhlcmVmb3JlIHJhbiBpbW1lZGlhdGVseS4gVGh1cywgZXZlbiBpZiB0aGUgYnVmZmVyIHdhcyBmdWxsLCB0aGUgYWN0aW9uIHN0aWxsIGhhcHBlbmVkLiBCeQogICAqICAgICAgICByZXF1aXJpbmcgdGhlIHByb21pc2UgdG8gYmUgd3JhcHBlZCBpbiBhIGZ1bmN0aW9uLCB3ZSBjYW4gZGVmZXIgcHJvbWlzZSBjcmVhdGlvbiB1bnRpbCBhZnRlciB0aGUgYnVmZmVyCiAgICogICAgICAgIGxpbWl0IGNoZWNrLgogICAqIEByZXR1cm5zIFRoZSBvcmlnaW5hbCBwcm9taXNlLgogICAqLwogIGZ1bmN0aW9uIGFkZCh0YXNrUHJvZHVjZXIpIHsKICAgIGlmICghaXNSZWFkeSgpKSB7CiAgICAgIHJldHVybiByZWplY3RlZFN5bmNQcm9taXNlKG5ldyBTZW50cnlFcnJvcignTm90IGFkZGluZyBQcm9taXNlIGJlY2F1c2UgYnVmZmVyIGxpbWl0IHdhcyByZWFjaGVkLicpKTsKICAgIH0KCiAgICAvLyBzdGFydCB0aGUgdGFzayBhbmQgYWRkIGl0cyBwcm9taXNlIHRvIHRoZSBxdWV1ZQogICAgY29uc3QgdGFzayA9IHRhc2tQcm9kdWNlcigpOwogICAgaWYgKGJ1ZmZlci5pbmRleE9mKHRhc2spID09PSAtMSkgewogICAgICBidWZmZXIucHVzaCh0YXNrKTsKICAgIH0KICAgIHZvaWQgdGFzawogICAgICAudGhlbigoKSA9PiByZW1vdmUodGFzaykpCiAgICAgIC8vIFVzZSBgdGhlbihudWxsLCByZWplY3Rpb25IYW5kbGVyKWAgcmF0aGVyIHRoYW4gYGNhdGNoKHJlamVjdGlvbkhhbmRsZXIpYCBzbyB0aGF0IHdlIGNhbiB1c2UgYFByb21pc2VMaWtlYAogICAgICAvLyByYXRoZXIgdGhhbiBgUHJvbWlzZWAuIGBQcm9taXNlTGlrZWAgZG9lc24ndCBoYXZlIGEgYC5jYXRjaGAgbWV0aG9kLCBtYWtpbmcgaXRzIHBvbHlmaWxsIHNtYWxsZXIuIChFUzUgZGlkbid0CiAgICAgIC8vIGhhdmUgcHJvbWlzZXMsIHNvIFRTIGhhcyB0byBwb2x5ZmlsbCB3aGVuIGRvd24tY29tcGlsaW5nLikKICAgICAgLnRoZW4obnVsbCwgKCkgPT4KICAgICAgICByZW1vdmUodGFzaykudGhlbihudWxsLCAoKSA9PiB7CiAgICAgICAgICAvLyBXZSBoYXZlIHRvIGFkZCBhbm90aGVyIGNhdGNoIGhlcmUgYmVjYXVzZSBgcmVtb3ZlKClgIHN0YXJ0cyBhIG5ldyBwcm9taXNlIGNoYWluLgogICAgICAgIH0pLAogICAgICApOwogICAgcmV0dXJuIHRhc2s7CiAgfQoKICAvKioKICAgKiBXYWl0IGZvciBhbGwgcHJvbWlzZXMgaW4gdGhlIHF1ZXVlIHRvIHJlc29sdmUgb3IgZm9yIHRpbWVvdXQgdG8gZXhwaXJlLCB3aGljaGV2ZXIgY29tZXMgZmlyc3QuCiAgICoKICAgKiBAcGFyYW0gdGltZW91dCBUaGUgdGltZSwgaW4gbXMsIGFmdGVyIHdoaWNoIHRvIHJlc29sdmUgdG8gYGZhbHNlYCBpZiB0aGUgcXVldWUgaXMgc3RpbGwgbm9uLWVtcHR5LiBQYXNzaW5nIGAwYCAob3IKICAgKiBub3QgcGFzc2luZyBhbnl0aGluZykgd2lsbCBtYWtlIHRoZSBwcm9taXNlIHdhaXQgYXMgbG9uZyBhcyBpdCB0YWtlcyBmb3IgdGhlIHF1ZXVlIHRvIGRyYWluIGJlZm9yZSByZXNvbHZpbmcgdG8KICAgKiBgdHJ1ZWAuCiAgICogQHJldHVybnMgQSBwcm9taXNlIHdoaWNoIHdpbGwgcmVzb2x2ZSB0byBgdHJ1ZWAgaWYgdGhlIHF1ZXVlIGlzIGFscmVhZHkgZW1wdHkgb3IgZHJhaW5zIGJlZm9yZSB0aGUgdGltZW91dCwgYW5kCiAgICogYGZhbHNlYCBvdGhlcndpc2UKICAgKi8KICBmdW5jdGlvbiBkcmFpbih0aW1lb3V0KSB7CiAgICByZXR1cm4gbmV3IFN5bmNQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHsKICAgICAgbGV0IGNvdW50ZXIgPSBidWZmZXIubGVuZ3RoOwoKICAgICAgaWYgKCFjb3VudGVyKSB7CiAgICAgICAgcmV0dXJuIHJlc29sdmUodHJ1ZSk7CiAgICAgIH0KCiAgICAgIC8vIHdhaXQgZm9yIGB0aW1lb3V0YCBtcyBhbmQgdGhlbiByZXNvbHZlIHRvIGBmYWxzZWAgKGlmIG5vdCBjYW5jZWxsZWQgZmlyc3QpCiAgICAgIGNvbnN0IGNhcHR1cmVkU2V0VGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4gewogICAgICAgIGlmICh0aW1lb3V0ICYmIHRpbWVvdXQgPiAwKSB7CiAgICAgICAgICByZXNvbHZlKGZhbHNlKTsKICAgICAgICB9CiAgICAgIH0sIHRpbWVvdXQpOwoKICAgICAgLy8gaWYgYWxsIHByb21pc2VzIHJlc29sdmUgaW4gdGltZSwgY2FuY2VsIHRoZSB0aW1lciBhbmQgcmVzb2x2ZSB0byBgdHJ1ZWAKICAgICAgYnVmZmVyLmZvckVhY2goaXRlbSA9PiB7CiAgICAgICAgdm9pZCByZXNvbHZlZFN5bmNQcm9taXNlKGl0ZW0pLnRoZW4oKCkgPT4gewogICAgICAgICAgaWYgKCEtLWNvdW50ZXIpIHsKICAgICAgICAgICAgY2xlYXJUaW1lb3V0KGNhcHR1cmVkU2V0VGltZW91dCk7CiAgICAgICAgICAgIHJlc29sdmUodHJ1ZSk7CiAgICAgICAgICB9CiAgICAgICAgfSwgcmVqZWN0KTsKICAgICAgfSk7CiAgICB9KTsKICB9CgogIHJldHVybiB7CiAgICAkOiBidWZmZXIsCiAgICBhZGQsCiAgICBkcmFpbiwKICB9Owp9CgovKioKICogRG9lcyB0aGlzIGZpbGVuYW1lIGxvb2sgbGlrZSBpdCdzIHBhcnQgb2YgdGhlIGFwcCBjb2RlPwogKi8KZnVuY3Rpb24gZmlsZW5hbWVJc0luQXBwKGZpbGVuYW1lLCBpc05hdGl2ZSA9IGZhbHNlKSB7CiAgY29uc3QgaXNJbnRlcm5hbCA9CiAgICBpc05hdGl2ZSB8fAogICAgKGZpbGVuYW1lICYmCiAgICAgIC8vIEl0J3Mgbm90IGludGVybmFsIGlmIGl0J3MgYW4gYWJzb2x1dGUgbGludXggcGF0aAogICAgICAhZmlsZW5hbWUuc3RhcnRzV2l0aCgnLycpICYmCiAgICAgIC8vIEl0J3Mgbm90IGludGVybmFsIGlmIGl0J3MgYW4gYWJzb2x1dGUgd2luZG93cyBwYXRoCiAgICAgICFmaWxlbmFtZS5tYXRjaCgvXltBLVpdOi8pICYmCiAgICAgIC8vIEl0J3Mgbm90IGludGVybmFsIGlmIHRoZSBwYXRoIGlzIHN0YXJ0aW5nIHdpdGggYSBkb3QKICAgICAgIWZpbGVuYW1lLnN0YXJ0c1dpdGgoJy4nKSAmJgogICAgICAvLyBJdCdzIG5vdCBpbnRlcm5hbCBpZiB0aGUgZnJhbWUgaGFzIGEgcHJvdG9jb2wuIEluIG5vZGUsIHRoaXMgaXMgdXN1YWxseSB0aGUgY2FzZSBpZiB0aGUgZmlsZSBnb3QgcHJlLXByb2Nlc3NlZCB3aXRoIGEgYnVuZGxlciBsaWtlIHdlYnBhY2sKICAgICAgIWZpbGVuYW1lLm1hdGNoKC9eW2EtekEtWl0oW2EtekEtWjAtOS5cLStdKSo6XC9cLy8pKTsgLy8gU2NoZW1hIGZyb206IGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8zNjQxNzgyCgogIC8vIGluX2FwcCBpcyBhbGwgdGhhdCdzIG5vdCBhbiBpbnRlcm5hbCBOb2RlIGZ1bmN0aW9uIG9yIGEgbW9kdWxlIHdpdGhpbiBub2RlX21vZHVsZXMKICAvLyBub3RlIHRoYXQgaXNOYXRpdmUgYXBwZWFycyB0byByZXR1cm4gdHJ1ZSBldmVuIGZvciBub2RlIGNvcmUgbGlicmFyaWVzCiAgLy8gc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9nZXRzZW50cnkvcmF2ZW4tbm9kZS9pc3N1ZXMvMTc2CgogIHJldHVybiAhaXNJbnRlcm5hbCAmJiBmaWxlbmFtZSAhPT0gdW5kZWZpbmVkICYmICFmaWxlbmFtZS5pbmNsdWRlcygnbm9kZV9tb2R1bGVzLycpOwp9Cgpjb25zdCBPTkVfU0VDT05EX0lOX01TID0gMTAwMDsKCi8qKgogKiBBIHBhcnRpYWwgZGVmaW5pdGlvbiBvZiB0aGUgW1BlcmZvcm1hbmNlIFdlYiBBUElde0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9QZXJmb3JtYW5jZX0KICogZm9yIGFjY2Vzc2luZyBhIGhpZ2gtcmVzb2x1dGlvbiBtb25vdG9uaWMgY2xvY2suCiAqLwoKLyoqCiAqIFJldHVybnMgYSB0aW1lc3RhbXAgaW4gc2Vjb25kcyBzaW5jZSB0aGUgVU5JWCBlcG9jaCB1c2luZyB0aGUgRGF0ZSBBUEkuCiAqCiAqIFRPRE8odjgpOiBSZXR1cm4gdHlwZSBzaG91bGQgYmUgcm91bmRlZC4KICovCmZ1bmN0aW9uIGRhdGVUaW1lc3RhbXBJblNlY29uZHMoKSB7CiAgcmV0dXJuIERhdGUubm93KCkgLyBPTkVfU0VDT05EX0lOX01TOwp9CgovKioKICogUmV0dXJucyBhIHdyYXBwZXIgYXJvdW5kIHRoZSBuYXRpdmUgUGVyZm9ybWFuY2UgQVBJIGJyb3dzZXIgaW1wbGVtZW50YXRpb24sIG9yIHVuZGVmaW5lZCBmb3IgYnJvd3NlcnMgdGhhdCBkbyBub3QKICogc3VwcG9ydCB0aGUgQVBJLgogKgogKiBXcmFwcGluZyB0aGUgbmF0aXZlIEFQSSB3b3JrcyBhcm91bmQgZGlmZmVyZW5jZXMgaW4gYmVoYXZpb3IgZnJvbSBkaWZmZXJlbnQgYnJvd3NlcnMuCiAqLwpmdW5jdGlvbiBjcmVhdGVVbml4VGltZXN0YW1wSW5TZWNvbmRzRnVuYygpIHsKICBjb25zdCB7IHBlcmZvcm1hbmNlIH0gPSBHTE9CQUxfT0JKIDsKICBpZiAoIXBlcmZvcm1hbmNlIHx8ICFwZXJmb3JtYW5jZS5ub3cpIHsKICAgIHJldHVybiBkYXRlVGltZXN0YW1wSW5TZWNvbmRzOwogIH0KCiAgLy8gU29tZSBicm93c2VyIGFuZCBlbnZpcm9ubWVudHMgZG9uJ3QgaGF2ZSBhIHRpbWVPcmlnaW4sIHNvIHdlIGZhbGxiYWNrIHRvCiAgLy8gdXNpbmcgRGF0ZS5ub3coKSB0byBjb21wdXRlIHRoZSBzdGFydGluZyB0aW1lLgogIGNvbnN0IGFwcHJveFN0YXJ0aW5nVGltZU9yaWdpbiA9IERhdGUubm93KCkgLSBwZXJmb3JtYW5jZS5ub3coKTsKICBjb25zdCB0aW1lT3JpZ2luID0gcGVyZm9ybWFuY2UudGltZU9yaWdpbiA9PSB1bmRlZmluZWQgPyBhcHByb3hTdGFydGluZ1RpbWVPcmlnaW4gOiBwZXJmb3JtYW5jZS50aW1lT3JpZ2luOwoKICAvLyBwZXJmb3JtYW5jZS5ub3coKSBpcyBhIG1vbm90b25pYyBjbG9jaywgd2hpY2ggbWVhbnMgaXQgc3RhcnRzIGF0IDAgd2hlbiB0aGUgcHJvY2VzcyBiZWdpbnMuIFRvIGdldCB0aGUgY3VycmVudAogIC8vIHdhbGwgY2xvY2sgdGltZSAoYWN0dWFsIFVOSVggdGltZXN0YW1wKSwgd2UgbmVlZCB0byBhZGQgdGhlIHN0YXJ0aW5nIHRpbWUgb3JpZ2luIGFuZCB0aGUgY3VycmVudCB0aW1lIGVsYXBzZWQuCiAgLy8KICAvLyBUT0RPOiBUaGlzIGRvZXMgbm90IGFjY291bnQgZm9yIHRoZSBjYXNlIHdoZXJlIHRoZSBtb25vdG9uaWMgY2xvY2sgdGhhdCBwb3dlcnMgcGVyZm9ybWFuY2Uubm93KCkgZHJpZnRzIGZyb20gdGhlCiAgLy8gd2FsbCBjbG9jayB0aW1lLCB3aGljaCBjYXVzZXMgdGhlIHJldHVybmVkIHRpbWVzdGFtcCB0byBiZSBpbmFjY3VyYXRlLiBXZSBzaG91bGQgaW52ZXN0aWdhdGUgaG93IHRvIGRldGVjdCBhbmQKICAvLyBjb3JyZWN0IGZvciB0aGlzLgogIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL2dldHNlbnRyeS9zZW50cnktamF2YXNjcmlwdC9pc3N1ZXMvMjU5MAogIC8vIFNlZTogaHR0cHM6Ly9naXRodWIuY29tL21kbi9jb250ZW50L2lzc3Vlcy80NzEzCiAgLy8gU2VlOiBodHRwczovL2Rldi50by9ub2Ftci93aGVuLWEtbWlsbGlzZWNvbmQtaXMtbm90LWEtbWlsbGlzZWNvbmQtM2g2CiAgcmV0dXJuICgpID0+IHsKICAgIHJldHVybiAodGltZU9yaWdpbiArIHBlcmZvcm1hbmNlLm5vdygpKSAvIE9ORV9TRUNPTkRfSU5fTVM7CiAgfTsKfQoKLyoqCiAqIFJldHVybnMgYSB0aW1lc3RhbXAgaW4gc2Vjb25kcyBzaW5jZSB0aGUgVU5JWCBlcG9jaCB1c2luZyBlaXRoZXIgdGhlIFBlcmZvcm1hbmNlIG9yIERhdGUgQVBJcywgZGVwZW5kaW5nIG9uIHRoZQogKiBhdmFpbGFiaWxpdHkgb2YgdGhlIFBlcmZvcm1hbmNlIEFQSS4KICoKICogQlVHOiBOb3RlIHRoYXQgYmVjYXVzZSBvZiBob3cgYnJvd3NlcnMgaW1wbGVtZW50IHRoZSBQZXJmb3JtYW5jZSBBUEksIHRoZSBjbG9jayBtaWdodCBzdG9wIHdoZW4gdGhlIGNvbXB1dGVyIGlzCiAqIGFzbGVlcC4gVGhpcyBjcmVhdGVzIGEgc2tldyBiZXR3ZWVuIGBkYXRlVGltZXN0YW1wSW5TZWNvbmRzYCBhbmQgYHRpbWVzdGFtcEluU2Vjb25kc2AuIFRoZQogKiBza2V3IGNhbiBncm93IHRvIGFyYml0cmFyeSBhbW91bnRzIGxpa2UgZGF5cywgd2Vla3Mgb3IgbW9udGhzLgogKiBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2dldHNlbnRyeS9zZW50cnktamF2YXNjcmlwdC9pc3N1ZXMvMjU5MC4KICovCmNvbnN0IHRpbWVzdGFtcEluU2Vjb25kcyA9IGNyZWF0ZVVuaXhUaW1lc3RhbXBJblNlY29uZHNGdW5jKCk7CgovKioKICogVGhlIG51bWJlciBvZiBtaWxsaXNlY29uZHMgc2luY2UgdGhlIFVOSVggZXBvY2guIFRoaXMgdmFsdWUgaXMgb25seSB1c2FibGUgaW4gYSBicm93c2VyLCBhbmQgb25seSB3aGVuIHRoZQogKiBwZXJmb3JtYW5jZSBBUEkgaXMgYXZhaWxhYmxlLgogKi8KKCgpID0+IHsKICAvLyBVbmZvcnR1bmF0ZWx5IGJyb3dzZXJzIG1heSByZXBvcnQgYW4gaW5hY2N1cmF0ZSB0aW1lIG9yaWdpbiBkYXRhLCB0aHJvdWdoIGVpdGhlciBwZXJmb3JtYW5jZS50aW1lT3JpZ2luIG9yCiAgLy8gcGVyZm9ybWFuY2UudGltaW5nLm5hdmlnYXRpb25TdGFydCwgd2hpY2ggcmVzdWx0cyBpbiBwb29yIHJlc3VsdHMgaW4gcGVyZm9ybWFuY2UgZGF0YS4gV2Ugb25seSB0cmVhdCB0aW1lIG9yaWdpbgogIC8vIGRhdGEgYXMgcmVsaWFibGUgaWYgdGhleSBhcmUgd2l0aGluIGEgcmVhc29uYWJsZSB0aHJlc2hvbGQgb2YgdGhlIGN1cnJlbnQgdGltZS4KCiAgY29uc3QgeyBwZXJmb3JtYW5jZSB9ID0gR0xPQkFMX09CSiA7CiAgaWYgKCFwZXJmb3JtYW5jZSB8fCAhcGVyZm9ybWFuY2Uubm93KSB7CiAgICByZXR1cm4gdW5kZWZpbmVkOwogIH0KCiAgY29uc3QgdGhyZXNob2xkID0gMzYwMCAqIDEwMDA7CiAgY29uc3QgcGVyZm9ybWFuY2VOb3cgPSBwZXJmb3JtYW5jZS5ub3coKTsKICBjb25zdCBkYXRlTm93ID0gRGF0ZS5ub3coKTsKCiAgLy8gaWYgdGltZU9yaWdpbiBpc24ndCBhdmFpbGFibGUgc2V0IGRlbHRhIHRvIHRocmVzaG9sZCBzbyBpdCBpc24ndCB1c2VkCiAgY29uc3QgdGltZU9yaWdpbkRlbHRhID0gcGVyZm9ybWFuY2UudGltZU9yaWdpbgogICAgPyBNYXRoLmFicyhwZXJmb3JtYW5jZS50aW1lT3JpZ2luICsgcGVyZm9ybWFuY2VOb3cgLSBkYXRlTm93KQogICAgOiB0aHJlc2hvbGQ7CiAgY29uc3QgdGltZU9yaWdpbklzUmVsaWFibGUgPSB0aW1lT3JpZ2luRGVsdGEgPCB0aHJlc2hvbGQ7CgogIC8vIFdoaWxlIHBlcmZvcm1hbmNlLnRpbWluZy5uYXZpZ2F0aW9uU3RhcnQgaXMgZGVwcmVjYXRlZCBpbiBmYXZvciBvZiBwZXJmb3JtYW5jZS50aW1lT3JpZ2luLCBwZXJmb3JtYW5jZS50aW1lT3JpZ2luCiAgLy8gaXMgbm90IGFzIHdpZGVseSBzdXBwb3J0ZWQuIE5hbWVseSwgcGVyZm9ybWFuY2UudGltZU9yaWdpbiBpcyB1bmRlZmluZWQgaW4gU2FmYXJpIGFzIG9mIHdyaXRpbmcuCiAgLy8gQWxzbyBhcyBvZiB3cml0aW5nLCBwZXJmb3JtYW5jZS50aW1pbmcgaXMgbm90IGF2YWlsYWJsZSBpbiBXZWIgV29ya2VycyBpbiBtYWluc3RyZWFtIGJyb3dzZXJzLCBzbyBpdCBpcyBub3QgYWx3YXlzCiAgLy8gYSB2YWxpZCBmYWxsYmFjay4gSW4gdGhlIGFic2VuY2Ugb2YgYW4gaW5pdGlhbCB0aW1lIHByb3ZpZGVkIGJ5IHRoZSBicm93c2VyLCBmYWxsYmFjayB0byB0aGUgY3VycmVudCB0aW1lIGZyb20gdGhlCiAgLy8gRGF0ZSBBUEkuCiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGRlcHJlY2F0aW9uL2RlcHJlY2F0aW9uCiAgY29uc3QgbmF2aWdhdGlvblN0YXJ0ID0gcGVyZm9ybWFuY2UudGltaW5nICYmIHBlcmZvcm1hbmNlLnRpbWluZy5uYXZpZ2F0aW9uU3RhcnQ7CiAgY29uc3QgaGFzTmF2aWdhdGlvblN0YXJ0ID0gdHlwZW9mIG5hdmlnYXRpb25TdGFydCA9PT0gJ251bWJlcic7CiAgLy8gaWYgbmF2aWdhdGlvblN0YXJ0IGlzbid0IGF2YWlsYWJsZSBzZXQgZGVsdGEgdG8gdGhyZXNob2xkIHNvIGl0IGlzbid0IHVzZWQKICBjb25zdCBuYXZpZ2F0aW9uU3RhcnREZWx0YSA9IGhhc05hdmlnYXRpb25TdGFydCA/IE1hdGguYWJzKG5hdmlnYXRpb25TdGFydCArIHBlcmZvcm1hbmNlTm93IC0gZGF0ZU5vdykgOiB0aHJlc2hvbGQ7CiAgY29uc3QgbmF2aWdhdGlvblN0YXJ0SXNSZWxpYWJsZSA9IG5hdmlnYXRpb25TdGFydERlbHRhIDwgdGhyZXNob2xkOwoKICBpZiAodGltZU9yaWdpbklzUmVsaWFibGUgfHwgbmF2aWdhdGlvblN0YXJ0SXNSZWxpYWJsZSkgewogICAgLy8gVXNlIHRoZSBtb3JlIHJlbGlhYmxlIHRpbWUgb3JpZ2luCiAgICBpZiAodGltZU9yaWdpbkRlbHRhIDw9IG5hdmlnYXRpb25TdGFydERlbHRhKSB7CiAgICAgIHJldHVybiBwZXJmb3JtYW5jZS50aW1lT3JpZ2luOwogICAgfSBlbHNlIHsKICAgICAgcmV0dXJuIG5hdmlnYXRpb25TdGFydDsKICAgIH0KICB9CiAgcmV0dXJuIGRhdGVOb3c7Cn0pKCk7CgovKioKICogQ3JlYXRlcyBhbiBlbnZlbG9wZS4KICogTWFrZSBzdXJlIHRvIGFsd2F5cyBleHBsaWNpdGx5IHByb3ZpZGUgdGhlIGdlbmVyaWMgdG8gdGhpcyBmdW5jdGlvbgogKiBzbyB0aGF0IHRoZSBlbnZlbG9wZSB0eXBlcyByZXNvbHZlIGNvcnJlY3RseS4KICovCmZ1bmN0aW9uIGNyZWF0ZUVudmVsb3BlKGhlYWRlcnMsIGl0ZW1zID0gW10pIHsKICByZXR1cm4gW2hlYWRlcnMsIGl0ZW1zXSA7Cn0KCi8qKgogKiBDb252ZW5pZW5jZSBmdW5jdGlvbiB0byBsb29wIHRocm91Z2ggdGhlIGl0ZW1zIGFuZCBpdGVtIHR5cGVzIG9mIGFuIGVudmVsb3BlLgogKiAoVGhpcyBmdW5jdGlvbiB3YXMgbW9zdGx5IGNyZWF0ZWQgYmVjYXVzZSB3b3JraW5nIHdpdGggZW52ZWxvcGUgdHlwZXMgaXMgcGFpbmZ1bCBhdCB0aGUgbW9tZW50KQogKgogKiBJZiB0aGUgY2FsbGJhY2sgcmV0dXJucyB0cnVlLCB0aGUgcmVzdCBvZiB0aGUgaXRlbXMgd2lsbCBiZSBza2lwcGVkLgogKi8KZnVuY3Rpb24gZm9yRWFjaEVudmVsb3BlSXRlbSgKICBlbnZlbG9wZSwKICBjYWxsYmFjaywKKSB7CiAgY29uc3QgZW52ZWxvcGVJdGVtcyA9IGVudmVsb3BlWzFdOwoKICBmb3IgKGNvbnN0IGVudmVsb3BlSXRlbSBvZiBlbnZlbG9wZUl0ZW1zKSB7CiAgICBjb25zdCBlbnZlbG9wZUl0ZW1UeXBlID0gZW52ZWxvcGVJdGVtWzBdLnR5cGU7CiAgICBjb25zdCByZXN1bHQgPSBjYWxsYmFjayhlbnZlbG9wZUl0ZW0sIGVudmVsb3BlSXRlbVR5cGUpOwoKICAgIGlmIChyZXN1bHQpIHsKICAgICAgcmV0dXJuIHRydWU7CiAgICB9CiAgfQoKICByZXR1cm4gZmFsc2U7Cn0KCi8qKgogKiBFbmNvZGUgYSBzdHJpbmcgdG8gVVRGOCBhcnJheS4KICovCmZ1bmN0aW9uIGVuY29kZVVURjgoaW5wdXQpIHsKICByZXR1cm4gbmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKGlucHV0KTsKfQoKLyoqCiAqIFNlcmlhbGl6ZXMgYW4gZW52ZWxvcGUuCiAqLwpmdW5jdGlvbiBzZXJpYWxpemVFbnZlbG9wZShlbnZlbG9wZSkgewogIGNvbnN0IFtlbnZIZWFkZXJzLCBpdGVtc10gPSBlbnZlbG9wZTsKCiAgLy8gSW5pdGlhbGx5IHdlIGNvbnN0cnVjdCBvdXIgZW52ZWxvcGUgYXMgYSBzdHJpbmcgYW5kIG9ubHkgY29udmVydCB0byBiaW5hcnkgY2h1bmtzIGlmIHdlIGVuY291bnRlciBiaW5hcnkgZGF0YQogIGxldCBwYXJ0cyA9IEpTT04uc3RyaW5naWZ5KGVudkhlYWRlcnMpOwoKICBmdW5jdGlvbiBhcHBlbmQobmV4dCkgewogICAgaWYgKHR5cGVvZiBwYXJ0cyA9PT0gJ3N0cmluZycpIHsKICAgICAgcGFydHMgPSB0eXBlb2YgbmV4dCA9PT0gJ3N0cmluZycgPyBwYXJ0cyArIG5leHQgOiBbZW5jb2RlVVRGOChwYXJ0cyksIG5leHRdOwogICAgfSBlbHNlIHsKICAgICAgcGFydHMucHVzaCh0eXBlb2YgbmV4dCA9PT0gJ3N0cmluZycgPyBlbmNvZGVVVEY4KG5leHQpIDogbmV4dCk7CiAgICB9CiAgfQoKICBmb3IgKGNvbnN0IGl0ZW0gb2YgaXRlbXMpIHsKICAgIGNvbnN0IFtpdGVtSGVhZGVycywgcGF5bG9hZF0gPSBpdGVtOwoKICAgIGFwcGVuZChgXG4ke0pTT04uc3RyaW5naWZ5KGl0ZW1IZWFkZXJzKX1cbmApOwoKICAgIGlmICh0eXBlb2YgcGF5bG9hZCA9PT0gJ3N0cmluZycgfHwgcGF5bG9hZCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpIHsKICAgICAgYXBwZW5kKHBheWxvYWQpOwogICAgfSBlbHNlIHsKICAgICAgbGV0IHN0cmluZ2lmaWVkUGF5bG9hZDsKICAgICAgdHJ5IHsKICAgICAgICBzdHJpbmdpZmllZFBheWxvYWQgPSBKU09OLnN0cmluZ2lmeShwYXlsb2FkKTsKICAgICAgfSBjYXRjaCAoZSkgewogICAgICAgIC8vIEluIGNhc2UsIGRlc3BpdGUgYWxsIG91ciBlZmZvcnRzIHRvIGtlZXAgYHBheWxvYWRgIGNpcmN1bGFyLWRlcGVuZGVuY3ktZnJlZSwgYEpTT04uc3RyaW5pZnkoKWAgc3RpbGwKICAgICAgICAvLyBmYWlscywgd2UgdHJ5IGFnYWluIGFmdGVyIG5vcm1hbGl6aW5nIGl0IGFnYWluIHdpdGggaW5maW5pdGUgbm9ybWFsaXphdGlvbiBkZXB0aC4gVGhpcyBvZiBjb3Vyc2UgaGFzIGEKICAgICAgICAvLyBwZXJmb3JtYW5jZSBpbXBhY3QgYnV0IGluIHRoaXMgY2FzZSBhIHBlcmZvcm1hbmNlIGhpdCBpcyBiZXR0ZXIgdGhhbiB0aHJvd2luZy4KICAgICAgICBzdHJpbmdpZmllZFBheWxvYWQgPSBKU09OLnN0cmluZ2lmeShub3JtYWxpemUocGF5bG9hZCkpOwogICAgICB9CiAgICAgIGFwcGVuZChzdHJpbmdpZmllZFBheWxvYWQpOwogICAgfQogIH0KCiAgcmV0dXJuIHR5cGVvZiBwYXJ0cyA9PT0gJ3N0cmluZycgPyBwYXJ0cyA6IGNvbmNhdEJ1ZmZlcnMocGFydHMpOwp9CgpmdW5jdGlvbiBjb25jYXRCdWZmZXJzKGJ1ZmZlcnMpIHsKICBjb25zdCB0b3RhbExlbmd0aCA9IGJ1ZmZlcnMucmVkdWNlKChhY2MsIGJ1ZikgPT4gYWNjICsgYnVmLmxlbmd0aCwgMCk7CgogIGNvbnN0IG1lcmdlZCA9IG5ldyBVaW50OEFycmF5KHRvdGFsTGVuZ3RoKTsKICBsZXQgb2Zmc2V0ID0gMDsKICBmb3IgKGNvbnN0IGJ1ZmZlciBvZiBidWZmZXJzKSB7CiAgICBtZXJnZWQuc2V0KGJ1ZmZlciwgb2Zmc2V0KTsKICAgIG9mZnNldCArPSBidWZmZXIubGVuZ3RoOwogIH0KCiAgcmV0dXJuIG1lcmdlZDsKfQoKY29uc3QgSVRFTV9UWVBFX1RPX0RBVEFfQ0FURUdPUllfTUFQID0gewogIHNlc3Npb246ICdzZXNzaW9uJywKICBzZXNzaW9uczogJ3Nlc3Npb24nLAogIGF0dGFjaG1lbnQ6ICdhdHRhY2htZW50JywKICB0cmFuc2FjdGlvbjogJ3RyYW5zYWN0aW9uJywKICBldmVudDogJ2Vycm9yJywKICBjbGllbnRfcmVwb3J0OiAnaW50ZXJuYWwnLAogIHVzZXJfcmVwb3J0OiAnZGVmYXVsdCcsCiAgcHJvZmlsZTogJ3Byb2ZpbGUnLAogIHJlcGxheV9ldmVudDogJ3JlcGxheScsCiAgcmVwbGF5X3JlY29yZGluZzogJ3JlcGxheScsCiAgY2hlY2tfaW46ICdtb25pdG9yJywKICBmZWVkYmFjazogJ2ZlZWRiYWNrJywKICAvLyBUT0RPOiBUaGlzIGlzIGEgdGVtcG9yYXJ5IHdvcmthcm91bmQgdW50aWwgd2UgaGF2ZSBhIHByb3BlciBkYXRhIGNhdGVnb3J5IGZvciBtZXRyaWNzCiAgc3RhdHNkOiAndW5rbm93bicsCn07CgovKioKICogTWFwcyB0aGUgdHlwZSBvZiBhbiBlbnZlbG9wZSBpdGVtIHRvIGEgZGF0YSBjYXRlZ29yeS4KICovCmZ1bmN0aW9uIGVudmVsb3BlSXRlbVR5cGVUb0RhdGFDYXRlZ29yeSh0eXBlKSB7CiAgcmV0dXJuIElURU1fVFlQRV9UT19EQVRBX0NBVEVHT1JZX01BUFt0eXBlXTsKfQoKLyoqIEV4dHJhY3RzIHRoZSBtaW5pbWFsIFNESyBpbmZvIGZyb20gZnJvbSB0aGUgbWV0YWRhdGEgb3IgYW4gZXZlbnRzICovCmZ1bmN0aW9uIGdldFNka01ldGFkYXRhRm9yRW52ZWxvcGVIZWFkZXIobWV0YWRhdGFPckV2ZW50KSB7CiAgaWYgKCFtZXRhZGF0YU9yRXZlbnQgfHwgIW1ldGFkYXRhT3JFdmVudC5zZGspIHsKICAgIHJldHVybjsKICB9CiAgY29uc3QgeyBuYW1lLCB2ZXJzaW9uIH0gPSBtZXRhZGF0YU9yRXZlbnQuc2RrOwogIHJldHVybiB7IG5hbWUsIHZlcnNpb24gfTsKfQoKLyoqCiAqIENyZWF0ZXMgZXZlbnQgZW52ZWxvcGUgaGVhZGVycywgYmFzZWQgb24gZXZlbnQsIHNkayBpbmZvIGFuZCB0dW5uZWwKICogTm90ZTogVGhpcyBmdW5jdGlvbiB3YXMgZXh0cmFjdGVkIGZyb20gdGhlIGNvcmUgcGFja2FnZSB0byBtYWtlIGl0IGF2YWlsYWJsZSBpbiBSZXBsYXkKICovCmZ1bmN0aW9uIGNyZWF0ZUV2ZW50RW52ZWxvcGVIZWFkZXJzKAogIGV2ZW50LAogIHNka0luZm8sCiAgdHVubmVsLAogIGRzbiwKKSB7CiAgY29uc3QgZHluYW1pY1NhbXBsaW5nQ29udGV4dCA9IGV2ZW50LnNka1Byb2Nlc3NpbmdNZXRhZGF0YSAmJiBldmVudC5zZGtQcm9jZXNzaW5nTWV0YWRhdGEuZHluYW1pY1NhbXBsaW5nQ29udGV4dDsKICByZXR1cm4gewogICAgZXZlbnRfaWQ6IGV2ZW50LmV2ZW50X2lkICwKICAgIHNlbnRfYXQ6IG5ldyBEYXRlKCkudG9JU09TdHJpbmcoKSwKICAgIC4uLihzZGtJbmZvICYmIHsgc2RrOiBzZGtJbmZvIH0pLAogICAgLi4uKCEhdHVubmVsICYmIGRzbiAmJiB7IGRzbjogZHNuVG9TdHJpbmcoZHNuKSB9KSwKICAgIC4uLihkeW5hbWljU2FtcGxpbmdDb250ZXh0ICYmIHsKICAgICAgdHJhY2U6IGRyb3BVbmRlZmluZWRLZXlzKHsgLi4uZHluYW1pY1NhbXBsaW5nQ29udGV4dCB9KSwKICAgIH0pLAogIH07Cn0KCi8vIEludGVudGlvbmFsbHkga2VlcGluZyB0aGUga2V5IGJyb2FkLCBhcyB3ZSBkb24ndCBrbm93IGZvciBzdXJlIHdoYXQgcmF0ZSBsaW1pdCBoZWFkZXJzIGdldCByZXR1cm5lZCBmcm9tIGJhY2tlbmQKCmNvbnN0IERFRkFVTFRfUkVUUllfQUZURVIgPSA2MCAqIDEwMDA7IC8vIDYwIHNlY29uZHMKCi8qKgogKiBFeHRyYWN0cyBSZXRyeS1BZnRlciB2YWx1ZSBmcm9tIHRoZSByZXF1ZXN0IGhlYWRlciBvciByZXR1cm5zIGRlZmF1bHQgdmFsdWUKICogQHBhcmFtIGhlYWRlciBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgJ1JldHJ5LUFmdGVyJyBoZWFkZXIKICogQHBhcmFtIG5vdyBjdXJyZW50IHVuaXggdGltZXN0YW1wCiAqCiAqLwpmdW5jdGlvbiBwYXJzZVJldHJ5QWZ0ZXJIZWFkZXIoaGVhZGVyLCBub3cgPSBEYXRlLm5vdygpKSB7CiAgY29uc3QgaGVhZGVyRGVsYXkgPSBwYXJzZUludChgJHtoZWFkZXJ9YCwgMTApOwogIGlmICghaXNOYU4oaGVhZGVyRGVsYXkpKSB7CiAgICByZXR1cm4gaGVhZGVyRGVsYXkgKiAxMDAwOwogIH0KCiAgY29uc3QgaGVhZGVyRGF0ZSA9IERhdGUucGFyc2UoYCR7aGVhZGVyfWApOwogIGlmICghaXNOYU4oaGVhZGVyRGF0ZSkpIHsKICAgIHJldHVybiBoZWFkZXJEYXRlIC0gbm93OwogIH0KCiAgcmV0dXJuIERFRkFVTFRfUkVUUllfQUZURVI7Cn0KCi8qKgogKiBHZXRzIHRoZSB0aW1lIHRoYXQgdGhlIGdpdmVuIGNhdGVnb3J5IGlzIGRpc2FibGVkIHVudGlsIGZvciByYXRlIGxpbWl0aW5nLgogKiBJbiBjYXNlIG5vIGNhdGVnb3J5LXNwZWNpZmljIGxpbWl0IGlzIHNldCBidXQgYSBnZW5lcmFsIHJhdGUgbGltaXQgYWNyb3NzIGFsbCBjYXRlZ29yaWVzIGlzIGFjdGl2ZSwKICogdGhhdCB0aW1lIGlzIHJldHVybmVkLgogKgogKiBAcmV0dXJuIHRoZSB0aW1lIGluIG1zIHRoYXQgdGhlIGNhdGVnb3J5IGlzIGRpc2FibGVkIHVudGlsIG9yIDAgaWYgdGhlcmUncyBubyBhY3RpdmUgcmF0ZSBsaW1pdC4KICovCmZ1bmN0aW9uIGRpc2FibGVkVW50aWwobGltaXRzLCBjYXRlZ29yeSkgewogIHJldHVybiBsaW1pdHNbY2F0ZWdvcnldIHx8IGxpbWl0cy5hbGwgfHwgMDsKfQoKLyoqCiAqIENoZWNrcyBpZiBhIGNhdGVnb3J5IGlzIHJhdGUgbGltaXRlZAogKi8KZnVuY3Rpb24gaXNSYXRlTGltaXRlZChsaW1pdHMsIGNhdGVnb3J5LCBub3cgPSBEYXRlLm5vdygpKSB7CiAgcmV0dXJuIGRpc2FibGVkVW50aWwobGltaXRzLCBjYXRlZ29yeSkgPiBub3c7Cn0KCi8qKgogKiBVcGRhdGUgcmF0ZWxpbWl0cyBmcm9tIGluY29taW5nIGhlYWRlcnMuCiAqCiAqIEByZXR1cm4gdGhlIHVwZGF0ZWQgUmF0ZUxpbWl0cyBvYmplY3QuCiAqLwpmdW5jdGlvbiB1cGRhdGVSYXRlTGltaXRzKAogIGxpbWl0cywKICB7IHN0YXR1c0NvZGUsIGhlYWRlcnMgfSwKICBub3cgPSBEYXRlLm5vdygpLAopIHsKICBjb25zdCB1cGRhdGVkUmF0ZUxpbWl0cyA9IHsKICAgIC4uLmxpbWl0cywKICB9OwoKICAvLyAiVGhlIG5hbWUgaXMgY2FzZS1pbnNlbnNpdGl2ZS4iCiAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL0hlYWRlcnMvZ2V0CiAgY29uc3QgcmF0ZUxpbWl0SGVhZGVyID0gaGVhZGVycyAmJiBoZWFkZXJzWyd4LXNlbnRyeS1yYXRlLWxpbWl0cyddOwogIGNvbnN0IHJldHJ5QWZ0ZXJIZWFkZXIgPSBoZWFkZXJzICYmIGhlYWRlcnNbJ3JldHJ5LWFmdGVyJ107CgogIGlmIChyYXRlTGltaXRIZWFkZXIpIHsKICAgIC8qKgogICAgICogcmF0ZSBsaW1pdCBoZWFkZXJzIGFyZSBvZiB0aGUgZm9ybQogICAgICogICAgIDxoZWFkZXI+LDxoZWFkZXI+LC4uCiAgICAgKiB3aGVyZSBlYWNoIDxoZWFkZXI+IGlzIG9mIHRoZSBmb3JtCiAgICAgKiAgICAgPHJldHJ5X2FmdGVyPjogPGNhdGVnb3JpZXM+OiA8c2NvcGU+OiA8cmVhc29uX2NvZGU+CiAgICAgKiB3aGVyZQogICAgICogICAgIDxyZXRyeV9hZnRlcj4gaXMgYSBkZWxheSBpbiBzZWNvbmRzCiAgICAgKiAgICAgPGNhdGVnb3JpZXM+IGlzIHRoZSBldmVudCB0eXBlKHMpIChlcnJvciwgdHJhbnNhY3Rpb24sIGV0YykgYmVpbmcgcmF0ZSBsaW1pdGVkIGFuZCBpcyBvZiB0aGUgZm9ybQogICAgICogICAgICAgICA8Y2F0ZWdvcnk+OzxjYXRlZ29yeT47Li4uCiAgICAgKiAgICAgPHNjb3BlPiBpcyB3aGF0J3MgYmVpbmcgbGltaXRlZCAob3JnLCBwcm9qZWN0LCBvciBrZXkpIC0gaWdub3JlZCBieSBTREsKICAgICAqICAgICA8cmVhc29uX2NvZGU+IGlzIGFuIGFyYml0cmFyeSBzdHJpbmcgbGlrZSAib3JnX3F1b3RhIiAtIGlnbm9yZWQgYnkgU0RLCiAgICAgKi8KICAgIGZvciAoY29uc3QgbGltaXQgb2YgcmF0ZUxpbWl0SGVhZGVyLnRyaW0oKS5zcGxpdCgnLCcpKSB7CiAgICAgIGNvbnN0IFtyZXRyeUFmdGVyLCBjYXRlZ29yaWVzXSA9IGxpbWl0LnNwbGl0KCc6JywgMik7CiAgICAgIGNvbnN0IGhlYWRlckRlbGF5ID0gcGFyc2VJbnQocmV0cnlBZnRlciwgMTApOwogICAgICBjb25zdCBkZWxheSA9ICghaXNOYU4oaGVhZGVyRGVsYXkpID8gaGVhZGVyRGVsYXkgOiA2MCkgKiAxMDAwOyAvLyA2MHNlYyBkZWZhdWx0CiAgICAgIGlmICghY2F0ZWdvcmllcykgewogICAgICAgIHVwZGF0ZWRSYXRlTGltaXRzLmFsbCA9IG5vdyArIGRlbGF5OwogICAgICB9IGVsc2UgewogICAgICAgIGZvciAoY29uc3QgY2F0ZWdvcnkgb2YgY2F0ZWdvcmllcy5zcGxpdCgnOycpKSB7CiAgICAgICAgICB1cGRhdGVkUmF0ZUxpbWl0c1tjYXRlZ29yeV0gPSBub3cgKyBkZWxheTsKICAgICAgICB9CiAgICAgIH0KICAgIH0KICB9IGVsc2UgaWYgKHJldHJ5QWZ0ZXJIZWFkZXIpIHsKICAgIHVwZGF0ZWRSYXRlTGltaXRzLmFsbCA9IG5vdyArIHBhcnNlUmV0cnlBZnRlckhlYWRlcihyZXRyeUFmdGVySGVhZGVyLCBub3cpOwogIH0gZWxzZSBpZiAoc3RhdHVzQ29kZSA9PT0gNDI5KSB7CiAgICB1cGRhdGVkUmF0ZUxpbWl0cy5hbGwgPSBub3cgKyA2MCAqIDEwMDA7CiAgfQoKICByZXR1cm4gdXBkYXRlZFJhdGVMaW1pdHM7Cn0KCi8qKgogKiBBIG5vZGUuanMgd2F0Y2hkb2cgdGltZXIKICogQHBhcmFtIHBvbGxJbnRlcnZhbCBUaGUgaW50ZXJ2YWwgdGhhdCB3ZSBleHBlY3QgdG8gZ2V0IHBvbGxlZCBhdAogKiBAcGFyYW0gYW5yVGhyZXNob2xkIFRoZSB0aHJlc2hvbGQgZm9yIHdoZW4gd2UgY29uc2lkZXIgQU5SCiAqIEBwYXJhbSBjYWxsYmFjayBUaGUgY2FsbGJhY2sgdG8gY2FsbCBmb3IgQU5SCiAqIEByZXR1cm5zIEFuIG9iamVjdCB3aXRoIGBwb2xsYCBhbmQgYGVuYWJsZWRgIGZ1bmN0aW9ucyB7QGxpbmsgV2F0Y2hkb2dSZXR1cm59CiAqLwpmdW5jdGlvbiB3YXRjaGRvZ1RpbWVyKAogIGNyZWF0ZVRpbWVyLAogIHBvbGxJbnRlcnZhbCwKICBhbnJUaHJlc2hvbGQsCiAgY2FsbGJhY2ssCikgewogIGNvbnN0IHRpbWVyID0gY3JlYXRlVGltZXIoKTsKICBsZXQgdHJpZ2dlcmVkID0gZmFsc2U7CiAgbGV0IGVuYWJsZWQgPSB0cnVlOwoKICBzZXRJbnRlcnZhbCgoKSA9PiB7CiAgICBjb25zdCBkaWZmTXMgPSB0aW1lci5nZXRUaW1lTXMoKTsKCiAgICBpZiAodHJpZ2dlcmVkID09PSBmYWxzZSAmJiBkaWZmTXMgPiBwb2xsSW50ZXJ2YWwgKyBhbnJUaHJlc2hvbGQpIHsKICAgICAgdHJpZ2dlcmVkID0gdHJ1ZTsKICAgICAgaWYgKGVuYWJsZWQpIHsKICAgICAgICBjYWxsYmFjaygpOwogICAgICB9CiAgICB9CgogICAgaWYgKGRpZmZNcyA8IHBvbGxJbnRlcnZhbCArIGFuclRocmVzaG9sZCkgewogICAgICB0cmlnZ2VyZWQgPSBmYWxzZTsKICAgIH0KICB9LCAyMCk7CgogIHJldHVybiB7CiAgICBwb2xsOiAoKSA9PiB7CiAgICAgIHRpbWVyLnJlc2V0KCk7CiAgICB9LAogICAgZW5hYmxlZDogKHN0YXRlKSA9PiB7CiAgICAgIGVuYWJsZWQgPSBzdGF0ZTsKICAgIH0sCiAgfTsKfQoKLy8gdHlwZXMgY29waWVkIGZyb20gaW5zcGVjdG9yLmQudHMKCi8qKgogKiBDb252ZXJ0cyBEZWJ1Z2dlci5DYWxsRnJhbWUgdG8gU2VudHJ5IFN0YWNrRnJhbWUKICovCmZ1bmN0aW9uIGNhbGxGcmFtZVRvU3RhY2tGcmFtZSgKICBmcmFtZSwKICB1cmwsCiAgZ2V0TW9kdWxlRnJvbUZpbGVuYW1lLAopIHsKICBjb25zdCBmaWxlbmFtZSA9IHVybCA/IHVybC5yZXBsYWNlKC9eZmlsZTpcL1wvLywgJycpIDogdW5kZWZpbmVkOwoKICAvLyBDYWxsRnJhbWUgcm93L2NvbCBhcmUgMCBiYXNlZCwgd2hlcmVhcyBTdGFja0ZyYW1lIGFyZSAxIGJhc2VkCiAgY29uc3QgY29sbm8gPSBmcmFtZS5sb2NhdGlvbi5jb2x1bW5OdW1iZXIgPyBmcmFtZS5sb2NhdGlvbi5jb2x1bW5OdW1iZXIgKyAxIDogdW5kZWZpbmVkOwogIGNvbnN0IGxpbmVubyA9IGZyYW1lLmxvY2F0aW9uLmxpbmVOdW1iZXIgPyBmcmFtZS5sb2NhdGlvbi5saW5lTnVtYmVyICsgMSA6IHVuZGVmaW5lZDsKCiAgcmV0dXJuIGRyb3BVbmRlZmluZWRLZXlzKHsKICAgIGZpbGVuYW1lLAogICAgbW9kdWxlOiBnZXRNb2R1bGVGcm9tRmlsZW5hbWUoZmlsZW5hbWUpLAogICAgZnVuY3Rpb246IGZyYW1lLmZ1bmN0aW9uTmFtZSB8fCBVTktOT1dOX0ZVTkNUSU9OLAogICAgY29sbm8sCiAgICBsaW5lbm8sCiAgICBpbl9hcHA6IGZpbGVuYW1lID8gZmlsZW5hbWVJc0luQXBwKGZpbGVuYW1lKSA6IHVuZGVmaW5lZCwKICB9KTsKfQoKLyoqCiAqIFRoaXMgc2VydmVzIGFzIGEgYnVpbGQgdGltZSBmbGFnIHRoYXQgd2lsbCBiZSB0cnVlIGJ5IGRlZmF1bHQsIGJ1dCBmYWxzZSBpbiBub24tZGVidWcgYnVpbGRzIG9yIGlmIHVzZXJzIHJlcGxhY2UgYF9fU0VOVFJZX0RFQlVHX19gIGluIHRoZWlyIGdlbmVyYXRlZCBjb2RlLgogKgogKiBBVFRFTlRJT046IFRoaXMgY29uc3RhbnQgbXVzdCBuZXZlciBjcm9zcyBwYWNrYWdlIGJvdW5kYXJpZXMgKGkuZS4gYmUgZXhwb3J0ZWQpIHRvIGd1YXJhbnRlZSB0aGF0IGl0IGNhbiBiZSB1c2VkIGZvciB0cmVlIHNoYWtpbmcuCiAqLwpjb25zdCBERUJVR19CVUlMRCA9ICh0eXBlb2YgX19TRU5UUllfREVCVUdfXyA9PT0gJ3VuZGVmaW5lZCcgfHwgX19TRU5UUllfREVCVUdfXyk7CgovKioKICogQ3JlYXRlcyBhIG5ldyBgU2Vzc2lvbmAgb2JqZWN0IGJ5IHNldHRpbmcgY2VydGFpbiBkZWZhdWx0IHBhcmFtZXRlcnMuIElmIG9wdGlvbmFsIEBwYXJhbSBjb250ZXh0CiAqIGlzIHBhc3NlZCwgdGhlIHBhc3NlZCBwcm9wZXJ0aWVzIGFyZSBhcHBsaWVkIHRvIHRoZSBzZXNzaW9uIG9iamVjdC4KICoKICogQHBhcmFtIGNvbnRleHQgKG9wdGlvbmFsKSBhZGRpdGlvbmFsIHByb3BlcnRpZXMgdG8gYmUgYXBwbGllZCB0byB0aGUgcmV0dXJuZWQgc2Vzc2lvbiBvYmplY3QKICoKICogQHJldHVybnMgYSBuZXcgYFNlc3Npb25gIG9iamVjdAogKi8KZnVuY3Rpb24gbWFrZVNlc3Npb24oY29udGV4dCkgewogIC8vIEJvdGggdGltZXN0YW1wIGFuZCBzdGFydGVkIGFyZSBpbiBzZWNvbmRzIHNpbmNlIHRoZSBVTklYIGVwb2NoLgogIGNvbnN0IHN0YXJ0aW5nVGltZSA9IHRpbWVzdGFtcEluU2Vjb25kcygpOwoKICBjb25zdCBzZXNzaW9uID0gewogICAgc2lkOiB1dWlkNCgpLAogICAgaW5pdDogdHJ1ZSwKICAgIHRpbWVzdGFtcDogc3RhcnRpbmdUaW1lLAogICAgc3RhcnRlZDogc3RhcnRpbmdUaW1lLAogICAgZHVyYXRpb246IDAsCiAgICBzdGF0dXM6ICdvaycsCiAgICBlcnJvcnM6IDAsCiAgICBpZ25vcmVEdXJhdGlvbjogZmFsc2UsCiAgICB0b0pTT046ICgpID0+IHNlc3Npb25Ub0pTT04oc2Vzc2lvbiksCiAgfTsKCiAgaWYgKGNvbnRleHQpIHsKICAgIHVwZGF0ZVNlc3Npb24oc2Vzc2lvbiwgY29udGV4dCk7CiAgfQoKICByZXR1cm4gc2Vzc2lvbjsKfQoKLyoqCiAqIFVwZGF0ZXMgYSBzZXNzaW9uIG9iamVjdCB3aXRoIHRoZSBwcm9wZXJ0aWVzIHBhc3NlZCBpbiB0aGUgY29udGV4dC4KICoKICogTm90ZSB0aGF0IHRoaXMgZnVuY3Rpb24gbXV0YXRlcyB0aGUgcGFzc2VkIG9iamVjdCBhbmQgcmV0dXJucyB2b2lkLgogKiAoSGFkIHRvIGRvIHRoaXMgaW5zdGVhZCBvZiByZXR1cm5pbmcgYSBuZXcgYW5kIHVwZGF0ZWQgc2Vzc2lvbiBiZWNhdXNlIGNsb3NpbmcgYW5kIHNlbmRpbmcgYSBzZXNzaW9uCiAqIG1ha2VzIGFuIHVwZGF0ZSB0byB0aGUgc2Vzc2lvbiBhZnRlciBpdCB3YXMgcGFzc2VkIHRvIHRoZSBzZW5kaW5nIGxvZ2ljLgogKiBAc2VlIEJhc2VDbGllbnQuY2FwdHVyZVNlc3Npb24gKQogKgogKiBAcGFyYW0gc2Vzc2lvbiB0aGUgYFNlc3Npb25gIHRvIHVwZGF0ZQogKiBAcGFyYW0gY29udGV4dCB0aGUgYFNlc3Npb25Db250ZXh0YCBob2xkaW5nIHRoZSBwcm9wZXJ0aWVzIHRoYXQgc2hvdWxkIGJlIHVwZGF0ZWQgaW4gQHBhcmFtIHNlc3Npb24KICovCi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBjb21wbGV4aXR5CmZ1bmN0aW9uIHVwZGF0ZVNlc3Npb24oc2Vzc2lvbiwgY29udGV4dCA9IHt9KSB7CiAgaWYgKGNvbnRleHQudXNlcikgewogICAgaWYgKCFzZXNzaW9uLmlwQWRkcmVzcyAmJiBjb250ZXh0LnVzZXIuaXBfYWRkcmVzcykgewogICAgICBzZXNzaW9uLmlwQWRkcmVzcyA9IGNvbnRleHQudXNlci5pcF9hZGRyZXNzOwogICAgfQoKICAgIGlmICghc2Vzc2lvbi5kaWQgJiYgIWNvbnRleHQuZGlkKSB7CiAgICAgIHNlc3Npb24uZGlkID0gY29udGV4dC51c2VyLmlkIHx8IGNvbnRleHQudXNlci5lbWFpbCB8fCBjb250ZXh0LnVzZXIudXNlcm5hbWU7CiAgICB9CiAgfQoKICBzZXNzaW9uLnRpbWVzdGFtcCA9IGNvbnRleHQudGltZXN0YW1wIHx8IHRpbWVzdGFtcEluU2Vjb25kcygpOwoKICBpZiAoY29udGV4dC5hYm5vcm1hbF9tZWNoYW5pc20pIHsKICAgIHNlc3Npb24uYWJub3JtYWxfbWVjaGFuaXNtID0gY29udGV4dC5hYm5vcm1hbF9tZWNoYW5pc207CiAgfQoKICBpZiAoY29udGV4dC5pZ25vcmVEdXJhdGlvbikgewogICAgc2Vzc2lvbi5pZ25vcmVEdXJhdGlvbiA9IGNvbnRleHQuaWdub3JlRHVyYXRpb247CiAgfQogIGlmIChjb250ZXh0LnNpZCkgewogICAgLy8gR29vZCBlbm91Z2ggdXVpZCB2YWxpZGF0aW9uLiDigJQgS2FtaWwKICAgIHNlc3Npb24uc2lkID0gY29udGV4dC5zaWQubGVuZ3RoID09PSAzMiA/IGNvbnRleHQuc2lkIDogdXVpZDQoKTsKICB9CiAgaWYgKGNvbnRleHQuaW5pdCAhPT0gdW5kZWZpbmVkKSB7CiAgICBzZXNzaW9uLmluaXQgPSBjb250ZXh0LmluaXQ7CiAgfQogIGlmICghc2Vzc2lvbi5kaWQgJiYgY29udGV4dC5kaWQpIHsKICAgIHNlc3Npb24uZGlkID0gYCR7Y29udGV4dC5kaWR9YDsKICB9CiAgaWYgKHR5cGVvZiBjb250ZXh0LnN0YXJ0ZWQgPT09ICdudW1iZXInKSB7CiAgICBzZXNzaW9uLnN0YXJ0ZWQgPSBjb250ZXh0LnN0YXJ0ZWQ7CiAgfQogIGlmIChzZXNzaW9uLmlnbm9yZUR1cmF0aW9uKSB7CiAgICBzZXNzaW9uLmR1cmF0aW9uID0gdW5kZWZpbmVkOwogIH0gZWxzZSBpZiAodHlwZW9mIGNvbnRleHQuZHVyYXRpb24gPT09ICdudW1iZXInKSB7CiAgICBzZXNzaW9uLmR1cmF0aW9uID0gY29udGV4dC5kdXJhdGlvbjsKICB9IGVsc2UgewogICAgY29uc3QgZHVyYXRpb24gPSBzZXNzaW9uLnRpbWVzdGFtcCAtIHNlc3Npb24uc3RhcnRlZDsKICAgIHNlc3Npb24uZHVyYXRpb24gPSBkdXJhdGlvbiA+PSAwID8gZHVyYXRpb24gOiAwOwogIH0KICBpZiAoY29udGV4dC5yZWxlYXNlKSB7CiAgICBzZXNzaW9uLnJlbGVhc2UgPSBjb250ZXh0LnJlbGVhc2U7CiAgfQogIGlmIChjb250ZXh0LmVudmlyb25tZW50KSB7CiAgICBzZXNzaW9uLmVudmlyb25tZW50ID0gY29udGV4dC5lbnZpcm9ubWVudDsKICB9CiAgaWYgKCFzZXNzaW9uLmlwQWRkcmVzcyAmJiBjb250ZXh0LmlwQWRkcmVzcykgewogICAgc2Vzc2lvbi5pcEFkZHJlc3MgPSBjb250ZXh0LmlwQWRkcmVzczsKICB9CiAgaWYgKCFzZXNzaW9uLnVzZXJBZ2VudCAmJiBjb250ZXh0LnVzZXJBZ2VudCkgewogICAgc2Vzc2lvbi51c2VyQWdlbnQgPSBjb250ZXh0LnVzZXJBZ2VudDsKICB9CiAgaWYgKHR5cGVvZiBjb250ZXh0LmVycm9ycyA9PT0gJ251bWJlcicpIHsKICAgIHNlc3Npb24uZXJyb3JzID0gY29udGV4dC5lcnJvcnM7CiAgfQogIGlmIChjb250ZXh0LnN0YXR1cykgewogICAgc2Vzc2lvbi5zdGF0dXMgPSBjb250ZXh0LnN0YXR1czsKICB9Cn0KCi8qKgogKiBTZXJpYWxpemVzIGEgcGFzc2VkIHNlc3Npb24gb2JqZWN0IHRvIGEgSlNPTiBvYmplY3Qgd2l0aCBhIHNsaWdodGx5IGRpZmZlcmVudCBzdHJ1Y3R1cmUuCiAqIFRoaXMgaXMgbmVjZXNzYXJ5IGJlY2F1c2UgdGhlIFNlbnRyeSBiYWNrZW5kIHJlcXVpcmVzIGEgc2xpZ2h0bHkgZGlmZmVyZW50IHNjaGVtYSBvZiBhIHNlc3Npb24KICogdGhhbiB0aGUgb25lIHRoZSBKUyBTREtzIHVzZSBpbnRlcm5hbGx5LgogKgogKiBAcGFyYW0gc2Vzc2lvbiB0aGUgc2Vzc2lvbiB0byBiZSBjb252ZXJ0ZWQKICoKICogQHJldHVybnMgYSBKU09OIG9iamVjdCBvZiB0aGUgcGFzc2VkIHNlc3Npb24KICovCmZ1bmN0aW9uIHNlc3Npb25Ub0pTT04oc2Vzc2lvbikgewogIHJldHVybiBkcm9wVW5kZWZpbmVkS2V5cyh7CiAgICBzaWQ6IGAke3Nlc3Npb24uc2lkfWAsCiAgICBpbml0OiBzZXNzaW9uLmluaXQsCiAgICAvLyBNYWtlIHN1cmUgdGhhdCBzZWMgaXMgY29udmVydGVkIHRvIG1zIGZvciBkYXRlIGNvbnN0cnVjdG9yCiAgICBzdGFydGVkOiBuZXcgRGF0ZShzZXNzaW9uLnN0YXJ0ZWQgKiAxMDAwKS50b0lTT1N0cmluZygpLAogICAgdGltZXN0YW1wOiBuZXcgRGF0ZShzZXNzaW9uLnRpbWVzdGFtcCAqIDEwMDApLnRvSVNPU3RyaW5nKCksCiAgICBzdGF0dXM6IHNlc3Npb24uc3RhdHVzLAogICAgZXJyb3JzOiBzZXNzaW9uLmVycm9ycywKICAgIGRpZDogdHlwZW9mIHNlc3Npb24uZGlkID09PSAnbnVtYmVyJyB8fCB0eXBlb2Ygc2Vzc2lvbi5kaWQgPT09ICdzdHJpbmcnID8gYCR7c2Vzc2lvbi5kaWR9YCA6IHVuZGVmaW5lZCwKICAgIGR1cmF0aW9uOiBzZXNzaW9uLmR1cmF0aW9uLAogICAgYWJub3JtYWxfbWVjaGFuaXNtOiBzZXNzaW9uLmFibm9ybWFsX21lY2hhbmlzbSwKICAgIGF0dHJzOiB7CiAgICAgIHJlbGVhc2U6IHNlc3Npb24ucmVsZWFzZSwKICAgICAgZW52aXJvbm1lbnQ6IHNlc3Npb24uZW52aXJvbm1lbnQsCiAgICAgIGlwX2FkZHJlc3M6IHNlc3Npb24uaXBBZGRyZXNzLAogICAgICB1c2VyX2FnZW50OiBzZXNzaW9uLnVzZXJBZ2VudCwKICAgIH0sCiAgfSk7Cn0KCi8qKgogKiBBcHBseSBTZGtJbmZvIChuYW1lLCB2ZXJzaW9uLCBwYWNrYWdlcywgaW50ZWdyYXRpb25zKSB0byB0aGUgY29ycmVzcG9uZGluZyBldmVudCBrZXkuCiAqIE1lcmdlIHdpdGggZXhpc3RpbmcgZGF0YSBpZiBhbnkuCiAqKi8KZnVuY3Rpb24gZW5oYW5jZUV2ZW50V2l0aFNka0luZm8oZXZlbnQsIHNka0luZm8pIHsKICBpZiAoIXNka0luZm8pIHsKICAgIHJldHVybiBldmVudDsKICB9CiAgZXZlbnQuc2RrID0gZXZlbnQuc2RrIHx8IHt9OwogIGV2ZW50LnNkay5uYW1lID0gZXZlbnQuc2RrLm5hbWUgfHwgc2RrSW5mby5uYW1lOwogIGV2ZW50LnNkay52ZXJzaW9uID0gZXZlbnQuc2RrLnZlcnNpb24gfHwgc2RrSW5mby52ZXJzaW9uOwogIGV2ZW50LnNkay5pbnRlZ3JhdGlvbnMgPSBbLi4uKGV2ZW50LnNkay5pbnRlZ3JhdGlvbnMgfHwgW10pLCAuLi4oc2RrSW5mby5pbnRlZ3JhdGlvbnMgfHwgW10pXTsKICBldmVudC5zZGsucGFja2FnZXMgPSBbLi4uKGV2ZW50LnNkay5wYWNrYWdlcyB8fCBbXSksIC4uLihzZGtJbmZvLnBhY2thZ2VzIHx8IFtdKV07CiAgcmV0dXJuIGV2ZW50Owp9CgovKiogQ3JlYXRlcyBhbiBlbnZlbG9wZSBmcm9tIGEgU2Vzc2lvbiAqLwpmdW5jdGlvbiBjcmVhdGVTZXNzaW9uRW52ZWxvcGUoCiAgc2Vzc2lvbiwKICBkc24sCiAgbWV0YWRhdGEsCiAgdHVubmVsLAopIHsKICBjb25zdCBzZGtJbmZvID0gZ2V0U2RrTWV0YWRhdGFGb3JFbnZlbG9wZUhlYWRlcihtZXRhZGF0YSk7CiAgY29uc3QgZW52ZWxvcGVIZWFkZXJzID0gewogICAgc2VudF9hdDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLAogICAgLi4uKHNka0luZm8gJiYgeyBzZGs6IHNka0luZm8gfSksCiAgICAuLi4oISF0dW5uZWwgJiYgZHNuICYmIHsgZHNuOiBkc25Ub1N0cmluZyhkc24pIH0pLAogIH07CgogIGNvbnN0IGVudmVsb3BlSXRlbSA9CiAgICAnYWdncmVnYXRlcycgaW4gc2Vzc2lvbiA/IFt7IHR5cGU6ICdzZXNzaW9ucycgfSwgc2Vzc2lvbl0gOiBbeyB0eXBlOiAnc2Vzc2lvbicgfSwgc2Vzc2lvbi50b0pTT04oKV07CgogIHJldHVybiBjcmVhdGVFbnZlbG9wZShlbnZlbG9wZUhlYWRlcnMsIFtlbnZlbG9wZUl0ZW1dKTsKfQoKLyoqCiAqIENyZWF0ZSBhbiBFbnZlbG9wZSBmcm9tIGFuIGV2ZW50LgogKi8KZnVuY3Rpb24gY3JlYXRlRXZlbnRFbnZlbG9wZSgKICBldmVudCwKICBkc24sCiAgbWV0YWRhdGEsCiAgdHVubmVsLAopIHsKICBjb25zdCBzZGtJbmZvID0gZ2V0U2RrTWV0YWRhdGFGb3JFbnZlbG9wZUhlYWRlcihtZXRhZGF0YSk7CgogIC8qCiAgICBOb3RlOiBEdWUgdG8gVFMsIGV2ZW50LnR5cGUgbWF5IGJlIGByZXBsYXlfZXZlbnRgLCB0aGVvcmV0aWNhbGx5LgogICAgSW4gcHJhY3RpY2UsIHdlIG5ldmVyIGNhbGwgYGNyZWF0ZUV2ZW50RW52ZWxvcGVgIHdpdGggYHJlcGxheV9ldmVudGAgdHlwZSwKICAgIGFuZCB3ZSdkIGhhdmUgdG8gYWRqdXQgYSBsb29vdCBvZiB0eXBlcyB0byBtYWtlIHRoaXMgd29yayBwcm9wZXJseS4KICAgIFdlIHdhbnQgdG8gYXZvaWQgY2FzdGluZyB0aGlzIGFyb3VuZCwgYXMgdGhhdCBjb3VsZCBsZWFkIHRvIGJ1Z3MgKGUuZy4gd2hlbiB3ZSBhZGQgYW5vdGhlciB0eXBlKQogICAgU28gdGhlIHNhZmUgY2hvaWNlIGlzIHRvIHJlYWxseSBndWFyZCBhZ2FpbnN0IHRoZSByZXBsYXlfZXZlbnQgdHlwZSBoZXJlLgogICovCiAgY29uc3QgZXZlbnRUeXBlID0gZXZlbnQudHlwZSAmJiBldmVudC50eXBlICE9PSAncmVwbGF5X2V2ZW50JyA/IGV2ZW50LnR5cGUgOiAnZXZlbnQnOwoKICBlbmhhbmNlRXZlbnRXaXRoU2RrSW5mbyhldmVudCwgbWV0YWRhdGEgJiYgbWV0YWRhdGEuc2RrKTsKCiAgY29uc3QgZW52ZWxvcGVIZWFkZXJzID0gY3JlYXRlRXZlbnRFbnZlbG9wZUhlYWRlcnMoZXZlbnQsIHNka0luZm8sIHR1bm5lbCwgZHNuKTsKCiAgLy8gUHJldmVudCB0aGlzIGRhdGEgKHdoaWNoLCBpZiBpdCBleGlzdHMsIHdhcyB1c2VkIGluIGVhcmxpZXIgc3RlcHMgaW4gdGhlIHByb2Nlc3NpbmcgcGlwZWxpbmUpIGZyb20gYmVpbmcgc2VudCB0bwogIC8vIHNlbnRyeS4gKE5vdGU6IE91ciB1c2Ugb2YgdGhpcyBwcm9wZXJ0eSBjb21lcyBhbmQgZ29lcyB3aXRoIHdoYXRldmVyIHdlIG1pZ2h0IGJlIGRlYnVnZ2luZywgd2hhdGV2ZXIgaGFja3Mgd2UgbWF5CiAgLy8gaGF2ZSB0ZW1wb3JhcmlseSBhZGRlZCwgZXRjLiBFdmVuIGlmIHdlIGRvbid0IGhhcHBlbiB0byBiZSB1c2luZyBpdCBhdCBzb21lIHBvaW50IGluIHRoZSBmdXR1cmUsIGxldCdzIG5vdCBnZXQgcmlkCiAgLy8gb2YgdGhpcyBgZGVsZXRlYCwgbGVzdCB3ZSBtaXNzIHB1dHRpbmcgaXQgYmFjayBpbiB0aGUgbmV4dCB0aW1lIHRoZSBwcm9wZXJ0eSBpcyBpbiB1c2UuKQogIGRlbGV0ZSBldmVudC5zZGtQcm9jZXNzaW5nTWV0YWRhdGE7CgogIGNvbnN0IGV2ZW50SXRlbSA9IFt7IHR5cGU6IGV2ZW50VHlwZSB9LCBldmVudF07CiAgcmV0dXJuIGNyZWF0ZUVudmVsb3BlKGVudmVsb3BlSGVhZGVycywgW2V2ZW50SXRlbV0pOwp9Cgpjb25zdCBTRU5UUllfQVBJX1ZFUlNJT04gPSAnNyc7CgovKiogUmV0dXJucyB0aGUgcHJlZml4IHRvIGNvbnN0cnVjdCBTZW50cnkgaW5nZXN0aW9uIEFQSSBlbmRwb2ludHMuICovCmZ1bmN0aW9uIGdldEJhc2VBcGlFbmRwb2ludChkc24pIHsKICBjb25zdCBwcm90b2NvbCA9IGRzbi5wcm90b2NvbCA/IGAke2Rzbi5wcm90b2NvbH06YCA6ICcnOwogIGNvbnN0IHBvcnQgPSBkc24ucG9ydCA/IGA6JHtkc24ucG9ydH1gIDogJyc7CiAgcmV0dXJuIGAke3Byb3RvY29sfS8vJHtkc24uaG9zdH0ke3BvcnR9JHtkc24ucGF0aCA/IGAvJHtkc24ucGF0aH1gIDogJyd9L2FwaS9gOwp9CgovKiogUmV0dXJucyB0aGUgaW5nZXN0IEFQSSBlbmRwb2ludCBmb3IgdGFyZ2V0LiAqLwpmdW5jdGlvbiBfZ2V0SW5nZXN0RW5kcG9pbnQoZHNuKSB7CiAgcmV0dXJuIGAke2dldEJhc2VBcGlFbmRwb2ludChkc24pfSR7ZHNuLnByb2plY3RJZH0vZW52ZWxvcGUvYDsKfQoKLyoqIFJldHVybnMgYSBVUkwtZW5jb2RlZCBzdHJpbmcgd2l0aCBhdXRoIGNvbmZpZyBzdWl0YWJsZSBmb3IgYSBxdWVyeSBzdHJpbmcuICovCmZ1bmN0aW9uIF9lbmNvZGVkQXV0aChkc24sIHNka0luZm8pIHsKICByZXR1cm4gdXJsRW5jb2RlKHsKICAgIC8vIFdlIHNlbmQgb25seSB0aGUgbWluaW11bSBzZXQgb2YgcmVxdWlyZWQgaW5mb3JtYXRpb24uIFNlZQogICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2dldHNlbnRyeS9zZW50cnktamF2YXNjcmlwdC9pc3N1ZXMvMjU3Mi4KICAgIHNlbnRyeV9rZXk6IGRzbi5wdWJsaWNLZXksCiAgICBzZW50cnlfdmVyc2lvbjogU0VOVFJZX0FQSV9WRVJTSU9OLAogICAgLi4uKHNka0luZm8gJiYgeyBzZW50cnlfY2xpZW50OiBgJHtzZGtJbmZvLm5hbWV9LyR7c2RrSW5mby52ZXJzaW9ufWAgfSksCiAgfSk7Cn0KCi8qKgogKiBSZXR1cm5zIHRoZSBlbnZlbG9wZSBlbmRwb2ludCBVUkwgd2l0aCBhdXRoIGluIHRoZSBxdWVyeSBzdHJpbmcuCiAqCiAqIFNlbmRpbmcgYXV0aCBhcyBwYXJ0IG9mIHRoZSBxdWVyeSBzdHJpbmcgYW5kIG5vdCBhcyBjdXN0b20gSFRUUCBoZWFkZXJzIGF2b2lkcyBDT1JTIHByZWZsaWdodCByZXF1ZXN0cy4KICovCmZ1bmN0aW9uIGdldEVudmVsb3BlRW5kcG9pbnRXaXRoVXJsRW5jb2RlZEF1dGgoCiAgZHNuLAogIC8vIFRPRE8gKHY4KTogUmVtb3ZlIGB0dW5uZWxPck9wdGlvbnNgIGluIGZhdm9yIG9mIGBvcHRpb25zYCwgYW5kIHVzZSB0aGUgc3Vic3RpdHV0ZSBjb2RlIGJlbG93CiAgLy8gb3B0aW9uczogQ2xpZW50T3B0aW9ucyA9IHt9IGFzIENsaWVudE9wdGlvbnMsCiAgdHVubmVsT3JPcHRpb25zID0ge30gLAopIHsKICAvLyBUT0RPICh2OCk6IFVzZSB0aGlzIGNvZGUgaW5zdGVhZAogIC8vIGNvbnN0IHsgdHVubmVsLCBfbWV0YWRhdGEgPSB7fSB9ID0gb3B0aW9uczsKICAvLyByZXR1cm4gdHVubmVsID8gdHVubmVsIDogYCR7X2dldEluZ2VzdEVuZHBvaW50KGRzbil9PyR7X2VuY29kZWRBdXRoKGRzbiwgX21ldGFkYXRhLnNkayl9YDsKCiAgY29uc3QgdHVubmVsID0gdHlwZW9mIHR1bm5lbE9yT3B0aW9ucyA9PT0gJ3N0cmluZycgPyB0dW5uZWxPck9wdGlvbnMgOiB0dW5uZWxPck9wdGlvbnMudHVubmVsOwogIGNvbnN0IHNka0luZm8gPQogICAgdHlwZW9mIHR1bm5lbE9yT3B0aW9ucyA9PT0gJ3N0cmluZycgfHwgIXR1bm5lbE9yT3B0aW9ucy5fbWV0YWRhdGEgPyB1bmRlZmluZWQgOiB0dW5uZWxPck9wdGlvbnMuX21ldGFkYXRhLnNkazsKCiAgcmV0dXJuIHR1bm5lbCA/IHR1bm5lbCA6IGAke19nZXRJbmdlc3RFbmRwb2ludChkc24pfT8ke19lbmNvZGVkQXV0aChkc24sIHNka0luZm8pfWA7Cn0KCmNvbnN0IERFRkFVTFRfVFJBTlNQT1JUX0JVRkZFUl9TSVpFID0gMzA7CgovKioKICogQ3JlYXRlcyBhbiBpbnN0YW5jZSBvZiBhIFNlbnRyeSBgVHJhbnNwb3J0YAogKgogKiBAcGFyYW0gb3B0aW9ucwogKiBAcGFyYW0gbWFrZVJlcXVlc3QKICovCmZ1bmN0aW9uIGNyZWF0ZVRyYW5zcG9ydCgKICBvcHRpb25zLAogIG1ha2VSZXF1ZXN0LAogIGJ1ZmZlciA9IG1ha2VQcm9taXNlQnVmZmVyKAogICAgb3B0aW9ucy5idWZmZXJTaXplIHx8IERFRkFVTFRfVFJBTlNQT1JUX0JVRkZFUl9TSVpFLAogICksCikgewogIGxldCByYXRlTGltaXRzID0ge307CiAgY29uc3QgZmx1c2ggPSAodGltZW91dCkgPT4gYnVmZmVyLmRyYWluKHRpbWVvdXQpOwoKICBmdW5jdGlvbiBzZW5kKGVudmVsb3BlKSB7CiAgICBjb25zdCBmaWx0ZXJlZEVudmVsb3BlSXRlbXMgPSBbXTsKCiAgICAvLyBEcm9wIHJhdGUgbGltaXRlZCBpdGVtcyBmcm9tIGVudmVsb3BlCiAgICBmb3JFYWNoRW52ZWxvcGVJdGVtKGVudmVsb3BlLCAoaXRlbSwgdHlwZSkgPT4gewogICAgICBjb25zdCBlbnZlbG9wZUl0ZW1EYXRhQ2F0ZWdvcnkgPSBlbnZlbG9wZUl0ZW1UeXBlVG9EYXRhQ2F0ZWdvcnkodHlwZSk7CiAgICAgIGlmIChpc1JhdGVMaW1pdGVkKHJhdGVMaW1pdHMsIGVudmVsb3BlSXRlbURhdGFDYXRlZ29yeSkpIHsKICAgICAgICBjb25zdCBldmVudCA9IGdldEV2ZW50Rm9yRW52ZWxvcGVJdGVtKGl0ZW0sIHR5cGUpOwogICAgICAgIG9wdGlvbnMucmVjb3JkRHJvcHBlZEV2ZW50KCdyYXRlbGltaXRfYmFja29mZicsIGVudmVsb3BlSXRlbURhdGFDYXRlZ29yeSwgZXZlbnQpOwogICAgICB9IGVsc2UgewogICAgICAgIGZpbHRlcmVkRW52ZWxvcGVJdGVtcy5wdXNoKGl0ZW0pOwogICAgICB9CiAgICB9KTsKCiAgICAvLyBTa2lwIHNlbmRpbmcgaWYgZW52ZWxvcGUgaXMgZW1wdHkgYWZ0ZXIgZmlsdGVyaW5nIG91dCByYXRlIGxpbWl0ZWQgZXZlbnRzCiAgICBpZiAoZmlsdGVyZWRFbnZlbG9wZUl0ZW1zLmxlbmd0aCA9PT0gMCkgewogICAgICByZXR1cm4gcmVzb2x2ZWRTeW5jUHJvbWlzZSh7fSk7CiAgICB9CgogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnkKICAgIGNvbnN0IGZpbHRlcmVkRW52ZWxvcGUgPSBjcmVhdGVFbnZlbG9wZShlbnZlbG9wZVswXSwgZmlsdGVyZWRFbnZlbG9wZUl0ZW1zICk7CgogICAgLy8gQ3JlYXRlcyBjbGllbnQgcmVwb3J0IGZvciBlYWNoIGl0ZW0gaW4gYW4gZW52ZWxvcGUKICAgIGNvbnN0IHJlY29yZEVudmVsb3BlTG9zcyA9IChyZWFzb24pID0+IHsKICAgICAgZm9yRWFjaEVudmVsb3BlSXRlbShmaWx0ZXJlZEVudmVsb3BlLCAoaXRlbSwgdHlwZSkgPT4gewogICAgICAgIGNvbnN0IGV2ZW50ID0gZ2V0RXZlbnRGb3JFbnZlbG9wZUl0ZW0oaXRlbSwgdHlwZSk7CiAgICAgICAgb3B0aW9ucy5yZWNvcmREcm9wcGVkRXZlbnQocmVhc29uLCBlbnZlbG9wZUl0ZW1UeXBlVG9EYXRhQ2F0ZWdvcnkodHlwZSksIGV2ZW50KTsKICAgICAgfSk7CiAgICB9OwoKICAgIGNvbnN0IHJlcXVlc3RUYXNrID0gKCkgPT4KICAgICAgbWFrZVJlcXVlc3QoeyBib2R5OiBzZXJpYWxpemVFbnZlbG9wZShmaWx0ZXJlZEVudmVsb3BlKSB9KS50aGVuKAogICAgICAgIHJlc3BvbnNlID0+IHsKICAgICAgICAgIC8vIFdlIGRvbid0IHdhbnQgdG8gdGhyb3cgb24gTk9LIHJlc3BvbnNlcywgYnV0IHdlIHdhbnQgdG8gYXQgbGVhc3QgbG9nIHRoZW0KICAgICAgICAgIGlmIChyZXNwb25zZS5zdGF0dXNDb2RlICE9PSB1bmRlZmluZWQgJiYgKHJlc3BvbnNlLnN0YXR1c0NvZGUgPCAyMDAgfHwgcmVzcG9uc2Uuc3RhdHVzQ29kZSA+PSAzMDApKSB7CiAgICAgICAgICAgIERFQlVHX0JVSUxEICYmIGxvZ2dlci53YXJuKGBTZW50cnkgcmVzcG9uZGVkIHdpdGggc3RhdHVzIGNvZGUgJHtyZXNwb25zZS5zdGF0dXNDb2RlfSB0byBzZW50IGV2ZW50LmApOwogICAgICAgICAgfQoKICAgICAgICAgIHJhdGVMaW1pdHMgPSB1cGRhdGVSYXRlTGltaXRzKHJhdGVMaW1pdHMsIHJlc3BvbnNlKTsKICAgICAgICAgIHJldHVybiByZXNwb25zZTsKICAgICAgICB9LAogICAgICAgIGVycm9yID0+IHsKICAgICAgICAgIHJlY29yZEVudmVsb3BlTG9zcygnbmV0d29ya19lcnJvcicpOwogICAgICAgICAgdGhyb3cgZXJyb3I7CiAgICAgICAgfSwKICAgICAgKTsKCiAgICByZXR1cm4gYnVmZmVyLmFkZChyZXF1ZXN0VGFzaykudGhlbigKICAgICAgcmVzdWx0ID0+IHJlc3VsdCwKICAgICAgZXJyb3IgPT4gewogICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFNlbnRyeUVycm9yKSB7CiAgICAgICAgICBERUJVR19CVUlMRCAmJiBsb2dnZXIuZXJyb3IoJ1NraXBwZWQgc2VuZGluZyBldmVudCBiZWNhdXNlIGJ1ZmZlciBpcyBmdWxsLicpOwogICAgICAgICAgcmVjb3JkRW52ZWxvcGVMb3NzKCdxdWV1ZV9vdmVyZmxvdycpOwogICAgICAgICAgcmV0dXJuIHJlc29sdmVkU3luY1Byb21pc2Uoe30pOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICB0aHJvdyBlcnJvcjsKICAgICAgICB9CiAgICAgIH0sCiAgICApOwogIH0KCiAgcmV0dXJuIHsKICAgIHNlbmQsCiAgICBmbHVzaCwKICB9Owp9CgpmdW5jdGlvbiBnZXRFdmVudEZvckVudmVsb3BlSXRlbShpdGVtLCB0eXBlKSB7CiAgaWYgKHR5cGUgIT09ICdldmVudCcgJiYgdHlwZSAhPT0gJ3RyYW5zYWN0aW9uJykgewogICAgcmV0dXJuIHVuZGVmaW5lZDsKICB9CgogIHJldHVybiBBcnJheS5pc0FycmF5KGl0ZW0pID8gKGl0ZW0gKVsxXSA6IHVuZGVmaW5lZDsKfQoKZnVuY3Rpb24gX251bGxpc2hDb2FsZXNjZSQyKGxocywgcmhzRm4pIHsgaWYgKGxocyAhPSBudWxsKSB7IHJldHVybiBsaHM7IH0gZWxzZSB7IHJldHVybiByaHNGbigpOyB9IH0vKioKICogVGhpcyBjb2RlIHdhcyBvcmlnaW5hbGx5IGZvcmtlZCBmcm9tIGh0dHBzOi8vZ2l0aHViLmNvbS9Ub29UYWxsTmF0ZS9wcm94eS1hZ2VudHMvdHJlZS9iMTMzMjk1ZmQxNmY2NDc1NTc4YjZiMTViZDliNGUzM2VjYjBkMGI3CiAqIFdpdGggdGhlIGZvbGxvd2luZyBsaWNlbmNlOgogKgogKiAoVGhlIE1JVCBMaWNlbnNlKQogKgogKiBDb3B5cmlnaHQgKGMpIDIwMTMgTmF0aGFuIFJhamxpY2ggPG5hdGhhbkB0b290YWxsbmF0ZS5uZXQ+KgogKgogKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcKICogYSBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlCiAqICdTb2Z0d2FyZScpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcKICogd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLAogKiBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8KICogcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvCiAqIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoqCiAqCiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlCiAqIGluY2x1ZGVkIGluIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLioKICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICdBUyBJUycsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsCiAqIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRgogKiBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuCiAqIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZCiAqIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsCiAqIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFCiAqIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLgogKi8KCmNvbnN0IElOVEVSTkFMID0gU3ltYm9sKCdBZ2VudEJhc2VJbnRlcm5hbFN0YXRlJyk7CgpjbGFzcyBBZ2VudCBleHRlbmRzIGh0dHAuQWdlbnQgewoKICAvLyBTZXQgYnkgYGh0dHAuQWdlbnRgIC0gbWlzc2luZyBmcm9tIGBAdHlwZXMvbm9kZWAKCiAgY29uc3RydWN0b3Iob3B0cykgewogICAgc3VwZXIob3B0cyk7CiAgICB0aGlzW0lOVEVSTkFMXSA9IHt9OwogIH0KCiAgLyoqCiAgICogRGV0ZXJtaW5lIHdoZXRoZXIgdGhpcyBpcyBhbiBgaHR0cGAgb3IgYGh0dHBzYCByZXF1ZXN0LgogICAqLwogIGlzU2VjdXJlRW5kcG9pbnQob3B0aW9ucykgewogICAgaWYgKG9wdGlvbnMpIHsKICAgICAgLy8gRmlyc3QgY2hlY2sgdGhlIGBzZWN1cmVFbmRwb2ludGAgcHJvcGVydHkgZXhwbGljaXRseSwgc2luY2UgdGhpcwogICAgICAvLyBtZWFucyB0aGF0IGEgcGFyZW50IGBBZ2VudGAgaXMgInBhc3NpbmcgdGhyb3VnaCIgdG8gdGhpcyBpbnN0YW5jZS4KICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1leHBsaWNpdC1hbnksIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtbWVtYmVyLWFjY2VzcwogICAgICBpZiAodHlwZW9mIChvcHRpb25zICkuc2VjdXJlRW5kcG9pbnQgPT09ICdib29sZWFuJykgewogICAgICAgIHJldHVybiBvcHRpb25zLnNlY3VyZUVuZHBvaW50OwogICAgICB9CgogICAgICAvLyBJZiBubyBleHBsaWNpdCBgc2VjdXJlYCBlbmRwb2ludCwgY2hlY2sgaWYgYHByb3RvY29sYCBwcm9wZXJ0eSBpcwogICAgICAvLyBzZXQuIFRoaXMgd2lsbCB1c3VhbGx5IGJlIHRoZSBjYXNlIHNpbmNlIHVzaW5nIGEgZnVsbCBzdHJpbmcgVVJMCiAgICAgIC8vIG9yIGBVUkxgIGluc3RhbmNlIHNob3VsZCBiZSB0aGUgbW9zdCBjb21tb24gdXNhZ2UuCiAgICAgIGlmICh0eXBlb2Ygb3B0aW9ucy5wcm90b2NvbCA9PT0gJ3N0cmluZycpIHsKICAgICAgICByZXR1cm4gb3B0aW9ucy5wcm90b2NvbCA9PT0gJ2h0dHBzOic7CiAgICAgIH0KICAgIH0KCiAgICAvLyBGaW5hbGx5LCBpZiBubyBgcHJvdG9jb2xgIHByb3BlcnR5IHdhcyBzZXQsIHRoZW4gZmFsbCBiYWNrIHRvCiAgICAvLyBjaGVja2luZyB0aGUgc3RhY2sgdHJhY2Ugb2YgdGhlIGN1cnJlbnQgY2FsbCBzdGFjaywgYW5kIHRyeSB0bwogICAgLy8gZGV0ZWN0IHRoZSAiaHR0cHMiIG1vZHVsZS4KICAgIGNvbnN0IHsgc3RhY2sgfSA9IG5ldyBFcnJvcigpOwogICAgaWYgKHR5cGVvZiBzdGFjayAhPT0gJ3N0cmluZycpIHJldHVybiBmYWxzZTsKICAgIHJldHVybiBzdGFjay5zcGxpdCgnXG4nKS5zb21lKGwgPT4gbC5pbmRleE9mKCcoaHR0cHMuanM6JykgIT09IC0xIHx8IGwuaW5kZXhPZignbm9kZTpodHRwczonKSAhPT0gLTEpOwogIH0KCiAgY3JlYXRlU29ja2V0KHJlcSwgb3B0aW9ucywgY2IpIHsKICAgIGNvbnN0IGNvbm5lY3RPcHRzID0gewogICAgICAuLi5vcHRpb25zLAogICAgICBzZWN1cmVFbmRwb2ludDogdGhpcy5pc1NlY3VyZUVuZHBvaW50KG9wdGlvbnMpLAogICAgfTsKICAgIFByb21pc2UucmVzb2x2ZSgpCiAgICAgIC50aGVuKCgpID0+IHRoaXMuY29ubmVjdChyZXEsIGNvbm5lY3RPcHRzKSkKICAgICAgLnRoZW4oc29ja2V0ID0+IHsKICAgICAgICBpZiAoc29ja2V0IGluc3RhbmNlb2YgaHR0cC5BZ2VudCkgewogICAgICAgICAgLy8gQHRzLWV4cGVjdC1lcnJvciBgYWRkUmVxdWVzdCgpYCBpc24ndCBkZWZpbmVkIGluIGBAdHlwZXMvbm9kZWAKICAgICAgICAgIHJldHVybiBzb2NrZXQuYWRkUmVxdWVzdChyZXEsIGNvbm5lY3RPcHRzKTsKICAgICAgICB9CiAgICAgICAgdGhpc1tJTlRFUk5BTF0uY3VycmVudFNvY2tldCA9IHNvY2tldDsKICAgICAgICAvLyBAdHMtZXhwZWN0LWVycm9yIGBjcmVhdGVTb2NrZXQoKWAgaXNuJ3QgZGVmaW5lZCBpbiBgQHR5cGVzL25vZGVgCiAgICAgICAgc3VwZXIuY3JlYXRlU29ja2V0KHJlcSwgb3B0aW9ucywgY2IpOwogICAgICB9LCBjYik7CiAgfQoKICBjcmVhdGVDb25uZWN0aW9uKCkgewogICAgY29uc3Qgc29ja2V0ID0gdGhpc1tJTlRFUk5BTF0uY3VycmVudFNvY2tldDsKICAgIHRoaXNbSU5URVJOQUxdLmN1cnJlbnRTb2NrZXQgPSB1bmRlZmluZWQ7CiAgICBpZiAoIXNvY2tldCkgewogICAgICB0aHJvdyBuZXcgRXJyb3IoJ05vIHNvY2tldCB3YXMgcmV0dXJuZWQgaW4gdGhlIGBjb25uZWN0KClgIGZ1bmN0aW9uJyk7CiAgICB9CiAgICByZXR1cm4gc29ja2V0OwogIH0KCiAgZ2V0IGRlZmF1bHRQb3J0KCkgewogICAgcmV0dXJuIF9udWxsaXNoQ29hbGVzY2UkMih0aGlzW0lOVEVSTkFMXS5kZWZhdWx0UG9ydCwgKCkgPT4gKCAodGhpcy5wcm90b2NvbCA9PT0gJ2h0dHBzOicgPyA0NDMgOiA4MCkpKTsKICB9CgogIHNldCBkZWZhdWx0UG9ydCh2KSB7CiAgICBpZiAodGhpc1tJTlRFUk5BTF0pIHsKICAgICAgdGhpc1tJTlRFUk5BTF0uZGVmYXVsdFBvcnQgPSB2OwogICAgfQogIH0KCiAgZ2V0IHByb3RvY29sKCkgewogICAgcmV0dXJuIF9udWxsaXNoQ29hbGVzY2UkMih0aGlzW0lOVEVSTkFMXS5wcm90b2NvbCwgKCkgPT4gKCAodGhpcy5pc1NlY3VyZUVuZHBvaW50KCkgPyAnaHR0cHM6JyA6ICdodHRwOicpKSk7CiAgfQoKICBzZXQgcHJvdG9jb2wodikgewogICAgaWYgKHRoaXNbSU5URVJOQUxdKSB7CiAgICAgIHRoaXNbSU5URVJOQUxdLnByb3RvY29sID0gdjsKICAgIH0KICB9Cn0KCmZ1bmN0aW9uIGRlYnVnJDEoLi4uYXJncykgewogIGxvZ2dlci5sb2coJ1todHRwcy1wcm94eS1hZ2VudDpwYXJzZS1wcm94eS1yZXNwb25zZV0nLCAuLi5hcmdzKTsKfQoKZnVuY3Rpb24gcGFyc2VQcm94eVJlc3BvbnNlKHNvY2tldCkgewogIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7CiAgICAvLyB3ZSBuZWVkIHRvIGJ1ZmZlciBhbnkgSFRUUCB0cmFmZmljIHRoYXQgaGFwcGVucyB3aXRoIHRoZSBwcm94eSBiZWZvcmUgd2UgZ2V0CiAgICAvLyB0aGUgQ09OTkVDVCByZXNwb25zZSwgc28gdGhhdCBpZiB0aGUgcmVzcG9uc2UgaXMgYW55dGhpbmcgb3RoZXIgdGhhbiBhbiAiMjAwIgogICAgLy8gcmVzcG9uc2UgY29kZSwgdGhlbiB3ZSBjYW4gcmUtcGxheSB0aGUgImRhdGEiIGV2ZW50cyBvbiB0aGUgc29ja2V0IG9uY2UgdGhlCiAgICAvLyBIVFRQIHBhcnNlciBpcyBob29rZWQgdXAuLi4KICAgIGxldCBidWZmZXJzTGVuZ3RoID0gMDsKICAgIGNvbnN0IGJ1ZmZlcnMgPSBbXTsKCiAgICBmdW5jdGlvbiByZWFkKCkgewogICAgICBjb25zdCBiID0gc29ja2V0LnJlYWQoKTsKICAgICAgaWYgKGIpIG9uZGF0YShiKTsKICAgICAgZWxzZSBzb2NrZXQub25jZSgncmVhZGFibGUnLCByZWFkKTsKICAgIH0KCiAgICBmdW5jdGlvbiBjbGVhbnVwKCkgewogICAgICBzb2NrZXQucmVtb3ZlTGlzdGVuZXIoJ2VuZCcsIG9uZW5kKTsKICAgICAgc29ja2V0LnJlbW92ZUxpc3RlbmVyKCdlcnJvcicsIG9uZXJyb3IpOwogICAgICBzb2NrZXQucmVtb3ZlTGlzdGVuZXIoJ3JlYWRhYmxlJywgcmVhZCk7CiAgICB9CgogICAgZnVuY3Rpb24gb25lbmQoKSB7CiAgICAgIGNsZWFudXAoKTsKICAgICAgZGVidWckMSgnb25lbmQnKTsKICAgICAgcmVqZWN0KG5ldyBFcnJvcignUHJveHkgY29ubmVjdGlvbiBlbmRlZCBiZWZvcmUgcmVjZWl2aW5nIENPTk5FQ1QgcmVzcG9uc2UnKSk7CiAgICB9CgogICAgZnVuY3Rpb24gb25lcnJvcihlcnIpIHsKICAgICAgY2xlYW51cCgpOwogICAgICBkZWJ1ZyQxKCdvbmVycm9yICVvJywgZXJyKTsKICAgICAgcmVqZWN0KGVycik7CiAgICB9CgogICAgZnVuY3Rpb24gb25kYXRhKGIpIHsKICAgICAgYnVmZmVycy5wdXNoKGIpOwogICAgICBidWZmZXJzTGVuZ3RoICs9IGIubGVuZ3RoOwoKICAgICAgY29uc3QgYnVmZmVyZWQgPSBCdWZmZXIuY29uY2F0KGJ1ZmZlcnMsIGJ1ZmZlcnNMZW5ndGgpOwogICAgICBjb25zdCBlbmRPZkhlYWRlcnMgPSBidWZmZXJlZC5pbmRleE9mKCdcclxuXHJcbicpOwoKICAgICAgaWYgKGVuZE9mSGVhZGVycyA9PT0gLTEpIHsKICAgICAgICAvLyBrZWVwIGJ1ZmZlcmluZwogICAgICAgIGRlYnVnJDEoJ2hhdmUgbm90IHJlY2VpdmVkIGVuZCBvZiBIVFRQIGhlYWRlcnMgeWV0Li4uJyk7CiAgICAgICAgcmVhZCgpOwogICAgICAgIHJldHVybjsKICAgICAgfQoKICAgICAgY29uc3QgaGVhZGVyUGFydHMgPSBidWZmZXJlZC5zbGljZSgwLCBlbmRPZkhlYWRlcnMpLnRvU3RyaW5nKCdhc2NpaScpLnNwbGl0KCdcclxuJyk7CiAgICAgIGNvbnN0IGZpcnN0TGluZSA9IGhlYWRlclBhcnRzLnNoaWZ0KCk7CiAgICAgIGlmICghZmlyc3RMaW5lKSB7CiAgICAgICAgc29ja2V0LmRlc3Ryb3koKTsKICAgICAgICByZXR1cm4gcmVqZWN0KG5ldyBFcnJvcignTm8gaGVhZGVyIHJlY2VpdmVkIGZyb20gcHJveHkgQ09OTkVDVCByZXNwb25zZScpKTsKICAgICAgfQogICAgICBjb25zdCBmaXJzdExpbmVQYXJ0cyA9IGZpcnN0TGluZS5zcGxpdCgnICcpOwogICAgICBjb25zdCBzdGF0dXNDb2RlID0gK2ZpcnN0TGluZVBhcnRzWzFdOwogICAgICBjb25zdCBzdGF0dXNUZXh0ID0gZmlyc3RMaW5lUGFydHMuc2xpY2UoMikuam9pbignICcpOwogICAgICBjb25zdCBoZWFkZXJzID0ge307CiAgICAgIGZvciAoY29uc3QgaGVhZGVyIG9mIGhlYWRlclBhcnRzKSB7CiAgICAgICAgaWYgKCFoZWFkZXIpIGNvbnRpbnVlOwogICAgICAgIGNvbnN0IGZpcnN0Q29sb24gPSBoZWFkZXIuaW5kZXhPZignOicpOwogICAgICAgIGlmIChmaXJzdENvbG9uID09PSAtMSkgewogICAgICAgICAgc29ja2V0LmRlc3Ryb3koKTsKICAgICAgICAgIHJldHVybiByZWplY3QobmV3IEVycm9yKGBJbnZhbGlkIGhlYWRlciBmcm9tIHByb3h5IENPTk5FQ1QgcmVzcG9uc2U6ICIke2hlYWRlcn0iYCkpOwogICAgICAgIH0KICAgICAgICBjb25zdCBrZXkgPSBoZWFkZXIuc2xpY2UoMCwgZmlyc3RDb2xvbikudG9Mb3dlckNhc2UoKTsKICAgICAgICBjb25zdCB2YWx1ZSA9IGhlYWRlci5zbGljZShmaXJzdENvbG9uICsgMSkudHJpbVN0YXJ0KCk7CiAgICAgICAgY29uc3QgY3VycmVudCA9IGhlYWRlcnNba2V5XTsKICAgICAgICBpZiAodHlwZW9mIGN1cnJlbnQgPT09ICdzdHJpbmcnKSB7CiAgICAgICAgICBoZWFkZXJzW2tleV0gPSBbY3VycmVudCwgdmFsdWVdOwogICAgICAgIH0gZWxzZSBpZiAoQXJyYXkuaXNBcnJheShjdXJyZW50KSkgewogICAgICAgICAgY3VycmVudC5wdXNoKHZhbHVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgaGVhZGVyc1trZXldID0gdmFsdWU7CiAgICAgICAgfQogICAgICB9CiAgICAgIGRlYnVnJDEoJ2dvdCBwcm94eSBzZXJ2ZXIgcmVzcG9uc2U6ICVvICVvJywgZmlyc3RMaW5lLCBoZWFkZXJzKTsKICAgICAgY2xlYW51cCgpOwogICAgICByZXNvbHZlKHsKICAgICAgICBjb25uZWN0OiB7CiAgICAgICAgICBzdGF0dXNDb2RlLAogICAgICAgICAgc3RhdHVzVGV4dCwKICAgICAgICAgIGhlYWRlcnMsCiAgICAgICAgfSwKICAgICAgICBidWZmZXJlZCwKICAgICAgfSk7CiAgICB9CgogICAgc29ja2V0Lm9uKCdlcnJvcicsIG9uZXJyb3IpOwogICAgc29ja2V0Lm9uKCdlbmQnLCBvbmVuZCk7CgogICAgcmVhZCgpOwogIH0pOwp9CgpmdW5jdGlvbiBfbnVsbGlzaENvYWxlc2NlJDEobGhzLCByaHNGbikgeyBpZiAobGhzICE9IG51bGwpIHsgcmV0dXJuIGxoczsgfSBlbHNlIHsgcmV0dXJuIHJoc0ZuKCk7IH0gfSBmdW5jdGlvbiBfb3B0aW9uYWxDaGFpbiQxKG9wcykgeyBsZXQgbGFzdEFjY2Vzc0xIUyA9IHVuZGVmaW5lZDsgbGV0IHZhbHVlID0gb3BzWzBdOyBsZXQgaSA9IDE7IHdoaWxlIChpIDwgb3BzLmxlbmd0aCkgeyBjb25zdCBvcCA9IG9wc1tpXTsgY29uc3QgZm4gPSBvcHNbaSArIDFdOyBpICs9IDI7IGlmICgob3AgPT09ICdvcHRpb25hbEFjY2VzcycgfHwgb3AgPT09ICdvcHRpb25hbENhbGwnKSAmJiB2YWx1ZSA9PSBudWxsKSB7IHJldHVybiB1bmRlZmluZWQ7IH0gaWYgKG9wID09PSAnYWNjZXNzJyB8fCBvcCA9PT0gJ29wdGlvbmFsQWNjZXNzJykgeyBsYXN0QWNjZXNzTEhTID0gdmFsdWU7IHZhbHVlID0gZm4odmFsdWUpOyB9IGVsc2UgaWYgKG9wID09PSAnY2FsbCcgfHwgb3AgPT09ICdvcHRpb25hbENhbGwnKSB7IHZhbHVlID0gZm4oKC4uLmFyZ3MpID0+IHZhbHVlLmNhbGwobGFzdEFjY2Vzc0xIUywgLi4uYXJncykpOyBsYXN0QWNjZXNzTEhTID0gdW5kZWZpbmVkOyB9IH0gcmV0dXJuIHZhbHVlOyB9LyoqCiAqIFRoaXMgY29kZSB3YXMgb3JpZ2luYWxseSBmb3JrZWQgZnJvbSBodHRwczovL2dpdGh1Yi5jb20vVG9vVGFsbE5hdGUvcHJveHktYWdlbnRzL3RyZWUvYjEzMzI5NWZkMTZmNjQ3NTU3OGI2YjE1YmQ5YjRlMzNlY2IwZDBiNwogKiBXaXRoIHRoZSBmb2xsb3dpbmcgbGljZW5jZToKICoKICogKFRoZSBNSVQgTGljZW5zZSkKICoKICogQ29weXJpZ2h0IChjKSAyMDEzIE5hdGhhbiBSYWpsaWNoIDxuYXRoYW5AdG9vdGFsbG5hdGUubmV0PioKICoKICogUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nCiAqIGEgY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZQogKiAnU29mdHdhcmUnKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nCiAqIHdpdGhvdXQgbGltaXRhdGlvbiB0aGUgcmlnaHRzIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwKICogZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvCiAqIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0bwogKiB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6KgogKgogKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZQogKiBpbmNsdWRlZCBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4qCiAqCiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAnQVMgSVMnLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELAogKiBFWFBSRVNTIE9SIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YKICogTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULgogKiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWQogKiBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULAogKiBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRQogKiBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS4KICovCgpmdW5jdGlvbiBkZWJ1ZyguLi5hcmdzKSB7CiAgbG9nZ2VyLmxvZygnW2h0dHBzLXByb3h5LWFnZW50XScsIC4uLmFyZ3MpOwp9CgovKioKICogVGhlIGBIdHRwc1Byb3h5QWdlbnRgIGltcGxlbWVudHMgYW4gSFRUUCBBZ2VudCBzdWJjbGFzcyB0aGF0IGNvbm5lY3RzIHRvCiAqIHRoZSBzcGVjaWZpZWQgIkhUVFAocykgcHJveHkgc2VydmVyIiBpbiBvcmRlciB0byBwcm94eSBIVFRQUyByZXF1ZXN0cy4KICoKICogT3V0Z29pbmcgSFRUUCByZXF1ZXN0cyBhcmUgZmlyc3QgdHVubmVsZWQgdGhyb3VnaCB0aGUgcHJveHkgc2VydmVyIHVzaW5nIHRoZQogKiBgQ09OTkVDVGAgSFRUUCByZXF1ZXN0IG1ldGhvZCB0byBlc3RhYmxpc2ggYSBjb25uZWN0aW9uIHRvIHRoZSBwcm94eSBzZXJ2ZXIsCiAqIGFuZCB0aGVuIHRoZSBwcm94eSBzZXJ2ZXIgY29ubmVjdHMgdG8gdGhlIGRlc3RpbmF0aW9uIHRhcmdldCBhbmQgaXNzdWVzIHRoZQogKiBIVFRQIHJlcXVlc3QgZnJvbSB0aGUgcHJveHkgc2VydmVyLgogKgogKiBgaHR0cHM6YCByZXF1ZXN0cyBoYXZlIHRoZWlyIHNvY2tldCBjb25uZWN0aW9uIHVwZ3JhZGVkIHRvIFRMUyBvbmNlCiAqIHRoZSBjb25uZWN0aW9uIHRvIHRoZSBwcm94eSBzZXJ2ZXIgaGFzIGJlZW4gZXN0YWJsaXNoZWQuCiAqLwpjbGFzcyBIdHRwc1Byb3h5QWdlbnQgZXh0ZW5kcyBBZ2VudCB7CiAgc3RhdGljIF9faW5pdFN0YXRpYygpIHt0aGlzLnByb3RvY29scyA9IFsnaHR0cCcsICdodHRwcyddOyB9CgogIGNvbnN0cnVjdG9yKHByb3h5LCBvcHRzKSB7CiAgICBzdXBlcihvcHRzKTsKICAgIHRoaXMub3B0aW9ucyA9IHt9OwogICAgdGhpcy5wcm94eSA9IHR5cGVvZiBwcm94eSA9PT0gJ3N0cmluZycgPyBuZXcgVVJMKHByb3h5KSA6IHByb3h5OwogICAgdGhpcy5wcm94eUhlYWRlcnMgPSBfbnVsbGlzaENvYWxlc2NlJDEoX29wdGlvbmFsQ2hhaW4kMShbb3B0cywgJ29wdGlvbmFsQWNjZXNzJywgXzIgPT4gXzIuaGVhZGVyc10pLCAoKSA9PiAoIHt9KSk7CiAgICBkZWJ1ZygnQ3JlYXRpbmcgbmV3IEh0dHBzUHJveHlBZ2VudCBpbnN0YW5jZTogJW8nLCB0aGlzLnByb3h5LmhyZWYpOwoKICAgIC8vIFRyaW0gb2ZmIHRoZSBicmFja2V0cyBmcm9tIElQdjYgYWRkcmVzc2VzCiAgICBjb25zdCBob3N0ID0gKHRoaXMucHJveHkuaG9zdG5hbWUgfHwgdGhpcy5wcm94eS5ob3N0KS5yZXBsYWNlKC9eXFt8XF0kL2csICcnKTsKICAgIGNvbnN0IHBvcnQgPSB0aGlzLnByb3h5LnBvcnQgPyBwYXJzZUludCh0aGlzLnByb3h5LnBvcnQsIDEwKSA6IHRoaXMucHJveHkucHJvdG9jb2wgPT09ICdodHRwczonID8gNDQzIDogODA7CiAgICB0aGlzLmNvbm5lY3RPcHRzID0gewogICAgICAvLyBBdHRlbXB0IHRvIG5lZ290aWF0ZSBodHRwLzEuMSBmb3IgcHJveHkgc2VydmVycyB0aGF0IHN1cHBvcnQgaHR0cC8yCiAgICAgIEFMUE5Qcm90b2NvbHM6IFsnaHR0cC8xLjEnXSwKICAgICAgLi4uKG9wdHMgPyBvbWl0KG9wdHMsICdoZWFkZXJzJykgOiBudWxsKSwKICAgICAgaG9zdCwKICAgICAgcG9ydCwKICAgIH07CiAgfQoKICAvKioKICAgKiBDYWxsZWQgd2hlbiB0aGUgbm9kZS1jb3JlIEhUVFAgY2xpZW50IGxpYnJhcnkgaXMgY3JlYXRpbmcgYQogICAqIG5ldyBIVFRQIHJlcXVlc3QuCiAgICovCiAgYXN5bmMgY29ubmVjdChyZXEsIG9wdHMpIHsKICAgIGNvbnN0IHsgcHJveHkgfSA9IHRoaXM7CgogICAgaWYgKCFvcHRzLmhvc3QpIHsKICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignTm8gImhvc3QiIHByb3ZpZGVkJyk7CiAgICB9CgogICAgLy8gQ3JlYXRlIGEgc29ja2V0IGNvbm5lY3Rpb24gdG8gdGhlIHByb3h5IHNlcnZlci4KICAgIGxldCBzb2NrZXQ7CiAgICBpZiAocHJveHkucHJvdG9jb2wgPT09ICdodHRwczonKSB7CiAgICAgIGRlYnVnKCdDcmVhdGluZyBgdGxzLlNvY2tldGA6ICVvJywgdGhpcy5jb25uZWN0T3B0cyk7CiAgICAgIGNvbnN0IHNlcnZlcm5hbWUgPSB0aGlzLmNvbm5lY3RPcHRzLnNlcnZlcm5hbWUgfHwgdGhpcy5jb25uZWN0T3B0cy5ob3N0OwogICAgICBzb2NrZXQgPSB0bHMuY29ubmVjdCh7CiAgICAgICAgLi4udGhpcy5jb25uZWN0T3B0cywKICAgICAgICBzZXJ2ZXJuYW1lOiBzZXJ2ZXJuYW1lICYmIG5ldC5pc0lQKHNlcnZlcm5hbWUpID8gdW5kZWZpbmVkIDogc2VydmVybmFtZSwKICAgICAgfSk7CiAgICB9IGVsc2UgewogICAgICBkZWJ1ZygnQ3JlYXRpbmcgYG5ldC5Tb2NrZXRgOiAlbycsIHRoaXMuY29ubmVjdE9wdHMpOwogICAgICBzb2NrZXQgPSBuZXQuY29ubmVjdCh0aGlzLmNvbm5lY3RPcHRzKTsKICAgIH0KCiAgICBjb25zdCBoZWFkZXJzID0KICAgICAgdHlwZW9mIHRoaXMucHJveHlIZWFkZXJzID09PSAnZnVuY3Rpb24nID8gdGhpcy5wcm94eUhlYWRlcnMoKSA6IHsgLi4udGhpcy5wcm94eUhlYWRlcnMgfTsKICAgIGNvbnN0IGhvc3QgPSBuZXQuaXNJUHY2KG9wdHMuaG9zdCkgPyBgWyR7b3B0cy5ob3N0fV1gIDogb3B0cy5ob3N0OwogICAgbGV0IHBheWxvYWQgPSBgQ09OTkVDVCAke2hvc3R9OiR7b3B0cy5wb3J0fSBIVFRQLzEuMVxyXG5gOwoKICAgIC8vIEluamVjdCB0aGUgYFByb3h5LUF1dGhvcml6YXRpb25gIGhlYWRlciBpZiBuZWNlc3NhcnkuCiAgICBpZiAocHJveHkudXNlcm5hbWUgfHwgcHJveHkucGFzc3dvcmQpIHsKICAgICAgY29uc3QgYXV0aCA9IGAke2RlY29kZVVSSUNvbXBvbmVudChwcm94eS51c2VybmFtZSl9OiR7ZGVjb2RlVVJJQ29tcG9uZW50KHByb3h5LnBhc3N3b3JkKX1gOwogICAgICBoZWFkZXJzWydQcm94eS1BdXRob3JpemF0aW9uJ10gPSBgQmFzaWMgJHtCdWZmZXIuZnJvbShhdXRoKS50b1N0cmluZygnYmFzZTY0Jyl9YDsKICAgIH0KCiAgICBoZWFkZXJzLkhvc3QgPSBgJHtob3N0fToke29wdHMucG9ydH1gOwoKICAgIGlmICghaGVhZGVyc1snUHJveHktQ29ubmVjdGlvbiddKSB7CiAgICAgIGhlYWRlcnNbJ1Byb3h5LUNvbm5lY3Rpb24nXSA9IHRoaXMua2VlcEFsaXZlID8gJ0tlZXAtQWxpdmUnIDogJ2Nsb3NlJzsKICAgIH0KICAgIGZvciAoY29uc3QgbmFtZSBvZiBPYmplY3Qua2V5cyhoZWFkZXJzKSkgewogICAgICBwYXlsb2FkICs9IGAke25hbWV9OiAke2hlYWRlcnNbbmFtZV19XHJcbmA7CiAgICB9CgogICAgY29uc3QgcHJveHlSZXNwb25zZVByb21pc2UgPSBwYXJzZVByb3h5UmVzcG9uc2Uoc29ja2V0KTsKCiAgICBzb2NrZXQud3JpdGUoYCR7cGF5bG9hZH1cclxuYCk7CgogICAgY29uc3QgeyBjb25uZWN0LCBidWZmZXJlZCB9ID0gYXdhaXQgcHJveHlSZXNwb25zZVByb21pc2U7CiAgICByZXEuZW1pdCgncHJveHlDb25uZWN0JywgY29ubmVjdCk7CiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L2Jhbi10cy1jb21tZW50CiAgICAvLyBAdHMtaWdub3JlIE5vdCBFdmVudEVtaXR0ZXIgaW4gTm9kZSB0eXBlcwogICAgdGhpcy5lbWl0KCdwcm94eUNvbm5lY3QnLCBjb25uZWN0LCByZXEpOwoKICAgIGlmIChjb25uZWN0LnN0YXR1c0NvZGUgPT09IDIwMCkgewogICAgICByZXEub25jZSgnc29ja2V0JywgcmVzdW1lKTsKCiAgICAgIGlmIChvcHRzLnNlY3VyZUVuZHBvaW50KSB7CiAgICAgICAgLy8gVGhlIHByb3h5IGlzIGNvbm5lY3RpbmcgdG8gYSBUTFMgc2VydmVyLCBzbyB1cGdyYWRlCiAgICAgICAgLy8gdGhpcyBzb2NrZXQgY29ubmVjdGlvbiB0byBhIFRMUyBjb25uZWN0aW9uLgogICAgICAgIGRlYnVnKCdVcGdyYWRpbmcgc29ja2V0IGNvbm5lY3Rpb24gdG8gVExTJyk7CiAgICAgICAgY29uc3Qgc2VydmVybmFtZSA9IG9wdHMuc2VydmVybmFtZSB8fCBvcHRzLmhvc3Q7CiAgICAgICAgcmV0dXJuIHRscy5jb25uZWN0KHsKICAgICAgICAgIC4uLm9taXQob3B0cywgJ2hvc3QnLCAncGF0aCcsICdwb3J0JyksCiAgICAgICAgICBzb2NrZXQsCiAgICAgICAgICBzZXJ2ZXJuYW1lOiBuZXQuaXNJUChzZXJ2ZXJuYW1lKSA/IHVuZGVmaW5lZCA6IHNlcnZlcm5hbWUsCiAgICAgICAgfSk7CiAgICAgIH0KCiAgICAgIHJldHVybiBzb2NrZXQ7CiAgICB9CgogICAgLy8gU29tZSBvdGhlciBzdGF0dXMgY29kZSB0aGF0J3Mgbm90IDIwMC4uLiBuZWVkIHRvIHJlLXBsYXkgdGhlIEhUVFAKICAgIC8vIGhlYWRlciAiZGF0YSIgZXZlbnRzIG9udG8gdGhlIHNvY2tldCBvbmNlIHRoZSBIVFRQIG1hY2hpbmVyeSBpcwogICAgLy8gYXR0YWNoZWQgc28gdGhhdCB0aGUgbm9kZSBjb3JlIGBodHRwYCBjYW4gcGFyc2UgYW5kIGhhbmRsZSB0aGUKICAgIC8vIGVycm9yIHN0YXR1cyBjb2RlLgoKICAgIC8vIENsb3NlIHRoZSBvcmlnaW5hbCBzb2NrZXQsIGFuZCBhIG5ldyAiZmFrZSIgc29ja2V0IGlzIHJldHVybmVkCiAgICAvLyBpbnN0ZWFkLCBzbyB0aGF0IHRoZSBwcm94eSBkb2Vzbid0IGdldCB0aGUgSFRUUCByZXF1ZXN0CiAgICAvLyB3cml0dGVuIHRvIGl0ICh3aGljaCBtYXkgY29udGFpbiBgQXV0aG9yaXphdGlvbmAgaGVhZGVycyBvciBvdGhlcgogICAgLy8gc2Vuc2l0aXZlIGRhdGEpLgogICAgLy8KICAgIC8vIFNlZTogaHR0cHM6Ly9oYWNrZXJvbmUuY29tL3JlcG9ydHMvNTQxNTAyCiAgICBzb2NrZXQuZGVzdHJveSgpOwoKICAgIGNvbnN0IGZha2VTb2NrZXQgPSBuZXcgbmV0LlNvY2tldCh7IHdyaXRhYmxlOiBmYWxzZSB9KTsKICAgIGZha2VTb2NrZXQucmVhZGFibGUgPSB0cnVlOwoKICAgIC8vIE5lZWQgdG8gd2FpdCBmb3IgdGhlICJzb2NrZXQiIGV2ZW50IHRvIHJlLXBsYXkgdGhlICJkYXRhIiBldmVudHMuCiAgICByZXEub25jZSgnc29ja2V0JywgKHMpID0+IHsKICAgICAgZGVidWcoJ1JlcGxheWluZyBwcm94eSBidWZmZXIgZm9yIGZhaWxlZCByZXF1ZXN0Jyk7CiAgICAgIGFzc2VydChzLmxpc3RlbmVyQ291bnQoJ2RhdGEnKSA+IDApOwoKICAgICAgLy8gUmVwbGF5IHRoZSAiYnVmZmVyZWQiIEJ1ZmZlciBvbnRvIHRoZSBmYWtlIGBzb2NrZXRgLCBzaW5jZSBhdAogICAgICAvLyB0aGlzIHBvaW50IHRoZSBIVFRQIG1vZHVsZSBtYWNoaW5lcnkgaGFzIGJlZW4gaG9va2VkIHVwIGZvcgogICAgICAvLyB0aGUgdXNlci4KICAgICAgcy5wdXNoKGJ1ZmZlcmVkKTsKICAgICAgcy5wdXNoKG51bGwpOwogICAgfSk7CgogICAgcmV0dXJuIGZha2VTb2NrZXQ7CiAgfQp9IEh0dHBzUHJveHlBZ2VudC5fX2luaXRTdGF0aWMoKTsKCmZ1bmN0aW9uIHJlc3VtZShzb2NrZXQpIHsKICBzb2NrZXQucmVzdW1lKCk7Cn0KCmZ1bmN0aW9uIG9taXQoCiAgb2JqLAogIC4uLmtleXMKKQoKIHsKICBjb25zdCByZXQgPSB7fQoKOwogIGxldCBrZXk7CiAgZm9yIChrZXkgaW4gb2JqKSB7CiAgICBpZiAoIWtleXMuaW5jbHVkZXMoa2V5KSkgewogICAgICByZXRba2V5XSA9IG9ialtrZXldOwogICAgfQogIH0KICByZXR1cm4gcmV0Owp9CgpmdW5jdGlvbiBfbnVsbGlzaENvYWxlc2NlKGxocywgcmhzRm4pIHsgaWYgKGxocyAhPSBudWxsKSB7IHJldHVybiBsaHM7IH0gZWxzZSB7IHJldHVybiByaHNGbigpOyB9IH0KLy8gRXN0aW1hdGVkIG1heGltdW0gc2l6ZSBmb3IgcmVhc29uYWJsZSBzdGFuZGFsb25lIGV2ZW50CmNvbnN0IEdaSVBfVEhSRVNIT0xEID0gMTAyNCAqIDMyOwoKLyoqCiAqIEdldHMgYSBzdHJlYW0gZnJvbSBhIFVpbnQ4QXJyYXkgb3Igc3RyaW5nCiAqIFJlYWRhYmxlLmZyb20gaXMgaWRlYWwgYnV0IHdhcyBhZGRlZCBpbiBub2RlLmpzIHYxMi4zLjAgYW5kIHYxMC4xNy4wCiAqLwpmdW5jdGlvbiBzdHJlYW1Gcm9tQm9keShib2R5KSB7CiAgcmV0dXJuIG5ldyBSZWFkYWJsZSh7CiAgICByZWFkKCkgewogICAgICB0aGlzLnB1c2goYm9keSk7CiAgICAgIHRoaXMucHVzaChudWxsKTsKICAgIH0sCiAgfSk7Cn0KCi8qKgogKiBDcmVhdGVzIGEgVHJhbnNwb3J0IHRoYXQgdXNlcyBuYXRpdmUgdGhlIG5hdGl2ZSAnaHR0cCcgYW5kICdodHRwcycgbW9kdWxlcyB0byBzZW5kIGV2ZW50cyB0byBTZW50cnkuCiAqLwpmdW5jdGlvbiBtYWtlTm9kZVRyYW5zcG9ydChvcHRpb25zKSB7CiAgbGV0IHVybFNlZ21lbnRzOwoKICB0cnkgewogICAgdXJsU2VnbWVudHMgPSBuZXcgVVJMKG9wdGlvbnMudXJsKTsKICB9IGNhdGNoIChlKSB7CiAgICBjb25zb2xlU2FuZGJveCgoKSA9PiB7CiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlCiAgICAgIGNvbnNvbGUud2FybigKICAgICAgICAnW0BzZW50cnkvbm9kZV06IEludmFsaWQgZHNuIG9yIHR1bm5lbCBvcHRpb24sIHdpbGwgbm90IHNlbmQgYW55IGV2ZW50cy4gVGhlIHR1bm5lbCBvcHRpb24gbXVzdCBiZSBhIGZ1bGwgVVJMIHdoZW4gdXNlZC4nLAogICAgICApOwogICAgfSk7CiAgICByZXR1cm4gY3JlYXRlVHJhbnNwb3J0KG9wdGlvbnMsICgpID0+IFByb21pc2UucmVzb2x2ZSh7fSkpOwogIH0KCiAgY29uc3QgaXNIdHRwcyA9IHVybFNlZ21lbnRzLnByb3RvY29sID09PSAnaHR0cHM6JzsKCiAgLy8gUHJveHkgcHJpb3JpdGl6YXRpb246IGh0dHAgPT4gYG9wdGlvbnMucHJveHlgIHwgYHByb2Nlc3MuZW52Lmh0dHBfcHJveHlgCiAgLy8gUHJveHkgcHJpb3JpdGl6YXRpb246IGh0dHBzID0+IGBvcHRpb25zLnByb3h5YCB8IGBwcm9jZXNzLmVudi5odHRwc19wcm94eWAgfCBgcHJvY2Vzcy5lbnYuaHR0cF9wcm94eWAKICBjb25zdCBwcm94eSA9IGFwcGx5Tm9Qcm94eU9wdGlvbigKICAgIHVybFNlZ21lbnRzLAogICAgb3B0aW9ucy5wcm94eSB8fCAoaXNIdHRwcyA/IHByb2Nlc3MuZW52Lmh0dHBzX3Byb3h5IDogdW5kZWZpbmVkKSB8fCBwcm9jZXNzLmVudi5odHRwX3Byb3h5LAogICk7CgogIGNvbnN0IG5hdGl2ZUh0dHBNb2R1bGUgPSBpc0h0dHBzID8gaHR0cHMgOiBodHRwOwogIGNvbnN0IGtlZXBBbGl2ZSA9IG9wdGlvbnMua2VlcEFsaXZlID09PSB1bmRlZmluZWQgPyBmYWxzZSA6IG9wdGlvbnMua2VlcEFsaXZlOwoKICAvLyBUT0RPKHY3KTogRXZhbHVhdGUgaWYgd2UgY2FuIHNldCBrZWVwQWxpdmUgdG8gdHJ1ZS4gVGhpcyB3b3VsZCBpbnZvbHZlIHRlc3RpbmcgZm9yIG1lbW9yeSBsZWFrcyBpbiBvbGRlciBub2RlCiAgLy8gdmVyc2lvbnMoPj0gOCkgYXMgdGhleSBoYWQgbWVtb3J5IGxlYWtzIHdoZW4gdXNpbmcgaXQ6ICMyNTU1CiAgY29uc3QgYWdlbnQgPSBwcm94eQogICAgPyAobmV3IEh0dHBzUHJveHlBZ2VudChwcm94eSkgKQogICAgOiBuZXcgbmF0aXZlSHR0cE1vZHVsZS5BZ2VudCh7IGtlZXBBbGl2ZSwgbWF4U29ja2V0czogMzAsIHRpbWVvdXQ6IDIwMDAgfSk7CgogIGNvbnN0IHJlcXVlc3RFeGVjdXRvciA9IGNyZWF0ZVJlcXVlc3RFeGVjdXRvcihvcHRpb25zLCBfbnVsbGlzaENvYWxlc2NlKG9wdGlvbnMuaHR0cE1vZHVsZSwgKCkgPT4gKCBuYXRpdmVIdHRwTW9kdWxlKSksIGFnZW50KTsKICByZXR1cm4gY3JlYXRlVHJhbnNwb3J0KG9wdGlvbnMsIHJlcXVlc3RFeGVjdXRvcik7Cn0KCi8qKgogKiBIb25vcnMgdGhlIGBub19wcm94eWAgZW52IHZhcmlhYmxlIHdpdGggdGhlIGhpZ2hlc3QgcHJpb3JpdHkgdG8gYWxsb3cgZm9yIGhvc3RzIGV4Y2x1c2lvbi4KICoKICogQHBhcmFtIHRyYW5zcG9ydFVybCBUaGUgVVJMIHRoZSB0cmFuc3BvcnQgaW50ZW5kcyB0byBzZW5kIGV2ZW50cyB0by4KICogQHBhcmFtIHByb3h5IFRoZSBjbGllbnQgY29uZmlndXJlZCBwcm94eS4KICogQHJldHVybnMgQSBwcm94eSB0aGUgdHJhbnNwb3J0IHNob3VsZCB1c2UuCiAqLwpmdW5jdGlvbiBhcHBseU5vUHJveHlPcHRpb24odHJhbnNwb3J0VXJsU2VnbWVudHMsIHByb3h5KSB7CiAgY29uc3QgeyBub19wcm94eSB9ID0gcHJvY2Vzcy5lbnY7CgogIGNvbnN0IHVybElzRXhlbXB0RnJvbVByb3h5ID0KICAgIG5vX3Byb3h5ICYmCiAgICBub19wcm94eQogICAgICAuc3BsaXQoJywnKQogICAgICAuc29tZSgKICAgICAgICBleGVtcHRpb24gPT4gdHJhbnNwb3J0VXJsU2VnbWVudHMuaG9zdC5lbmRzV2l0aChleGVtcHRpb24pIHx8IHRyYW5zcG9ydFVybFNlZ21lbnRzLmhvc3RuYW1lLmVuZHNXaXRoKGV4ZW1wdGlvbiksCiAgICAgICk7CgogIGlmICh1cmxJc0V4ZW1wdEZyb21Qcm94eSkgewogICAgcmV0dXJuIHVuZGVmaW5lZDsKICB9IGVsc2UgewogICAgcmV0dXJuIHByb3h5OwogIH0KfQoKLyoqCiAqIENyZWF0ZXMgYSBSZXF1ZXN0RXhlY3V0b3IgdG8gYmUgdXNlZCB3aXRoIGBjcmVhdGVUcmFuc3BvcnRgLgogKi8KZnVuY3Rpb24gY3JlYXRlUmVxdWVzdEV4ZWN1dG9yKAogIG9wdGlvbnMsCiAgaHR0cE1vZHVsZSwKICBhZ2VudCwKKSB7CiAgY29uc3QgeyBob3N0bmFtZSwgcGF0aG5hbWUsIHBvcnQsIHByb3RvY29sLCBzZWFyY2ggfSA9IG5ldyBVUkwob3B0aW9ucy51cmwpOwogIHJldHVybiBmdW5jdGlvbiBtYWtlUmVxdWVzdChyZXF1ZXN0KSB7CiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4gewogICAgICBsZXQgYm9keSA9IHN0cmVhbUZyb21Cb2R5KHJlcXVlc3QuYm9keSk7CgogICAgICBjb25zdCBoZWFkZXJzID0geyAuLi5vcHRpb25zLmhlYWRlcnMgfTsKCiAgICAgIGlmIChyZXF1ZXN0LmJvZHkubGVuZ3RoID4gR1pJUF9USFJFU0hPTEQpIHsKICAgICAgICBoZWFkZXJzWydjb250ZW50LWVuY29kaW5nJ10gPSAnZ3ppcCc7CiAgICAgICAgYm9keSA9IGJvZHkucGlwZShjcmVhdGVHemlwKCkpOwogICAgICB9CgogICAgICBjb25zdCByZXEgPSBodHRwTW9kdWxlLnJlcXVlc3QoCiAgICAgICAgewogICAgICAgICAgbWV0aG9kOiAnUE9TVCcsCiAgICAgICAgICBhZ2VudCwKICAgICAgICAgIGhlYWRlcnMsCiAgICAgICAgICBob3N0bmFtZSwKICAgICAgICAgIHBhdGg6IGAke3BhdGhuYW1lfSR7c2VhcmNofWAsCiAgICAgICAgICBwb3J0LAogICAgICAgICAgcHJvdG9jb2wsCiAgICAgICAgICBjYTogb3B0aW9ucy5jYUNlcnRzLAogICAgICAgIH0sCiAgICAgICAgcmVzID0+IHsKICAgICAgICAgIHJlcy5vbignZGF0YScsICgpID0+IHsKICAgICAgICAgICAgLy8gRHJhaW4gc29ja2V0CiAgICAgICAgICB9KTsKCiAgICAgICAgICByZXMub24oJ2VuZCcsICgpID0+IHsKICAgICAgICAgICAgLy8gRHJhaW4gc29ja2V0CiAgICAgICAgICB9KTsKCiAgICAgICAgICByZXMuc2V0RW5jb2RpbmcoJ3V0ZjgnKTsKCiAgICAgICAgICAvLyAiS2V5LXZhbHVlIHBhaXJzIG9mIGhlYWRlciBuYW1lcyBhbmQgdmFsdWVzLiBIZWFkZXIgbmFtZXMgYXJlIGxvd2VyLWNhc2VkLiIKICAgICAgICAgIC8vIGh0dHBzOi8vbm9kZWpzLm9yZy9hcGkvaHR0cC5odG1sI2h0dHBfbWVzc2FnZV9oZWFkZXJzCiAgICAgICAgICBjb25zdCByZXRyeUFmdGVySGVhZGVyID0gX251bGxpc2hDb2FsZXNjZShyZXMuaGVhZGVyc1sncmV0cnktYWZ0ZXInXSwgKCkgPT4gKCBudWxsKSk7CiAgICAgICAgICBjb25zdCByYXRlTGltaXRzSGVhZGVyID0gX251bGxpc2hDb2FsZXNjZShyZXMuaGVhZGVyc1sneC1zZW50cnktcmF0ZS1saW1pdHMnXSwgKCkgPT4gKCBudWxsKSk7CgogICAgICAgICAgcmVzb2x2ZSh7CiAgICAgICAgICAgIHN0YXR1c0NvZGU6IHJlcy5zdGF0dXNDb2RlLAogICAgICAgICAgICBoZWFkZXJzOiB7CiAgICAgICAgICAgICAgJ3JldHJ5LWFmdGVyJzogcmV0cnlBZnRlckhlYWRlciwKICAgICAgICAgICAgICAneC1zZW50cnktcmF0ZS1saW1pdHMnOiBBcnJheS5pc0FycmF5KHJhdGVMaW1pdHNIZWFkZXIpID8gcmF0ZUxpbWl0c0hlYWRlclswXSA6IHJhdGVMaW1pdHNIZWFkZXIsCiAgICAgICAgICAgIH0sCiAgICAgICAgICB9KTsKICAgICAgICB9LAogICAgICApOwoKICAgICAgcmVxLm9uKCdlcnJvcicsIHJlamVjdCk7CiAgICAgIGJvZHkucGlwZShyZXEpOwogICAgfSk7CiAgfTsKfQoKLyoqIG5vcm1hbGl6ZXMgV2luZG93cyBwYXRocyAqLwpmdW5jdGlvbiBub3JtYWxpemVXaW5kb3dzUGF0aChwYXRoKSB7CiAgcmV0dXJuIHBhdGgKICAgIC5yZXBsYWNlKC9eW0EtWl06LywgJycpIC8vIHJlbW92ZSBXaW5kb3dzLXN0eWxlIHByZWZpeAogICAgLnJlcGxhY2UoL1xcL2csICcvJyk7IC8vIHJlcGxhY2UgYWxsIGBcYCBpbnN0YW5jZXMgd2l0aCBgL2AKfQoKLyoqIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IGdldHMgdGhlIG1vZHVsZSBuYW1lIGZyb20gYSBmaWxlbmFtZSAqLwpmdW5jdGlvbiBjcmVhdGVHZXRNb2R1bGVGcm9tRmlsZW5hbWUoCiAgYmFzZVBhdGggPSBwcm9jZXNzLmFyZ3ZbMV0gPyBkaXJuYW1lKHByb2Nlc3MuYXJndlsxXSkgOiBwcm9jZXNzLmN3ZCgpLAogIGlzV2luZG93cyA9IHNlcCA9PT0gJ1xcJywKKSB7CiAgY29uc3Qgbm9ybWFsaXplZEJhc2UgPSBpc1dpbmRvd3MgPyBub3JtYWxpemVXaW5kb3dzUGF0aChiYXNlUGF0aCkgOiBiYXNlUGF0aDsKCiAgcmV0dXJuIChmaWxlbmFtZSkgPT4gewogICAgaWYgKCFmaWxlbmFtZSkgewogICAgICByZXR1cm47CiAgICB9CgogICAgY29uc3Qgbm9ybWFsaXplZEZpbGVuYW1lID0gaXNXaW5kb3dzID8gbm9ybWFsaXplV2luZG93c1BhdGgoZmlsZW5hbWUpIDogZmlsZW5hbWU7CgogICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHByZWZlci1jb25zdAogICAgbGV0IHsgZGlyLCBiYXNlOiBmaWxlLCBleHQgfSA9IHBvc2l4LnBhcnNlKG5vcm1hbGl6ZWRGaWxlbmFtZSk7CgogICAgaWYgKGV4dCA9PT0gJy5qcycgfHwgZXh0ID09PSAnLm1qcycgfHwgZXh0ID09PSAnLmNqcycpIHsKICAgICAgZmlsZSA9IGZpbGUuc2xpY2UoMCwgZXh0Lmxlbmd0aCAqIC0xKTsKICAgIH0KCiAgICBpZiAoIWRpcikgewogICAgICAvLyBObyBkaXJuYW1lIHdoYXRzb2V2ZXIKICAgICAgZGlyID0gJy4nOwogICAgfQoKICAgIGNvbnN0IG4gPSBkaXIubGFzdEluZGV4T2YoJy9ub2RlX21vZHVsZXMnKTsKICAgIGlmIChuID4gLTEpIHsKICAgICAgcmV0dXJuIGAke2Rpci5zbGljZShuICsgMTQpLnJlcGxhY2UoL1wvL2csICcuJyl9OiR7ZmlsZX1gOwogICAgfQoKICAgIC8vIExldCdzIHNlZSBpZiBpdCdzIGEgcGFydCBvZiB0aGUgbWFpbiBtb2R1bGUKICAgIC8vIFRvIGJlIGEgcGFydCBvZiBtYWluIG1vZHVsZSwgaXQgaGFzIHRvIHNoYXJlIHRoZSBzYW1lIGJhc2UKICAgIGlmIChkaXIuc3RhcnRzV2l0aChub3JtYWxpemVkQmFzZSkpIHsKICAgICAgbGV0IG1vZHVsZU5hbWUgPSBkaXIuc2xpY2Uobm9ybWFsaXplZEJhc2UubGVuZ3RoICsgMSkucmVwbGFjZSgvXC8vZywgJy4nKTsKCiAgICAgIGlmIChtb2R1bGVOYW1lKSB7CiAgICAgICAgbW9kdWxlTmFtZSArPSAnOic7CiAgICAgIH0KICAgICAgbW9kdWxlTmFtZSArPSBmaWxlOwoKICAgICAgcmV0dXJuIG1vZHVsZU5hbWU7CiAgICB9CgogICAgcmV0dXJuIGZpbGU7CiAgfTsKfQoKZnVuY3Rpb24gX29wdGlvbmFsQ2hhaW4ob3BzKSB7IGxldCBsYXN0QWNjZXNzTEhTID0gdW5kZWZpbmVkOyBsZXQgdmFsdWUgPSBvcHNbMF07IGxldCBpID0gMTsgd2hpbGUgKGkgPCBvcHMubGVuZ3RoKSB7IGNvbnN0IG9wID0gb3BzW2ldOyBjb25zdCBmbiA9IG9wc1tpICsgMV07IGkgKz0gMjsgaWYgKChvcCA9PT0gJ29wdGlvbmFsQWNjZXNzJyB8fCBvcCA9PT0gJ29wdGlvbmFsQ2FsbCcpICYmIHZhbHVlID09IG51bGwpIHsgcmV0dXJuIHVuZGVmaW5lZDsgfSBpZiAob3AgPT09ICdhY2Nlc3MnIHx8IG9wID09PSAnb3B0aW9uYWxBY2Nlc3MnKSB7IGxhc3RBY2Nlc3NMSFMgPSB2YWx1ZTsgdmFsdWUgPSBmbih2YWx1ZSk7IH0gZWxzZSBpZiAob3AgPT09ICdjYWxsJyB8fCBvcCA9PT0gJ29wdGlvbmFsQ2FsbCcpIHsgdmFsdWUgPSBmbigoLi4uYXJncykgPT4gdmFsdWUuY2FsbChsYXN0QWNjZXNzTEhTLCAuLi5hcmdzKSk7IGxhc3RBY2Nlc3NMSFMgPSB1bmRlZmluZWQ7IH0gfSByZXR1cm4gdmFsdWU7IH0KY29uc3Qgb3B0aW9ucyA9IHdvcmtlckRhdGE7CmxldCBzZXNzaW9uOwpsZXQgaGFzU2VudEFuckV2ZW50ID0gZmFsc2U7CgpmdW5jdGlvbiBsb2cobXNnKSB7CiAgaWYgKG9wdGlvbnMuZGVidWcpIHsKICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlCiAgICBjb25zb2xlLmxvZyhgW0FOUiBXb3JrZXJdICR7bXNnfWApOwogIH0KfQoKY29uc3QgdXJsID0gZ2V0RW52ZWxvcGVFbmRwb2ludFdpdGhVcmxFbmNvZGVkQXV0aChvcHRpb25zLmRzbik7CmNvbnN0IHRyYW5zcG9ydCA9IG1ha2VOb2RlVHJhbnNwb3J0KHsKICB1cmwsCiAgcmVjb3JkRHJvcHBlZEV2ZW50OiAoKSA9PiB7CiAgICAvLwogIH0sCn0pOwoKYXN5bmMgZnVuY3Rpb24gc2VuZEFibm9ybWFsU2Vzc2lvbigpIHsKICAvLyBvZiB3ZSBoYXZlIGFuIGV4aXN0aW5nIHNlc3Npb24gcGFzc2VkIGZyb20gdGhlIG1haW4gdGhyZWFkLCBzZW5kIGl0IGFzIGFibm9ybWFsCiAgaWYgKHNlc3Npb24pIHsKICAgIGxvZygnU2VuZGluZyBhYm5vcm1hbCBzZXNzaW9uJyk7CiAgICB1cGRhdGVTZXNzaW9uKHNlc3Npb24sIHsgc3RhdHVzOiAnYWJub3JtYWwnLCBhYm5vcm1hbF9tZWNoYW5pc206ICdhbnJfZm9yZWdyb3VuZCcgfSk7CgogICAgY29uc3QgZW52ZWxvcGUgPSBjcmVhdGVTZXNzaW9uRW52ZWxvcGUoc2Vzc2lvbiwgb3B0aW9ucy5kc24sIG9wdGlvbnMuc2RrTWV0YWRhdGEpOwogICAgLy8gTG9nIHRoZSBlbnZlbG9wZSBzbyB0byBhaWQgaW4gdGVzdGluZwogICAgbG9nKEpTT04uc3RyaW5naWZ5KGVudmVsb3BlKSk7CgogICAgYXdhaXQgdHJhbnNwb3J0LnNlbmQoZW52ZWxvcGUpOwoKICAgIHRyeSB7CiAgICAgIC8vIE5vdGlmeSB0aGUgbWFpbiBwcm9jZXNzIHRoYXQgdGhlIHNlc3Npb24gaGFzIGVuZGVkIHNvIHRoZSBzZXNzaW9uIGNhbiBiZSBjbGVhcmVkIGZyb20gdGhlIHNjb3BlCiAgICAgIF9vcHRpb25hbENoYWluKFtwYXJlbnRQb3J0LCAnb3B0aW9uYWxBY2Nlc3MnLCBfMiA9PiBfMi5wb3N0TWVzc2FnZSwgJ2NhbGwnLCBfMyA9PiBfMygnc2Vzc2lvbi1lbmRlZCcpXSk7CiAgICB9IGNhdGNoIChfKSB7CiAgICAgIC8vIGlnbm9yZQogICAgfQogIH0KfQoKbG9nKCdTdGFydGVkJyk7CgpmdW5jdGlvbiBwcmVwYXJlU3RhY2tGcmFtZXMoc3RhY2tGcmFtZXMpIHsKICBpZiAoIXN0YWNrRnJhbWVzKSB7CiAgICByZXR1cm4gdW5kZWZpbmVkOwogIH0KCiAgLy8gU3RyaXAgU2VudHJ5IGZyYW1lcyBhbmQgcmV2ZXJzZSB0aGUgc3RhY2sgZnJhbWVzIHNvIHRoZXkgYXJlIGluIHRoZSBjb3JyZWN0IG9yZGVyCiAgY29uc3Qgc3RyaXBwZWRGcmFtZXMgPSBzdHJpcFNlbnRyeUZyYW1lc0FuZFJldmVyc2Uoc3RhY2tGcmFtZXMpOwoKICAvLyBJZiB3ZSBoYXZlIGFuIGFwcCByb290IHBhdGgsIHJld3JpdGUgdGhlIGZpbGVuYW1lcyB0byBiZSByZWxhdGl2ZSB0byB0aGUgYXBwIHJvb3QKICBpZiAob3B0aW9ucy5hcHBSb290UGF0aCkgewogICAgZm9yIChjb25zdCBmcmFtZSBvZiBzdHJpcHBlZEZyYW1lcykgewogICAgICBpZiAoIWZyYW1lLmZpbGVuYW1lKSB7CiAgICAgICAgY29udGludWU7CiAgICAgIH0KCiAgICAgIGZyYW1lLmZpbGVuYW1lID0gbm9ybWFsaXplVXJsVG9CYXNlKGZyYW1lLmZpbGVuYW1lLCBvcHRpb25zLmFwcFJvb3RQYXRoKTsKICAgIH0KICB9CgogIHJldHVybiBzdHJpcHBlZEZyYW1lczsKfQoKYXN5bmMgZnVuY3Rpb24gc2VuZEFuckV2ZW50KGZyYW1lcywgdHJhY2VDb250ZXh0KSB7CiAgaWYgKGhhc1NlbnRBbnJFdmVudCkgewogICAgcmV0dXJuOwogIH0KCiAgaGFzU2VudEFuckV2ZW50ID0gdHJ1ZTsKCiAgYXdhaXQgc2VuZEFibm9ybWFsU2Vzc2lvbigpOwoKICBsb2coJ1NlbmRpbmcgZXZlbnQnKTsKCiAgY29uc3QgZXZlbnQgPSB7CiAgICBldmVudF9pZDogdXVpZDQoKSwKICAgIGNvbnRleHRzOiB7IC4uLm9wdGlvbnMuY29udGV4dHMsIHRyYWNlOiB0cmFjZUNvbnRleHQgfSwKICAgIHJlbGVhc2U6IG9wdGlvbnMucmVsZWFzZSwKICAgIGVudmlyb25tZW50OiBvcHRpb25zLmVudmlyb25tZW50LAogICAgZGlzdDogb3B0aW9ucy5kaXN0LAogICAgcGxhdGZvcm06ICdub2RlJywKICAgIGxldmVsOiAnZXJyb3InLAogICAgZXhjZXB0aW9uOiB7CiAgICAgIHZhbHVlczogWwogICAgICAgIHsKICAgICAgICAgIHR5cGU6ICdBcHBsaWNhdGlvbk5vdFJlc3BvbmRpbmcnLAogICAgICAgICAgdmFsdWU6IGBBcHBsaWNhdGlvbiBOb3QgUmVzcG9uZGluZyBmb3IgYXQgbGVhc3QgJHtvcHRpb25zLmFuclRocmVzaG9sZH0gbXNgLAogICAgICAgICAgc3RhY2t0cmFjZTogeyBmcmFtZXM6IHByZXBhcmVTdGFja0ZyYW1lcyhmcmFtZXMpIH0sCiAgICAgICAgICAvLyBUaGlzIGVuc3VyZXMgdGhlIFVJIGRvZXNuJ3Qgc2F5ICdDcmFzaGVkIGluJyBmb3IgdGhlIHN0YWNrIHRyYWNlCiAgICAgICAgICBtZWNoYW5pc206IHsgdHlwZTogJ0FOUicgfSwKICAgICAgICB9LAogICAgICBdLAogICAgfSwKICAgIHRhZ3M6IG9wdGlvbnMuc3RhdGljVGFncywKICB9OwoKICBjb25zdCBlbnZlbG9wZSA9IGNyZWF0ZUV2ZW50RW52ZWxvcGUoZXZlbnQsIG9wdGlvbnMuZHNuLCBvcHRpb25zLnNka01ldGFkYXRhKTsKICAvLyBMb2cgdGhlIGVudmVsb3BlIHNvIHRvIGFpZCBpbiB0ZXN0aW5nCiAgbG9nKEpTT04uc3RyaW5naWZ5KGVudmVsb3BlKSk7CgogIGF3YWl0IHRyYW5zcG9ydC5zZW5kKGVudmVsb3BlKTsKICBhd2FpdCB0cmFuc3BvcnQuZmx1c2goMjAwMCk7CgogIC8vIERlbGF5IGZvciA1IHNlY29uZHMgc28gdGhhdCBzdGRpbyBjYW4gZmx1c2ggaW4gdGhlIG1haW4gZXZlbnQgbG9vcCBldmVyIHJlc3RhcnRzLgogIC8vIFRoaXMgaXMgbWFpbmx5IGZvciB0aGUgYmVuZWZpdCBvZiBsb2dnaW5nL2RlYnVnZ2luZyBpc3N1ZXMuCiAgc2V0VGltZW91dCgoKSA9PiB7CiAgICBwcm9jZXNzLmV4aXQoMCk7CiAgfSwgNTAwMCk7Cn0KCmxldCBkZWJ1Z2dlclBhdXNlOwoKaWYgKG9wdGlvbnMuY2FwdHVyZVN0YWNrVHJhY2UpIHsKICBsb2coJ0Nvbm5lY3RpbmcgdG8gZGVidWdnZXInKTsKCiAgY29uc3Qgc2Vzc2lvbiA9IG5ldyBTZXNzaW9uKCk7CiAgc2Vzc2lvbi5jb25uZWN0VG9NYWluVGhyZWFkKCk7CgogIGxvZygnQ29ubmVjdGVkIHRvIGRlYnVnZ2VyJyk7CgogIC8vIENvbGxlY3Qgc2NyaXB0SWQgLT4gdXJsIG1hcCBzbyB3ZSBjYW4gbG9vayB1cCB0aGUgZmlsZW5hbWVzIGxhdGVyCiAgY29uc3Qgc2NyaXB0cyA9IG5ldyBNYXAoKTsKCiAgc2Vzc2lvbi5vbignRGVidWdnZXIuc2NyaXB0UGFyc2VkJywgZXZlbnQgPT4gewogICAgc2NyaXB0cy5zZXQoZXZlbnQucGFyYW1zLnNjcmlwdElkLCBldmVudC5wYXJhbXMudXJsKTsKICB9KTsKCiAgc2Vzc2lvbi5vbignRGVidWdnZXIucGF1c2VkJywgZXZlbnQgPT4gewogICAgaWYgKGV2ZW50LnBhcmFtcy5yZWFzb24gIT09ICdvdGhlcicpIHsKICAgICAgcmV0dXJuOwogICAgfQoKICAgIHRyeSB7CiAgICAgIGxvZygnRGVidWdnZXIgcGF1c2VkJyk7CgogICAgICAvLyBjb3B5IHRoZSBmcmFtZXMKICAgICAgY29uc3QgY2FsbEZyYW1lcyA9IFsuLi5ldmVudC5wYXJhbXMuY2FsbEZyYW1lc107CgogICAgICBjb25zdCBnZXRNb2R1bGVOYW1lID0gb3B0aW9ucy5hcHBSb290UGF0aCA/IGNyZWF0ZUdldE1vZHVsZUZyb21GaWxlbmFtZShvcHRpb25zLmFwcFJvb3RQYXRoKSA6ICgpID0+IHVuZGVmaW5lZDsKICAgICAgY29uc3Qgc3RhY2tGcmFtZXMgPSBjYWxsRnJhbWVzLm1hcChmcmFtZSA9PgogICAgICAgIGNhbGxGcmFtZVRvU3RhY2tGcmFtZShmcmFtZSwgc2NyaXB0cy5nZXQoZnJhbWUubG9jYXRpb24uc2NyaXB0SWQpLCBnZXRNb2R1bGVOYW1lKSwKICAgICAgKTsKCiAgICAgIC8vIEV2YWx1YXRlIGEgc2NyaXB0IGluIHRoZSBjdXJyZW50bHkgcGF1c2VkIGNvbnRleHQKICAgICAgc2Vzc2lvbi5wb3N0KAogICAgICAgICdSdW50aW1lLmV2YWx1YXRlJywKICAgICAgICB7CiAgICAgICAgICAvLyBHcmFiIHRoZSB0cmFjZSBjb250ZXh0IGZyb20gdGhlIGN1cnJlbnQgc2NvcGUKICAgICAgICAgIGV4cHJlc3Npb246CiAgICAgICAgICAgICdjb25zdCBjdHggPSBfX1NFTlRSWV9fLmFjcz8uZ2V0Q3VycmVudFNjb3BlKCkuZ2V0UHJvcGFnYXRpb25Db250ZXh0KCkgfHwge307IGN0eC50cmFjZUlkICsgIi0iICsgY3R4LnNwYW5JZCArICItIiArIGN0eC5wYXJlbnRTcGFuSWQnLAogICAgICAgICAgLy8gRG9uJ3QgcmUtdHJpZ2dlciB0aGUgZGVidWdnZXIgaWYgdGhpcyBjYXVzZXMgYW4gZXJyb3IKICAgICAgICAgIHNpbGVudDogdHJ1ZSwKICAgICAgICB9LAogICAgICAgIChfLCBwYXJhbSkgPT4gewogICAgICAgICAgY29uc3QgdHJhY2VJZCA9IHBhcmFtICYmIHBhcmFtLnJlc3VsdCA/IChwYXJhbS5yZXN1bHQudmFsdWUgKSA6ICctLSc7CiAgICAgICAgICBjb25zdCBbdHJhY2VfaWQsIHNwYW5faWQsIHBhcmVudF9zcGFuX2lkXSA9IHRyYWNlSWQuc3BsaXQoJy0nKSA7CgogICAgICAgICAgc2Vzc2lvbi5wb3N0KCdEZWJ1Z2dlci5yZXN1bWUnKTsKICAgICAgICAgIHNlc3Npb24ucG9zdCgnRGVidWdnZXIuZGlzYWJsZScpOwoKICAgICAgICAgIGNvbnN0IGNvbnRleHQgPSBfb3B0aW9uYWxDaGFpbihbdHJhY2VfaWQsICdvcHRpb25hbEFjY2VzcycsIF80ID0+IF80Lmxlbmd0aF0pICYmIF9vcHRpb25hbENoYWluKFtzcGFuX2lkLCAnb3B0aW9uYWxBY2Nlc3MnLCBfNSA9PiBfNS5sZW5ndGhdKSA/IHsgdHJhY2VfaWQsIHNwYW5faWQsIHBhcmVudF9zcGFuX2lkIH0gOiB1bmRlZmluZWQ7CiAgICAgICAgICBzZW5kQW5yRXZlbnQoc3RhY2tGcmFtZXMsIGNvbnRleHQpLnRoZW4obnVsbCwgKCkgPT4gewogICAgICAgICAgICBsb2coJ1NlbmRpbmcgQU5SIGV2ZW50IGZhaWxlZC4nKTsKICAgICAgICAgIH0pOwogICAgICAgIH0sCiAgICAgICk7CiAgICB9IGNhdGNoIChlKSB7CiAgICAgIHNlc3Npb24ucG9zdCgnRGVidWdnZXIucmVzdW1lJyk7CiAgICAgIHNlc3Npb24ucG9zdCgnRGVidWdnZXIuZGlzYWJsZScpOwogICAgICB0aHJvdyBlOwogICAgfQogIH0pOwoKICBkZWJ1Z2dlclBhdXNlID0gKCkgPT4gewogICAgdHJ5IHsKICAgICAgc2Vzc2lvbi5wb3N0KCdEZWJ1Z2dlci5lbmFibGUnLCAoKSA9PiB7CiAgICAgICAgc2Vzc2lvbi5wb3N0KCdEZWJ1Z2dlci5wYXVzZScpOwogICAgICB9KTsKICAgIH0gY2F0Y2ggKF8pIHsKICAgICAgLy8KICAgIH0KICB9Owp9CgpmdW5jdGlvbiBjcmVhdGVIclRpbWVyKCkgewogIC8vIFRPRE8gKHY4KTogV2UgY2FuIHVzZSBwcm9jZXNzLmhydGltZS5iaWdpbnQoKSBhZnRlciB3ZSBkcm9wIG5vZGUgdjgKICBsZXQgbGFzdFBvbGwgPSBwcm9jZXNzLmhydGltZSgpOwoKICByZXR1cm4gewogICAgZ2V0VGltZU1zOiAoKSA9PiB7CiAgICAgIGNvbnN0IFtzZWNvbmRzLCBuYW5vU2Vjb25kc10gPSBwcm9jZXNzLmhydGltZShsYXN0UG9sbCk7CiAgICAgIHJldHVybiBNYXRoLmZsb29yKHNlY29uZHMgKiAxZTMgKyBuYW5vU2Vjb25kcyAvIDFlNik7CiAgICB9LAogICAgcmVzZXQ6ICgpID0+IHsKICAgICAgbGFzdFBvbGwgPSBwcm9jZXNzLmhydGltZSgpOwogICAgfSwKICB9Owp9CgpmdW5jdGlvbiB3YXRjaGRvZ1RpbWVvdXQoKSB7CiAgbG9nKCdXYXRjaGRvZyB0aW1lb3V0Jyk7CgogIGlmIChkZWJ1Z2dlclBhdXNlKSB7CiAgICBsb2coJ1BhdXNpbmcgZGVidWdnZXIgdG8gY2FwdHVyZSBzdGFjayB0cmFjZScpOwogICAgZGVidWdnZXJQYXVzZSgpOwogIH0gZWxzZSB7CiAgICBsb2coJ0NhcHR1cmluZyBldmVudCB3aXRob3V0IGEgc3RhY2sgdHJhY2UnKTsKICAgIHNlbmRBbnJFdmVudCgpLnRoZW4obnVsbCwgKCkgPT4gewogICAgICBsb2coJ1NlbmRpbmcgQU5SIGV2ZW50IGZhaWxlZCBvbiB3YXRjaGRvZyB0aW1lb3V0LicpOwogICAgfSk7CiAgfQp9Cgpjb25zdCB7IHBvbGwgfSA9IHdhdGNoZG9nVGltZXIoY3JlYXRlSHJUaW1lciwgb3B0aW9ucy5wb2xsSW50ZXJ2YWwsIG9wdGlvbnMuYW5yVGhyZXNob2xkLCB3YXRjaGRvZ1RpbWVvdXQpOwoKX29wdGlvbmFsQ2hhaW4oW3BhcmVudFBvcnQsICdvcHRpb25hbEFjY2VzcycsIF82ID0+IF82Lm9uLCAnY2FsbCcsIF83ID0+IF83KCdtZXNzYWdlJywgKG1zZykgPT4gewogIGlmIChtc2cuc2Vzc2lvbikgewogICAgc2Vzc2lvbiA9IG1ha2VTZXNzaW9uKG1zZy5zZXNzaW9uKTsKICB9CgogIHBvbGwoKTsKfSldKTs=";
@@ -1 +0,0 @@
1
- {"version":3,"file":"worker-script.js","sources":["../../../../src/integrations/anr/worker-script.ts"],"sourcesContent":["// This file is a placeholder that gets overwritten in the build directory.\nexport const base64WorkerScript = '';\n"],"names":[],"mappings":";;AAAA;AACO,MAAM,kBAAmB,GAAE;;;;"}
@@ -1,40 +0,0 @@
1
- Object.defineProperty(exports, '__esModule', { value: true });
2
-
3
- const util = require('util');
4
- const core = require('@sentry/core');
5
- const utils = require('@sentry/utils');
6
-
7
- const INTEGRATION_NAME = 'Console';
8
-
9
- const _consoleIntegration = (() => {
10
- return {
11
- name: INTEGRATION_NAME,
12
- setup(client) {
13
- utils.addConsoleInstrumentationHandler(({ args, level }) => {
14
- if (core.getClient() !== client) {
15
- return;
16
- }
17
-
18
- core.addBreadcrumb(
19
- {
20
- category: 'console',
21
- level: utils.severityLevelFromString(level),
22
- message: util.format.apply(undefined, args),
23
- },
24
- {
25
- input: [...args],
26
- level,
27
- },
28
- );
29
- });
30
- },
31
- };
32
- }) ;
33
-
34
- /**
35
- * Capture console logs as breadcrumbs.
36
- */
37
- const consoleIntegration = core.defineIntegration(_consoleIntegration);
38
-
39
- exports.consoleIntegration = consoleIntegration;
40
- //# sourceMappingURL=console.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"console.js","sources":["../../../src/integrations/console.ts"],"sourcesContent":["import * as util from 'util';\nimport { addBreadcrumb, defineIntegration, getClient } from '@sentry/core';\nimport type { IntegrationFn } from '@sentry/types';\nimport { addConsoleInstrumentationHandler, severityLevelFromString } from '@sentry/utils';\n\nconst INTEGRATION_NAME = 'Console';\n\nconst _consoleIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setup(client) {\n addConsoleInstrumentationHandler(({ args, level }) => {\n if (getClient() !== client) {\n return;\n }\n\n addBreadcrumb(\n {\n category: 'console',\n level: severityLevelFromString(level),\n message: util.format.apply(undefined, args),\n },\n {\n input: [...args],\n level,\n },\n );\n });\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Capture console logs as breadcrumbs.\n */\nexport const consoleIntegration = defineIntegration(_consoleIntegration);\n"],"names":["addConsoleInstrumentationHandler","getClient","addBreadcrumb","severityLevelFromString","defineIntegration"],"mappings":";;;;;;AAKA,MAAM,gBAAA,GAAmB,SAAS,CAAA;AAClC;AACA,MAAM,mBAAoB,IAAG,MAAM;AACnC,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,gBAAgB;AAC1B,IAAI,KAAK,CAAC,MAAM,EAAE;AAClB,MAAMA,sCAAgC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAA,EAAO,KAAK;AAC5D,QAAQ,IAAIC,cAAS,EAAG,KAAI,MAAM,EAAE;AACpC,UAAU,OAAM;AAChB,SAAQ;AACR;AACA,QAAQC,kBAAa;AACrB,UAAU;AACV,YAAY,QAAQ,EAAE,SAAS;AAC/B,YAAY,KAAK,EAAEC,6BAAuB,CAAC,KAAK,CAAC;AACjD,YAAY,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC;AACvD,WAAW;AACX,UAAU;AACV,YAAY,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;AAC5B,YAAY,KAAK;AACjB,WAAW;AACX,SAAS,CAAA;AACT,OAAO,CAAC,CAAA;AACR,KAAK;AACL,GAAG,CAAA;AACH,CAAC,CAAE,EAAA;AACH;AACA;AACA;AACA;MACa,kBAAmB,GAAEC,sBAAiB,CAAC,mBAAmB;;;;"}